diff options
162 files changed, 5516 insertions, 5810 deletions
@@ -37,7 +37,7 @@ ScummVM Team Matthew Hoops Filippos Karapetis Pawel Kolodziejski - Walter van Niftrik + Walter van Niftrik - (retired) Kari Salminen Eugene Sandulenko David Symonds - (retired) @@ -141,7 +141,7 @@ ScummVM Team Max Horn - (retired) Filippos Karapetis Martin Kiewitz - Walter van Niftrik + Walter van Niftrik - (retired) Willem Jan Palenstijn Jordi Vilalta Prat Lars Skovlund @@ -2,10 +2,13 @@ For a more comprehensive changelog of the latest experimental code, see: https://github.com/scummvm/scummvm/commits/ 1.4.0 (????-??-??) + SCUMM: + - Implemented PC Speaker support for SCUMM v5 games. + SDL ports: - Added support for OpenGL (GSoC Task). -1.3.1 (????-??-??) +1.3.1 (2011-07-12) General: - Improved audio device detection and fallback. There should be no more silent errors due to invalid audio devices. diff --git a/audio/decoders/aac.cpp b/audio/decoders/aac.cpp index 874062a702..50325dc9f0 100644 --- a/audio/decoders/aac.cpp +++ b/audio/decoders/aac.cpp @@ -28,74 +28,34 @@ #ifdef USE_FAAD #include "common/debug.h" +#include "common/memstream.h" #include "common/stream.h" #include "common/textconsole.h" #include "common/util.h" #include "audio/audiostream.h" +#include "audio/decoders/codec.h" +#include "audio/decoders/raw.h" #include <neaacdec.h> namespace Audio { -class AACStream : public AudioStream { +class AACDecoder : public Codec { public: - AACStream(Common::SeekableReadStream *stream, - DisposeAfterUse::Flag disposeStream, - Common::SeekableReadStream *extraData, + AACDecoder(Common::SeekableReadStream *extraData, DisposeAfterUse::Flag disposeExtraData); - ~AACStream(); + ~AACDecoder(); - int readBuffer(int16 *buffer, const int numSamples); - - bool endOfData() const { return _inBufferPos >= _inBufferSize && !_remainingSamples; } - bool isStereo() const { return _channels == 2; } - int getRate() const { return _rate; } + AudioStream *decodeFrame(Common::SeekableReadStream &stream); private: NeAACDecHandle _handle; byte _channels; unsigned long _rate; - - byte *_inBuffer; - uint32 _inBufferSize; - uint32 _inBufferPos; - - int16 *_remainingSamples; - uint32 _remainingSamplesSize; - uint32 _remainingSamplesPos; - - void init(Common::SeekableReadStream *extraData); }; -AACStream::AACStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeStream, - Common::SeekableReadStream *extraData, DisposeAfterUse::Flag disposeExtraData) { - - _remainingSamples = 0; - _inBufferPos = 0; - - init(extraData); - - // Copy all the data to a pointer so it can be passed through - // (At least MPEG-4 chunks shouldn't be large) - _inBufferSize = stream->size(); - _inBuffer = new byte[_inBufferSize]; - stream->read(_inBuffer, _inBufferSize); - - if (disposeStream == DisposeAfterUse::YES) - delete stream; - - if (disposeExtraData == DisposeAfterUse::YES) - delete extraData; -} - -AACStream::~AACStream() { - NeAACDecClose(_handle); - delete[] _inBuffer; - delete[] _remainingSamples; -} - -void AACStream::init(Common::SeekableReadStream *extraData) { +AACDecoder::AACDecoder(Common::SeekableReadStream *extraData, DisposeAfterUse::Flag disposeExtraData) { // Open the library _handle = NeAACDecOpen(); @@ -117,59 +77,55 @@ void AACStream::init(Common::SeekableReadStream *extraData) { if (err < 0) error("Could not initialize AAC decoder: %s", NeAACDecGetErrorMessage(err)); -} - -int AACStream::readBuffer(int16 *buffer, const int numSamples) { - int samples = 0; - assert((numSamples % _channels) == 0); + if (disposeExtraData == DisposeAfterUse::YES) + delete extraData; +} - // Dip into our remaining samples pool if it's available - if (_remainingSamples) { - samples = MIN<int>(numSamples, _remainingSamplesSize - _remainingSamplesPos); +AACDecoder::~AACDecoder() { + NeAACDecClose(_handle); +} - memcpy(buffer, _remainingSamples + _remainingSamplesPos, samples * 2); - _remainingSamplesPos += samples; +AudioStream *AACDecoder::decodeFrame(Common::SeekableReadStream &stream) { + // read everything into a buffer + uint32 inBufferPos = 0; + uint32 inBufferSize = stream.size(); + byte *inBuffer = new byte[inBufferSize]; + stream.read(inBuffer, inBufferSize); - if (_remainingSamplesPos == _remainingSamplesSize) { - delete[] _remainingSamples; - _remainingSamples = 0; - } - } + QueuingAudioStream *audioStream = makeQueuingAudioStream(_rate, _channels == 2); // Decode until we have enough samples (or there's no more left) - while (samples < numSamples && !endOfData()) { + while (inBufferPos < inBufferSize) { NeAACDecFrameInfo frameInfo; - uint16 *decodedSamples = (uint16 *)NeAACDecDecode(_handle, &frameInfo, _inBuffer + _inBufferPos, _inBufferSize - _inBufferPos); + void *decodedSamples = NeAACDecDecode(_handle, &frameInfo, inBuffer + inBufferPos, inBufferSize - inBufferPos); if (frameInfo.error != 0) error("Failed to decode AAC frame: %s", NeAACDecGetErrorMessage(frameInfo.error)); - int decodedSampleSize = frameInfo.samples; - int copySamples = (decodedSampleSize > (numSamples - samples)) ? (numSamples - samples) : decodedSampleSize; + byte *buffer = (byte *)malloc(frameInfo.samples * 2); + memcpy(buffer, decodedSamples, frameInfo.samples * 2); - memcpy(buffer + samples, decodedSamples, copySamples * 2); - samples += copySamples; + byte flags = FLAG_16BITS; - // Copy leftover samples for use in a later readBuffer() call - if (copySamples != decodedSampleSize) { - _remainingSamplesSize = decodedSampleSize - copySamples; - _remainingSamples = new int16[_remainingSamplesSize]; - _remainingSamplesPos = 0; - memcpy(_remainingSamples, decodedSamples + copySamples, _remainingSamplesSize * 2); - } + if (_channels == 2) + flags |= FLAG_STEREO; - _inBufferPos += frameInfo.bytesconsumed; +#ifdef SCUMM_LITTLE_ENDIAN + flags |= FLAG_LITTLE_ENDIAN; +#endif + + audioStream->queueBuffer(buffer, frameInfo.samples * 2, DisposeAfterUse::YES, flags); + + inBufferPos += frameInfo.bytesconsumed; } - return samples; + return audioStream; } // Factory function -AudioStream *makeAACStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeStream, - Common::SeekableReadStream *extraData, DisposeAfterUse::Flag disposeExtraData) { - - return new AACStream(stream, disposeStream, extraData, disposeExtraData); +Codec *makeAACDecoder(Common::SeekableReadStream *extraData, DisposeAfterUse::Flag disposeExtraData) { + return new AACDecoder(extraData, disposeExtraData); } } // End of namespace Audio diff --git a/audio/decoders/aac.h b/audio/decoders/aac.h index efcbcc6f42..c5085fadaa 100644 --- a/audio/decoders/aac.h +++ b/audio/decoders/aac.h @@ -43,23 +43,19 @@ namespace Common { namespace Audio { -class AudioStream; +class Codec; /** - * Create a new AudioStream from the AAC data of an MPEG-4 file in the given stream. + * Create a new Codec for decoding AAC data of an MPEG-4 file in the given stream. * * @note This should *only* be called by our QuickTime/MPEG-4 decoder since it relies * on the MPEG-4 extra data. If you want to decode a file using AAC, go use * makeQuickTimeStream() instead! - * @param stream the SeekableReadStream from which to read the AAC data - * @param disposeStream whether to delete the stream after use * @param extraData the SeekableReadStream from which to read the AAC extra data * @param disposeExtraData whether to delete the extra data stream after use - * @return a new AudioStream, or NULL, if an error occurred + * @return a new Codec, or NULL, if an error occurred */ -AudioStream *makeAACStream( - Common::SeekableReadStream *stream, - DisposeAfterUse::Flag disposeStream, +Codec *makeAACDecoder( Common::SeekableReadStream *extraData, DisposeAfterUse::Flag disposeExtraData = DisposeAfterUse::NO); diff --git a/audio/decoders/codec.h b/audio/decoders/codec.h new file mode 100644 index 0000000000..93b6878dee --- /dev/null +++ b/audio/decoders/codec.h @@ -0,0 +1,44 @@ +/* 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 AUDIO_DECODERS_CODEC_H +#define AUDIO_DECODERS_CODEC_H + +namespace Common { + class SeekableReadStream; +} + +namespace Audio { + +class AudioStream; + +class Codec { +public: + Codec() {} + virtual ~Codec() {} + + virtual AudioStream *decodeFrame(Common::SeekableReadStream &data) = 0; +}; + +} // End of namespace Audio + +#endif diff --git a/audio/decoders/qdm2.cpp b/audio/decoders/qdm2.cpp index a178c363b5..ec2911ef20 100644 --- a/audio/decoders/qdm2.cpp +++ b/audio/decoders/qdm2.cpp @@ -28,7 +28,9 @@ #ifdef AUDIO_QDM2_H #include "audio/audiostream.h" +#include "audio/decoders/codec.h" #include "audio/decoders/qdm2data.h" +#include "audio/decoders/raw.h" #include "common/array.h" #include "common/debug.h" @@ -150,19 +152,14 @@ struct RDFTContext { FFTContext fft; }; -class QDM2Stream : public AudioStream { +class QDM2Stream : public Codec { public: - QDM2Stream(Common::SeekableReadStream *stream, Common::SeekableReadStream *extraData); + QDM2Stream(Common::SeekableReadStream *extraData, DisposeAfterUse::Flag disposeExtraData); ~QDM2Stream(); - bool isStereo() const { return _channels == 2; } - bool endOfData() const { return _stream->pos() >= _stream->size() && _outputSamples.size() == 0 && _subPacket == 0; } - int getRate() const { return _sampleRate; } - int readBuffer(int16 *buffer, const int numSamples); + AudioStream *decodeFrame(Common::SeekableReadStream &stream); private: - Common::SeekableReadStream *_stream; - // Parameters from codec header, do not change during playback uint8 _channels; uint16 _sampleRate; @@ -204,7 +201,6 @@ private: // I/O data uint8 *_compressedData; float _outputBuffer[1024]; - Common::Array<int16> _outputSamples; // Synthesis filter int16 ff_mpa_synth_window[512]; @@ -285,7 +281,7 @@ private: void qdm2_fft_tone_synthesizer(uint8 sub_packet); void qdm2_calculate_fft(int channel); void qdm2_synthesis_filter(uint8 index); - int qdm2_decodeFrame(Common::SeekableReadStream *in); + bool qdm2_decodeFrame(Common::SeekableReadStream &in, QueuingAudioStream *audioStream); }; // Fix compilation for non C99-compliant compilers, like MSVC @@ -1711,7 +1707,7 @@ void QDM2Stream::initVlc(void) { } } -QDM2Stream::QDM2Stream(Common::SeekableReadStream *stream, Common::SeekableReadStream *extraData) { +QDM2Stream::QDM2Stream(Common::SeekableReadStream *extraData, DisposeAfterUse::Flag disposeExtraData) { uint32 tmp; int32 tmp_s; int tmp_val; @@ -1719,7 +1715,6 @@ QDM2Stream::QDM2Stream(Common::SeekableReadStream *stream, Common::SeekableReadS debug(1, "QDM2Stream::QDM2Stream() Call"); - _stream = stream; _compressedData = NULL; _subPacket = 0; _superBlockStart = 0; @@ -1906,11 +1901,13 @@ QDM2Stream::QDM2Stream(Common::SeekableReadStream *stream, Common::SeekableReadS initNoiseSamples(); _compressedData = new uint8[_packetSize]; + + if (disposeExtraData == DisposeAfterUse::YES) + delete extraData; } QDM2Stream::~QDM2Stream() { delete[] _compressedData; - delete _stream; } static int qdm2_get_vlc(GetBitContext *gb, VLC *vlc, int flag, int depth) { @@ -3158,30 +3155,30 @@ void QDM2Stream::qdm2_synthesis_filter(uint8 index) _outputBuffer[_channels * i + ch] += (float)(samples[_channels * sub_sampling * i + ch] >> (sizeof(int16)*8-16)); } -int QDM2Stream::qdm2_decodeFrame(Common::SeekableReadStream *in) { - debug(1, "QDM2Stream::qdm2_decodeFrame in->pos(): %d in->size(): %d", in->pos(), in->size()); +bool QDM2Stream::qdm2_decodeFrame(Common::SeekableReadStream &in, QueuingAudioStream *audioStream) { + debug(1, "QDM2Stream::qdm2_decodeFrame in.pos(): %d in.size(): %d", in.pos(), in.size()); int ch, i; const int frame_size = (_sFrameSize * _channels); // If we're in any packet but the first, seek back to the first if (_subPacket == 0) - _superBlockStart = in->pos(); + _superBlockStart = in.pos(); else - in->seek(_superBlockStart); + in.seek(_superBlockStart); // select input buffer - if (in->eos() || in->pos() >= in->size()) { + if (in.eos() || in.pos() >= in.size()) { debug(1, "QDM2Stream::qdm2_decodeFrame End of Input Stream"); - return 0; + return false; } - if ((in->size() - in->pos()) < _packetSize) { - debug(1, "QDM2Stream::qdm2_decodeFrame Insufficient Packet Data in Input Stream Found: %d Need: %d", in->size() - in->pos(), _packetSize); - return 0; + if ((in.size() - in.pos()) < _packetSize) { + debug(1, "QDM2Stream::qdm2_decodeFrame Insufficient Packet Data in Input Stream Found: %d Need: %d", in.size() - in.pos(), _packetSize); + return false; } - if (!in->eos()) { - in->read(_compressedData, _packetSize); + if (!in.eos()) { + in.read(_compressedData, _packetSize); debug(1, "QDM2Stream::qdm2_decodeFrame constructed input data"); } @@ -3190,7 +3187,7 @@ int QDM2Stream::qdm2_decodeFrame(Common::SeekableReadStream *in) { memset(&_outputBuffer[frame_size], 0, frame_size * sizeof(float)); debug(1, "QDM2Stream::qdm2_decodeFrame cleared outputBuffer"); - if (!in->eos()) { + if (!in.eos()) { // decode block of QDM2 compressed data debug(1, "QDM2Stream::qdm2_decodeFrame decode block of QDM2 compressed data"); if (_subPacket == 0) { @@ -3218,7 +3215,7 @@ int QDM2Stream::qdm2_decodeFrame(Common::SeekableReadStream *in) { if (!_hasErrors && _subPacketListC[0].packet != NULL) { error("QDM2 : has errors, and C list is not empty"); - return 0; + return false; } } @@ -3236,6 +3233,12 @@ int QDM2Stream::qdm2_decodeFrame(Common::SeekableReadStream *in) { debug(1, "QDM2Stream::qdm2_decodeFrame clip and convert output float[] to 16bit signed samples"); } + if (frame_size == 0) + return false; + + // Prepare a buffer for queuing + uint16 *outputBuffer = (uint16 *)malloc(frame_size * 2); + for (i = 0; i < frame_size; i++) { int value = (int)_outputBuffer[i]; @@ -3244,34 +3247,35 @@ int QDM2Stream::qdm2_decodeFrame(Common::SeekableReadStream *in) { else if (value < -SOFTCLIP_THRESHOLD) value = (value < -HARDCLIP_THRESHOLD) ? -32767 : -_softclipTable[-value - SOFTCLIP_THRESHOLD]; - _outputSamples.push_back(value); + outputBuffer[i] = value; } - return frame_size; -} -int QDM2Stream::readBuffer(int16 *buffer, const int numSamples) { - debug(1, "QDM2Stream::readBuffer numSamples: %d", numSamples); - int32 decodedSamples = _outputSamples.size(); - int32 i; + // Queue the translated buffer to our stream + byte flags = FLAG_16BITS; - while (decodedSamples < numSamples) { - i = qdm2_decodeFrame(_stream); - if (i == 0) - break; // Out Of Decode Frames... - decodedSamples += i; - } + if (_channels == 2) + flags |= FLAG_STEREO; + +#ifdef SCUMM_LITTLE_ENDIAN + flags |= FLAG_LITTLE_ENDIAN; +#endif + + audioStream->queueBuffer((byte *)outputBuffer, frame_size * 2, DisposeAfterUse::YES, flags); + + return true; +} - if (decodedSamples > numSamples) - decodedSamples = numSamples; +AudioStream *QDM2Stream::decodeFrame(Common::SeekableReadStream &stream) { + QueuingAudioStream *audioStream = makeQueuingAudioStream(_sampleRate, _channels == 2); - for (i = 0; i < decodedSamples; i++) - buffer[i] = _outputSamples.remove_at(0); + while (qdm2_decodeFrame(stream, audioStream)) + ; - return decodedSamples; + return audioStream; } -AudioStream *makeQDM2Stream(Common::SeekableReadStream *stream, Common::SeekableReadStream *extraData) { - return new QDM2Stream(stream, extraData); +Codec *makeQDM2Decoder(Common::SeekableReadStream *extraData, DisposeAfterUse::Flag disposeExtraData) { + return new QDM2Stream(extraData, disposeExtraData); } } // End of namespace Audio diff --git a/audio/decoders/qdm2.h b/audio/decoders/qdm2.h index c0ec647bfd..f0793e3c1e 100644 --- a/audio/decoders/qdm2.h +++ b/audio/decoders/qdm2.h @@ -26,22 +26,25 @@ #ifndef AUDIO_QDM2_H #define AUDIO_QDM2_H +#include "common/types.h" + namespace Common { class SeekableReadStream; } namespace Audio { -class AudioStream; +class Codec; /** - * Create a new AudioStream from the QDM2 data in the given stream. + * Create a new Codec from the QDM2 data in the given stream. * - * @param stream the SeekableReadStream from which to read the FLAC data - * @param extraData the QuickTime extra data stream - * @return a new AudioStream, or NULL, if an error occurred + * @param extraData the QuickTime extra data stream + * @param disposeExtraData the QuickTime extra data stream + * @return a new Codec, or NULL, if an error occurred */ -AudioStream *makeQDM2Stream(Common::SeekableReadStream *stream, Common::SeekableReadStream *extraData); +Codec *makeQDM2Decoder(Common::SeekableReadStream *extraData, + DisposeAfterUse::Flag disposeExtraData = DisposeAfterUse::NO); } // End of namespace Audio diff --git a/audio/decoders/quicktime.cpp b/audio/decoders/quicktime.cpp index 0ad2821cd5..a39fedc1d6 100644 --- a/audio/decoders/quicktime.cpp +++ b/audio/decoders/quicktime.cpp @@ -30,6 +30,7 @@ #include "common/textconsole.h" #include "audio/audiostream.h" +#include "audio/decoders/codec.h" #include "audio/decoders/quicktime.h" #include "audio/decoders/quicktime_intern.h" @@ -86,6 +87,9 @@ void QuickTimeAudioDecoder::init() { // Make sure the bits per sample transfers to the sample size if (entry->getCodecTag() == MKTAG('r', 'a', 'w', ' ') || entry->getCodecTag() == MKTAG('t', 'w', 'o', 's')) _tracks[_audioTrackIndex]->sampleSize = (entry->_bitsPerSample / 8) * entry->_channels; + + // Initialize the codec (if necessary) + entry->initCodec(); } } } @@ -217,6 +221,9 @@ void QuickTimeAudioDecoder::setAudioStreamPos(const Timestamp &where) { Audio::QuickTimeAudioDecoder::AudioSampleDesc *entry = (Audio::QuickTimeAudioDecoder::AudioSampleDesc *)_tracks[_audioTrackIndex]->sampleDescs[0]; _audStream = Audio::makeQueuingAudioStream(entry->_sampleRate, entry->_channels == 2); + // Reinitialize the codec + entry->initCodec(); + // First, we need to track down what audio sample we need Audio::Timestamp curAudioTime = where.convertToFramerate(_tracks[_audioTrackIndex]->timeScale); uint32 sample = curAudioTime.totalNumberOfFrames(); @@ -266,6 +273,11 @@ QuickTimeAudioDecoder::AudioSampleDesc::AudioSampleDesc(Common::QuickTimeParser: _samplesPerFrame = 0; _bytesPerFrame = 0; _bitsPerSample = 0; + _codec = 0; +} + +QuickTimeAudioDecoder::AudioSampleDesc::~AudioSampleDesc() { + delete _codec; } bool QuickTimeAudioDecoder::AudioSampleDesc::isAudioCodecSupported() const { @@ -313,7 +325,12 @@ AudioStream *QuickTimeAudioDecoder::AudioSampleDesc::createAudioStream(Common::S if (!stream) return 0; - if (_codecTag == MKTAG('t', 'w', 'o', 's') || _codecTag == MKTAG('r', 'a', 'w', ' ')) { + if (_codec) { + // If we've loaded a codec, make sure we use first + AudioStream *audioStream = _codec->decodeFrame(*stream); + delete stream; + return audioStream; + } else if (_codecTag == MKTAG('t', 'w', 'o', 's') || _codecTag == MKTAG('r', 'a', 'w', ' ')) { // Fortunately, most of the audio used in Myst videos is raw... uint16 flags = 0; if (_codecTag == MKTAG('r', 'a', 'w', ' ')) @@ -330,24 +347,32 @@ AudioStream *QuickTimeAudioDecoder::AudioSampleDesc::createAudioStream(Common::S } else if (_codecTag == MKTAG('i', 'm', 'a', '4')) { // Riven uses this codec (as do some Myst ME videos) return makeADPCMStream(stream, DisposeAfterUse::YES, stream->size(), kADPCMApple, _sampleRate, _channels, 34); - } else if (_codecTag == MKTAG('m', 'p', '4', 'a')) { - // The 7th Guest iOS uses an MPEG-4 codec -#ifdef USE_FAAD - if (_parentTrack->objectTypeMP4 == 0x40) - return makeAACStream(stream, DisposeAfterUse::YES, _parentTrack->extraData); -#endif -#ifdef AUDIO_QDM2_H - } else if (_codecTag == MKTAG('Q', 'D', 'M', '2')) { - // Myst ME uses this codec for many videos - return makeQDM2Stream(stream, _parentTrack->extraData); -#endif } error("Unsupported audio codec"); - return NULL; } +void QuickTimeAudioDecoder::AudioSampleDesc::initCodec() { + delete _codec; _codec = 0; + + switch (_codecTag) { + case MKTAG('Q', 'D', 'M', '2'): +#ifdef AUDIO_QDM2_H + _codec = makeQDM2Decoder(_parentTrack->extraData); +#endif + break; + case MKTAG('m', 'p', '4', 'a'): +#ifdef USE_FAAD + if (_parentTrack->objectTypeMP4 == 0x40) + _codec = makeAACDecoder(_parentTrack->extraData); +#endif + break; + default: + break; + } +} + /** * A wrapper around QuickTimeAudioDecoder that implements the RewindableAudioStream API */ diff --git a/audio/decoders/quicktime_intern.h b/audio/decoders/quicktime_intern.h index f288d5604b..7ce06b85fe 100644 --- a/audio/decoders/quicktime_intern.h +++ b/audio/decoders/quicktime_intern.h @@ -45,6 +45,7 @@ namespace Common { namespace Audio { class AudioStream; +class Codec; class QueuingAudioStream; class QuickTimeAudioDecoder : public Common::QuickTimeParser { @@ -68,10 +69,12 @@ protected: class AudioSampleDesc : public Common::QuickTimeParser::SampleDesc { public: AudioSampleDesc(Common::QuickTimeParser::Track *parentTrack, uint32 codecTag); + ~AudioSampleDesc(); bool isAudioCodecSupported() const; uint32 getAudioChunkSampleCount(uint chunk) const; AudioStream *createAudioStream(Common::SeekableReadStream *stream) const; + void initCodec(); // TODO: Make private in the long run uint16 _bitsPerSample; @@ -79,6 +82,8 @@ protected: uint32 _sampleRate; uint32 _samplesPerFrame; uint32 _bytesPerFrame; + + Codec *_codec; }; // Common::QuickTimeParser API diff --git a/audio/mididrv.cpp b/audio/mididrv.cpp index b71c02f991..27f02c9053 100644 --- a/audio/mididrv.cpp +++ b/audio/mididrv.cpp @@ -128,7 +128,8 @@ Common::String MidiDriver::getDeviceString(DeviceHandle handle, DeviceStringType MidiDriver::DeviceHandle MidiDriver::detectDevice(int flags) { // Query the selected music device (defaults to MT_AUTO device). - DeviceHandle hdl = getDeviceHandle(ConfMan.get("music_driver")); + Common::String selDevStr = ConfMan.hasKey("music_driver") ? ConfMan.get("music_driver") : Common::String("auto"); + DeviceHandle hdl = getDeviceHandle(selDevStr.empty() ? Common::String("auto") : selDevStr); DeviceHandle reslt = 0; _forceTypeMT32 = false; @@ -200,7 +201,7 @@ MidiDriver::DeviceHandle MidiDriver::detectDevice(int flags) { if (getMusicType(hdl) == MT_INVALID) { // If the expressly selected driver or device cannot be found (no longer compiled in, turned off, etc.) // we display a warning and continue. - failedDevStr = ConfMan.get("music_driver"); + failedDevStr = selDevStr; Common::String warningMsg = Common::String::format(_("The selected audio device '%s' was not found (e.g. might be turned off or disconnected). Attempting to fall back to the next available device..."), failedDevStr.c_str()); GUI::MessageDialog dialog(warningMsg); dialog.runModal(); @@ -230,13 +231,15 @@ MidiDriver::DeviceHandle MidiDriver::detectDevice(int flags) { // If a preferred MT32 or GM device has been selected that device gets returned if available. Common::String devStr; if (flags & MDT_PREFER_MT32) - devStr = ConfMan.get("mt32_device"); + devStr = ConfMan.hasKey("mt32_device") ? ConfMan.get("mt32_device") : Common::String("null"); else if (flags & MDT_PREFER_GM) - devStr = ConfMan.get("gm_device"); + devStr = ConfMan.hasKey("gm_device") ? ConfMan.get("gm_device") : Common::String("null"); else devStr = "auto"; - - hdl = getDeviceHandle(devStr); + + // Default to Null device here, since we also register a default null setting for + // the MT32 or GM device in the config manager. + hdl = getDeviceHandle(devStr.empty() ? Common::String("null") : devStr); const MusicType type = getMusicType(hdl); // If we have a "Don't use GM/MT-32" setting we skip this part and jump diff --git a/audio/softsynth/fmtowns_pc98/towns_midi.cpp b/audio/softsynth/fmtowns_pc98/towns_midi.cpp index e415a0dda5..d69ed73ee6 100644 --- a/audio/softsynth/fmtowns_pc98/towns_midi.cpp +++ b/audio/softsynth/fmtowns_pc98/towns_midi.cpp @@ -464,9 +464,10 @@ int TownsMidiOutputChannel::advanceEffectEnvelope(EffectEnvelope *s, EffectDef * s->currentLevel = t; s->modWheelLast = s->modWheelState; t = getEffectModLevel(t, s->modWheelState); - if (t != d->phase) + if (t != d->phase) { d->phase = t; - retFlags |= 1; + retFlags |= 1; + } } if (--s->stepCounter) diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp index 66207b6808..2d41ecead4 100644 --- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp +++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp @@ -752,6 +752,12 @@ bool SurfaceSdlGraphicsManager::loadGFXMode() { error("allocating _screen failed"); #endif + // SDL 1.2 palettes default to all black, + // SDL 1.3 palettes default to all white, + // Thus set our own default palette to all black. + // SDL_SetColors does nothing for non indexed surfaces. + SDL_SetColors(_screen, _currentPalette, 0, 256); + // // Create the surface that contains the scaled graphics in 16 bit mode // diff --git a/backends/mixer/wincesdl/wincesdl-mixer.cpp b/backends/mixer/wincesdl/wincesdl-mixer.cpp index 36ac310ad9..c7659cb0f5 100644 --- a/backends/mixer/wincesdl/wincesdl-mixer.cpp +++ b/backends/mixer/wincesdl/wincesdl-mixer.cpp @@ -131,15 +131,20 @@ uint32 WINCESdlMixerManager::compute_sample_rate() { ConfMan.setBool("FM_medium_quality", true); ConfMan.flushToDisk(); } + } else { + if (!ConfMan.hasKey("FM_high_quality") && !ConfMan.hasKey("FM_medium_quality")) { + ConfMan.setBool("FM_high_quality", true); + ConfMan.flushToDisk(); + } } // See if the output frequency is forced by the game if (gameid == "ft" || gameid == "dig" || gameid == "comi" || gameid == "queen" || gameid == "sword" || gameid == "agi") sampleRate = SAMPLES_PER_SEC_NEW; else { - if (ConfMan.hasKey("high_sample_rate") && ConfMan.getBool("high_sample_rate")) - sampleRate = SAMPLES_PER_SEC_NEW; - else + if (ConfMan.hasKey("high_sample_rate") && !ConfMan.getBool("high_sample_rate")) sampleRate = SAMPLES_PER_SEC_OLD; + else + sampleRate = SAMPLES_PER_SEC_NEW; } #ifdef USE_VORBIS diff --git a/backends/platform/dc/dc-fs.cpp b/backends/platform/dc/dc-fs.cpp index ac709f62b9..c46f9df093 100644 --- a/backends/platform/dc/dc-fs.cpp +++ b/backends/platform/dc/dc-fs.cpp @@ -124,7 +124,7 @@ bool RoninCDDirectoryNode::getChildren(AbstractFSList &myList, ListMode mode, bo if (mode == Common::FSNode::kListFilesOnly) continue; - myList.push_back(new RoninCDDirectoryNode(newPath+"/")); + myList.push_back(new RoninCDDirectoryNode(newPath)); } else { // Honor the chosen mode if (mode == Common::FSNode::kListDirectoriesOnly) diff --git a/backends/platform/dc/selector.cpp b/backends/platform/dc/selector.cpp index 859f2a40ed..339e5df62d 100644 --- a/backends/platform/dc/selector.cpp +++ b/backends/platform/dc/selector.cpp @@ -185,12 +185,24 @@ static void makeDefIcon(Icon &icon) icon.load(scummvm_icon, sizeof(scummvm_icon)); } +static bool sameOrSubdir(const char *dir1, const char *dir2) +{ + int l1 = strlen(dir1), l2 = strlen(dir2); + if (l1<=l2) + return !strcmp(dir1, dir2); + else + return !memcmp(dir1, dir2, l2); +} + static bool uniqueGame(const char *base, const char *dir, Common::Language lang, Common::Platform plf, Game *games, int cnt) { while (cnt--) - if (!strcmp(dir, games->dir) && + if (/*Don't detect the same game in a subdir, + this is a workaround for the detector bug in toon... */ + sameOrSubdir(dir, games->dir) && + /*!strcmp(dir, games->dir) &&*/ !stricmp(base, games->filename_base) && lang == games->language && plf == games->platform) @@ -237,19 +249,24 @@ static int findGames(Game *games, int max, bool use_ini) } while ((curr_game < max || use_ini) && curr_dir < num_dirs) { - strncpy(dirs[curr_dir].name, dirs[curr_dir].node.getPath().c_str(), 252); - dirs[curr_dir].name[251] = '\0'; + strncpy(dirs[curr_dir].name, dirs[curr_dir].node.getPath().c_str(), 251); + dirs[curr_dir].name[250] = '\0'; + if (!dirs[curr_dir].name[0] || + dirs[curr_dir].name[strlen(dirs[curr_dir].name)-1] != '/') + strcat(dirs[curr_dir].name, "/"); dirs[curr_dir].deficon[0] = '\0'; Common::FSList files, fslist; dirs[curr_dir++].node.getChildren(fslist, Common::FSNode::kListAll); for (Common::FSList::const_iterator entry = fslist.begin(); entry != fslist.end(); ++entry) { if (entry->isDirectory()) { - if (!use_ini && num_dirs < MAX_DIR && - strcasecmp(entry->getDisplayName().c_str(), "install")) { + if (!use_ini && num_dirs < MAX_DIR) { dirs[num_dirs].node = *entry; num_dirs++; } + /* Toonstruck detector needs directories to be present too */ + if(!use_ini) + files.push_back(*entry); } else if (isIcon(*entry)) strcpy(dirs[curr_dir-1].deficon, entry->getDisplayName().c_str()); diff --git a/backends/platform/gph/devices/gp2x/mmuhack/readme.txt b/backends/platform/gph/devices/gp2x/mmuhack/README index bea49d7d6d..6db7d81845 100644 --- a/backends/platform/gph/devices/gp2x/mmuhack/readme.txt +++ b/backends/platform/gph/devices/gp2x/mmuhack/README @@ -1,3 +1,10 @@ +PLEASE NOTE: + +The binary object 'mmuhack.o' is stored in the source tree as it is very awkward to +build it manually each time and would require the use of 2 toolchains to do so. + +Notes on how to rebuild from the included source can be found below. + About ----- @@ -107,4 +114,3 @@ Credits Original idea/implementation: Squidge (this whole thing is also known as squidgehack) Kernel module: NK Documentation: notaz - diff --git a/backends/platform/openpandora/build/PXML.xml b/backends/platform/openpandora/build/PXML.xml index f4d2e2a595..a87c49e2b8 100755 --- a/backends/platform/openpandora/build/PXML.xml +++ b/backends/platform/openpandora/build/PXML.xml @@ -1,34 +1,55 @@ <?xml version="1.0" encoding="UTF-8"?> <PXML xmlns="http://openpandora.org/namespaces/PXML" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="PXML_schema.xsd"> - - <application id="scummvm.djwillis.0001" appdata="scummvm"> - - <title lang="en_US">ScummVM</title> - - <exec command="./runscummvm.sh"/> - <icon src="icon/scummvm.png"/> - - <previewpics> - <pic src="icon/preview-pic.png"/> - </previewpics> - - <info name="ScummVM Documentation" type="text/html" src="docs/index.html"/> - - <description lang="en_US">Point & click game interpreter.</description> - - <author name="DJWillis" website="http://www.scummvm.org/"/> - - <version major="1" minor="1" release="1" build="1"/><!--This programs version--> - <osversion major="1" minor="0" release="0" build="0"/><!--The minimum OS version required--> - - <categories> - <category name="Game"><!--category like "Games", "Graphics", "Internet" etc--> - <subcategory name="Adventure Games"/><!--subcategory, like "Board Games", "Strategy", "First Person Shooters"--> - </category> - </categories> - - <clockspeed frequency="500"/><!--Frequency in Hz--> - - </application> - + <!-- This is the package, in our case ScummVM --> + <package id="scummvm.djwillis.0001"> + <author name="DJWillis" website="http://www.scummvm.org/"/> + <!-- version type can be alpha, beta or release, set to release in branch --> + <version major="1" minor="4" release="0" build="1" type="alpha"/> + <!-- Both title and titles are needed --> + <title lang="en_US">ScummVM</title> + <titles> + <title lang="en_US">ScummVM</title> + </titles> + <descriptions> + <description lang="en_US"> + ScummVM is a program which allows you to run certain classic graphical point-and-click adventure games, provided you already have their data files. The clever part about this: ScummVM just replaces the executables shipped with the games, allowing you to play them on systems for which they were never designed! + + ScummVM supports many adventure games, including LucasArts SCUMM games (such as Monkey Island 1-3, Day of the Tentacle, Sam & Max, ...), many of Sierra's AGI and SCI games (such as King's Quest 1-6, Space Quest 1-5, ...), Discworld 1 and 2, Simon the Sorcerer 1 and 2, Beneath A Steel Sky, Lure of the Temptress, Broken Sword 1 and 2, Flight of the Amazon Queen, Gobliiins 1-3, The Legend of Kyrandia 1-3, many of Humongous Entertainment's children's SCUMM games (including Freddi Fish and Putt Putt games) and many more. + </description> + </descriptions> + <icon src="icon/scummvm.png"/> + </package> + + <!-- This is the application, the ScummVM binary --> + <application id="scummvm.djwillis.0001" appdata="scummvm"> + <exec command="./runscummvm.sh"/> + <author name="DJWillis" website="http://www.scummvm.org/"/> + <!-- version type can be alpha, beta or release, set to release in branch --> + <version major="1" minor="4" release="0" build="1" type="alpha"/> + <!-- Both title and titles are needed --> + <title lang="en_US">ScummVM</title> + <titles> + <title lang="en_US">ScummVM</title> + </titles> + <descriptions> + <description lang="en_US"> + ScummVM is a program which allows you to run certain classic graphical point-and-click adventure games, provided you already have their data files. The clever part about this: ScummVM just replaces the executables shipped with the games, allowing you to play them on systems for which they were never designed! + + ScummVM supports many adventure games, including LucasArts SCUMM games (such as Monkey Island 1-3, Day of the Tentacle, Sam & Max, ...), many of Sierra's AGI and SCI games (such as King's Quest 1-6, Space Quest 1-5, ...), Discworld 1 and 2, Simon the Sorcerer 1 and 2, Beneath A Steel Sky, Lure of the Temptress, Broken Sword 1 and 2, Flight of the Amazon Queen, Gobliiins 1-3, The Legend of Kyrandia 1-3, many of Humongous Entertainment's children's SCUMM games (including Freddi Fish and Putt Putt games) and many more. + </description> + </descriptions> + <licenses> + <license name="GPLv2" url="http://www.gnu.org/licenses/gpl-2.0.html" sourcecodeurl="http://www.scummvm.org"/> + </licenses> + <icon src="icon/scummvm.png"/> + <previewpics> + <pic src="icon/preview-pic.png"/> + </previewpics> + <info name="ScummVM Documentation" type="text/html" src="docs/index.html"/> + <categories> + <category name="Game"> + <subcategory name="AdventureGame"/> + </category> + </categories> + </application> </PXML> diff --git a/backends/platform/openpandora/build/PXML_schema.xsd b/backends/platform/openpandora/build/PXML_schema.xsd new file mode 100644 index 0000000000..335efe5002 --- /dev/null +++ b/backends/platform/openpandora/build/PXML_schema.xsd @@ -0,0 +1,341 @@ +<?xml version="1.0" encoding="utf-8"?> +<xs:schema targetNamespace="http://openpandora.org/namespaces/PXML" xmlns="http://openpandora.org/namespaces/PXML" xmlns:xs="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" elementFormDefault="qualified"> + + + <!-- declare some simpleTypes for later usage --> + + <!-- Specify params allows with the 'x11' entry in exec --> + <xs:simpleType name="x11Param"> + <xs:restriction base="xs:string"> + <xs:enumeration value="req" /> + <xs:enumeration value="stop" /> + <xs:enumeration value="ignore" /> + </xs:restriction> + </xs:simpleType> + + <!-- Specify the valid documentation formats in the <info> block --> + <xs:simpleType name="docType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="text/html" /> + <xs:enumeration value="text/plain" /> + </xs:restriction> + </xs:simpleType> + + <!-- Make sure that version numbers only consist of letters, numbers and + as well as - --> + <xs:simpleType name="versionNumber"> + <xs:restriction base="xs:string"> + <xs:minLength value="1"/> + <xs:pattern value="[a-zA-Z0-9+-]*" /> + </xs:restriction> + </xs:simpleType> + + <!-- Specify what is valid as release type --> + <xs:simpleType name="releaseType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="alpha" /> + <xs:enumeration value="beta" /> + <xs:enumeration value="release" /> + </xs:restriction> + </xs:simpleType> + + <!-- Specify what makes an email address "valid" --> + <xs:simpleType name="emailAddress"> + <xs:restriction base="xs:string"> + <xs:pattern value="[^@]+@[^\.]+\..+"/> + </xs:restriction> + </xs:simpleType> + + <!-- some restrictions regarding file names that are eg not allowed/possible when using sd cards formated as fat32 --> + <xs:simpleType name="dumbPath"> + <xs:restriction base="xs:normalizedString"> + <xs:pattern value="[^?>:]+" /> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="dumbFolderName"> + <xs:restriction base="xs:normalizedString"> + <xs:pattern value="[^?>:/]+" /> + </xs:restriction> + </xs:simpleType> + + <!-- Specify lang codes --> + <xs:simpleType name="isoLangcode"> + <xs:restriction base="xs:string"> + <xs:minLength value="2"/> + <xs:pattern value="[a-zA-Z]{2,3}(_[a-zA-Z0-9]{2,3})*" /> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="isoLangcode_en_US"> + <xs:restriction base="xs:string"> + <xs:enumeration value="en_US" /> + </xs:restriction> + </xs:simpleType> + + <!-- Definition of all allowed categories following the FDO specs --> + <xs:simpleType name="fdoCategory"> + <xs:restriction base="xs:string"> + <xs:pattern value="AudioVideo|Audio|Video|Development|Education|Game|Graphics|Network|Office|Settings|System|Utility"/> + </xs:restriction> + </xs:simpleType> + <!-- Definition of all allowed subcategories following the FDO specs (should be based upon the given main categories, but would significantly increase complexity of the schema) --> + <xs:simpleType name="fdoSubCategory"> + <xs:restriction base="xs:string"> + <xs:pattern value="Building|Debugger|IDE|GUIDesigner|Profiling|RevisionControl|Translation|Calendar|ContactManagement|Database|Dictionary|Chart|Email|Finance|FlowChart|PDA|ProjectManagement|Presentation|Spreadsheet|WordProcessor|2DGraphics|VectorGraphics|RasterGraphics|3DGraphics|Scanning|OCR|Photography|Publishing|Viewer|TextTools|DesktopSettings|HardwareSettings|Printing|PackageManager|Dialup|InstantMessaging|Chat|IRCClient|FileTransfer|HamRadio|News|P2P|RemoteAccess|Telephony|TelephonyTools|VideoConference|WebBrowser|WebDevelopment|Midi|Mixer|Sequencer|Tuner|TV|AudioVideoEditing|Player|Recorder|DiscBurning|ActionGame|AdventureGame|ArcadeGame|BoardGame|BlocksGame|CardGame|KidsGame|LogicGame|RolePlaying|Simulation|SportsGame|StrategyGame|Art|Construction|Music|Languages|Science|ArtificialIntelligence|Astronomy|Biology|Chemistry|ComputerScience|DataVisualization|Economy|Electricity|Geography|Geology|Geoscience|History|ImageProcessing|Literature|Math|NumericalAnalysis|MedicalSoftware|Physics|Robotics|Sports|ParallelComputing|Amusement|Archiving|Compression|Electronics|Emulator|Engineering|FileTools|FileManager|TerminalEmulator|Filesystem|Monitor|Security|Accessibility|Calculator|Clock|TextEditor|Documentation|Core|KDE|GNOME|GTK|Qt|Motif|Java|ConsoleOnly"/> + </xs:restriction> + </xs:simpleType> + + <!-- Create some way to enforce entries to be nonempty --> + <xs:simpleType name="nonempty_token"> + <xs:restriction base="xs:token"> + <xs:minLength value="1"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="nonempty_string"> + <xs:restriction base="xs:string"> + <xs:minLength value="1"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="nonempty_normalizedString"> + <xs:restriction base="xs:string"> + <xs:minLength value="1"/> + </xs:restriction> + </xs:simpleType> + + + + <!-- declare some complexTypes for later usage --> + + <!-- type used for file associations --> + <xs:complexType name="association_data"> + <xs:attribute name="name" use="required" type="nonempty_normalizedString" /> + <xs:attribute name="filetype" use="required" type="nonempty_token" /> + <xs:attribute name="exec" use="required" type="nonempty_token" /> + </xs:complexType> + + <!-- type used for author info --> + <xs:complexType name="author_data"> + <xs:attribute name="name" use="required" type="nonempty_normalizedString" /> + <xs:attribute name="website" use="optional" type="xs:anyURI" /> + <xs:attribute name="email" use="optional" type="emailAddress" /> + </xs:complexType> + + <!-- type used for version informations (full entry as well as os version) --> + <xs:complexType name="app_version_info"> + <xs:attribute name="major" use="required" type="versionNumber" /> + <xs:attribute name="minor" use="required" type="versionNumber" /> + <xs:attribute name="release" use="required" type="versionNumber" /> + <xs:attribute name="build" use="required" type="versionNumber" /> + <xs:attribute name="type" use="optional" type="releaseType" /> + </xs:complexType> + <xs:complexType name="os_version_info"> + <xs:attribute name="major" use="required" type="versionNumber" /> + <xs:attribute name="minor" use="required" type="versionNumber" /> + <xs:attribute name="release" use="required" type="versionNumber" /> + <xs:attribute name="build" use="required" type="versionNumber" /> + </xs:complexType> + + <!-- type used for exec entries --> + <xs:complexType name="exec_params"> + <xs:attribute name="command" use="required" type="nonempty_token" /> + <xs:attribute name="arguments" use="optional" type="nonempty_token" /> + <xs:attribute name="background" use="optional" type="xs:boolean" /> + <xs:attribute name="startdir" use="optional" type="dumbPath" /> + <xs:attribute name="standalone" use="optional" type="xs:boolean" /> + <xs:attribute name="x11" use="optional" type="x11Param" /> + </xs:complexType> + + <!-- type used for tiles or descriptions, once in 'normal' version, once enforcing usage of en_US --> + <xs:complexType name="title_or_description"> + <xs:simpleContent> + <xs:extension base="nonempty_string"> + <xs:attribute name="lang" use="required" type="isoLangcode" /> + </xs:extension> + </xs:simpleContent> + </xs:complexType> + <xs:complexType name="title_or_description_enUS"> + <xs:simpleContent> + <xs:extension base="nonempty_string"> + <xs:attribute name="lang" use="required" type="isoLangcode_en_US" /> + </xs:extension> + </xs:simpleContent> + </xs:complexType> + + <!-- type used for referencing images --> + <xs:complexType name="image_entry"> + <xs:attribute name="src" use="required" type="dumbPath" /> + </xs:complexType> + + <!-- type for referencing manuals/readme docs --> + <xs:complexType name="information_entry"> + <xs:attribute name="name" use="required" type="nonempty_normalizedString" /> + <xs:attribute name="type" use="required" type="docType" /> + <xs:attribute name="src" use="required" type="dumbPath" /> + </xs:complexType> + + <!-- type used for the license information --> + <xs:complexType name="license_info"> + <xs:attribute name="name" use="required" type="nonempty_normalizedString" /> + <xs:attribute name="url" use="optional" type="xs:anyURI" /> + <xs:attribute name="sourcecodeurl" use="optional" type="xs:anyURI" /> + </xs:complexType> + + + + <!-- Combine the symple and complex types into the "real" PXML specification --> + + <xs:element name="PXML"> + <xs:complexType> + <xs:sequence> + <!-- specify the <package> tag with info about the complete package, information providable: + author + version + title(s) + description(s) + icon + --> + <xs:element name="package" minOccurs="1" maxOccurs="1"> + <xs:complexType> + <xs:all> + <!--Author info--> + <xs:element name="author" type="author_data" minOccurs="1" /> + <!--App version info--> + <xs:element name="version" type="app_version_info" minOccurs="1" /> + <!--Title--> + <xs:element name="titles" minOccurs="1"> + <xs:complexType> + <xs:sequence> + <xs:element name="title" type="title_or_description_enUS" minOccurs="1" maxOccurs="1" /> + <xs:element name="title" type="title_or_description" minOccurs="0" maxOccurs="unbounded" /> + </xs:sequence> + </xs:complexType> + </xs:element> + <!--Description--> + <xs:element name="descriptions" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="title" type="title_or_description_enUS" minOccurs="0" maxOccurs="1" /> + <xs:element name="description" type="title_or_description" minOccurs="0" maxOccurs="unbounded" /> + </xs:sequence> + </xs:complexType> + </xs:element> + <!--Icon--> + <xs:element name="icon" type="image_entry" minOccurs="0" /> + </xs:all> + <!--Package ID--> + <xs:attribute name="id" use="required" type="dumbFolderName" /> + </xs:complexType> + </xs:element> + <!-- specify the <application> tag with info about a single program + executable call + author + version (of the application) + osversion (min OS version supported) + title(s) (allowing compatibility to <HF6, too!) + description(s) (allowing compatibility to <HF6, too!) + icon + license + preview pictures + info/manual/readme entry + categories + associations to file types + clockspeed + --> + <xs:element name="application" minOccurs="1" maxOccurs="unbounded"> + <xs:complexType> + <xs:all> + <!--Execution params --> + <xs:element name="exec" type="exec_params" minOccurs="1" /> + <!--Author info--> + <xs:element name="author" type="author_data" minOccurs="1" /> + <!--App version info--> + <xs:element name="version" type="app_version_info" minOccurs="1" /> + <!--OS Version info--> + <xs:element name="osversion" type="os_version_info" minOccurs="0" /> + <!--Title--> + <!-- via <titles> element, used for HF6+ --> + <xs:element name="titles" minOccurs="1"> + <xs:complexType> + <xs:sequence> + <xs:element name="title" type="title_or_description_enUS" minOccurs="1" maxOccurs="1" /> + <xs:element name="title" type="title_or_description" minOccurs="0" maxOccurs="unbounded" /> + </xs:sequence> + </xs:complexType> + </xs:element> + <!--Title--> + <!-- via <title> element, only one for en_US allowed, meant for backwards compatibility with libpnd from <HF6 --> + <xs:element name="title" type="title_or_description_enUS" minOccurs="0" /> + <!--Description--> + <!-- via <descriptions> element, used for HF6+ --> + <xs:element name="descriptions" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="description" type="title_or_description_enUS" minOccurs="1" maxOccurs="1" /> + <xs:element name="description" type="title_or_description" minOccurs="0" maxOccurs="unbounded" /> + </xs:sequence> + </xs:complexType> + </xs:element> + <!--Description--> + <!-- via <description> element, only one for en_US allowed, meant for backwards compatibility with libpnd from <HF6 --> + <xs:element name="description" type="title_or_description_enUS" minOccurs="0" /> + <!--Icon--> + <xs:element name="icon" type="image_entry" minOccurs="0" /> + <!--License--> + <xs:element name="licenses" minOccurs="1"> + <xs:complexType> + <xs:sequence> + <xs:element name="license" type="license_info" minOccurs="1" maxOccurs="unbounded" /> + </xs:sequence> + </xs:complexType> + </xs:element> + <!--Preview pics--> + <xs:element name="previewpics" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="pic" type="image_entry" minOccurs="0" maxOccurs="unbounded" /> + </xs:sequence> + </xs:complexType> + </xs:element> + <!--Info (aka manual or readme entry)--> + <xs:element name="info" type="information_entry" minOccurs="0" /> + <!--Categories--> + <xs:element name="categories" minOccurs="1"> + <xs:complexType> + <xs:sequence> + <xs:element name="category" minOccurs="1" maxOccurs="unbounded"> + <xs:complexType> + <xs:sequence> + <xs:element name="subcategory" minOccurs="0" maxOccurs="unbounded"> + <xs:complexType> + <xs:attribute name="name" type="fdoSubCategory" /> + </xs:complexType> + </xs:element> + </xs:sequence> + <xs:attribute name="name" use="required" type="fdoCategory" /> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <!--Associations--> + <xs:element name="associations" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="association" type="association_data" maxOccurs="unbounded" /> + </xs:sequence> + </xs:complexType> + </xs:element> + <!--Clockspeed--> + <xs:element name="clockspeed" minOccurs="0"> + <xs:complexType> + <xs:attribute name="frequency" use="required" type="xs:positiveInteger" /> + </xs:complexType> + </xs:element> + </xs:all> + <!--AppID--> + <xs:attribute name="id" use="required" type="dumbFolderName" /> + <xs:attribute name="appdata" use="optional" type="dumbFolderName" /> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> +</xs:schema>
\ No newline at end of file diff --git a/backends/platform/openpandora/build/pnd_make.sh b/backends/platform/openpandora/build/pnd_make.sh index b19de87bb4..0c03e8154d 100755 --- a/backends/platform/openpandora/build/pnd_make.sh +++ b/backends/platform/openpandora/build/pnd_make.sh @@ -1,65 +1,321 @@ -#!/bin/sh +#!/bin/bash +# +# pnd_make.sh +# +# This script is meant to ease generation of a pnd file. Please consult the output +# when running --help for a list of available parameters and an explaination of +# those. +# +# Required tools when running the script: +# bash +# echo, cat, mv, rm +# mkisofs or mksquashfs (the latter when using the -c param!) +# xmllint (optional, only for validation of the PXML against the schema) -######adjust path of genpxml.sh if you want to use that "feture"##### -TEMP=`getopt -o p:d:x:i:c -- "$@"` +PXML_schema=$(dirname ${0})/PXML_schema.xsd +GENPXML_PATH=$(dirname ${0})/genpxml.sh -if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi +# useful functions ... +black='\E[30m' +red='\E[31m' +green='\E[32m' +yellow='\E[33m' +blue='\E[34m' +magenta='\E[35m' +cyan='\E[36m' +white='\E[37m' -eval set -- "$TEMP" -while true ; do - case "$1" in - -p) echo "PNDNAME set to $2" ;PNDNAME=$2;shift 2;; - -d) echo "FOLDER set to $2" ;FOLDER=$2;shift 2 ;; - -x) echo "PXML set to $2" ;PXML=$2;shift 2 ;; - -i) echo "ICON set to $2" ;ICON=$2;shift 2 ;; - -c) echo "-c set, will create compressed squasfs image instead of iso $2" ;SQUASH=1;shift 1 ;; - --) shift ; break ;; - *) echo "Error while parsing arguments! $2" ; exit 1 ;; - esac +check_for_tool() +{ + which $1 &> /dev/null + if [ "$?" -ne "0" ]; + then + cecho "ERROR: Could not find the program '$1'. Please make sure +that it is available in your PATH since it is required to complete your request." $red + exit 1 + fi +} + +cecho () # Color-echo. Argument $1 = message, Argument $2 = color +{ + local default_msg="No message passed." # Doesn't really need to be a local variable. + message=${1:-$default_msg} # Defaults to default message. + color=${2:-$black} # Defaults to black, if not specified. + echo -e "$color$message" + tput sgr0 # Reset to normal. + return +} + + +print_help() +{ + cat << EOSTREAM +pnd_make.sh - A script to package "something" into a PND. + +Usage: + $(basename ${0}) {--directory|-d} <folder> {--pndname|-p} <file> [{--compress-squashfs|-c}] + [{--genpxml} <file>] [{--icon|-i} <file>] [{--pxml|-x} <file>] + [{--schema|-s} <file>] [{--help|-h}] + + +Switches: + --compress-squashfs / -c Define whether or not the pnd should be compressed using + squashfs. If this parameter is selected, a compressed pnd + will be created. + + --directory / -d Sets the folder that is to be used for the resulting pnd + to <folder>. This option is mandatory for the script to + function correctly. + + --genpxml Sets the script used for generating a PXML file (if none + is available already) to <file>. Please make sure to either + provide a full path or prefix a script in the current folder + with './' so that the script can actually be executed. If + this variable is not specified, $GENPXML_PATH + will be used. + + --help / -h Displays this help text. + + --icon / -i Sets the icon that will be appended in the pnd to <file>. + + --pndname / -p Sets the output filename of the resulting pnd to <file>. + This option is mandatory for the script to function + correctly. + + --pxml / -x Sets the PXML file that is to be used to <file>. If you + neither provide a PXML file or set this entry to 'guess', + an existing 'PXML.xml' in your selected '--directory' + will be used, or the script $GENPXML_PATH + will be called to try to generate a basic PXML file for you. + + --schema / -s Sets the schema file, that is to be used for validation, + to <file. If this is not defined, the script will try to + use the file '$PXML_schema'. If this fails, + a warning is issued. + +If you select the option to create a compressed squashfs, a version >=4.0 of squashfs +is required to be available in your PATH. +EOSTREAM +} + + +# Parse command line parameters +while [ "${1}" != "" ]; do + if [ "${1}" = "--compress-squashfs" ] || [ "${1}" = "-c" ]; + then + SQUASH=1 + shift 1 + elif [ "${1}" = "--directory" ] || [ "${1}" = "-d" ]; + then + FOLDER=$2 + shift 2 + elif [ "${1}" = "--genpxml" ]; + then + GENPXML_PATH=$2 + shift 2 + elif [ "${1}" = "--help" ] || [ "${1}" = "-h" ]; + then + print_help + exit 0 + elif [ "${1}" = "--icon" ] || [ "${1}" = "-i" ]; + then + ICON=$2 + shift 2 + elif [ "${1}" = "--pndname" ] || [ "${1}" = "-p" ]; + then + PNDNAME=$2 + shift 2 + elif [ "${1}" = "--pxml" ] || [ "${1}" = "-x" ]; + then + PXML=$2 + shift 2 + elif [ "${1}" = "--schema" ] || [ "${1}" = "-f" ] + then + PXML_schema=$2 + shift 2 + else + cecho "ERROR: '$1' is not a known argument. Printing --help and aborting." $red + print_help + exit 1 + fi done -rnd=$RANDOM; # random number for genpxml and index$rnd.xml -#generate pxml if guess or empty -if [ ! $PXML ] || [ $PXML = "guess" ] && [ $PNDNAME ] && [ $FOLDER ]; then - PXMLtxt=$(/home/user/libpnd/pandora-libraries/testdata/scripts/genpxml.sh $FOLDER $ICON) - PXML=$FOLDER/PXML.xml - echo "$PXMLtxt" > $FOLDER/PXML.xml +# Generate a PXML if the param is set to Guess or it is empty. +if [ ! $PXML ] || [ $PXML = "guess" ] && [ $PNDNAME ] && [ $FOLDER ]; +then + if [ -f $FOLDER/PXML.xml ]; # use the already existing PXML.xml file if there is one... + then + PXML=$FOLDER/PXML.xml + PXML_ALREADY_EXISTING="true" + else + if [ -f $GENPXML_PATH ]; + then + $GENPXML_PATH --src $FOLDER --dest $FOLDER --author $USER + if [ -f $FOLDER/PXML.xml ]; + then + PXML_GENERATED="true" + else + cecho "ERROR: Generating a PXML file using '$GENPXML_PATH' failed. +Please generate a PXML file manually." $red + exit 1 + fi + else + cecho "ERROR: Could not find '$GENPXML_PATH' for generating a PXML file." $red + exit 1 + fi + fi fi -#check arguments -if [ ! $PNDNAME ] || [ ! $FOLDER ] || [ ! $PXML ]; then - echo " Usage: pnd_make.sh -p your.pnd -d folder/containing/your/app/ -x - your.pxml (or \"guess\" to try to generate it from the folder) -i icon.png" + +# Probe if required variables were set +echo -e +cecho "Checking if all required variables were set." $green +if [ ! $PNDNAME ] || [ ! $FOLDER ] || [ ! $PXML ]; +then + echo -e + cecho "ERROR: Not all required options were set! Please see the --help information below." $red + echo -e + print_help exit 1 +else + echo "PNDNAME set to '$PNDNAME'." +fi +# Check if the selected folder actually exists +if [ ! -d $FOLDER ]; +then + echo -e + cecho "ERROR: '$FOLDER' doesn't exist or is not a folder." $red + exit 1 +else + echo "FOLDER set to '$FOLDER'." +fi +# Check if the selected PXML file actually exists +if [ ! -f $PXML ]; +then + echo -e + cecho "ERROR: '$PXML' doesn't exist or is not a file." $red + exit 1 +else + if [ $PXML_ALREADY_EXISTING ]; + then + echo "You have not explicitly specified a PXML to use, but an existing file was +found. Will be using this one." + elif [ $PXML_GENERATED ]; + then + echo "A PXML file was generated for you using '$GENPXML_PATH'. This file will +not be removed at the end of this script because you might want to review it, adjust +single entries and rerun the script to generate a pnd with a PXML file with all the +information you want to have listed." + fi + echo "PXML set to '$PXML'." fi -if [ ! -d $FOLDER ]; then echo "$FOLDER doesnt exist"; exit 1; fi #check if folder actually exists -if [ ! -f $PXML ]; then echo "$PXML doesnt exist"; exit 1; fi #check if pxml actually exists -#make iso from folder -if [ ! $SQUASH ]; then - mkisofs -o $PNDNAME.iso -R $FOLDER +# Print the other variables: +if [ $ICON ]; +then + if [ ! -f $ICON ] + then + cecho "WARNING: '$ICON' doesn't exist, will not append the selected icon to the pnd." $red + else + echo "ICON set to '$ICON'." + USE_ICON="true" + fi +fi +if [ $SQUASH ]; +then + echo "Will use a squashfs for '$PNDNAME'." +fi + + +# Validate the PXML file (if xmllint is available) +# Errors and problems in this section will be shown but are not fatal. +echo -e +cecho "Trying to validate '$PXML' now. Will be using '$PXML_schema' to do so." $green +which xmllint &> /dev/null +if [ "$?" -ne "0" ]; +then + VALIDATED=false + cecho "WARNING: Could not find 'xmllint'. Validity check of '$PXML' is not possible!" $red else - if [ $(mksquashfs -version | awk '{if ($3 >= 4) print 1}') = 1 ]; then - echo "your squashfs version is older then version 4, please upgrade to 4.0 or later" + if [ ! -f "$PXML_schema" ]; + then + VALIDATED=false + cecho "WARNING: Could not find '$PXML_schema'. If you want to validate your +PXML file please make sure to provide a schema using the --schema option." $red + else + xmllint --noout --schema $PXML_schema $PXML + if [ "$?" -ne "0" ]; then VALIDATED=false; else VALIDATED=true; fi + fi +fi +# Print some message at the end about the validation in case the user missed the output above +if [ $VALIDATED = "false" ] +then + cecho "WARNING: Could not successfully validate '$PXML'. Please check the output +above. This does not mean that your pnd will be broken. Either you are not following the strict +syntax required for validation or you don't have all files/programs required for validating." $red +else + cecho "Your file '$PXML' was validated successfully. The resulting pnd should +work nicely with libpnd." $green +fi + + +# Make iso from folder +echo -e +cecho "Creating an iso file based on '$FOLDER'." $green +if [ $SQUASH ]; +then + check_for_tool mksquashfs + if [ $(mksquashfs -version | awk 'BEGIN{r=0} $3>=4{r=1} END{print r}') -eq 0 ]; + then + cecho "ERROR: Your squashfs version is older then version 4, please upgrade to 4.0 or later" $red exit 1 fi - mksquashfs -no-recovery -nopad $FOLDER $PNDNAME.iso + mksquashfs $FOLDER $PNDNAME.iso -nopad -no-recovery +else + check_for_tool mkisofs + mkisofs -o $PNDNAME.iso -R $FOLDER +fi + +# Check that the iso file was actually created before continuing +if [ ! -f $PNDNAME.iso ]; +then + cecho "ERROR: The temporary file '$PNDNAME.iso' could not be created. +Please check the output above for any errors and retry after fixing them. Aborting." $red + exit 1 fi -#append pxml to iso -cat $PNDNAME.iso $PXML > $PNDNAME + + +# Append pxml to iso +echo -e +cecho "Appending '$PXML' to the created iso file." $green +cat $PNDNAME.iso $PXML > $PNDNAME rm $PNDNAME.iso #cleanup -#append icon if specified -if [ $ICON ]; then # check if we want to add an icon - if [ ! -f $ICON ]; then #does the icon actually exist? - echo "$ICON doesnt exist" - else # yes + +# Append icon if specified and available +if [ $USE_ICON ]; +then + echo -e + cecho "Appending the icon '$ICON' to the pnd." $green mv $PNDNAME $PNDNAME.tmp cat $PNDNAME.tmp $ICON > $PNDNAME # append icon rm $PNDNAME.tmp #cleanup - fi fi -if [ $PXML = "guess" ];then rm $FOLDER/PXML.xml; fi #cleanup + +# Final message +echo -e +if [ -f $PNDNAME ]; +then + cecho "Successfully finished creating the pnd '$PNDNAME'." $green +else + cecho "There seems to have been a problem and '$PNDNAME' was not created. Please check +the output above for any error messages. A possible cause for this is that there was +not enough space available." $red + exit 1 +fi + + +#if [ $PXML = "guess" ];then rm $FOLDER/PXML.xml; fi #cleanup diff --git a/backends/platform/openpandora/build/runscummvm.sh b/backends/platform/openpandora/build/runscummvm.sh index 48d24a2b81..c641235219 100755 --- a/backends/platform/openpandora/build/runscummvm.sh +++ b/backends/platform/openpandora/build/runscummvm.sh @@ -11,4 +11,5 @@ mkdir saves mkdir runtime cd runtime -../bin/scummvm --fullscreen --gfx-mode=2x --config=../scummvm.config +../bin/scummvm --fullscreen --gfx-mode=2x --config=../scummvm.config --themepath=../data + diff --git a/backends/platform/openpandora/op-bundle.mk b/backends/platform/openpandora/op-bundle.mk index 163f4711ce..089430f43c 100755 --- a/backends/platform/openpandora/op-bundle.mk +++ b/backends/platform/openpandora/op-bundle.mk @@ -75,11 +75,10 @@ endif $(CP) $(libloc)/../arm-angstrom-linux-gnueabi/usr/lib/libFLAC.so.8.2.0 $(bundle_name)/scummvm/lib/libFLAC.so.8 - $(srcdir)/backends/platform/openpandora/build/pnd_make.sh -p $(bundle_name).pnd -d $(bundle_name)/scummvm -x $(bundle_name)/scummvm/data/PXML.xml -i $(bundle_name)/scummvm/icon/scummvm.png + $(srcdir)/backends/platform/openpandora/build/pnd_make.sh -p $(bundle_name).pnd -c -d $(bundle_name)/scummvm -x $(bundle_name)/scummvm/data/PXML.xml -i $(bundle_name)/scummvm/icon/scummvm.png $(CP) $(srcdir)/backends/platform/openpandora/build/README-PND.txt $(bundle_name) tar -cvjf $(bundle_name)-pnd.tar.bz2 $(bundle_name).pnd $(bundle_name)/README-PND.txt rm -R ./$(bundle_name) -# rm $(bundle_name).pnd .PHONY: op-bundle op-pnd diff --git a/backends/platform/sdl/macosx/appmenu_osx.h b/backends/platform/sdl/macosx/appmenu_osx.h new file mode 100755 index 0000000000..005414b789 --- /dev/null +++ b/backends/platform/sdl/macosx/appmenu_osx.h @@ -0,0 +1,32 @@ +/* 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 APPMENU_OSX_H +#define APPMENU_OSX_H + +#if defined(MACOSX) + +void replaceApplicationMenuItems(); + +#endif // MACOSX + +#endif diff --git a/backends/platform/sdl/macosx/appmenu_osx.mm b/backends/platform/sdl/macosx/appmenu_osx.mm new file mode 100755 index 0000000000..bb089a6b61 --- /dev/null +++ b/backends/platform/sdl/macosx/appmenu_osx.mm @@ -0,0 +1,110 @@ +/* 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. + * + */ + +// Disable symbol overrides so that we can use system headers. +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +#include "backends/platform/sdl/macosx/appmenu_osx.h" +#include "common/translation.h" + +#include <Cocoa/Cocoa.h> + +// Apple removed setAppleMenu from the header files in 10.4, +// but as the method still exists we declare it ourselves here. +// Yes, this works :) +@interface NSApplication(MissingFunction) +- (void)setAppleMenu:(NSMenu *)menu; +@end + +void replaceApplicationMenuItems() { + + // Code mainly copied and adapted from SDLmain.m + NSMenu *appleMenu; + NSMenu *windowMenu; + NSMenuItem *menuItem; + + // For some reason [[NSApp mainMenu] removeAllItems] doesn't work and crashes, so we need + // to remove the SDL generated menus one by one + [[NSApp mainMenu] removeItemAtIndex:0]; // Remove application menu + [[NSApp mainMenu] removeItemAtIndex:0]; // Remove "Windows" menu + + // Create new application menu + appleMenu = [[NSMenu alloc] initWithTitle:@""]; + + // Get current encoding +#ifdef USE_TRANSLATION + NSStringEncoding stringEncoding = CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding((CFStringRef)[NSString stringWithCString:(TransMan.getCurrentCharset()).c_str() encoding:NSASCIIStringEncoding])); +#else + NSStringEncoding stringEncoding = NSASCIIStringEncoding; +#endif + + // Add "About ScummVM" menu item + [appleMenu addItemWithTitle:[NSString stringWithCString:_("About ScummVM") encoding:stringEncoding] action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""]; + + // Add separator + [appleMenu addItem:[NSMenuItem separatorItem]]; + + // Add "Hide ScummVM" menu item + [appleMenu addItemWithTitle:[NSString stringWithCString:_("Hide ScummVM") encoding:stringEncoding] action:@selector(hide:) keyEquivalent:@"h"]; + + // Add "Hide Others" menu item + menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:[NSString stringWithCString:_("Hide Others") encoding:stringEncoding] action:@selector(hideOtherApplications:) keyEquivalent:@"h"]; + [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)]; + + // Add "Show All" menu item + [appleMenu addItemWithTitle:[NSString stringWithCString:_("Show All") encoding:stringEncoding] action:@selector(unhideAllApplications:) keyEquivalent:@""]; + + // Add separator + [appleMenu addItem:[NSMenuItem separatorItem]]; + + // Add "Quit ScummVM" menu item + [appleMenu addItemWithTitle:[NSString stringWithCString:_("Quit ScummVM") encoding:stringEncoding] action:@selector(terminate:) keyEquivalent:@"q"]; + + // Put application menu into the menubar + menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]; + [menuItem setSubmenu:appleMenu]; + [[NSApp mainMenu] addItem:menuItem]; + + // Tell the application object that this is now the application menu + [NSApp setAppleMenu:appleMenu]; + + + // Create new "Window" menu + windowMenu = [[NSMenu alloc] initWithTitle:[NSString stringWithCString:_("Window") encoding:stringEncoding]]; + + // Add "Minimize" menu item + menuItem = [[NSMenuItem alloc] initWithTitle:[NSString stringWithCString:_("Minimize") encoding:stringEncoding] action:@selector(performMiniaturize:) keyEquivalent:@"m"]; + [windowMenu addItem:menuItem]; + + // Put menu into the menubar + menuItem = [[NSMenuItem alloc] initWithTitle:[NSString stringWithCString:_("Window") encoding:stringEncoding] action:nil keyEquivalent:@""]; + [menuItem setSubmenu:windowMenu]; + [[NSApp mainMenu] addItem:menuItem]; + + // Tell the application object that this is now the window menu. + [NSApp setWindowsMenu:windowMenu]; + + // Finally give up our references to the objects + [appleMenu release]; + [windowMenu release]; + [menuItem release]; +} diff --git a/backends/platform/sdl/macosx/macosx.cpp b/backends/platform/sdl/macosx/macosx.cpp index 817f61e864..ddfc99570a 100644 --- a/backends/platform/sdl/macosx/macosx.cpp +++ b/backends/platform/sdl/macosx/macosx.cpp @@ -29,9 +29,12 @@ #include "backends/platform/sdl/macosx/macosx.h" #include "backends/mixer/doublebuffersdl/doublebuffersdl-mixer.h" +#include "backends/platform/sdl/macosx/appmenu_osx.h" #include "common/archive.h" +#include "common/config-manager.h" #include "common/fs.h" +#include "common/translation.h" #include "ApplicationServices/ApplicationServices.h" // for LSOpenFSRef #include "CoreFoundation/CoreFoundation.h" // for CF* stuff @@ -51,6 +54,15 @@ void OSystem_MacOSX::initBackend() { _mixerManager->init(); } +#ifdef USE_TRANSLATION + // We need to initialize the translataion manager here for the following + // call to replaceApplicationMenuItems() work correctly + TransMan.setLanguage(ConfMan.get("gui_language").c_str()); +#endif // USE_TRANSLATION + + // Replace the SDL generated menu items with our own translated ones on Mac OS X + replaceApplicationMenuItems(); + // Invoke parent implementation of this method OSystem_POSIX::initBackend(); } diff --git a/backends/platform/sdl/module.mk b/backends/platform/sdl/module.mk index e67bf859d6..f1afe37349 100644 --- a/backends/platform/sdl/module.mk +++ b/backends/platform/sdl/module.mk @@ -14,7 +14,8 @@ endif ifdef MACOSX MODULE_OBJS += \ macosx/macosx-main.o \ - macosx/macosx.o + macosx/macosx.o \ + macosx/appmenu_osx.o endif ifdef WIN32 diff --git a/backends/platform/sdl/ps3/ps3.cpp b/backends/platform/sdl/ps3/ps3.cpp index 16722ccdb7..33586ce693 100644 --- a/backends/platform/sdl/ps3/ps3.cpp +++ b/backends/platform/sdl/ps3/ps3.cpp @@ -21,7 +21,7 @@ */ #define FORBIDDEN_SYMBOL_EXCEPTION_mkdir -#define FORBIDDEN_SYMBOL_EXCEPTION_time_h //On IRIX, sys/stat.h includes sys/time.h +#define FORBIDDEN_SYMBOL_EXCEPTION_time_h // sys/stat.h includes sys/time.h #define FORBIDDEN_SYMBOL_EXCEPTION_unistd_h #include "common/scummsys.h" diff --git a/backends/platform/wince/README-WinCE.txt b/backends/platform/wince/README-WinCE.txt index 8f1262051a..87f6e78ffe 100644 --- a/backends/platform/wince/README-WinCE.txt +++ b/backends/platform/wince/README-WinCE.txt @@ -1,10 +1,15 @@ ScummVM Windows CE FAQ -Last updated: 2011-07-01 -Release version: 1.3.1 +Last updated: 2011-07-14 +Release version: x.x.x ------------------------------------------------------------------------ New in this version ------------------- +x.x.x: +- Changed default values for "high_sample_rate" & "FM_high_quality" to "true" as + most devices today are fast enough to handle this. It's still possible to set + this to "false" if you have a slower device. + 1.3.1: - Fix for Normal2xAspect scaler which was causing screen update issues in some games. @@ -361,14 +366,13 @@ Some parameters are specific to this port : Game specific sections (f.e. [monkey2]) - performance options * high_sample_rate bool Desktop quality (22 kHz) sound output if - set. The default is 11 kHz. - If you have a fast device, you can set this - to true to enjoy better sound effects and - music. + set. This is the default. + If you have a slow device, you can set this + to false to prevent lags/delays in the game. * FM_high_quality bool Desktop quality FM synthesis if set. Lower - quality otherwise. The default is low + quality otherwise. The default is high quality. You can change this if you have a - fast device. + slow device. * sound_thread_priority int Set the priority of the sound thread (0, 1, 2). Depending on the release, this is set to 1 internally (above normal). diff --git a/base/commandLine.cpp b/base/commandLine.cpp index a4fefc413a..6550f60670 100644 --- a/base/commandLine.cpp +++ b/base/commandLine.cpp @@ -184,8 +184,8 @@ void registerDefaults() { ConfMan.registerDefault("native_mt32", false); ConfMan.registerDefault("enable_gs", false); ConfMan.registerDefault("midi_gain", 100); -// ConfMan.registerDefault("music_driver", ???); + ConfMan.registerDefault("music_driver", "auto"); ConfMan.registerDefault("mt32_device", "null"); ConfMan.registerDefault("gm_device", "null"); @@ -662,7 +662,7 @@ static Common::Error listSaves(const char *target) { " ---- ------------------------------------------------------\n"); for (SaveStateList::const_iterator x = saveList.begin(); x != saveList.end(); ++x) { - printf(" %-4s %s\n", x->save_slot().c_str(), x->description().c_str()); + printf(" %-4d %s\n", x->getSaveSlot(), x->getDescription().c_str()); // TODO: Could also iterate over the full hashmap, printing all key-value pairs } } else { diff --git a/common/debug.cpp b/common/debug.cpp index 50f99753db..9c3a93e5a6 100644 --- a/common/debug.cpp +++ b/common/debug.cpp @@ -23,6 +23,7 @@ #include "common/debug-channels.h" #include "common/system.h" #include "common/textconsole.h" +#include "common/algorithm.h" #include <stdarg.h> // For va_list etc. diff --git a/common/hashmap.h b/common/hashmap.h index f2a4d843b8..347ac1fd25 100644 --- a/common/hashmap.h +++ b/common/hashmap.h @@ -106,8 +106,9 @@ private: HASHMAP_MEMORYPOOL_SIZE = HASHMAP_MIN_CAPACITY * HASHMAP_LOADFACTOR_NUMERATOR / HASHMAP_LOADFACTOR_DENOMINATOR }; - +#ifdef USE_HASHMAP_MEMORY_POOL ObjectPool<Node, HASHMAP_MEMORYPOOL_SIZE> _nodePool; +#endif Node **_storage; ///< hashtable of size arrsize. uint _mask; ///< Capacity of the HashMap minus one; must be a power of two of minus one @@ -128,12 +129,20 @@ private: #endif Node *allocNode(const Key &key) { +#ifdef USE_HASHMAP_MEMORY_POOL return new (_nodePool) Node(key); +#else + return new Node(key); +#endif } void freeNode(Node *node) { if (node && node != HASHMAP_DUMMY_NODE) +#ifdef USE_HASHMAP_MEMORY_POOL _nodePool.deleteChunk(node); +#else + delete node; +#endif } void assign(const HM_t &map); diff --git a/common/system.h b/common/system.h index 15fbe386b1..9b833c5b1a 100644 --- a/common/system.h +++ b/common/system.h @@ -154,9 +154,9 @@ protected: #if defined(USE_TASKBAR) /** - * No default value is provided for _savefileManager by OSystem. + * No default value is provided for _taskbarManager by OSystem. * - * @note _savefileManager is deleted by the OSystem destructor. + * @note _taskbarManager is deleted by the OSystem destructor. */ Common::TaskbarManager *_taskbarManager; #endif diff --git a/common/xmlparser.h b/common/xmlparser.h index 40c779b87e..d75dc0e4a9 100644 --- a/common/xmlparser.h +++ b/common/xmlparser.h @@ -31,6 +31,7 @@ #include "common/hashmap.h" #include "common/hash-str.h" #include "common/stack.h" +#include "common/memorypool.h" namespace Common { @@ -121,7 +121,6 @@ add_engine touche "Touche: The Adventures of the Fifth Musketeer" yes add_engine tsage "Ringworld: Revenge Of The Patriarch" no add_engine tucker "Bud Tucker in Double Trouble" yes - # # Default settings # @@ -2069,6 +2068,7 @@ if test -n "$_host"; then gamecube) _backend="wii" _build_scalers=no + _vkeybd=yes _mt32emu=no _port_mk="backends/platform/wii/wii.mk" add_line_to_config_mk 'GAMECUBE = 1' @@ -2283,6 +2283,7 @@ if test -n "$_host"; then wii) _backend="wii" _build_scalers=no + _vkeybd=yes _port_mk="backends/platform/wii/wii.mk" add_line_to_config_mk 'GAMECUBE = 0' add_line_to_config_h '#define AUDIO_REVERSE_STEREO' diff --git a/devtools/create_project/msvc10/create_project.vcxproj b/devtools/create_project/msvc10/create_project.vcxproj index 3d7f8fdd3d..40c515f26b 100644 --- a/devtools/create_project/msvc10/create_project.vcxproj +++ b/devtools/create_project/msvc10/create_project.vcxproj @@ -59,11 +59,11 @@ </Link> <PostBuildEvent> <Command>@echo off -xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\msvc10\ -xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\msvc9\ -xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\msvc8\ -xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\codeblocks\ -xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\iphone\</Command> +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc10\" +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc9\" +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc8\" +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\codeblocks\" +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\iphone\"</Command> </PostBuildEvent> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> @@ -84,10 +84,12 @@ xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\iphone\</Command> <TargetMachine>MachineX86</TargetMachine> </Link> <PostBuildEvent> - <Command>xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\msvc10\ -xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\msvc9\ -xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\msvc8\ -xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\codeblocks\</Command> + <Command>@echo off +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc10\" +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc9\" +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc8\" +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\codeblocks\" +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\iphone\"</Command> </PostBuildEvent> <PreBuildEvent> <Command> @@ -120,4 +122,4 @@ xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\codeblocks\</Command> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> </ImportGroup> -</Project>
\ No newline at end of file +</Project> diff --git a/devtools/create_project/scripts/postbuild.cmd b/devtools/create_project/scripts/postbuild.cmd index a5051d8228..dd52c0217c 100644 --- a/devtools/create_project/scripts/postbuild.cmd +++ b/devtools/create_project/scripts/postbuild.cmd @@ -23,23 +23,7 @@ if "%~5"=="" goto error_installer echo Copying data files
echo.
-REM xcopy /F /Y "%~1/AUTHORS" %~2 1>NUL 2>&1
-REM xcopy /F /Y "%~1/COPYING.GPL" %~2 1>NUL 2>&1
-REM xcopy /F /Y "%~1/COPYING" %~2 1>NUL 2>&1
-REM xcopy /F /Y "%~1/COPYING.LGPL" %~2 1>NUL 2>&1
-REM xcopy /F /Y "%~1/COPYRIGHT" %~2 1>NUL 2>&1
-REM xcopy /F /Y "%~1/NEWS" %~2 1>NUL 2>&1
-REM xcopy /F /Y "%~1/README" %~2 1>NUL 2>&1
-
-REM xcopy /F /Y "%~1/dists/engine-data/*.dat" %~2 1>NUL 2>&1
-REM xcopy /F /Y "%~1/dists/engine-data/*.tbl" %~2 1>NUL 2>&1
-REM xcopy /F /Y "%~1/dists/engine-data/*.cpt" %~2 1>NUL 2>&1
-REM xcopy /F /Y "%~1/gui/themes/*.zip" %~2 1>NUL 2>&1
-REM xcopy /F /Y "%~1/gui/themes/translations.dat" %~2 1>NUL 2>&1
-
-xcopy /F /Y "%~4/lib/%~3/SDL.dll" "%~2" 1>NUL 2>&1
-xcopy /F /Y "%~4/README-SDL" "%~2" 1>NUL 2>&1
-
+xcopy /F /Y "%~4/lib/%~3/SDL.dll" "%~2" 1>NUL 2>&1
xcopy /F /Y "%~1/backends/vkeybd/packs/vkeybd_default.zip" "%~2" 1>NUL 2>&1
if "%~5"=="0" goto done
diff --git a/devtools/credits.pl b/devtools/credits.pl index 602dfb6a60..a124314670 100755 --- a/devtools/credits.pl +++ b/devtools/credits.pl @@ -486,7 +486,7 @@ begin_credits("Credits"); add_person("Matthew Hoops", "clone2727", ""); add_person("Filippos Karapetis", "[md5]", ""); add_person("Paweł Kołodziejski", "aquadran", ""); - add_person("Walter van Niftrik", "waltervn", ""); + add_person("Walter van Niftrik", "waltervn", "(retired)"); add_person("Kari Salminen", "Buddha^", ""); add_person("Eugene Sandulenko", "sev", ""); add_person("David Symonds", "dsymonds", "(retired)"); @@ -609,7 +609,7 @@ begin_credits("Credits"); add_person("Max Horn", "Fingolfin", "(retired)"); add_person("Filippos Karapetis", "[md5]", ""); add_person("Martin Kiewitz", "m_kiewitz", ""); - add_person("Walter van Niftrik", "waltervn", ""); + add_person("Walter van Niftrik", "waltervn", "(retired)"); add_person("Willem Jan Palenstijn", "wjp", ""); add_person("Jordi Vilalta Prat", "jvprat", ""); add_person("Lars Skovlund", "lskovlun", ""); diff --git a/devtools/tasmrecover/tasm-recover b/devtools/tasmrecover/tasm-recover index 5f7a528a5b..54fc091f06 100755 --- a/devtools/tasmrecover/tasm-recover +++ b/devtools/tasmrecover/tasm-recover @@ -24,6 +24,7 @@ generator = cpp(context, "DreamGen", blacklist = [ 'readabyte', 'readoneblock', 'frameoutv', - 'modifychar' + 'modifychar', + 'lockmon' ]) generator.generate('dreamweb') #start routine diff --git a/dists/redhat/scummvm.spec b/dists/redhat/scummvm.spec index 777e0afc8a..cd51f45c0a 100644 --- a/dists/redhat/scummvm.spec +++ b/dists/redhat/scummvm.spec @@ -68,6 +68,8 @@ install -m644 -D dists/engine-data/queen.tbl %{buildroot}%{_datadir}/scummvm/que install -m644 -D dists/engine-data/sky.cpt %{buildroot}%{_datadir}/scummvm/sky.cpt install -m644 -D dists/engine-data/drascula.dat %{buildroot}%{_datadir}/scummvm/drascula.dat install -m644 -D dists/engine-data/teenagent.dat %{buildroot}%{_datadir}/scummvm/teenagent.dat +install -m644 -D dists/engine-data/hugo.dat %{buildroot}%{_datadir}/scummvm/hugo.dat +install -m644 -D dists/engine-data/toon.dat %{buildroot}%{_datadir}/scummvm/toon.dat desktop-file-install --vendor scummvm --dir=%{buildroot}/%{_datadir}/applications dists/scummvm.desktop %clean @@ -105,6 +107,8 @@ fi %{_datadir}/scummvm/lure.dat %{_datadir}/scummvm/drascula.dat %{_datadir}/scummvm/teenagent.dat +%{_datadir}/scummvm/hugo.dat +%{_datadir}/scummvm/toon.dat %{_mandir}/man6/scummvm.6* #------------------------------------------------------------------------------ diff --git a/dists/redhat/scummvm.spec.in b/dists/redhat/scummvm.spec.in index 13ce600d02..838a05411a 100644 --- a/dists/redhat/scummvm.spec.in +++ b/dists/redhat/scummvm.spec.in @@ -68,6 +68,8 @@ install -m644 -D dists/engine-data/queen.tbl %{buildroot}%{_datadir}/scummvm/que install -m644 -D dists/engine-data/sky.cpt %{buildroot}%{_datadir}/scummvm/sky.cpt install -m644 -D dists/engine-data/drascula.dat %{buildroot}%{_datadir}/scummvm/drascula.dat install -m644 -D dists/engine-data/teenagent.dat %{buildroot}%{_datadir}/scummvm/teenagent.dat +install -m644 -D dists/engine-data/hugo.dat %{buildroot}%{_datadir}/scummvm/hugo.dat +install -m644 -D dists/engine-data/toon.dat %{buildroot}%{_datadir}/scummvm/toon.dat desktop-file-install --vendor scummvm --dir=%{buildroot}/%{_datadir}/applications dists/scummvm.desktop %clean @@ -105,6 +107,8 @@ fi %{_datadir}/scummvm/lure.dat %{_datadir}/scummvm/drascula.dat %{_datadir}/scummvm/teenagent.dat +%{_datadir}/scummvm/hugo.dat +%{_datadir}/scummvm/toon.dat %{_mandir}/man6/scummvm.6* #------------------------------------------------------------------------------ diff --git a/dists/scummvm.rc b/dists/scummvm.rc index 55f9dfbc6c..9fa5489547 100644 --- a/dists/scummvm.rc +++ b/dists/scummvm.rc @@ -7,10 +7,13 @@ #define FILE 256 #define IDI_ICON 1001 #define IDI_COUNT 1002 +#define ID_GDF_XML __GDF_XML IDI_ICON ICON DISCARDABLE "icons/scummvm.ico" IDI_COUNT ICON DISCARDABLE "icons/count.ico" +ID_GDF_XML DATA "dists/win32/scummvm.gdf.xml" + scummmodern.zip FILE "gui/themes/scummmodern.zip" #ifdef USE_TRANSLATION translations.dat FILE "gui/themes/translations.dat" diff --git a/dists/scummvm.rc.in b/dists/scummvm.rc.in index 2fd3946cc5..b91e7ebb0c 100644 --- a/dists/scummvm.rc.in +++ b/dists/scummvm.rc.in @@ -7,10 +7,13 @@ #define FILE 256 #define IDI_ICON 1001 #define IDI_COUNT 1002 +#define ID_GDF_XML __GDF_XML IDI_ICON ICON DISCARDABLE "icons/scummvm.ico" IDI_COUNT ICON DISCARDABLE "icons/count.ico" +ID_GDF_XML DATA "dists/win32/scummvm.gdf.xml" + scummmodern.zip FILE "gui/themes/scummmodern.zip" #ifdef USE_TRANSLATION translations.dat FILE "gui/themes/translations.dat" diff --git a/dists/win32/plugins/Games.dll b/dists/win32/plugins/Games.dll Binary files differnew file mode 100644 index 0000000000..3a378b7064 --- /dev/null +++ b/dists/win32/plugins/Games.dll diff --git a/dists/win32/scummvm.gdf.xml b/dists/win32/scummvm.gdf.xml new file mode 100644 index 0000000000..1c50924e15 --- /dev/null +++ b/dists/win32/scummvm.gdf.xml @@ -0,0 +1,44 @@ +<?xml version="1.0"?> +<GameDefinitionFile xmlns:baseTypes="urn:schemas-microsoft-com:GamesExplorerBaseTypes.v1" xmlns="urn:schemas-microsoft-com:GameDescription.v1"> + <GameDefinition gameID="{F2475C5C-EA7C-41F0-A56D-1ABF7CFEA389}"> + <Name>ScummVM</Name> + <Description>ScummVM is a program which allows you to run certain classic graphical point-and-click adventure games, provided you already have their data files. The clever part about this: ScummVM just replaces the executables shipped with the games, allowing you to play them on systems for which they were never designed!</Description> + <ReleaseDate>2011-09-30</ReleaseDate> + <Genres> + <Genre>Adventure</Genre> + </Genres> + <Version> + <VersionFile path="scummvm.exe" /> + </Version> + <WindowsSystemPerformanceRating minimum="1.0" recommended="2.0" /> + <Developers> + <Developer URI="http://www.scummvm.org">The ScummVM Team</Developer> + </Developers> + <Publishers> + <Publisher URI="http://www.scummvm.org">The ScummVM Team</Publisher> + </Publishers> + <GameExecutables> + <GameExecutable path="scummvm.exe" /> + </GameExecutables> + <ExtendedProperties> + <GameTasks> + <Play> + <Primary> + <FileTask path="scummvm.exe" arguments="--no-console" /> + </Primary> + <Task index="1" name="Play (console)"> + <FileTask path="scummvm.exe" arguments="" /> + </Task> + </Play> + <Support> + <Task index="0" name="View README"> + <FileTask path="README.txt" arguments="" /> + </Task> + <Task index="1" name="ScummVM Website"> + <URLTask Link="http://www.scummvm.org" /> + </Task> + </Support> + </GameTasks> + </ExtendedProperties> + </GameDefinition> +</GameDefinitionFile>
\ No newline at end of file diff --git a/dists/win32/scummvm.nsi b/dists/win32/scummvm.nsi index 480f8f47ee..01a7e72afe 100644 --- a/dists/win32/scummvm.nsi +++ b/dists/win32/scummvm.nsi @@ -20,12 +20,20 @@ #!define _DEBUG #!define _INCLUDE_DATA_FILES +!define _ENABLE_GAME_EXPLORER +#!define _LOG_BUILD +!define _CONVERT_TEXT Name ScummVM # Included files !include MUI2.nsh +# Plugins +!ifdef _ENABLE_GAME_EXPLORER +!AddPluginDir "./plugins" +!endif + ######################################################################################### # Command line options ######################################################################################### @@ -221,6 +229,9 @@ Var StartMenuGroup # Installer sections ######################################################################################### Section "ScummVM" SecMain +!ifdef _LOG_BUILD + LogSet on +!endif SetOutPath $INSTDIR SetOverwrite on @@ -232,6 +243,7 @@ Section "ScummVM" SecMain File /oname=NEWS.txt "${top_srcdir}\NEWS" File /oname=README.txt "${top_srcdir}\README" +!ifdef _CONVERT_TEXT # Convert line endings Push "$INSTDIR\AUTHORS.txt" Call unix2dos @@ -245,6 +257,7 @@ Section "ScummVM" SecMain Call unix2dos Push "$INSTDIR\README.txt" Call unix2dos +!endif !ifdef _INCLUDE_DATA_FILES # Engine data @@ -271,6 +284,23 @@ Section "ScummVM" SecMain File "${staging_dir}\SDL.dll" WriteRegStr HKCU "${REGKEY}" InstallPath "$INSTDIR" ; Store installation folder + + #Register with game explorer +!ifdef _ENABLE_GAME_EXPLORER + Games::registerGame "$INSTDIR\scummvm.exe" + pop $0 + # This is for Vista only, for 7 the tasks are defined in the gdf xml + ${If} $0 != "0" + ${AndIf} $0 != "" + ${AndIf} $0 != "$INSTDIR\scummvm.exe" + CreateDirectory "$0\PlayTasks\0" + CreateShortcut "$0\PlayTasks\0\Play.lnk" "$INSTDIR\scummvm.exe" "--no-console" + CreateDirectory "$0\PlayTasks\1" + CreateShortcut "$0\PlayTasks\1\Play (console).lnk" "$INSTDIR\scummvm.exe" + CreateDirectory "$0\SupportTasks\0" + CreateShortcut "$0\SupportTasks\0\Home Page.lnk" "${URL}" + ${EndIf} +!endif SectionEnd # Write Start menu entries and uninstaller @@ -280,7 +310,8 @@ Section -post SecMainPost !insertmacro MUI_STARTMENU_WRITE_BEGIN Application SetShellVarContext all ; Create shortcuts in the all-users folder CreateDirectory "$SMPROGRAMS\$StartMenuGroup" - CreateShortCut "$SMPROGRAMS\$StartMenuGroup\$(^Name).lnk" $INSTDIR\$(^Name).exe "" "$INSTDIR\$(^Name).exe" 0 ; Create shortcut with icon + CreateShortCut "$SMPROGRAMS\$StartMenuGroup\$(^Name).lnk" $INSTDIR\$(^Name).exe "" "$INSTDIR\$(^Name).exe" 0 ; Create shortcut with icon + CreateShortCut "$SMPROGRAMS\$StartMenuGroup\$(^Name) (No console).lnk" $INSTDIR\$(^Name).exe "--no-console" "$INSTDIR\$(^Name).exe" 0 CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Readme.lnk" $INSTDIR\README.txt CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall $(^Name).lnk" $INSTDIR\uninstall.exe !insertmacro MUI_STARTMENU_WRITE_END @@ -334,6 +365,10 @@ Section -un.Main SecUninstall Delete /REBOOTOK $INSTDIR\translations.dat !endif +!ifdef _ENABLE_GAME_EXPLORER + Games::unregisterGame "$INSTDIR\scummvm.exe" +!endif + Delete /REBOOTOK $INSTDIR\scummvm.exe Delete /REBOOTOK $INSTDIR\SDL.dll SectionEnd @@ -374,6 +409,7 @@ FunctionEnd # Helper functions ######################################################################################### +!ifdef _CONVERT_TEXT ;------------------------------------------------------------------------------- ; strips all CRs and then converts all LFs into CRLFs ; (this is roughly equivalent to "cat file | dos2unix | unix2dos") @@ -426,3 +462,4 @@ unix2dos_done: Pop $0 Delete $0.U2D FunctionEnd +!endif diff --git a/dists/win32/scummvm.nsi.in b/dists/win32/scummvm.nsi.in index a87f5d6244..cba1e81e33 100644 --- a/dists/win32/scummvm.nsi.in +++ b/dists/win32/scummvm.nsi.in @@ -20,12 +20,20 @@ #!define _DEBUG #!define _INCLUDE_DATA_FILES +!define _ENABLE_GAME_EXPLORER +#!define _LOG_BUILD +!define _CONVERT_TEXT Name ScummVM # Included files !include MUI2.nsh +# Plugins +!ifdef _ENABLE_GAME_EXPLORER +!AddPluginDir "./plugins" +!endif + ######################################################################################### # Command line options ######################################################################################### @@ -221,6 +229,9 @@ Var StartMenuGroup # Installer sections ######################################################################################### Section "ScummVM" SecMain +!ifdef _LOG_BUILD + LogSet on +!endif SetOutPath $INSTDIR SetOverwrite on @@ -232,6 +243,7 @@ Section "ScummVM" SecMain File /oname=NEWS.txt "${top_srcdir}\NEWS" File /oname=README.txt "${top_srcdir}\README" +!ifdef _CONVERT_TEXT # Convert line endings Push "$INSTDIR\AUTHORS.txt" Call unix2dos @@ -245,6 +257,7 @@ Section "ScummVM" SecMain Call unix2dos Push "$INSTDIR\README.txt" Call unix2dos +!endif !ifdef _INCLUDE_DATA_FILES # Engine data @@ -271,6 +284,23 @@ Section "ScummVM" SecMain File "${staging_dir}\SDL.dll" WriteRegStr HKCU "${REGKEY}" InstallPath "$INSTDIR" ; Store installation folder + + #Register with game explorer +!ifdef _ENABLE_GAME_EXPLORER + Games::registerGame "$INSTDIR\scummvm.exe" + pop $0 + # This is for Vista only, for 7 the tasks are defined in the gdf xml + ${If} $0 != "0" + ${AndIf} $0 != "" + ${AndIf} $0 != "$INSTDIR\scummvm.exe" + CreateDirectory "$0\PlayTasks\0" + CreateShortcut "$0\PlayTasks\0\Play.lnk" "$INSTDIR\scummvm.exe" "--no-console" + CreateDirectory "$0\PlayTasks\1" + CreateShortcut "$0\PlayTasks\1\Play (console).lnk" "$INSTDIR\scummvm.exe" + CreateDirectory "$0\SupportTasks\0" + CreateShortcut "$0\SupportTasks\0\Home Page.lnk" "${URL}" + ${EndIf} +!endif SectionEnd # Write Start menu entries and uninstaller @@ -280,7 +310,8 @@ Section -post SecMainPost !insertmacro MUI_STARTMENU_WRITE_BEGIN Application SetShellVarContext all ; Create shortcuts in the all-users folder CreateDirectory "$SMPROGRAMS\$StartMenuGroup" - CreateShortCut "$SMPROGRAMS\$StartMenuGroup\$(^Name).lnk" $INSTDIR\$(^Name).exe "" "$INSTDIR\$(^Name).exe" 0 ; Create shortcut with icon + CreateShortCut "$SMPROGRAMS\$StartMenuGroup\$(^Name).lnk" $INSTDIR\$(^Name).exe "" "$INSTDIR\$(^Name).exe" 0 ; Create shortcut with icon + CreateShortCut "$SMPROGRAMS\$StartMenuGroup\$(^Name) (No console).lnk" $INSTDIR\$(^Name).exe "--no-console" "$INSTDIR\$(^Name).exe" 0 CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Readme.lnk" $INSTDIR\README.txt CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall $(^Name).lnk" $INSTDIR\uninstall.exe !insertmacro MUI_STARTMENU_WRITE_END @@ -334,6 +365,10 @@ Section -un.Main SecUninstall Delete /REBOOTOK $INSTDIR\translations.dat !endif +!ifdef _ENABLE_GAME_EXPLORER + Games::unregisterGame "$INSTDIR\scummvm.exe" +!endif + Delete /REBOOTOK $INSTDIR\scummvm.exe Delete /REBOOTOK $INSTDIR\SDL.dll SectionEnd @@ -374,6 +409,7 @@ FunctionEnd # Helper functions ######################################################################################### +!ifdef _CONVERT_TEXT ;------------------------------------------------------------------------------- ; strips all CRs and then converts all LFs into CRLFs ; (this is roughly equivalent to "cat file | dos2unix | unix2dos") @@ -426,3 +462,4 @@ unix2dos_done: Pop $0 Delete $0.U2D FunctionEnd +!endif diff --git a/doc/translations/README-translation_template.txt b/doc/QuickStart index ec43ebef60..ec43ebef60 100755..100644 --- a/doc/translations/README-translation_template.txt +++ b/doc/QuickStart diff --git a/doc/de/Liesmich b/doc/de/Liesmich new file mode 100644 index 0000000000..b5f16f4a88 --- /dev/null +++ b/doc/de/Liesmich @@ -0,0 +1,770 @@ +ScummVM – Liesmich-Datei +------------------------------------------------------------------------ + +Dieses Dokument ist eine auszugsweise Ãœbersetzung der englischen README-Datei. +Das Original-Dokument enthält viel mehr Informationen. Sollten Sie hier also +nicht das finden, was Sie benötigen und ein wenig Englisch können, sollten Sie +sich die englische README-Datei ansehen. + +Für weitere Informationen, Kompatibilitätslisten, Einzelheiten zu Spenden, die +neusten veröffentlichten Versionen, Fortschrittsberichte und mehr besuchen Sie +bitte die ScummVM-Website unter der Adresse: http://www.scummvm.org/ + + +Inhaltsverzeichnis: +------------------- +1.0) Einführung + * 1.1 Ãœber ScummVM + * 1.2 Schnellstart +2.0) Kontakt + * 2.1 Fehler berichten +3.0) Unterstützte Spiele + * 3.1 Kopierschutz + * 3.2 Hinweise zu Commodore64-Spielen + * 3.3 Hinweise zu Maniac Mansion NES + * 3.4 Hinweise zu Macintosh-Spielen + * 3.5 Hinweise zu Spielen auf mehren CDs + * 3.6 Hinweise zu The Curse of Monkey Island + * 3.7 Hinweise zu den Baphomets-Fluch-Spielen + * 3.8 Hinweise zu Beneath a Steel Sky + * 3.9 Hinweise zu Flight of the Amazon Queen + * 3.10 Hinweise zu Gobliiins + * 3.11 Hinweise zu Inherit the Earth: Quest for the Orb (Macintosh) + * 3.12 Hinweise zu Simon the Sorcerer 1 und 2 + * 3.13 Hinweise zu Floyd – Es gibt noch Helden + * 3.14 Hinweise zu The Legend of Kyrandia + * 3.15 Hinweise zum vorhersagenden Eingabedialog bei Sierras AGI-Spielen + + +1.0) Einführung: +---- ----------- + +1.1) Ãœber ScummVM: +---- ------------- +ScummVM ist ein Programm, welches es Ihnen ermöglicht, bestimmte klassische +Grafik-Adventure (unter anderem aus dem Point-and-Click-Bereich) zu spielen, +vorausgesetzt, Sie sind im Besitz der Dateien des Spiels. Der Trick dabei ist: +ScummVM ersetzt lediglich die Funktion der ausführbaren Dateien, die mit den +Spielen kamen, was ermöglicht, diese Spiele auf Systemen zu spielen, für welche +sie nie erstellt wurden! + +Ursprünglich wurde dieses Programm dafür entwickelt, um SCUMM-Spiele von +LucasArts auszuführen, wie beispielsweise Maniac Mansion, Monkey Island, Day of +the Tentacle oder Sam & Max. SCUMM steht als Abkürzung für „Script Creation +Utility for Maniac Mansion“ (deutsch etwa: Skripterstellungsdienstprogramm für +Maniac Mansion), was das erste Spiel von LucasArts war, für welches LucasArts +dieses System entworfen hatte. Und viel später verlieh es seinen Namen an +ScummVM (wobei „VM“ für „Virtuelle Maschine“ steht). + +Mit der Zeit wurde Unterstützung für viele Nicht-SCUMM-Spiele hinzugefügt und +ScummVM unterstützt nun auch viele AGI- und SCI-Spiele von Sierra (wie +beispielsweise King's Quest 1-6, Space Quest 1-5, ...), Discworld 1 und 2, Simon +the Sorcerer 1 und 2, Beneath A Steel Sky, Lure of the Temptress, Baphomets +Fluch I und II, Flight of the Amazon Queen, Gobliiins 1-3, die Adventure-Reihe +The Legend of Kyrandia, viele der SCUMM-Spiele für Kinder von Humongous +Entertainment (einschließlich der Spiele von Fritzi Fisch und Töff-Töff) und +viele mehr. Sie können eine vollständige Liste mit Einzelheiten einsehen, welche +Auskunft darüber gibt, welche Spiele unterstützt werden und wie gut. Gehen Sie +hierfür auf die Kompatibilitätsseite. ScummVM wird fortlaufend verbessert, also +schauen Sie öfter einmal vorbei. + +Unter den Systemen, mit denen Sie diese Spiele spielen können, befinden sich +normale Schreibtisch-Computer (mit den Betriebssystemen Windows, Linux, +Mac OS X, ...), Spielekonsolen (Dreamcast, Nintendo DS & Wii, PS2, PSP, ...), +Smartphones (Android, iPhone, PocketPC, Symbian ...) und einige weitere. + +Zurzeit befindet sich ScummVM immer noch stark in der Entwicklung. Seien Sie +sich bewusst, dass wir zwar versuchen, dass viele Spiele mit wenigen erheblichen +Fehlern durchgespielt werden können, aber es dennoch zu Abstürzen kommen kann +und wir keine Gewähr übernehmen. Davon abgesehen: Einige Spiele werden seit +längerer Zeit unterstützt und sollten in jeder neusten stabilen veröffentlichten +Version ohne größere Probleme laufen. Sie können sich einen Eindruck davon +verschaffen, wie gut jedes Spiel unter ScummVM läuft, indem Sie auf die +Kompatibilitätsseite schauen. Wenn Sie sich ein wenig im Internet umsehen, +können Sie feststellen, dass ScummVM sogar kommerziell genutzt wird, um einige +der unterstützen Spiele für moderne Plattformen wiederzuveröffentlichen. Dies +zeigt, dass mehrere Firmen mit der Qualität der Software zufrieden sind und wie +gut einige der Spiele mit Hilfe des Programms laufen. + +Wenn Ihnen ScummVM gefällt, können Sie uns gerne Geld spenden, indem Sie auf die +PayPal-Schaltfläche auf der ScummVM-Website klicken. Dies hilft uns dabei, +notwendige Dienstprogramme zu kaufen, um ScummVM einfacher und schneller zu +entwickeln. Wenn Sie nicht spenden können, dürfen Sie auch gerne einen Patch +beisteuern. + +1.2) Schnellstart: +---- ------------- +WICHTIG: In dieser kurzen Anleitung wird davon ausgegangen, dass Sie ScummVM auf +Deutsch benutzen. Standardmäßig wird ScummVM die Sprache Ihres Betriebssystems +verwenden. Wenn Sie ScummVM lieber auf Englisch verwenden möchten, benutzen Sie +bitte die Anleitung in der englischen README-Datei. + +Für die ungeduldigen unter den Anwendern ist hier in fünf einfachen Schritten +kurz beschrieben, wie man ScummVM lauffähig macht und das Programm verwendet. + +1. Laden Sie ScummVM unter der Adresse http://www.scummvm.org/downloads.php +herunter und installieren Sie es. + +2. Erstellen Sie ein Verzeichnis auf Ihrer Festplatte und kopieren Sie die +Dateien des Spiels vom Original-Datenträger in dieses Verzeichnis. Wiederholen +Sie diesen Vorgang für jedes Spiel, das Sie spielen möchten (es ist besser, für +jedes Spiel ein eigenes Verzeichnis zu verwenden). + +3. Starten Sie ScummVM. + +Sollte an diesem Punkt ScummVM auf Englisch statt auf Deutsch erscheinen, gehen +Sie wie folgt vor, um die Spracheinstellung zu ändern: +-Klicken Sie auf „Options“. +-Klicken Sie auf den rechten Pfeil in der Reiterleiste und wählen den Reiter + „Misc“ aus. +-Wählen Sie im Feld „GUI Language“ „Deutsch“ aus und klicken auf „OK“. +-Bestätigen Sie die erscheinende Nachricht, klicken auf „Quit“, um ScummVM zu + beenden, und starten dann das Programm erneut. + +Nun klicken Sie auf „Spiel hinzufügen“, wählen das Verzeichnis mit den Dateien +des Spiels aus (versuchen Sie nicht, die Dateien des Spiels selbst auszuwählen!) +und klicken Sie auf „Auswählen“. + +4. Ein Dialog sollte erscheinen, der Ihnen ermöglicht, verschiedene +Einstellungen vorzunehmen, sollten Sie dies wünschen (es sollte jedoch in +Ordnung sein, alles voreingestellt zu belassen). Bestätigen Sie diesen Dialog. + +5. Wählen Sie das Spiel aus der Liste aus, welches Sie spielen möchten, und +klicken Sie auf „Starten“. + +ScummVM behält die Spiele in der Liste, die Sie hinzufügen. Wenn Sie also +ScummVM schließen, werden beim nächsten Start alle Spiele, die Sie zuvor +hinzugefügt haben, in der Liste angezeigt. Sie können somit direkt zu Schritt 5 +übergehen, außer Sie wollen noch mehr Spiele hinzufügen. + +Tipp: Wenn Sie mehrere Spiele auf einmal hinzufügen möchten, drücken Sie die +Umschalt-Taste (Shift), bevor Sie auf „Spiel hinzufügen“ klicken. Diese +Schaltfläche wird somit ihren Text zu „Durchsuchen“ umändern und wenn Sie dann +auf diese klicken, werden Sie auch dazu aufgefordert, ein Verzeichnis +auszuwählen, nur dieses Mal wird ScummVM alle Unterverzeichnisse automatisch +nach unterstützen Spielen durchsuchen. + + +2.0) Kontakt: +---- -------- +Der einfachste Weg, um mit dem ScummVM-Team in Verbindung zu treten, ist, +Fehlerberichte einzusenden (siehe Abschnitt 2.1) oder durch Verwendung des +Forums unter der Adresse http://forums.scummvm.org . +Sie können ebenso der Mailing-Liste scummvm-devel beitreten und an diese E-Mails +versenden oder mit uns im IRC chatten (#scummvm unter irc.freenode.net). Bitte +fordern Sie uns nicht dazu auf, ein nicht unterstütztes Spiel zu unterstützen. +Lesen Sie zuerst die Seite FAQ (Häufig gestellte Fragen) auf unserer Website. +Bitte beachten Sie, dass die offizielle Sprache des Forums, der Mailing-Liste +und des Chats Englisch ist und keine andere Sprache dort verwendet werden +sollte. + + +2.1) Fehler berichten: +---- ----------------- +Um einen Fehler zu berichten, erstellen Sie bitte ein SourceForge-Konto und +folgen Sie dem Link „Bug Tracker“ auf der ScummVM-Website. Bitte stellen Sie +sicher, dass sich der Bug wiedererzeugen lässt und immer noch in der neusten +Version von SVN oder des Daily Builds auftritt. Bitte sehen Sie auch auf der +Kompatibilitätsliste der ScummVM-Website für dieses Spiel nach, um +sicherzustellen, dass das Problem nicht bereits bekannt ist: + + http://www.scummvm.org/compatibility_stable.php + +Bitte berichten Sie keine Fehler zu Spielen, die nicht als durchspielbar im +Bereich „Supported Games“ oder der Kompatibilitätsliste aufgelistet sind. +Wir -wissen-, dass diese Spiele Fehler aufweisen. + +Bitte liefern Sie folgende Informationen: + - ScummVM-Version (BITTE mit neuster Version von SVN oder des Daily Builds + testen) + - Einzelheiten zum Fehler, einschließlich Anweisungen, um den Fehler + hervorzurufen + - Sprache des Spiels (Deutsch, Englisch ...) + - Version des Spiels (Version mit Sprachausgabe [Talkie], + Diskettenversion, ...) + - Plattform und gegebenenfalls Compiler (Win32, Linux, FreeBSD, ...) + - Fügen Sie – wenn möglich - einen Speicherstand hinzu. + - Wenn dieser Fehler erst seit kurzem Auftritt, teilen Sie bitte die letzte + Version ohne den Fehler mit und die erste Version mit diesem Fehler. + Auf diese Weise können wir diesen schneller beseitigen, indem wir die + vorgenommen Veränderungen einsehen. + +Zum Schluss möchten wir Sie noch bitten, jeden Punkt einzeln zu berichten. Bitte +senden Sie nicht mehrere Punkte mit demselben Ticket ein, ansonsten wird es +schwierig, den Status jedes einzelnen Fehlers zu verfolgen. Denken Sie bitte +auch daran, dass alle Fehlerberichte in Englisch verfasst sein müssen. + + +3.0) Unterstützte Spiele: +---- -------------------- +Im Moment gelten folgende Spiele als funktionsfähig gemeldet und sollten bis zum +Ende spielbar sein: + +SCUMM-Spiele von LucasArts: + Maniac Mansion [maniac] + Zak McKracken and the Alien Mindbenders [zak] + Indiana Jones and the Last Crusade [indy3] + Loom [loom] + The Secret of Monkey Island [monkey] + Monkey Island 2: LeChuck's Revenge [monkey2] + Indiana Jones and the Fate of Atlantis [atlantis] + Day of the Tentacle [tentacle] + Sam & Max Hit the Road [samnmax] + Vollgas [ft] + The Dig [dig] + The Curse of Monkey Island [comi] + +AGI-Spiele von Sierra: + The Black Cauldron [bc] + Gold Rush! [goldrush] + King's Quest I [kq1] + King's Quest II [kq2] + King's Quest III [kq3] + King's Quest IV [kq4] + Leisure Suit Larry in the Land of the + Lounge Lizards [lsl1] + Mixed-Up Mother Goose [mixedup] + Manhunter 1: New York [mh1] + Manhunter 2: San Francisco [mh2] + Police Quest I: In Pursuit of the Death + Angel [pq1] + Space Quest I: The Sarien Encounter [sq1] + Space Quest II: Vohaul's Revenge [sq2] + Erstellte Spiele von Fans [agi-fanmade] + +AGOS-Spiele von Adventuresoft/Horrorsoft: + Elvira - Mistress of the Dark [elvira1] + Elvira II - The Jaws of Cerberus [elvira2] + Personal Nightmare [pn] + Waxworks [waxworks] + Simon the Sorcerer 1 [simon1] + Simon the Sorcerer 2 [simon2] + Simon the Sorcerer's Game Pack + - Dämonen in meinem PC [dimp] + Simon the Sorcerer's Game Pack + - Jumble [jumble] + Simon the Sorcerer's Game Pack + - NoPatience [puzzle] + Simon the Sorcerer's Game Pack + - Swampy Adventures [swampy] + Floyd - Es gibt noch Helden [feeble] + +GOB-Spiele von Coktel Vision: + Bargon Attack [bargon] + Gobliiins [gob1] + Gobliins 2 [gob2] + Goblins 3 [gob3] + Lost in Time [lostintime] + Woodruff and the Schnibble of Azimuth [woodruff] + Ween: The Prophecy [ween] + +MADE-Spiele von Activision: + Leather Goddesses of Phobos 2 [lgop2] + Return to Zork [rtz] + Rodney's Funscreen [rodney] + The Manhole [manhole] + +Andere Spiele: + Beneath a Steel Sky [sky] + Baphomets Fluch [sword1] + Baphomets Fluch II: + Die Spiegel der Finsternis [sword2] + Cruise for a Corpse [cruise] + Discworld [dw] + Discworld 2: Vermutlich vermisst [dw2] + Draci Historie [draci] + Drascula: The Vampire Strikes Back [drascula] + Flight of the Amazon Queen [queen] + Future Wars [fw] + Erben der Erde: Die große Suche [ite] + Nippon Safes Inc. [nippon] + The Legend of Kyrandia [kyra1] + The Legend of Kyrandia: The Hand of Fate [kyra2] + The Legend of Kyrandia: Malcolm's Revenge [kyra3] + Touché: Die Abenteuer des fünften + Musketiers [touche] + +SCUMM-Spiele von Humongous Entertainment: + Backyard Baseball [baseball] + Backyard Baseball 2001 [baseball2001] + Backyard Football [football] + Big Thinkers First Grade [thinker1] + Big Thinkers Kindergarten [thinkerk] + Blue's 123 Time Activities [Blues123Time] + Blue's ABC Time Activities [BluesABCTime] + Blue's Art Time Activities [arttime] + Blue's Reading Time Activities [readtime] + Fatty Bear's Birthday Surprise [fbear] + Fatty Bear's Fun Pack [fbpack] + Fritzi Fisch und der verschwundene Schatz [freddi] + Fritzi Fisch und das Flossengespenst [freddi2] + Fritzi Fisch und der Fall der gestohlenen + Trompetenschnecke [freddi3] + Freddi Fisch und das Geheimnis + der Salzwasserschlucht [freddi4] + Freddi Fisch und das Rätsel + der Korallenbucht [freddicove] + Freddi Fish and Luther's Maze Madness [maze] + Freddi Fish and Luther's Water Worries [water] + Let's Explore the Airport with Buzzy [airport] + Let's Explore the Farm with Buzzy [farm] + Let's Explore the Jungle with Buzzy [jungle] + Pyjama Pit: Keine Angst im Dunkeln [pajama] + Pyjama Sam: Donner und Blitz + machen mir nix [pajama2] + Pyjama Sam 3: Süßigkeiten kriegen Saures [pajama3] + Pajama Sam's Lost & Found [lost] + Pajama Sam's Sock Works [socks] + Putt-Putt Joins the Parade [puttputt] + Putt-Putt Goes to the Moon [puttmoon] + Töff-Töff rettet den Zoo [puttzoo] + Töff-Töff reist durch die Zeit [putttime] + Töff-Töff und das große Rennen [puttrace] + Töff-Töff geht zum Zirkus [puttcircus] + Putt-Putt and Pep's Balloon-O-Rama [balloon] + Putt-Putt and Pep's Dog on a Stick [dog] + Putt-Putt & Fatty Bear's Activity Pack [activity] + Putt-Putt's Fun Pack [funpack] + SPY Fox: Das Milchkartell [spyfox] + SPY Fox: Operation Robobund [spyfox2] + SPY Fox: Alarm im Weltall [spyozon] + SPY Fox in Cheese Chase [chase] + SPY Fox in Hold the Mustard [mustard] + +Spiele von Living Books: + Aesop's Fables: The Tortoise and the Hare [tortoise] + Arthur's Birthday [arthurbday] + Arthur's Teacher Trouble [arthur] + Dr. Seuss's ABC [seussabc] + Green Eggs and Ham [greeneggs] + Harry and the Haunted House [harryhh] + Just Grandma and Me [grandma] + Little Monster at School [lilmonster] + Ruff's Bone [ruff] + Sheila Rae, the Brave [sheila] + Stellaluna [stellaluna] + The Berenstain Bears Get in a Fight [bearfight] + The Berenstain Bears in the Dark [beardark] + The New Kid on the Block [newkid] + +Die folgenden Spiele sollten geladen werden, sind aber noch nicht vollständig +spielbar. Spielen erfolgt auf eigenes Risiko. Bitte reichen Sie für diese Spiele +keine Fehlerberichte ein. +Wenn Sie über den neusten Stand bezüglich der Kompatibilität des Spiels erfahren +möchten, besuchen Sie unsere Website und schauen Sie in der Kompatibilitätsliste +nach. + + Backyard Baseball 2003 [baseball2003] + Backyard Football 2002 [football2002] + Backyard Soccer [soccer] + Backyard Soccer MLS [soccermls] + Backyard Soccer 2004 [soccer2004] + Blue's Birthday Adventure [BluesBirthday] + Blue's Treasure Hunt [BluesTreasureHunt] + Pajama Sam: Games to Play on Any Day [pjgames] + +Die folgenden Spiele basieren auf der SCUMM-Engine, werden aber (noch) nicht von +ScummVM unterstützt: + + Andere Spiele von Humongous Entertainment + +Seien Sie sich bitte bewusst, dass die Engines („Motoren“ der Spiele) Fehler +enthalten können und manche Funktionen möglicherweise fehlen, was es unmöglich +macht, das Spiel zu Ende zu spielen. Speichern Sie oft und bitte schicken Sie +englische Fehlerberichte ein (Anweisungen zum Senden von Fehlerberichten finden +Sie oben), wenn Sie einen solchen Fehler in einem „unterstützten“ Spiel +vorfinden. + + +3.1) Kopierschutz: +---- ------------- +Das ScummVM-Team duldet keine Spielepiraterie. Es gibt jedoch Fälle, in denen +die Spielefirmen (wie beispielsweise LucasArts) selbst „gecrackte“ +Ausführdateien in ihre Spiele gepackt haben -- in diesen Fällen beinhalten die +Dateien des Spiels immer noch die Kopierschutzskripte, aber der Interpreter +umgeht sie (ähnlich wie illegale gecrackte Versionen es tun können, nur dass es +hier der Spielehersteller getan hat). Es gibt für uns keinerlei Möglichkeit, den +Unterschied zwischen einer legitimen und einer illegalen Spieldatei zu erkennen, +also wird ScummVM bei Spielen, von denen wir wissen, dass eine gecrackte Version +des Orginalinterpreters zu irgendeinem Zeitpunkt verkauft wurde, immer den +Kopierschutz umgehen müssen. + +In einigen Fällen wird ScummVM immer noch den Kopierschutzbildschirm anzeigen. +Versuchen Sie, irgendeine Antwort einzugeben. Die Chancen stehen gut, dass sie +akzeptiert wird. + +ScummVM wird den Kopierschutz in folgenden Spielen überspringen: + + * Maniac Mansion + * Zak McKracken and the Alien Mindbenders + * Loom (EGA) + * The Secret of Monkey Island (VGA) + * Monkey Island 2: LeChuck's Revenge + * Beneath a Steel Sky + -- umgangen mit freundlicher Genehmigung von Revolution Software. + * Erben der Erde: Die große Suche (Diskettenversion) + -- umgangen mit freundlicher Genehmigung von Wyrmkeep Entertainment, + da er in allen CD-Versionen des Spiels umgangen wurde. + * Simon the Sorcerer 1 (Diskettenversion) + * Simon the Sorcerer 2 (Diskettenversion) + -- umgangen mit freundlicher Genehmigung von Adventure Soft, + da er in allen CD-Versionen des Spiels umgangen wurde. + * Waxworks + +3.2) Hinweise zu Commodore64-Spielen: +---- -------------------------------- +Sowohl Maniac Mansion als auch Zak McKracken laufen, aber Maniac Mansion ist +noch nicht spielbar. Benennen Sie einfach die D64-Datenträger um in +„maniac1.d64“ und „maniac2.d64“ und entsprechend „zak1.d64“ und „zak2.d64“, dann +sollte ScummVM in der Lage sein, das Spiel automatisch zu erkennen, wenn Sie auf +das richtige Verzeichnis zeigen. + +Alternativ können Sie „extract_mm_c64“ aus dem Tools-Paket verwenden, um die +Spieldateien zu extrahieren. Dann wird das Spiel jedoch nicht einwandfrei von +ScummVM automatisch erkannt und Sie müssen sicherstellen, dass Commodore64 als +Plattform eingestellt ist. Wir empfehlen, auf die viel einfachere Methode +zurückzugreifen, die im vorherigen Absatz beschrieben ist. + + +3.3) Hinweise zu Maniac Mansion NES: +---- ------------------------------- +Unterstützte Versionen sind Deutsch (G) [G=German], Englisch GB (E), Französisch +(F), Italienisch (I), Schwedisch (SW) und Englisch US (U). ScummVM benötigt nur +den PRG-Bereich und nicht die gesamte ROM-Datei, um das Spiel laufen zu lassen. + +Damit das Spiel funktioniert, müssen Sie die ersten 16 Bytes aus der ROM-Datei +entfernen, die Sie verwenden wollen. Das klappt mit jedem Hexeditor, solange Sie +mit diesem kopieren und einfügen können. Nachdem Sie die ROM-Datei mit dem +Hexeditor geöffnet haben, kopieren Sie alles von der zweiten Reihe (17. Byte) +bis zum Ende. Danach fügen Sie den kopierten Inhalt in eine neue Hexdatei ein. +Speichern Sie die neue Datei unter dem Namen „Maniac Mansion (XX).prg“, wobei XX +für die Sprachversion steht, die Sie verwenden wollen (G, E, F, I, SW oder U). +Die Größe der neuen Datei sollte genau 262144 Bytes betragen. + +Wenn Sie das Spiel manuell hinzufügen, stellen Sie sicher, dass die Plattform +auf NES eingestellt ist. + +Die häufigsten Fehler, die verhindern, dass das Spiel läuft: + + * Fehlerhafte Datei + * ROM extrahiert mit den Tools der Version 0.7.0 + * Sie versuchen, in ScummVM die VOLLE ROM-DATEI zu laden und nicht nur den + PRG-Bereich. + +Es ist auch möglich, die einzelnen LFL-Dateien aus dem PRG-Bereich zu +extrahieren. Um dies zu tun, verwenden Sie das Dienstprogramm „extract_mm_nes“ +aus dem Tools-Paket. + + +3.4) Hinweise zu Macintosh-Spielen: +---- ------------------------------ +Alle auf SCUMM basierenden Adventures von Lucasarts, mit Ausnahme von COMI, +existieren auch als Versionen für den Macintosh. ScummVM kann die meisten +(alle?) von diesen verwenden, jedoch ist in manchen Fällen zusätzliche Arbeit +erforderlich. Zuallererst: Wenn Sie keinen Macintosh dafür verwenden, könnte es +kompliziert werden, auf die CD- oder Diskettendaten zuzugreifen. Der Grund +hierfür ist, dass der Mac ein spezielles Datenträgerformat nutzt, welches sich +HFS nennt, und das andere Systeme normalerweise nicht unterstützen. Es gibt +jedoch zahlreiche kostenlose Tools, die es ermöglichen, einen solchen HFS- +Datenträger zu lesen. Z. B. „HFVExplorer“ für Windows und „hfsutils“ für Linux +und andere Betriebssysteme, die Unix ähnlich sind. + +Die meisten neueren Spiele für den Macintosh wurden nur mit einer einzigen +Spieldatei ausgeliefert (beachten Sie, dass in manchen Fällen diese Spieldatei +unsichtbar gemacht wurde und Sie somit zusätzliche Tools benötigen, um diese zu +kopieren). ScummVM ist in der Lage, eine solche Spieldatei direkt zu verwenden; +verweisen Sie ScummVM einfach auf das Verzeichnis, welches diese enthält und es +sollte klappen (so wie mit jedem anderen unterstützten Spiel). + +Wir stellen außerdem ein Tool mit dem Namen „extract_scumm_mac“ im Tools-Paket +zur Verfügung, um die Daten aus diesen Spieldateien zu extrahieren, aber dies +ist weder erforderlich noch wird es empfohlen. + +Für weitere Informationen dazu, wie Sie Macintosh-Spieldateien auf Ihre +Festplatte kopieren können, lesen Sie: + + http://wiki.scummvm.org/index.php/HOWTO-Mac_Games + + +3.5) Hinweise zu Spielen auf mehren CDs: +---- ----------------------------------- +Allgemein kann ScummVM nicht sehr gut mit Spielen auf mehreren CDs umgehen. Das +liegt daran, dass ScummVM annimmt, alles von einem Spiel in einem Verzeichnis +vorzufinden. Selbst wenn ScummVM einige Fälle berücksichtigt und den Anwender +dazu auffordert, die CD zu wechseln, so installierten die ursprünglichen +ausführbaren Dateien des Spiels normalerweise eine kleine Anzahl an Dateien auf +die Festplatte. Sofern diese Dateien nicht auf allen CDs vorgefunden werden +können, wird ScummVM Schwierigkeiten haben. + +Glücklicherweise hat ScummVM keine Probleme damit, die Spiele komplett von der +Festplatte aus laufen zu lassen, wenn Sie ein Verzeichnis mit der richtigen +Kombination der Dateien erstellen. Wenn eine Datei auf mehr als einer CD +vorkommt, ist es normalerweise egal, welche sie in das Verzeichnis +hineinkopieren. + + +3.6) Hinweise zu The Curse of Monkey Island: +---- --------------------------------------- +Für dieses Spiel benötigen Sie die Dateien comi.la0, comi.la1 und comi.la2. Die +Datei comi.la0 kann auf beiden CDs vorgefunden werden, ist aber auf beiden +identisch, womit es egal ist, welche der beiden Sie verwenden. + +Zusätzlich müssen Sie ein Unterverzeichnis namens „resource“ erstellen, das alle +Dateien des Unterverzeichnisses „resource“ auf –beiden- CDs beinhaltet. Einige +dieser Dateien lassen sich auf beiden CDs vorfinden, jedoch sind sie auch in +diesem Fall identisch. + + +3.7) Hinweise zu den Baphomets-Fluch-Spielen: +---- ---------------------------------------- +Die Anweisungen für die Baphomets-Fluch-Spiele sind für die ausverkauften +Software-Versionen, bei welchen sich jedes Spiel auf je zwei CDs befindet, da +diese am leichtesten erhältlich waren, als ScummVM Unterstützung für diese +Spiele erlangte. Wir hoffen, dass sie allgemein ausreichend ausführlich sind, um +für andere Ausgaben genauso hilfreich zu sein. + + +3.7.1) Zwischensequenzen der Baphomets-Fluch-Spiele: +------ --------------------------------------------- +Die Zwischensequenzen für die Baphomets-Fluch-Spiele haben eine kleine +Geschichte (schauen Sie im nächsten Abschnitt, wenn Sie interessiert sind), aber +im Großen und Ganzen müssen Sie nur die .SMK-Dateien aus den „SMACKS“- oder +„SMACKSHI“-Verzeichnissen auf den CDs in dasselbe Verzeichnis wie die anderen +Spieldateien kopieren. (Baphomets Fluch hat ein „SMACKSLO“-Verzeichnis mit +denselben Zwischensequenzen, aber diese sind von niedrigerer Qualität.) Sie +können sie auch in einem Unterverzeichnis namens „video“ ablegen, wenn Ihnen das +lieber ist. + +Einige Neuausgaben der Spiele, wie beispielsweise die PlayStation-Version, haben +keine Smacker-Videos. Revolution Software hat uns freundlicherweise erlaubt, die +Zwischensequenzen umgewandelt auf unserer Website als Download zur Verfügung zu +stellen. Siehe hierfür: + + http://www.scummvm.org/downloads.php + +Diese Zwischensequenzen werden im DXA-Format mit FLAC-Audio zur Verfügung +gestellt. Ihre Qualität ist durch die Verwendung verlustfreier Kompression +gleich wie im Originalspiel. Um diese Zwischensequenzen abspielen zu können, ist +eine Version von ScummVM erforderlich, die sowohl mit Unterstützung von FLAC als +auch zlib kompiliert wurde. + +Für Systeme, die zu langsam sind, um die Entschlüsselung von FLAC-Audio zu +handhaben, wird die Tonspur für diese Zwischensequenzen gesondert auch mit Ogg- +Vorbis-Audio angeboten. Um diese Zwischensequenzen mit Ogg-Vorbis-Audio +abspielen zu können, ist eine Version von ScummVM erforderlich, die sowohl mit +Unterstützung von libVorbis als auch zlib kompiliert wurde. + +Für Baphomets Fluch bieten wir auch ein Untertitel-Paket an. Entpacken Sie es +einfach und folgen Sie den Anweisungen in der liesmich.txt. (Baphomets Fluch II +hat bereits Untertitel; für diese ist keine zusätzliche Arbeit notwendig.) + + +3.7.2) Zwischensequenzen der Baphomets-Fluch-Spiele im Rückblick +------ --------------------------------------------------------- +Die Originalausgaben der Baphomets-Fluch-Spiele verwendeten das Smackerâ„¢-Format +der RAD Game Tools. Da RAD uns nicht die ältere Ur-Version dieses Formats +offenlegen wollte und uns aufforderte, es nicht mittels Reverse Engineering zu +rekonstruieren, musste eine alternative Lösung gefunden werden. + +In Baphomets Fluch II war es möglich, die Sprachausgabe ohne das Video +wiederzugeben. Dies blieb bis ScummVM 1.0.0 eine Ausweichmöglichkeit, war aber +nie die alleinige Lösung für eine stabile Veröffentlichung. + +In ScummVM 0.6.0 verwendeten wir MPEG, das einen zumutbaren Kompromiss zwischen +Größe und Qualität bot. In ScummVM 0.10.0 wurde dies durch DXA abgelöst (das +ursprünglich für Adventure Softs „Floyd – Es gibt noch Helden“ hinzugefügt +wurde). Dies gab uns die Möglichkeit, die Zwischensequenzen mit genau derselben +Qualität wie im Original anzubieten, zu dem Preis, dass die Dateien größer +waren. + +Schließlich wurde Anfang 2006 das Smacker-Format für das FFmpeg-Projekt mittels +Reverse Engineering rekonstruiert. Dank der harten Arbeit in diesem Projekt +unterstützt ScummVM nun die originalen Zwischensequenzen. Zur selben Zeit wurde +die MPEG-Unterstützung eingestellt. Vom technischen Standpunkt war das eine gute +Sache, da das Entschlüsseln von MPEG-Filmen mit vielen Schwierigkeiten verbunden +war und diese ohnehin nicht so gut aussahen wie Smacker- und DXA-Versionen. + + +3.7.3) Baphomets Fluch: +------ ---------------- +Für dieses Spiel benötigen Sie die Dateien aus dem Verzeichnis clusters von +beiden CDs. Für die Windows- und Macintosh-Versionen benötigen Sie auch die +Datei speech.clu aus dem Verzeichnis speech von beiden CDs. Da diese jedoch +nicht identisch sind, müssen Sie diese in speech1.clu und speech2.clu für CD 1 +und 2 entsprechend umbenennen. Die PlayStation-Version erfordert die Dateien +speech.tab, speech.dat, speech.lis, und speech.inf. + +Zusätzlich benötigen die Windows- und Macintosh-Versionen das Unterverzeichnis +„music“ mit allen Dateien der „music“-Unterverzeichnisse auf beiden CDs. Einige +dieser Dateien tauchen auf beiden CDs auf, aber in diesen Fällen sind sie +entweder identisch oder in einem Fall nahezu so identisch, dass es wenig +Unterschied macht. Die PlayStation-Version erfordert die Dateien tunes.dat und +tunes.tab. + + +3.7.4) Baphomets Fluch II: +------ ------------------- +Für dieses Spiel benötigen Sie die Dateien aus dem Verzeichnis clusters von +beiden CDs. (Ein paar von ihnen sind streng genommen eigentlich nicht notwendig, +aber diejenigen, über die Unsicherheit besteht, sind alle ziemlich klein.) +Sie müssen die Dateien speech.clu und music.clu umbenennen, und zwar in +speech1.clu, speech2.clu, music1.clu und music2.clu, sodass ScummVM weiß, welche +der Dateien von CD 1 und welche von CD 2 sind. Alle anderen Dateien, die in +beiden „clusters“-Verzeichnissen auftauchen, sind identisch. Verwenden Sie in +diesen Fällen die Datei, die Sie möchten. + +Zusätzlich brauchen Sie die Datei cd.inf und optional die Datei startup.inf aus +dem Verzeichnis sword2 von CD 1. + + +3.8) Hinweise zu Beneath a Steel Sky: +---- -------------------------------- +Beginnend mit ScummVM 0.8.0 benötigen Sie die zusätzliche Datei „SKY.CPT“, um +Beneath a Steel Sky laufen lassen. + +Diese Datei ist auf der Seite „Downloads“ der ScummVM-Website verfügbar. Sie +können sie entweder im Verzeichnis mit den anderen Spieldateien (SKY.DNR, +SKY.DSK) ablegen, in einem Extrapfad oder im Verzeichnis, in dem sich Ihre +ausführbare ScummVM-Datei befindet. + + +3.9) Hinweise zu Flight of the Amazon Queen: +---- --------------------------------------- +Um eine Nicht-Freeware-Version von Flight of the Amazon Queen zu verwenden (von +einer Original-CD), müssen Sie die Datei „queen.tbl“ (erhältlich von der Seite +„Downloads“ auf unserer Website) entweder im Verzeichnis mit der Spieldatei +„queen.1“ ablegen, in einem Extrapfad oder im Verzeichnis, in dem sich Ihre +ausführbare ScummVM-Datei befindet. + +Alternativ können Sie das Tool „compress_queen“ aus dem Tools-Paket verwenden, +um Ihre FOTAQ-Spieldatei neu „zusammenzubauen“, um die Tabellendatei für diese +spezielle Version miteinzubeziehen und somit die Laufzeit-Abhängigkeit von der +Datei „queen.tbl“ zu lösen. Dieses Tool kann auch die Sprachausgabe und +Soundeffekte mittels MP3, OGG oder FLAC komprimieren. + + +3.10) Hinweise zu Gobliiins: +----- ---------------------- +Die CD-Versionen der Gobliiins-Serie enthalten einen großen Audio-Titel, den Sie +extrahieren müssen (siehe Abschnitt über die Verwendung komprimierter Audio- +Dateien) sowie ins Spielverzeichnis kopieren, wenn Sie Musik im Spiel hören +möchten, ohne die CD die ganze Zeit im Laufwerk haben zu müssen. Die +Sprachausgabe ist auch in diesem Titel und ihre Lautstärke wird deshalb ebenso +über die Musiklautstärke-Regelung geändert. + + +3.11) Hinweise zu Inherit the Earth: Quest for the Orb (Macintosh): +----- ------------------------------------------------------------- +Um die Neuausgabe des Spiels für Mac OS X von Wyrmkeep laufen zu lassen, müssen +Sie die Daten von der CD auf die Festplatte kopieren. Wenn Sie an einem PC +arbeiten, lesen Sie hierfür: + + http://wiki.scummvm.org/index.php/HOWTO-Mac_Games + +Obwohl hier in erster Linie über SCUMM-Spiele gesprochen wird, findet das +Dienstprogramm „HFVExplorer“ Erwähnung, welches Sie benötigen, um die Dateien zu +extrahieren. Beachten Sie, dass Sie die Sprachausgabedaten aus „Inherit the +Earth Voices“ im selben Verzeichnis ablegen müssen wie die Spieldaten, die sich +an folgendem Ort befinden: + + Inherit the Earth.app/Contents/Resources + +Bei der alten Ausgabe für Mac OS 9 müssen Sie die Dateien im MacBinary-Format +kopieren, da sie sowohl Ressourcen- und Datenverzweigungen beinhalten sollten. +Kopieren Sie alle „ITE *“-Dateien. + + +3.12) Hinweise zu Simon the Sorcerer 1 und 2: +----- --------------------------------------- +Wenn Sie die Doppel-Version von Simon the Sorcerer 1 oder 2 auf CD haben, finden +Sie die Windows-Version im Hauptverzeichnis der CD und die DOS-Version im +DOS-Verzeichnis der CD. + + +3.13) Hinweise zu Floyd – Es gibt noch Helden: +----- ---------------------------------------- +Wenn Sie die Windows-Version von Floyd – Es gibt noch Helden haben, sind einige +Dinge zu beachten. + +Viele notwendige Dateien für das Spiel sind in einer InstallShield-Datei namens +data1.cab gespeichert, die ScummVM nicht entpacken kann. Sie müssen das +Original-Installationsprogramm oder i5comp verwenden, um die Inhalte dieser +Datei zu entpacken. Das Tool i5comp für die Dekompression kann durch Suchen im +Internet gefunden werden. + +Um die Sprachdateien in ScummVM zu verwenden, müssen sie nach dem Kopiervorgang +wie folgt umbenannt werden: +voices.wav von CD1 in voices1.wav +voices.wav von CD2 in voices2.wav +voices.wav von CD3 in voices3.wav +voices.wav von CD4 in voices4.wav + + +3.14) Hinweise zu The Legend of Kyrandia: +----- ----------------------------------- +Um The Legend of Kyrandia unter ScummVM laufen zu lassen, benötigen Sie die +Datei „kyra.dat“, welche auf der Seite „Downloads“ der ScummVM-Website gefunden +werden kann. + + +3.15) Hinweise zum vorhersagenden Eingabedialog bei Sierras AGI-Spielen: +----- ------------------------------------------------------------------ +Der vorhersagende Eingabedialog ist ein ScummVM-Hilfsmittel, um die englischen +Spiele der AGI-Engine (die offensichtlich Kommandozeilen-Eingabe erfordern) auf +Geräten laufen zu lassen, die eingeschränkte Tastatur-Unterstützung haben. Da es +mühsam ist, mit emulierten Tastaturen zu tippen, können in solchen Fällen +Befehle schnell und einfach über den vorhersagenden Eingabedialog eingegeben +werden. + +Um die vorhersagende Eingabe in AGI-Spielen zu aktivieren, müssen Sie die Datei +pred.dic in den Extrapfad von ScummVM oder in das Verzeichnis des Spiels +kopieren, das Sie spielen möchten. Dieses Wörterbuch wurde erstellt, indem alle +bekannten AGI-Spiele analysiert wurden, und enthält den maximalen Satz +gebräuchlicher Wörter. + +Wenn das Wörterbuch erkannt wurde, wird der vorhersagende Eingabedialog entweder +durch Klicken auf den Kommandozeilenbereich angezeigt (dort, wo auch immer eine +Tastatureingabe erforderlich ist, auch in Dialogfeldern) oder in einigen Ports +durch Drücken eines bestimmten Tastenkürzels. + +Der vorhersagende Eingabedialog funktioniert in drei Modi, zwischen denen mit +der Schaltfläche (*)Pre/123/Abc gewechselt werden kann. Die primäre +Eingabemethode ist der vorhersagende Modus (Pre), welcher der Worterkennung bei +„schnellem Tippen“ auf Mobilfunktelefonen ähnelt. Das Alphabet ist in neun +Gruppen unterteilt, die naturgemäß den neun Ziffern auf dem Ziffernblock +zugeteilt sind (0 ist die Leertaste). Um ein Wort einzugeben, drücken Sie einmal +die Ziffer der Gruppe, die den Buchstaben des Worts enthält, den Sie tippen +möchten, dann gehen Sie zum nächsten Buchstaben über. Um z. B. den Befehl „look“ +einzugeben, sollten Sie 5665 drücken. Während Sie schrittweise die Ziffernfolge +des beabsichtigten Wortes eingeben, wird auf das Wörterbuch zugegriffen, um +bekannte Wörter, die mit Ihrer Eingabe bis zu diesem Punkt übereinstimmen, zu +finden. Während Sie mehr und mehr Tasten drücken, läuft die Vorhersage auf das +richtige Wort zu. Das ist der Grund, warum das angezeigte Wort sich zwischen +einem Tastendruck drastisch verändern kann. Es gibt jedoch Fälle, in denen mehr +als ein Wort dieselbe Zahlenkombination teilen. Z. B. haben die Worte „quit“ und +„suit“ dieselbe Nummer, nämlich 7848. In diesen Fällen hilft die Schaltfläche +(#)next weiter. Durch ihre Betätigung können Sie durch die Liste der Wörter +schalten, welche denselben Zahlencode haben und schließlich das richtige Wort +akzeptieren, indem Sie die (0) für Leertaste oder OK drücken. + +Die zweite Eingabemethode (123) ist die numerische Eingabe: Jede Taste, die Sie +drücken, wird als tatsächliche Ziffer eingegeben. + +Die dritte Eingabemethode (Abc) ist die Multi-Tipp-Alpha-Eingabemthode. Dieser +Modus ist dazu gedacht, um freien Text einzugeben, ohne die Hilfe des +Wörterbuchschemas des vorhersagenden Modus (Pre). Der Text wird Buchstabe für +Buchstabe eingegeben. Für jeden Buchstaben drücken Sie zuerst die Ziffer der +Gruppe, die den Buchstaben beinhaltet, den Sie tippen wollen, dann verwenden Sie +die Schaltfläche (#)next, um durch die Buchstaben zu schalten, bis der richtige +erscheint, und wiederholen dies mit der nächsten Ziffer. Um z. B. das Wort +„look“ einzugeben, müssen Sie folgendes Drücken: 5##6##6##5# + +Der Dialog kann vollständig mit der Maus verwendet werden, aber ein paar +Maßnahmen wurden getroffen, um dessen Verwendung bei einigen ScummVM-Ports +komfortabler zu gestalten, indem naturgemäß dessen Funktionsweise dem +Ziffernblock zugewiesen wurde. Ebenso können die Schaltflächen mittels der +Pfeiltasten und der Eingabetaste gesteuert werden. + + +(Ãœbersetzung basiert auf README mit SHA1 ID: +eae06884b6c6da23b7932ceba65e435d9be6ef82) diff --git a/doc/de/Schnellstart b/doc/de/Schnellstart new file mode 100644 index 0000000000..dcefadb702 --- /dev/null +++ b/doc/de/Schnellstart @@ -0,0 +1,176 @@ +Dieses Dokument ist eine auszugsweise Ãœbersetzung der englischen REAMDE-Datei. +Das Original-Dokument enthält viel mehr Informationen. Sollten Sie hier also +nicht das finden, was Sie benötigen und ein wenig Englisch können, sollten Sie +sich die englische README-Datei ansehen. + +Für weitere Informationen, Kompatibilitätslisten, Einzelheiten zu Spenden, die +neusten veröffentlichten Versionen, Fortschrittsberichte und mehr besuchen Sie +bitte die ScummVM-Website unter der Adresse: http://www.scummvm.org/ + + +Inhaltsverzeichnis: +------------------ +1.0) Einführung + * 1.1 Ãœber ScummVM + * 1.2 Schnellstart +2.0) Kontakt + * 2.1 Fehler berichten + + +1.0) Einführung: +---- ------------- + +1.1) Ãœber ScummVM: +---- ------------- +ScummVM ist ein Programm, welches es Ihnen ermöglicht, bestimmte klassische +Grafik-Adventure (unter anderem aus dem Point-and-Click-Bereich) zu spielen, +vorausgesetzt, Sie sind im Besitz der Dateien des Spiels. Der Trick dabei ist: +ScummVM ersetzt lediglich die Funktion der ausführbaren Dateien, die mit den +Spielen kamen, was ermöglicht, diese Spiele auf Systemen zu spielen, für welche +sie nie erstellt wurden! + +Ursprünglich wurde dieses Programm dafür entwickelt, um SCUMM-Spiele von +LucasArts auszuführen, wie beispielsweise Maniac Mansion, Monkey Island, Day of +the Tentacle oder Sam & Max. SCUMM steht als Abkürzung für „Script Creation +Utility for Maniac Mansion“ (deutsch etwa: Skripterstellungsdienstprogramm für +Maniac Mansion), was das erste Spiel von LucasArts war, für welches LucasArts +dieses System entworfen hatte. Und viel später verlieh es seinen Namen an +ScummVM (wobei „VM“ für „Virtuelle Maschine“ steht). + +Mit der Zeit wurde Unterstützung für viele Nicht-SCUMM-Spiele hinzugefügt und +ScummVM unterstützt nun auch viele AGI- und SCI-Spiele von Sierra (wie +beispielsweise King's Quest 1-6, Space Quest 1-5, ...), Discworld 1 und 2, Simon +the Sorcerer 1 und 2, Beneath A Steel Sky, Lure of the Temptress, Baphomets +Fluch I und II, Flight of the Amazon Queen, Gobliiins 1-3, die Adventure-Reihe +The Legend of Kyrandia, viele der SCUMM-Spiele für Kinder von Humongous +Entertainment (einschließlich der Spiele von Fritzi Fisch und Töff-Töff) und +viele mehr. Sie können eine vollständige Liste mit Einzelheiten einsehen, welche +Auskunft darüber gibt, welche Spiele unterstützt werden und wie gut. Gehen Sie +hierfür auf die Kompatibilitätsseite. ScummVM wird fortlaufend verbessert, also +schauen Sie öfter einmal vorbei. + +Unter den Systemen, mit denen Sie diese Spiele spielen können, befinden sich +normale Schreibtisch-Computer (mit den Betriebssystemen Windows, Linux, +Mac OS X, ...), Spielekonsolen (Dreamcast, Nintendo DS & Wii, PS2, PSP, ...), +Smartphones (Android, iPhone, PocketPC, Symbian ...) und einige weitere. + +Zurzeit befindet sich ScummVM immer noch stark in der Entwicklung. Seien Sie +sich bewusst, dass wir zwar versuchen, dass viele Spiele mit wenigen erheblichen +Fehlern durchgespielt werden können, aber es dennoch zu Abstürzen kommen kann +und wir keine Gewähr übernehmen. Davon abgesehen: Einige Spiele werden seit +längerer Zeit unterstützt und sollten in jeder neusten stabilen veröffentlichten +Version ohne größere Probleme laufen. Sie können sich einen Eindruck davon +verschaffen, wie gut jedes Spiel unter ScummVM läuft, indem Sie auf die +Kompatibilitätsseite schauen. Wenn Sie sich ein wenig im Internet umsehen, +können Sie feststellen, dass ScummVM sogar kommerziell genutzt wird, um einige +der unterstützen Spiele für moderne Plattformen wiederzuveröffentlichen. Dies +zeigt, dass mehrere Firmen mit der Qualität der Software zufrieden sind und wie +gut einige der Spiele mit Hilfe des Programms laufen. + +Wenn Ihnen ScummVM gefällt, können Sie uns gerne Geld spenden, indem Sie auf die +PayPal-Schaltfläche auf der ScummVM-Website klicken. Dies hilft uns dabei, +notwendige Dienstprogramme zu kaufen, um ScummVM einfacher und schneller zu +entwickeln. Wenn Sie nicht spenden können, dürfen Sie auch gerne einen Patch +beisteuern. + +1.2) Schnellstart: +---- ------------- +WICHTIG: In dieser kurzen Anleitung wird davon ausgegangen, dass Sie ScummVM auf +Deutsch benutzen. Standardmäßig wird ScummVM die Sprache Ihres Betriebssystems +verwenden. Wenn Sie ScummVM lieber auf Englisch verwenden möchten, benutzen Sie +bitte die Anleitung in der englischen README-Datei. + +Für die ungeduldigen unter den Anwendern ist hier in fünf einfachen Schritten +kurz beschrieben, wie man ScummVM lauffähig macht und das Programm verwendet. + +1. Laden Sie ScummVM unter der Adresse http://www.scummvm.org/downloads.php +herunter und installieren Sie es. + +2. Erstellen Sie ein Verzeichnis auf Ihrer Festplatte und kopieren Sie die +Dateien des Spiels vom Original-Datenträger in dieses Verzeichnis. Wiederholen +Sie diesen Vorgang für jedes Spiel, das Sie spielen möchten (es ist besser, für +jedes Spiel ein eigenes Verzeichnis zu verwenden). + +3. Starten Sie ScummVM. + +Sollte an diesem Punkt ScummVM auf Englisch statt auf Deutsch erscheinen, gehen +Sie wie folgt vor, um die Spracheinstellung zu ändern: +-Klicken Sie auf „Options“. +-Klicken Sie auf den rechten Pfeil in der Reiterleiste und wählen den Reiter + „Misc“ aus. +-Wählen Sie im Feld „GUI Language“ „Deutsch“ aus und klicken auf „OK“. +-Bestätigen Sie die erscheinende Nachricht, klicken auf „Quit“, um ScummVM zu + beenden, und starten dann das Programm erneut. + +Nun klicken Sie auf „Spiel hinzufügen“, wählen das Verzeichnis mit den Dateien +des Spiels aus (versuchen Sie nicht, die Dateien des Spiels selbst auszuwählen!) +und klicken Sie auf „Auswählen“. + +4. Ein Dialog sollte erscheinen, der Ihnen ermöglicht, verschiedene +Einstellungen vorzunehmen, sollten Sie dies wünschen (es sollte jedoch in +Ordnung sein, alles voreingestellt zu belassen). Bestätigen Sie diesen Dialog. + +5. Wählen Sie das Spiel aus der Liste aus, welches Sie spielen möchten, und +klicken Sie auf „Starten“. + +ScummVM behält die Spiele in der Liste, die Sie hinzufügen. Wenn Sie also +ScummVM schließen, werden beim nächsten Start alle Spiele, die Sie zuvor +hinzugefügt haben, in der Liste angezeigt. Sie können somit direkt zu Schritt 5 +übergehen, außer Sie wollen noch mehr Spiele hinzufügen. + +Tipp: Wenn Sie mehrere Spiele auf einmal hinzufügen möchten, drücken Sie die +Umschalt-Taste (Shift), bevor Sie auf „Spiel hinzufügen“ klicken. Diese +Schaltfläche wird somit ihren Text zu „Durchsuchen“ umändern und wenn Sie dann +auf diese klicken, werden Sie auch dazu aufgefordert, ein Verzeichnis +auszuwählen, nur dieses Mal wird ScummVM alle Unterverzeichnisse automatisch +nach unterstützen Spielen durchsuchen. + + +2.0) Kontakt: +---- -------- +Der einfachste Weg, um mit dem ScummVM-Team in Verbindung zu treten, ist, +Fehlerberichte einzusenden (siehe Abschnitt 2.1) oder durch Verwendung des +Forums unter der Adresse http://forums.scummvm.org . +Sie können ebenso der Mailing-Liste scummvm-devel beitreten und an diese E-Mails +versenden oder mit uns im IRC chatten (#scummvm unter irc.freenode.net). Bitte +fordern Sie uns nicht dazu auf, ein nicht unterstütztes Spiel zu unterstützen. +Lesen Sie zuerst die Seite FAQ (Häufig gestellte Fragen) auf unserer Website. +Bitte beachten Sie, dass die offizielle Sprache des Forums, der Mailing-Liste +und des Chats Englisch ist und keine andere Sprache dort verwendet werden +sollte. + + +2.1) Fehler berichten: +---- ----------------- +Um einen Fehler zu berichten, erstellen Sie bitte ein SourceForge-Konto und +folgen Sie dem Link „Bug Tracker“ auf der ScummVM-Website. Bitte stellen Sie +sicher, dass sich der Bug wiedererzeugen lässt und immer noch in der neusten +Version von SVN oder des Daily Builds auftritt. Bitte sehen Sie auch auf der +Kompatibilitätsliste der ScummVM-Website für dieses Spiel nach, um +sicherzustellen, dass das Problem nicht bereits bekannt ist: + + http://www.scummvm.org/compatibility_stable.php + +Bitte berichten Sie keine Fehler zu Spielen, die nicht als durchspielbar im +Bereich „Supported Games“ oder der Kompatibilitätsliste aufgelistet sind. +Wir -wissen-, dass diese Spiele Fehler aufweisen. + +Bitte liefern Sie folgende Informationen: + - ScummVM-Version (BITTE mit neuster Version von SVN oder des Daily Builds + testen) + - Einzelheiten zum Fehler, einschließlich Anweisungen, um den Fehler + hervorzurufen + - Sprache des Spiels (Deutsch, Englisch ...) + - Version des Spiels (Version mit Sprachausgabe [Talkie], + Diskettenversion, ...) + - Plattform und gegebenenfalls Compiler (Win32, Linux, FreeBSD, ...) + - Fügen Sie – wenn möglich - einen Speicherstand hinzu. + - Wenn dieser Fehler erst seit kurzem Auftritt, teilen Sie bitte die letzte + Version ohne den Fehler mit und die erste Version mit diesem Fehler. + Auf diese Weise können wir diesen schneller beseitigen, indem wir die + vorgenommen Veränderungen einsehen. + +Zum Schluss möchten wir Sie noch bitten, jeden Punkt einzeln zu berichten. Bitte +senden Sie nicht mehrere Punkte mit demselben Ticket ein, ansonsten wird es +schwierig, den Status jedes einzelnen Fehlers zu verfolgen. Denken Sie bitte +auch daran, dass alle Fehlerberichte in Englisch verfasst sein müssen. diff --git a/doc/translations/fr/Lisezmoi.txt b/doc/fr/QuickStart_fr index 186f0cd24d..186f0cd24d 100755..100644 --- a/doc/translations/fr/Lisezmoi.txt +++ b/doc/fr/QuickStart_fr diff --git a/doc/he/bink-md5s.txt b/doc/he/bink-md5s.txt deleted file mode 100644 index 5cfcc1c4af..0000000000 --- a/doc/he/bink-md5s.txt +++ /dev/null @@ -1,28 +0,0 @@ -(soccer2004 russian cd) // uses bink but just for external three files -sev -F:\HEdev\scummsys\SPUTM\Src\SrcPWin\*.cpp -2808c81e388743998b3c7331501cc4dd Soccer2004.(a) -7e358891079c9f366184211d14707a70 Soccer2004.(b) -c4ffae9fac495475d6bc3343ccc8faf9 Soccer2004.HE0 -b6eae47432b9545d33d4d867cef0b4ae Soccer2004.he3 -c83971b2f2020bf68724df52c9ae70a8 soccer2004.he2 -212776c1a2dc3d44a393afc4611afbc3 soccer2004.he4 -8f70113f7c01f7bfe9f83f02749d449d soccer2004.he9 -5fba7c0899429399f944a0353307863c DATA/helogo.da2 -56ed9865373c4fe63e8986989ef75999 DATA/infogrames.da2 -678dc9831679dd3f09933d0e568f6d3c DATA/intro.da2 - -(soccer2004 cd) // uses bink but just for external three files -sev -F:\HEdev\scummsys\SPUTM\Src\SrcPWin\*.cpp -e10cb34c774852175134fe166a602012 Soccer2004.(a) -8acec50e5cd48830121a3b22a8bfaa46 Soccer2004.(b) -c4ffae9fac495475d6bc3343ccc8faf9 Soccer2004.HE0 -b6eae47432b9545d33d4d867cef0b4ae Soccer2004.he3 -c83971b2f2020bf68724df52c9ae70a8 soccer2004.he2 -212776c1a2dc3d44a393afc4611afbc3 soccer2004.he4 -8f70113f7c01f7bfe9f83f02749d449d soccer2004.he9 -5fba7c0899429399f944a0353307863c DATA/helogo.da2 -56ed9865373c4fe63e8986989ef75999 DATA/infogrames.da2 -678dc9831679dd3f09933d0e568f6d3c DATA/intro.da2 - diff --git a/doc/he/md5s.txt b/doc/he/md5s.txt deleted file mode 100644 index 5007298b26..0000000000 --- a/doc/he/md5s.txt +++ /dev/null @@ -1,2861 +0,0 @@ -$Id$ - -TODO khalek -* hfs data on puttputt -* hfs data on spyfox -* extract & md5sum from farm cd hfs - - Fatty Bear Demo.sea - - Putt-Putt Moon Demo.sea - - Putt-Putt's Demo.sea -* misc other bits - -TODO sev -* hfs data on all CDs - -(baseball cd hfs) -Joachim -5494820d943b126282b31a7d00645400 BaseBall -cf8d13446ec6cb6222287a925fd47c1d BaseBall (0) -a37e1eb72b969d1461075b7f3d9dd323 BaseBall (1) -c37abed5add924975fad0df9417a8885 BaseBall (2) -cb029eb006c1758aa992e28af7e036db BaseBall (4) -91b6158bc7ec68da700f90e0fabab4b8 BaseBall (9) -d41d8cd98f00b204e9800998ecf8427e BaseBall (r) - -(baseball cd) -sev, Joachim -D:\Scummsys.90\sputm.90\*.c - -c0c0934580cde95879bef0b6a5a49c29 BASEBALL.D32 -58843bf6425883bbe143b96d11d56582 BASEBALL.EXE -cf8d13446ec6cb6222287a925fd47c1d BASEBALL.HE0 -a37e1eb72b969d1461075b7f3d9dd323 BASEBALL.HE1 -c37abed5add924975fad0df9417a8885 BASEBALL.HE2 -cb029eb006c1758aa992e28af7e036db BASEBALL.HE4 -91b6158bc7ec68da700f90e0fabab4b8 BASEBALL.HE9 -7989c98adce2b84cd710818c950616ac BASEBALL.W32 -57a68828de21e1afa208d0a5ea2fdf92 BASEBALL.X32 - - -(baseball2001 cd hfs) -kirben -??? - -(baseball2001 cd) -kirben -??? - -(bb2demo cd hfs) -khalek, sev -??? - -(humongous ftp) -2000-05-01 16:09 bb2demo.W32 -khalek, sev -C:\Dev\Project\SPUTM\Src\*.cpp -0b38fda342fdaa5e206b2a82c8ab6b9b bb2demo.(a) -a194f15f51ee62badab74b9e7da97693 bb2demo.HE0 -04862d3b91c49585400f1021bdb9faa1 bb2demo.he2 -0b3a9ff634f2fabb695358aa591154b3 bb2demo.he4 -17255b19a57a1ba0c35802b1b01792f7 BB2demo.HE9 -04770d822d0e78cf13bbf1870de3528b bb2demo.W32 - -(baseball2003 cd hfs) -sev -??? - -(baseball2003 cd) -sev -c:\Build\SRC\SPUTM\Src\SrcPWin\*.cpp -e0ea75ae94e527652ebd56b26140998c baseball2003.(a) -324f57a63fd20746195810b61a82b711 baseball2003.(b) -ba5635a315af707462b7681189287832 Baseball2003.exe -efe0a04a703e765ebebe92b6c8aa6b86 baseball2003.HE0 -c47186351316e17552532e6c31bf951a baseball2003.he2 -63d581c9548045ee8bc90633f4d123da baseball2003.he3 -fe816c17a87ed5420f1440c85e34f72e baseball2003.he4 -7f06715731111bfe639cde435ec3b650 baseball2003.he9 -b2e1d0e25ed9dbe0ea47ef1a5204ac4a DATA/infogrames.da2 -755a5cf5515610e30370a0afb7d1bc7b DATA/intro.da2 - -(football cd hfs) -Joachim -b1376bcd9c9addb7ffec43455f41f9db Football -7fc6cdb46b4c9d384c52327f4bca6416 FootBall (0) -6c33bde70c28c2eac78de8b9f3add1b4 FootBall (2) -8d02e9002b8033c00bbaf3d71bb695cc FootBall (4) -435ae8ebf6998b1ea395a5989457985f FootBall (a) -7df3c5eb3575aef947729213d6c3a877 FootBall (b) -7c44b542163266658a6110fd03973e6c Football (i) -d41d8cd98f00b204e9800998ecf8427e FootBall (r) -c9ca805103de1888a331a98f98bab22a football (u) - -(football cd) -sev, Joachim -C:\Dev\Project\SPUTM\Src\*.cpp - -435ae8ebf6998b1ea395a5989457985f FOOTBALL.(A) -7df3c5eb3575aef947729213d6c3a877 FOOTBALL.(B) -ccca9a823d117afb1a882fd707586bf0 FOOTBALL.D32 -b9e149d859b6b4ab1906ea670c4c7449 football.esk -af00c36fe744362cb60349f61db78e16 Football.exe -7fc6cdb46b4c9d384c52327f4bca6416 FOOTBALL.HE0 -6c33bde70c28c2eac78de8b9f3add1b4 FOOTBALL.HE2 -8d02e9002b8033c00bbaf3d71bb695cc football.he4 -a7e708342776af913fb70c842310379f football.mmz -e03725ba7069e7a94c28168b70dc99c4 FOOTBALL.R32 -07656b959c7febb6359c8de5fd6b6f76 FOOTBALL.U32 -1671f9302d4eca3bfcccc7d68d75d42a FOOTBALL.W32 - - -(pajama3 hfs) -Joachim -51c909630d8ca434c6e1dfe070a15792 Football Demo -425205754fa749f4f0b0dd9d09fa45fd FootBall Demo (0) -bf65bf5fbfd26a63f7bd32437a960667 FootBall Demo (2) -9e53fbcf1061636d3d192c786c4e3b7b FootBall Demo (4) -b79809888128b1d31080664487c8fc5e FootBall Demo (a) -d41d8cd98f00b204e9800998ecf8427e Football Demo (i) -d41d8cd98f00b204e9800998ecf8427e FootBall Demo (r) -c9ca805103de1888a331a98f98bab22a Football Demo (u) - -(pajama3 cd) -Joachim -b79809888128b1d31080664487c8fc5e footdemo.(a) -ccca9a823d117afb1a882fd707586bf0 footdemo.d32 -afd8621bd60d686ebc97ef259a6f0fe0 footdemo.exe -425205754fa749f4f0b0dd9d09fa45fd footdemo.HE0 -bf65bf5fbfd26a63f7bd32437a960667 footdemo.he2 -9e53fbcf1061636d3d192c786c4e3b7b footdemo.he4 -07656b959c7febb6359c8de5fd6b6f76 FOOTDEMO.U32 - -(puttsfunshop hfs/samsfunshop hfs/freddisfunshop hfs/freddicove hfs) -Joachim -51c909630d8ca434c6e1dfe070a15792 Football Demo -5bd335265a61caa3d78956ad9f88ba23 FootBall Demo (0) -bf65bf5fbfd26a63f7bd32437a960667 FootBall Demo (2) -9e53fbcf1061636d3d192c786c4e3b7b FootBall Demo (4) -bb6ec9a3a2a016b239367c2b26d9ee3b FootBall Demo (a) -d41d8cd98f00b204e9800998ecf8427e Football Demo (i) -d41d8cd98f00b204e9800998ecf8427e FootBall Demo (r) -c9ca805103de1888a331a98f98bab22a Football Demo (u) - -(putsfunshop cd/pajama3 cd/spyozon cd/freddicove cd/freddisfunshop cd/samsfunshop cd/pajama win cd) -sev, Joachim (Comment by Joachim: this version is not on the pajama3 cd for me, see above) -C:\Dev\Project\SPUTM\Src\*.cpp -bb6ec9a3a2a016b239367c2b26d9ee3b FOOTDEMO.(A) -ccca9a823d117afb1a882fd707586bf0 footdemo.d32 -afd8621bd60d686ebc97ef259a6f0fe0 footdemo.exe -5bd335265a61caa3d78956ad9f88ba23 FOOTDEMO.HE0 -bf65bf5fbfd26a63f7bd32437a960667 footdemo.he2 -9e53fbcf1061636d3d192c786c4e3b7b footdemo.he4 -07656b959c7febb6359c8de5fd6b6f76 FOOTDEMO.U32 - -(football demo hfs) -khalek -??? - -(football demo) -khalek -??? - -(football2002 cd hfs) // uses Bink as external files. 137 files -Joachim -4bfe515242f8ee4cc01b9fc4cf52b29a Football 2002 -d0549508a06bbb9f99ed19c9e97891f3 Football 2002 (0) -7c6f5da8f9d223942ff387c3b3b1262a Football 2002 (2) -eded7062b612284a62df6be9e37e8d9e Football 2002 (3) -5f22d1edf87e08f151c93726684d47a5 Football 2002 (4) -b81d20adb6371ed620fedcc0156c6fb7 Football 2002 (a) -1e45c754359ca021d50cc6776f3240a6 Football 2002 (b) -4017d76fa35c60e64011d333443dfa9c Football 2002 (i) -932e34469fd78234fff755a22960114d football 2002 (u) - -(football2002 cd) // uses Bink as external files. 137 files -c:\SRC_RELEASE\SPUTM\Src\SrcPWin\*.cpp -Joachim -b81d20adb6371ed620fedcc0156c6fb7 Football2002.(a) -1e45c754359ca021d50cc6776f3240a6 Football2002.(b) -7894dd82c874b535dc8acadef0950be4 Football2002.exe -d0549508a06bbb9f99ed19c9e97891f3 Football2002.HE0 -7c6f5da8f9d223942ff387c3b3b1262a Football2002.HE2 -eded7062b612284a62df6be9e37e8d9e Football2002.HE3 -5f22d1edf87e08f151c93726684d47a5 Football2002.HE4 - -(football2002 cd hfs) -??? - -(football2002 cd) // uses Bink as external files. 137 files -2001-09-11 14:22 football2002.exe -khalek (Comment by Joachim: I completed the deatils with details from above, I hope this is right) -C:\SRC_RELEASE\SPUTM\Src\SrcPWin\*.cpp -b81d20adb6371ed620fedcc0156c6fb7 Football2002.(a) -20aca400df5f580e4d3c019c3386d361 Football2002.(b) -2234bbc4d12a09fadf8540343eb1c00e football2002.exe -2e85f7aa054930c692a5b1bed1dfc295 Football2002.HE0 -7c6f5da8f9d223942ff387c3b3b1262a Football2002.HE2 -eded7062b612284a62df6be9e37e8d9e Football2002.HE3 -5f22d1edf87e08f151c93726684d47a5 Football2002.HE4 - -(soccer cd hfs) -Joachim -462a01a55236b1dc5aa3ea543bbfc904 Soccer -701246819d1a70573f41bf33fc19214f Soccer (0) -6b8840d83784dbceb44f9d8694fce9d4 Soccer (2) -b50ac4df3a13b7ccc73e68dae5851d36 Soccer (4) -6a89ce2925a36a1d9e0d9e9f7060c533 Soccer (9) -a70431a271fd64eb958bab0a75b9db5b Soccer (A) -d41d8cd98f00b204e9800998ecf8427e Soccer (r) -8605a367b4d66e756ccc00c8b6a22e0b Soccer (u) - -(soccer cd) -sev, Joachim -D:\scummsys.98\sputm.98\*.c -a70431a271fd64eb958bab0a75b9db5b SOCCER.(A) -ccca9a823d117afb1a882fd707586bf0 soccer.d32 -431076c63ffa5b0caf66dbe03c1eef30 SOCCER.EXE -701246819d1a70573f41bf33fc19214f SOCCER.HE0 -6b8840d83784dbceb44f9d8694fce9d4 SOCCER.HE2 -b50ac4df3a13b7ccc73e68dae5851d36 SOCCER.HE4 -6a89ce2925a36a1d9e0d9e9f7060c533 SOCCER.HE9 -ed64133f8cdfca57fb3cd09057def978 SOCCER.U32 -db16386ae24902866ec908c31f58dd6c Soccer.w32 - - -(soccerMLS cd hfs) -??? - -(soccerMLS cd) -sev -C:\Dev\Project\SPUTM\Src\*.cpp -bda62f35e0ce1f910d63f0713b3426cb SoccerMLS.(a) -9705d481fd818835e68bb3ac3ddaf787 SoccerMLS.exe -bfdf584b01503f0762baded581f6a0a2 SoccerMLS.he0 -b44275bf54bfa7e01548eec5b7101ed9 SoccerMLS.he2 -a8fa25dc67dee77f009fe5fb59b1961a SoccerMLS.he4 -6a89ce2925a36a1d9e0d9e9f7060c533 SoccerMLS.he9 - -(soccer2004 cd) // uses bink but just for external three files -sev -F:\HEdev\scummsys\SPUTM\Src\SrcPWin\*.cpp -e10cb34c774852175134fe166a602012 Soccer2004.(a) -8acec50e5cd48830121a3b22a8bfaa46 Soccer2004.(b) -c4ffae9fac495475d6bc3343ccc8faf9 Soccer2004.HE0 -b6eae47432b9545d33d4d867cef0b4ae Soccer2004.he3 -c83971b2f2020bf68724df52c9ae70a8 soccer2004.he2 -212776c1a2dc3d44a393afc4611afbc3 soccer2004.he4 -8f70113f7c01f7bfe9f83f02749d449d soccer2004.he9 -5fba7c0899429399f944a0353307863c DATA/helogo.da2 -56ed9865373c4fe63e8986989ef75999 DATA/infogrames.da2 -678dc9831679dd3f09933d0e568f6d3c DATA/intro.da2 - -(soccer2004 cd russian) // uses bink but just for external three files -sev -F:\HEdev\scummsys\SPUTM\Src\SrcPWin\*.cpp -2808c81e388743998b3c7331501cc4dd Soccer2004.(a) -7e358891079c9f366184211d14707a70 Soccer2004.(b) -c4ffae9fac495475d6bc3343ccc8faf9 Soccer2004.HE0 -b6eae47432b9545d33d4d867cef0b4ae Soccer2004.he3 -c83971b2f2020bf68724df52c9ae70a8 soccer2004.he2 -212776c1a2dc3d44a393afc4611afbc3 soccer2004.he4 -8f70113f7c01f7bfe9f83f02749d449d soccer2004.he9 -5fba7c0899429399f944a0353307863c DATA/helogo.da2 -56ed9865373c4fe63e8986989ef75999 DATA/infogrames.da2 -678dc9831679dd3f09933d0e568f6d3c DATA/intro.da2 - -(thinkerk cd hfs) -Joachim -0c8f2ebce5116dc8a4fd7cd971cab19b ThinkerK -92fc0073a4cf259ff36070ecb8628ba8 ThinkerK (0) -2b06d67c5332c84d389fa681961920da ThinkerK (1) -61b858cb5e97fc2960e74b18297be540 ThinkerK (2) -06a5613cf59c7fdb5d5b888142d6d8b4 ThinkerK (4) -d41d8cd98f00b204e9800998ecf8427e ThinkerK (r) - -(thinkerk cd) -kirben, Joachim -c0c0934580cde95879bef0b6a5a49c29 THINKERK.D32 -37b4a8ce5bc28bc958c2c2548a453d31 THINKERK.EXE -92fc0073a4cf259ff36070ecb8628ba8 THINKERK.HE0 -2b06d67c5332c84d389fa681961920da THINKERK.HE1 -61b858cb5e97fc2960e74b18297be540 THINKERK.HE2 -06a5613cf59c7fdb5d5b888142d6d8b4 THINKERK.HE4 -b10981a0805c37cda1420f29745d6537 THINKERK.W32 - -(freddi cd hfs) -khalek -1997-12-09 19:59 Kinddemo -9c445edf28ee4a2a7b3ff36ea1f75c05 Kinddemo -695fe0b3963333b7e15b37514db3c745 Kinddemo (0) -d3af0fb2011b158a28c43480fb59c588 Kinddemo (1) -e5da782a19575d12ff98feb74f7602e3 Kinddemo (2) -ba7a9148040e2421c4129b1d32c40627 Kinddemo (4) -d41d8cd98f00b204e9800998ecf8427e Kinddemo (r) - -(ftp/pajama2 cd/puttrace cd/freddi3 cd/soccer cd) -1997-09-03 18:32 kinddemo.w32 -khalek, sev, Joachim -D:\Scummsys.90\sputm.90\*.c -c0c0934580cde95879bef0b6a5a49c29 KINDDEMO.D32 -37b4a8ce5bc28bc958c2c2548a453d31 KINDDEMO.EXE -695fe0b3963333b7e15b37514db3c745 KINDDEMO.HE0 -d3af0fb2011b158a28c43480fb59c588 KINDDEMO.HE1 -e5da782a19575d12ff98feb74f7602e3 KINDDEMO.HE2 -ba7a9148040e2421c4129b1d32c40627 KINDDEMO.HE4 -b10981a0805c37cda1420f29745d6537 KINDDEMO.W32 - -(thinker1 cd hfs) -Joachim -cd7d15788407e42cb2d25e91bcb5649f Thinker1 -5c21fc49aee8f46e58fef21579e614a1 Thinker1 (0) -d208e601cbeda1082aae9959bc80d736 Thinker1 (1) -2e3a3f3cf83a6125a9bc0637dcd3daec Thinker1 (2) -70d4c5fcba615fca984a3cb4bc42fb6a Thinker1 (4) -d41d8cd98f00b204e9800998ecf8427e Thinker1 (r) - -(thinker1 cd) -Joachim -c0c0934580cde95879bef0b6a5a49c29 THINKER1.D32 -ac403714308c2a6200bbffd4cd49c77c THINKER1.EXE -5c21fc49aee8f46e58fef21579e614a1 THINKER1.HE0 -d208e601cbeda1082aae9959bc80d736 THINKER1.HE1 -2e3a3f3cf83a6125a9bc0637dcd3daec THINKER1.HE2 -70d4c5fcba615fca984a3cb4bc42fb6a THINKER1.HE4 -dafbd5699d72d4b985f1f6c46ae9a556 THINKER1.W32 - -(1grademo hfs) -??? - -1997-09-03 14:21 1grademo.w32 -khalek -D:\Scummsys.90\sputm.90\*.c -0f5935bd5e88ba6f09e558d64459746d 1grademo.he0 -e41b3ba697f00251fdefd7d64a8cf125 1grademo.he1 -007961d43ada4cca6f15b2dcedcb695e 1grademo.he2 -ae77dc6ff68d6fdfb23e5f792f91ab2d 1grademo.he4 -5d4a7c36dee1a11ed50d260f8413c27a 1grademo.w32 - -(puttsfunshop cd hfs/puttcircus cd hfs/freddisfunshop cd hfs/samsfunshop cd hfs) -Joachim -fcd508025e1963a619b2aec191907f22 BluesABCTimeDemo -7ddeaf52c8b9a50551ce0aa2ac811d07 BluesABCTimeDemo (0) -e4a7e95b00feb1a3e13b542c164c7ff3 BluesABCTimeDemo (2) -de94e921f02e3b4c6e061aab0f4cc339 BluesABCTimeDemo (4) -06fee308ab288ece9b2ab18f9c7b9f41 BluesABCTimeDemo (a) -d41d8cd98f00b204e9800998ecf8427e BluesABCTimeDemo (r) - - -(puttsfunshop cd/pajama3 cd/puttcircus cd/freddisfunshop cd/samsfunshop cd) -1998-07-26 13:36 BLUESABCTIMEDEMO.W32 -khalek, sev, Joachim -D:\scummsys.98\sputm.98\*.c -06fee308ab288ece9b2ab18f9c7b9f41 BluesABCTimeDemo.(a) -ccca9a823d117afb1a882fd707586bf0 BluesABCTimeDemo.d32 -f67221ca7890906f29ab38aedafb0802 BluesABCTimeDemo.exe -7ddeaf52c8b9a50551ce0aa2ac811d07 BluesABCTimeDemo.HE0 -e4a7e95b00feb1a3e13b542c164c7ff3 BluesABCTimeDemo.he2 -de94e921f02e3b4c6e061aab0f4cc339 BluesABCTimeDemo.he4 - -(puttrace cd hfs/freddi4 cd hfs/puttzoo cd hfs/pajama3 cd hfs) -Joachim -fcd508025e1963a619b2aec191907f22 BluesABCTimeDemo -810a9da887aefa597b0cf3c77d262897 BluesABCTimeDemo (0) -5800ab15c53341fa4b4470cd20c2affa BluesABCTimeDemo (2) -de94e921f02e3b4c6e061aab0f4cc339 BluesABCTimeDemo (4) -860eb5a38ce8edef04f614bb50489aab BluesABCTimeDemo (a) -d41d8cd98f00b204e9800998ecf8427e BluesABCTimeDemo (r) - -(puttrace cd/freddi4 cd/puttzoo cd) -sev, Joachim -D:\scummsys.98\sputm.98\*.c -860eb5a38ce8edef04f614bb50489aab BluesABCTimeDemo.(a) -ccca9a823d117afb1a882fd707586bf0 BluesABCTimeDemo.d32 -f67221ca7890906f29ab38aedafb0802 BluesABCTimeDemo.exe -810a9da887aefa597b0cf3c77d262897 BluesABCTimeDemo.HE0 -5800ab15c53341fa4b4470cd20c2affa BluesABCTimeDemo.he2 -de94e921f02e3b4c6e061aab0f4cc339 BluesABCTimeDemo.he4 - -(freddi5 cd hfs) // uses smacker videos -Joachim -181b98beb756fe07650608b0357fa934 Blues-ArtTime Demo -d00ffc8c32d17e575fd985d435d2eb88 Blues-ArtTime Demo (0) -58c91c3f750b227b136e96b410b0e7cc Blues-ArtTime Demo (2) -47f0573a8a629c6e7f8b9236112fe10e Blues-ArtTime Demo (4) -548fcedaa9cee84443a5a9acfff4cb04 Blues-ArtTime Demo (a) -5272e8074130bdcc431d6ce325e3f0ab Blues-ArtTime Demo (i) -2f1a08df8aa13924959905fc5dc34a9b Data/intr_at_in_01.dat -f7841f8a37394805fc0699999898bcca Data/intr_at_in_02.dat -6a2f8c39d2ce07d422bae9f9bf416839 Data/intr_at_in_20_b.dat - -(freddi5 cd) // uses smacker videos -sev, Joachim -C:\Dev\Project\SPUTM\Src\SrcPWin\*.cpp -548fcedaa9cee84443a5a9acfff4cb04 artdemo.(a) -e856bf226130de0d84bcaaa7ecfb5a3a artdemo.D32 -840be04790ddb035725978e70f7c78f8 ARTDEMO.EXE -d00ffc8c32d17e575fd985d435d2eb88 artdemo.HE0 -58c91c3f750b227b136e96b410b0e7cc artdemo.he2 -47f0573a8a629c6e7f8b9236112fe10e artdemo.he4 -7e98a8e45cbac83e65d98f3c133ae34d artdemo.w32 -2f1a08df8aa13924959905fc5dc34a9b Data/intr_at_in_01.dat -f7841f8a37394805fc0699999898bcca Data/intr_at_in_02.dat -6a2f8c39d2ce07d422bae9f9bf416839 Data/intr_at_in_20_b.dat - -(puttsfunshop cd hfs/freddisfunshop cd hfs/samsfunshop cd hfs/pajama3 cd hfs/puttcircus cd hfs) // uses smacker videos -Joachim -30ea41602894a180aac747198388bc5e BluesBirthdayDemo -dbf4d59d70b826733f379f998354d350 BluesBirthdayDemo (0) -60cc055b47b53cb53eaa89e1f974c888 BluesBirthdayDemo (2) -0794110b085ee91c2aa4a5fc844ff2f4 BluesBirthdayDemo (4) -44e5c3d256fe45c334ac772fa2dd23e2 BluesBirthdayDemo (+) -6ddf8b026cfb9410b560f91f353dc0f4 BluesBirthdayDemo (a) -409a570e46466aef89c3cd3a30992543 BluesBirthdayDemo (b) -b46f3aa845f11020d8420d624c120120 BluesBirthdayDemo (i) -d41d8cd98f00b204e9800998ecf8427e BluesBirthdayDemo (r) - -(puttsfunshop cd/freddisfunshop cd/samsfunshop cd/pajama3 cd/puttcircus cd) // uses smacker videos -sev, Joachim -D:\scummsys.98\sputm.98\*.c -6ddf8b026cfb9410b560f91f353dc0f4 BluesBirthdayDemo.(a) -409a570e46466aef89c3cd3a30992543 BluesBirthdayDemo.(b) -e07a222d121f7e8b04266bf4d7809cb4 BluesBirthdayDemo.a32 -ccca9a823d117afb1a882fd707586bf0 BluesBirthdayDemo.d32 -6d283612076435baad21d5cc5f40fba3 BluesBirthdayDemo.exe -dbf4d59d70b826733f379f998354d350 BluesBirthdayDemo.HE0 -60cc055b47b53cb53eaa89e1f974c888 BluesBirthdayDemo.he2 -0794110b085ee91c2aa4a5fc844ff2f4 BluesBirthdayDemo.he4 - -(puttrace cd hfs) // uses smacker videos -Joachim -30ea41602894a180aac747198388bc5e BluesBirthdayDemo -2d4acbdcfd8e374c9da8c2e7303a5cd0 BluesBirthdayDemo (0) -dc5e63ecf2672d4a3a0458fe32902a4e BluesBirthdayDemo (2) -0794110b085ee91c2aa4a5fc844ff2f4 BluesBirthdayDemo (4) -44e5c3d256fe45c334ac772fa2dd23e2 BluesBirthdayDemo (+) -18ee74255c93da057c92effbd39ebd9a BluesBirthdayDemo (a) -409a570e46466aef89c3cd3a30992543 BluesBirthdayDemo (b) -b46f3aa845f11020d8420d624c120120 BluesBirthdayDemo (i) -d41d8cd98f00b204e9800998ecf8427e BluesBirthdayDemo (r) - -(puttrace cd) // uses smacker videos -sev, Joachim -D:\scummsys.98\sputm.98\*.c -18ee74255c93da057c92effbd39ebd9a BluesBirthdayDemo.(a) -409a570e46466aef89c3cd3a30992543 BluesBirthdayDemo.(b) -e07a222d121f7e8b04266bf4d7809cb4 BluesBirthdayDemo.a32 -ccca9a823d117afb1a882fd707586bf0 BluesBirthdayDemo.d32 -e478bdc989beeeaec7e2528a11c88729 BluesBirthdayDemo.exe -2d4acbdcfd8e374c9da8c2e7303a5cd0 BluesBirthdayDemo.HE0 -dc5e63ecf2672d4a3a0458fe32902a4e BluesBirthdayDemo.he2 -0794110b085ee91c2aa4a5fc844ff2f4 BluesBirthdayDemo.he4 - - -(freddi5 cd hfs) // uses smacker videos -Joachim -853c41736ce7e4c5d6b3431dd550ea3f Blues-ReadingTime Demo -95818b178d473c989ac753574e8892aa Blues-ReadingTime Demo (0) -7c64b87e454e642e36a83c79341007b0 Blues-ReadingTime Demo (2) -4f307cf26e46f765298cc8f92f02db49 Blues-ReadingTime Demo (4) -f536221cc5d8da02009278523eda6bd5 Blues-ReadingTime Demo (a) -5272e8074130bdcc431d6ce325e3f0ab Blues-ReadingTime Demo (i) -45a973a322b177ee4b36bea81981462d Data/INT_RT_IN_01.DAT -9e0c144bf1b7f0cc8ba3edae6135e313 Data/INT_RT_IN_03.DAT -8d150f9d9e12e485da50c4560135b4ef Data/INT_RT_IN_04.DAT -8cde496829546daaaa28084c49f3f4f7 Data/INT_RT_IN_05.DAT -c784fa970208b5bd49fff568ca0036ec Data/INT_RT_IN_06.DAT - -(freddi5 cd) // uses smacker videos -sev, Joachim -C:\Dev\Project\SPUTM\Src\SrcPWin\*.cpp -f536221cc5d8da02009278523eda6bd5 readdemo.(a) -e856bf226130de0d84bcaaa7ecfb5a3a readDemo.D32 -2be2b18bf04dcd9d9dc6b16e88b8f811 READDEMO.EXE -95818b178d473c989ac753574e8892aa readdemo.HE0 -7c64b87e454e642e36a83c79341007b0 readDemo.he2 -4f307cf26e46f765298cc8f92f02db49 readdemo.he4 -eac7453b1dca87447974ef54137470f9 readDemo.w32 -45a973a322b177ee4b36bea81981462d Data/INT_RT_IN_01.DAT -9e0c144bf1b7f0cc8ba3edae6135e313 Data/INT_RT_IN_03.DAT -8d150f9d9e12e485da50c4560135b4ef Data/INT_RT_IN_04.DAT -8cde496829546daaaa28084c49f3f4f7 Data/INT_RT_IN_05.DAT -c784fa970208b5bd49fff568ca0036ec Data/INT_RT_IN_06.DAT - -(fbear cd 3do) -??? - -(he classics cd) -khalek, sev -6.1.1 (Jun 23 1993 15:31:14) -9f5ada54fef54f1602bb1b642d0fe412 FBEAR.EXE -3824e60cdf639d22f6df92a03dc4b131 FBEAR.HE0 -c75f511786a4e0c474660d074c9a421a FBEAR.HE1 -d05d89374e5e459067603cd075dd3134 FBEAR.SNG -c542564fc561aca36626259455738126 FBEAR.TLK - -(fbear cd) -Joachim -9f5ada54fef54f1602bb1b642d0fe412 FBEAR.EXE -3824e60cdf639d22f6df92a03dc4b131 FBEAR.HE0 -c75f511786a4e0c474660d074c9a421a FBEAR.HE1 -d05d89374e5e459067603cd075dd3134 FBEAR.SNG -0f19cfc74cbeb0a255b289772acad687 FBEAR.TLK - -(fbear cd hebrew) -??? - -(he classics cd hfs) -khalek -3df6ead57930488bc61e6e41901d0e97 Fatty Bear 0 -93cdebdbf8f1ec8c3f05dff0c8fedc82 Fatty Bear 1 -fc3885128832fcb876ccd79124ba36fe Fatty Bear 2 -d05d89374e5e459067603cd075dd3134 Fatty Bear Songs - -(fbear cd hfs) -Joachim -d41d8cd98f00b204e9800998ecf8427e Fatty Bear -3df6ead57930488bc61e6e41901d0e97 Fatty Bear 0 -93cdebdbf8f1ec8c3f05dff0c8fedc82 Fatty Bear 1 -110890cbcbbdacdd3a02159cbde20889 Fatty Bear 2 -d05d89374e5e459067603cd075dd3134 Fatty Bear Songs - -(he classics cd) -khalek, sev -7.0.0 (Feb 7 1995 13:27:40) -179879b6e35c1ead0d93aab26db0951b FBEAR.HE0 -7f733155adcb049e887fef942e81602a FBEAR.HE1 -fc3885128832fcb876ccd79124ba36fe FBEAR.HE2 -58dfc09f344a9dec565bb914920800d3 FBEAR.HE3 -a6b0d9c55f747f906142ed60c7d780e8 FBEAR.HE4 -d05d89374e5e459067603cd075dd3134 FBEAR.SNG -564d213162f0375b62a8fc5a3a9ef94d FBEAR.W32 - -(fbear cd) -Joachim -333714828ec2e0bd97a189882bf4e49e FBEAR.EXE -179879b6e35c1ead0d93aab26db0951b FBEAR.HE0 -7f733155adcb049e887fef942e81602a FBEAR.HE1 -110890cbcbbdacdd3a02159cbde20889 FBEAR.HE2 -58dfc09f344a9dec565bb914920800d3 FBEAR.HE3 -a6b0d9c55f747f906142ed60c7d780e8 FBEAR.HE4 -d05d89374e5e459067603cd075dd3134 FBEAR.SNG -564d213162f0375b62a8fc5a3a9ef94d FBEAR.W32 - -6.1.1 (Apr 6 1993 20:48:56) -khalek -59c820951585b7dfb0307992bbb275c7 fbdemo.exe -47e75b1bdcb44c78cb94883d1731ccf8 fbdemo.he0 -7c61c90ec5ceb812698d40b29f356559 fbdemo.he1 -f054dd0158bafd59570794397727c882 fbdemo.tlk - -(puttmoon cd hfs/airport cd hfs/jungle cd hfs) -Joachim -d41d8cd98f00b204e9800998ecf8427e Fatty Bear Demo -6df20c50c1ab19799de9be7ae7716881 Fatty Bear Demo 0 -d9e4a20226b6120d2a3d8d3a9a643a86 Fatty Bear Demo 1 -0d95ea172d9c94f4c90b9f542a824ced Fatty Bear Demo 2 - -(puttputt cd/he classics cd/fbear cd/puttmoon cd) -khalek, sev, Joachim -7.0.0 (Feb 7 1995 13:27:40) -9b44bf1f45abc809cf81fde9ff80e5a7 FBDEMO.EXE -22c9eb04455440131ffc157aeb8d40a8 FBDEMO.HE0 -5293d81516126086766540ab12a9c499 FBDEMO.HE1 -f054dd0158bafd59570794397727c882 FBDEMO.HE2 -58dfc09f344a9dec565bb914920800d3 FBDEMO.HE3 -76954add1f2c5bd9d967746ab4137d3a FBDEMO.HE4 -564d213162f0375b62a8fc5a3a9ef94d FBDEMO.W32 - -(freddi cd hfs) -khalek -1998-02-18 16:06 Freddi Fish -560da18bc11f6cf7b068a96dd928ae7e Freddi Fish -df047cc4792150f601290357566d36a6 Freddi Fish (0) -d30fb13dd3baa94a4cabe4cc1a6228d1 Freddi Fish (1) -f2f1e70bd9388c98c0ef38b1ef286ae2 Freddi Fish (2) -cb0fb189e08144bbc713b8df739ba9fc Freddi Fish (4) -d41d8cd98f00b204e9800998ecf8427e Freddi Fish (r) - -(freddi cd) -khalek, Joachim -1998-01-21 02:13 freddi.w32 -D:\Scummsys.90\sputm.90\*.c -c0c0934580cde95879bef0b6a5a49c29 FREDDI.D32 -2e0253f624f34b56cf888e557d931a3b FREDDI.EXE -df047cc4792150f601290357566d36a6 FREDDI.HE0 -d30fb13dd3baa94a4cabe4cc1a6228d1 FREDDI.HE1 -f2f1e70bd9388c98c0ef38b1ef286ae2 FREDDI.HE2 -cb0fb189e08144bbc713b8df739ba9fc FREDDI.HE4 -0d6f0f65403bd23afb78c143587d11a8 FREDDI.W32 - -(freddi cd russian) -sev -7.0.0 (Jun 23 1995 09:58:48) -d4cccb5af88f3e77f370896e9ba8c5f9 FREDDI.HE0 -1705aa5c12a2959f1b69abc1fd145f01 FREDDI.HE1 -199c5c38798ddacce5cfbfe7b31267cf FREDDI.HE2 -6daf76c1fe724ce6bf2e4c5175f39352 FREDDI.HE3 -a176fababbf7944a1d4b5d6521b20f4d FREDDI.HE4 -2085ef0c1d1cc64db1ec52901b4856b9 FREDDI.HE5 -8be6d657bcbda8b4926448e530528d6a FREDDI.W32 - -(freddi cd dutch) -adutchguy -??? - -(freddi cd german) -oncer, Joachim -fc00ad009697e2c9a50dd222f8f40c73 FREDDI.EXE -cf8ef3a1fb483c5c4b1c584d1167b2c4 FREDDI.HE0 -e3b21adcc7ad12e0b8a0a8fa9bdd30a9 FREDDI.HE1 -1d10f0e80dc84a3dd8331c55f4146ed5 FREDDI.HE2 -6daf76c1fe724ce6bf2e4c5175f39352 FREDDI.HE3 -8e27aebf6d89f8576a08b58e216a6a90 FREDDI.HE4 -842badd1332ab8d6c8fd4e8277e0471c FREDDI.W32 - -(freddi cd nb) -Karl Ove Hufthammer -??? - -(freddi cd russian updated) -sev -D:\Scummsys.90\sputm.90\*.c -746e88c172a5b7a1ae89ac0ee3ee681a Freddi.HE0 -02b964d6d7a3fcace1bc89ae2a2c9db7 FREDDI.HE1 -14a1058745c609eefa08f1591cc5d4df FREDDI.HE2 -2b219196f0cc74d626a3216932d3ea54 Freddi.he4 -58d117ae89707c7360f403186641e87f FREDDI.W32 - -(freddi cd swedish) -Sven Arvidsson -??? - -(farm cd hfs/airportcd hfs/jungle cd hfs/thinker1 cd hfs/thinkerk cd hfs/socks cd hfs/baseball cd hfs) -khalek, Joachim -1995-09-14 17:35 Freddi Demo -42f4a55732734e3c54c0b198f2615970 Freddi Demo -c8aac5e3e701874e2fa4117896f9e1b1 Freddi Demo (0) -b4805ccd0841854d6b2f596f0efb5551 Freddi Demo (1) -faca7509c38beabb37b2347b8b6bb1ea Freddi Demo (2) -a8c3ced34ecb16ad1b0eed5b464ad61e Freddi Demo (4) - -(he classics cd hfs/pajama cd hfs/puttzoo cd hfs) -khalek (comment: is this double entry really necessary?) -1996-11-17 13:28 Freddi Demo -42f4a55732734e3c54c0b198f2615970 Freddi Demo -c8aac5e3e701874e2fa4117896f9e1b1 Freddi Demo (0) -b4805ccd0841854d6b2f596f0efb5551 Freddi Demo (1) -faca7509c38beabb37b2347b8b6bb1ea Freddi Demo (2) -a8c3ced34ecb16ad1b0eed5b464ad61e Freddi Demo (4) - -(puttputt cd/puttmoon cd/fbear cd) -khalek, sev, Joachim -7.0.0 (Oct 20 1994 10:00:19) -10f764e586228d090d66bdf43cc5a1ef FREDDEMO.EXE -084ed0fa98a6d1e9368d67fe9cfbd417 FREDDEMO.HE0 -273e622b5fdf60859b549fee08384a33 FREDDEMO.HE1 -faca7509c38beabb37b2347b8b6bb1ea FREDDEMO.HE2 -6daf76c1fe724ce6bf2e4c5175f39352 FREDDEMO.HE3 -a8c3ced34ecb16ad1b0eed5b464ad61e FREDDEMO.HE4 -0ebc6a8cc24babc41dbfbfb07ee6456f FREDDEMO.W32 - -(farm cd/airport cd/jungle cd/airport hfs/jungle hfs) -khalek, Joachim -7.0.0 (Jun 22 1995 14:06:25) -e269b675a252296640430feab730e8b7 FREDDEMO.EXE -0855496dde35356b1a9691e22ba84cdc FREDDEMO.HE0 -5374aef0d7c547a95dc779f4ea51e20f FREDDEMO.HE1 -faca7509c38beabb37b2347b8b6bb1ea FREDDEMO.HE2 -6daf76c1fe724ce6bf2e4c5175f39352 FREDDEMO.HE3 -a8c3ced34ecb16ad1b0eed5b464ad61e FREDDEMO.HE4 -3d43af3f3ecc18744dda721d951e2a2f FREDDEMO.W32 - -(spyfox cd/pajama cd/puttzoo cd/he classics cd/freddi2 cd/baseball cd/socks cd/thinker1 cd/thinkerk cd) -khalek, sev, Joachim (comment: all files uppercase on CD) -7.0.0 (Jul 5 1995 14:46:05) -e269b675a252296640430feab730e8b7 FREDDEMO.EXE -566165a7338fa11029e7c14d94fa70d0 FREDDEMO.HE0 -649724a605cb66fef3fac73297ef4259 FREDDEMO.HE1 -faca7509c38beabb37b2347b8b6bb1ea FREDDEMO.HE2 -6daf76c1fe724ce6bf2e4c5175f39352 FREDDEMO.HE3 -a8c3ced34ecb16ad1b0eed5b464ad61e FREDDEMO.HE4 -25003798cd5f4b51bc1f4d02c6a2e218 FREDDEMO.W32 - -(humongous ftp) -7.0.0 (Jul 5 1995 14:46:05) -khalek, sev -566165a7338fa11029e7c14d94fa70d0 freddemo.he0 -649724a605cb66fef3fac73297ef4259 freddemo.he1 -faca7509c38beabb37b2347b8b6bb1ea freddemo.he2 -6daf76c1fe724ce6bf2e4c5175f39352 freddemo.he3 -a8c3ced34ecb16ad1b0eed5b464ad61e freddemo.he4 -a5459bfe36183cf1f4ced00fe325aa90 freddemo.w32 - -(freddi2 cd german/freddi2 cd hfs german) -Joachim -fc00ad009697e2c9a50dd222f8f40c73 FREDDEMO.EXE -cf4ef315214c7d8cdab6302cdb7e50db FREDDEMO.HE0 -c4671ee12bcb89be376a8432ac23ce77 FREDDEMO.HE1 -468e8c93b4831ff6e84ac69140f8b603 FREDDEMO.HE2 -6daf76c1fe724ce6bf2e4c5175f39352 FREDDEMO.HE3 -a8c3ced34ecb16ad1b0eed5b464ad61e FREDDEMO.HE4 -842badd1332ab8d6c8fd4e8277e0471c FREDDEMO.W32 - -(freddi2 cd hfs) -Kirben -??? - -(freddi2 hfs) -Kirben -??? - -(freddi2 cd hfs) -kirben, Joachim -91a8077251d21b9a060792f50df91cbc Freddi Fish 2 -51305e929e330e24a75a0351c8f9975e Freddi Fish 2 (0) -2f0f418ca29e298343a76e4a76ce5d96 Freddi Fish 2 (2) -c87140d52e550ee923f18789517e61ab Freddi Fish 2 (4) -722286b727e75a3e44f9333d6b604427 Freddi Fish 2 (a) -d5920b5082d570d03500fe165bb75c0a Freddi Fish 2 (i) -d41d8cd98f00b204e9800998ecf8427e Freddi Fish 2 (r) - -(freddi2 cd) -kirben, Joachim -722286b727e75a3e44f9333d6b604427 Freddi2.(a) -ccca9a823d117afb1a882fd707586bf0 Freddi2.d32 -c45467455384a11c608530d371d6669e FREDDI2.EXE -51305e929e330e24a75a0351c8f9975e Freddi2.HE0 -2f0f418ca29e298343a76e4a76ce5d96 Freddi2.he2 -c87140d52e550ee923f18789517e61ab Freddi2.he4 -15e826c4702e0c44018a6b6a31de76ef FREDDI2.w32 - -(freddi2 cd hfs german) -Joachim -5d6f8f48c758f7ce07ace9141bd177d4 Fritzi Fisch 2 -fce4b8010704b103acfeea9413788f32 Fritzi Fisch 2 (0) -d857b6f3ee3a2347faf589a823be6d6c Fritzi Fisch 2 (1) -3e25355859e2fc97c88ebebfd63c5c14 Fritzi Fisch 2 (2) -2b7114ad0e35ca65ec8de54b7acd352d Fritzi Fisch 2 (4) - -(freddi2 cd german) -Joachim -4c695f3d8015af4277fd284981e0d2c4 FREDDI2.D32 -9d4373de9fd1c25671de1500dbe358a2 FREDDI2.EXE -fce4b8010704b103acfeea9413788f32 FREDDI2.HE0 -d857b6f3ee3a2347faf589a823be6d6c FREDDI2.HE1 -3e25355859e2fc97c88ebebfd63c5c14 FREDDI2.HE2 -2b7114ad0e35ca65ec8de54b7acd352d FREDDI2.HE4 -e24b9e887a04f66db3edcd5fc81767fd FREDDI2.W32 - -(freddi2 cd) -sev -D:\Scummsrc.80\Sputm\*.c -5057fb0e99e5aa29df1836329232f101 FREDDI2.HE0 -a586db95af3146aa7793c5e2d0ed9e83 FREDDI2.HE1 -9ff9a777a343e605278127c0bbdde58f FREDDI2.HE2 -d22f1b3bd41cb4901f89164043953bc8 FREDDI2.HE4 -d06066ae0ba8ffb338d6a00f556ae3ac FREDDI2.W32 - -(freddi2 cd russian) -sev -D:\Scummsrc.80\Sputm\*.c -5057fb0e99e5aa29df1836329232f101 FREDDI2.HE0 -1b6d479d15a7eb4a55c5e90711511b00 FREDDI2.HE1 -53f72ce417e28af51e3b8a60cd6ca5ef FREDDI2.HE2 -52494431dd3f658a8dc1d4348e677e48 FREDDI2.HE4 -a1a7f76f9de6b74031f4d6c9b8cbb130 FREDDI2.W32 - -(freddi2 cd dutch) -joostp -??? - -(freddi2 cd) -vampir_raziel -??? - -(freddi2 cd russian updated) -sev -c:\Build\SRC\SPUTM\Src\SrcPWin\*.cpp -c40f2b3cf5b82d34afc222779b3f0a7c FreddiCHSH.(a) -b92b53d360319b1e0fa93d353503fbfd FreddiCHSH.exe -e41de1c2a15abbcdbf9977e2d7e8a340 FreddiCHSH.he0 -83619bbe6b084ebf1ae53b5a56442719 FreddiCHSH.he2 -c366efa1e6b3d4406b5f3123c2247d8f FreddiCHSH.he4 - -(freddi cd hfs/he classics hfs/pajama cd hfs/puttzoo cd hfs) -khalek -1997-10-28 17:16 Freddi Fish 2 Demo -d7e1af5d819c98b2f0ec8150f54ad51f Freddi Fish 2 Demo -fc8d197a22146e74766e9cb0cfcaf1da Freddi Fish 2 Demo (0) -203cf83989f6410ec19edb9bd1455512 Freddi Fish 2 Demo (1) -f96261232a8a7ae6bc7478d8c1c5a49c Freddi Fish 2 Demo (2) -a97bf54bcae67fabb8d6e4a1e506efef Freddi Fish 2 Demo (4) - -(spyfox cd/pajama cd/puttzoo cd/he classics cd/pajama2 cd/freddi3 cd/baseball cd) -khalek, sev, Joachim -1996-10-17 03:54 ff2-demo.w32 -D:\Scummsrc.80\Sputm\*.c -9d4373de9fd1c25671de1500dbe358a2 FF2-DEMO.EXE -fc8d197a22146e74766e9cb0cfcaf1da FF2-DEMO.HE0 -203cf83989f6410ec19edb9bd1455512 FF2-DEMO.HE1 -f96261232a8a7ae6bc7478d8c1c5a49c FF2-DEMO.HE2 -a97bf54bcae67fabb8d6e4a1e506efef FF2-DEMO.HE4 -21935da87e116e29f558145b0c491770 FF2-DEMO.W32 - -(freddi2 demo hfs) -??? - -(ftp) -2002-06-05 15:23 ffhsdemo.exe -khalek -c:\Build\SRC\SPUTM\Src\*.cpp -874613bc4b14dba444b43e31d843e622 ffhsdemo.exe -d0a925e6d57938021ce5b1260731ec7d FFHSDemo.(a) -d37c55388294b66e53e7ced3af88fa68 ffhsdemo.he0 -d0a925e6d57938021ce5b1260731ec7d ffhsdemo.he1 -7480dfa29b4df0002d23c72bb4932dde ffhsdemo.he2 -a97bf54bcae67fabb8d6e4a1e506efef ffhsdemo.he4 - -(freddi3 cd hfs) -Joachim -560da18bc11f6cf7b068a96dd928ae7e Freddi Fish 3 -8368f552b1e3eba559f8d559bcc4cadb Freddi Fish 3 (0) -89bba1d711672a8b52ac4a47ffcf442c Freddi Fish 3 (1) -6e95640d43a66bdec5a9b9cd42921881 Freddi Fish 3 (2) -47fed8094093a2d4d9f8d4f61d51e088 Freddi Fish 3 (4) -d41d8cd98f00b204e9800998ecf8427e Freddi Fish 3 (r) - -(freddi3 cd) -sev, Joachim -D:\Scummsys.90\sputm.90\*.c -c0c0934580cde95879bef0b6a5a49c29 FREDDI3.D32 -56e44f51bd02de77cb75737e45396987 FREDDI3.EXE -8368f552b1e3eba559f8d559bcc4cadb FREDDI3.HE0 -89bba1d711672a8b52ac4a47ffcf442c FREDDI3.HE1 -6e95640d43a66bdec5a9b9cd42921881 FREDDI3.HE2 -47fed8094093a2d4d9f8d4f61d51e088 FREDDI3.HE4 -88d57485970d3e801364812c82dec001 FREDDI3.W32 - -(freddi3 cd russian) -sev -D:\Scummsys.90\sputm.90\*.c -8368f552b1e3eba559f8d559bcc4cadb FREDDI3.HE0 -28afc2494f8f5d45726409743c2763cc FREDDI3.HE1 -2be336eb6b1853c3493da984340dc80a FREDDI3.HE2 -211d598c446697f8203857d012d83d67 FREDDI3.HE4 -1f33f143fd76de496215eaa654a60f04 FREDDI3.W32 - -(freddi3 cd hfs german) -Joachim -e228f3d94242920355d8ffc1f478ddb9 FreddiFGT -83cedbe26aa8b58988e984e3d34cac8e FreddiFGT (0) -a850841f6486fd5c8f1731f3092abfd0 FreddiFGT (2) -3aab38ffaee61ada59211fa417231292 FreddiFGT (4) -1c17cedc8593e0caebbae3ca61a8a78d FreddiFGT (a) -01368f1a5c87746b09f50363696f5883 FreddiFGT (i) - -(freddi3 cd german) -Joachim -1c17cedc8593e0caebbae3ca61a8a78d FreddiFGT.(a) -0fb226dcdd09aaa48dd77925c467d1cd FreddiFGT.D32 -045e9fab1078af432741aff53e6e438b FreddiFGT.exe -83cedbe26aa8b58988e984e3d34cac8e FreddiFGT.HE0 -a850841f6486fd5c8f1731f3092abfd0 FreddiFGT.HE2 -3aab38ffaee61ada59211fa417231292 FreddiFGT.HE4 -d8fcf115eb08f1fbed13a61a23e37851 FreddiFGT.w32 - -(freddi3 cd dutch) -adutchguy -??? - -(freddi3 cd russian alt) -sev -D:\Scummsys.90\sputm.90\*.c -898ce8eb1234a955ef75e87141902bb3 FREDDI3.HE0 -78f35e7aab370a3b4e828d317ecd7f27 FREDDI3.HE1 -ba7fe7de583c9b7a1e9173afc5d75b42 FREDDI3.HE2 -ef0df7bdc61977f783dbe1e37f6a15fe FREDDI3.HE4 -88d57485970d3e801364812c82dec001 FREDDI3.W32 - -(freddi3 cd russian updated) -sev -d:\dev\SPUTM\Src\*.cpp -b2b8622d2a1d954fedf526043fc185eb FreddiSCS.(a) -75bff95816b84672b877d22a911ab811 FreddiSCS.he0 -39b5ea82513c799a6dba899b950c2977 FreddiSCS.he2 -fff20670a77450240918f8315fcfb33d FreddiSCS.HE4 -199a34d9dd51e79e2a5022c778321af8 freddiSCS.w32 - -(freddi cd hfs/freddi3 cd hfs/pajama2 cd hfs) -khalek, Joachim -1997-12-04 18:25 F3-Mdemo -e711a6fb0b7330782c6b5ae0e1283084 F3-Mdemo -cb1559e8405d17a5a278a6b5ad9338d1 F3-Mdemo (0) -a2fde75fcbd2376f057f4a40f9893cbe F3-Mdemo (1) -30e3f97a2290f0683ccedf8b08a6ba55 F3-Mdemo (2) -b90004518ba5bb4dc473170f5c975568 F3-Mdemo (4) -d41d8cd98f00b204e9800998ecf8427e F3-Mdemo (r) - -(pajama2 cd/freddi3 cd/freddi cd) -sev, Joachim -D:\Scummsys.90\sputm.90\*.c -c0c0934580cde95879bef0b6a5a49c29 F3-MDEMO.D32 -56e44f51bd02de77cb75737e45396987 F3-MDEMO.EXE -cb1559e8405d17a5a278a6b5ad9338d1 F3-MDEMO.HE0 -a2fde75fcbd2376f057f4a40f9893cbe F3-MDEMO.HE1 -30e3f97a2290f0683ccedf8b08a6ba55 F3-MDEMO.HE2 -b90004518ba5bb4dc473170f5c975568 F3-MDEMO.HE4 -66ed086cf061ca023e5924147fc585be F3-MDEMO.W32 - -(humongous ftp) -1997-10-28 12:42 f3-mdemo.w32 -khalek, sev, Joachim -D:\Scummsys.90\sputm.90\*.c -c0c0934580cde95879bef0b6a5a49c29 F3-MDEMO.D32 -56e44f51bd02de77cb75737e45396987 F3-MDEMO.EXE -cb1559e8405d17a5a278a6b5ad9338d1 F3-MDEMO.HE0 -a2fde75fcbd2376f057f4a40f9893cbe F3-MDEMO.HE1 -30e3f97a2290f0683ccedf8b08a6ba55 F3-MDEMO.HE2 -b90004518ba5bb4dc473170f5c975568 F3-MDEMO.HE4 -3ff95314abdeebe0b2d11f4417efa449 f3-mdemo.w32 - -(puttrace cd/soccer cd) -Joachim -c0c0934580cde95879bef0b6a5a49c29 F3-MDEMO.D32 -3ff95314abdeebe0b2d11f4417efa449 F3-MDEMO.EXE -cb1559e8405d17a5a278a6b5ad9338d1 F3-MDEMO.HE0 -a2fde75fcbd2376f057f4a40f9893cbe F3-MDEMO.HE1 -30e3f97a2290f0683ccedf8b08a6ba55 F3-MDEMO.HE2 -b90004518ba5bb4dc473170f5c975568 F3-MDEMO.HE4 - -(freddi3 demo hfs french) -kirben -??? - -(freddi3 demo french) -kirben -??? - -(freddi3 demo dutch) -adutchguy -??? - -(freddi4 cd hfs) -Joachim -382e75cc3252683c18ccb4b8a964b8bf Freddi 4 -4f580a021eee026f3b4589e17d130d78 Freddi 4 (0) -944d9c81ce26f8820bbd2a6d2c2d987c Freddi 4 (2) -d1c47dfa05160c783da89e6dc9894d3e Freddi 4 (4) -d3cb0cbdd52b7684d321a3630bdf8abc Freddi 4 (a) -d41d8cd98f00b204e9800998ecf8427e Freddi 4 (r) - -(freddi4 cd) -Joachim -d3cb0cbdd52b7684d321a3630bdf8abc FREDDI4.(A) -ccca9a823d117afb1a882fd707586bf0 FREDDI4.D32 -dbde280a3b554db62f8f7920775cbed5 FREDDI4.EXE -4f580a021eee026f3b4589e17d130d78 FREDDI4.HE0 -944d9c81ce26f8820bbd2a6d2c2d987c FREDDI4.HE2 -d1c47dfa05160c783da89e6dc9894d3e FREDDI4.HE4 -24b409ff575c52d385cdc6b7e91b5b79 FREDDI4.W32 - -(freddi4 cd russian) -sev -D:\scummsys.98\sputm.98\*.c -0fb24aa2d37a8a6cbf90066c2f792596 freddi4.(a) -4f580a021eee026f3b4589e17d130d78 freddi4.he0 -02d4dba3fedc64e24c1baa9523035701 freddi4.he2 -a2e2010e75a1fd164ef6fc58eae7238d freddi4.he4 -24b409ff575c52d385cdc6b7e91b5b79 freddi4.w32 - -(freddi4 cd dutch) -adutchguy -??? - -(freddi4 cd german) -Joachim -25da2483b1d36a35c371393e907f57bf FreddiGS.(a) -0fb226dcdd09aaa48dd77925c467d1cd FreddiGS.D32 -e9e4997d16bc12ec0d7048571c84023b FREDDIGS.EXE -b5298a5c15ffbe8b381d51ea4e26d35c FreddiGS.HE0 -ee9720cc979cbad31193895c91e530f6 FreddiGS.HE2 -766c4f81601fe5fd69f6975c1dc51b98 FreddiGS.HE4 -25cb2425ded9b2e7557e8eb4dd7bb8d6 FreddiGS.w32 - - -(freddi4 cd russian updated} -sev -C:\HESystems\SPUTM\Src\*.cpp -658d27fdb9219f5c62468314cf0007ff FreddiHRBG.(a) -78bd5f036ea35a878b74e4f47941f784 FreddiHRBG.he0 -1d4023e93ffde7dae77426d293dab95b FreddiHRBG.he2 -ae8defe36ebe7d46f7b1796f3e95b139 FreddiHRBG.he4 -74b50dcbd98cd9bb3560be9a918c37db FreddiHRBG.w32 - -(freddi4 russian alt) -sev -D:\scummsys.98\sputm.98\*.c -41c340501caa1bf90cb0107679bf3e03 FREDDI4.(A) -07b810e37be7489263f7bc7627d4765d FREDDI4.HE0 -b90be0993b688bfcdd361c55fd263ccc FREDDI4.HE2 -d1c47dfa05160c783da89e6dc9894d3e FREDDI4.HE4 -8da938ee682f5f83aa2d51789e9602f4 FREDDI4.W32 - -(humongous ftp/pajama3 cd hfs/spyfox2 cd hfs/football cd hfs) -Joachim -8a61ffd683a01c2cddd9bb37e2fff119 Freddi 4 Demo -7c2e76087027eeee9c8f8985f93a1cc5 Freddi 4 Demo (0) -23632be3c8c4e77c3917148c5f8e56ef Freddi 4 Demo (2) -0453fdf42a9aa750ed198bca1d9f8e91 Freddi 4 Demo (4) -53b0e5c820bd264684df59231dbdc031 Freddi 4 Demo (a) -d41d8cd98f00b204e9800998ecf8427e Freddi 4 Demo (r) - -(humongous ftp) -1999-02-08 19:21 F4-demo.w32 -khalek, sev, Joachim -D:\scummsys.98\sputm.98\*.c -53b0e5c820bd264684df59231dbdc031 f4-demo.(a) -ccca9a823d117afb1a882fd707586bf0 F4-demo.d32 -dbde280a3b554db62f8f7920775cbed5 F4-demo.exe -7c2e76087027eeee9c8f8985f93a1cc5 f4-demo.HE0 -23632be3c8c4e77c3917148c5f8e56ef f4-demo.he2 -0453fdf42a9aa750ed198bca1d9f8e91 f4-demo.he4 -24b409ff575c52d385cdc6b7e91b5b79 F4-demo.w32 - -(pajama3 cd/spyfox2 cd/football cd) -Joachim -53b0e5c820bd264684df59231dbdc031 f4-demo.(a) -ccca9a823d117afb1a882fd707586bf0 F4-demo.d32 -24b409ff575c52d385cdc6b7e91b5b79 F4-demo.exe -7c2e76087027eeee9c8f8985f93a1cc5 f4-demo.HE0 -23632be3c8c4e77c3917148c5f8e56ef f4-demo.he2 -0453fdf42a9aa750ed198bca1d9f8e91 f4-demo.he4 - -(puttsfunshop cd hfs/puttcircus cd hfs/putttime cd hfs/spyozon cd hfs/freddicove cd hfs) -Joachim -7b08032b5e6ad870170e0d82d5786909 Freddi 4 Demo -ebd324dcf06a4c49e1ba5c231eee1060 Freddi 4 Demo (0) -23632be3c8c4e77c3917148c5f8e56ef Freddi 4 Demo (2) -0453fdf42a9aa750ed198bca1d9f8e91 Freddi 4 Demo (4) -0a5e8a6eb824c9e006dea982adf72d1e Freddi 4 Demo (a) -d41d8cd98f00b204e9800998ecf8427e Freddi 4 Demo (i) - - -(puttsfunshop cd/puttcircus cd/putttime cd/spyozon cd/freddicove cd/soccerMLS cd) -sev, Joachim -C:\Documents and Settings\stevej\My Documents\HECode\SPUTM\Src\*.cpp -0a5e8a6eb824c9e006dea982adf72d1e f4-demo.(a) -ccca9a823d117afb1a882fd707586bf0 f4-demo.D32 -20f57c3bf3f9fae1f88df9434bfd78e0 f4-demo.exe -ebd324dcf06a4c49e1ba5c231eee1060 f4-demo.HE0 -23632be3c8c4e77c3917148c5f8e56ef f4-demo.he2 -0453fdf42a9aa750ed198bca1d9f8e91 f4-demo.he4 - -(freddi4 demo hfs) -??? - -(dog cd) -sev -D:\scummsys.98\sputm.98\*.c -bd6a0ac7c15562250349dd5b64709e92 F4-DEMO.(A) -ccca9a823d117afb1a882fd707586bf0 F4-demo.d32 -24b409ff575c52d385cdc6b7e91b5b79 F4-demo.exe -c25755b08a8d0d47695e05f1e2111bfc F4-DEMO.HE0 -23632be3c8c4e77c3917148c5f8e56ef F4-DEMO.HE2 -0453fdf42a9aa750ed198bca1d9f8e91 F4-DEMO.HE4 - -(freddi4 demo hfs german) -Joachim -c089c75f6bc0f4a60c621a957043d279 Ff4demo -688328c5bdc4c8ec4145688dfa077bf2 Ff4demo (0) -3ad28b05239e4480644bea99d3804622 Ff4demo (2) -0453fdf42a9aa750ed198bca1d9f8e91 Ff4demo (4) -0eef3e0fca1f1ab0204982234be943a0 Ff4demo (a) -d41d8cd98f00b204e9800998ecf8427e Ff4demo (i) - -(freddi4 demo german) -Joachim -0eef3e0fca1f1ab0204982234be943a0 Ff4demo.(a) -2188b22aa1534b5248a8aa7dfa9c7861 Ff4demo.d32 -e179e35382bdc90601e01612c7a52ce8 FF4DEMO.EXE -688328c5bdc4c8ec4145688dfa077bf2 Ff4demo.HE0 -3ad28b05239e4480644bea99d3804622 Ff4demo.HE2 -0453fdf42a9aa750ed198bca1d9f8e91 Ff4demo.he4 - -(freddi4 demo dutch) -joostp -??? - -(freddi4 demo dutch) -adutchguy -??? - -(PuttTime CD UK release) -eriktorbjorn -d:\dev\SPUTM\Src\*.cpp -a2bb4dbf44dbf26587c2c213064853a8 FF4DEMO.(A) -cb52cbabfa8e91b76a0c6d76ded339c6 ff4demo.exe -e03ed1474ec14de78359970e0457a820 FF4DEMO.HE0 -15c9746d2d612d2693ec7e509c4e9fb5 FF4DEMO.HE2 -9470cd17e5e301f33876477f14992f29 ff4demo.he4 - -(Kellogg cereals pack) -bc20db254834452db602728f90e9a6d4 FreddiMini.(a) -d1286487c342ac81b28f3e1b90a2b7f3 FreddiMini.D32 -03d3b18ee3fd68114e2a687c871e38d5 FreddiMini.HE0 -cb52cbabfa8e91b76a0c6d76ded339c6 FreddiMini.exe -38189191a5824dd54377f0dbd4779046 FreddiMini.he2 -9470cd17e5e301f33876477f14992f29 FreddiMini.he4 - - -(freddicove hfs cd) -Joachim -b8ae37c647509afe5a406cab82e8f789 FreddiCove -590e6546aacd0d374b7f3a4f53013ab1 FreddiCove (0) -52b33175cf8abfbadcafbd4702275e0d FreddiCove (2) -a9f9f4a7ad25a3efda4626d4b6c80ffb FreddiCove (3) -dfbd9adb0d406184383dd069a64c8757 FreddiCove (4) -04ad937605bffa28fdf47693e61620cc FreddiCove (a) -63082e55aefcec01986fdfda9c57e55a FreddiCove (i) - -(freddicove cd) -Joachim -C:\Spyfox3Sputm\Src\SrcPWin\*.cpp -04ad937605bffa28fdf47693e61620cc freddicove.(a) -b4c292854d70ff6cf89e20030630c5e0 freddicove.EXE -590e6546aacd0d374b7f3a4f53013ab1 freddicove.HE0 -52b33175cf8abfbadcafbd4702275e0d freddicove.he2 -a9f9f4a7ad25a3efda4626d4b6c80ffb FreddiCove.he3 -dfbd9adb0d406184383dd069a64c8757 freddicove.he4 -213f75f25b1c92c1b401203440e2720e freddicove.w32 - -(freddicove cd) -sev -C:\Spyfox3Sputm\Src\SrcPWin\*.cpp -04ad937605bffa28fdf47693e61620cc FREDDICOVE.(A) -b4c292854d70ff6cf89e20030630c5e0 FREDDICOVE.EXE -590e6546aacd0d374b7f3a4f53013ab1 FREDDICOVE.HE0 -52b33175cf8abfbadcafbd4702275e0d FREDDICOVE.HE2 -a9f9f4a7ad25a3efda4626d4b6c80ffb FREDDICOVE.HE3 -dfbd9adb0d406184383dd069a64c8757 FREDDICOVE.HE4 - -(freddicove cd russian) -sev -C:\Spyfox3Sputm\Src\SrcPWin\*.cpp -04ad937605bffa28fdf47693e61620cc FREDDICOVE.(A) -b4c292854d70ff6cf89e20030630c5e0 FREDDICOVE.EXE -590e6546aacd0d374b7f3a4f53013ab1 FREDDICOVE.HE0 -62c6daba6da11b26e259e49c092cb08f FREDDICOVE.HE2 -a9f9f4a7ad25a3efda4626d4b6c80ffb FREDDICOVE.HE3 -dfbd9adb0d406184383dd069a64c8757 FREDDICOVE.HE4 - -(freddicove cd dutch) -adutchguy -??? - -(freddicove cd russian alt) -sev -C:\Spyfox3Sputm\Src\SrcPWin\*.cpp -2cac27c79aebf9db05ed516783d950a6 freddicove.(a) -21abe302e1b1e2b66d6f5c12e241ebfd freddicove.HE0 -52b33175cf8abfbadcafbd4702275e0d freddicove.he2 -a9f9f4a7ad25a3efda4626d4b6c80ffb FreddiCove.he3 -dfbd9adb0d406184383dd069a64c8757 freddicove.he4 -ca263c140b091bff2b31b1570e47aebe freddicove.w32 - -(freddicove cd russian updated) -sev -C:\HE_dev\SPUTM\Src\*.cpp -50211d918df60b69d78c03962a5b09ed FreddiCCC.(a) -b3d5a75a35d165c5750ab84fdc6fd638 FreddiCCC.EXE -4ce2d5b355964bbcb5e5ce73236ef868 FreddiCCC.HE0 -2890b42997816aae1bcaa618e77444bf FreddiCCC.he2 -2f238b51cfad1b8b5c179468a19aa29b FreddiCCC.he3 -29ef3472e3675c4a0e6ea440e0df4ffd FreddiCCC.he4 - -(freddicove demo dutch) -kirben, sev -??? - -(freddicove demo hfs) -??? - -(pajama4 cd) -sev -c:\SRC_RELEASE\SPUTM\Src\SrcPWin\*.cpp -f1b5cd6bceb50f8296d7a8db6efb69ec FFCoveDemo.(a) -e856bf226130de0d84bcaaa7ecfb5a3a FFCoveDemo.d32 -554762d1e011ade6cc29ab8024124017 FFCoveDemo.exe -45082a5c9f42ba14dacfe1fdeeba819d FFCoveDemo.HE0 -0c8f5b94bee7ddcbe5d41abce1daf9e3 ffCoveDemo.he2 -af9375aa14e4d967801938ee355e1486 ffCoveDemo.he4 -912c159f4a0232ceaff2b6759b18fd2f ffCoveDemo.w32 - -(super duper arcade 1 cd hfs) -Joachim -20b697227835007b68aaf078d19e239d Water Worries -4ba37f835be11a59d969f90f272f575b Water Worries (0) -e577863ba03c4c1001052e6c809bf66a Water Worries (1) -9d4a6d9c383ab9b1d0a486a5bb6bfb34 Water Worries (2) -3d5f7153500339e05815cfa9c3e9369e Water Worries (4) -2856fa0e0e74484f9c55dc58b2e9203c Water Worries (7) - -(super duper arcade 1 cd) -Joachim -7a266bd72dc8ae9a4d1c209e49502c00 Water.a32 -9a8e77ece8ed9cfcadd214ad0efabcee water.exe -4ba37f835be11a59d969f90f272f575b WATER.HE0 -e577863ba03c4c1001052e6c809bf66a WATER.HE1 -9d4a6d9c383ab9b1d0a486a5bb6bfb34 water.He2 -3d5f7153500339e05815cfa9c3e9369e water.he4 -2856fa0e0e74484f9c55dc58b2e9203c WATER.HE7 - - -(water cd hfs) -Joachim -2856fa0e0e74484f9c55dc58b2e9203c Water (7) -91a8077251d21b9a060792f50df91cbc Water Worries -f1b0e0d587b85052de5534a3847e68fe Water Worries (0) -162e516eaea7f6635e0d09923ed819d2 Water Worries (2) -3d5f7153500339e05815cfa9c3e9369e Water Worries (4) -bc97954ab2fd772d67ed91d21cd67cfd Water Worries (A) -e39e1837ed467d2e26fb57d9f14624ed Water Worries (i) -d41d8cd98f00b204e9800998ecf8427e Water Worries (r) - -(water cd) -Joachim -bc97954ab2fd772d67ed91d21cd67cfd Water.(a) -ccca9a823d117afb1a882fd707586bf0 Water.d32 -20902148fe2cdaaf73ad7fdf3663c01d Water.exe -f1b0e0d587b85052de5534a3847e68fe Water.he0 -162e516eaea7f6635e0d09923ed819d2 Water.he2 -3d5f7153500339e05815cfa9c3e9369e Water.he4 -2856fa0e0e74484f9c55dc58b2e9203c Water.he7 -2eacfb93a578132a2194937dc4be7c85 WATER.w32 - - -(water cd russian) -sev -D:\scummsys\sputm80\*.c -214d0ece69f444cc2ced3fd7bc0738dc Water.a32 -2012f854d83d9cc6f73b2b544cd8bbf8 WATER.HE0 -967f8921b88bebc81dc08cef276cdb3f WATER.HE1 -243bedd4215ec0640df55a35394b6778 water.He2 -3d5f7153500339e05815cfa9c3e9369e WATER.HE4 -2856fa0e0e74484f9c55dc58b2e9203c WATER.HE7 - -(water cd russian updated) -sev -D:\scummsys\sputm80\*.c -c2e40b953f90ed35926a958cc8cb6a52 WATER.HE2 -3d5f7153500339e05815cfa9c3e9369e WATER.HE4 -2856fa0e0e74484f9c55dc58b2e9203c WATER.HE7 -0be4193477036d3b1c57b5aaa0f4a709 WATER.W32 -6271130f440066830eca9056c1d7926f water.he0 -96a30e55cb95fc0611e4353637d6e5a7 water.he1 - -(maze cd hfs) -Kirben -??? - -(maze cd) -Kirben -??? - -(super duper arcade 2 cd hfs) -Kirben, Joachim -20d2fe8f124bd4224c52f4a545995895 Maze Madness -4f04b321a95d4315ce6d65f8e1dd0368 Maze Madness (0) -4efc960a9e16764ad3cdaa64ee79f4f7 Maze Madness (1) -86e4d05f086ab253e41eea36f9953b7b Maze Madness (2) -818620a54fe0232fa17d6df1c3e547aa Maze Madness (4) -40175d873ed23efa26dd49e3e108e943 Maze Madness (8) - - -(super duper arcade 2 cd) -Kirben, Joachim -6b201406803dfce87682febb6d99c155 maze.a32 -0c80dbb40c4edb8c9c93f7cebc34f4ab MAZE.EXE -4f04b321a95d4315ce6d65f8e1dd0368 maze.HE0 -4efc960a9e16764ad3cdaa64ee79f4f7 maze.HE1 -86e4d05f086ab253e41eea36f9953b7b maze.he2 -818620a54fe0232fa17d6df1c3e547aa maze.he4 -40175d873ed23efa26dd49e3e108e943 maze.he8 - -(freddisfunshop cd hfs) -Joachim -430d3ede85344fe8ca75f8b446be8a53 Freddi's FunShop -16542a7342a918bfe4ba512007d36c47 Freddi's FunShop (0) -ac8faff875fd9e47328c0ad6dacc1326 Freddi's FunShop (2) -db2ef7f3fdce0c5aa8932138636ab63b Freddi's FunShop (4) -895b6746ab176b3ba3e70afa3ce6588b Freddi's FunShop (a) -7a7b1e2d7b17c616c300ea736276f8e4 Freddi's FunShop (b) -de6b13747c34a629162dd257cc4f0866 Freddi's FunShop (i) -2d4bcfe0a03f44876182664b303f2bf7 Freddi's FunShop (u) - -(freddisfunshop cd) -Joachim -895b6746ab176b3ba3e70afa3ce6588b FreddisFunShop.(a) -7a7b1e2d7b17c616c300ea736276f8e4 FreddisFunShop.(b) -ccca9a823d117afb1a882fd707586bf0 FreddisFunShop.d32 -4bb50266471b1955d423d40fc716ecbf FreddisFunShop.exe -16542a7342a918bfe4ba512007d36c47 FreddisFunShop.HE0 -ac8faff875fd9e47328c0ad6dacc1326 FreddisFunShop.he2 -db2ef7f3fdce0c5aa8932138636ab63b FreddisFunShop.he4 -d82da74cd5b040fdbee2330c85006810 FreddisFunShop.map -39c468587c4bdad304be49e8d4041a22 FreddisFunShop.u32 -1f102a306b108951c86d0ea9f849935c FreddisFunShop.w32 -a38b59ccd74792e348b57e6f07ce2ccc FreddisFunShop.x32 - -(puttputt cd/puttmoon cd/fbear cd) -khalek, sev, Joachim -7.0.0 (Feb 8 1995 16:33:26) -d4d3dd3b039a5c0ecfae502064b5b2de CATALOG.EXE -11e6e244078ff09b0f3832e35420e0a7 CATALOG.HE0 -0cb65eb736529221b9269b15a7fd1914 CATALOG.HE1 -c0e6ea1d47493cca09fc674c3d097836 CATALOG.HE2 -c0e6ea1d47493cca09fc674c3d097836 CATALOG.HE3 -1978944e3e597362d3f4f13606ab2264 CATALOG.W32 - -(farm cd/airport cd/jungle cd/airport hfs/jungle hfs) -khalek, sev, Joachim -7.0.0 (Jun 22 1995 14:01:50) -698d32c4dd2cca76918710665a8c3e6c CATALOG2.EXE -037385a953789190298494d92b89b3d0 CATALOG2.HE0 -d43e75c3e71f3668727f436b4c777334 CATALOG2.HE1 -c0e6ea1d47493cca09fc674c3d097836 CATALOG2.HE2 -c0e6ea1d47493cca09fc674c3d097836 CATALOG2.HE3 -d33843ac942167d564ae5682e2b381c3 CATALOG2.W32 - -(airport cd hfs) -Joachim -df6c3ad8f24c73b153e1d1fe1f011f5b The AirPort -d6334a5a9b61afe18c368540fdf522ca The AirPort (0) -e51ba2794c8fbe267b3cc9cf5f511ea9 The AirPort (1) -0d20f6a921a35ed907a875e26e050b9c The AirPort (2) -45348231d5da1aaa87e65ca170956eee The AirPort (4) -cb6ef7b42f7804834a731826567d4212 The AirPort (7) -765492059d83bc0ae8c30a4feef50a6a The AirPort (9) - -(trips collection cd/airport cd/airport cd hfs) -sev, Joachim -7.0.0 (Jul 1 1995 21:55:39) -d031299fa80f81b7348ed57665aea617 AIRPORT.EXE -07433205acdca3bc553d0e731588b35f AIRPORT.HE0 -1a40631092357a0a2fb63ed881a83730 AIRPORT.HE1 -0d20f6a921a35ed907a875e26e050b9c AIRPORT.HE2 -c0e6ea1d47493cca09fc674c3d097836 AIRPORT.HE3 -45348231d5da1aaa87e65ca170956eee AIRPORT.HE4 -cb6ef7b42f7804834a731826567d4212 AIRPORT.HE7 -765492059d83bc0ae8c30a4feef50a6a AIRPORT.HE9 -3c45181f2f31b7d67932295d0f2bafcb AIRPORT.W32 - -(farm cd hfs/freddi cd hfs/he classics hfs/chase hfs/baseball hfs/pajama2 hfs/freddi3 hfs/socks hfs/thinker1 hfs/thinkerk hfs/jungle hfs) -khalek, Joachim (comment: checked all MD5s, there is only 1 Mac-Demo-Version for sure) -1995-09-14 17:20 Airport Demo -af4f7ee28b83c0ba471459a779a34043 Airport Demo -7ea2da67ebabea4ac20cee9f4f9d2934 Airport Demo (0) -608f6b919b663642be7104c14440434f Airport Demo (1) -858db51aa87dd51df99c00c0bab31d65 Airport Demo (2) -42161ad979949daf67924b5227b94f2d Airport Demo (4) -765492059d83bc0ae8c30a4feef50a6a Airport Demo (9) - -(puttputt cd/fbear cd/puttmoon cd/) -khalek, sev, Joachim -7.0.0 (Feb 8 1995 16:33:47) -009e6924ae0913e7728e9a7f70f5a9db AIRDEMO.EXE -86c9902b7bec1a17926d4dae85beaa45 AIRDEMO.HE0 -e5ce3f8cddd5d54aaf2b040c831dcc96 AIRDEMO.HE1 -858db51aa87dd51df99c00c0bab31d65 AIRDEMO.HE2 -c0e6ea1d47493cca09fc674c3d097836 AIRDEMO.HE3 -42161ad979949daf67924b5227b94f2d AIRDEMO.HE4 -765492059d83bc0ae8c30a4feef50a6a AIRDEMO.HE9 -a16fc5d8c29efffb65f84f3a42b154f1 AIRDEMO.W32 - -(spyfox cd/pajama cd/puttzoo cd/he classics cd/freddi2 cd/baseball cd/thinker1 cd/thinkerk cd/socks cd/) -khalek, sev, Joachim -7.0.0 (Jul 5 1995 14:46:05) -371f3abc95359eff033e6ef47c27190b AIRDEMO.EXE -e144f5f49d9241d2a9dee2576b3d09cb AIRDEMO.HE0 -855ecd2da58317064d2e01263d6ca493 AIRDEMO.HE1 -858db51aa87dd51df99c00c0bab31d65 AIRDEMO.HE2 -c0e6ea1d47493cca09fc674c3d097836 AIRDEMO.HE3 -42161ad979949daf67924b5227b94f2d AIRDEMO.HE4 -765492059d83bc0ae8c30a4feef50a6a AIRDEMO.HE9 -a5459bfe36183cf1f4ced00fe325aa90 AIRDEMO.W32 - -(farm cd/airport cd/airport hfs/jungle cd/jungle hfs/) -khalek, sev, Joachim -7.0.0 (Jun 22 1995 14:06:25) -371f3abc95359eff033e6ef47c27190b AIRDEMO.EXE -8ffd618a776a4c0d8922bb28b09f8ce8 AIRDEMO.HE0 -64fb30a7c26d119216cdadaff1b4e1bd AIRDEMO.HE1 -858db51aa87dd51df99c00c0bab31d65 AIRDEMO.HE2 -c0e6ea1d47493cca09fc674c3d097836 AIRDEMO.HE3 -42161ad979949daf67924b5227b94f2d AIRDEMO.HE4 -765492059d83bc0ae8c30a4feef50a6a AIRDEMO.HE9 -3d43af3f3ecc18744dda721d951e2a2f AIRDEMO.W32 - -(freddi cd/pajama2 cd/freddi3 cd/chase cd) -khalek, sev, Joachim -7.0.0 (Jul 5 1995 14:46:05) -371f3abc95359eff033e6ef47c27190b AIRDEMO.EXE -8ffd618a776a4c0d8922bb28b09f8ce8 AIRDEMO.HE0 -64fb30a7c26d119216cdadaff1b4e1bd AIRDEMO.HE1 -858db51aa87dd51df99c00c0bab31d65 AIRDEMO.HE2 -c0e6ea1d47493cca09fc674c3d097836 AIRDEMO.HE3 -42161ad979949daf67924b5227b94f2d AIRDEMO.HE4 -765492059d83bc0ae8c30a4feef50a6a AIRDEMO.HE9 -a5459bfe36183cf1f4ced00fe325aa90 AIRDEMO.W32 - -(farm cd hfs) -khalek -1995-09-16 14:11 The Farm -f4f88abc0635e80a4fc8c605ce9d0db3 The Farm -fbbbb38a81fc9d6a61d509278390a290 The Farm (0) -3941f75ccb280e7c73890833f2a09514 The Farm (1) -e778f5f5bbc457966f6ac90ec8f3d9ee The Farm (2) -449029f90e778a4504de146ca9d0963b The Farm (4) -3d29c1d665dcb4e4b036dfc7752b990b The Farm (9) - -(farm cd/trips collection cd) -khalek, sev -7.0.0 (Jun 11 1996 19:12:56) -a85856675429fe88051744f755b72f93 farm.he0 -3e1111db20b879a482814b4a06122672 farm.he1 -e778f5f5bbc457966f6ac90ec8f3d9ee farm.he2 -c0e6ea1d47493cca09fc674c3d097836 farm.he3 -449029f90e778a4504de146ca9d0963b farm.he4 -3d29c1d665dcb4e4b036dfc7752b990b farm.he9 -fa49452f871e506a6930cc8697db6181 farm.w32 - -(airport hfs) -Joachim -19a57595f7d2367286058a41241e574a Farm Demo -39fd6db10d0222d817025c4d3346e3b4 Farm Demo (0) -ba3cb50770848a91216565b91edf8579 Farm Demo (1) -706d44b32f7c74e98ff4fe88d625826d Farm Demo (2) -ad6a4dea7b696a28b99d40ea1d685788 Farm Demo (4) - -(farm demo dutch) -adutchguy -??? - -(farm cd/pajama cd/airport cd/jungle cd/airport hfs/jungle hfs) -khalek, sev, Joachim -7.0.0 (Jun 22 1995 14:05:27) -2e698fdcf17be7de5c70e9a66d6e8fc0 FARMDEMO.EXE -8d479e36f35e80257dfc102cf4b8a912 FARMDEMO.HE0 -4d4cb9fdb5a0f3b651bbf0f80735cbe2 FARMDEMO.HE1 -706d44b32f7c74e98ff4fe88d625826d FARMDEMO.HE2 -c0e6ea1d47493cca09fc674c3d097836 FARMDEMO.HE3 -ad6a4dea7b696a28b99d40ea1d685788 FARMDEMO.HE4 -daca65342b60a86a8ba5fbbd5d8b71d4 FARMDEMO.W32 - -(puttputt cd/puttmoon cd/fbear cd) -khalek, sev, Joachim -7.0.0 (Oct 13 1994 19:15:16) -1b6b66d63a7e80edde33a9b2f57011ba FARMDEMO.EXE -bf8b52fdd9a69c67f34e8e9fec72661c FARMDEMO.HE0 -6f5d57f1fdc449424792d840a9c85acc FARMDEMO.HE1 -706d44b32f7c74e98ff4fe88d625826d FARMDEMO.HE2 -1c26d0c926e9c31d1b77c0611a643dc9 FARMDEMO.HE3 -cdadbf8daf9c8f811dac28d348ff8825 FARMDEMO.W32 - -(jungle hfs) -Joachim -0e896300a0af8bd43f82d57a9da6a525 The Jungle -659942b9a6b519f123a13cca3c333a13 The Jungle (0) -0212155e5de27230b4ce5e36fb910945 The Jungle (1) -9a5bf899124f45288749d81a0918907a The Jungle (2) -222ad352670c1d94366a8511af846f49 The Jungle (4) -f80c48c622ba21d46fc518630f324cf7 The Jungle (9) - - -(trips collection cd/jungle cd) -sev, joachim -7.0.0 (Oct 5 1995 08:20:42) -11994b691574b2ecea7043a80a908647 JUNGLE.EXE -8801fb4a1200b347f7a38523339526dd JUNGLE.HE0 -1b39261e8d7e7384cf47fe9a6fa808d8 JUNGLE.HE1 -9a5bf899124f45288749d81a0918907a JUNGLE.HE2 -c0e6ea1d47493cca09fc674c3d097836 JUNGLE.HE3 -222ad352670c1d94366a8511af846f49 JUNGLE.HE4 -f80c48c622ba21d46fc518630f324cf7 JUNGLE.HE9 -d8561c70fe52082eace566fe038995f7 JUNGLE.W32 - -(pajama cd hfs) -Kirben -??? - -(pajama cd) -Kirben -??? - -(pajama cd hfs) -khalek -1996-09-12 20:55 Pajama Sam -57fab7dc46bb7d9450970d95cf14e8fc Pajama Sam -672dec94b82f7f0877ebb5b5cf7f4bc1 Pajama Sam (0) -2e83592ae635f53d1cc94c3d98da6335 Pajama Sam (1) -048a2cb8baad19ca90a4510783ab032b Pajama Sam (2) -147be86929b5969224c72edac30896fd Pajama Sam (4) -2546d42491fa61ac8e2d20d68d264fce Pajama Sam (7) - -(pajama cd) -khalek, sev -1996-09-14 00:28 pajama.w32 -D:\Scummsrc.80\Sputm\*.c -672dec94b82f7f0877ebb5b5cf7f4bc1 pajama.he0 -2e83592ae635f53d1cc94c3d98da6335 pajama.he1 -048a2cb8baad19ca90a4510783ab032b pajama.he2 -4417ea03a6d1b0b7522526f41d1097f6 pajama.he3 -147be86929b5969224c72edac30896fd pajama.he4 -2546d42491fa61ac8e2d20d68d264fce pajama.he7 -8e0e6d39728cc6a87b32f5e71f602b20 pajama.w32 - -(pajama cd dutch) -joostp -??? - -(pajama cd) -Joachim -1e5baa49222b0f6a6cb671bf6cb208d8 Pajama.(a) -ccca9a823d117afb1a882fd707586bf0 pajama.d32 -8f18bc14ff62d55d20cb3a9dc2ac1451 Pajama.exe -898eaa21f79cf8d4f08db856244689ff Pajama.HE0 -4dc07befa5e311abd787a2580c91a12d Pajama.he2 -f81b518a579d83c8d4d1911a365ea982 Pajama.he3 -147be86929b5969224c72edac30896fd Pajama.he4 -2546d42491fa61ac8e2d20d68d264fce Pajama.he7 -2c0273605aecaf223287da677679e42a pajama.w32 - -(freddi cd hfs/he classics hfs/puttzoo cd hfs) -khalek -1997-10-28 17:16 Pajama Sam Demo -3b032e02ccbc5d65c7397cfb32f65f1d Pajama Sam Demo -f237bf8a5ef9af78b2a6a4f3901da341 Pajama Sam Demo (0) -5c12305ff68ed053daba74a700a56ad2 Pajama Sam Demo (1) -4ccd03ca710a9053c42292cae09a6471 Pajama Sam Demo (2) -6e0fdfcf13e37b659b7155cf5969965f Pajama Sam Demo (4) - -(spyfox cd/puttzoo cd/he classics cd/pajama2 cd/freddi cd/freddi2 cd/freddi3 cd/baseball cd) -khalek, sev, Joachim -1996-10-31 22:34 pjs-demo.w32 -D:\Scummsrc.80\Sputm\*.c -11875252dea74302ea77f8adeaf9c2e9 PJS-DEMO.EXE -f237bf8a5ef9af78b2a6a4f3901da341 PJS-DEMO.HE0 -5c12305ff68ed053daba74a700a56ad2 PJS-DEMO.HE1 -4ccd03ca710a9053c42292cae09a6471 PJS-DEMO.HE2 -6e0fdfcf13e37b659b7155cf5969965f PJS-DEMO.HE4 -0c7e0d0ef005f289e9ca06bbbf5e8839 PJS-DEMO.W32 - -(pajama demo hfs) -khalek -??? - -(ftp) -2002-05-20 15:11 PjSamDemo.exe -khalek, sev -c:\Build\SRC\SPUTM\Src\SrcPWin\*.cpp -1f5564cba5d070703c85fe8eda1f6236 PjSamDemo.(a) -2c380ca1224d0c83a9de178546028cb5 PjSamDemo.exe -d7ab7cd6105546016e6a0d46fb36b964 PjSamDemo.he0 -5207295bb0b0e0b3f71b7593dd7c3a81 PjSamDemo.he2 -6e0fdfcf13e37b659b7155cf5969965f PjSamDemo.he4 - -(pajama demo hfs french) -Kirben -??? - -(pajama demo french) -Kirben -??? - -(pajama demo dutch) -adutchguy -??? - -(pajama2 cd hfs) -Joachim -b921d8279b5a3aa567c669b83d89e489 Pajama Sam 2 -d4e79c3d8645b8266cd78c325bc35154 Pajama Sam 2 (0) -cf1e7394ae00c0c65fa5af486e752e5c Pajama Sam 2 (1) -53f95adc8f6727d26e3248fb1bad8180 Pajama Sam 2 (2) -297787a960f2b591bb98add9b0689e9f Pajama Sam 2 (4) -d41d8cd98f00b204e9800998ecf8427e Pajama Sam 2 (r) - -(pajama2 cd) -sev, Joachim -D:\scummsys.95\sputm.95\*.cpp -ccca9a823d117afb1a882fd707586bf0 PAJAMA2.D32 -1830278a7bef7d5800ba02f816dbe373 PAJAMA2.EXE -d4e79c3d8645b8266cd78c325bc35154 PAJAMA2.HE0 -cf1e7394ae00c0c65fa5af486e752e5c PAJAMA2.HE1 -53f95adc8f6727d26e3248fb1bad8180 PAJAMA2.HE2 -297787a960f2b591bb98add9b0689e9f PAJAMA2.HE4 -44a282944b6392ad883a48fc03f37146 PAJAMA2.W32 -58dfc09f344a9dec565bb914920800d3 PAJAMA2.X32 - -(pajama2 cd hfs german) -Joachim -7ba80800b1302376b3a3d4d26d42aa50 PyjamaDBMN -c6907d44f1166941d982864cd42cdc89 PyjamaDBMN (0) -b4ecb33716598531823dc2a971a762f1 PyjamaDBMN (2) -297787a960f2b591bb98add9b0689e9f PyjamaDBMN (4) -55f4e9402bec2bded383843123f37c5c PyjamaDBMN (a) -01368f1a5c87746b09f50363696f5883 PyjamaDBMN (i) - -(pajama2 cd german) -Joachim -55f4e9402bec2bded383843123f37c5c PyjamaDBMN.(a) -b27cc88bc13451e9334fbf1d5f3c9c52 PyjamaDBMN.D32 -cecafac67b1f299b6f1c326bc58ba50f PyjamaDBMN.EXE -c6907d44f1166941d982864cd42cdc89 PyjamaDBMN.HE0 -b4ecb33716598531823dc2a971a762f1 PyjamaDBMN.HE2 -297787a960f2b591bb98add9b0689e9f PyjamaDBMN.HE4 -b27bf7501668c7244baf779a947b585c PyjamaDBMN.w32 - -(pajama2 cd russian updated) -sev -d:\dev\SPUTM\Src\*.cpp -486b48e4ae421cdbecfcc1431c7e801f PajamaTAL.(a) -738be524db140dc1c7fd6ddfab647c0b PajamaTAL.exe -32709cbeeb3044b34129950860a83f14 PajamaTAL.he0 -f71fe00306d8246bd5f7ee99703aaaff PajamaTAL.he2 -297787a960f2b591bb98add9b0689e9f PajamaTAL.he4 - -(pajama2 demo dutch hfs) -Kirben -??? - -(pajama2 demo dutch) -Kirben -??? - -(freddi2 cd hfs/freddi4 cd hfs/pajama3 cd hfs/puttrace cd hfs/putttime cd hfs/puttzoo cd hfs/spyfox cd hfs/superarcade1 cd hfs/superarcade2 cd hfs/water cd hfs/football cd hfs/soccer cd hfs) -sev, Joachim -01bae6f21e5c42b6a776efd57f363eb1 PJ2Demo -36a6750e03fb505fc19fc2bf3e4dbe91 PJ2Demo (0) -6b1f2b0359d146fda362f1b81892fc76 PJ2Demo (1) -0c8b86610f358f9a6b45cdd45cb70a58 PJ2Demo (2) -0f28e36711b55cc139921ddaaff6b341 PJ2Demo (4) -d41d8cd98f00b204e9800998ecf8427e PJ2Demo (r) - -(freddi2 cd/freddi4 cd/pajama3 cd/puttrace cd/putttime cd/puttzoo cd/spyfox cd/superarcade1 cd/superarcade2 cd/water cd/football cd/soccer cd ) -Joachim -ccca9a823d117afb1a882fd707586bf0 PJ2DEMO.D32 -44a282944b6392ad883a48fc03f37146 PJ2DEMO.EXE -36a6750e03fb505fc19fc2bf3e4dbe91 PJ2DEMO.HE0 -6b1f2b0359d146fda362f1b81892fc76 PJ2DEMO.HE1 -0c8b86610f358f9a6b45cdd45cb70a58 PJ2DEMO.HE2 -0f28e36711b55cc139921ddaaff6b341 PJ2DEMO.HE4 -58dfc09f344a9dec565bb914920800d3 PJ2DEMO.X32 - - -(ftp/puttrace cd/dog cd/spyfox2 cd/putttime cd/football cd/soccer cd) -1998-05-09 20:27 PJ2DEMO.W32 -khalek -D:\scummsys.95\sputm.95\*.c -36a6750e03fb505fc19fc2bf3e4dbe91 PJ2DEMO.HE0 -6b1f2b0359d146fda362f1b81892fc76 PJ2DEMO.HE1 -0c8b86610f358f9a6b45cdd45cb70a58 PJ2DEMO.HE2 -0f28e36711b55cc139921ddaaff6b341 PJ2DEMO.HE4 -44a282944b6392ad883a48fc03f37146 PJ2DEMO.W32 - -(pajama3 cd hfs) -Joachim -0b642feb91da52a174e192a082fcc70f Pajama Sam 3 -f7711f9264d4d43c2a1518ec7c10a607 Pajama Sam 3 (0) -978c86a8313b66d3b254c3b43e034460 Pajama Sam 3 (2) -87938c64ef72195231d58fec4f5add88 Pajama Sam 3 (4) -f7b0ad01b6a78bcd3854edd0ee9694df Pajama Sam 3 (a) -5a40804b409c888525b04361a907dd39 Pajama Sam 3 (i) - -(pajama3 cd) -sev, Joachim -C:\Dev\Project\SPUTM\Src\*.cpp -f7b0ad01b6a78bcd3854edd0ee9694df PAJAMA3.(A) -ccca9a823d117afb1a882fd707586bf0 Pajama3.d32 -aaf2001f4d7120fccac9123278cb0db2 Pajama3.exe -f7711f9264d4d43c2a1518ec7c10a607 PAJAMA3.HE0 -978c86a8313b66d3b254c3b43e034460 PAJAMA3.HE2 -87938c64ef72195231d58fec4f5add88 PAJAMA3.HE4 -7c4127882d847866cafd474b914da595 Pajama3.w32 - -(pajama3 cd hfs german) -Joachim -d47b3fa7fbb331d83b4cdcf6effc88d6 PyjamaSkS -2e8a1f76ea33bc5e04347646feee173d PyjamaSKS (0) -2d9d0e25c050cc1d30d78d5d2c475178 PyjamaSKS (2) -435437659b3c647c5a223e143e219846 PyjamaSKS (4) -3694b1ef70da192f3c19cd24638ec79b PyjamaSKS (a) -d41d8cd98f00b204e9800998ecf8427e PyjamaSkS (i) - - -(pajama3 cd german) -Joachim -3694b1ef70da192f3c19cd24638ec79b PyjamaSKS.(a) -c8538fa7fbb9c1b09bc4b833e04ce0dd PyjamaSKS.d32 -24efc2c233d1dfcf32e75c877e7640c0 PyjamaSKS.exe -2e8a1f76ea33bc5e04347646feee173d PyjamaSKS.HE0 -2d9d0e25c050cc1d30d78d5d2c475178 PyjamaSKS.he2 -435437659b3c647c5a223e143e219846 PyjamaSKS.he4 -88084b7b68f19dc5ded4dc5a5a8c3c76 PyjamaSKS.w32 - -(pajama3 cd russian) -sev -C:\HESystems\SPUTM\Src\SrcPWin\*.cpp -20176076d708bf14407bcc9bdcd7a418 UKPajamaEAT.he0 -6c0b2725387fe0b0bc7bfe043714492b UKPajamaEAT.(a) -eea6df70b4930c0d9e2ea69a1a193fc5 UKpajamaEAT.he2 -a7f5e841f72a72c0dec10d7d9fd74a51 UKpajamaEAT.HE4 - -(pajama3 demo hfs dutch) -joostp -??? - -(pajama3 demo dutch) -joostp -??? - -(puttcircus cd hfs/spyozon cd hfsfreddicove cd hfs) -Joachim -e221e2a53e9726ecb9bc422ed7650d42 Pajama Sam 3-Demo -a9f2f04b1ecaab9495b59befffe9bf88 Pajama Sam 3-Demo (0) -057190fd8706c51c6e6657a8eb8f6898 Pajama Sam 3-Demo (2) -d5b1d81d25d3d4850184fdb0ab627bea Pajama Sam 3-Demo (4) -e305c20b5d26d7084f035be22617d8a8 Pajama Sam 3-Demo (a) -d41d8cd98f00b204e9800998ecf8427e Pajama Sam 3-Demo (i) - -(puttcircus cd/spyozon cd/freddicove cd/soccerMLS cd) -sev, Joachim -e305c20b5d26d7084f035be22617d8a8 pj3-demo.(a) -ccca9a823d117afb1a882fd707586bf0 pj3-demo.D32 -7c4127882d847866cafd474b914da595 pj3-demo.exe -a9f2f04b1ecaab9495b59befffe9bf88 pj3-demo.HE0 -057190fd8706c51c6e6657a8eb8f6898 pj3-demo.he2 -d5b1d81d25d3d4850184fdb0ab627bea pj3-demo.he4 - -(freddi3 cd hfs german/pajama2 cd hfs german/putttime cd hfs german/spyfox cd hfs german) -Joachim -37c439a53e3b0426f8e1a57e56e1f9eb PJ3Demo -0c45eb4baff0c12c3d9dfa889c8070ab PJ3Demo (0) -5989dc5d4fecf651db4d5f497ee36d0d PJ3Demo (2) -44cef52dfec87a2dcccda97f3ac6b2cd PJ3Demo (4) -e04352df925c102041c6e954bc86d71c PJ3Demo (a) -d41d8cd98f00b204e9800998ecf8427e PJ3Demo (i) - -(freddi3 cd german/pajama2 cd german/putttime cd german/spyfox cd german) -Joachim -e04352df925c102041c6e954bc86d71c Gpj3demo.(a) -2188b22aa1534b5248a8aa7dfa9c7861 GPJ3Demo.d32 -45d9f75902265d1ecbfbf5ff37a7bc70 GPJ3Demo.exe -0c45eb4baff0c12c3d9dfa889c8070ab Gpj3demo.HE0 -5989dc5d4fecf651db4d5f497ee36d0d GPJ3Demo.HE2 -44cef52dfec87a2dcccda97f3ac6b2cd GPJ3Demo.HE4 - -(puttsfunshop cd hfs/freddisfunshop cd hfs/samsfunshop cd hfs) -Joachim -e221e2a53e9726ecb9bc422ed7650d42 Pajama Sam 3-Demo -a654fb60c3b67d6317a7894ffd9f25c5 Pajama Sam 3-Demo (0) -057190fd8706c51c6e6657a8eb8f6898 Pajama Sam 3-Demo (2) -d5b1d81d25d3d4850184fdb0ab627bea Pajama Sam 3-Demo (4) -795bb07d00d8628631e767d2c23fba56 Pajama Sam 3-Demo (a) -d41d8cd98f00b204e9800998ecf8427e Pajama Sam 3-Demo (i) - -(puttsfunshop cd/freddisfunshop cd/samsfunshop cd) -sev, Joachim -C:\Dev\Project\SPUTM\Src\*.cpp -795bb07d00d8628631e767d2c23fba56 pj3-demo.(a) -ccca9a823d117afb1a882fd707586bf0 pj3-demo.D32 -7c4127882d847866cafd474b914da595 pj3-demo.exe -a654fb60c3b67d6317a7894ffd9f25c5 pj3-demo.HE0 -057190fd8706c51c6e6657a8eb8f6898 pj3-demo.he2 -d5b1d81d25d3d4850184fdb0ab627bea pj3-demo.he4 - -2002-10-19 11:37 pj3-demo.w32 -khalek -C:\Dev\Project\SPUTM\Src\*.cpp -a2fe82b76e0e3db5d8e2f44ec9772548 pj3-demo.(a) -cf90b4db5486ef798db78fe6fbf897e5 pj3-demo.he0 -e923a8f282ad6900b24beb562894661f pj3-demo.he2 -d5b1d81d25d3d4850184fdb0ab627bea pj3-demo.he4 -7c4127882d847866cafd474b914da595 pj3-demo.w32 - -(PuttPutt CD UK release) -eriktorbjorn -d:\dev\SPUTM\Src\*.cpp -5b0f71b2503688d8783f4cc37c302666 PJ3DEMO.(A) -2702b7fad34607adea8e8a7b6adb1202 pj3demo.exe -3e48298920fab9b7aec5a971e1bd1fab PJ3DEMO.HE0 -22df1316d6594bc5c70442874079c46d Pj3Demo.he2 -0794110b085ee91c2aa4a5fc844ff2f4 Pj3Demo.he4 - -(pjgames cd hfs) -Kirben -??? - -(pjgames cd) -Kirben -??? - -(lost cd hfs) -Kirben -??? - -(lost cd) -Kirben -??? - -(superarcade2 cd hfs) -Kirben, Joachim -deb9d0989a2ffa00f77c06360b4e4794 Lost and Found -ed361270102e355afe5236954216aba2 Lost and Found (0) -2f1636bf18a437092f7e3de9614c7c49 Lost and Found (2) -e0499c7a9aad75122c902934aaa98b62 Lost and Found (a) -d41d8cd98f00b204e9800998ecf8427e Lost and Found (r) - - -(superarcade2 cd) -Kirben, Joachim -e0499c7a9aad75122c902934aaa98b62 lost.(a) -4a4564b8bdd8b3c004f2f84bf5e7fc85 lost.a32 -ccca9a823d117afb1a882fd707586bf0 lost.d32 -9d01495e4f8b34e4aefb1e29adcdd37f LOST.EXE -ed361270102e355afe5236954216aba2 lost.HE0 -2f1636bf18a437092f7e3de9614c7c49 lost.he2 - -(lost demo) -1999-07-08 08:46 SMALLER.EXE -khalek -D:\(vss)scummsys.99\SPUTM\Src\SrcPWin\*.cpp -070702d4a191580455acee3d38d5ca9e smaller.(a) -7d2b945c2afb05a370da690c36b22bdd SMALLER.EXE -a2bb6aa0537402c1b3c2ea899ccef64b SMALLER.HE0 -7fe73db8981467a6d0abdd92105f8618 data/world-1/levels/level-10.ot1 -b988a3d95f638bb342135d9bd04e0137 data/world-1/levels/level-10.ot2 -ce60d91581be1cde2d0619a85647b1a9 data/world-1/levels/level-11.ot1 -8cd6dea0b18593c8d1aaa12daff10cc7 data/world-1/levels/level-11.ot2 -7bfa53f7aa0b06372472b7fa475254cb data/world-1/levels/level-12.ot1 -ad2e8c62013a1aee64e3af638d7fac3a data/world-1/levels/level-12.ot2 -0dda1de323c63baa645863259937cfaa data/world-1/levels/level-13.ot1 -0832514ef1b2206b119054e838003241 data/world-1/levels/level-13.ot2 -08b28bfae2169083bdaf2635faf75213 data/world-1/levels/level-14.ot1 -510121696a26e6410766d3d414a4a1ed data/world-1/levels/level-14.ot2 -459027319d6db400bbb60acd37dd31a0 data/world-1/levels/level-15.ot1 -7c73fcd8abcb837bbcb72457eb71da44 data/world-1/levels/level-15.ot2 -ec75f20929d3ab9ad7b68b650e55b713 data/world-1/levels/level-16.ot1 -f90cd5c12b9dc3777b3371460bb6da1f data/world-1/levels/level-16.ot2 -085feba2672c7dc41570726e098d0d02 data/world-1/levels/level-17.ot1 -4a85080de411c54dcfd42b9929e1c0c3 data/world-1/levels/level-17.ot2 -37dacba43a2407c31d8a69dd302991a7 data/world-1/levels/level-18.ot1 -0dbc99bedd086e11dcf78794e1a21d50 data/world-1/levels/level-18.ot2 -67d9d144436e57215212bf65c6665395 data/world-1/levels/level-19.ot1 -679c0c4cdb9781ca9fe73d1f4314fc50 data/world-1/levels/level-19.ot2 -c60abc377414f72a16341901c4895b41 data/world-1/levels/level-1.ot1 -b69f642322a618c2c122e40f9533dd86 data/world-1/levels/level-1.ot2 -93de8918e2d6d35d04f21f067203b8f7 data/world-1/levels/level-20.ot1 -f5da057f3408613b5b8ed0bcd876833f data/world-1/levels/level-20.ot2 -8b175a1cb5722fccd2c649ff15e85e39 data/world-1/levels/level-2.ot1 -f958fbf2de135bcfdffd9e8d0cbfcaa4 data/world-1/levels/level-2.ot2 -453569e6100e194b2e40e52ea13a1747 data/world-1/levels/level-3.ot1 -388bb8ae5805a87ec6a9af5ffef67b65 data/world-1/levels/level-3.ot2 -a6719d4797937bc1501015d8ba02faf3 data/world-1/levels/level-4.ot1 -69946a0c1fded7a1cd1fd7e5da5bc716 data/world-1/levels/level-4.ot2 -170121ca31f889039771cf76a01fd60b data/world-1/levels/level-5.ot1 -9cd61c833f3342b881c280dd7c746db8 data/world-1/levels/level-5.ot2 -cfe953b525b530f144ba322f8969e9b8 data/world-1/levels/level-6.ot1 -650563fd608cc5f6418a20bdb3e3f6eb data/world-1/levels/level-6.ot2 -dd1d60970ff90ffe00f6a201b125ddd1 data/world-1/levels/level-7.ot1 -e5598a32e874f7451581c2fcc8118e8a data/world-1/levels/level-7.ot2 -8d9b7d1e209aa6103b5440d098e005ee data/world-1/levels/level-8.ot1 -f69c2ce78a6f2a70bf43f0cf665ac075 data/world-1/levels/level-8.ot2 -049b95a44520347dabf1d14b1cd9b9f4 data/world-1/levels/level-9.ot1 -b6087413d0aac4078203a1ef5fd88cb8 data/world-1/levels/level-9.ot2 - -(samsfunshop cd hfs) -Joachim -b4673b59ed60b26fda077c43993102ab Sam's FunShop -68155a6bf082221525f431c2cbdac8ab Sam's FunShop (0) -2e44235ef224b25ce766eab34ecc0ab5 Sam's FunShop (2) -c13b823a4f12d20a22f01acdc89102dc Sam's FunShop (4) -35202bb9a0fa8fa23bbc3c9b606ad6b6 Sam's FunShop (a) -eebac1d5bf74832aae8031c47c699197 Sam's FunShop (b) -78d5350b0d208be368e1169c6f53728b Sam's FunShop (i) -2d4bcfe0a03f44876182664b303f2bf7 Sam's FunShop (u) - -(samsfunshop cd) -Joachim -35202bb9a0fa8fa23bbc3c9b606ad6b6 SamsFunShop.(a) -eebac1d5bf74832aae8031c47c699197 SamsFunShop.(b) -ccca9a823d117afb1a882fd707586bf0 SamsFunShop.d32 -486422eba1f7ca37c6314ad13e00a041 SamsFunShop.exe -68155a6bf082221525f431c2cbdac8ab SamsFunShop.HE0 -2e44235ef224b25ce766eab34ecc0ab5 SamsFunShop.he2 -c13b823a4f12d20a22f01acdc89102dc SAMSFUNSHOP.HE4 -e03725ba7069e7a94c28168b70dc99c4 SamsFunShop.r32 -39c468587c4bdad304be49e8d4041a22 SamsFunShop.u32 -591674119a23295aede9ced62642498a SamsFunShop.w32 -a38b59ccd74792e348b57e6f07ce2ccc SamsFunShop.x32 - -(sock cd hfs/superarcade1 cd hfs) -Joachim -8351724df7b6141c57596a70f71261d1 SockWorks -5e8fb66971a60e523e5afbc4c129c0e8 SockWorks (0) -a8ae3fedb8ff53e798d22e495929812f SockWorks (1) -70c23a4651349e957ac8996275fe66f3 SockWorks (2) -14a5574aeae3187bbb71ce7f4a1b803b SockWorks (4) -c137e6e5d636c13df8ccb108523640cc SockWorks (7) - -(sock cd) -Joachim -6e076d748dd4726d1d7a230cfdb13dec SOCKS.D32 -be18099a608458fb63bc996a86195a73 SOCKS.DLL -d82c48a90176dafb1f344f13a0cefb60 SOCKS.EXE -5e8fb66971a60e523e5afbc4c129c0e8 SOCKS.HE0 -a8ae3fedb8ff53e798d22e495929812f SOCKS.HE1 -70c23a4651349e957ac8996275fe66f3 SOCKS.HE2 -14a5574aeae3187bbb71ce7f4a1b803b SOCKS.HE4 -c137e6e5d636c13df8ccb108523640cc SOCKS.HE7 -619755f82f852d94f252add9bbc73a61 SOCKS.W32 - -(superarcade1 cd) -Joachim -619755f82f852d94f252add9bbc73a61 Socks.a32 -6e076d748dd4726d1d7a230cfdb13dec socks.d32 -be18099a608458fb63bc996a86195a73 SOCKS.DLL -aa2b672c687c4cda492e3d9ceb7486eb socks.exe -5e8fb66971a60e523e5afbc4c129c0e8 SOCKS.HE0 -a8ae3fedb8ff53e798d22e495929812f SOCKS.HE1 -70c23a4651349e957ac8996275fe66f3 SOCKS.HE2 -14a5574aeae3187bbb71ce7f4a1b803b SOCKS.HE4 -c137e6e5d636c13df8ccb108523640cc SOCKS.HE7 - -(socks cd russian) -sev -D:\scummsys.80\sputm80\*.c -19263586f749a560c1adf8b3393a9593 SOCKS.HE0 -d4bc7dd56e22720c96ecf96bd68fbecd SOCKS.HE1 -5b1e928ecb604dba17e41fb739218a49 SOCKS.HE2 -14a5574aeae3187bbb71ce7f4a1b803b SOCKS.HE4 -c137e6e5d636c13df8ccb108523640cc SOCKS.HE7 -65b08876afc8c55b8dbb2022fb1b6a95 Socks.a32 - - -<----END OF WORK TODAY----> - -(puttrace cd hfs) -Joachim -??? - -(puttrace cd) -sev -D:\scummsys.98\sputm.98\*.c -ef68d6670cce33d4300468d0b76b3894 puttrace.(a) -e56b14495c0075850c900ca0999f90f4 puttrace.(b) -7ded875e14d324f610a4fde12de2d407 PUTTRACE.A32 -981e1e1891f2be7e25a01f50ae55a5af PUTTRACE.HE0 -1bb81a151d72f56b81b43b55b1de63e4 PUTTRACE.HE2 -3f368bd19438204b34db7d7ff8e5395d PUTTRACE.HE4 - -(puttrace cd russian) -sev -C:\HESystems\SPUTM\Src\*.cpp -cde08c76ce62dcb6081a3fb7dfd2bc89 UKPuttRace.(a) -e348fe80ca1a40a30bd57ff9d08812c0 UKPuttRace.(b) -62050da376483d8edcbd98cd26b6cb57 UKPuttRace.he0 -fdd32528084cd48078bb073ead02d2a9 UKPuttRace.he2 -4dfdf4303fa6769535eba7fed539002e UKPuttRace.he4 -91c0bc455b81e7e556646db1dacd461f UKPuttRace.w32 - -(puttrace cd russian alt) ALL IN MD5 -sev -D:\scummsys.98\sputm.98\*.c -fe0cbe12588be2c8e509603821566a87 Puttrace.(a) -e56b14495c0075850c900ca0999f90f4 Puttrace.(b) -86821f1e71e2a2d679da7827485fdab1 PUTTRACE.A32 -981e1e1891f2be7e25a01f50ae55a5af PUTTRACE.HE0 -544b59d0b904a745033e1850c07a8b5f Puttrace.he2 -5d930459fd1827eaa9df846a20757932 Puttrace.he4 - -(puttrace cd hfs german) -Joachim -??? - -(puttrace cd german) -Joachim -??? - -(puttrace demo hfs dutch) -Kirben -??? - -(puttrace demo dutch) -Kirben -??? - -(puttrace demo hfs dutch) -joostp -??? - -(puttrace demo dutch) -joostp -??? - -(puttrace demo hfs) -sev -??? - -(pajama3 cd/putt dog cd/spyfox2 cd/puttcircus cd/putttime cd/football cd) -sev -D:\scummsys.98\sputm.98\*.c -36590dcf019a0fa78de77354cf4db342 RACEDEMO.(A) -7ded875e14d324f610a4fde12de2d407 RACEDEMO.A32 -8e1d77b06c92662ef5128b087f84f229 racedemo.exe -0ac41e2e3d2174e5a042a6b565328dba RACEDEMO.HE0 -07e92dfae14eb6ef3afc6d40ba98fcd2 RACEDEMO.HE2 -e80168dc9bfca4577b4e2bbdd70db60b RACEDEMO.HE4 - -2002-05-07 02:53 RACEDEMO.W32 -khalek -D:\scummsys.98\sputm.98\*.c -36590dcf019a0fa78de77354cf4db342 RACEDEMO.(A) -0ac41e2e3d2174e5a042a6b565328dba RACEDEMO.HE0 -07e92dfae14eb6ef3afc6d40ba98fcd2 RACEDEMO.HE2 -e80168dc9bfca4577b4e2bbdd70db60b RACEDEMO.HE4 -a030210d465ed001953df89e3df1e558 RACEDEMO.W32 - -(puttrace demo hfs german) -Joachim -??? - -(puttrace demo german) -Joachim -??? - -(PuttPutt CD UK release) -eriktorbjorn -d:\dev\SPUTM\Src\*.cpp -cb6041f10fbaaa5e491aa8d14fc26dc0 RACEDEMO.(A) -3616b3bf5877b2fb50ce33c705f15413 racedemo.exe -7c8100e360e8ef05f88069d4cfa0afd1 RACEDEMO.HE0 -095795832ad8a4323bbfa6c137b691bb RACEDEMO.HE4 -177f4e5579e0279700c2b6b7f4f4ba71 RaceDemo.he2 - -(puttmoon 3do) -sev -??? - -(he classics cd) -khalek, sev -6.1.1 (Nov 4 1993 11:12:57) -19113cc2ecc1dc24c70c46ae015abd78 PUTTMOON.BRS -c6adfe1876ac936ff19546f0cd1e2b5b PUTTMOON.EXE -780e4a0ae2ff17dc296f4a79543b44f8 PUTTMOON.HE0 -f02f36270d684e0c245d0fd0519b5e7b PUTTMOON.HE1 -bfecc91f0bf7b86acd7f82a3dfb53ca5 PUTTMOON.TLK - -(puttmoon cd russian) -sev -6.1.1 (Nov 4 1993 11:12:57) -c6adfe1876ac936ff19546f0cd1e2b5b PUTTMOON.EXE -780e4a0ae2ff17dc296f4a79543b44f8 PUTTMOON.HE0 -6a9457c786a8dcf8d2da8a2ec0123343 PUTTMOON.HE1 -c57a7faf7416d9da11919d0957332574 PUTTMOON.SG0 -3d6deb9406a3357764d11623ed6e48ee PUTTMOON.SG1 -1927fb2e7954326152630cb0f56158f8 PUTTMOON.TLK - -(puttmoon cd russian alt) -sev -6.1.1 (Nov 4 1993 11:12:57) -c6adfe1876ac936ff19546f0cd1e2b5b PUTTMOON.EXE -780e4a0ae2ff17dc296f4a79543b44f8 PUTTMOON.HE0 -2de9f712c62fab29507298c9f69591ec PUTTMOON.HE1 -c57a7faf7416d9da11919d0957332574 PUTTMOON.SG0 -3d6deb9406a3357764d11623ed6e48ee PUTTMOON.SG1 -3a35a45c5634203c72b9f2083e0d5717 PUTTMOON.TLK - -(puttmoon cd hebrew) -sev -??? - -(he classics cd hfs) -khalek -9dc02577bf50d4cfaf3de3fbac06fbe2 Putt-Putt Moon 0 -e4e07a2763824a7646e11b6d9ad795c8 Putt-Putt Moon 1 -bfecc91f0bf7b86acd7f82a3dfb53ca5 Putt-Putt Moon 2 -19113cc2ecc1dc24c70c46ae015abd78 PUTTMOON.BRS - -(he classics cd) -khalek, sev -7.0.0 (Feb 7 1995 13:27:20) -19113cc2ecc1dc24c70c46ae015abd78 PUTTMOON.BRS -9c92eeaf517a31b7221ec2546ab669fd PUTTMOON.HE0 -cfe6d4059c4c5edb9f9f2351efb32a7b PUTTMOON.HE1 -965c113b3978682530e121ba8af7419b PUTTMOON.HE2 -58dfc09f344a9dec565bb914920800d3 PUTTMOON.HE3 -05d387396aabba20e7e3b8778bc0cf09 PUTTMOON.HE4 -56c8455570af6106931818e19344b46a PUTTMOON.W32 - -6.1.1 (Sep 29 1993 17:18:45) -khalek -ef2d93dd02bcdabc7a1a59101e31f8be MOONDEMO.EXE -aa6a91b7f6f119d1b7b1f2a4c9e24d59 MOONDEMO.HE0 -086b6835bbb924109a31e50f0b5c9e9a MOONDEMO.HE1 -0d06e43d5b5460375575a74d15d6bf07 MOONDEMO.TLK - -(puttmoon demo hfs) -khalek -??? - -(puttputt cd/he classics cd) -khalek, sev -7.0.0 (Feb 7 1995 13:27:20) -9c143c5905055d5df7a0f014ab379aee moondemo.he0 -ec82bd61eff3218216fb145004d2b005 moondemo.he1 -0d06e43d5b5460375575a74d15d6bf07 moondemo.he2 -7cf09a515cb499890e3faeab3a2aa491 moondemo.he3 -c182763838b5d06581cc9fb1c1bb1cfd moondemo.he4 -56c8455570af6106931818e19344b46a moondemo.w32 - -(puttcircus cd hfs) -sev -??? - -(puttcircus cd) -sev -C:\Dev\Project\SPUTM\Src\*.cpp -2efc1faef85c78dbfe91d46fcc26a3ec puttcircus.(a) -ab0693e9324cfcf498fdcbb12acf8bb4 puttcircus.HE0 -320a3bca28c8c30ad7aeff74f24ced2e puttcircus.he2 -9c01311b009b0b1b65735beb51eb526a puttcircus.HE4 -d0552089e0c2bbf75969643e8dc30ef1 PUTTCIRCUS.w32 - -(puttcircus cd hfs russian) -sev -??? - -(puttcircus cd russian) -sev -C:\Dev\Project\SPUTM\Src\*.cpp -0deaf09aff8db115b7da47272955f206 puttcircus.(a) -7bad72e332a59f9fcc1d437f4edad32a puttcircus.he0 -9ef7154db4ba00b89b5424ffd5cfce26 puttcircus.he2 -e902d67046bfb7cb09c9148b4462f297 puttcircus.he4 -f22635a81cf4abb712704990b7d9d597 PUTTCIRCUS.w32 - -(puttcircus demo hfs) -sev -??? - -(puttsfunshop cd/freddicove cd/soccerMLS cd) -sev -C:\Dev\Project\SPUTM\Src\*.cpp -d78d1eff392096c83687231fe2e78c6b circdemo.(a) -ccca9a823d117afb1a882fd707586bf0 circdemo.D32 -79c9cf9572d32b2c587226f32b1ab946 circdemo.exe -a7cacad9c40c4dc9e1812abf6c8af9d5 circdemo.HE0 -14b7f2b5180be87991338ea1017421be circdemo.he2 -860b38ff47ba90e910025ac8c6e9a823 circdemo.he4 - -(puttputt 3do cd) -khalek -c817613033ceb12eb4c31ea6c336808f BREEZY.DMU -fa14bc146cc6086ab44c906a320699c9 CALLIOPE.DMU -67f93260bf6519d9a47fe987f46d286b CARWASH.DMU -60fe949efb311eb660c1516fcc20edd2 CONGA.DMU -667d5c394b63381f309d8c85085748d8 GASTASHN.DMU -ed39e74166eb60b6d93ab5a26790dcac GROCER2.DMU -a06560553d188e1dc5886c7633ee602a HAPPY.DMU -01fd3afbc1b0f8b6e01a18232181cc39 HONEYBEE.DMU -6bedd1f644ff35d55f2dd4e818f662ed MARSEILL.DMU -ba59b9918a11a3f366719bb6dbb02426 MICE.DMU -3031ecf1f94e9712ec9e2d192af5adaa MISCHIEF.DMU -5b45f41c5e02ea737f64b8fb306346fa MONKEYS.DMU -6beb885fb7fae9a4dc0a7b66b8e31e27 PAINTING.DMU -725518498492603428a4b481a74f0ecd PARADE.DMU -9d166dc6e1e55f78bfac5ede2e9c2daa PAUSE.CEL -1748c190e7df232fabe70130f6636c9f PERFORM.CEL -cbcf447cb91de76b6d034d41601bd148 PLAYFUL.DMU -d8051a79de027921c27d08a67fb5fc09 POPWEASL.DMU -8296845e881ba14f6c3e76e51220896c PUPPY.DMU -7e151c17adf624f1966c8fc5827c95e9 PUTTPUTT.HE0 -3c985277e56fda01c1ef3d6da6817fd2 PUTTPUTT.HE1 -46f5aae1faea566f0e21b34572563e40 PUTTPUTT.TLK -e4978c237ab8b7eb7820048a90a3161e PUTTSONG.DMU -79e68c29627a5ba3514b87edacb57232 SHORTOCK.DMU -87ffadb9e4d62e60fa2f8b16b672677a STARTUP.CEL -d9b9d645a4f7949f127b32eb152e343b SUNNYDAY.DMU -66d7b0f5c5b9bf0cf57a96b7fa457569 TICKTOCK.DMU -b274a80fde5aaf92123972a4f3aabaa9 TOYSHOP.DMU -cefbc7824935e5377bf25b3e461effdd WADDLE.DMU -8f4c6d28938fb3a532d6038ebaadf234 WAITING.DMU -a7914691959037a5a4f25fc5a6a138d2 WALTZ.DMU -3caac70fd907c450ad8f4cd2d75ab576 WANDRING.DMU -cf7150acba9df96c16a9e20d2345941d WHISTLIN.DMU - -(puttputt patch) -khalek -6.1.1 (Nov 20 1993 12:42:10) -868b739deaf9319825137e5e55d4aee1 PUTTPUTT.EXE - -(puttputt cd/he classics cd) -khalek, sev -6.1.1 (Jan 18 1994 09:32:55) -7564ee82886b8c75b3b1bd895c98fcb4 puttputt.exe -9708cf716ed8bcc9ff3fcfc69413b746 puttputt.he0 -d109f3215ca2d5cd38c2efd83da5a51c puttputt.he1 -5f5a783f29c3da080d3bddbef0e2f01d puttputt.tlk - -(puttputt cd hebrew) -sev -??? - -(puttputt cd russian) -sev -6.1.1 (Nov 19 1992 17:56:19) -0b3222aaa7efcf283eb621e0cefd26cc PUTTPUTT.HE0 -64b5aee54f2b1453100b2040e1d778ef PUTTPUTT.HE1 -a4e799011c8320dffef43db7869b839a PUTTPUTT.TLK - -(puttputt cd russian alt) -sev -6.1.1 (Nov 19 1992 17:56:19) -68ca57feaa198976c87f4a69f1e9a958 PUTTPUTT.EXE -0b3222aaa7efcf283eb621e0cefd26cc PUTTPUTT.HE0 -64b5aee54f2b1453100b2040e1d778ef PUTTPUTT.HE1 -32453797af20693a00ccbe4dfa6db54f PUTTPUTT.TLK - -(he classics cd hfs) -khalek -684732efb5799c0f78804c99d8de9aba Putt-Putt Parade 0 -dc086db2e995aff8b2336147ccbd75d6 Putt-Putt Parade 1 -5f5a783f29c3da080d3bddbef0e2f01d Putt-Putt Parade 2 - -(puttputt cd/he classics cd) -khalek, sev -7.0.0 (Feb 7 1995 13:26:59) -6a30a07f353a75cdc602db27d73e1b42 puttputt.he0 -ce76be89bcace9527f457cab9d8231a6 puttputt.he1 -328b11537db07809864d8b2f536d07ae puttputt.he2 -58dfc09f344a9dec565bb914920800d3 puttputt.he3 -6cb903fb3d4d726fe0229affb1d22525 puttputt.he4 -71e615a8493f357e4de824a1e4632a80 puttputt.w32 - -6.1.1 (Mar 9 1993 21:19:14) -khalek -57cbe80e524afa5330a77d04316d2bf6 puttdemo.exe -31aa57f460a3d12429f0552a46a90b39 puttdemo.he0 -282a5503b45ddc15c7fb83c8e911b091 puttdemo.he1 -a49e0880f7c0638fbf7adf88894da3df puttdemo.tlk - -(puttputt demo hfs) -khalek -??? - -(puttputt cd/he classics cd) -khalek, sev -7.0.0 (Feb 7 1995 13:26:59) -37ff1b308999c4cca7319edfcc1280a0 puttdemo.he0 -9be0197fa0dac01ca3d72cf060826045 puttdemo.he1 -a49e0880f7c0638fbf7adf88894da3df puttdemo.he2 -58dfc09f344a9dec565bb914920800d3 puttdemo.he3 -cd26452706d7e66a3f4ba13975fe5c68 puttdemo.he4 -71e615a8493f357e4de824a1e4632a80 puttdemo.w32 - -(puttzoo cd hfs) -cyx -??? - -(puttzoo cd) -cyx -??? - -(puttzoo cd hfs) -khalek -1995-09-14 17:11 Putt-Putt Saves the Zoo -2f328b89b4404eaefb9bd18045dddd06 Putt-Putt Saves the Zoo -58fdf4c7ad13540a734e18f8584cad89 Putt-Putt Saves the Zoo (0) -8cffc74555fed521cc2008ed6a119118 Putt-Putt Saves the Zoo (1) -225991e6f8d3d6ac5e519413392c34f3 Putt-Putt Saves the Zoo (2) -d3235443d88751acd3412c1b0c6cec35 Putt-Putt Saves the Zoo (4) - -(puttzoo cd dutch) -joostp -??? - -########## There is 9.8 version of puttzoo, Kirben has it -(puttzoo cd) -khalek -7.0.0 (Jul 13 1995 18:45:07) -1005456bfe351c1b679e1ff2dc2849e9 puttzoo.he0 -1399aaabdfc340203ac63aff57abf8a0 puttzoo.he1 -225991e6f8d3d6ac5e519413392c34f3 puttzoo.he2 -4417ea03a6d1b0b7522526f41d1097f6 puttzoo.he3 -d3235443d88751acd3412c1b0c6cec35 puttzoo.he4 -f6cc3beae345e71055efb143a342983c puttzoo.w32 - -(puttzoo russian) (Comment: ALL LANGUAGES) -sev -7.0.0 (Jul 13 1995 18:45:07) -1005456bfe351c1b679e1ff2dc2849e9 PUTTZOO.HE0 -1399aaabdfc340203ac63aff57abf8a0 PUTTZOO.HE1 -d03846ce20bab80288af295bb66870a3 PUTTZOO.HE2 -4417ea03a6d1b0b7522526f41d1097f6 PUTTZOO.HE3 -d3235443d88751acd3412c1b0c6cec35 PUTTZOO.HE4 -91903ca0f67564d78d229afa479b0b02 PUTTZOO.W32 - -(he classics hfs/pajama cd hfs/farm cd hfs) -khalek -1996-11-17 13:28 Puttzoo Demo -34727db5bde5a2f78a1ec84f75d0810c Puttzoo Demo -3486ede0f904789267d4bcc5537a46d4 Puttzoo Demo (0) -e0cde64b0c37a188c97a0bc93225cce9 Puttzoo Demo (1) -a0cd041eb6c1a289a23549ef8740ff17 Puttzoo Demo (2) -86dc7e6f520dbabe79b324ae64456686 Puttzoo Demo (4) - -(puttzoo demo hfs) -Joachim -??? - -(ftp) -sev -7.0.0 (Jul 5 1995 14:45:19) -f3d55aea441e260e9e9c7d2a187097e0 zoodemo.he0 -92722a557c952ff5178eb32964a12061 zoodemo.he1 -a0cd041eb6c1a289a23549ef8740ff17 zoodemo.he2 -47539950e6e6f656db4c1cc963bf9a8f zoodemo.he3 -86dc7e6f520dbabe79b324ae64456686 zoodemo.he4 -d30c3ce43992a116be1a28a4edccf597 zoodemo.w32 - -(spyfox cd/pajama cd/he classics cd/freddi2 cd/baseball cd) -khalek -7.0.0 (Jun 4 1995 15:47:12) -de4efb910210736813c9a1185384bace zoodemo.he0 -8ad56037c37b1c84efc2fa00bf4c59d5 zoodemo.he1 -c9b8363220ea094d2da8cc24635d8d48 zoodemo.he2 -47539950e6e6f656db4c1cc963bf9a8f zoodemo.he3 -86dc7e6f520dbabe79b324ae64456686 zoodemo.he4 -f3324cfe3dec0288fd38197cf88962af zoodemo.w32 - -(farm cd/pajama cd) -khalek, sev -7.0.0 (Jun 22 1995 14:03:05) -de4efb910210736813c9a1185384bace zoodemo.he0 -8ad56037c37b1c84efc2fa00bf4c59d5 zoodemo.he1 -c9b8363220ea094d2da8cc24635d8d48 zoodemo.he2 -47539950e6e6f656db4c1cc963bf9a8f zoodemo.he3 -86dc7e6f520dbabe79b324ae64456686 zoodemo.he4 -37e4b9463ead881fd53bf401aa62d0bf zoodemo.w32 - -(puttzoo demo hfs german) -Joachim -??? - -(putttime cd hfs) -Kirben -??? - -(putttime cd) -Kirben -??? - -(putttime cd hfs) -sev -??? - -(putttime cd) -sev -C:\Dev\Project\SPUTM\Src\*.cpp -833cb49dd6767dc7722d671a4067ab5a PuttTime.(a) -2108d83dcf09f8adb4bc524669c8cf51 PuttTime.he0 -802147789449535e375c7c4f2e666b96 PuttTime.he2 -15d5f719ebc6bcd4fe674587a8fa8596 PuttTime.he4 -a30dd1cd2b58b2c5c6eb1aa970f5a3c2 PuttTime.w32 - -(putttime cd hfs german) -Joachim -??? - -(putttime cd german) -Joachim -??? - -(putttime cd dutch) -adutchguy -??? - -(putttime cd) -iziku -??? - -(putttime cd UK Release) -eriktorbjorn -d:\dev\SPUTM\Src\*.cpp -6ea0c0e68384e588ece7e3e110c62b09 puttputtTTT.(a) -d4aac997e2f4e15341f0bfbf905419bd puttputtTTT.HE0 -79e5273f8626f6b1448788bc0a279049 PuttPuttTTT.HE2 -7a0d96204f8874e4eda4918f63ca7b4e PuttPuttTTT.HE4 -a75403b5e853d7cc65cde2ec358ca5ba puttputtTTT.w32 - -(putttime cd german) -oncer -??? - -(putttime cd russian) -sev -d:\dev\SPUTM\Src\SAVELOAD.cpp -4a7452aabc69cdaf897ccc099ff0bafa puttputtTTT.(a) -defb8cb9ec4b0f91acfb6b61c6129ad9 puttputtTTT.he0 -5247f60e3913296860a74eef4bdfad2a PuttPuttTTT.he2 -a4816cbb60fa01f16295ab46868e7c41 PuttPuttTTT.he4 -947ce44f2336f8467ceadb184dbaa3e9 puttputtTTT.w32 - -(freddi cd hfs) -khalek -1997-12-09 19:59 TimeDemo -f2ece54cc9ca9621217c71cfd1ea594e TimeDemo -4e5867848ee61bc30d157e2c94eee9b4 TimeDemo (0) -5c58da43055710e93cfedd45bb14b03c TimeDemo (1) -42df84a2b73a3d2ee461b89474ee2f57 TimeDemo (2) -72339e5cf3f2902ad78e58c05bfcf7bb TimeDemo (4) -d41d8cd98f00b204e9800998ecf8427e TimeDemo (r) - -(pajama2 cd/puttrace cd/soccer cd) -sev -D:\Scummsys.90\sputm.90\*.c -c0c0934580cde95879bef0b6a5a49c29 timedemo.d32 -4e5867848ee61bc30d157e2c94eee9b4 timedemo.he0 -5c58da43055710e93cfedd45bb14b03c timedemo.he1 -42df84a2b73a3d2ee461b89474ee2f57 timedemo.he2 -72339e5cf3f2902ad78e58c05bfcf7bb timedemo.he4 -4c33312418b27bfe8ad307a6e14604e9 timedemo.w32 - -(ftp/freddi3 cd) -sev -D:\Scummsys.90\sputm.90\*.c -c0c0934580cde95879bef0b6a5a49c29 TIMEDEMO.D32 -4e5867848ee61bc30d157e2c94eee9b4 TIMEDEMO.HE0 -5c58da43055710e93cfedd45bb14b03c TIMEDEMO.HE1 -42df84a2b73a3d2ee461b89474ee2f57 TIMEDEMO.HE2 -72339e5cf3f2902ad78e58c05bfcf7bb TIMEDEMO.HE4 -a43540b44806b8311c7fd04c12cbf46a TIMEDEMO.W32 - -(putttime demo hfs) -sev -??? - -(web) -2002-06-10 20:14 TimeDemo.exe -khalek, sev -c:\Build\SRC\SPUTM\Src\SrcPWin\*.cpp -a64bde414f464ef8522fa0ffeea36d9c TimeDemo.exe -0ab19be9e2a3f6938226638b2a3744fe TimeDemo.HE0 -1691e37409d7f0593c1aa1449f882058 TimeDemo.(a) -63adb23ead513d5fcf657ed555e525ee TimeDemo.he2 -72339e5cf3f2902ad78e58c05bfcf7bb TimeDemo.he4 - -(putttime demo hfs french) -Kirben -??? - -(putttime demo french) -Kirben -??? - -(putttime demo dutch) -adutchguy -??? - -(Kellogg cereals pack) -a6d982141c88f167cf4ec5dc684e2684 PuttMini.(a) -d1286487c342ac81b28f3e1b90a2b7f3 PuttMini.D32 -0a6d7b81b850ed4a77811c60c9b5c555 PuttMini.HE0 -a75403b5e853d7cc65cde2ec358ca5ba PuttMini.exe -ddcb5d9f71edc07982db401776c2d79e PuttMini.he2 -72339e5cf3f2902ad78e58c05bfcf7bb PuttMini.he4 - -(balloon cd hfs) -Kirben -??? - -(balloon cd) -Kirben -??? - -(balloon cd hfs) -Kirben -??? - -(balloon cd) -Kirben -??? - -(balloon cd) -iziku -??? - -(russian balloon) -sev -D:\Scummsrc.80\Sputm\*.c -ad2d6ffbae12d46a2d50ccbbd2a15a83 Balloon.a32 -145bd3373574feb668cc2eea2ec6cf86 BALLOON.HE0 -86282ac950041a1a9723d2c86098939a BALLOON.HE1 -1dabd9eea9fa31c751ac52cfc2048c9c BALLOON.HE2 -4417ea03a6d1b0b7522526f41d1097f6 BALLOON.HE3 -6770978a98ae08e208c188d6c844ab69 BALLOON.HE4 -c2eb18b88529dc5cf79f868c73925f14 BALLOON.HE8 -cbe95e475b634087dc92d23596ad995f BALLOON.HE9 - -(dog cd hfs) -Kirben -??? - -(dog cd) -Kirben -??? - -(dog cd) -sev -C:\Dev\Project\SPUTM\Src\*.cpp -ed126ee70102f94b8c725b3b90576f1e DOG.w32 -d4b8ee426b1afd3e53bc0cf020418cf6 dog.HE0 -43821dcacadd3340396dc9bdcf9fe455 dog.(a) -8cbaaef96c0def188a98794f7e8826d6 dog.he2 -fc47c58d925148b1c1cce784d1f9fec1 dog.he4 -880f0f5e1acc4eb19c889c4d7c7492ef dog.he7 -50438756f002a90fbe7d6a4be184dccb dog.he8 -ccca9a823d117afb1a882fd707586bf0 dog.d32 - -(activity cd) -??? - -(funpack cd 3do) -sev -??? - -(funpack cd) -iziku -??? - -(funpack patch) -khalek -6.1.1 (Nov 20 1993 12:20:32) -091d066c93e751504e4b18c6748b97e0 FUNPACK.EXE - -(funpack cd) -6.1.1 (Feb 15 1993 20:31:55) -khalek -f90f40b9702cfd3e2f6c9af76c743e41 funpack.exe -46b53fd430adcfbed791b48a0d4b079f funpack.he0 -af6283c82fb6a867f91f28039b716036 funpack.he1 -7d6dec34833328722665c1e5a64e735f funpack.tlk - -(funpack cd hebrew) -??? - -(puttsfunshop cd hfs) -sev -??? - -(puttsfunshop cd) -sev -C:\Dev\Project\SPUTM\Src\SrcPWin\*.cpp -b525ccb6634db6c7f2762864f627f17a PuttsFunShop.(a) -4504676bd50cb7b0e28b1b2026dce1b3 PuttsFunShop.(b) -ccca9a823d117afb1a882fd707586bf0 PuttsFunShop.d32 -5262a27afcaee04e5c4900220bd463e7 PuttsFunShop.HE0 -5543c6d936bbec16be896902a473d2a4 PuttsFunShop.he2 -e93a12735e1a95559c755d7193676085 PUTTSFUNSHOP.HE4 -970f3883eefc562bc3949d1b1f88673e PuttsFunShop.map -39c468587c4bdad304be49e8d4041a22 PuttsFunShop.u32 -7ea658395895f10ba7dfc4a7d147f615 PuttsFunShop.w32 -a38b59ccd74792e348b57e6f07ce2ccc PuttsFunShop.x32 - -(spyfox cd hfs) -Kirben -??? - -(spyfox cd) -Kirben -??? - -(spyfox cd hfs) -Joachim -??? - -(spyfox cd) -Joachim -??? - -(spyfox cd hfs german) -Joachim -??? - -(spyfox cd german updated) -Joachim -??? - -(spyfox cd german) -nachbarnebenan -a28135a7ade38cc0208b04507c46efd1 spyfox.he0 -96da98152ccc2f0d9002c834f34d5cd0 spyfox.he1 -75bd69c4fc660695691844a68110a337 spyfox.he2 -f8029f33e2bc3da6fe38f6bda58c1f31 spyfox.he4 - -(spyfox cd dutch) -joostp -??? - -(spyfox cd) (COMMENT: ALL LANG) -khalek -1997-08-10 03:41 spyfox.w32 -D:\Scummsys.90\sputm.90\*.c -6bf70eee5de3d24d2403e0dd3d267e8a spyfox.he0 -e01f959bdd49d5b0c8660fd8a14d4799 spyfox.he1 -0a7f78543f30138effbe593d9d09e720 spyfox.he2 -9fbab8bb60448f30ce7508dbf277ab05 spyfox.he4 -b7aa3c76d463137a8a09c68d9a1045d1 spyfox.w32 - -(spyfox cd russian) -sev -D:\Scummsys.90\sputm.90\*.c -6bf70eee5de3d24d2403e0dd3d267e8a SPYFOX.HE0 -f1b79e1dcb5f57b8d91aac8487a284d7 SPYFOX.HE1 -506a333aad3af2ca8abf5b862ceeb365 SPYFOX.HE2 -9fbab8bb60448f30ce7508dbf277ab05 SPYFOX.HE4 -1355eb775fa71d6df9d506fb906a51db SPYFOX.HLP -b7aa3c76d463137a8a09c68d9a1045d1 SPYFOX.W32 - -(spyfox cd russian updated) -sev -d:\dev\SPUTM\Src\*.cpp -51ac439f04951d0910bc423e2825dab8 SPYFoxDC.(a) -72ac6bc980d5101c2142189d746bd62f SPYFoxDC.he0 -10b638ee633558d528d7be0376175065 SPYFoxDC.he2 -f8029f33e2bc3da6fe38f6bda58c1f31 SPYFoxDC.he4 -b185cdec4ea6bc218afe08325af787a4 spyfoxdc.w32 - -(farm cd hfs) -khalek -1997-12-09 19:59 FoxDemo -09507650b60e891e9c1ed5e0a7aa0152 FoxDemo -53e94115b55dd51d4b8ff0871aa1df1e FoxDemo (0) -81fef80fadf4cd3ad0e04ac619f6eaed FoxDemo (1) -1229ed0135d97aac8b50224a74ee4f34 FoxDemo (2) -6f7993e15da433b58ea63e59e3666cea FoxDemo (4) -d41d8cd98f00b204e9800998ecf8427e FoxDemo (r) - -(ftp/pajama2 demo/freddi3 cd) -sev -53e94115b55dd51d4b8ff0871aa1df1e foxdemo.he0 -81fef80fadf4cd3ad0e04ac619f6eaed foxdemo.he1 -1229ed0135d97aac8b50224a74ee4f34 foxdemo.he2 -6f7993e15da433b58ea63e59e3666cea foxdemo.he4 -b7aa3c76d463137a8a09c68d9a1045d1 foxdemo.w32 - -(spyfox demo hfs) -khalek -??? - -(ftp/putt dog cd/spyfox2 cd/putttime cd/football cd) -1999-05-17 12:21 spydemo.w32 -khalek -D:\Scummsys.90\sputm.90\*.c -fbdd947d21e8f5bac6d6f7a316af1c5a spydemo.he0 -820bceab2a1ab02254c33e6e3fc81628 spydemo.he1 -bc8ed64e6a101f6646b80aa294fa5bdc spydemo.he2 -88867a804055334db8485d7da5d2c51f spydemo.he4 -b7aa3c76d463137a8a09c68d9a1045d1 spydemo.w32 - -(spyfox demo hfs) -khalek -??? - -2002-05-21 13:29 Spydemo.exe -khalek -c:\Build\SRC\SPUTM\Src\SrcPWin\*.cpp -f5207b882c9015a4e4a9599460be6294 Spydemo.(a) -4d34bf8f8ec20f2e653b19aa283da352 Spydemo.exe -9d4ab3e0e1d1ebc6ba8a6a4c470ed184 Spydemo.HE0 -b34d614a23a7dac2be1407bbb51c6b24 Spydemo.he2 -88867a804055334db8485d7da5d2c51f Spydemo.he4 - -(spyfox demo hfs french) -Kirben -??? - -(spyfox demo french) -Kirben -??? - -(spyfox demo dutch) -Kirben -??? - -(spyfox2 cd hfs) -sev -??? - -(spyfox2 cd) -sev -D:\(vss)scummsys.99\SPUTM\Src\*.cpp -5f7ece9a7aefc709f11b6f4216c8764e spyfox2.(a) -f79e60c17cca601e411f1f75e8ee9b5a SPYFOX2.HE0 -c8f3ab5d05e09360dc88c00243db0c2a SPYFOX2.HE2 -d601630d0dcf6b3084ecd42b6c8c5a33 SPYFOX2.HE4 -0b381fa8531972edca34f9b631638148 spyfox2.he9 -26ef6933e4a560f40bbb3dc0525a783c spy2arc.hst -77179b054447bb7080aff0ec343588c6 Spyfox2.w32 - -(spyfox2 cd russian) (COMMENT: ALL LANGUAGES) -sev -d68c11a69a955b66ee1a6b8f5a2ee9e0 spyfox2.(a) -f79e60c17cca601e411f1f75e8ee9b5a SPYFOX2.HE0 -0a718eae78a467f5e664a34b601471e3 SPYFOX2.HE2 -d601630d0dcf6b3084ecd42b6c8c5a33 SPYFOX2.HE4 -0b381fa8531972edca34f9b631638148 spyfox2.he9 -010b18d51f6bf84c69333d03a4cc3c9b SPYFOX2.HLP -77179b054447bb7080aff0ec343588c6 Spyfox2.w32 - -(spyfox2 cd hfs russian updated) -sev -??? - -(spyfox2 cd russian updated) -sev -C:\HESystems\SPUTM\Src\*.cpp -4ecc3a54d961a23b80239e191309bb2a spyfoxsr.(a) -cea91e3dd47f2518ea418e41611aa77f spyfoxsr.he0 -2e73380e32fb1960de5e9871042c6b2e spyfoxsr.he2 -42e883fdae113021eaa30bca3a7bfd2c spyfoxsr.he4 -0b381fa8531972edca34f9b631638148 spyfoxsr.he9 -dda8932e4ddd10c538086df4eaa965d2 SPYFOXSR.w32 - -(spyfox2 cd dutch) -adutchguy -??? - -(spyfox2 demo hfs dutch) -joostp -??? - -(spyfox2 demo dutch) -joostp -??? - -(putsfunshop cd/pajama3 cd/puttcircus cd/spyozon cd/soccerMLS cd) -sev -C:\Dev\Project\SPUTM\Src\*.cpp -2ee6a9c1c8352d4aca638aeab38a194e sf2-demo.(a) -f378c570abf42d4875d26674a35acd83 SF2-DEMO.EXE -7222f260253f325c21fcfa68b5bfab67 sf2-demo.HE0 -8634f4ad2f224842364a86ddc57bb072 sf2-demo.he2 -c23f18777b5ad558826493f69749c4c6 SF2-DEMO.HE4 - -(humongous ftp) -sev -D:\(vss)scummsys.99\SPUTM\Src\*.cpp -2ee6a9c1c8352d4aca638aeab38a194e sf2-demo.(a) -ccca9a823d117afb1a882fd707586bf0 sf2-demo.d32 -77179b054447bb7080aff0ec343588c6 sf2-demo.exe -7222f260253f325c21fcfa68b5bfab67 sf2-demo.he0 -8634f4ad2f224842364a86ddc57bb072 sf2-demo.he2 -c23f18777b5ad558826493f69749c4c6 sf2-demo.he4 - -(spyfox2 demo hfs german) -Joachim -??? - -(spyfox2 demo german) -Joachim -??? - -(PuttPutt CD UK release) -eriktorbjorn -d:\dev\SPUTM\Src\*.cpp -e79b9525fd1e38c140424f48c609e642 SF2DEMO.(A) -6dbe2db93323010de257bcb55d99c3fa sf2demo.exe -19bf6938a94698296bcb0c99c31c91a7 SF2DEMO.HE0 -2577b0029ecfcb9e764e20a9b2a4be6a Sf2Demo.he2 -c23f18777b5ad558826493f69749c4c6 Sf2Demo.he4 - -(spyozon cd hfs) -sev -??? - -(spyozon cd) -sev -C:\Spyfox3Sputm\Src\*.cpp -845312206b245156183ffa0ee79fcede SPYOZON.(A) -600abd3e9f47e63e670188b7e4e86ac7 SPYOZON.HE0 -eec7f697ba008211d12be2108f9e6b56 SPYOZON.HE2 -2f238b51cfad1b8b5c179468a19aa29b SPYOZON.HE3 -6654406759193503d618405b075322e4 SPYOZON.HE4 -a76f985eb0fe5b9600dd8563cd5ac7d8 spyozon.w32 - -(spyozon cd hfs russian updated) -sev -??? - -(spyozon cd russian updated) -sev -C:\Spyfox3Sputm\Src\SrcPWin\*.cpp -eb03a8bd9e7654d5d06635d934f2059b SPYFoxOzu.(a) -194af4195ddb1f3a6017fbd6b27a92aa spyfoxozu.exe -96a3069a3c63caa7329588ce1fef41ee SPYFoxOzu.he0 -efab08f94696fc1a7404ba366c6629d3 SPYFoxOZU.he2 -2f238b51cfad1b8b5c179468a19aa29b SPYFoxOZU.he3 -64531d4b40f2b932c8434b5c2c0f3547 SPYFoxOzu.he4 - -(spyozon cd) -??? - -(spyozon demo hfs) -??? - -(freddicove cd/pajama4 cd) -sev -d:\dev\SPUTM\Src\SrcPWin\*.cpp -0b3dac19ac1107f3fcfa9b38c47b2dfb SF3-DEMO.(A) -ad443efafb53aa0c05749b7d523019cf SF3-DEMO.EXE -ebd0b2c8a387f18887282afe6cad894a SF3-DEMO.HE0 -46dd1febbcad9683be77f23b666cdbbe SF3-DEMO.HE2 -145feca064ba53c0002c56a199bdc719 SF3-DEMO.HE3 -24f341ed410a69e052f90f9b3cb5ecf4 SF3-DEMO.HE4 - -(chase cd hfs) -Kirben -??? - -(chase hfs) -Kirben -??? - -(chase cd hfs) -Kirben -??? - -(chase hfs) -Kirben -??? - -(chase cd russian) -sev -D:\scummsys.95\sputm.95\*.c -dab6994bacb768b75a7085c01a473c94 Chase.a32 -9cdd327c1034c046cb595d251c44da2f CHASE.HE0 -d61f7c0fa645c0cead10e93b5223197c CHASE.HE1 -79fbaace4a08b14772aeea0250e95330 CHASE.HE2 -fe9666d561a54a101c92086d2ef77448 CHASE.HE4 -5201bee3111b5335fac48ecf30b27830 CHASE.HE8 -6d12e727e12365a23270269ca4c7e538 CHASE.HE9 - -(mustard cd hfs) -Kirben -??? - -(mustard cd) -Kirben -??? - diff --git a/doc/he/smacker-md5s.txt b/doc/he/smacker-md5s.txt deleted file mode 100644 index 39233c402b..0000000000 --- a/doc/he/smacker-md5s.txt +++ /dev/null @@ -1,46 +0,0 @@ -(puttsfunshop cd/pj3 cd/puttcircus cd) -sev -D:\scummsys.98\sputm.98\*.c -e07a222d121f7e8b04266bf4d7809cb4 BluesBirthdayDemo.a32 -dbf4d59d70b826733f379f998354d350 BluesBirthdayDemo.HE0 -6ddf8b026cfb9410b560f91f353dc0f4 BluesBirthdayDemo.(a) -409a570e46466aef89c3cd3a30992543 BluesBirthdayDemo.(b) -60cc055b47b53cb53eaa89e1f974c888 BluesBirthdayDemo.he2 -0794110b085ee91c2aa4a5fc844ff2f4 BluesBirthdayDemo.he4 - -(puttrace cd) -sev -D:\scummsys.98\sputm.98\*.c -e07a222d121f7e8b04266bf4d7809cb4 BluesBirthdayDemo.a32 -2d4acbdcfd8e374c9da8c2e7303a5cd0 BluesBirthdayDemo.HE0 -18ee74255c93da057c92effbd39ebd9a BluesBirthdayDemo.(a) -409a570e46466aef89c3cd3a30992543 BluesBirthdayDemo.(b) -dc5e63ecf2672d4a3a0458fe32902a4e BluesBirthdayDemo.he2 -0794110b085ee91c2aa4a5fc844ff2f4 BluesBirthdayDemo.he4 -ccca9a823d117afb1a882fd707586bf0 BluesBirthdayDemo.d32 - -(freddi5 cd) -sev -C:\Dev\Project\SPUTM\Src\SrcPWin\*.cpp -548fcedaa9cee84443a5a9acfff4cb04 ARTDEMO.(A) -d00ffc8c32d17e575fd985d435d2eb88 ARTDEMO.HE0 -58c91c3f750b227b136e96b410b0e7cc ARTDEMO.HE2 -47f0573a8a629c6e7f8b9236112fe10e ARTDEMO.HE4 -7e98a8e45cbac83e65d98f3c133ae34d ARTDEMO.W32 -2f1a08df8aa13924959905fc5dc34a9b DATA/INTR_AT_IN_01.DAT -f7841f8a37394805fc0699999898bcca DATA/INTR_AT_IN_02.DAT -6a2f8c39d2ce07d422bae9f9bf416839 DATA/INTR_AT_IN_20_B.DAT - -(freddi5 cd) -sev -C:\Dev\Project\SPUTM\Src\SrcPWin\*.cpp -f536221cc5d8da02009278523eda6bd5 READDEMO.(A) -95818b178d473c989ac753574e8892aa READDEMO.HE0 -7c64b87e454e642e36a83c79341007b0 READDEMO.HE2 -4f307cf26e46f765298cc8f92f02db49 READDEMO.HE4 -eac7453b1dca87447974ef54137470f9 READDEMO.W32 -45a973a322b177ee4b36bea81981462d DATA/INT_RT_IN_01.DAT -9e0c144bf1b7f0cc8ba3edae6135e313 DATA/INT_RT_IN_03.DAT -8d150f9d9e12e485da50c4560135b4ef DATA/INT_RT_IN_04.DAT -8cde496829546daaaa28084c49f3f4f7 DATA/INT_RT_IN_05.DAT -c784fa970208b5bd49fff568ca0036ec DATA/INT_RT_IN_06.DAT diff --git a/doc/he/u32.txt b/doc/he/u32.txt deleted file mode 100644 index e4735cac71..0000000000 --- a/doc/he/u32.txt +++ /dev/null @@ -1,39 +0,0 @@ -500demo, puttrace, racedemo [55808] -39F6C16743D2AA4E0D92C2E6C4993311 500DEMO.U32 -39F6C16743D2AA4E0D92C2E6C4993311 PUTTRACE.U32 -39F6C16743D2AA4E0D92C2E6C4993311 RACEDEMO.U32 - -basketball [282690] -6e8c11a5294981e58032e9f2c8fcdb74 BASKETBALL.U32 - -baseball2001, bb2demo [180224] -23843A93F55BF0B4D7D22E80E0EEFD0A bb2demo.u32 - -chase (he100) [118784] -CC119A63F923076C300DC52575CB47C5 uberedit.u32 - -football, footdemo [155648] -07656b959c7febb6359c8de5fd6b6f76 FOOTBALL.U32 - -football2002 [90156] -2d027f461187ebadad44801c366b892c Football2002.u32 - -moonbase 1.0 [458827] -4c18f01f3020678d2ce9d5312057cb9d Moonbase.u32 - -moondemo [458827] -0C645CDF171CC79DAB28BF8962D6904B moondemo.u32 - -FreddisFunShop, PuttsFunShop, SamsFunShop [40960] -39C468587C4BDAD304BE49E8D4041A22 PuttsFunShop.u32 -39C468587C4BDAD304BE49E8D4041A22 SamsFunShop.u32 -39C468587C4BDAD304BE49E8D4041A22 FreddisFunShop.u32 - -soccer [123904] -ed64133f8cdfca57fb3cd09057def978 SOCCER.U32 - -soccer2004 [90186] -C7B6AB1B4408C4F6EB66ADD731A0DF1A SOCCER2004.U32 - -soccerMLS [135168] -86cb9583ca987446d12a4f36dd8d631b SoccerMLS.u32 diff --git a/doc/he/versions.html b/doc/he/versions.html deleted file mode 100644 index 3ab604c128..0000000000 --- a/doc/he/versions.html +++ /dev/null @@ -1,754 +0,0 @@ -<html> -<!-- $Id$ --> -<p> -Games below are believed to be SCUMM based games... most haven't been proven however. -Every title Humongous Entertainment released before Backyard Hockey (early 2002) should be SCUMM based. -Mac versions not listed in the interest of space, they seem to be the same as pc ones after you rename -certain files anyway. Besides anyone who has a mac version has a PC version as the games are on hybrid -HFS/ISO9660 CDs. - -<table border=1> - -<tr> -<td>Game -<td>Year -<td>Plat -<td>SPU Ver -<td>Source dir - - -<tr> -<td>Putt-Putt Joins the Parade -<td>1992 -<td>dos -<td>6.1.1 (Jan 18 1994 09:32:55) -<td> - -<tr> -<td>Putt-Putt Joins the Parade (patch) -<td>1992 -<td>dos -<td>6.1.1 (Nov 20 1993 12:42:10) -<td> - -<tr> -<td>Putt-Putt Joins the Parade -<td>1992 -<td>win -<td>7.0.0 (Feb 7 1995 13:26:59) -<td> - -<tr> -<td>Putt-Putt Joins the Parade -<td>1992 -<td>3do -<td>6.5.1 (3DO) -<td> - -<tr> -<td>Putt-Putt Joins the Parade (demo) -<td>1993 -<td>dos -<td>6.1.1 (Mar 9 1993 21:19:14) -<td> - -<tr> -<td>Putt-Putt Joins the Parade (demo) -<td>1993 -<td>win -<td>7.0.0 (Feb 7 1995 13:26:59) -<td> - -<tr> -<td>Putt-Putt Goes to the Moon -<td>1993 -<td>dos -<td>6.1.1 (Nov 4 1993 11:12:57) -<td> - -<tr> -<td>Putt-Putt Goes to the Moon -<td>1993 -<td>win -<td>7.0.0 (Feb 7 1995 13:27:20) -<td> - -<tr> -<td>Putt-Putt Goes to the Moon -<td>1993 -<td>3do -<td> - -<tr> -<td>Putt-Putt Goes to the Moon (demo) -<td>1993 -<td>dos -<td>6.1.1 (Sep 29 1993 17:18:45) -<td> - -<tr> -<td>Putt-Putt Goes to the Moon (demo) -<td>1993 -<td>win -<td>7.0.0 (Feb 7 1995 13:27:20) -<td> - -<tr> -<td>Putt-Putt's Fun Pack -<td>1993 -<td>dos -<td>6.1.1 (Feb 15 1993 20:31:55) -<td> - -<tr> -<td>Putt-Putt's Fun Pack (patch) -<td>1993 -<td>dos -<td>6.1.1 (Nov 20 1993 12:20:32) -<td> - -<tr> -<td>Putt-Putt's Fun Pack -<td>1993 -<td>3do -<td> -<td> - -<tr> -<td>Putt-Putt Saves the Zoo -<td>1995 -<td>win -<td>7.0.0 (Jul 13 1995 18:45:07) -<td>D:\scummsys.98\sputm.98\*.c - -<tr> -<td>Putt-Putt Saves the Zoo (demo) -<td>1995 -<td>win -<td>7.0.0 (Jun 4 1995 15:47:12) -<td> - -<tr> -<td>Putt-Putt Saves the Zoo (demo) -<td>1995 -<td>win -<td>7.0.0 (Jun 22 1995 14:03:05) -<td> - -<tr> -<td>Putt-Putt Saves the Zoo (demo) -<td>1995 -<td>win -<td>7.0.0 (Jul 5 1995 14:45:19) -<td> - -<tr> -<td>Putt-Putt Travels Through Time -<td>1997 -<td>win -<td> -<td>C:\Dev\Project\SPUTM\Src\*.cpp - -<tr> -<td>Putt-Putt Travels Through Time (demo) -<td>1997 -<td>win -<td>7.?.? -<td>D:\Scummsys.90\sputm.90\*.c - -<tr> -<td>Putt-Putt Travels Through Time (demo) -<td>1997 -<td>win -<td>7.?.? -<td>c:\Build\SRC\SPUTM\Src\*.cpp - -<tr> -<td>Putt-Putt Enters the Race -<td>1998 -<td>win -<td>7.?.? -<td>D:\scummsys.98\sputm.98\*.c - -<tr> -<td>Putt-Putt Enters the Race (demo) -<td>1998 -<td>win -<td>7.?.? -<td>D:\scummsys.98\sputm.98\*.c - -<tr> -<td>Putt-Putt Joins the Circus -<td> -<td> -<td> -<td>C:\Documents and Settings\stevej.BOT\My Documents\HECode\Libs\Wtoolkit\Rawbitm.cpp - -<tr> -<td>Putt-Putt One-Stop Fun Shop -<td>2000 -<td>win -<td>7.?.? -<td>C:\Dev\Project\SPUTM\Src\*.cpp - -<tr> -<td>Putt-Putt and Pep's Balloon-O-Rama? (arcade)? -<td> -<td>win -<td> -<td>D:\Scummsrc.80\Sputm\*.c - -<tr> -<td>Putt-Putt and Pep's Dog on a Stick? (arcade) -<td>1999 -<td>win -<td>7.?.? -<td>C:\Dev\Project\SPUTM\Src\*.cpp - -<tr> -<td colspan=5> - - -<tr> -<td>Pajama Sam 1: No Need To Hide When Its Dark -<td>1996 -<td>win -<td>7.?.? -<td>D:\Scummsrc.80\Sputm\*.c - -<tr> -<td>Pajama Sam 1: No Need To Hide When Its Dark (demo) -<td>1996 -<td>win -<td> -<td>D:\Scummsrc.80\Sputm\*.c - -<tr> -<td>Pajama Sam 1: No Need to Hide When Its Dark (demo) -<td> -<td>win -<td> -<td>c:\Build\SRC\SPUTM\Src\*.cpp - -<tr> -<td>Pajama Sam 2: Thunder and Lightning -<td>1998 -<td>win -<td>7.?.? -<td>D:\scummsys.95\sputm.95\*.c - -<tr> -<td>Pajama Sam 2: Thunder and Lightning (demo) -<td>1998 -<td>win -<td> -<td>D:\scummsys.95\sputm.95\*.c - -<tr> -<td>Pajama Sam 3: You Are What You Eat From Your -<td>2000 -<td>win -<td>7.?.? -<td>C:\Dev\Project\SPUTM\Src\*.cpp - -<tr> -<td>Pajama Sam 3: You Are What You Eat From (demo) -<td>2000 -<td>win -<td>7.?.? -<td>C:\Dev\Project\SPUTM\Src\*.cpp - -<tr> -<td>Pajama Sam One-Stop Fun Shop -<td>2000 -<td>win -<td> -<td>C:\Documents and Settings\stevej\My Documents\HECode\SPUTM\Src\SrcPWin\*.cpp - -<tr> -<td>Pajama Sam's Sock Works (arcade) -<td>1999 -<td>win -<td> -<td>D:\scummsys.80\sputm80\*.c - -<tr> -<td>Pajama Sam's Lost & Found (arcade) -<td>1999 -<td>win -<td> -<td>D:\scummsys.98\sputm.98\*.c - -<tr> -<td>Pajama Sam's Lost & Found (demo) -<td>1999 -<td>win -<td> -<td>D:\(vss)scummsys.99\SPUTM\Src\SrcPWin\*.cpp - -<tr> -<td colspan=5> - -<tr> -<td>Freddi Fish 1: The Case of the Missing Kelp -<td>1995 -<td>? -<td>7.0.0 (Jun 23 1995 09:58:48) -<td> - -<tr> -<td>Freddi Fish 1: The Case of the Missing Kelp -<td>1998 -<td>? -<td> -<td>D:\Scummsys.90\sputm.90\*.c - -<tr> -<td>Freddi Fish 1: The Case of the Missing Kelp (demo) -<td>1995 -<td>win -<td>7.0.0 (Oct 20 1994 10:00:19) -<td> - -<tr> -<td>Freddi Fish 1: The Case of the Missing Kelp (demo) -<td>1995 -<td>win -<td>7.0.0 (Jun 22 1995 14:06:25) -<td> - -<tr> -<td>Freddi Fish 1: The Case of the Missing Kelp (demo) -<td>1995 -<td>? -<td>7.0.0 (Jul 5 1995 14:46:05) -<td> - -<tr> -<td>Freddi Fish 2: The Case of the Haunted Schoolhouse -<td>1998 -<td>win -<td> -<td>D:\Scummsrc.80\Sputm\*.c - -<tr> -<td>Freddi Fish 2: The Case of the Haunted (demo) -<td>1996 -<td>win -<td>7.?.? -<td>D:\Scummsrc.80\Sputm\*.c - -<tr> -<td>Freddi Fish 2: The Case of the Haunted (demo) -<td>1998 -<td>win -<td>7.?.? -<td>c:\Build\SRC\SPUTM\Src\*.cpp - -<tr> -<td>Freddi Fish 3: The Case of the Stolen Conch -<td>1998 -<td>win -<td> -<td>D:\Scummsys.90\sputm.90\*.c - -<tr> -<td>Freddi Fish 3: The Case of the Stolen (demo) -<td>1997 -<td>win -<td> -<td>D:\Scummsys.90\sputm.90\*.c - -<tr> -<td>Freddi Fish 4: The Case of the Hogfish Rustlers -<td>1999 -<td>win -<td> -<td>D:\scummsys.98\sputm.98\*.c - -<tr> -<td>Freddi Fish 4: The Case of the Hogfish (demo) -<td>1999 -<td>win -<td> -<td>D:\scummsys.98\sputm.98\*.c - -<tr> -<td>Freddi Fish 5: The Case of the Creature of Coral -<td>2001 -<td>win -<td> -<td>C:\Spyfox3Sputm\Src\*.cpp - -<tr> -<td>Freddi Fish One Stop Fun Shop -<td>2000 -<td>win -<td> -<td>C:\Documents and Settings\stevej\My Documents\HECode\SPUTM\Src\*.cpp<br> - -<tr> -<td>Freddi Fish and Luther's Maze Madness -<td>1999 -<td>win -<td> -<td>D:\scummsys\sputm80\*.c - -<tr> -<td>Freddi Fish and Luther's Water Worries -<td>1999 -<td>win -<td> -<td>D:\scummsys\sputm80\*.c - -<tr> -<td colspan=5> - - -<tr> -<td>Spy Fox 1: Dry Cereal -<td>1997 -<td>win -<td> -<td>D:\Scummsys.90\sputm.90\*.c - -<tr> -<td>Spy Fox 1: Dry Cereal (demo) -<td> -<td> -<td>7.?.? -<td>D:\Scummsys.90\sputm.90\*.c - -<tr> -<td>Spy Fox 1: Dry Cereal (demo) -<td> -<td> -<td>7.?.? -<td>c:\Build\SRC\SPUTM\Src\*.cpp - -<tr> -<td>Spy Fox 2: Some Assembly Required -<td>1999 -<td>win -<td> -<td>D:\(vss)scummsys.99\SPUTM\Src\*.cpp - -<tr> -<td>Spy Fox 2: Some Assembly Required (Demo) -<td> -<td>win -<td> -<td>D:\(vss)scummsys.99\SPUTM\Src\*.cpp - -<tr> -<td>Spy Fox 3: Operation Ozone -<td> -<td>win -<td> -<td>C:\Spyfox3Sputm\Src\SrcPWin\*.cpp - -<tr> -<td>Spy Fox In Cheese Chase -<td>1999 -<td>win -<td> -<td>D:\scummsys.95\sputm.95\*.c - -<tr> -<td>Spy Fox in Hold the Mustard -<td>1999 -<td>win -<td> -<td>D:\(vss)scummsys.99\SPUTM\Src\*.cpp - -<tr> -<td colspan=5> - - -<tr> -<td>Fatty's Birthday Surprise -<td>1993 -<td>dos -<td>6.1.1 (Jun 23 1993 15:31:14) -<td> - -<tr> -<td>Fatty's Birthday Surprise -<td>1993 -<td>win -<td>7.0.0 (Feb 7 1995 13:27:40) -<td> - -<tr> -<td>Fatty's Birthday Surprise -<td>1993 -<td>3do -<td> -<td> - -<tr> -<td>Fatty's Birthday Surprise (demo) -<td>1993 -<td>dos -<td>6.1.1 (Apr 6 1993 20:48:56) -<td> - -<tr> -<td>Fatty's Birthday Surprise (demo) -<td>1993 -<td>win -<td>7.0.0 (Feb 7 1995 13:27:40) -<td> - -<tr> -<td>Fatty Bear's Fun Pack -<td>1993 -<td>dos -<td>6.1.1 (Nov 11 1993 09:17:08) -<td> - -<tr> -<td>Fatty Bear's Fun Pack -<td>1993 -<td>3do -<td> -<td> - -<tr> -<td colspan=5> - - -<tr> -<td>Blue's ABC Time Activities -<td> -<td>win -<td> -<td> - -<tr> -<td>Blue's ABC Time Activities (demo) -<td> -<td>win -<td>7.?.? -<td>D:\scummsys.98\sputm.98\*.c - -<tr> -<td>Blue's 123 Time Activities -<td> -<td>win -<td> -<td> - -<tr> -<td>Blue's Art Time Activities -<td> -<td>win -<td> -<td> - -<tr> -<td>Blue's Birthday Adventure -<td> -<td>win -<td> -<td> - -<tr> -<td>Blue's Learning Time -<td> -<td>win -<td> -<td> - -<tr> -<td>Blue's Play Time -<td> -<td>win -<td> -<td> - -<tr> -<td>Blue's Reading Time Activities -<td> -<td>win -<td> -<td> - -<tr> -<td>Blue's Treasure Hunt -<td> -<td>win -<td> -<td> - -<tr> -<td colspan=5> - - -<tr> -<td>Let's Explore the Airport with Buzzy -<td> -<td>win -<td>7.0.0 (Jul 1 1995 21:55:39) -<td> - -<tr> -<td>Let's Explore the Airport with Buzzy (demo) -<td>1995 -<td>win -<td>7.0.0 (Feb 8 1995 16:33:47) -<td> - -<tr> -<td>Let's Explore the Airport with Buzzy (demo) -<td>1995 -<td>win -<td>7.0.0 (Jun 22 1995 14:06:25) -<td> - -<tr> -<td>Let's Explore the Airport with Buzzy (demo) -<td>1995 -<td>win -<td>7.0.0 (Jul 5 1995 14:46:05) -<td> - -<tr> -<td>Let's Explore the Jungle with Buzzy -<td> -<td>win -<td>7.0.0 (Jul 1 1995 21:55:39)<br>7.0.0 (Oct 5 1995 08:20:42) -<td> - -<tr> -<td>Let's Explore the Farm with Buzzy -<td>1996 -<td>win -<td>7.0.0 (Jun 11 1996 19:12:56) -<td> - -<tr> -<td>Let's Explore the Farm with Buzzy (demo) -<td>1994 -<td>win -<td>7.0.0 (Oct 13 1994 19:15:16) -<td> - -<tr> -<td>Let's Explore the Farm with Buzzy (demo) (farm cd) -<td>1995 -<td>win -<td>7.0.0 (Jun 22 1995 14:05:27) -<td> - -<tr> -<td colspan=5> - - -<tr> -<td>Big Thinkers First Grade -<td> -<td>win -<td> -<td> - -<tr> -<td>Big Thinkers First Grade (demo) -<td>1997 -<td>win -<td> -<td>D:\Scummsys.90\sputm.90\*.c - -<tr> -<td>Big Thinkers Kindergarten -<td>1997 -<td>win -<td> -<td>D:\Scummsys.90\sputm.90\*.c - -<tr> -<td>Big Thinkers Kindergarten (demo) -<td>1997 -<td>win -<td> -<td>D:\Scummsys.90\sputm.90\*.c - -<tr> -<td colspan=5> - - -<tr> -<td>Humongous demo launcher "catalog" -<td>1995 -<td>win -<td>7.0.0 (Feb 8 1995 16:33:26) -<td> - -<tr> -<td>Humongous demo launcher "catalog2" -<td>1995 -<td>win -<td>7.0.0 (Jun 22 1995 14:01:50) -<td> - -<tr> -<td colspan=5> - - -<tr> -<td>Backyard Basketball -<td>2001 -<td>win -<td> -<td>c:\Build\SRC\SPUTM\Src\*.cpp - -<tr> -<td>Backyard Soccer -<td>1998 -<td>win -<td> -<td>D:\scummsys.98\sputm.98\*.c - -<tr> -<td>Backyard Soccer 2004 -<td>2003 -<td>win -<td> -<td>F:\HEdev\scummsys\SPUTM\Src\*.cpp - -<tr> -<td>Backyard Football -<td>1999 -<td>win -<td> -<td> - -<tr> -<td>Backyard Football 2002 -<td>? -<td>win -<td> -<td>C:\SRC_RELEASE\SPUTM\Src\*.cpp - -<tr> -<td>Backyard Baseball -<td>1997 -<td>win -<td> -<td>D:\Scummsys.90\sputm.90\*.c - -<tr> -<td>Backyard Baseball 2001 -<td>2000 -<td>win -<td> -<td>C:\Dev\Project\SPUTM\Src\*.cpp - -<tr> -<td>Backyard Baseball 2001 (demo) -<td>2000 -<td>win -<td> -<td>C:\Dev\Project\SPUTM\Src\*.cpp -</table> -</html> diff --git a/doc/translations/de/Liesmich.txt b/doc/translations/de/Liesmich.txt deleted file mode 100755 index a1d7d6eb5f..0000000000 --- a/doc/translations/de/Liesmich.txt +++ /dev/null @@ -1,178 +0,0 @@ -Dieses Dokument ist eine auszugsweise Ãœbersetzung der englischen -REAMDE-Datei. Das Original-Dokument enthält viel mehr Informationen. -Sollten Sie hier also nicht das finden, was Sie benötigen und ein wenig -Englisch können, sollten Sie sich die englische README-Datei ansehen. - -Für weitere Informationen, Kompatiblitätslisten, Einzelheiten zu Spenden, -die neusten veröffentlichten Versionen, Fortschrittberichte und mehr -besuchen Sie bitte die ScummVM-Website unter der Adresse: -http://www.scummvm.org/ - -Inhaltsverzeichnis: ------------------- -1.0) Einführung - * 1.1 Ãœber ScummVM - * 1.2 Schnellstart -2.0) Kontakt - * 2.1 Fehler berichten - -1.0) Einführung: ----- ------------- - -1.1) Ãœber ScummVM: ----- -------------- -ScummVM ist ein Programm, welches es Ihnen ermöglicht, bestimmte klassische -Grafik-Adventure (unter anderem aus dem Point-and-Click-Bereich) zu spielen, -vorausgesetzt, Sie sind im Besitz der Dateien des Spiels. Das Schlaue daran -ist: ScummVM ersetzt lediglich die Funktion der ausführbaren Dateien, -die mit den Spielen kamen, was ermöglicht, diese Spiele auf Systemen zu spielen, -für welche sie nie erstellt wurden! - -Ursprünglich wurde dieses Programm dafür entwickelt, um SCUMM-Spiele von -LucasArts auszuführen, wie beispielsweise Maniac Mansion, Monkey Island, -Day of the Tentacle oder Sam and Max. SCUMM steht als Abkürzung für -„Script Creation Utility for Maniac Mansion“ (deutsch etwa: -Skripterstellungsdienstprogramm für Maniac Mansion), was das erste -Spiel von LucasArts war, für welches LucasArts dieses System entworfen hatte. -Und viel später verlieh es seinen Namen an ScummVM (wobei „VM“ für -„Virtuelle Maschine“ steht). - -Mit der Zeit wurde Unterstützung für viele Nicht-SCUMM-Spiele hinzugefügt. -Einige Adventures, die ScummVM unterstützt, sind unter anderem Simon the -Sorcerer 1 und 2 von Adventure Soft, Beneath A Steel Sky und -Baphomets Fluch 1 und 2 von Revolution, Flight of the Amazon Queen, -Erben der Erde (Wyrmkeep), Gobliiins von Coktel Vision sowie -The Legend of Kyrandia von Westwood Studios. -Sie können eine genaue Liste mit Einzelheiten einsehen, welche Auskunft -darüber gibt, welche Spiele unterstützt werden und wie gut. Gehen Sie -hierfür auf die Kompatiblitätsseite. ScummVM wird kontinuierlich -verbessert, also schauen Sie oft vorbei. - -Unter den Systemen, mit denen Sie diese Spiele spielen können, befinden -sich Windows, Linux, Mac OS X, Dreamcast, PocketPC, PalmOS, iPhone, -AmigaOS, BeOS, OS/2, PSP, PS2, SymbianOS/EPOC und viele mehr. - -Zurzeit befindet sich ScummVM immer noch stark in der Entwicklung. -Seien Sie sich bewusst, dass wir zwar versuchen, dass viele Spiele -mit wenigen erheblichen Fehlern durchgespielt werden können, aber es -dennoch zu Abstürzen kommen kann und wir keine Gewähr übernehmen. -Davon abgesehen: Einige Spiele werden seit längerer Zeit unterstützt -und sollten in jeder stabilen veröffentlichten Version gut laufen. -Sie können sich einen Eindruck davon verschaffen, wie gut jedes Spiel -unter ScummVM läuft, indem Sie auf die Kompatiblitätsseite schauen. - -Wenn Sie sich ein wenig umsehen, können Sie herausfinden, dass -ScummVM sogar kommerziell genutzt wird, um einige der unterstützen Spiele -auf modernen Plattformen wiederzuveröffentlichen. Dies zeigt, dass -verschiedene Firmen mit der Qualität der Software zufrieden sind und wie gut -einige der Spiele mit ihrer Hilfe laufen. - -Wenn Ihnen ScummVM gefällt, können Sie uns gerne etwas Geld spenden, -um uns finanziell zu unterstützen. Dies hilft uns dabei, notwendige -Dienstprogramme zu kaufen, um ScummVM einfacher und schneller zu entwickeln. -Wenn Sie nicht spenden können, dürfen Sie auch gerne einen Patch beisteuern. - -1.2) Schnellstart: ----- ------------ -WICHTIG: In der unteren kurzen Anleitung wird davon ausgegangen, dass Sie -ScummVM auf Deutsch benutzen. Standardmäßig wird ScummVM die Sprache -Ihres Betriebssystems verwenden. Falls ScummVM auf Englisch statt auf -Deutsch erscheint, sollten Sie folgende Schritte ausführen, wenn Sie bei -Schritt 3 angelangt sind und ScummVM gestartet haben: --Klicken Sie auf "Options". --Klicken Sie auf den rechten Pfeil in der Reiterleiste und wählen den - Reiter "Misc" aus. --Wählen Sie im Feld "GUI Language" "Deutsch" aus und klicken auf "OK". --Bestätigen Sie die erscheinende Nachricht, klicken auf "Quit", um - ScummVM zu beenden und starten dann das Programm erneut. - -Wenn Sie ScummVM lieber in Englisch verwenden möchten, benutzen Sie bitte -die Anleitung in der englischen README-Datei. - - -Für die ungelduldigen unter den Benutzern ist hier in fünf einfachen -Schritten kurz beschrieben, wie man ScummVM lauffähig macht und das -Programm verwendet. - -1. Laden Sie ScummVM unter der Adresse -<http://www.scummvm.org/downloads.php> herunter und installieren Sie es. - -2. Erstellen Sie ein Verzeichnis auf Ihrer Festplatte und kopieren Sie -die Dateien des Spiels vom Original-Datenträger in dieses Verzeichnis. -Wiederholen Sie diesen Vorgang für jedes Spiel, das Sie spielen möchten. - -3. Starten Sie ScummVM, wählen Sie "Spiel hinzufügen" aus, wählen Sie das -Verzeichnis mit den Dateien des Spiels aus (versuchen Sie nicht, die -Dateien des Spiels selbst auszuwählen!) und klicken Sie auf "Auswählen". - -4. Ein Dialog sollte erscheinen, der Ihnen ermöglicht, verschiedene -Einstellungen vorzunehmn, sollten Sie dies wünschen (es sollte jedoch in -Ordnung sein, alles voreingestellt zu belassen). Bestätigen Sie diesen -Dialog. - -5. Wählen Sie das Spiel aus der Liste aus, welches Sie spielen möchten -und klicken Sie auf "Starten". - -In Zukunft sollte es nun möglich sein, direkt zu Schritt 5 überzugehen, -außer Sie wollen noch mehr Spiele hinzufügen. - -Tipp: Wenn Sie mehrere Spiele auf einmal hinzufügen möchten, drücken Sie -die Umschalt-Taste (Shift), bevor Sie auf "Spiel hinzufügen" klicken. -Diese Schaltfläche wird somit ihren Text zu "Durchsuchen" umändern und -wenn Sie dann auf diese klicken, werden Sie auch dazu aufgefordert, ein -Verzeichnis auszuwählen, nur dieses Mal wird ScummVM alle -Unterverzeichnisse automatisch nach unterstützen Spielen durchsuchen. - - -2.0) Kontakt: ----- -------- -Der einfachste Weg, um mit dem ScummVM-Team in Verbindung zu treten, ist, -Fehlerberichte einzusenden (siehe Abschnitt 2.1) oder durch Verwendung -des Forums unter der Adresse http://forums.scummvm.org . -Sie können ebenso der Mailing-Liste scummvm-devel betreiten und an diese -E-Mails versenden oder mit uns im IRC chatten (#scummvm unter -irc.freenode.net). Bitte fordern Sie uns nicht dazu auf, ein nicht -unterstütztes Spiel zu unterstützen. Lesen Sie zuerst die Seite FAQ -(Häufig gestellte Fragen) auf unserer Website. -Bitte beachten Sie Kenntnis, dass die offizielle Sprache des Forums, -der Mailing-Liste und des Chats Englisch ist und keine andere Sprache -dort verwendet werden sollte. - - -2.1) Fehler berichten: ----- --------------- -Um einen Fehler zu berichten, erstellen Sie bitte ein SourceForge-Konto -und folgen Sie dem Link "Bug Tracker" auf der ScummVM-Website. Bitte -stellen Sie sicher, dass sich der Bug wiedererzeugen lässt und immer noch -in der neusten Version von SVN oder des Daily builds auftritt. Bitte -sehen Sie auch auf der Problemliste unten und der Kompatiblitätsliste auf -der ScummVM-Website für dieses Spiel nach, um sicherzustellen, dass das -Problem nicht bereits bekannt ist: - - http://www.scummvm.org/compatibility_stable.php - -Bitte berichten Sie keine Fehler zu Spielen, die nicht als durchspielbar -im Bereich "Supported Games" oder der Kompatiblitätsliste aufgelistet -sind. Wir -wissen-, dass diese Spiele Fehler aufweisen. - -Bitte liefern Sie folgende Informationen: - - ScummVM-Version (BITTE mit neuster Version von SVN oder - des Daily builds testen) - - Einzelheiten zum Fehler, einschließlich Anweisungen, um den Fehler - hervorzurufen - - Sprache des Spiels (Englisch, Deutsch, ...) - - Version des Spiels (Version mit Sprachausgabe [Talkie], - Disketten-Version, ...) - - Plattform und gegebenenfalls Compiler (Win32, Linux, FreeBSD, ...) - - Fügen Sie einen Speicherstand hinzu, wenn es möglich ist. - - Wenn dieser Fehler erst seit kurzem Auftritt, teilen Sie bitte die - letzte Version ohne den Fehler mit und die erste Version mit diesem - Fehler. Auf diese Weise können wir diesen schneller beseitigen, - indem wir die vorgenommen Veränderungen einsehen. - -Zum Schluss möchten wir Sie noch bitten, jeden Punkt einzeln zu -berichten; bitte senden Sie nicht mehrere Punkte mit dem selben Ticket -ein, ansonsten wird es schwierig, den Status jedes einzelnen Fehlers -zu verfolgen. Denken Sie bitte auch daran, dass alle Fehlerberichte in -Englisch verfasst sein müssen. - diff --git a/engines/agi/preagi_winnie.cpp b/engines/agi/preagi_winnie.cpp index 1df31ff72a..af26fe62d0 100644 --- a/engines/agi/preagi_winnie.cpp +++ b/engines/agi/preagi_winnie.cpp @@ -86,27 +86,30 @@ void Winnie::parseObjHeader(WTP_OBJ_HDR *objHdr, byte *buffer, int len) { } uint32 Winnie::readRoom(int iRoom, uint8 *buffer, WTP_ROOM_HDR &roomHdr) { - char szFile[256] = {0}; + Common::String fileName; if (_vm->getPlatform() == Common::kPlatformPC) - sprintf(szFile, IDS_WTP_ROOM_DOS, iRoom); + fileName = Common::String::format(IDS_WTP_ROOM_DOS, iRoom); else if (_vm->getPlatform() == Common::kPlatformAmiga) - sprintf(szFile, IDS_WTP_ROOM_AMIGA, iRoom); + fileName = Common::String::format(IDS_WTP_ROOM_AMIGA, iRoom); else if (_vm->getPlatform() == Common::kPlatformC64) - sprintf(szFile, IDS_WTP_ROOM_C64, iRoom); + fileName = Common::String::format(IDS_WTP_ROOM_C64, iRoom); else if (_vm->getPlatform() == Common::kPlatformApple2GS) - sprintf(szFile, IDS_WTP_ROOM_APPLE, iRoom); + fileName = Common::String::format(IDS_WTP_ROOM_APPLE, iRoom); + Common::File file; - if (!file.open(szFile)) { - warning ("Could not open file \'%s\'", szFile); + if (!file.open(fileName)) { + warning("Could not open file \'%s\'", fileName.c_str()); return 0; } + uint32 filelen = file.size(); - if (_vm->getPlatform() == Common::kPlatformC64) { //Skip the loading address + if (_vm->getPlatform() == Common::kPlatformC64) { // Skip the loading address filelen -= 2; file.seek(2, SEEK_CUR); } - memset(buffer, 0, sizeof(buffer)); + + memset(buffer, 0, 4096); file.read(buffer, filelen); file.close(); @@ -116,26 +119,30 @@ uint32 Winnie::readRoom(int iRoom, uint8 *buffer, WTP_ROOM_HDR &roomHdr) { } uint32 Winnie::readObj(int iObj, uint8 *buffer) { - char szFile[256] = {0}; + Common::String fileName; + if (_vm->getPlatform() == Common::kPlatformPC) - sprintf(szFile, IDS_WTP_OBJ_DOS, iObj); + fileName = Common::String::format(IDS_WTP_OBJ_DOS, iObj); else if (_vm->getPlatform() == Common::kPlatformAmiga) - sprintf(szFile, IDS_WTP_OBJ_AMIGA, iObj); + fileName = Common::String::format(IDS_WTP_OBJ_AMIGA, iObj); else if (_vm->getPlatform() == Common::kPlatformC64) - sprintf(szFile, IDS_WTP_OBJ_C64, iObj); + fileName = Common::String::format(IDS_WTP_OBJ_C64, iObj); else if (_vm->getPlatform() == Common::kPlatformApple2GS) - sprintf(szFile, IDS_WTP_OBJ_APPLE, iObj); + fileName = Common::String::format(IDS_WTP_OBJ_APPLE, iObj); + Common::File file; - if (!file.open(szFile)) { - warning ("Could not open file \'%s\'", szFile); + if (!file.open(fileName)) { + warning ("Could not open file \'%s\'", fileName.c_str()); return 0; } + uint32 filelen = file.size(); - if (_vm->getPlatform() == Common::kPlatformC64) { //Skip the loading address + if (_vm->getPlatform() == Common::kPlatformC64) { // Skip the loading address filelen -= 2; file.seek(2, SEEK_CUR); } - memset(buffer, 0, sizeof(buffer)); + + memset(buffer, 0, 2048); file.read(buffer, filelen); file.close(); return filelen; @@ -461,8 +468,6 @@ void Winnie::keyHelp() { } void Winnie::inventory() { - char szMissing[41] = {0}; - if (_game.iObjHave) printObjStr(_game.iObjHave, IDI_WTP_OBJ_TAKE); else { @@ -470,8 +475,9 @@ void Winnie::inventory() { _vm->drawStr(IDI_WTP_ROW_MENU, IDI_WTP_COL_MENU, IDA_DEFAULT, IDS_WTP_INVENTORY_0); } - sprintf(szMissing, IDS_WTP_INVENTORY_1, _game.nObjMiss); - _vm->drawStr(IDI_WTP_ROW_OPTION_4, IDI_WTP_COL_MENU, IDA_DEFAULT, szMissing); + Common::String missing = Common::String::format(IDS_WTP_INVENTORY_1, _game.nObjMiss); + + _vm->drawStr(IDI_WTP_ROW_OPTION_4, IDI_WTP_COL_MENU, IDA_DEFAULT, missing.c_str()); _vm->_gfx->doUpdate(); _vm->_system->updateScreen(); //TODO: Move to game's main loop _vm->getSelection(kSelAnyKey); @@ -1042,16 +1048,15 @@ phase2: } void Winnie::drawPic(const char *szName) { - char szFile[256] = {0}; - Common::File file; + Common::String fileName = szName; - // construct filename if (_vm->getPlatform() != Common::kPlatformAmiga) - sprintf(szFile, "%s.pic", szName); - else - strcpy(szFile, szName); - if (!file.open(szFile)) { - warning ("Could not open file \'%s\'", szFile); + fileName += ".pic"; + + Common::File file; + + if (!file.open(fileName)) { + warning ("Could not open file \'%s\'", fileName.c_str()); return; } @@ -1142,12 +1147,11 @@ void Winnie::gameOver() { } void Winnie::saveGame() { - Common::OutSaveFile* outfile; - char szFile[256] = {0}; int i = 0; - sprintf(szFile, IDS_WTP_FILE_SAVEGAME); - if (!(outfile = _vm->getSaveFileMan()->openForSaving(szFile))) + Common::OutSaveFile *outfile = _vm->getSaveFileMan()->openForSaving(IDS_WTP_FILE_SAVEGAME); + + if (!outfile) return; outfile->writeUint32BE(MKTAG('W','I','N','N')); // header @@ -1171,19 +1175,18 @@ void Winnie::saveGame() { outfile->finalize(); if (outfile->err()) - warning("Can't write file '%s'. (Disk full?)", szFile); + warning("Can't write file '%s'. (Disk full?)", IDS_WTP_FILE_SAVEGAME); delete outfile; } void Winnie::loadGame() { - Common::InSaveFile* infile; - char szFile[256] = {0}; int saveVersion = 0; int i = 0; - sprintf(szFile, IDS_WTP_FILE_SAVEGAME); - if (!(infile = _vm->getSaveFileMan()->openForLoading(szFile))) + Common::InSaveFile *infile = _vm->getSaveFileMan()->openForLoading(IDS_WTP_FILE_SAVEGAME); + + if (!infile) return; if (infile->readUint32BE() == MKTAG('W','I','N','N')) { diff --git a/engines/dreamweb/detection.cpp b/engines/dreamweb/detection.cpp index d32be6a2b7..ef4a746b62 100644 --- a/engines/dreamweb/detection.cpp +++ b/engines/dreamweb/detection.cpp @@ -43,7 +43,7 @@ public: AdvancedMetaEngine(DreamWeb::gameDescriptions, sizeof(DreamWeb::DreamWebGameDescription), dreamWebGames) { _singleid = "dreamweb"; - _guioptions = Common::GUIO_NOMIDI; + _guioptions = Common::GUIO_NOMIDI | Common::GUIO_NOLAUNCHLOAD; } virtual const char *getName() const { diff --git a/engines/dreamweb/dreamgen.cpp b/engines/dreamweb/dreamgen.cpp index a183c7c798..a25fae0874 100644 --- a/engines/dreamweb/dreamgen.cpp +++ b/engines/dreamweb/dreamgen.cpp @@ -11039,19 +11039,6 @@ void DreamGenContext::scrollmonitor() { ax = pop(); } -void DreamGenContext::lockmon() { - STACK_CHECK; - _cmp(data.byte(kLasthardkey), 57); - if (!flags.z()) - return /* (notlock) */; - locklighton(); -lockloop: - _cmp(data.byte(kLasthardkey), 57); - if (flags.z()) - goto lockloop; - locklightoff(); -} - void DreamGenContext::monitorlogo() { STACK_CHECK; al = data.byte(kLogonum); @@ -22407,7 +22394,6 @@ void DreamGenContext::__dispatch_call(uint16 addr) { case 0xc550: searchforstring(); break; case 0xc554: parser(); break; case 0xc558: scrollmonitor(); break; - case 0xc55c: lockmon(); break; case 0xc560: monitorlogo(); break; case 0xc564: printlogo(); break; case 0xc568: showcurrentfile(); break; diff --git a/engines/dreamweb/dreamgen.h b/engines/dreamweb/dreamgen.h index 71c466da24..08053b6f54 100644 --- a/engines/dreamweb/dreamgen.h +++ b/engines/dreamweb/dreamgen.h @@ -602,7 +602,6 @@ public: void clearbuffers(); void neterror(); void storeit(); - void lockeddoorway(); void isitworn(); void putundertimed(); void dumpmap(); @@ -958,9 +957,8 @@ public: void showmonk(); void diarykeyn(); void set16colpalette(); - void convicons(); - void interviewer(); void sparky(); + void interviewer(); void purgeanitem(); void madman(); void createpanel(); @@ -1255,12 +1253,14 @@ public: void usechurchgate(); void monkandryan(); void allocatebuffers(); + void convicons(); void swapwithinv(); void usecontrol(); void buttonseven(); void redrawmainscrn(); void finishedwalking(); void findallryan(); + void lockeddoorway(); void channel0tran(); void buttonpress(); void parseblaster(); diff --git a/engines/dreamweb/dreamweb.cpp b/engines/dreamweb/dreamweb.cpp index eebadfddae..719549cc7d 100644 --- a/engines/dreamweb/dreamweb.cpp +++ b/engines/dreamweb/dreamweb.cpp @@ -219,7 +219,13 @@ Common::Error DreamWebEngine::run() { syncSoundSettings(); _console = new DreamWebConsole(this); - _loadSavefile = Common::ConfigManager::instance().getInt("save_slot"); + if (ConfMan.hasKey("save_slot")) { + _enableSavingOrLoading = true; + _loadSavefile = ConfMan.getInt("save_slot"); + } else { + _enableSavingOrLoading = false; + _loadSavefile = -1; + } getTimerManager()->installTimerProc(vSyncInterrupt, 1000000 / 70, this); _context.__start(); @@ -591,7 +597,7 @@ uint8 DreamWebEngine::modifyChar(uint8 c) const { return 'Z' + 4; case 154: return 'Z' + 6; - case 255: + case 225: return 'A' - 1; case 153: return 'Z' + 5; diff --git a/engines/dreamweb/stubs.cpp b/engines/dreamweb/stubs.cpp index 5614aa391a..2d3c819561 100644 --- a/engines/dreamweb/stubs.cpp +++ b/engines/dreamweb/stubs.cpp @@ -554,4 +554,30 @@ void DreamGenContext::modifychar() { al = engine->modifyChar(al); } +void DreamGenContext::lockmon() { + // Pressing space pauses text output in the monitor. We use the "hard" + // key because calling readkey() drains characters from the input + // buffer, we we want the user to be able to type ahead while the text + // is being printed. + if (data.byte(kLasthardkey) == 57) { + // Clear the keyboard buffer. Otherwise the space that caused + // the pause will be read immediately unpause the game. + do { + readkey(); + } while (data.byte(kCurrentkey) != 0); + + locklighton(); + while (!engine->shouldQuit()) { + engine->waitForVSync(); + readkey(); + if (data.byte(kCurrentkey) == ' ') + break; + } + // Forget the last "hard" key, otherwise the space that caused + // the unpausing will immediately re-pause the game. + data.byte(kLasthardkey) = 0; + locklightoff(); + } +} + } /*namespace dreamgen */ diff --git a/engines/engine.cpp b/engines/engine.cpp index b952f065ad..b19daa2611 100644 --- a/engines/engine.cpp +++ b/engines/engine.cpp @@ -410,7 +410,7 @@ void Engine::openMainMenuDialog() { // value, which is quite bad since it could // be a fatal loading error, which renders // the engine unusable. - if (_saveSlotToLoad > 0) + if (_saveSlotToLoad >= 0) loadGameState(_saveSlotToLoad); syncSoundSettings(); diff --git a/engines/groovie/saveload.cpp b/engines/groovie/saveload.cpp index a0463db0be..14e7a09cb2 100644 --- a/engines/groovie/saveload.cpp +++ b/engines/groovie/saveload.cpp @@ -102,7 +102,7 @@ Common::InSaveFile *SaveLoad::openForLoading(const Common::String &target, int s // Fill the SaveStateDescriptor if it was provided if (descriptor) { // Initialize the SaveStateDescriptor - descriptor->setVal("save_slot", Common::String('0' + slot)); + descriptor->setSaveSlot(slot); descriptor->setDeletableFlag(true); descriptor->setWriteProtectedFlag(false); @@ -132,7 +132,7 @@ Common::InSaveFile *SaveLoad::openForLoading(const Common::String &target, int s description += c; } } - descriptor->setVal("description", description); + descriptor->setDescription(description); } // Return a substream, skipping the metadata diff --git a/engines/groovie/script.cpp b/engines/groovie/script.cpp index f87e6bb91b..5a24559e8b 100644 --- a/engines/groovie/script.cpp +++ b/engines/groovie/script.cpp @@ -1350,15 +1350,15 @@ void Script::o_checkvalidsaves() { uint count = 0; SaveStateList::iterator it = list.begin(); while (it != list.end()) { - int8 slot = it->getVal("save_slot").lastChar() - '0'; + int8 slot = it->getSaveSlot(); if (SaveLoad::isSlotValid(slot)) { - debugScript(2, true, " Found valid savegame: %s", it->getVal("description").c_str()); + debugScript(2, true, " Found valid savegame: %s", it->getDescription().c_str()); // Mark this slot as used setVariable(slot, 1); // Cache this slot's description - _saveNames[slot] = it->getVal("description"); + _saveNames[slot] = it->getDescription(); count++; } it++; diff --git a/engines/kyra/debugger.cpp b/engines/kyra/debugger.cpp index e8dd9e9a15..4a48ac0674 100644 --- a/engines/kyra/debugger.cpp +++ b/engines/kyra/debugger.cpp @@ -71,7 +71,7 @@ bool Debugger::cmd_loadPalette(int argc, const char **argv) { } if (_vm->game() != GI_KYRA1 && _vm->resource()->getFileSize(argv[1]) != 768) { - uint8 *buffer = (uint8 *)malloc(320 * 200 * sizeof(uint8)); + uint8 *buffer = new uint8[320 * 200 * sizeof(uint8)]; if (!buffer) { DebugPrintf("ERROR: Cannot allocate buffer for screen region!\n"); return true; @@ -82,7 +82,7 @@ bool Debugger::cmd_loadPalette(int argc, const char **argv) { palette.copy(_vm->screen()->getCPagePtr(5), 0, 256); _vm->screen()->copyBlockToPage(5, 0, 0, 320, 200, buffer); - free(buffer); + delete[] buffer; } else if (!_vm->screen()->loadPalette(argv[1], palette)) { DebugPrintf("ERROR: Palette '%s' not found!\n", argv[1]); return true; diff --git a/engines/kyra/detection_tables.h b/engines/kyra/detection_tables.h index 47a3c4362a..165eddf599 100644 --- a/engines/kyra/detection_tables.h +++ b/engines/kyra/detection_tables.h @@ -99,6 +99,18 @@ const KYRAGameDescription adGameDescs[] = { { "kyra1", "Extracted", + AD_ENTRY1("GEMCUT.EMC", "689b62b7519215c1b2571d466c95624c"), + Common::RU_RUS, + Common::kPlatformPC, + ADGF_NO_FLAGS, + Common::GUIO_NOSPEECH | Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIPCSPK + }, + KYRA1_FLOPPY_FLAGS + }, + { + { + "kyra1", + "Extracted", AD_ENTRY1("GEMCUT.EMC", "796e44863dd22fa635b042df1bf16673"), Common::EN_ANY, Common::kPlatformPC, @@ -977,6 +989,24 @@ const KYRAGameDescription adGameDescs[] = { "lol", "CD", { + { "GENERAL.PAK", 0, "19354b0f464295c38c801d30588df062", -1 }, + { "L01.PAK", 0, "174d37f21e0336c5d91020f8c58717ef", -1 }, + { "VOC.PAK", 0, "eb398f09ba3321d872b6174a68a987d9", -1 }, + { 0, 0, 0, 0 } + }, + Common::RU_RUS, + Common::kPlatformPC, + ADGF_DROPLANGUAGE | ADGF_CD, + Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + }, + LOL_CD_FLAGS + }, + + { + { + "lol", + "CD", + { { "GENERAL.PAK", 0, "05a4f588fb81dc9c0ef1f2ec20d89e24", -1 }, { "L01.PAK", 0, "759a0ac26808d77ea968bd392355ba1d", -1 }, { 0, 0, 0, 0 } diff --git a/engines/kyra/gui_lok.cpp b/engines/kyra/gui_lok.cpp index eac82ec2c5..eba2f8f279 100644 --- a/engines/kyra/gui_lok.cpp +++ b/engines/kyra/gui_lok.cpp @@ -576,6 +576,15 @@ void GUI_LoK::setupSavegames(Menu &menu, int num) { if ((in = _vm->openSaveForReading(_vm->getSavegameFilename(_saveSlots[i + _savegameOffset]), header))) { Common::strlcpy(_savegameNames[i], header.description.c_str(), ARRAYSIZE(_savegameNames[0])); + // Trim long GMM save descriptions to fit our save slots + _screen->_charWidth = -2; + int fC = _screen->getTextWidth(_savegameNames[i]); + while (_savegameNames[i][0] && (fC > 240 )) { + _savegameNames[i][strlen(_savegameNames[i]) - 1] = 0; + fC = _screen->getTextWidth(_savegameNames[i]); + } + _screen->_charWidth = 0; + Util::convertISOToDOS(_savegameNames[i]); menu.item[i].itemString = _savegameNames[i]; @@ -693,12 +702,15 @@ void GUI_LoK::updateSavegameString() { if (_keyPressed.keycode) { length = strlen(_savegameName); + _screen->_charWidth = -2; + int width = _screen->getTextWidth(_savegameName) + 7; + _screen->_charWidth = 0; char inputKey = _keyPressed.ascii; Util::convertISOToDOS(inputKey); if ((uint8)inputKey > 31 && (uint8)inputKey < (_vm->gameFlags().lang == Common::JA_JPN ? 128 : 226)) { - if (length < ARRAYSIZE(_savegameName)-1) { + if ((length < ARRAYSIZE(_savegameName)-1) && (width <= 240)) { _savegameName[length] = inputKey; _savegameName[length+1] = 0; redrawTextfield(); diff --git a/engines/kyra/gui_lol.cpp b/engines/kyra/gui_lol.cpp index fb11040168..c64d3e7723 100644 --- a/engines/kyra/gui_lol.cpp +++ b/engines/kyra/gui_lol.cpp @@ -2572,9 +2572,19 @@ void GUI_LoL::setupSaveMenuSlots(Menu &menu, int num) { slotOffs = 1; } + int saveSlotMaxLen = ((_screen->getScreenDim(8))->w << 3) - _screen->getCharWidth('W'); + for (int i = startSlot; i < num && _savegameOffset + i - slotOffs < _savegameListSize; ++i) { if (_savegameList[_saveSlots[i + _savegameOffset - slotOffs]]) { Common::strlcpy(s, _savegameList[_saveSlots[i + _savegameOffset - slotOffs]], 80); + + // Trim long GMM save descriptions to fit our save slots + int fC = _screen->getTextWidth(s); + while (s[0] && fC >= saveSlotMaxLen) { + s[strlen(s) - 1] = 0; + fC = _screen->getTextWidth(s); + } + menu.item[i].itemString = s; s += (strlen(s) + 1); menu.item[i].saveSlot = _saveSlots[i + _savegameOffset - slotOffs]; diff --git a/engines/kyra/gui_v2.cpp b/engines/kyra/gui_v2.cpp index 0b82df8cd5..dcc53b7c9e 100644 --- a/engines/kyra/gui_v2.cpp +++ b/engines/kyra/gui_v2.cpp @@ -457,6 +457,15 @@ void GUI_v2::setupSavegameNames(Menu &menu, int num) { Common::strlcpy(s, header.description.c_str(), 80); Util::convertISOToDOS(s); + // Trim long GMM save descriptions to fit our save slots + _screen->_charWidth = -2; + int fC = _screen->getTextWidth(s); + while (s[0] && fC > 240) { + s[strlen(s) - 1] = 0; + fC = _screen->getTextWidth(s); + } + _screen->_charWidth = 0; + menu.item[i].saveSlot = _saveSlots[i + _savegameOffset]; menu.item[i].enabled = true; delete in; diff --git a/engines/kyra/kyra_v1.cpp b/engines/kyra/kyra_v1.cpp index 3d81368d2d..3b2c9b67eb 100644 --- a/engines/kyra/kyra_v1.cpp +++ b/engines/kyra/kyra_v1.cpp @@ -83,7 +83,9 @@ KyraEngine_v1::KyraEngine_v1(OSystem *system, const GameFlags &flags) } void KyraEngine_v1::pauseEngineIntern(bool pause) { - _sound->pause(pause); + Engine::pauseEngineIntern(pause); + if (_sound) + _sound->pause(pause); _timer->pause(pause); } diff --git a/engines/kyra/sound.cpp b/engines/kyra/sound.cpp index 3713537afd..4da35cc28b 100644 --- a/engines/kyra/sound.cpp +++ b/engines/kyra/sound.cpp @@ -43,10 +43,6 @@ Sound::Sound(KyraEngine_v1 *vm, Audio::Mixer *mixer) Sound::~Sound() { } -void Sound::pause(bool paused) { - _mixer->pauseAll(paused); -} - bool Sound::voiceFileIsPresent(const char *file) { for (int i = 0; _supportedCodecs[i].fileext; ++i) { Common::String f = file; diff --git a/engines/kyra/sound.h b/engines/kyra/sound.h index 566b37ff43..c3c32331be 100644 --- a/engines/kyra/sound.h +++ b/engines/kyra/sound.h @@ -156,7 +156,7 @@ public: /** * Stops all audio playback when paused. Continues after end of pause. */ - virtual void pause(bool paused); + virtual void pause(bool paused) {} void enableMusic(int enable) { _musicEnabled = enable; } int musicEnabled() const { return _musicEnabled; } diff --git a/engines/kyra/sound_midi.cpp b/engines/kyra/sound_midi.cpp index dc0f8c11ec..26b6b31d0a 100644 --- a/engines/kyra/sound_midi.cpp +++ b/engines/kyra/sound_midi.cpp @@ -716,9 +716,6 @@ void SoundMidiPC::beginFadeOut() { } void SoundMidiPC::pause(bool paused) { - // Stop all mixer related sounds - Sound::pause(paused); - Common::StackLock lock(_mutex); if (paused) { diff --git a/engines/lastexpress/data/snd.cpp b/engines/lastexpress/data/snd.cpp index fa2d8a2e51..6845be8808 100644 --- a/engines/lastexpress/data/snd.cpp +++ b/engines/lastexpress/data/snd.cpp @@ -36,16 +36,336 @@ namespace LastExpress { +#pragma region Sound filters tables + +static const int stepTable[1424] = { + 0, 0, 0, 0, 128, 256, 384, 512, 0, 0, 0, 0, 128, 256, + 384, 512, 0, 0, 0, 0, 192, 320, 448, 576, 0, 0, 0, 0, + 192, 320, 448, 576, 64, 64, 64, 64, 256, 384, 512, 640, + 64, 64, 64, 64, 256, 384, 512, 640, 128, 128, 128, 128, + 320, 448, 576, 704, 128, 128, 128, 128, 320, 448, 576, + 704, 192, 192, 192, 192, 384, 512, 640, 768, 192, 192, + 192, 192, 384, 512, 640, 768, 256, 256, 256, 256, 448, + 576, 704, 832, 256, 256, 256, 256, 448, 576, 704, 832, + 320, 320, 320, 320, 512, 640, 768, 896, 320, 320, 320, + 320, 512, 640, 768, 896, 384, 384, 384, 384, 576, 704, + 832, 960, 384, 384, 384, 384, 576, 704, 832, 960, 448, + 448, 448, 448, 640, 768, 896, 1024, 448, 448, 448, 448, + 640, 768, 896, 1024, 512, 512, 512, 512, 704, 832, 960, + 1088, 512, 512, 512, 512, 704, 832, 960, 1088, 576, + 576, 576, 576, 768, 896, 1024, 1152, 576, 576, 576, + 576, 768, 896, 1024, 1152, 640, 640, 640, 640, 832, + 960, 1088, 1216, 640, 640, 640, 640, 832, 960, 1088, + 1216, 704, 704, 704, 704, 896, 1024, 1152, 1280, 704, + 704, 704, 704, 896, 1024, 1152, 1280, 768, 768, 768, + 768, 960, 1088, 1216, 1344, 768, 768, 768, 768, 960, + 1088, 1216, 1344, 832, 832, 832, 832, 1024, 1152, 1280, + 1408, 832, 832, 832, 832, 1024, 1152, 1280, 1408, 896, + 896, 896, 896, 1088, 1216, 1344, 1472, 896, 896, 896, + 896, 1088, 1216, 1344, 1472, 960, 960, 960, 960, 1152, + 1280, 1408, 1536, 960, 960, 960, 960, 1152, 1280, 1408, + 1536, 1024, 1024, 1024, 1024, 1216, 1344, 1472, 1600, + 1024, 1024, 1024, 1024, 1216, 1344, 1472, 1600, 1088, + 1088, 1088, 1088, 1280, 1408, 1536, 1664, 1088, 1088, + 1088, 1088, 1280, 1408, 1536, 1664, 1152, 1152, 1152, + 1152, 1344, 1472, 1600, 1728, 1152, 1152, 1152, 1152, + 1344, 1472, 1600, 1728, 1216, 1216, 1216, 1216, 1408, + 1536, 1664, 1792, 1216, 1216, 1216, 1216, 1408, 1536, + 1664, 1792, 1280, 1280, 1280, 1280, 1472, 1600, 1728, + 1856, 1280, 1280, 1280, 1280, 1472, 1600, 1728, 1856, + 1344, 1344, 1344, 1344, 1536, 1664, 1792, 1920, 1344, + 1344, 1344, 1344, 1536, 1664, 1792, 1920, 1408, 1408, + 1408, 1408, 1600, 1728, 1856, 1984, 1408, 1408, 1408, + 1408, 1600, 1728, 1856, 1984, 1472, 1472, 1472, 1472, + 1664, 1792, 1920, 2048, 1472, 1472, 1472, 1472, 1664, + 1792, 1920, 2048, 1536, 1536, 1536, 1536, 1728, 1856, + 1984, 2112, 1536, 1536, 1536, 1536, 1728, 1856, 1984, + 2112, 1600, 1600, 1600, 1600, 1792, 1920, 2048, 2176, + 1600, 1600, 1600, 1600, 1792, 1920, 2048, 2176, 1664, + 1664, 1664, 1664, 1856, 1984, 2112, 2240, 1664, 1664, + 1664, 1664, 1856, 1984, 2112, 2240, 1728, 1728, 1728, + 1728, 1920, 2048, 2176, 2304, 1728, 1728, 1728, 1728, + 1920, 2048, 2176, 2304, 1792, 1792, 1792, 1792, 1984, + 2112, 2240, 2368, 1792, 1792, 1792, 1792, 1984, 2112, + 2240, 2368, 1856, 1856, 1856, 1856, 2048, 2176, 2304, + 2432, 1856, 1856, 1856, 1856, 2048, 2176, 2304, 2432, + 1920, 1920, 1920, 1920, 2112, 2240, 2368, 2496, 1920, + 1920, 1920, 1920, 2112, 2240, 2368, 2496, 1984, 1984, + 1984, 1984, 2176, 2304, 2432, 2560, 1984, 1984, 1984, + 1984, 2176, 2304, 2432, 2560, 2048, 2048, 2048, 2048, + 2240, 2368, 2496, 2624, 2048, 2048, 2048, 2048, 2240, + 2368, 2496, 2624, 2112, 2112, 2112, 2112, 2304, 2432, + 2560, 2688, 2112, 2112, 2112, 2112, 2304, 2432, 2560, + 2688, 2176, 2176, 2176, 2176, 2368, 2496, 2624, 2752, + 2176, 2176, 2176, 2176, 2368, 2496, 2624, 2752, 2240, + 2240, 2240, 2240, 2432, 2560, 2688, 2816, 2240, 2240, + 2240, 2240, 2432, 2560, 2688, 2816, 2304, 2304, 2304, + 2304, 2496, 2624, 2752, 2880, 2304, 2304, 2304, 2304, + 2496, 2624, 2752, 2880, 2368, 2368, 2368, 2368, 2560, + 2688, 2816, 2944, 2368, 2368, 2368, 2368, 2560, 2688, + 2816, 2944, 2432, 2432, 2432, 2432, 2624, 2752, 2880, + 3008, 2432, 2432, 2432, 2432, 2624, 2752, 2880, 3008, + 2496, 2496, 2496, 2496, 2688, 2816, 2944, 3072, 2496, + 2496, 2496, 2496, 2688, 2816, 2944, 3072, 2560, 2560, + 2560, 2560, 2752, 2880, 3008, 3136, 2560, 2560, 2560, + 2560, 2752, 2880, 3008, 3136, 2624, 2624, 2624, 2624, + 2816, 2944, 3072, 3200, 2624, 2624, 2624, 2624, 2816, + 2944, 3072, 3200, 2688, 2688, 2688, 2688, 2880, 3008, + 3136, 3264, 2688, 2688, 2688, 2688, 2880, 3008, 3136, + 3264, 2752, 2752, 2752, 2752, 2944, 3072, 3200, 3328, + 2752, 2752, 2752, 2752, 2944, 3072, 3200, 3328, 2816, + 2816, 2816, 2816, 3008, 3136, 3264, 3392, 2816, 2816, + 2816, 2816, 3008, 3136, 3264, 3392, 2880, 2880, 2880, + 2880, 3072, 3200, 3328, 3456, 2880, 2880, 2880, 2880, + 3072, 3200, 3328, 3456, 2944, 2944, 2944, 2944, 3136, + 3264, 3392, 3520, 2944, 2944, 2944, 2944, 3136, 3264, + 3392, 3520, 3008, 3008, 3008, 3008, 3200, 3328, 3456, + 3584, 3008, 3008, 3008, 3008, 3200, 3328, 3456, 3584, + 3072, 3072, 3072, 3072, 3264, 3392, 3520, 3648, 3072, + 3072, 3072, 3072, 3264, 3392, 3520, 3648, 3136, 3136, + 3136, 3136, 3328, 3456, 3584, 3712, 3136, 3136, 3136, + 3136, 3328, 3456, 3584, 3712, 3200, 3200, 3200, 3200, + 3392, 3520, 3648, 3776, 3200, 3200, 3200, 3200, 3392, + 3520, 3648, 3776, 3264, 3264, 3264, 3264, 3456, 3584, + 3712, 3840, 3264, 3264, 3264, 3264, 3456, 3584, 3712, + 3840, 3328, 3328, 3328, 3328, 3520, 3648, 3776, 3904, + 3328, 3328, 3328, 3328, 3520, 3648, 3776, 3904, 3392, + 3392, 3392, 3392, 3584, 3712, 3840, 3968, 3392, 3392, + 3392, 3392, 3584, 3712, 3840, 3968, 3456, 3456, 3456, + 3456, 3648, 3776, 3904, 4032, 3456, 3456, 3456, 3456, + 3648, 3776, 3904, 4032, 3520, 3520, 3520, 3520, 3712, + 3840, 3968, 4096, 3520, 3520, 3520, 3520, 3712, 3840, + 3968, 4096, 3584, 3584, 3584, 3584, 3776, 3904, 4032, + 4160, 3584, 3584, 3584, 3584, 3776, 3904, 4032, 4160, + 3648, 3648, 3648, 3648, 3840, 3968, 4096, 4224, 3648, + 3648, 3648, 3648, 3840, 3968, 4096, 4224, 3712, 3712, + 3712, 3712, 3904, 4032, 4160, 4288, 3712, 3712, 3712, + 3712, 3904, 4032, 4160, 4288, 3776, 3776, 3776, 3776, + 3968, 4096, 4224, 4352, 3776, 3776, 3776, 3776, 3968, + 4096, 4224, 4352, 3840, 3840, 3840, 3840, 4032, 4160, + 4288, 4416, 3840, 3840, 3840, 3840, 4032, 4160, 4288, + 4416, 3904, 3904, 3904, 3904, 4096, 4224, 4352, 4480, + 3904, 3904, 3904, 3904, 4096, 4224, 4352, 4480, 3968, + 3968, 3968, 3968, 4160, 4288, 4416, 4544, 3968, 3968, + 3968, 3968, 4160, 4288, 4416, 4544, 4032, 4032, 4032, + 4032, 4224, 4352, 4480, 4608, 4032, 4032, 4032, 4032, + 4224, 4352, 4480, 4608, 4096, 4096, 4096, 4096, 4288, + 4416, 4544, 4672, 4096, 4096, 4096, 4096, 4288, 4416, + 4544, 4672, 4160, 4160, 4160, 4160, 4352, 4480, 4608, + 4736, 4160, 4160, 4160, 4160, 4352, 4480, 4608, 4736, + 4224, 4224, 4224, 4224, 4416, 4544, 4672, 4800, 4224, + 4224, 4224, 4224, 4416, 4544, 4672, 4800, 4288, 4288, + 4288, 4288, 4480, 4608, 4736, 4864, 4288, 4288, 4288, + 4288, 4480, 4608, 4736, 4864, 4352, 4352, 4352, 4352, + 4544, 4672, 4800, 4928, 4352, 4352, 4352, 4352, 4544, + 4672, 4800, 4928, 4416, 4416, 4416, 4416, 4608, 4736, + 4864, 4992, 4416, 4416, 4416, 4416, 4608, 4736, 4864, + 4992, 4480, 4480, 4480, 4480, 4672, 4800, 4928, 5056, + 4480, 4480, 4480, 4480, 4672, 4800, 4928, 5056, 4544, + 4544, 4544, 4544, 4736, 4864, 4992, 5120, 4544, 4544, + 4544, 4544, 4736, 4864, 4992, 5120, 4608, 4608, 4608, + 4608, 4800, 4928, 5056, 5184, 4608, 4608, 4608, 4608, + 4800, 4928, 5056, 5184, 4672, 4672, 4672, 4672, 4864, + 4992, 5120, 5248, 4672, 4672, 4672, 4672, 4864, 4992, + 5120, 5248, 4736, 4736, 4736, 4736, 4928, 5056, 5184, + 5312, 4736, 4736, 4736, 4736, 4928, 5056, 5184, 5312, + 4800, 4800, 4800, 4800, 4992, 5120, 5248, 5376, 4800, + 4800, 4800, 4800, 4992, 5120, 5248, 5376, 4864, 4864, + 4864, 4864, 5056, 5184, 5312, 5440, 4864, 4864, 4864, + 4864, 5056, 5184, 5312, 5440, 4928, 4928, 4928, 4928, + 5120, 5248, 5376, 5504, 4928, 4928, 4928, 4928, 5120, + 5248, 5376, 5504, 4992, 4992, 4992, 4992, 5184, 5312, + 5440, 5568, 4992, 4992, 4992, 4992, 5184, 5312, 5440, + 5568, 5056, 5056, 5056, 5056, 5248, 5376, 5504, 5632, + 5056, 5056, 5056, 5056, 5248, 5376, 5504, 5632, 5120, + 5120, 5120, 5120, 5312, 5440, 5568, 5632, 5120, 5120, + 5120, 5120, 5312, 5440, 5568, 5632, 5184, 5184, 5184, + 5184, 5376, 5504, 5632, 5632, 5184, 5184, 5184, 5184, + 5376, 5504, 5632, 5632, 5248, 5248, 5248, 5248, 5440, + 5568, 5632, 5632, 5248, 5248, 5248, 5248, 5440, 5568, + 5632, 5632, 5312, 5312, 5312, 5312, 5504, 5632, 5632, + 5632, 5312, 5312, 5312, 5312, 5504, 5632, 5632, 5632, + 5376, 5376, 5376, 5376, 5568, 5632, 5632, 5632, 5376, + 5376, 5376, 5376, 5568, 5632, 5632, 5632, 5440, 5440, + 5440, 5440, 5632, 5632, 5632, 5632, 5440, 5440, 5440, + 5440, 5632, 5632, 5632, 5632, 5504, 5504, 5504, 5504, + 5632, 5632, 5632, 5632, 5504, 5504, 5504, 5504, 5632, + 5632, 5632, 5632, 5568, 5568, 5568, 5568, 5632, 5632, + 5632, 5632, 5568, 5568, 5568, 5568, 5632, 5632, 5632, + 5632 +}; + +static const int imaTable[1424] = { + 0, 2, 4, 6, 7, 9, 11, 13, 0, -2, -4, -6, -7, -9, -11, + -13, 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, + -11, -13, -15, 1, 3, 5, 7, 10, 12, 14, 16, -1, -3, -5, + -7, -10, -12, -14, -16, 1, 3, 6, 8, 11, 13, 16, 18, + -1, -3, -6, -8, -11, -13, -16, -18, 1, 4, 6, 9, 12, + 15, 17, 20, -1, -4, -6, -9, -12, -15, -17, -20, 1, 4, + 7, 10, 13, 16, 19, 22, -1, -4, -7, -10, -13, -16, -19, + -22, 1, 4, 8, 11, 14, 17, 21, 24, -1, -4, -8, -11, -14, + -17, -21, -24, 1, 5, 8, 12, 15, 19, 22, 26, -1, -5, + -8, -12, -15, -19, -22, -26, 2, 6, 10, 14, 18, 22, 26, + 30, -2, -6, -10, -14, -18, -22, -26, -30, 2, 6, 10, + 14, 19, 23, 27, 31, -2, -6, -10, -14, -19, -23, -27, + -31, 2, 7, 11, 16, 21, 26, 30, 35, -2, -7, -11, -16, + -21, -26, -30, -35, 2, 7, 13, 18, 23, 28, 34, 39, -2, + -7, -13, -18, -23, -28, -34, -39, 2, 8, 14, 20, 25, + 31, 37, 43, -2, -8, -14, -20, -25, -31, -37, -43, 3, + 9, 15, 21, 28, 34, 40, 46, -3, -9, -15, -21, -28, -34, + -40, -46, 3, 10, 17, 24, 31, 38, 45, 52, -3, -10, -17, + -24, -31, -38, -45, -52, 3, 11, 19, 27, 34, 42, 50, + 58, -3, -11, -19, -27, -34, -42, -50, -58, 4, 12, 21, + 29, 38, 46, 55, 63, -4, -12, -21, -29, -38, -46, -55, + -63, 4, 13, 23, 32, 41, 50, 60, 69, -4, -13, -23, -32, + -41, -50, -60, -69, 5, 15, 25, 35, 46, 56, 66, 76, -5, + -15, -25, -35, -46, -56, -66, -76, 5, 16, 28, 39, 50, + 61, 73, 84, -5, -16, -28, -39, -50, -61, -73, -84, 6, + 18, 31, 43, 56, 68, 81, 93, -6, -18, -31, -43, -56, + -68, -81, -93, 6, 20, 34, 48, 61, 75, 89, 103, -6, -20, + -34, -48, -61, -75, -89, -103, 7, 22, 37, 52, 67, 82, + 97, 112, -7, -22, -37, -52, -67, -82, -97, -112, 8, + 24, 41, 57, 74, 90, 107, 123, -8, -24, -41, -57, -74, + -90, -107, -123, 9, 27, 45, 63, 82, 100, 118, 136, -9, + -27, -45, -63, -82, -100, -118, -136, 10, 30, 50, 70, + 90, 110, 130, 150, -10, -30, -50, -70, -90, -110, -130, + -150, 11, 33, 55, 77, 99, 121, 143, 165, -11, -33, -55, + -77, -99, -121, -143, -165, 12, 36, 60, 84, 109, 133, + 157, 181, -12, -36, -60, -84, -109, -133, -157, -181, + 13, 40, 66, 93, 120, 147, 173, 200, -13, -40, -66, -93, + -120, -147, -173, -200, 14, 44, 73, 103, 132, 162, 191, + 221, -14, -44, -73, -103, -132, -162, -191, -221, 16, + 48, 81, 113, 146, 178, 211, 243, -16, -48, -81, -113, + -146, -178, -211, -243, 17, 53, 89, 125, 160, 196, 232, + 268, -17, -53, -89, -125, -160, -196, -232, -268, 19, + 58, 98, 137, 176, 215, 255, 294, -19, -58, -98, -137, + -176, -215, -255, -294, 21, 64, 108, 151, 194, 237, + 281, 324, -21, -64, -108, -151, -194, -237, -281, -324, + 23, 71, 118, 166, 213, 261, 308, 356, -23, -71, -118, + -166, -213, -261, -308, -356, 26, 78, 130, 182, 235, + 287, 339, 391, -26, -78, -130, -182, -235, -287, -339, + -391, 28, 86, 143, 201, 258, 316, 373, 431, -28, -86, + -143, -201, -258, -316, -373, -431, 31, 94, 158, 221, + 284, 347, 411, 474, -31, -94, -158, -221, -284, -347, + -411, -474, 34, 104, 174, 244, 313, 383, 453, 523, -34, + -104, -174, -244, -313, -383, -453, -523, 38, 115, 191, + 268, 345, 422, 498, 575, -38, -115, -191, -268, -345, + -422, -498, -575, 42, 126, 210, 294, 379, 463, 547, + 631, -42, -126, -210, -294, -379, -463, -547, -631, + 46, 139, 231, 324, 417, 510, 602, 695, -46, -139, -231, + -324, -417, -510, -602, -695, 51, 153, 255, 357, 459, + 561, 663, 765, -51, -153, -255, -357, -459, -561, -663, + -765, 56, 168, 280, 392, 505, 617, 729, 841, -56, -168, + -280, -392, -505, -617, -729, -841, 61, 185, 308, 432, + 555, 679, 802, 926, -61, -185, -308, -432, -555, -679, + -802, -926, 68, 204, 340, 476, 612, 748, 884, 1020, + -68, -204, -340, -476, -612, -748, -884, -1020, 74, + 224, 373, 523, 672, 822, 971, 1121, -74, -224, -373, + -523, -672, -822, -971, -1121, 82, 246, 411, 575, 740, + 904, 1069, 1233, -82, -246, -411, -575, -740, -904, + -1069, -1233, 90, 271, 452, 633, 814, 995, 1176, 1357, + -90, -271, -452, -633, -814, -995, -1176, -1357, 99, + 298, 497, 696, 895, 1094, 1293, 1492, -99, -298, -497, + -696, -895, -1094, -1293, -1492, 109, 328, 547, 766, + 985, 1204, 1423, 1642, -109, -328, -547, -766, -985, + -1204, -1423, -1642, 120, 361, 601, 842, 1083, 1324, + 1564, 1805, -120, -361, -601, -842, -1083, -1324, -1564, + -1805, 132, 397, 662, 927, 1192, 1457, 1722, 1987, -132, + -397, -662, -927, -1192, -1457, -1722, -1987, 145, 437, + 728, 1020, 1311, 1603, 1894, 2186, -145, -437, -728, + -1020, -1311, -1603, -1894, -2186, 160, 480, 801, 1121, + 1442, 1762, 2083, 2403, -160, -480, -801, -1121, -1442, + -1762, -2083, -2403, 176, 529, 881, 1234, 1587, 1940, + 2292, 2645, -176, -529, -881, -1234, -1587, -1940, -2292, + -2645, 194, 582, 970, 1358, 1746, 2134, 2522, 2910, + -194, -582, -970, -1358, -1746, -2134, -2522, -2910, + 213, 640, 1066, 1493, 1920, 2347, 2773, 3200, -213, + -640, -1066, -1493, -1920, -2347, -2773, -3200, 234, + 704, 1173, 1643, 2112, 2582, 3051, 3521, -234, -704, + -1173, -1643, -2112, -2582, -3051, -3521, 258, 774, + 1291, 1807, 2324, 2840, 3357, 3873, -258, -774, -1291, + -1807, -2324, -2840, -3357, -3873, 284, 852, 1420, 1988, + 2556, 3124, 3692, 4260, -284, -852, -1420, -1988, -2556, + -3124, -3692, -4260, 312, 937, 1561, 2186, 2811, 3436, + 4060, 4685, -312, -937, -1561, -2186, -2811, -3436, + -4060, -4685, 343, 1030, 1718, 2405, 3092, 3779, 4467, + 5154, -343, -1030, -1718, -2405, -3092, -3779, -4467, + -5154, 378, 1134, 1890, 2646, 3402, 4158, 4914, 5670, + -378, -1134, -1890, -2646, -3402, -4158, -4914, -5670, + 415, 1247, 2079, 2911, 3742, 4574, 5406, 6238, -415, + -1247, -2079, -2911, -3742, -4574, -5406, -6238, 457, + 1372, 2287, 3202, 4117, 5032, 5947, 6862, -457, -1372, + -2287, -3202, -4117, -5032, -5947, -6862, 503, 1509, + 2516, 3522, 4529, 5535, 6542, 7548, -503, -1509, -2516, + -3522, -4529, -5535, -6542, -7548, 553, 1660, 2767, + 3874, 4981, 6088, 7195, 8302, -553, -1660, -2767, -3874, + -4981, -6088, -7195, -8302, 608, 1826, 3044, 4262, 5479, + 6697, 7915, 9133, -608, -1826, -3044, -4262, -5479, + -6697, -7915, -9133, 669, 2009, 3348, 4688, 6027, 7367, + 8706, 10046, -669, -2009, -3348, -4688, -6027, -7367, + -8706, -10046, 736, 2210, 3683, 5157, 6630, 8104, 9577, + 11051, -736, -2210, -3683, -5157, -6630, -8104, -9577, + -11051, 810, 2431, 4052, 5673, 7294, 8915, 10536, 12157, + -810, -2431, -4052, -5673, -7294, -8915, -10536, -12157, + 891, 2674, 4457, 6240, 8023, 9806, 11589, 13372, -891, + -2674, -4457, -6240, -8023, -9806, -11589, -13372, 980, + 2941, 4903, 6864, 8825, 10786, 12748, 14709, -980, -2941, + -4903, -6864, -8825, -10786, -12748, -14709, 1078, 3236, + 5393, 7551, 9708, 11866, 14023, 16181, -1078, -3236, + -5393, -7551, -9708, -11866, -14023, -16181, 1186, 3559, + 5933, 8306, 10679, 13052, 15426, 17799, -1186, -3559, + -5933, -8306, -10679, -13052, -15426, -17799, 1305, + 3915, 6526, 9136, 11747, 14357, 16968, 19578, -1305, + -3915, -6526, -9136, -11747, -14357, -16968, -19578, + 1435, 4307, 7179, 10051, 12922, 15794, 18666, 21538, + -1435, -4307, -7179, -10051, -12922, -15794, -18666, + -21538, 1579, 4738, 7896, 11055, 14214, 17373, 20531, + 23690, -1579, -4738, -7896, -11055, -14214, -17373, + -20531, -23690, 1737, 5212, 8686, 12161, 15636, 19111, + 22585, 26060, -1737, -5212, -8686, -12161, -15636, -19111, + -22585, -26060, 1911, 5733, 9555, 13377, 17200, 21022, + 24844, 28666, -1911, -5733, -9555, -13377, -17200, -21022, + -24844, -28666, 2102, 6306, 10511, 14715, 18920, 23124, + 27329, 31533, -2102, -6306, -10511, -14715, -18920, + -23124, -27329, -31533, 2312, 6937, 11562, 16187, 20812, + 25437, 30062, 32767, -2312, -6937, -11562, -16187, -20812, + -25437, -30062, -32767, 2543, 7631, 12718, 17806, 22893, + 27981, 32767, 32767, -2543, -7631, -12718, -17806, -22893, + -27981, -32767, -32767, 2798, 8394, 13990, 19586, 25183, + 30779, 32767, 32767, -2798, -8394, -13990, -19586, -25183, + -30779, -32767, -32767, 3077, 9233, 15389, 21545, 27700, + 32767, 32767, 32767, -3077, -9233, -15389, -21545, -27700, + -32767, -32767, -32767, 3385, 10157, 16928, 23700, 30471, + 32767, 32767, 32767, -3385, -10157, -16928, -23700, + -30471, -32767, -32767, -32767, 3724, 11172, 18621, + 26069, 32767, 32767, 32767, 32767, -3724, -11172, -18621, + -26069, -32767, -32767, -32767, -32767, 4095, 12287, + 20479, 28671, 32767, 32767, 32767, 32767, -4095, -12287, + -20479, -28671, -32767, -32767, -32767, -32767 +}; + +static const int p1s[17] = { 0, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4, 0 }; +static const int p2s[17] = { 0, 1, 1, 3, 1, 5, 3, 7, 1, 9, 5, 11, 3, 13, 7, 15, 1 }; + +#pragma endregion + // Last Express ADPCM is similar to MS IMA mono, but inverts its nibbles // and does not have the 4 byte per channel requirement -class LastExpress_ADPCMStream : public Audio::Ima_ADPCMStream { +class LastExpress_ADPCMStream : public Audio::ADPCMStream { public: - LastExpress_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, uint32 blockSize) : - Audio::Ima_ADPCMStream(stream, disposeAfterUse, size, 44100, 1, blockSize) {} + LastExpress_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, uint32 blockSize, int32 filterId) : + Audio::ADPCMStream(stream, disposeAfterUse, size, 44100, 1, blockSize) { + _currentFilterId = -1; + _nextFilterId = filterId; + } int readBuffer(int16 *buffer, const int numSamples) { int samples = 0; + // Temporary data + int step = 0; + int sample = 0; + byte idx = 0; assert(numSamples % 2 == 0); @@ -53,20 +373,50 @@ public: if (_blockPos[0] == _blockAlign) { // read block header _status.ima_ch[0].last = _stream->readSint16LE(); - _status.ima_ch[0].stepIndex = _stream->readSint16LE(); + _status.ima_ch[0].stepIndex = _stream->readSint16LE() << 6; _blockPos[0] = 4; + + // Get current filter + _currentFilterId = _nextFilterId; + _nextFilterId = -1; + + // No filter: skip decoding + if (_currentFilterId == -1) + break; + + // Compute step adjustment + _stepAdjust1 = p1s[_currentFilterId]; + _stepAdjust2 = p2s[_currentFilterId]; } for (; samples < numSamples && _blockPos[0] < _blockAlign && !_stream->eos() && _stream->pos() < _endpos; samples += 2) { byte data = _stream->readByte(); _blockPos[0]++; - buffer[samples] = decodeIMA((data >> 4) & 0x0f); - buffer[samples + 1] = decodeIMA(data & 0x0f); + + // First nibble + idx = data >> 4; + step = stepTable[idx + _status.ima_ch[0].stepIndex / 4]; + sample = CLIP(imaTable[idx + _status.ima_ch[0].stepIndex / 4] + _status.ima_ch[0].last, -32767, 32767); + buffer[samples] = (_stepAdjust2 * sample) >> _stepAdjust1; + + // Second nibble + idx = data & 0xF; + _status.ima_ch[0].stepIndex = stepTable[idx + step / 4]; + _status.ima_ch[0].last = CLIP(imaTable[idx + step / 4] + sample, -32767, 32767); + buffer[samples + 1] = (_stepAdjust2 * _status.ima_ch[0].last) >> _stepAdjust1; } } return samples; } + + void setFilterId(int32 filterId) { _nextFilterId = filterId; } + +private: + int32 _currentFilterId; + int32 _nextFilterId; // the sound filter id, -1 for none + int32 _stepAdjust1; + int32 _stepAdjust2; }; ////////////////////////////////////////////////////////////////////////// @@ -92,8 +442,8 @@ void SimpleSound::loadHeader(Common::SeekableReadStream *in) { _blockSize = _size / _blocks; } -Audio::AudioStream *SimpleSound::makeDecoder(Common::SeekableReadStream *in, uint32 size) const { - return new LastExpress_ADPCMStream(in, DisposeAfterUse::YES, size, _blockSize); +Audio::AudioStream *SimpleSound::makeDecoder(Common::SeekableReadStream *in, uint32 size, int32 filterId) const { + return new LastExpress_ADPCMStream(in, DisposeAfterUse::YES, size, _blockSize, filterId); } void SimpleSound::play(Audio::AudioStream *as) { @@ -103,11 +453,11 @@ void SimpleSound::play(Audio::AudioStream *as) { ////////////////////////////////////////////////////////////////////////// // StreamedSound ////////////////////////////////////////////////////////////////////////// -StreamedSound::StreamedSound() : _loaded(false) {} +StreamedSound::StreamedSound() : _as(NULL), _loaded(false) {} StreamedSound::~StreamedSound() {} -bool StreamedSound::load(Common::SeekableReadStream *stream) { +bool StreamedSound::load(Common::SeekableReadStream *stream, int32 filterId) { if (!stream) return false; @@ -116,10 +466,10 @@ bool StreamedSound::load(Common::SeekableReadStream *stream) { loadHeader(stream); // Start decoding the input stream - Audio::AudioStream *as = makeDecoder(stream, _size); + _as = makeDecoder(stream, _size, filterId); // Start playing the decoded audio stream - play(as); + play(_as); _loaded = true; @@ -133,6 +483,10 @@ bool StreamedSound::isFinished() { return !g_system->getMixer()->isSoundHandleActive(_handle); } +void StreamedSound::setFilterId(int32 filterId) { + ((LastExpress_ADPCMStream *)_as)->setFilterId(filterId); +} + ////////////////////////////////////////////////////////////////////////// // StreamedSound ////////////////////////////////////////////////////////////////////////// diff --git a/engines/lastexpress/data/snd.h b/engines/lastexpress/data/snd.h index 1c34e4f950..7111d939e7 100644 --- a/engines/lastexpress/data/snd.h +++ b/engines/lastexpress/data/snd.h @@ -59,7 +59,7 @@ public: protected: void loadHeader(Common::SeekableReadStream *in); - Audio::AudioStream *makeDecoder(Common::SeekableReadStream *in, uint32 size) const; + Audio::AudioStream *makeDecoder(Common::SeekableReadStream *in, uint32 size, int32 filterId = -1) const; void play(Audio::AudioStream *as); uint32 _size; ///< data size @@ -76,11 +76,13 @@ public: StreamedSound(); ~StreamedSound(); - bool load(Common::SeekableReadStream *stream); - + bool load(Common::SeekableReadStream *stream, int32 filterId = -1); virtual bool isFinished(); + void setFilterId(int32 filterId); + private: + Audio::AudioStream *_as; bool _loaded; }; diff --git a/engines/lastexpress/game/savegame.cpp b/engines/lastexpress/game/savegame.cpp index ebada5dd4e..57c18b5697 100644 --- a/engines/lastexpress/game/savegame.cpp +++ b/engines/lastexpress/game/savegame.cpp @@ -45,12 +45,12 @@ namespace LastExpress { static const struct { const char *saveFile; } gameInfo[6] = { - {"blue.egg"}, - {"red.egg"}, - {"green.egg"}, - {"purple.egg"}, - {"teal.egg"}, - {"gold.egg"} + {"lastexpress-blue.egg"}, + {"lastexpress-red.egg"}, + {"lastexpress-green.egg"}, + {"lastexpress-purple.egg"}, + {"lastexpress-teal.egg"}, + {"lastexpress-gold.egg"} }; ////////////////////////////////////////////////////////////////////////// diff --git a/engines/lastexpress/resource.h b/engines/lastexpress/resource.h index 7dc909ab34..9e05a90399 100644 --- a/engines/lastexpress/resource.h +++ b/engines/lastexpress/resource.h @@ -26,6 +26,8 @@ #include "lastexpress/data/archive.h" #include "lastexpress/shared.h" +#include "common/array.h" + namespace LastExpress { class Background; diff --git a/engines/lastexpress/shared.h b/engines/lastexpress/shared.h index b4ced96ee1..d60a498447 100644 --- a/engines/lastexpress/shared.h +++ b/engines/lastexpress/shared.h @@ -84,29 +84,26 @@ enum SoundFlag { }; enum SoundState { - kSoundState0 = 0, - kSoundState1 = 1, - kSoundState2 = 2 + kSoundStateNone = 0, + kSoundState1 = 1, + kSoundState2 = 2 }; enum SoundStatus { + kSoundStatusClear0 = 0x10, + kSoundStatusFilter = 0x1F, kSoundStatus_20 = 0x20, kSoundStatus_40 = 0x40, + kSoundStatusCached = 0x80, kSoundStatus_180 = 0x180, - kSoundStatusRemoved = 0x200, + kSoundStatusClosed = 0x200, kSoundStatus_400 = 0x400, - + kSoundStatusClear4 = 0x800, kSoundStatus_8000 = 0x8000, kSoundStatus_20000 = 0x20000, kSoundStatus_100000 = 0x100000, kSoundStatus_20000000 = 0x20000000, kSoundStatus_40000000 = 0x40000000, - - kSoundStatusClear0 = 0x10, - kSoundStatusFilterVariant = 0x1F, - kSoundStatusClear2 = 0x80, - kSoundStatusClear3 = 0x200, - kSoundStatusClear4 = 0x800, kSoundStatusClearAll = 0xFFFFFFE0 }; diff --git a/engines/lastexpress/sound/entry.cpp b/engines/lastexpress/sound/entry.cpp index 2840d85ca7..44cc68a57b 100644 --- a/engines/lastexpress/sound/entry.cpp +++ b/engines/lastexpress/sound/entry.cpp @@ -47,9 +47,6 @@ namespace LastExpress { SoundEntry::SoundEntry(LastExpressEngine *engine) : _engine(engine) { _type = kSoundTypeNone; - _currentDataPtr = NULL; - _soundBuffer = NULL; - _blockCount = 0; _time = 0; @@ -76,8 +73,6 @@ SoundEntry::~SoundEntry() { SAFE_DELETE(_stream); delete _soundStream; - free(_soundBuffer); - // Zero passed pointers _engine = NULL; } @@ -86,18 +81,15 @@ void SoundEntry::open(Common::String name, SoundFlag flag, int priority) { _priority = priority; setType(flag); setupStatus(flag); - - // Add entry to cache and load sound data - setupCache(); - loadSoundData(name); + loadStream(name); } void SoundEntry::close() { - _status.status |= kSoundStatusRemoved; + _status.status |= kSoundStatusClosed; // Loop until ready - while (!(_status.status1 & 4) && !(getSoundQueue()->getFlag() & 8) && (getSoundQueue()->getFlag() & 1)) - ; // empty loop body + //while (!(_status.status1 & 4) && !(getSoundQueue()->getFlag() & 8) && (getSoundQueue()->getFlag() & 1)) + // ; // empty loop body // The original game remove the entry from the cache here, // but since we are called from within an iterator loop @@ -123,34 +115,24 @@ void SoundEntry::play() { return; } - if (_queued) - return; - - // Apply filter - int16 *buffer = (int16 *)malloc(FILTER_BUFFER_SIZE); - memset(buffer, 0, FILTER_BUFFER_SIZE); - - applyFilter(buffer); - - // Queue the filtered data -#if 0 + // Prepare sound stream if (!_soundStream) - _soundStream = new AppendableSound(); + _soundStream = new StreamedSound(); - // FIXME: make sure the filtered sound buffer is disposed - _soundStream->queueBuffer((const byte *)buffer, FILTER_BUFFER_SIZE /* true */); -#else - free(buffer); + // Compute current filter id + int32 filterId = _status.status & kSoundStatusFilter; + // TODO adjust status (based on stepIndex) - // DEBUG: unfiltered stream - if (!_soundStream) - _soundStream = new StreamedSound(); + if (_queued) { + _soundStream->setFilterId(filterId); + } else { + _stream->seek(0); - _stream->seek(0); - _soundStream->load(_stream); -#endif + // Load the stream and start playing + _soundStream->load(_stream, filterId); - _queued = true; + _queued = true; + } } bool SoundEntry::isFinished() { @@ -238,8 +220,8 @@ void SoundEntry::setType(SoundFlag flag) { void SoundEntry::setupStatus(SoundFlag flag) { SoundStatus statusFlag = (SoundStatus)flag; - if (!((statusFlag & 0xFF) & kSoundStatusFilterVariant)) - statusFlag = (SoundStatus)(statusFlag | kSoundStatusClear2); + if (!((statusFlag & 0xFF) & kSoundStatusFilter)) + statusFlag = (SoundStatus)(statusFlag | kSoundStatusCached); if (((statusFlag & 0xFF00) >> 8) & kSoundStatusClear0) _status.status = (uint32)statusFlag; @@ -247,23 +229,7 @@ void SoundEntry::setupStatus(SoundFlag flag) { _status.status = (statusFlag | kSoundStatusClear4); } -void SoundEntry::setupCache() { - if (_soundBuffer) - return; - - // Original has a priority-based shared buffer (of 6 entries) - // We simply allocate a new buffer for each sound entry that needs it - _soundBuffer = (byte *)malloc(SOUNDCACHE_ENTRY_SIZE); - memset(_soundBuffer, 0, SOUNDCACHE_ENTRY_SIZE); - - setInCache(); -} - -void SoundEntry::setInCache() { - _status.status |= kSoundStatusClear2; -} - -void SoundEntry::loadSoundData(Common::String name) { +void SoundEntry::loadStream(Common::String name) { _name2 = name; // Load sound data @@ -272,12 +238,8 @@ void SoundEntry::loadSoundData(Common::String name) { if (!_stream) _stream = getArchive("DEFAULT.SND"); - if (_stream) { - _stream->read(_soundBuffer, MIN(SOUNDCACHE_ENTRY_SIZE, _stream->size())); - _currentDataPtr = _soundBuffer + 6; - } else { - _status.status = kSoundStatusRemoved; - } + if (!_stream) + _status.status = kSoundStatusClosed; } void SoundEntry::update(uint val) { @@ -300,10 +262,60 @@ void SoundEntry::update(uint val) { } } +bool SoundEntry::updateSound() { + bool result; + char sub[16]; + + if (_status.status2 & 4) { + result = false; + } else { + if (_status.status2 & 0x80) { + if (_field_48 <= getSound()->getData2()) { + _status.status |= 0x20; + _status.status &= ~0x8000; + strcpy(sub, _name2.c_str()); + + int l = strlen(sub) + 1; + if (l - 1 > 4) + sub[l - 1 - 4] = 0; + showSubtitle(sub); + } + } else { + if (!(getSoundQueue()->getFlag() & 0x20)) { + if (!(_status.status3 & 8)) { + if (_entity) { + if (_entity < 0x80) { + updateEntryFlag(getSound()->getSoundFlag(_entity)); + } + } + } + } + //if (status.status2 & 0x40 && !((uint32)_status.status & 0x180) && v1->soundBuffer) + // Sound_FillSoundBuffer(v1); + } + result = true; + } + + return result; +} + +void SoundEntry::updateEntryFlag(SoundFlag flag) { + if (flag) { + if (getSoundQueue()->getFlag() & 0x20 && _type != kSoundType9 && _type != kSoundType7) + update(flag); + else + _status.status = flag + (_status.status & ~0x1F); + } else { + _variant = 0; + _status.status |= 0x80u; + _status.status &= ~0x10001F; + } +} + void SoundEntry::updateState() { if (getSoundQueue()->getFlag() & 32) { if (_type != kSoundType9 && _type != kSoundType7 && _type != kSoundType5) { - uint32 variant = _status.status & kSoundStatusFilterVariant; + uint32 variant = _status.status & kSoundStatusFilter; _status.status &= kSoundStatusClearAll; @@ -316,7 +328,7 @@ void SoundEntry::updateState() { } void SoundEntry::reset() { - _status.status |= kSoundStatusRemoved; + _status.status |= kSoundStatusClosed; _entity = kEntityPlayer; if (_stream) { @@ -372,366 +384,6 @@ void SoundEntry::saveLoadWithSerializer(Common::Serializer &s) { } ////////////////////////////////////////////////////////////////////////// -// Sound filters -////////////////////////////////////////////////////////////////////////// -static const int filterData[1424] = { - 0, 0, 0, 0, 128, 256, 384, 512, 0, 0, 0, 0, 128, 256, - 384, 512, 0, 0, 0, 0, 192, 320, 448, 576, 0, 0, 0, 0, - 192, 320, 448, 576, 64, 64, 64, 64, 256, 384, 512, 640, - 64, 64, 64, 64, 256, 384, 512, 640, 128, 128, 128, 128, - 320, 448, 576, 704, 128, 128, 128, 128, 320, 448, 576, - 704, 192, 192, 192, 192, 384, 512, 640, 768, 192, 192, - 192, 192, 384, 512, 640, 768, 256, 256, 256, 256, 448, - 576, 704, 832, 256, 256, 256, 256, 448, 576, 704, 832, - 320, 320, 320, 320, 512, 640, 768, 896, 320, 320, 320, - 320, 512, 640, 768, 896, 384, 384, 384, 384, 576, 704, - 832, 960, 384, 384, 384, 384, 576, 704, 832, 960, 448, - 448, 448, 448, 640, 768, 896, 1024, 448, 448, 448, 448, - 640, 768, 896, 1024, 512, 512, 512, 512, 704, 832, 960, - 1088, 512, 512, 512, 512, 704, 832, 960, 1088, 576, - 576, 576, 576, 768, 896, 1024, 1152, 576, 576, 576, - 576, 768, 896, 1024, 1152, 640, 640, 640, 640, 832, - 960, 1088, 1216, 640, 640, 640, 640, 832, 960, 1088, - 1216, 704, 704, 704, 704, 896, 1024, 1152, 1280, 704, - 704, 704, 704, 896, 1024, 1152, 1280, 768, 768, 768, - 768, 960, 1088, 1216, 1344, 768, 768, 768, 768, 960, - 1088, 1216, 1344, 832, 832, 832, 832, 1024, 1152, 1280, - 1408, 832, 832, 832, 832, 1024, 1152, 1280, 1408, 896, - 896, 896, 896, 1088, 1216, 1344, 1472, 896, 896, 896, - 896, 1088, 1216, 1344, 1472, 960, 960, 960, 960, 1152, - 1280, 1408, 1536, 960, 960, 960, 960, 1152, 1280, 1408, - 1536, 1024, 1024, 1024, 1024, 1216, 1344, 1472, 1600, - 1024, 1024, 1024, 1024, 1216, 1344, 1472, 1600, 1088, - 1088, 1088, 1088, 1280, 1408, 1536, 1664, 1088, 1088, - 1088, 1088, 1280, 1408, 1536, 1664, 1152, 1152, 1152, - 1152, 1344, 1472, 1600, 1728, 1152, 1152, 1152, 1152, - 1344, 1472, 1600, 1728, 1216, 1216, 1216, 1216, 1408, - 1536, 1664, 1792, 1216, 1216, 1216, 1216, 1408, 1536, - 1664, 1792, 1280, 1280, 1280, 1280, 1472, 1600, 1728, - 1856, 1280, 1280, 1280, 1280, 1472, 1600, 1728, 1856, - 1344, 1344, 1344, 1344, 1536, 1664, 1792, 1920, 1344, - 1344, 1344, 1344, 1536, 1664, 1792, 1920, 1408, 1408, - 1408, 1408, 1600, 1728, 1856, 1984, 1408, 1408, 1408, - 1408, 1600, 1728, 1856, 1984, 1472, 1472, 1472, 1472, - 1664, 1792, 1920, 2048, 1472, 1472, 1472, 1472, 1664, - 1792, 1920, 2048, 1536, 1536, 1536, 1536, 1728, 1856, - 1984, 2112, 1536, 1536, 1536, 1536, 1728, 1856, 1984, - 2112, 1600, 1600, 1600, 1600, 1792, 1920, 2048, 2176, - 1600, 1600, 1600, 1600, 1792, 1920, 2048, 2176, 1664, - 1664, 1664, 1664, 1856, 1984, 2112, 2240, 1664, 1664, - 1664, 1664, 1856, 1984, 2112, 2240, 1728, 1728, 1728, - 1728, 1920, 2048, 2176, 2304, 1728, 1728, 1728, 1728, - 1920, 2048, 2176, 2304, 1792, 1792, 1792, 1792, 1984, - 2112, 2240, 2368, 1792, 1792, 1792, 1792, 1984, 2112, - 2240, 2368, 1856, 1856, 1856, 1856, 2048, 2176, 2304, - 2432, 1856, 1856, 1856, 1856, 2048, 2176, 2304, 2432, - 1920, 1920, 1920, 1920, 2112, 2240, 2368, 2496, 1920, - 1920, 1920, 1920, 2112, 2240, 2368, 2496, 1984, 1984, - 1984, 1984, 2176, 2304, 2432, 2560, 1984, 1984, 1984, - 1984, 2176, 2304, 2432, 2560, 2048, 2048, 2048, 2048, - 2240, 2368, 2496, 2624, 2048, 2048, 2048, 2048, 2240, - 2368, 2496, 2624, 2112, 2112, 2112, 2112, 2304, 2432, - 2560, 2688, 2112, 2112, 2112, 2112, 2304, 2432, 2560, - 2688, 2176, 2176, 2176, 2176, 2368, 2496, 2624, 2752, - 2176, 2176, 2176, 2176, 2368, 2496, 2624, 2752, 2240, - 2240, 2240, 2240, 2432, 2560, 2688, 2816, 2240, 2240, - 2240, 2240, 2432, 2560, 2688, 2816, 2304, 2304, 2304, - 2304, 2496, 2624, 2752, 2880, 2304, 2304, 2304, 2304, - 2496, 2624, 2752, 2880, 2368, 2368, 2368, 2368, 2560, - 2688, 2816, 2944, 2368, 2368, 2368, 2368, 2560, 2688, - 2816, 2944, 2432, 2432, 2432, 2432, 2624, 2752, 2880, - 3008, 2432, 2432, 2432, 2432, 2624, 2752, 2880, 3008, - 2496, 2496, 2496, 2496, 2688, 2816, 2944, 3072, 2496, - 2496, 2496, 2496, 2688, 2816, 2944, 3072, 2560, 2560, - 2560, 2560, 2752, 2880, 3008, 3136, 2560, 2560, 2560, - 2560, 2752, 2880, 3008, 3136, 2624, 2624, 2624, 2624, - 2816, 2944, 3072, 3200, 2624, 2624, 2624, 2624, 2816, - 2944, 3072, 3200, 2688, 2688, 2688, 2688, 2880, 3008, - 3136, 3264, 2688, 2688, 2688, 2688, 2880, 3008, 3136, - 3264, 2752, 2752, 2752, 2752, 2944, 3072, 3200, 3328, - 2752, 2752, 2752, 2752, 2944, 3072, 3200, 3328, 2816, - 2816, 2816, 2816, 3008, 3136, 3264, 3392, 2816, 2816, - 2816, 2816, 3008, 3136, 3264, 3392, 2880, 2880, 2880, - 2880, 3072, 3200, 3328, 3456, 2880, 2880, 2880, 2880, - 3072, 3200, 3328, 3456, 2944, 2944, 2944, 2944, 3136, - 3264, 3392, 3520, 2944, 2944, 2944, 2944, 3136, 3264, - 3392, 3520, 3008, 3008, 3008, 3008, 3200, 3328, 3456, - 3584, 3008, 3008, 3008, 3008, 3200, 3328, 3456, 3584, - 3072, 3072, 3072, 3072, 3264, 3392, 3520, 3648, 3072, - 3072, 3072, 3072, 3264, 3392, 3520, 3648, 3136, 3136, - 3136, 3136, 3328, 3456, 3584, 3712, 3136, 3136, 3136, - 3136, 3328, 3456, 3584, 3712, 3200, 3200, 3200, 3200, - 3392, 3520, 3648, 3776, 3200, 3200, 3200, 3200, 3392, - 3520, 3648, 3776, 3264, 3264, 3264, 3264, 3456, 3584, - 3712, 3840, 3264, 3264, 3264, 3264, 3456, 3584, 3712, - 3840, 3328, 3328, 3328, 3328, 3520, 3648, 3776, 3904, - 3328, 3328, 3328, 3328, 3520, 3648, 3776, 3904, 3392, - 3392, 3392, 3392, 3584, 3712, 3840, 3968, 3392, 3392, - 3392, 3392, 3584, 3712, 3840, 3968, 3456, 3456, 3456, - 3456, 3648, 3776, 3904, 4032, 3456, 3456, 3456, 3456, - 3648, 3776, 3904, 4032, 3520, 3520, 3520, 3520, 3712, - 3840, 3968, 4096, 3520, 3520, 3520, 3520, 3712, 3840, - 3968, 4096, 3584, 3584, 3584, 3584, 3776, 3904, 4032, - 4160, 3584, 3584, 3584, 3584, 3776, 3904, 4032, 4160, - 3648, 3648, 3648, 3648, 3840, 3968, 4096, 4224, 3648, - 3648, 3648, 3648, 3840, 3968, 4096, 4224, 3712, 3712, - 3712, 3712, 3904, 4032, 4160, 4288, 3712, 3712, 3712, - 3712, 3904, 4032, 4160, 4288, 3776, 3776, 3776, 3776, - 3968, 4096, 4224, 4352, 3776, 3776, 3776, 3776, 3968, - 4096, 4224, 4352, 3840, 3840, 3840, 3840, 4032, 4160, - 4288, 4416, 3840, 3840, 3840, 3840, 4032, 4160, 4288, - 4416, 3904, 3904, 3904, 3904, 4096, 4224, 4352, 4480, - 3904, 3904, 3904, 3904, 4096, 4224, 4352, 4480, 3968, - 3968, 3968, 3968, 4160, 4288, 4416, 4544, 3968, 3968, - 3968, 3968, 4160, 4288, 4416, 4544, 4032, 4032, 4032, - 4032, 4224, 4352, 4480, 4608, 4032, 4032, 4032, 4032, - 4224, 4352, 4480, 4608, 4096, 4096, 4096, 4096, 4288, - 4416, 4544, 4672, 4096, 4096, 4096, 4096, 4288, 4416, - 4544, 4672, 4160, 4160, 4160, 4160, 4352, 4480, 4608, - 4736, 4160, 4160, 4160, 4160, 4352, 4480, 4608, 4736, - 4224, 4224, 4224, 4224, 4416, 4544, 4672, 4800, 4224, - 4224, 4224, 4224, 4416, 4544, 4672, 4800, 4288, 4288, - 4288, 4288, 4480, 4608, 4736, 4864, 4288, 4288, 4288, - 4288, 4480, 4608, 4736, 4864, 4352, 4352, 4352, 4352, - 4544, 4672, 4800, 4928, 4352, 4352, 4352, 4352, 4544, - 4672, 4800, 4928, 4416, 4416, 4416, 4416, 4608, 4736, - 4864, 4992, 4416, 4416, 4416, 4416, 4608, 4736, 4864, - 4992, 4480, 4480, 4480, 4480, 4672, 4800, 4928, 5056, - 4480, 4480, 4480, 4480, 4672, 4800, 4928, 5056, 4544, - 4544, 4544, 4544, 4736, 4864, 4992, 5120, 4544, 4544, - 4544, 4544, 4736, 4864, 4992, 5120, 4608, 4608, 4608, - 4608, 4800, 4928, 5056, 5184, 4608, 4608, 4608, 4608, - 4800, 4928, 5056, 5184, 4672, 4672, 4672, 4672, 4864, - 4992, 5120, 5248, 4672, 4672, 4672, 4672, 4864, 4992, - 5120, 5248, 4736, 4736, 4736, 4736, 4928, 5056, 5184, - 5312, 4736, 4736, 4736, 4736, 4928, 5056, 5184, 5312, - 4800, 4800, 4800, 4800, 4992, 5120, 5248, 5376, 4800, - 4800, 4800, 4800, 4992, 5120, 5248, 5376, 4864, 4864, - 4864, 4864, 5056, 5184, 5312, 5440, 4864, 4864, 4864, - 4864, 5056, 5184, 5312, 5440, 4928, 4928, 4928, 4928, - 5120, 5248, 5376, 5504, 4928, 4928, 4928, 4928, 5120, - 5248, 5376, 5504, 4992, 4992, 4992, 4992, 5184, 5312, - 5440, 5568, 4992, 4992, 4992, 4992, 5184, 5312, 5440, - 5568, 5056, 5056, 5056, 5056, 5248, 5376, 5504, 5632, - 5056, 5056, 5056, 5056, 5248, 5376, 5504, 5632, 5120, - 5120, 5120, 5120, 5312, 5440, 5568, 5632, 5120, 5120, - 5120, 5120, 5312, 5440, 5568, 5632, 5184, 5184, 5184, - 5184, 5376, 5504, 5632, 5632, 5184, 5184, 5184, 5184, - 5376, 5504, 5632, 5632, 5248, 5248, 5248, 5248, 5440, - 5568, 5632, 5632, 5248, 5248, 5248, 5248, 5440, 5568, - 5632, 5632, 5312, 5312, 5312, 5312, 5504, 5632, 5632, - 5632, 5312, 5312, 5312, 5312, 5504, 5632, 5632, 5632, - 5376, 5376, 5376, 5376, 5568, 5632, 5632, 5632, 5376, - 5376, 5376, 5376, 5568, 5632, 5632, 5632, 5440, 5440, - 5440, 5440, 5632, 5632, 5632, 5632, 5440, 5440, 5440, - 5440, 5632, 5632, 5632, 5632, 5504, 5504, 5504, 5504, - 5632, 5632, 5632, 5632, 5504, 5504, 5504, 5504, 5632, - 5632, 5632, 5632, 5568, 5568, 5568, 5568, 5632, 5632, - 5632, 5632, 5568, 5568, 5568, 5568, 5632, 5632, 5632, - 5632 -}; - -static const int filterData2[1424] = { - 0, 2, 4, 6, 7, 9, 11, 13, 0, -2, -4, -6, -7, -9, -11, - -13, 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, - -11, -13, -15, 1, 3, 5, 7, 10, 12, 14, 16, -1, -3, -5, - -7, -10, -12, -14, -16, 1, 3, 6, 8, 11, 13, 16, 18, - -1, -3, -6, -8, -11, -13, -16, -18, 1, 4, 6, 9, 12, - 15, 17, 20, -1, -4, -6, -9, -12, -15, -17, -20, 1, 4, - 7, 10, 13, 16, 19, 22, -1, -4, -7, -10, -13, -16, -19, - -22, 1, 4, 8, 11, 14, 17, 21, 24, -1, -4, -8, -11, -14, - -17, -21, -24, 1, 5, 8, 12, 15, 19, 22, 26, -1, -5, - -8, -12, -15, -19, -22, -26, 2, 6, 10, 14, 18, 22, 26, - 30, -2, -6, -10, -14, -18, -22, -26, -30, 2, 6, 10, - 14, 19, 23, 27, 31, -2, -6, -10, -14, -19, -23, -27, - -31, 2, 7, 11, 16, 21, 26, 30, 35, -2, -7, -11, -16, - -21, -26, -30, -35, 2, 7, 13, 18, 23, 28, 34, 39, -2, - -7, -13, -18, -23, -28, -34, -39, 2, 8, 14, 20, 25, - 31, 37, 43, -2, -8, -14, -20, -25, -31, -37, -43, 3, - 9, 15, 21, 28, 34, 40, 46, -3, -9, -15, -21, -28, -34, - -40, -46, 3, 10, 17, 24, 31, 38, 45, 52, -3, -10, -17, - -24, -31, -38, -45, -52, 3, 11, 19, 27, 34, 42, 50, - 58, -3, -11, -19, -27, -34, -42, -50, -58, 4, 12, 21, - 29, 38, 46, 55, 63, -4, -12, -21, -29, -38, -46, -55, - -63, 4, 13, 23, 32, 41, 50, 60, 69, -4, -13, -23, -32, - -41, -50, -60, -69, 5, 15, 25, 35, 46, 56, 66, 76, -5, - -15, -25, -35, -46, -56, -66, -76, 5, 16, 28, 39, 50, - 61, 73, 84, -5, -16, -28, -39, -50, -61, -73, -84, 6, - 18, 31, 43, 56, 68, 81, 93, -6, -18, -31, -43, -56, - -68, -81, -93, 6, 20, 34, 48, 61, 75, 89, 103, -6, -20, - -34, -48, -61, -75, -89, -103, 7, 22, 37, 52, 67, 82, - 97, 112, -7, -22, -37, -52, -67, -82, -97, -112, 8, - 24, 41, 57, 74, 90, 107, 123, -8, -24, -41, -57, -74, - -90, -107, -123, 9, 27, 45, 63, 82, 100, 118, 136, -9, - -27, -45, -63, -82, -100, -118, -136, 10, 30, 50, 70, - 90, 110, 130, 150, -10, -30, -50, -70, -90, -110, -130, - -150, 11, 33, 55, 77, 99, 121, 143, 165, -11, -33, -55, - -77, -99, -121, -143, -165, 12, 36, 60, 84, 109, 133, - 157, 181, -12, -36, -60, -84, -109, -133, -157, -181, - 13, 40, 66, 93, 120, 147, 173, 200, -13, -40, -66, -93, - -120, -147, -173, -200, 14, 44, 73, 103, 132, 162, 191, - 221, -14, -44, -73, -103, -132, -162, -191, -221, 16, - 48, 81, 113, 146, 178, 211, 243, -16, -48, -81, -113, - -146, -178, -211, -243, 17, 53, 89, 125, 160, 196, 232, - 268, -17, -53, -89, -125, -160, -196, -232, -268, 19, - 58, 98, 137, 176, 215, 255, 294, -19, -58, -98, -137, - -176, -215, -255, -294, 21, 64, 108, 151, 194, 237, - 281, 324, -21, -64, -108, -151, -194, -237, -281, -324, - 23, 71, 118, 166, 213, 261, 308, 356, -23, -71, -118, - -166, -213, -261, -308, -356, 26, 78, 130, 182, 235, - 287, 339, 391, -26, -78, -130, -182, -235, -287, -339, - -391, 28, 86, 143, 201, 258, 316, 373, 431, -28, -86, - -143, -201, -258, -316, -373, -431, 31, 94, 158, 221, - 284, 347, 411, 474, -31, -94, -158, -221, -284, -347, - -411, -474, 34, 104, 174, 244, 313, 383, 453, 523, -34, - -104, -174, -244, -313, -383, -453, -523, 38, 115, 191, - 268, 345, 422, 498, 575, -38, -115, -191, -268, -345, - -422, -498, -575, 42, 126, 210, 294, 379, 463, 547, - 631, -42, -126, -210, -294, -379, -463, -547, -631, - 46, 139, 231, 324, 417, 510, 602, 695, -46, -139, -231, - -324, -417, -510, -602, -695, 51, 153, 255, 357, 459, - 561, 663, 765, -51, -153, -255, -357, -459, -561, -663, - -765, 56, 168, 280, 392, 505, 617, 729, 841, -56, -168, - -280, -392, -505, -617, -729, -841, 61, 185, 308, 432, - 555, 679, 802, 926, -61, -185, -308, -432, -555, -679, - -802, -926, 68, 204, 340, 476, 612, 748, 884, 1020, - -68, -204, -340, -476, -612, -748, -884, -1020, 74, - 224, 373, 523, 672, 822, 971, 1121, -74, -224, -373, - -523, -672, -822, -971, -1121, 82, 246, 411, 575, 740, - 904, 1069, 1233, -82, -246, -411, -575, -740, -904, - -1069, -1233, 90, 271, 452, 633, 814, 995, 1176, 1357, - -90, -271, -452, -633, -814, -995, -1176, -1357, 99, - 298, 497, 696, 895, 1094, 1293, 1492, -99, -298, -497, - -696, -895, -1094, -1293, -1492, 109, 328, 547, 766, - 985, 1204, 1423, 1642, -109, -328, -547, -766, -985, - -1204, -1423, -1642, 120, 361, 601, 842, 1083, 1324, - 1564, 1805, -120, -361, -601, -842, -1083, -1324, -1564, - -1805, 132, 397, 662, 927, 1192, 1457, 1722, 1987, -132, - -397, -662, -927, -1192, -1457, -1722, -1987, 145, 437, - 728, 1020, 1311, 1603, 1894, 2186, -145, -437, -728, - -1020, -1311, -1603, -1894, -2186, 160, 480, 801, 1121, - 1442, 1762, 2083, 2403, -160, -480, -801, -1121, -1442, - -1762, -2083, -2403, 176, 529, 881, 1234, 1587, 1940, - 2292, 2645, -176, -529, -881, -1234, -1587, -1940, -2292, - -2645, 194, 582, 970, 1358, 1746, 2134, 2522, 2910, - -194, -582, -970, -1358, -1746, -2134, -2522, -2910, - 213, 640, 1066, 1493, 1920, 2347, 2773, 3200, -213, - -640, -1066, -1493, -1920, -2347, -2773, -3200, 234, - 704, 1173, 1643, 2112, 2582, 3051, 3521, -234, -704, - -1173, -1643, -2112, -2582, -3051, -3521, 258, 774, - 1291, 1807, 2324, 2840, 3357, 3873, -258, -774, -1291, - -1807, -2324, -2840, -3357, -3873, 284, 852, 1420, 1988, - 2556, 3124, 3692, 4260, -284, -852, -1420, -1988, -2556, - -3124, -3692, -4260, 312, 937, 1561, 2186, 2811, 3436, - 4060, 4685, -312, -937, -1561, -2186, -2811, -3436, - -4060, -4685, 343, 1030, 1718, 2405, 3092, 3779, 4467, - 5154, -343, -1030, -1718, -2405, -3092, -3779, -4467, - -5154, 378, 1134, 1890, 2646, 3402, 4158, 4914, 5670, - -378, -1134, -1890, -2646, -3402, -4158, -4914, -5670, - 415, 1247, 2079, 2911, 3742, 4574, 5406, 6238, -415, - -1247, -2079, -2911, -3742, -4574, -5406, -6238, 457, - 1372, 2287, 3202, 4117, 5032, 5947, 6862, -457, -1372, - -2287, -3202, -4117, -5032, -5947, -6862, 503, 1509, - 2516, 3522, 4529, 5535, 6542, 7548, -503, -1509, -2516, - -3522, -4529, -5535, -6542, -7548, 553, 1660, 2767, - 3874, 4981, 6088, 7195, 8302, -553, -1660, -2767, -3874, - -4981, -6088, -7195, -8302, 608, 1826, 3044, 4262, 5479, - 6697, 7915, 9133, -608, -1826, -3044, -4262, -5479, - -6697, -7915, -9133, 669, 2009, 3348, 4688, 6027, 7367, - 8706, 10046, -669, -2009, -3348, -4688, -6027, -7367, - -8706, -10046, 736, 2210, 3683, 5157, 6630, 8104, 9577, - 11051, -736, -2210, -3683, -5157, -6630, -8104, -9577, - -11051, 810, 2431, 4052, 5673, 7294, 8915, 10536, 12157, - -810, -2431, -4052, -5673, -7294, -8915, -10536, -12157, - 891, 2674, 4457, 6240, 8023, 9806, 11589, 13372, -891, - -2674, -4457, -6240, -8023, -9806, -11589, -13372, 980, - 2941, 4903, 6864, 8825, 10786, 12748, 14709, -980, -2941, - -4903, -6864, -8825, -10786, -12748, -14709, 1078, 3236, - 5393, 7551, 9708, 11866, 14023, 16181, -1078, -3236, - -5393, -7551, -9708, -11866, -14023, -16181, 1186, 3559, - 5933, 8306, 10679, 13052, 15426, 17799, -1186, -3559, - -5933, -8306, -10679, -13052, -15426, -17799, 1305, - 3915, 6526, 9136, 11747, 14357, 16968, 19578, -1305, - -3915, -6526, -9136, -11747, -14357, -16968, -19578, - 1435, 4307, 7179, 10051, 12922, 15794, 18666, 21538, - -1435, -4307, -7179, -10051, -12922, -15794, -18666, - -21538, 1579, 4738, 7896, 11055, 14214, 17373, 20531, - 23690, -1579, -4738, -7896, -11055, -14214, -17373, - -20531, -23690, 1737, 5212, 8686, 12161, 15636, 19111, - 22585, 26060, -1737, -5212, -8686, -12161, -15636, -19111, - -22585, -26060, 1911, 5733, 9555, 13377, 17200, 21022, - 24844, 28666, -1911, -5733, -9555, -13377, -17200, -21022, - -24844, -28666, 2102, 6306, 10511, 14715, 18920, 23124, - 27329, 31533, -2102, -6306, -10511, -14715, -18920, - -23124, -27329, -31533, 2312, 6937, 11562, 16187, 20812, - 25437, 30062, 32767, -2312, -6937, -11562, -16187, -20812, - -25437, -30062, -32767, 2543, 7631, 12718, 17806, 22893, - 27981, 32767, 32767, -2543, -7631, -12718, -17806, -22893, - -27981, -32767, -32767, 2798, 8394, 13990, 19586, 25183, - 30779, 32767, 32767, -2798, -8394, -13990, -19586, -25183, - -30779, -32767, -32767, 3077, 9233, 15389, 21545, 27700, - 32767, 32767, 32767, -3077, -9233, -15389, -21545, -27700, - -32767, -32767, -32767, 3385, 10157, 16928, 23700, 30471, - 32767, 32767, 32767, -3385, -10157, -16928, -23700, - -30471, -32767, -32767, -32767, 3724, 11172, 18621, - 26069, 32767, 32767, 32767, 32767, -3724, -11172, -18621, - -26069, -32767, -32767, -32767, -32767, 4095, 12287, - 20479, 28671, 32767, 32767, 32767, 32767, -4095, -12287, - -20479, -28671, -32767, -32767, -32767, -32767 -}; - -static const int p1s[17] = { 0, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4, 0 }; -static const int p2s[17] = { 0, 1, 1, 3, 1, 5, 3, 7, 1, 9, 5, 11, 3, 13, 7, 15, 1 }; - -static void soundFilter(byte *data, int16 *buffer, int p1, int p2); - -void SoundEntry::applyFilter(int16 *buffer) { - if ((READ_UINT16((int16 *)(_currentDataPtr + 2)) << 6) > 5632) { - _status.status |= kSoundStatus_20000000; - } else { - int variant = _status.status & kSoundStatusFilterVariant; - - soundFilter(_currentDataPtr, buffer, p1s[variant], p2s[variant]); - _currentDataPtr += 739; - } -} - -static void soundFilter(byte *data, int16 *buffer, int p1, int p2) { - int data1, data2, data1p, data2p; - byte idx; - - data2 = data[0]; - data1 = data[1] << 6; - - data += 2; - - for (int count = 0; count < 735; count++) { - idx = data[count] >> 4; - - if ((idx + data1) > ARRAYSIZE(filterData)) { - warning("Error in sound filter, aborting..."); - return; - } - - data1p = filterData[idx + data1]; - data2p = CLIP(filterData2[idx + data1] + data2, -32767, 32767); - - buffer[2 * count] = (p2 * data2p) >> p1; - - idx = data[count] & 0xF; - - if ((idx + data1p) > ARRAYSIZE(filterData)) { - warning("Error in sound filter, aborting..."); - return; - } - - data1 = filterData[idx + data1p]; - data2 = CLIP(filterData2[idx + data1p] + data2p, -32767, 32767); - buffer[2 * count + 1] = (p2 * data2) >> p1; - } -} - -////////////////////////////////////////////////////////////////////////// // SubtitleEntry ////////////////////////////////////////////////////////////////////////// SubtitleEntry::SubtitleEntry(LastExpressEngine *engine) : _engine(engine) { diff --git a/engines/lastexpress/sound/entry.h b/engines/lastexpress/sound/entry.h index a466d31b3a..a88b0b7210 100644 --- a/engines/lastexpress/sound/entry.h +++ b/engines/lastexpress/sound/entry.h @@ -102,7 +102,9 @@ public: void reset(); bool isFinished(); void update(uint val); + bool updateSound(); void updateState(); + void updateEntryFlag(SoundFlag flag); // Subtitles void showSubtitle(Common::String filename); @@ -124,8 +126,7 @@ public: Common::String getName2() { return _name2; } // Streams - SimpleSound *getSoundStream() { return _soundStream; } - byte *getSoundBuffer() { return _soundBuffer; } + SimpleSound *getSoundStream() { return _soundStream; } private: LastExpressEngine *_engine; @@ -141,7 +142,7 @@ private: //int _size; //int _field_28; Common::SeekableReadStream *_stream; // The file stream - //int _field_30; + //int _archive; int _field_34; int _field_38; int _field_3C; @@ -156,16 +157,11 @@ private: // Sound buffer & stream bool _queued; - byte *_soundBuffer; StreamedSound *_soundStream; // the filtered sound stream void setType(SoundFlag flag); void setupStatus(SoundFlag flag); - void setupCache(); - void setInCache(); - void loadSoundData(Common::String name); - - void applyFilter(int16 *buffer); + void loadStream(Common::String name); }; ////////////////////////////////////////////////////////////////////////// @@ -184,7 +180,7 @@ public: // Accessors SoundStatusUnion getStatus() { return _status; } - SoundEntry *getSoundEntry() { return _sound; } + SoundEntry *getSoundEntry() { return _sound; } private: LastExpressEngine *_engine; diff --git a/engines/lastexpress/sound/queue.cpp b/engines/lastexpress/sound/queue.cpp index ad5c9bf4e3..33b4c06793 100644 --- a/engines/lastexpress/sound/queue.cpp +++ b/engines/lastexpress/sound/queue.cpp @@ -102,9 +102,41 @@ void SoundQueue::removeFromQueue(Common::String filename) { } void SoundQueue::updateQueue() { - //Common::StackLock locker(_mutex); + Common::StackLock locker(_mutex); + + ++_flag; + + if (getSoundState() & kSoundState1) { + SoundEntry *entry = getEntry(kSoundType1); + if (!entry || getFlags()->flag_3 || (entry && entry->getTime() > getSound()->getLoopingSoundDuration())) { + getSound()->playLoopingSound(0x45); + } else { + if (getSound()->getData1() && getSound()->getData2() >= getSound()->getData1()) { + entry->update(getSound()->getData0()); + getSound()->setData1(0); + } + } + } + + for (Common::List<SoundEntry *>::iterator it = _soundList.begin(); it != _soundList.end(); ++it) { + SoundEntry *entry = *it; + + // Original removes the entry data from the cache and sets the archive as not loaded + // and if the sound data buffer is not full, loads a new entry to be played based on + // its priority and filter id - //warning("[Sound::updateQueue] Not implemented"); + if (!entry->updateSound() && !(entry->getStatus().status3 & 0x8)) { + entry->close(); + SAFE_DELETE(entry); + it = _soundList.reverse_erase(it); + } + } + + // Original update the current entry, loading another set of samples to be decoded + + getFlags()->flag_3 = 0; + + --_flag; } void SoundQueue::resetQueue() { @@ -138,17 +170,10 @@ void SoundQueue::resetQueue(SoundType type1, SoundType type2) { } void SoundQueue::clearQueue() { - _flag |= 4; - - // FIXME: Wait a while for a flag to be set - //for (int i = 0; i < 3000000; i++) - // if (_flag & 8) - // break; + Common::StackLock locker(_mutex); _flag |= 8; - Common::StackLock locker(_mutex); - for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) { SoundEntry *entry = (*i); @@ -169,7 +194,7 @@ void SoundQueue::clearStatus() { Common::StackLock locker(_mutex); for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) - (*i)->setStatus((*i)->getStatus().status | kSoundStatusClear3); + (*i)->setStatus((*i)->getStatus().status | kSoundStatusClosed); } ////////////////////////////////////////////////////////////////////////// @@ -292,11 +317,11 @@ void SoundQueue::updateSubtitles() { if (!(status & kSoundStatus_40) || status & kSoundStatus_180 || soundEntry->getTime() == 0 - || (status & kSoundStatusFilterVariant) < 6 + || (status & kSoundStatusFilter) < 6 || ((getFlags()->nis & 0x8000) && soundEntry->getPriority() < 90)) { current_index = 0; } else { - current_index = soundEntry->getPriority() + (status & kSoundStatusFilterVariant); + current_index = soundEntry->getPriority() + (status & kSoundStatusFilter); if (_currentSubtitle == (*i)) current_index += 4; diff --git a/engines/lastexpress/sound/sound.cpp b/engines/lastexpress/sound/sound.cpp index c04b6d361f..2f7bb4a601 100644 --- a/engines/lastexpress/sound/sound.cpp +++ b/engines/lastexpress/sound/sound.cpp @@ -1305,8 +1305,8 @@ void SoundManager::playLoopingSound(int param) { int partNumber = 1; int fnameLen = 6; - if (_queue->getSoundState() & 1 && param >= 0x45 && param <= 0x46) { - if (_queue->getSoundState() & 2) { + if (_queue->getSoundState() & kSoundState1 && param >= 0x45 && param <= 0x46) { + if (_queue->getSoundState() & kSoundState2) { strcpy(tmp, "STEAM.SND"); _loopingSoundDuration = 32767; diff --git a/engines/lastexpress/sound/sound.h b/engines/lastexpress/sound/sound.h index 797e52646e..517543f470 100644 --- a/engines/lastexpress/sound/sound.h +++ b/engines/lastexpress/sound/sound.h @@ -64,7 +64,13 @@ public: // Accessors SoundQueue *getQueue() { return _queue; } - uint32 getData2() { return _data2; } + uint32 getData0() { return _data0; } + int32 getData1() { return _data1; } + int32 getData2() { return _data2; } + uint32 getLoopingSoundDuration() { return _loopingSoundDuration; } + + // Setters + void setData1(int32 data) { _data1 = data; } private: LastExpressEngine *_engine; @@ -78,8 +84,8 @@ private: // Unknown data uint32 _data0; - uint32 _data1; - uint32 _data2; + int32 _data1; + int32 _data2; }; } // End of namespace LastExpress diff --git a/engines/mohawk/console.cpp b/engines/mohawk/console.cpp index 05012bec3d..e7dc84606c 100644 --- a/engines/mohawk/console.cpp +++ b/engines/mohawk/console.cpp @@ -700,14 +700,25 @@ bool LivingBooksConsole::Cmd_DrawImage(int argc, const char **argv) { } bool LivingBooksConsole::Cmd_ChangePage(int argc, const char **argv) { - if (argc == 1) { - DebugPrintf("Usage: changePage <page> [<mode>]\n"); + if (argc < 2 || argc > 3) { + DebugPrintf("Usage: changePage <page>[.<subpage>] [<mode>]\n"); return true; } - if (_vm->tryLoadPageStart(argc == 2 ? _vm->getCurMode() : (LBMode)atoi(argv[2]), atoi(argv[1]))) - return false; - DebugPrintf("no such page %d\n", atoi(argv[1])); + int page, subpage = 0; + if (sscanf(argv[1], "%d.%d", &page, &subpage) == 0) { + DebugPrintf("Usage: changePage <page>[.<subpage>] [<mode>]\n"); + return true; + } + LBMode mode = argc == 2 ? _vm->getCurMode() : (LBMode)atoi(argv[2]); + if (subpage == 0) { + if (_vm->tryLoadPageStart(mode, page)) + return false; + } else { + if (_vm->loadPage(mode, page, subpage)) + return false; + } + DebugPrintf("no such page %d.%d\n", page, subpage); return true; } diff --git a/engines/mohawk/cursors.cpp b/engines/mohawk/cursors.cpp index 3284a3228f..78e099ccfe 100644 --- a/engines/mohawk/cursors.cpp +++ b/engines/mohawk/cursors.cpp @@ -252,6 +252,17 @@ void LivingBooksCursorManager_v2::setCursor(uint16 id) { } } +void LivingBooksCursorManager_v2::setCursor(const Common::String &name) { + if (!_sysArchive) + return; + + uint16 id = _sysArchive->findResourceID(ID_TCUR, name); + if (id == 0xffff) + error("Could not find cursor '%s'", name.c_str()); + else + setCursor(id); +} + PECursorManager::PECursorManager(const Common::String &appName) { _exe = new Common::PEResources(); diff --git a/engines/mohawk/cursors.h b/engines/mohawk/cursors.h index d92b6b4285..7bfa491904 100644 --- a/engines/mohawk/cursors.h +++ b/engines/mohawk/cursors.h @@ -56,6 +56,7 @@ public: virtual void showCursor(); virtual void hideCursor(); virtual void setCursor(uint16 id); + virtual void setCursor(const Common::String &name) {} virtual void setDefaultCursor(); virtual bool hasSource() const { return false; } @@ -157,6 +158,7 @@ public: ~LivingBooksCursorManager_v2(); void setCursor(uint16 id); + void setCursor(const Common::String &name); bool hasSource() const { return _sysArchive != 0; } private: diff --git a/engines/mohawk/livingbooks.cpp b/engines/mohawk/livingbooks.cpp index f9d18ff7ff..65073bd970 100644 --- a/engines/mohawk/livingbooks.cpp +++ b/engines/mohawk/livingbooks.cpp @@ -204,9 +204,12 @@ Common::Error MohawkEngine_LivingBooks::run() { break; case Common::EVENT_LBUTTONDOWN: - for (uint16 i = 0; i < _items.size(); i++) - if (_items[i]->contains(event.mouse)) - found = _items[i]; + for (Common::List<LBItem *>::const_iterator i = _orderedItems.begin(); i != _orderedItems.end(); ++i) { + if ((*i)->contains(event.mouse)) { + found = *i; + break; + } + } if (found) found->handleMouseDown(event.mouse); @@ -341,6 +344,7 @@ void MohawkEngine_LivingBooks::destroyPage() { delete _page; assert(_items.empty()); + assert(_orderedItems.empty()); _page = NULL; _notifyEvents.clear(); @@ -567,6 +571,7 @@ void MohawkEngine_LivingBooks::updatePage() { case kLBDelayedEventDestroy: _items.remove_at(i); i--; + _orderedItems.remove(delayedEvent.item); delete delayedEvent.item; _page->itemDestroyed(delayedEvent.item); if (_focus == delayedEvent.item) @@ -613,6 +618,8 @@ void MohawkEngine_LivingBooks::removeArchive(Archive *archive) { void MohawkEngine_LivingBooks::addItem(LBItem *item) { _items.push_back(item); + _orderedItems.push_front(item); + item->_iterator = _orderedItems.begin(); } void MohawkEngine_LivingBooks::removeItems(const Common::Array<LBItem *> &items) { @@ -626,6 +633,7 @@ void MohawkEngine_LivingBooks::removeItems(const Common::Array<LBItem *> &items) break; } assert(found); + _orderedItems.erase(items[i]->_iterator); } } @@ -1319,8 +1327,13 @@ void MohawkEngine_LivingBooks::handleNotify(NotifyEvent &event) { if (getGameType() == GType_LIVINGBOOKSV1) { debug(2, "kLBNotifyChangeMode: %d", event.param); quitGame(); - } else { - debug(2, "kLBNotifyChangeMode: mode %d, page %d.%d", + break; + } + + debug(2, "kLBNotifyChangeMode: v2 type %d", event.param); + switch (event.param) { + case 1: + debug(2, "kLBNotifyChangeMode:, mode %d, page %d.%d", event.newMode, event.newPage, event.newSubpage); // TODO: what is entry.newUnknown? if (!event.newMode) @@ -1331,6 +1344,13 @@ void MohawkEngine_LivingBooks::handleNotify(NotifyEvent &event) { error("kLBNotifyChangeMode failed to move to mode %d, page %d.%d", event.newMode, event.newPage, event.newSubpage); } + break; + case 3: + debug(2, "kLBNotifyChangeMode: new cursor '%s'", event.newCursor.c_str()); + _cursor->setCursor(event.newCursor); + break; + default: + error("unknown v2 kLBNotifyChangeMode type %d", event.param); } break; @@ -2084,16 +2104,32 @@ LBScriptEntry *LBItem::parseScriptEntry(uint16 type, uint16 &size, Common::Memor } if (type == kLBNotifyScript && entry->opcode == kLBNotifyChangeMode && _vm->getGameType() != GType_LIVINGBOOKSV1) { - if (size < 8) { - error("%d unknown bytes in notify entry kLBNotifyChangeMode", size); + switch (entry->param) { + case 1: + if (size < 8) + error("%d unknown bytes in notify entry kLBNotifyChangeMode", size); + entry->newUnknown = stream->readUint16(); + entry->newMode = stream->readUint16(); + entry->newPage = stream->readUint16(); + entry->newSubpage = stream->readUint16(); + debug(4, "kLBNotifyChangeMode: unknown %04x, mode %d, page %d.%d", + entry->newUnknown, entry->newMode, entry->newPage, entry->newSubpage); + size -= 8; + break; + case 3: + { + Common::String newCursor = _vm->readString(stream); + entry->newCursor = newCursor; + if (size < newCursor.size() + 1) + error("failed to read newCursor in notify entry"); + size -= newCursor.size() + 1; + debug(4, "kLBNotifyChangeMode: new cursor '%s'", newCursor.c_str()); + } + break; + default: + // the original engine also does something when param==2 (but not a notify) + error("unknown v2 kLBNotifyChangeMode type %d", entry->param); } - entry->newUnknown = stream->readUint16(); - entry->newMode = stream->readUint16(); - entry->newPage = stream->readUint16(); - entry->newSubpage = stream->readUint16(); - debug(4, "kLBNotifyChangeMode: unknown %04x, mode %d, page %d.%d", - entry->newUnknown, entry->newMode, entry->newPage, entry->newSubpage); - size -= 8; } if (entry->opcode == kLBOpSendExpression) { if (size < 4) @@ -2577,6 +2613,7 @@ void LBItem::runScript(uint event, uint16 data, uint16 from) { notifyEvent.newMode = entry->newMode; notifyEvent.newPage = entry->newPage; notifyEvent.newSubpage = entry->newSubpage; + notifyEvent.newCursor = entry->newCursor; _vm->addNotifyEvent(notifyEvent); } else _vm->addNotifyEvent(NotifyEvent(entry->opcode, entry->param)); diff --git a/engines/mohawk/livingbooks.h b/engines/mohawk/livingbooks.h index 6cf3ee361b..27e703a578 100644 --- a/engines/mohawk/livingbooks.h +++ b/engines/mohawk/livingbooks.h @@ -133,7 +133,9 @@ enum { kLBEventMouseUp = 5, kLBEventPhaseMain = 6, kLBEventNotified = 7, + kLBEventDragStart = 8, kLBEventDragMove = 9, + kLBEventDragEnd = 0xa, kLBEventRolloverBegin = 0xb, kLBEventRolloverMove = 0xc, kLBEventRolloverEnd = 0xd, @@ -271,6 +273,7 @@ struct LBScriptEntry { uint16 newMode; uint16 newPage; uint16 newSubpage; + Common::String newCursor; // kLBEventNotified uint16 matchFrom; @@ -405,6 +408,8 @@ public: uint16 getSoundPriority() { return _soundMode; } bool isAmbient() { return _isAmbient; } + Common::List<LBItem *>::iterator _iterator; + protected: MohawkEngine_LivingBooks *_vm; LBPage *_page; @@ -608,6 +613,7 @@ struct NotifyEvent { uint16 newMode; uint16 newPage; uint16 newSubpage; + Common::String newCursor; }; enum DelayedEventType { @@ -667,7 +673,7 @@ public: GUI::Debugger *getDebugger() { return _console; } void addArchive(Archive *archive); - void removeArchive(Archive *Archive); + void removeArchive(Archive *archive); void addItem(LBItem *item); void removeItems(const Common::Array<LBItem *> &items); @@ -688,6 +694,7 @@ public: LBMode getCurMode() { return _curMode; } bool tryLoadPageStart(LBMode mode, uint page); + bool loadPage(LBMode mode, uint page, uint subpage); void prevPage(); void nextPage(); @@ -713,10 +720,10 @@ private: uint16 _phase; LBPage *_page; Common::Array<LBItem *> _items; + Common::List<LBItem *> _orderedItems; Common::Queue<DelayedEvent> _eventQueue; LBItem *_focus; void destroyPage(); - bool loadPage(LBMode mode, uint page, uint subpage); void updatePage(); uint16 _lastSoundOwner, _lastSoundId; diff --git a/engines/mohawk/livingbooks_code.cpp b/engines/mohawk/livingbooks_code.cpp index 95f3261787..80b5fe9660 100644 --- a/engines/mohawk/livingbooks_code.cpp +++ b/engines/mohawk/livingbooks_code.cpp @@ -277,27 +277,27 @@ LBValue LBCode::runCode(byte terminator) { void LBCode::parseStatement() { parseComparisons(); - if (_currToken != kTokenAnd && _currToken != kTokenOr) - return; - byte op = _currToken; - if (op == kTokenAnd) - debugN(" && "); - else - debugN(" || "); + while (_currToken == kTokenAnd || _currToken == kTokenOr) { + byte op = _currToken; + if (op == kTokenAnd) + debugN(" && "); + else + debugN(" || "); - nextToken(); - parseComparisons(); + nextToken(); + parseComparisons(); - LBValue val2 = _stack.pop(); - LBValue val1 = _stack.pop(); - bool result; - if (op == kTokenAnd) - result = !val1.isZero() && !val2.isZero(); - else - result = !val1.isZero() || !val2.isZero(); + LBValue val2 = _stack.pop(); + LBValue val1 = _stack.pop(); + bool result; + if (op == kTokenAnd) + result = !val1.isZero() && !val2.isZero(); + else + result = !val1.isZero() || !val2.isZero(); - debugN(" [--> %s]", result ? "true" : "false"); - _stack.push(result); + debugN(" [--> %s]", result ? "true" : "false"); + _stack.push(result); + } } void LBCode::parseComparisons() { @@ -365,49 +365,95 @@ void LBCode::parseComparisons() { void LBCode::parseConcat() { parseArithmetic1(); - if (_currToken != kTokenConcat) - return; - - debugN(" & "); - nextToken(); - parseArithmetic1(); + while (_currToken == kTokenConcat) { + debugN(" & "); + nextToken(); + parseArithmetic1(); - LBValue val2 = _stack.pop(); - LBValue val1 = _stack.pop(); - Common::String result = val1.toString() + val2.toString(); - debugN(" [--> \"%s\"]", result.c_str()); - _stack.push(result); + LBValue val2 = _stack.pop(); + LBValue val1 = _stack.pop(); + Common::String result = val1.toString() + val2.toString(); + debugN(" [--> \"%s\"]", result.c_str()); + _stack.push(result); + } } void LBCode::parseArithmetic1() { parseArithmetic2(); - if (_currToken != kTokenMinus && _currToken != kTokenPlus) - return; - - byte op = _currToken; - if (op == kTokenMinus) - debugN(" - "); - else if (op == kTokenPlus) - debugN(" + "); + while (_currToken == kTokenMinus || _currToken == kTokenPlus) { + byte op = _currToken; + if (op == kTokenMinus) + debugN(" - "); + else if (op == kTokenPlus) + debugN(" + "); - nextToken(); - parseArithmetic2(); - - LBValue val2 = _stack.pop(); - LBValue val1 = _stack.pop(); - LBValue result; - // TODO: cope with non-integers - if (op == kTokenMinus) - result = val1.toInt() - val2.toInt(); - else - result = val1.toInt() + val2.toInt(); - _stack.push(result); + nextToken(); + parseArithmetic2(); + + LBValue val2 = _stack.pop(); + LBValue val1 = _stack.pop(); + LBValue result; + // TODO: cope with non-integers + if (op == kTokenMinus) + result = val1.toInt() - val2.toInt(); + else + result = val1.toInt() + val2.toInt(); + debugN(" [--> %d]", result.toInt()); + _stack.push(result); + } } void LBCode::parseArithmetic2() { - // FIXME: other math operators parseMain(); + + while (true) { + byte op = _currToken; + switch (op) { + case kTokenMultiply: + debugN(" * "); + break; + case kTokenDivide: + debugN(" / "); + break; + case kTokenIntDivide: + debugN(" div "); + break; + case kTokenModulo: + debugN(" %% "); + break; + default: + return; + } + + nextToken(); + parseMain(); + + LBValue val2 = _stack.pop(); + LBValue val1 = _stack.pop(); + LBValue result; + // TODO: cope with non-integers + if (op == kTokenMultiply) { + result = val1.toInt() * val2.toInt(); + } else if (val2.toInt() == 0) { + result = 1; + } else { + switch (op) { + case kTokenDivide: + // TODO: fp divide + result = val1.toInt() / val2.toInt(); + break; + case kTokenIntDivide: + result = val1.toInt() / val2.toInt(); + break; + case kTokenModulo: + result = val1.toInt() % val2.toInt(); + break; + } + } + + _stack.push(result); + } } void LBCode::parseMain() { @@ -640,8 +686,8 @@ struct CodeCommandInfo { CodeCommandInfo generalCommandInfo[NUM_GENERAL_COMMANDS] = { { "eval", &LBCode::cmdEval }, { "random", &LBCode::cmdRandom }, - { "stringLen", 0 }, - { "substring", 0 }, + { "stringLen", &LBCode::cmdStringLen }, + { "substring", &LBCode::cmdSubstring }, { "max", 0 }, { "min", 0 }, { "abs", 0 }, @@ -815,6 +861,31 @@ void LBCode::cmdRandom(const Common::Array<LBValue> ¶ms) { _stack.push(_vm->_rnd->getRandomNumberRng(min, max)); } +void LBCode::cmdStringLen(const Common::Array<LBValue> ¶ms) { + if (params.size() != 1) + error("incorrect number of parameters (%d) to stringLen", params.size()); + + const Common::String &string = params[0].toString(); + _stack.push(string.size()); +} + +void LBCode::cmdSubstring(const Common::Array<LBValue> ¶ms) { + if (params.size() != 3) + error("incorrect number of parameters (%d) to substring", params.size()); + + const Common::String &string = params[0].toString(); + uint begin = params[1].toInt(); + uint end = params[2].toInt(); + if (begin == 0) + error("invalid substring call (%d to %d)", begin, end); + if (begin > end || end > string.size()) { + _stack.push(Common::String()); + return; + } + Common::String substring(string.c_str() + (begin - 1), end - begin + 1); + _stack.push(substring); +} + void LBCode::cmdGetRect(const Common::Array<LBValue> ¶ms) { if (params.size() < 2) { _stack.push(getRectFromParams(params)); @@ -1110,8 +1181,8 @@ bool LBCode::parseCodeSymbol(const Common::String &name, uint &pos, Common::Arra // first, check whether the name matches a known function for (uint i = 0; i < 2; i++) { byte cmdToken; - CodeCommandInfo *cmdInfo; - uint cmdCount; + CodeCommandInfo *cmdInfo = NULL; + uint cmdCount = 0; switch (i) { case 0: diff --git a/engines/mohawk/livingbooks_code.h b/engines/mohawk/livingbooks_code.h index 9c58ed7a46..79c9af94f7 100644 --- a/engines/mohawk/livingbooks_code.h +++ b/engines/mohawk/livingbooks_code.h @@ -222,6 +222,8 @@ public: void cmdUnimplemented(const Common::Array<LBValue> ¶ms); void cmdEval(const Common::Array<LBValue> ¶ms); void cmdRandom(const Common::Array<LBValue> ¶ms); + void cmdStringLen(const Common::Array<LBValue> ¶ms); + void cmdSubstring(const Common::Array<LBValue> ¶ms); void cmdGetRect(const Common::Array<LBValue> ¶ms); void cmdTopLeft(const Common::Array<LBValue> ¶ms); void cmdBottomRight(const Common::Array<LBValue> ¶ms); diff --git a/engines/mohawk/myst_scripts.cpp b/engines/mohawk/myst_scripts.cpp index 17f6de534f..307be2dd05 100644 --- a/engines/mohawk/myst_scripts.cpp +++ b/engines/mohawk/myst_scripts.cpp @@ -560,6 +560,7 @@ void MystScriptParser::o_playSoundBlocking(uint16 op, uint16 var, uint16 argc, u debugC(kDebugScript, "Opcode %d: playSoundBlocking", op); debugC(kDebugScript, "\tsoundId: %d", soundId); + _vm->_sound->stopSound(); _vm->_sound->playSoundBlocking(soundId); } diff --git a/engines/mohawk/myst_stacks/mechanical.cpp b/engines/mohawk/myst_stacks/mechanical.cpp index d6dd1b5407..12d9dc7e2f 100644 --- a/engines/mohawk/myst_stacks/mechanical.cpp +++ b/engines/mohawk/myst_stacks/mechanical.cpp @@ -102,6 +102,7 @@ void Mechanical::setupOpcodes() { void Mechanical::disablePersistentScripts() { _fortressSimulationRunning = false; + _elevatorRotationLeverMoving = false; _elevatorGoingMiddle = false; _birdSinging = false; _fortressRotationRunning = false; @@ -126,10 +127,10 @@ void Mechanical::runPersistentScripts() { uint16 Mechanical::getVar(uint16 var) { switch(var) { - case 0: // Sirrus's Secret Panel State - return _state.sirrusPanelState; - case 1: // Achenar's Secret Panel State + case 0: // Achenar's Secret Panel State return _state.achenarPanelState; + case 1: // Sirrus's Secret Panel State + return _state.sirrusPanelState; case 2: // Achenar's Secret Room Crate Lid Open and Blue Page Present if (_state.achenarCrateOpened) { if (_globals.bluePagesInBook & 4 || _globals.heldPage == 3) @@ -195,16 +196,21 @@ uint16 Mechanical::getVar(uint16 var) { void Mechanical::toggleVar(uint16 var) { switch(var) { - case 0: // Sirrus's Secret Panel State - _state.sirrusPanelState ^= 1; - case 1: // Achenar's Secret Panel State + case 0: // Achenar's Secret Panel State _state.achenarPanelState ^= 1; + break; + case 1: // Sirrus's Secret Panel State + _state.sirrusPanelState ^= 1; + break; case 3: // Achenar's Secret Room Crate State _state.achenarCrateOpened ^= 1; + break; case 4: // Myst Book Room Staircase State _mystStaircaseState ^= 1; + break; case 10: // Fortress Staircase State _state.staircaseState ^= 1; + break; case 16: // Code Lock Shape #1 - Left case 17: // Code Lock Shape #2 case 18: // Code Lock Shape #3 @@ -242,6 +248,7 @@ bool Mechanical::setVarValue(uint16 var, uint16 value) { switch (var) { case 13: _elevatorPosition = value; + break; case 14: // Elevator going down when at top _elevatorGoingDown = value; break; @@ -724,6 +731,7 @@ void Mechanical::birdSing_run() { uint32 time = _vm->_system->getMillis(); if (_birdSingEndTime < time) { _bird->pauseMovie(true); + _vm->_sound->stopSound(); _birdSinging = false; } } diff --git a/engines/mohawk/sound.cpp b/engines/mohawk/sound.cpp index 6144c89e21..791b18db49 100644 --- a/engines/mohawk/sound.cpp +++ b/engines/mohawk/sound.cpp @@ -141,6 +141,19 @@ Audio::SoundHandle *Sound::replaceSoundMyst(uint16 id, byte volume, bool loop) { && name.equals(_vm->getResourceName(ID_MSND, convertMystID(_handles[i].id)))) return &_handles[i].handle; + // The original engine also forces looping for those sounds + switch (id) { + case 2205: + case 2207: + case 5378: + case 7220: + case 9119: // Elevator engine sound in mechanical age is looping. + case 9120: + case 9327: + loop = true; + break; + } + stopSound(); return playSound(id, volume, loop); } diff --git a/engines/parallaction/graphics.h b/engines/parallaction/graphics.h index 2f86f3693b..3eea1e871a 100644 --- a/engines/parallaction/graphics.h +++ b/engines/parallaction/graphics.h @@ -28,6 +28,7 @@ #include "common/hashmap.h" #include "common/hash-str.h" #include "common/stream.h" +#include "common/array.h" #include "graphics/surface.h" diff --git a/engines/saga/actor.h b/engines/saga/actor.h index a4f475660d..d9d4b70168 100644 --- a/engines/saga/actor.h +++ b/engines/saga/actor.h @@ -650,7 +650,7 @@ private: public: #ifdef ACTOR_DEBUG #ifndef SAGA_DEBUG - you must also define SAGA_DEBUG + #error You must also define SAGA_DEBUG #endif //path debug - use with care struct DebugPoint { diff --git a/engines/saga/detection.cpp b/engines/saga/detection.cpp index 7a98fe4164..2f1b61eed8 100644 --- a/engines/saga/detection.cpp +++ b/engines/saga/detection.cpp @@ -67,9 +67,6 @@ int SagaEngine::getGameId() const { return _gameDescription->gameId; } uint32 SagaEngine::getFeatures() const { uint32 result = _gameDescription->features; - if (_gf_wyrmkeep) - result |= GF_WYRMKEEP; - return result; } diff --git a/engines/saga/detection_tables.h b/engines/saga/detection_tables.h index ab73fcba6e..a29d835a54 100644 --- a/engines/saga/detection_tables.h +++ b/engines/saga/detection_tables.h @@ -221,7 +221,7 @@ static const SAGAGameDescription gameDescriptions[] = { GUIO_NOSPEECH }, GID_ITE, - GF_WYRMKEEP | GF_SCENE_SUBSTITUTES | GF_MONO_MUSIC | GF_LE_VOICES, + 0, ITE_DEFAULT_SCENE, &ITE_Resources, ARRAYSIZE(ITEWINDEMO_GameFonts), @@ -247,7 +247,7 @@ static const SAGAGameDescription gameDescriptions[] = { GUIO_NOSPEECH }, GID_ITE, - GF_WYRMKEEP | GF_LE_VOICES, + 0, ITE_DEFAULT_SCENE, &ITE_Resources, ARRAYSIZE(ITEWINDEMO_GameFonts), @@ -273,7 +273,7 @@ static const SAGAGameDescription gameDescriptions[] = { GUIO_NONE }, GID_ITE, - GF_WYRMKEEP | GF_SCENE_SUBSTITUTES, + 0, ITE_DEFAULT_SCENE, &ITE_Resources, ARRAYSIZE(ITEWINDEMO_GameFonts), @@ -299,7 +299,7 @@ static const SAGAGameDescription gameDescriptions[] = { GUIO_NONE }, GID_ITE, - GF_WYRMKEEP | GF_8BIT_UNSIGNED_PCM, + GF_8BIT_UNSIGNED_PCM, ITE_DEFAULT_SCENE, &ITE_Resources, ARRAYSIZE(ITEWINDEMO_GameFonts), @@ -356,7 +356,7 @@ static const SAGAGameDescription gameDescriptions[] = { GUIO_NONE }, GID_ITE, - GF_WYRMKEEP, + 0, ITE_DEFAULT_SCENE, &ITE_Resources, ARRAYSIZE(ITEWINDEMO_GameFonts), @@ -388,7 +388,7 @@ static const SAGAGameDescription gameDescriptions[] = { GUIO_NONE }, GID_ITE, - GF_WYRMKEEP, + 0, ITE_DEFAULT_SCENE, &ITE_Resources, ARRAYSIZE(ITE_GameFonts), @@ -418,7 +418,7 @@ static const SAGAGameDescription gameDescriptions[] = { GUIO_NONE }, GID_ITE, - GF_WYRMKEEP, + 0, ITE_DEFAULT_SCENE, &ITE_Resources, ARRAYSIZE(ITE_GameFonts), diff --git a/engines/saga/introproc_ite.cpp b/engines/saga/introproc_ite.cpp index 87fd48e2d2..9248f2b530 100644 --- a/engines/saga/introproc_ite.cpp +++ b/engines/saga/introproc_ite.cpp @@ -179,21 +179,22 @@ enum { EventColumns *Scene::ITEQueueCredits(int delta_time, int duration, int n_credits, const IntroCredit credits[]) { int game; Common::Language lang; + bool hasWyrmkeepCredits = (Common::File::exists("credit3n.dlt") || // PC + Common::File::exists("credit3m.dlt")); // Mac // The assumption here is that all WyrmKeep versions have the same // credits, regardless of which operating system they're for. lang = _vm->getLanguage(); - if (_vm->getFeatures() & GF_WYRMKEEP) { + if (hasWyrmkeepCredits) game = kITEWyrmKeep; - } else if (_vm->getPlatform() == Common::kPlatformMacintosh) { + else if (_vm->getPlatform() == Common::kPlatformMacintosh) game = kITEMac; - } else if (_vm->getFeatures() & GF_EXTRA_ITE_CREDITS) { + else if (_vm->getFeatures() & GF_EXTRA_ITE_CREDITS) game = kITEPCCD; - } else { + else game = kITEPC; - } int line_spacing = 0; int paragraph_spacing; @@ -303,6 +304,11 @@ int Scene::SC_ITEIntroAnimProc(int param, void *refCon) { int Scene::ITEIntroAnimProc(int param) { Event event; EventColumns *eventColumns; + bool isMac = _vm->getPlatform() == Common::kPlatformMacintosh; + bool isMultiCD = _vm->getPlatform() == Common::kPlatformUnknown; + bool hasWyrmkeepCredits = (Common::File::exists("credit3n.dlt") || // PC + Common::File::exists("credit3m.dlt")); // Mac + bool isDemo = Common::File::exists("scriptsd.rsc"); switch (param) { case SCENE_BEGIN:{ @@ -324,19 +330,10 @@ int Scene::ITEIntroAnimProc(int param) { // playback int lastAnim; - if (_vm->getFeatures() & GF_WYRMKEEP) { - if (_vm->getPlatform() == Common::kPlatformMacintosh) { - lastAnim = 3; - } else { - lastAnim = 2; - } - } else { - if (_vm->getPlatform() == Common::kPlatformMacintosh) { - lastAnim = 4; - } else { - lastAnim = 5; - } - } + if (hasWyrmkeepCredits || isMultiCD || isDemo) + lastAnim = isMac ? 3 : 2; + else + lastAnim = isMac ? 4 : 5; for (int i = 0; i < lastAnim; i++) _vm->_anim->link(i, i+1); diff --git a/engines/saga/music.cpp b/engines/saga/music.cpp index 21f3cc489e..49d3f91d77 100644 --- a/engines/saga/music.cpp +++ b/engines/saga/music.cpp @@ -287,7 +287,12 @@ void Music::play(uint32 resourceId, MusicFlags flags) { if (_vm->isBigEndian()) musicFlags &= ~Audio::FLAG_LITTLE_ENDIAN; - if (_vm->getFeatures() & GF_MONO_MUSIC) + // The newer ITE Mac demo version contains a music file, but it has mono music. + // This is the only music file that is about 7MB, whereas all the other ones + // are much larger. Thus, we use this simple heuristic to determine if we got + // mono music in the ITE demos or not. + if (!strcmp(_digitalMusicContext->fileName(), "musicd.rsc") && + _digitalMusicContext->fileSize() < 8000000) musicFlags &= ~Audio::FLAG_STEREO; audioStream = Audio::makeRawStream(musicStream, 11025, musicFlags, DisposeAfterUse::YES); @@ -368,10 +373,12 @@ void Music::play(uint32 resourceId, MusicFlags flags) { void Music::pause() { _player->pause(); + _player->setVolume(0); } void Music::resume() { _player->resume(); + _player->setVolume(_vm->_musicVolume); } void Music::stop() { diff --git a/engines/saga/resource.cpp b/engines/saga/resource.cpp index 72b021309c..1b0dfa2f22 100644 --- a/engines/saga/resource.cpp +++ b/engines/saga/resource.cpp @@ -162,12 +162,6 @@ bool Resource::createContexts() { uint16 voiceFileAddType; }; - - // If the Wyrmkeep credits file is found, set the Wyrmkeep version flag to true - if (Common::File::exists("credit3n.dlt")) { - _vm->_gf_wyrmkeep = true; - } - for (const ADGameFileDescription *gameFileDescription = _vm->getFilesDescriptions(); gameFileDescription->fileName; gameFileDescription++) { addContext(gameFileDescription->fileName, gameFileDescription->fileType); diff --git a/engines/saga/saga.cpp b/engines/saga/saga.cpp index d168605e99..6e272d37c0 100644 --- a/engines/saga/saga.cpp +++ b/engines/saga/saga.cpp @@ -72,9 +72,8 @@ SagaEngine::SagaEngine(OSystem *syst, const SAGAGameDescription *gameDesc) _readingSpeed = 0; _copyProtection = false; - _gf_wyrmkeep = false; _musicWasPlaying = false; - + _hasITESceneSubstitutes = false; _sndRes = NULL; _sound = NULL; @@ -211,9 +210,9 @@ Common::Error SagaEngine::run() { _subtitlesEnabled = ConfMan.getBool("subtitles"); _readingSpeed = getTalkspeed(); _copyProtection = ConfMan.getBool("copy_protection"); - _gf_wyrmkeep = false; _musicWasPlaying = false; _isIHNMDemo = Common::File::exists("music.res"); + _hasITESceneSubstitutes = Common::File::exists("boarhall.bbm"); if (_readingSpeed > 3) _readingSpeed = 0; diff --git a/engines/saga/saga.h b/engines/saga/saga.h index 23258e1277..336883680a 100644 --- a/engines/saga/saga.h +++ b/engines/saga/saga.h @@ -137,16 +137,12 @@ enum GameFileTypes { }; enum GameFeatures { - GF_WYRMKEEP = 1 << 0, - GF_ITE_FLOPPY = 1 << 1, - GF_SCENE_SUBSTITUTES = 1 << 2, + GF_ITE_FLOPPY = 1 << 0, #if 0 - GF_OLD_ITE_DOS = 1 << 3, // Currently unused + GF_OLD_ITE_DOS = 1 << 1, // Currently unused #endif - GF_MONO_MUSIC = 1 << 4, - GF_EXTRA_ITE_CREDITS = 1 << 5, - GF_LE_VOICES = 1 << 6, - GF_8BIT_UNSIGNED_PCM = 1 << 7 + GF_EXTRA_ITE_CREDITS = 1 << 2, + GF_8BIT_UNSIGNED_PCM = 1 << 3 }; enum VerbTypeIds { @@ -532,9 +528,9 @@ public: int _readingSpeed; bool _copyProtection; - bool _gf_wyrmkeep; bool _musicWasPlaying; bool _isIHNMDemo; + bool _hasITESceneSubstitutes; SndRes *_sndRes; Sound *_sound; diff --git a/engines/saga/scene.cpp b/engines/saga/scene.cpp index 66ee8f4504..61e62d5626 100644 --- a/engines/saga/scene.cpp +++ b/engines/saga/scene.cpp @@ -451,7 +451,7 @@ void Scene::changeScene(int16 sceneNumber, int actorsEntrance, SceneTransitionTy // This is used for latter ITE demos where all places on world map except // Tent Faire are substituted with LBM picture and short description - if (_vm->getFeatures() & GF_SCENE_SUBSTITUTES) { + if (_vm->_hasITESceneSubstitutes) { for (int i = 0; i < ARRAYSIZE(sceneSubstitutes); i++) { if (sceneSubstitutes[i].sceneId == sceneNumber) { Surface bbmBuffer; diff --git a/engines/saga/sndres.cpp b/engines/saga/sndres.cpp index 2433c93e93..add34e22a2 100644 --- a/engines/saga/sndres.cpp +++ b/engines/saga/sndres.cpp @@ -262,9 +262,12 @@ bool SndRes::load(ResourceContext *context, uint32 resourceId, SoundBuffer &buff buffer.flags |= Audio::FLAG_UNSIGNED; buffer.flags &= ~Audio::FLAG_16BITS; } else { - // Voice files in newer ITE demo versions are OKI ADPCM (VOX) encoded - if (!uncompressedSound && !scumm_stricmp(context->fileName(), "voicesd.rsc")) + // Voice files in newer ITE demo versions are OKI ADPCM (VOX) encoded. + // These are LE in all the Windows and Mac demos + if (!uncompressedSound && !scumm_stricmp(context->fileName(), "voicesd.rsc")) { resourceType = kSoundVOX; + buffer.flags |= Audio::FLAG_LITTLE_ENDIAN; + } } } buffer.buffer = NULL; @@ -272,8 +275,6 @@ bool SndRes::load(ResourceContext *context, uint32 resourceId, SoundBuffer &buff // Check for LE sounds if (!context->isBigEndian()) buffer.flags |= Audio::FLAG_LITTLE_ENDIAN; - if ((context->fileType() & GAME_VOICEFILE) && (_vm->getFeatures() & GF_LE_VOICES)) - buffer.flags |= Audio::FLAG_LITTLE_ENDIAN; // Older Mac versions of ITE were Macbinary packed int soundOffset = (context->fileType() & GAME_MACBINARY) ? 36 : 0; diff --git a/engines/savestate.cpp b/engines/savestate.cpp index 551c39b880..0b187ce630 100644 --- a/engines/savestate.cpp +++ b/engines/savestate.cpp @@ -24,49 +24,34 @@ #include "graphics/surface.h" #include "common/textconsole.h" -void SaveStateDescriptor::setThumbnail(Graphics::Surface *t) { - if (_thumbnail.get() == t) - return; - - _thumbnail = Common::SharedPtr<Graphics::Surface>(t, Graphics::SharedPtrSurfaceDeleter()); +SaveStateDescriptor::SaveStateDescriptor() + // FIXME: default to 0 (first slot) or to -1 (invalid slot) ? + : _slot(-1), _description(), _isDeletable(true), _isWriteProtected(false), + _saveDate(), _saveTime(), _playTime(), _thumbnail() { } -bool SaveStateDescriptor::getBool(const Common::String &key) const { - if (contains(key)) { - const Common::String value = getVal(key); - bool valueAsBool; - if (Common::parseBool(value, valueAsBool)) - return valueAsBool; - error("SaveStateDescriptor: %s '%s' has unknown value '%s' for boolean '%s'", - save_slot().c_str(), description().c_str(), value.c_str(), key.c_str()); - } - return false; +SaveStateDescriptor::SaveStateDescriptor(int s, const Common::String &d) + : _slot(s), _description(d), _isDeletable(true), _isWriteProtected(false), + _saveDate(), _saveTime(), _playTime(), _thumbnail() { } -void SaveStateDescriptor::setDeletableFlag(bool state) { - setVal("is_deletable", state ? "true" : "false"); -} +void SaveStateDescriptor::setThumbnail(Graphics::Surface *t) { + if (_thumbnail.get() == t) + return; -void SaveStateDescriptor::setWriteProtectedFlag(bool state) { - setVal("is_write_protected", state ? "true" : "false"); + _thumbnail = Common::SharedPtr<Graphics::Surface>(t, Graphics::SharedPtrSurfaceDeleter()); } void SaveStateDescriptor::setSaveDate(int year, int month, int day) { - Common::String buffer; - buffer = Common::String::format("%.2d.%.2d.%.4d", day, month, year); - setVal("save_date", buffer); + _saveDate = Common::String::format("%.2d.%.2d.%.4d", day, month, year); } void SaveStateDescriptor::setSaveTime(int hour, int min) { - Common::String buffer; - buffer = Common::String::format("%.2d:%.2d", hour, min); - setVal("save_time", buffer); + _saveTime = Common::String::format("%.2d:%.2d", hour, min); } void SaveStateDescriptor::setPlayTime(int hours, int minutes) { - Common::String buffer; - buffer = Common::String::format("%.2d:%.2d", hours, minutes); - setVal("play_time", buffer); + _playTime = Common::String::format("%.2d:%.2d", hours, minutes); } void SaveStateDescriptor::setPlayTime(uint32 msecs) { diff --git a/engines/savestate.h b/engines/savestate.h index df01732058..6cbdb22edf 100644 --- a/engines/savestate.h +++ b/engines/savestate.h @@ -24,7 +24,7 @@ #define ENGINES_SAVESTATE_H #include "common/array.h" -#include "common/hash-str.h" +#include "common/str.h" #include "common/ptr.h" @@ -33,65 +33,60 @@ struct Surface; } /** - * A hashmap describing details about a given save state. - * TODO - * Guaranteed to contain save_slot and description values. - * Additional ideas: Playtime, creation date, thumbnail, ... + * Object describing a save state. + * + * This at least includes the save slot number and a human readable + * description of the save state. + * + * Further possibilites are a thumbnail, play time, creation date, + * creation time, delete protected, write protection. */ -class SaveStateDescriptor : public Common::StringMap { -protected: - Common::SharedPtr<Graphics::Surface> _thumbnail; // can be 0 - +class SaveStateDescriptor { public: - SaveStateDescriptor() : _thumbnail() { - setVal("save_slot", "-1"); // FIXME: default to 0 (first slot) or to -1 (invalid slot) ? - setVal("description", ""); - } - - SaveStateDescriptor(int s, const Common::String &d) : _thumbnail() { - setVal("save_slot", Common::String::format("%d", s)); - setVal("description", d); - } + SaveStateDescriptor(); + SaveStateDescriptor(int s, const Common::String &d); - SaveStateDescriptor(const Common::String &s, const Common::String &d) : _thumbnail() { - setVal("save_slot", s); - setVal("description", d); - } - - /** The saveslot id, as it would be passed to the "-x" command line switch. */ - Common::String &save_slot() { return getVal("save_slot"); } + /** + * @param slot The saveslot id, as it would be passed to the "-x" command line switch. + */ + void setSaveSlot(int slot) { _slot = slot; } - /** The saveslot id, as it would be passed to the "-x" command line switch (read-only variant). */ - const Common::String &save_slot() const { return getVal("save_slot"); } + /** + * @return The saveslot id, as it would be passed to the "-x" command line switch. + */ + int getSaveSlot() const { return _slot; } - /** A human readable description of the save state. */ - Common::String &description() { return getVal("description"); } + /** + * @param desc A human readable description of the save state. + */ + void setDescription(const Common::String &desc) { _description = desc; } - /** A human readable description of the save state (read-only variant). */ - const Common::String &description() const { return getVal("description"); } + /** + * @return A human readable description of the save state. + */ + const Common::String &getDescription() const { return _description; } /** Optional entries only included when querying via MetaEngine::querySaveMetaInfo */ /** - * Returns the value of a given key as boolean. - * It accepts 'true', 'yes' and '1' for true and - * 'false', 'no' and '0' for false. - * (FIXME:) On unknown value it errors out ScummVM. - * On unknown key it returns false as default. + * Defines whether the save state is allowed to be deleted. */ - bool getBool(const Common::String &key) const; + void setDeletableFlag(bool state) { _isDeletable = state; } /** - * Sets the 'is_deletable' key, which indicates if the - * given savestate is safe for deletion. + * Queries whether the save state is allowed to be deleted. */ - void setDeletableFlag(bool state); + bool getDeletableFlag() const { return _isDeletable; } /** - * Sets the 'is_write_protected' key, which indicates if the - * given savestate can be overwritten or not + * Defines whether the save state is write protected. */ - void setWriteProtectedFlag(bool state); + void setWriteProtectedFlag(bool state) { _isWriteProtected = state; } + + /** + * Queries whether the save state is write protected. + */ + bool getWriteProtectedFlag() const { return _isWriteProtected; } /** * Return a thumbnail graphics surface representing the savestate visually. @@ -109,24 +104,100 @@ public: void setThumbnail(Graphics::Surface *t); /** - * Sets the 'save_date' key properly, based on the given values. + * Sets the date the save state was created. + * + * @param year Year of creation. + * @param month Month of creation. + * @param day Day of creation. */ void setSaveDate(int year, int month, int day); /** - * Sets the 'save_time' key properly, based on the given values. + * Queries a human readable description of the date the save state was created. + * + * This will return an empty string in case the value is not set. + */ + const Common::String &getSaveDate() const { return _saveDate; } + + /** + * Sets the time the save state was created. + * + * @param hour Hour of creation. + * @param min Minute of creation. */ void setSaveTime(int hour, int min); /** - * Sets the 'play_time' key properly, based on the given values. + * Queries a human readable description of the time the save state was created. + * + * This will return an empty string in case the value is not set. + */ + const Common::String &getSaveTime() const { return _saveTime; } + + /** + * Sets the time the game was played before the save state was created. + * + * @param hours How many hours the user played the game so far. + * @param min How many minutes the user played the game so far. */ void setPlayTime(int hours, int minutes); /** - * Sets the 'play_time' key properly, based on the given value. + * Sets the time the game was played before the save state was created. + * + * @param msecs How many milliseconds the user played the game so far. */ void setPlayTime(uint32 msecs); + + /** + * Queries a human readable description of the time the game was played + * before the save state was created. + * + * This will return an empty string in case the value is not set. + */ + const Common::String &getPlayTime() const { return _playTime; } + +private: + /** + * The saveslot id, as it would be passed to the "-x" command line switch. + */ + int _slot; + + /** + * A human readable description of the save state. + */ + Common::String _description; + + /** + * Whether the save state can be deleted. + */ + bool _isDeletable; + + /** + * Whether the save state is write protected. + */ + bool _isWriteProtected; + + /** + * Human readable description of the date the save state was created. + */ + Common::String _saveDate; + + /** + * Human readable description of the time the save state was created. + */ + Common::String _saveTime; + + /** + * Human readable description of the time the game was played till the + * save state was created. + */ + Common::String _playTime; + + /** + * The thumbnail of the save state. + */ + Common::SharedPtr<Graphics::Surface> _thumbnail; }; /** List of savestates. */ diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h index 6641f243e6..3b18a1f68d 100644 --- a/engines/sci/detection_tables.h +++ b/engines/sci/detection_tables.h @@ -3150,6 +3150,15 @@ static const struct ADGameDescription SciGameDescriptions[] = { AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + + // Slater & Charlie Go Camping - English DOS/Windows (Sierra Originals) + {"slater", "", { + {"resource.000", 0, "d7b4cc8e2c0b3a4768f8dfb5de27f206", 2256126}, + {"resource.map", 0, "21f85414124dc23e54544a5536dc35cd", 4044}, + {"resource.msg", 0, "c44f51fb955eae266fecf360ebcd5ad2", 1132}, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + // Space Quest 1 VGA Remake - English Amiga (from www.back2roots.org) // SCI interpreter version 1.000.510 (just a guess) {"sq1sci", "SCI", { diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp index 9f10691767..b383f88840 100644 --- a/engines/sci/engine/kstring.cpp +++ b/engines/sci/engine/kstring.cpp @@ -336,8 +336,9 @@ reg_t kFormat(EngineState *s, int argc, reg_t *argv) { if (align >= 0) while (str_leng-- > 1) *target++ = ' '; /* Format into the text */ - - *target++ = arguments[paramindex++]; + char argchar = arguments[paramindex++]; + if (argchar) + *target++ = argchar; mode = 0; } break; @@ -730,6 +731,10 @@ reg_t kString(EngineState *s, int argc, reg_t *argv) { case 8: { // Dup const char *rawString = 0; uint32 size = 0; + reg_t stringHandle; + // We allocate the new string first because if the StringTable needs to + // grow, our rawString pointer will be invalidated + SciString *dupString = s->_segMan->allocateString(&stringHandle); if (argv[1].segment == s->_segMan->getStringSegmentId()) { SciString *string = s->_segMan->lookupString(argv[1]); @@ -741,8 +746,6 @@ reg_t kString(EngineState *s, int argc, reg_t *argv) { size = string.size() + 1; } - reg_t stringHandle; - SciString *dupString = s->_segMan->allocateString(&stringHandle); dupString->setSize(size); for (uint32 i = 0; i < size; i++) diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp index e61da20f97..b2cde47f4a 100644 --- a/engines/sci/engine/workarounds.cpp +++ b/engines/sci/engine/workarounds.cpp @@ -283,6 +283,8 @@ const SciWorkaroundEntry kGraphSaveBox_workarounds[] = { // gameID, room,script,lvl, object-name, method-name, call,index, workaround const SciWorkaroundEntry kGraphRestoreBox_workarounds[] = { + { GID_LSL6, -1, 86, 0, "LL6Inv", "show", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // happens when restoring, is called with hunk segment, but hunk is not allocated at that time + // ^^ TODO: check, if this is really a script error or an issue with our restore code { GID_LSL6, -1, 86, 0, "LL6Inv", "hide", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // happens during the game, gets called with 1 extra parameter { GID_SQ5, 850, 850, 0, NULL, "changeState", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // happens while playing Battle Cruiser (invalid segment) - bug #3056811 SCI_WORKAROUNDENTRY_TERMINATOR diff --git a/engines/scumm/charset.cpp b/engines/scumm/charset.cpp index eaae64dc77..8558da397e 100644 --- a/engines/scumm/charset.cpp +++ b/engines/scumm/charset.cpp @@ -49,35 +49,28 @@ void ScummEngine::loadCJKFont() { _newLineCharacter = 0; if (_game.version <= 5 && _game.platform == Common::kPlatformFMTowns && _language == Common::JA_JPN) { // FM-TOWNS v3 / v5 Kanji -#ifdef DISABLE_TOWNS_DUAL_LAYER_MODE +#if defined(DISABLE_TOWNS_DUAL_LAYER_MODE) || !defined(USE_RGB_COLOR) GUIErrorMessage("FM-Towns Kanji font drawing requires dual graphics layer support which is disabled in this build"); error("FM-Towns Kanji font drawing requires dual graphics layer support which is disabled in this build"); #else // use FM-TOWNS font rom, since game files don't have kanji font resources - _cjkFont = Graphics::FontSJIS::createFont(Common::kPlatformFMTowns); + _cjkFont = Graphics::FontSJIS::createFont(_game.platform); if (!_cjkFont) error("SCUMM::Font: Could not open file 'FMT_FNT.ROM'"); _textSurfaceMultiplier = 2; _useCJKMode = true; #endif } else if (_game.id == GID_LOOM && _game.platform == Common::kPlatformPCEngine && _language == Common::JA_JPN) { - int numChar = 3418; - _2byteWidth = 12; - _2byteHeight = 12; +#ifdef USE_RGB_COLOR // use PC-Engine System Card, since game files don't have kanji font resources - if (!fp.open("pce.cdbios")) { - error("SCUMM::Font: Could not open System Card pce.cdbios"); - } else { - _useCJKMode = true; - debug(2, "Loading PC-Engine System Card"); - - // A 0x200 byte header can be present at the beginning of the syscard. Seek past it too. - fp.seek((fp.size() & 0x200) ? 0x30200 : 0x30000); + _cjkFont = Graphics::FontSJIS::createFont(_game.platform); + if (!_cjkFont) + error("SCUMM::Font: Could not open file 'pce.cdbios'"); - _2byteFontPtr = new byte[_2byteWidth * _2byteHeight * numChar / 8]; - fp.read(_2byteFontPtr, _2byteWidth * _2byteHeight * numChar / 8); - fp.close(); - } + _cjkFont->setDrawingMode(Graphics::FontSJIS::kShadowMode); + _2byteWidth = _2byteHeight = 12; + _useCJKMode = true; +#endif } else if (_game.id == GID_MONKEY && _game.platform == Common::kPlatformSegaCD && _language == Common::JA_JPN) { int numChar = 1413; _2byteWidth = 16; @@ -161,71 +154,16 @@ void ScummEngine::loadCJKFont() { } } -static int SJIStoPCEChunk(int f, int s) { //converts sjis code to pce font offset - // rangeTbl maps SJIS char-codes to the PCE System Card font rom. - // Each pair {<upperBound>,<lowerBound>} in the array represents a SJIS range. - const int rangeCnt = 45; - static const uint16 rangeTbl[rangeCnt][2] = { - // Symbols - {0x8140,0x817E},{0x8180,0x81AC}, - // 0-9 - {0x824F,0x8258}, - // Latin upper - {0x8260,0x8279}, - // Latin lower - {0x8281,0x829A}, - // Kana - {0x829F,0x82F1},{0x8340,0x837E},{0x8380,0x8396}, - // Greek upper - {0x839F,0x83B6}, - // Greek lower - {0x83BF,0x83D6}, - // Cyrillic upper - {0x8440,0x8460}, - // Cyrillic lower - {0x8470,0x847E},{0x8480,0x8491}, - // Kanji - {0x889F,0x88FC}, - {0x8940,0x897E},{0x8980,0x89FC}, - {0x8A40,0x8A7E},{0x8A80,0x8AFC}, - {0x8B40,0x8B7E},{0x8B80,0x8BFC}, - {0x8C40,0x8C7E},{0x8C80,0x8CFC}, - {0x8D40,0x8D7E},{0x8D80,0x8DFC}, - {0x8E40,0x8E7E},{0x8E80,0x8EFC}, - {0x8F40,0x8F7E},{0x8F80,0x8FFC}, - {0x9040,0x907E},{0x9080,0x90FC}, - {0x9140,0x917E},{0x9180,0x91FC}, - {0x9240,0x927E},{0x9280,0x92FC}, - {0x9340,0x937E},{0x9380,0x93FC}, - {0x9440,0x947E},{0x9480,0x94FC}, - {0x9540,0x957E},{0x9580,0x95FC}, - {0x9640,0x967E},{0x9680,0x96FC}, - {0x9740,0x977E},{0x9780,0x97FC}, - {0x9840,0x9872} - }; - - int ch = (f << 8) | (s & 0xFF); - int offset = 0; - for (int i = 0; i < rangeCnt; ++i) { - if (ch >= rangeTbl[i][0] && ch <= rangeTbl[i][1]) - return offset + ch - rangeTbl[i][0]; - offset += rangeTbl[i][1] - rangeTbl[i][0] + 1; - } - - debug(4, "Invalid Char: 0x%x", ch); - return 0; -} - byte *ScummEngine::get2byteCharPtr(int idx) { + if (_game.platform == Common::kPlatformFMTowns || _game.platform == Common::kPlatformPCEngine) + return 0; + switch (_language) { case Common::KO_KOR: idx = ((idx % 256) - 0xb0) * 94 + (idx / 256) - 0xa1; break; case Common::JA_JPN: - if (_game.id == GID_LOOM && _game.platform == Common::kPlatformPCEngine) { - idx = SJIStoPCEChunk((idx % 256), (idx / 256)); - return _2byteFontPtr + (_2byteWidth * _2byteHeight / 8) * idx; - } else if (_game.id == GID_MONKEY && _game.platform == Common::kPlatformSegaCD && _language == Common::JA_JPN) { + if (_game.id == GID_MONKEY && _game.platform == Common::kPlatformSegaCD && _language == Common::JA_JPN) { // init pointer to charset resource if (_2byteFontPtr[0] == 0xFF) { int charsetId = 5; @@ -314,7 +252,7 @@ CharsetRenderer::~CharsetRenderer() { CharsetRendererCommon::CharsetRendererCommon(ScummEngine *vm) : CharsetRenderer(vm), _bytesPerPixel(0), _fontHeight(0), _numChars(0) { - _shadowMode = kNoShadowMode; + _shadowMode = false; _shadowColor = 0; } @@ -362,17 +300,9 @@ void CharsetRendererV3::setCurID(int32 id) { } int CharsetRendererCommon::getFontHeight() { - if (_vm->_useCJKMode) { - if (_vm->_game.platform == Common::kPlatformFMTowns) { - static const uint8 sjisFontHeightM1[] = { 0, 8, 9, 8, 9, 8, 9, 0, 0, 0 }; - static const uint8 sjisFontHeightM2[] = { 0, 8, 9, 9, 9, 8, 9, 9, 9, 8 }; - static const uint8 sjisFontHeightI4[] = { 0, 8, 9, 9, 9, 8, 8, 8, 8, 8 }; - const uint8 *htbl = (_vm->_game.id == GID_MONKEY) ? sjisFontHeightM1 : ((_vm->_game.id == GID_INDY4) ? sjisFontHeightI4 : sjisFontHeightM2); - return (_vm->_game.version == 3) ? 8 : htbl[_curId]; - } else { - return MAX(_vm->_2byteHeight + 1, _fontHeight); - } - } else + if (_vm->_useCJKMode) + return MAX(_vm->_2byteHeight + 1, _fontHeight); + else return _fontHeight; } @@ -380,57 +310,16 @@ int CharsetRendererCommon::getFontHeight() { int CharsetRendererClassic::getCharWidth(uint16 chr) { int spacing = 0; - if (_vm->_useCJKMode) { - if (_vm->_game.platform == Common::kPlatformFMTowns) { - if ((chr & 0xff00) == 0xfd00) { - chr &= 0xff; - } else if (chr >= 256) { - spacing = 8; - } else if (useTownsFontRomCharacter(chr)) { - spacing = 4; - } + if (_vm->_useCJKMode && chr >= 0x80) + return _vm->_2byteWidth / 2; - if (spacing) { - if (_vm->_game.id == GID_MONKEY) { - spacing++; - if (_curId == 2) - spacing++; - } else if (_vm->_game.id != GID_INDY4 && _curId == 1) { - spacing++; - } - } - - } else if (chr >= 0x80) { - return _vm->_2byteWidth / 2; - } - } - - if (!spacing) { - int offs = READ_LE_UINT32(_fontPtr + chr * 4 + 4); - if (offs) { - spacing = _fontPtr[offs] + (signed char)_fontPtr[offs + 2]; - } - } + int offs = READ_LE_UINT32(_fontPtr + chr * 4 + 4); + if (offs) + spacing = _fontPtr[offs] + (signed char)_fontPtr[offs + 2]; return spacing; } -bool CharsetRendererClassic::useTownsFontRomCharacter(uint16 chr) { -#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE - if (_vm->_game.platform != Common::kPlatformFMTowns || !_vm->_useCJKMode) - return false; - - if (chr < 128) { - if (((_vm->_game.id == GID_MONKEY2 && _curId != 0) || (_vm->_game.id == GID_INDY4 && _curId != 3)) && (chr > 31 && chr != 94 && chr != 95 && chr != 126 && chr != 127)) - return true; - return false; - } - return true; -#else - return false; -#endif -} - int CharsetRenderer::getStringWidth(int arg, const byte *text) { int pos = 0; int width = 1; @@ -608,22 +497,51 @@ void CharsetRenderer::addLinebreaks(int a, byte *str, int pos, int maxwidth) { int CharsetRendererV3::getCharWidth(uint16 chr) { int spacing = 0; - if (_vm->_useCJKMode) { - if (_vm->_game.platform == Common::kPlatformFMTowns) { - if (chr >= 256) - spacing = 8; - else if (chr >= 128) - spacing = 4; - } else if (chr & 0x80) { - spacing = _vm->_2byteWidth / 2; + if (_vm->_useCJKMode && (chr & 0x80)) + spacing = _vm->_2byteWidth / 2; + + if (!spacing) + spacing = *(_widthTable + chr); + + return spacing; +} + +void CharsetRendererV3::enableShadow(bool enable) { + _shadowColor = 0; + _shadowMode = enable; +} + +void CharsetRendererV3::drawBits1(const Graphics::Surface &s, byte *dst, const byte *src, int drawTop, int width, int height, uint8 bitDepth) { + int y, x; + byte bits = 0; + uint8 col = _color; + int pitch = s.pitch - width * bitDepth; + byte *dst2 = dst + s.pitch; + + for (y = 0; y < height && y + drawTop < s.h; y++) { + for (x = 0; x < width; x++) { + if ((x % 8) == 0) + bits = *src++; + if ((bits & revBitMask(x % 8)) && y + drawTop >= 0) { + if (_shadowMode) + dst[1] = dst2[0] = dst2[1] = _shadowColor; + dst[0] = col; + } + dst += bitDepth; + dst2 += bitDepth; } - } - if (!spacing) { - spacing = *(_widthTable + chr); + dst += pitch; + dst2 += pitch; } +} - return spacing; +int CharsetRendererV3::getDrawWidthIntern(uint16 chr) { + return getCharWidth(chr); +} + +int CharsetRendererV3::getDrawHeightIntern(uint16) { + return 8; } void CharsetRendererV3::setColor(byte color) { @@ -662,43 +580,6 @@ void CharsetRendererPCE::setColor(byte color) { } #endif -void CharsetRendererCommon::enableShadow(bool enable) { - if (enable) { - if (_vm->_game.platform == Common::kPlatformFMTowns) { - _shadowColor = 8; -#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE - _shadowColor = _vm->_game.version == 5 ? _vm->_townsCharsetColorMap[0] : 0x88; - if (_vm->_cjkFont) { - if (_vm->_game.version == 5) { - if (((_vm->_game.id == GID_MONKEY) && (_curId == 2 || _curId == 4 || _curId == 6)) || - ((_vm->_game.id == GID_MONKEY2) && (_curId != 1 && _curId != 5 && _curId != 9)) || - ((_vm->_game.id == GID_INDY4) && (_curId == 2 || _curId == 3 || _curId == 4))) { - _vm->_cjkFont->setDrawingMode(Graphics::FontSJIS::kOutlineMode); - } else { - _vm->_cjkFont->setDrawingMode(Graphics::FontSJIS::kDefaultMode); - } - _vm->_cjkFont->toggleFlippedMode((_vm->_game.id == GID_MONKEY || _vm->_game.id == GID_MONKEY2) && _curId == 3); - } else { - _vm->_cjkFont->setDrawingMode(Graphics::FontSJIS::kShadowMode); - } - } -#endif - _shadowMode = kFMTOWNSShadowMode; - } else { - _shadowColor = 0; - _shadowMode = kNormalShadowMode; - } - } else { -#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE - if (_vm->_cjkFont) { - _vm->_cjkFont->setDrawingMode(Graphics::FontSJIS::kDefaultMode); - _vm->_cjkFont->toggleFlippedMode(false); - } -#endif - _shadowMode = kNoShadowMode; - } -} - void CharsetRendererV3::printChar(int chr, bool ignoreCharsetMask) { // WORKAROUND for bug #1509509: Indy3 Mac does not show black // characters (such as in the grail diary) if ignoreCharsetMask @@ -721,33 +602,19 @@ void CharsetRendererV3::printChar(int chr, bool ignoreCharsetMask) { if (chr == '@') return; -#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE - if (_vm->_useCJKMode && chr > 127) { - if (_vm->_game.platform == Common::kPlatformFMTowns) { - charPtr = 0; - width = _vm->_cjkFont->getCharWidth(chr); - height = _vm->_cjkFont->getFontHeight(); - } else { - width = _vm->_2byteWidth; - height = _vm->_2byteHeight; - charPtr = _vm->get2byteCharPtr(chr); - } - } else -#endif - { - charPtr = _fontPtr + chr * 8; - width = getCharWidth(chr); - height = 8; - } + charPtr = (_vm->_useCJKMode && chr > 127) ? _vm->get2byteCharPtr(chr) : _fontPtr + chr * 8; + width = getDrawWidthIntern(chr); + height = getDrawHeightIntern(chr); + setDrawCharIntern(chr); + + origWidth = width; + origHeight = height; // Clip at the right side (to avoid drawing "outside" the screen bounds). if (_left + origWidth > _right + 1) return; - origWidth = width; - origHeight = height; - - if (_shadowMode != kNoShadowMode) { + if (_shadowMode) { width++; height++; } @@ -769,30 +636,17 @@ void CharsetRendererV3::printChar(int chr, bool ignoreCharsetMask) { _textScreenID = vs->number; } - if ( -#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE - (_vm->_game.platform != Common::kPlatformFMTowns) && -#endif - (ignoreCharsetMask || !vs->hasTwoBuffers)) { + if ((ignoreCharsetMask || !vs->hasTwoBuffers)) { dst = vs->getPixels(_left, drawTop); - if (charPtr) - drawBits1(*vs, dst, charPtr, drawTop, origWidth, origHeight, vs->format.bytesPerPixel); -#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE - else if (_vm->_cjkFont) - _vm->_cjkFont->drawChar(*vs, chr, _left, drawTop, _color, _shadowColor); -#endif + drawBits1(*vs, dst, charPtr, drawTop, origWidth, origHeight, vs->format.bytesPerPixel); } else { dst = (byte *)_vm->_textSurface.getBasePtr(_left * _vm->_textSurfaceMultiplier, _top * _vm->_textSurfaceMultiplier); - if (charPtr) - drawBits1(_vm->_textSurface, dst, charPtr, drawTop, origWidth, origHeight, _vm->_textSurface.format.bytesPerPixel, (_vm->_textSurfaceMultiplier == 2 && !is2byte)); -#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE - else if (_vm->_cjkFont) - _vm->_cjkFont->drawChar(_vm->_textSurface, chr, _left * _vm->_textSurfaceMultiplier, _top * _vm->_textSurfaceMultiplier, _color, _shadowColor); -#endif - if (is2byte) { - origWidth /= _vm->_textSurfaceMultiplier; - height /= _vm->_textSurfaceMultiplier; - } + drawBits1(_vm->_textSurface, dst, charPtr, drawTop, origWidth, origHeight, _vm->_textSurface.format.bytesPerPixel); + } + + if (is2byte) { + origWidth /= _vm->_textSurfaceMultiplier; + height /= _vm->_textSurfaceMultiplier; } if (_str.left > _left) @@ -802,7 +656,7 @@ void CharsetRendererV3::printChar(int chr, bool ignoreCharsetMask) { if (_str.right < _left) { _str.right = _left; - if (_shadowMode != kNoShadowMode) + if (_shadowMode) _str.right++; } @@ -811,30 +665,12 @@ void CharsetRendererV3::printChar(int chr, bool ignoreCharsetMask) { } void CharsetRendererV3::drawChar(int chr, Graphics::Surface &s, int x, int y) { - const byte *charPtr; - byte *dst; - int width, height; - int is2byte = (chr >= 0x80 && _vm->_useCJKMode) ? 1 : 0; - if (is2byte) { -#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE - if (_vm->_game.platform == Common::kPlatformFMTowns) { - _vm->_cjkFont->drawChar(s, chr, x * _vm->_textSurfaceMultiplier, y * _vm->_textSurfaceMultiplier, _color, _shadowColor); - return; - } - else -#endif - { - charPtr = _vm->get2byteCharPtr(chr); - width = _vm->_2byteWidth; - height = _vm->_2byteHeight; - } - } else { - charPtr = _fontPtr + chr * 8; -// width = height = 8; - width = getCharWidth(chr); - height = 8; - } - dst = (byte *)s.pixels + y * s.pitch + x; + const byte *charPtr = (_vm->_useCJKMode && chr > 127) ? _vm->get2byteCharPtr(chr) : _fontPtr + chr * 8; + int width = getDrawWidthIntern(chr); + int height = getDrawHeightIntern(chr); + setDrawCharIntern(chr); + + byte *dst = (byte *)s.pixels + y * s.pitch + x; drawBits1(s, dst, charPtr, y, width, height, s.format.bytesPerPixel); } @@ -853,29 +689,6 @@ void CharsetRenderer::translateColor() { } } -#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE -void CharsetRenderer::processTownsCharsetColors(uint8 bytesPerPixel) { - if (_vm->_game.platform == Common::kPlatformFMTowns) { - for (int i = 0; i < (1 << bytesPerPixel); i++) { - uint8 c = _vm->_charsetColorMap[i]; - - if (c > 16) { - uint8 t = (_vm->_currentPalette[c * 3] < 32) ? 4 : 12; - t |= ((_vm->_currentPalette[c * 3 + 1] < 32) ? 2 : 10); - t |= ((_vm->_currentPalette[c * 3 + 1] < 32) ? 1 : 9); - c = t; - } - - if (c == 0) - c = _vm->_townsOverrideShadowColor; - - c = ((c & 0x0f) << 4) | (c & 0x0f); - _vm->_townsCharsetColorMap[i] = c; - } - } -} -#endif - void CharsetRenderer::saveLoadWithSerializer(Serializer *ser) { static const SaveLoadEntry charsetRendererEntries[] = { MKLINE_OLD(CharsetRenderer, _curId, sleByte, VER(73), VER(73)), @@ -893,10 +706,7 @@ void CharsetRenderer::saveLoadWithSerializer(Serializer *ser) { } void CharsetRendererClassic::printChar(int chr, bool ignoreCharsetMask) { - int width, height, origWidth, origHeight; - int offsX, offsY; VirtScreen *vs; - const byte *charPtr; bool is2byte = (chr >= 256 && _vm->_useCJKMode); assertRange(1, _curId, _vm->_numCharsets - 1, "charset"); @@ -911,64 +721,8 @@ void CharsetRendererClassic::printChar(int chr, bool ignoreCharsetMask) { _vm->_charsetColorMap[1] = _color; -#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE - processTownsCharsetColors(_bytesPerPixel); - bool noSjis = false; - - if (_vm->_game.platform == Common::kPlatformFMTowns && _vm->_useCJKMode) { - if ((chr & 0x00ff) == 0x00fd) { - chr >>= 8; - noSjis = true; - } - } - - if (useTownsFontRomCharacter(chr) && !noSjis) { - charPtr = 0; - _vm->_cjkChar = chr; - enableShadow(true); - - width = getCharWidth(chr); - // For whatever reason MI1 uses a different font width - // for alignment calculation and for drawing when - // charset 2 is active. This fixes some subtle glitches. - if (_vm->_game.id == GID_MONKEY && _curId == 2) - width--; - origWidth = width; - - origHeight = height = getFontHeight(); - offsX = offsY = 0; - } else if (_vm->_useCJKMode && (chr >= 128) && !noSjis) { - enableShadow(true); - origWidth = width = _vm->_2byteWidth; - origHeight = height = _vm->_2byteHeight; - charPtr = _vm->get2byteCharPtr(chr); - offsX = offsY = 0; - if (_shadowMode != kNoShadowMode) { - width++; - height++; - } - } else -#endif - { - uint32 charOffs = READ_LE_UINT32(_fontPtr + chr * 4 + 4); - assert(charOffs < 0x14000); - if (!charOffs) - return; - charPtr = _fontPtr + charOffs; - - width = origWidth = charPtr[0]; - height = origHeight = charPtr[1]; - - if (_disableOffsX) { - offsX = 0; - } else { - offsX = (signed char)charPtr[2]; - } - - offsY = (signed char)charPtr[3]; - - charPtr += 4; // Skip over char header - } + if (!prepareDraw(chr)) + return; if (_firstChar) { _str.left = 0; @@ -977,12 +731,12 @@ void CharsetRendererClassic::printChar(int chr, bool ignoreCharsetMask) { _str.bottom = 0; } - _top += offsY; - _left += offsX; + _top += _offsY; + _left += _offsX; - if (_left + origWidth > _right + 1 || _left < 0) { - _left += origWidth; - _top -= offsY; + if (_left + _origWidth > _right + 1 || _left < 0) { + _left += _origWidth; + _top -= _offsY; return; } @@ -1004,33 +758,29 @@ void CharsetRendererClassic::printChar(int chr, bool ignoreCharsetMask) { int drawTop = _top - vs->topline; - _vm->markRectAsDirty(vs->number, _left, _left + width, drawTop, drawTop + height); + _vm->markRectAsDirty(vs->number, _left, _left + _width, drawTop, drawTop + _height); // This check for kPlatformFMTowns and kMainVirtScreen is at least required for the chat with // the navigator's head in front of the ghost ship in Monkey Island 1 - if (!ignoreCharsetMask -#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE - || (_vm->_game.platform == Common::kPlatformFMTowns && vs->number == kMainVirtScreen) -#endif - ) { + if (!ignoreCharsetMask || (_vm->_game.platform == Common::kPlatformFMTowns && vs->number == kMainVirtScreen)) { _hasMask = true; _textScreenID = vs->number; } - printCharIntern(is2byte, charPtr, origWidth, origHeight, width, height, vs, ignoreCharsetMask); + printCharIntern(is2byte, _charPtr, _origWidth, _origHeight, _width, _height, vs, ignoreCharsetMask); - _left += origWidth; + _left += _origWidth; if (_str.right < _left) { _str.right = _left; - if (_vm->_game.platform != Common::kPlatformFMTowns && _shadowMode != kNoShadowMode) + if (_vm->_game.platform != Common::kPlatformFMTowns && _shadowMode) _str.right++; } - if (_str.bottom < _top + origHeight) - _str.bottom = _top + origHeight; + if (_str.bottom < _top + _origHeight) + _str.bottom = _top + _origHeight; - _top -= offsY; + _top -= _offsY; } void CharsetRendererClassic::printCharIntern(bool is2byte, const byte *charPtr, int origWidth, int origHeight, int width, int height, VirtScreen *vs, bool ignoreCharsetMask) { @@ -1068,11 +818,7 @@ void CharsetRendererClassic::printCharIntern(bool is2byte, const byte *charPtr, } else { Graphics::Surface dstSurface; Graphics::Surface backSurface; - if ((ignoreCharsetMask || !vs->hasTwoBuffers) -#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE - && (_vm->_game.platform != Common::kPlatformFMTowns) -#endif - ) { + if ((ignoreCharsetMask || !vs->hasTwoBuffers)) { dstSurface = *vs; dstPtr = vs->getPixels(_left, drawTop); } else { @@ -1091,16 +837,7 @@ void CharsetRendererClassic::printCharIntern(bool is2byte, const byte *charPtr, drawTop = _top - _vm->_screenTop; } -#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE - if (!charPtr && _vm->_cjkFont) { - _vm->_cjkFont->drawChar(dstSurface, _vm->_cjkChar, _left * _vm->_textSurfaceMultiplier, (_top - _vm->_screenTop) * _vm->_textSurfaceMultiplier, _vm->_townsCharsetColorMap[1], _shadowColor); - } else -#endif - if (is2byte) { - drawBits1(dstSurface, dstPtr, charPtr, drawTop, origWidth, origHeight, dstSurface.format.bytesPerPixel); - } else { - drawBitsN(dstSurface, dstPtr, charPtr, *_fontPtr, drawTop, origWidth, origHeight, _vm->_textSurfaceMultiplier == 2); - } + drawBitsN(dstSurface, dstPtr, charPtr, *_fontPtr, drawTop, origWidth, origHeight); if (_blitAlso && vs->hasTwoBuffers) { // FIXME: Revisiting this code, I think the _blitAlso mode is likely broken @@ -1139,54 +876,36 @@ void CharsetRendererClassic::printCharIntern(bool is2byte, const byte *charPtr, } } -void CharsetRendererClassic::drawChar(int chr, Graphics::Surface &s, int x, int y) { - const byte *charPtr; - byte *dst; - int width, height; - int is2byte = (chr >= 0x80 && _vm->_useCJKMode) ? 1 : 0; - - if (is2byte) { - enableShadow(true); -#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE - if (_vm->_game.platform == Common::kPlatformFMTowns) { - _vm->_cjkFont->drawChar(s, chr, x * _vm->_textSurfaceMultiplier, y * _vm->_textSurfaceMultiplier, _color, _shadowColor); - return; - } else -#endif - { - charPtr = _vm->get2byteCharPtr(chr); - width = _vm->_2byteWidth; - height = _vm->_2byteHeight; - } - } else { - uint32 charOffs = READ_LE_UINT32(_fontPtr + chr * 4 + 4); - assert(charOffs < 0x10000); - if (!charOffs) - return; - charPtr = _fontPtr + charOffs; +bool CharsetRendererClassic::prepareDraw(uint16 chr) { + uint32 charOffs = READ_LE_UINT32(_fontPtr + chr * 4 + 4); + assert(charOffs < 0x14000); + if (!charOffs) + return false; + _charPtr = _fontPtr + charOffs; - width = charPtr[0]; - height = charPtr[1]; + _width = _origWidth = _charPtr[0]; + _height = _origHeight = _charPtr[1]; - charPtr += 4; // Skip over char header + if (_disableOffsX) { + _offsX = 0; + } else { + _offsX = (signed char)_charPtr[2]; } - dst = (byte *)s.pixels + y * s.pitch + x; + _offsY = (signed char)_charPtr[3]; - if (is2byte) { - drawBits1(s, dst, charPtr, y, width, height, s.format.bytesPerPixel); - } else { - drawBitsN(s, dst, charPtr, *_fontPtr, y, width, height); - } + _charPtr += 4; // Skip over char header + return true; } -void CharsetRendererClassic::drawBitsN(const Graphics::Surface &s, byte *dst, const byte *src, byte bpp, int drawTop, int width, int height, -#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE - bool scale2x) { -#else - bool) { -#endif +void CharsetRendererClassic::drawChar(int chr, Graphics::Surface &s, int x, int y) { + if (!prepareDraw(chr)) + return; + byte *dst = (byte *)s.pixels + y * s.pitch + x; + drawBitsN(s, dst, _charPtr, *_fontPtr, y, _width, _height); +} +void CharsetRendererClassic::drawBitsN(const Graphics::Surface &s, byte *dst, const byte *src, byte bpp, int drawTop, int width, int height) { int y, x; int color; byte numbits, bits; @@ -1198,38 +917,13 @@ void CharsetRendererClassic::drawBitsN(const Graphics::Surface &s, byte *dst, co numbits = 8; byte *cmap = _vm->_charsetColorMap; -#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE - byte *dst2 = dst; - - if (_vm->_game.platform == Common::kPlatformFMTowns) - cmap = _vm->_townsCharsetColorMap; - if (scale2x) { - dst2 += s.pitch; - pitch <<= 1; - } -#endif - for (y = 0; y < height && y + drawTop < s.h; y++) { for (x = 0; x < width; x++) { color = (bits >> (8 - bpp)) & 0xFF; - if (color && y + drawTop >= 0) { + if (color && y + drawTop >= 0) *dst = cmap[color]; - -#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE - if (scale2x) - dst[1] = dst2[0] = dst2[1] = dst[0]; -#endif - } dst++; - -#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE - if (scale2x) { - dst++; - dst2 += 2; - } -#endif - bits <<= bpp; numbits -= bpp; if (numbits == 0) { @@ -1238,52 +932,93 @@ void CharsetRendererClassic::drawBitsN(const Graphics::Surface &s, byte *dst, co } } dst += pitch; + } +} + +CharsetRendererTownsV3::CharsetRendererTownsV3(ScummEngine *vm) : CharsetRendererV3(vm), _sjisCurChar(0) { +} + +int CharsetRendererTownsV3::getCharWidth(uint16 chr) { + int spacing = 0; + + if (_vm->_useCJKMode) { + if (chr >= 256) + spacing = 8; + else if (chr >= 128) + spacing = 4; + } + + if (!spacing) + spacing = *(_widthTable + chr); + + return spacing; +} + +int CharsetRendererTownsV3::getFontHeight() { + return _vm->_useCJKMode ? 8 : _fontHeight; +} + +void CharsetRendererTownsV3::enableShadow(bool enable) { + _shadowColor = 8; + _shadowMode = enable; + #ifndef DISABLE_TOWNS_DUAL_LAYER_MODE - dst2 += pitch; + _shadowColor = 0x88; +#ifdef USE_RGB_COLOR + if (_vm->_cjkFont) + _vm->_cjkFont->setDrawingMode(enable ? Graphics::FontSJIS::kFMTownsShadowMode : Graphics::FontSJIS::kDefaultMode); +#endif #endif - } } -void CharsetRendererCommon::drawBits1(const Graphics::Surface &s, byte *dst, const byte *src, int drawTop, int width, int height, uint8 bitDepth, +void CharsetRendererTownsV3::drawBits1(const Graphics::Surface &s, byte *dst, const byte *src, int drawTop, int width, int height, uint8 bitDepth) { #ifndef DISABLE_TOWNS_DUAL_LAYER_MODE - bool scale2x) { +#ifdef USE_RGB_COLOR + if (_sjisCurChar) { + assert(_vm->_cjkFont); + _vm->_cjkFont->drawChar(_vm->_textSurface, _sjisCurChar, _left * _vm->_textSurfaceMultiplier, _top * _vm->_textSurfaceMultiplier, _color, _shadowColor); + return; + } +#endif + + dst = (byte *)_vm->_textSurface.getBasePtr(_left * _vm->_textSurfaceMultiplier, _top * _vm->_textSurfaceMultiplier); + int sfPitch = _vm->_textSurface.pitch; + int sfHeight = _vm->_textSurface.h; + bool scale2x = (_vm->_textSurfaceMultiplier == 2 && !(_sjisCurChar >= 256 && _vm->_useCJKMode)); #else - bool) { + int sfPitch = s.pitch; + int sfHeight = s.h; #endif int y, x; byte bits = 0; uint8 col = _color; - int pitch = s.pitch - width * bitDepth; - byte *dst2 = dst + s.pitch; + int pitch = sfPitch - width * bitDepth; + byte *dst2 = dst + sfPitch; #ifndef DISABLE_TOWNS_DUAL_LAYER_MODE byte *dst3 = dst2; byte *dst4 = dst2; if (scale2x) { - dst3 = dst2 + s.pitch; - dst4 = dst3 + s.pitch; + dst3 = dst2 + sfPitch; + dst4 = dst3 + sfPitch; pitch <<= 1; } - if (_vm->_game.platform == Common::kPlatformFMTowns && _vm->_game.version == 5) - col = _vm->_townsCharsetColorMap[1]; #endif - for (y = 0; y < height && y + drawTop < s.h; y++) { + for (y = 0; y < height && y + drawTop < sfHeight; y++) { for (x = 0; x < width; x++) { if ((x % 8) == 0) bits = *src++; if ((bits & revBitMask(x % 8)) && y + drawTop >= 0) { if (bitDepth == 2) { - if (_shadowMode != kNoShadowMode) { + if (_shadowMode) { WRITE_UINT16(dst + 2, _vm->_16BitPalette[_shadowColor]); - WRITE_UINT16(dst + s.pitch, _vm->_16BitPalette[_shadowColor]); - if (_shadowMode != kFMTOWNSShadowMode) - WRITE_UINT16(dst + s.pitch + 2, _vm->_16BitPalette[_shadowColor]); + WRITE_UINT16(dst + sfPitch, _vm->_16BitPalette[_shadowColor]); } WRITE_UINT16(dst, _vm->_16BitPalette[_color]); } else { - if (_shadowMode != kNoShadowMode) { + if (_shadowMode) { #ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (scale2x) { dst[2] = dst[3] = dst2[2] = dst2[3] = _shadowColor; @@ -1292,8 +1027,6 @@ void CharsetRendererCommon::drawBits1(const Graphics::Surface &s, byte *dst, con #endif { dst[1] = dst2[0] = _shadowColor; - if (_shadowMode != kFMTOWNSShadowMode) - dst2[1] = _shadowColor; } } dst[0] = col; @@ -1324,31 +1057,64 @@ void CharsetRendererCommon::drawBits1(const Graphics::Surface &s, byte *dst, con #endif } } +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE +int CharsetRendererTownsV3::getDrawWidthIntern(uint16 chr) { +#ifdef USE_RGB_COLOR + if (_vm->_useCJKMode && chr > 127) { + assert(_vm->_cjkFont); + return _vm->_cjkFont->getCharWidth(chr); + } +#endif + return CharsetRendererV3::getDrawWidthIntern(chr); +} + +int CharsetRendererTownsV3::getDrawHeightIntern(uint16 chr) { +#ifdef USE_RGB_COLOR + if (_vm->_useCJKMode && chr > 127) { + assert(_vm->_cjkFont); + return _vm->_cjkFont->getFontHeight(); + } +#endif + return CharsetRendererV3::getDrawHeightIntern(chr); +} + +void CharsetRendererTownsV3::setDrawCharIntern(uint16 chr) { + _sjisCurChar = (_vm->_useCJKMode && chr > 127) ? chr : 0; +} +#endif #ifdef USE_RGB_COLOR -void CharsetRendererPCE::drawBits1(const Graphics::Surface &s, byte *dst, const byte *src, int drawTop, int width, int height, uint8 bitDepth, bool scalex) { +void CharsetRendererPCE::drawBits1(const Graphics::Surface &s, byte *dst, const byte *src, int drawTop, int width, int height, uint8 bitDepth) { + if (_sjisCurChar) { + assert(_vm->_cjkFont); + uint16 col1 = _color; + uint16 col2 = _shadowColor; + + if (s.format.bytesPerPixel == 2) { + col1 = _vm->_16BitPalette[col1]; + col2 = _vm->_16BitPalette[col2]; + } + + _vm->_cjkFont->drawChar(dst, _sjisCurChar, s.pitch, s.format.bytesPerPixel, col1, col2, -1, -1); + return; + } + int y, x; - int bitCount = 0; byte bits = 0; - const bool resetLineBitCount = (_vm->_language != Common::JA_JPN || width != 12); - for (y = 0; y < height && y + drawTop < s.h; y++) { - if (resetLineBitCount) - bitCount = 0; + int bitCount = 0; for (x = 0; x < width; x++) { if ((bitCount % 8) == 0) bits = *src++; if ((bits & revBitMask(bitCount % 8)) && y + drawTop >= 0) { if (bitDepth == 2) { - if (_shadowMode != kNoShadowMode) { + if (_shadowMode) WRITE_UINT16(dst + s.pitch + 2, _vm->_16BitPalette[_shadowColor]); - } WRITE_UINT16(dst, _vm->_16BitPalette[_color]); } else { - if (_shadowMode != kNoShadowMode) { + if (_shadowMode) *(dst + s.pitch + 1) = _shadowColor; - } *dst = _color; } } @@ -1359,6 +1125,22 @@ void CharsetRendererPCE::drawBits1(const Graphics::Surface &s, byte *dst, const dst += s.pitch - width * bitDepth; } } + +int CharsetRendererPCE::getDrawWidthIntern(uint16 chr) { + if (_vm->_useCJKMode && chr > 127) + return _vm->_2byteWidth; + return CharsetRendererV3::getDrawWidthIntern(chr); +} + +int CharsetRendererPCE::getDrawHeightIntern(uint16 chr) { + if (_vm->_useCJKMode && chr > 127) + return _vm->_2byteHeight; + return CharsetRendererV3::getDrawHeightIntern(chr); +} + +void CharsetRendererPCE::setDrawCharIntern(uint16 chr) { + _sjisCurChar = (_vm->_useCJKMode && chr > 127) ? chr : 0; +} #endif #ifdef ENABLE_SCUMM_7_8 @@ -1533,7 +1315,7 @@ void CharsetRendererNES::printChar(int chr, bool ignoreCharsetMask) { if (_str.right < _left) { _str.right = _left; - if (_shadowMode != kNoShadowMode) + if (_shadowMode) _str.right++; } @@ -1556,7 +1338,204 @@ void CharsetRendererNES::drawChar(int chr, Graphics::Surface &s, int x, int y) { drawBits1(s, dst, charPtr, y, width, height, s.format.bytesPerPixel); } -void CharsetRendererNES::drawBits1(const Graphics::Surface &s, byte *dst, const byte *src, int drawTop, int width, int height, uint8 bitDepth, bool scalex) { +#ifdef USE_RGB_COLOR +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE +CharsetRendererTownsClassic::CharsetRendererTownsClassic(ScummEngine *vm) : CharsetRendererClassic(vm), _sjisCurChar(0) { +} + +int CharsetRendererTownsClassic::getCharWidth(uint16 chr) { + int spacing = 0; + + if (_vm->_useCJKMode) { + if ((chr & 0xff00) == 0xfd00) { + chr &= 0xff; + } else if (chr >= 256) { + spacing = 8; + } else if (useFontRomCharacter(chr)) { + spacing = 4; + } + + if (spacing) { + if (_vm->_game.id == GID_MONKEY) { + spacing++; + if (_curId == 2) + spacing++; + } else if (_vm->_game.id != GID_INDY4 && _curId == 1) { + spacing++; + } + } + } + + if (!spacing) { + int offs = READ_LE_UINT32(_fontPtr + chr * 4 + 4); + if (offs) + spacing = _fontPtr[offs] + (signed char)_fontPtr[offs + 2]; + } + + return spacing; +} + +int CharsetRendererTownsClassic::getFontHeight() { + static const uint8 sjisFontHeightM1[] = { 0, 8, 9, 8, 9, 8, 9, 0, 0, 0 }; + static const uint8 sjisFontHeightM2[] = { 0, 8, 9, 9, 9, 8, 9, 9, 9, 8 }; + static const uint8 sjisFontHeightI4[] = { 0, 8, 9, 9, 9, 8, 8, 8, 8, 8 }; + const uint8 *htbl = (_vm->_game.id == GID_MONKEY) ? sjisFontHeightM1 : ((_vm->_game.id == GID_INDY4) ? sjisFontHeightI4 : sjisFontHeightM2); + return _vm->_useCJKMode ? htbl[_curId] : _fontHeight; +} + +void CharsetRendererTownsClassic::drawBitsN(const Graphics::Surface&, byte *dst, const byte *src, byte bpp, int drawTop, int width, int height) { + if (_sjisCurChar) { + assert(_vm->_cjkFont); + _vm->_cjkFont->drawChar(_vm->_textSurface, _sjisCurChar, _left * _vm->_textSurfaceMultiplier, (_top - _vm->_screenTop) * _vm->_textSurfaceMultiplier, _vm->_townsCharsetColorMap[1], _shadowColor); + return; + } + + bool scale2x = (_vm->_textSurfaceMultiplier == 2); + dst = (byte *)_vm->_textSurface.pixels + (_top - _vm->_screenTop) * _vm->_textSurface.pitch * _vm->_textSurfaceMultiplier + _left * _vm->_textSurfaceMultiplier; + + int y, x; + int color; + byte numbits, bits; + + int pitch = _vm->_textSurface.pitch - width; + + assert(bpp == 1 || bpp == 2 || bpp == 4 || bpp == 8); + bits = *src++; + numbits = 8; + byte *cmap = _vm->_charsetColorMap; + byte *dst2 = dst; + + if (_vm->_game.platform == Common::kPlatformFMTowns) + cmap = _vm->_townsCharsetColorMap; + if (scale2x) { + dst2 += _vm->_textSurface.pitch; + pitch <<= 1; + } + + for (y = 0; y < height && y + drawTop < _vm->_textSurface.h; y++) { + for (x = 0; x < width; x++) { + color = (bits >> (8 - bpp)) & 0xFF; + + if (color && y + drawTop >= 0) { + *dst = cmap[color]; + if (scale2x) + dst[1] = dst2[0] = dst2[1] = dst[0]; + } + dst++; + + if (scale2x) { + dst++; + dst2 += 2; + } + + bits <<= bpp; + numbits -= bpp; + if (numbits == 0) { + bits = *src++; + numbits = 8; + } + } + dst += pitch; + dst2 += pitch; + } +} + +bool CharsetRendererTownsClassic::prepareDraw(uint16 chr) { + processCharsetColors(); + bool noSjis = false; + + if (_vm->_game.platform == Common::kPlatformFMTowns && _vm->_useCJKMode) { + if ((chr & 0x00ff) == 0x00fd) { + chr >>= 8; + noSjis = true; + } + } + + if (useFontRomCharacter(chr) && !noSjis) { + setupShadowMode(); + _charPtr = 0; + _sjisCurChar = chr; + + _width = getCharWidth(chr); + // For whatever reason MI1 uses a different font width + // for alignment calculation and for drawing when + // charset 2 is active. This fixes some subtle glitches. + if (_vm->_game.id == GID_MONKEY && _curId == 2) + _width--; + _origWidth = _width; + + _origHeight = _height = getFontHeight(); + _offsX = _offsY = 0; + } else if (_vm->_useCJKMode && (chr >= 128) && !noSjis) { + setupShadowMode(); + _origWidth = _width = _vm->_2byteWidth; + _origHeight = _height = _vm->_2byteHeight; + _charPtr = _vm->get2byteCharPtr(chr); + _offsX = _offsY = 0; + if (_shadowMode) { + _width++; + _height++; + } + } else { + _sjisCurChar = 0; + return CharsetRendererClassic::prepareDraw(chr); + } + return true; +} + +void CharsetRendererTownsClassic::setupShadowMode() { + _shadowMode = true; + _shadowColor = _vm->_townsCharsetColorMap[0]; + assert(_vm->_cjkFont); + + if (((_vm->_game.id == GID_MONKEY) && (_curId == 2 || _curId == 4 || _curId == 6)) || + ((_vm->_game.id == GID_MONKEY2) && (_curId != 1 && _curId != 5 && _curId != 9)) || + ((_vm->_game.id == GID_INDY4) && (_curId == 2 || _curId == 3 || _curId == 4))) { + _vm->_cjkFont->setDrawingMode(Graphics::FontSJIS::kOutlineMode); + } else { + _vm->_cjkFont->setDrawingMode(Graphics::FontSJIS::kDefaultMode); + } + + _vm->_cjkFont->toggleFlippedMode((_vm->_game.id == GID_MONKEY || _vm->_game.id == GID_MONKEY2) && _curId == 3); +} + +bool CharsetRendererTownsClassic::useFontRomCharacter(uint16 chr) { + if (!_vm->_useCJKMode) + return false; + + // Some SCUMM 5 games contain hard coded logic to determine whether to use + // the SCUMM fonts or the FM-Towns font rom to draw a character. For the other + // games we will simply check for a character greater 127. + if (chr < 128) { + if (((_vm->_game.id == GID_MONKEY2 && _curId != 0) || (_vm->_game.id == GID_INDY4 && _curId != 3)) && (chr > 31 && chr != 94 && chr != 95 && chr != 126 && chr != 127)) + return true; + return false; + } + return true; +} + +void CharsetRendererTownsClassic::processCharsetColors() { + for (int i = 0; i < (1 << _bytesPerPixel); i++) { + uint8 c = _vm->_charsetColorMap[i]; + + if (c > 16) { + uint8 t = (_vm->_currentPalette[c * 3] < 32) ? 4 : 12; + t |= ((_vm->_currentPalette[c * 3 + 1] < 32) ? 2 : 10); + t |= ((_vm->_currentPalette[c * 3 + 1] < 32) ? 1 : 9); + c = t; + } + + if (c == 0) + c = _vm->_townsOverrideShadowColor; + + c = ((c & 0x0f) << 4) | (c & 0x0f); + _vm->_townsCharsetColorMap[i] = c; + } +} +#endif +#endif + +void CharsetRendererNES::drawBits1(const Graphics::Surface &s, byte *dst, const byte *src, int drawTop, int width, int height, uint8 bitDepth) { for (int i = 0; i < 8; i++) { byte c0 = src[i]; byte c1 = src[i + 8]; diff --git a/engines/scumm/charset.h b/engines/scumm/charset.h index 4c657b475e..b23ec996f5 100644 --- a/engines/scumm/charset.h +++ b/engines/scumm/charset.h @@ -25,6 +25,7 @@ #include "common/scummsys.h" #include "common/rect.h" #include "graphics/sjis.h" +#include "scumm/scumm.h" #include "scumm/gfx.h" #include "scumm/saveload.h" @@ -78,10 +79,6 @@ public: void addLinebreaks(int a, byte *str, int pos, int maxwidth); void translateColor(); -#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE - void processTownsCharsetColors(uint8 bytesPerPixel); -#endif - virtual void setCurID(int32 id) = 0; int getCurID() { return _curId; } @@ -101,31 +98,26 @@ protected: int _fontHeight; int _numChars; - enum ShadowMode { - kNoShadowMode, - kFMTOWNSShadowMode, - kNormalShadowMode - }; byte _shadowColor; - ShadowMode _shadowMode; - - void enableShadow(bool enable); - virtual void drawBits1(const Graphics::Surface &s, byte *dst, const byte *src, int drawTop, int width, int height, uint8 bitDepth, bool scale2x = false); - + bool _shadowMode; public: CharsetRendererCommon(ScummEngine *vm); void setCurID(int32 id); - int getFontHeight(); + virtual int getFontHeight(); }; class CharsetRendererClassic : public CharsetRendererCommon { protected: - void drawBitsN(const Graphics::Surface &s, byte *dst, const byte *src, byte bpp, int drawTop, int width, int height, bool scale2x = false); + virtual void drawBitsN(const Graphics::Surface &s, byte *dst, const byte *src, byte bpp, int drawTop, int width, int height); + void printCharIntern(bool is2byte, const byte *charPtr, int origWidth, int origHeight, int width, int height, VirtScreen *vs, bool ignoreCharsetMask); + virtual bool prepareDraw(uint16 chr); - void printCharIntern(bool is2byte, const byte *charPtr, int origWidth, int origHeight, int width, int height, VirtScreen *vs, bool ignoreCharsetMask); + int _width, _height, _origWidth, _origHeight; + int _offsX, _offsY; + const byte *_charPtr; public: CharsetRendererClassic(ScummEngine *vm) : CharsetRendererCommon(vm) {} @@ -134,18 +126,34 @@ public: void drawChar(int chr, Graphics::Surface &s, int x, int y); int getCharWidth(uint16 chr); +}; + +#ifdef USE_RGB_COLOR +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE +class CharsetRendererTownsClassic : public CharsetRendererClassic { +public: + CharsetRendererTownsClassic(ScummEngine *vm); + + int getCharWidth(uint16 chr); + int getFontHeight(); - // Some SCUMM 5 games contain hard coded logic to determine whether to use - // the SCUMM fonts or the FM-Towns font rom to draw a character. For the other - // games we will simply check for a character greater 127. - bool useTownsFontRomCharacter(uint16 chr); +private: + void drawBitsN(const Graphics::Surface &s, byte *dst, const byte *src, byte bpp, int drawTop, int width, int height); + bool prepareDraw(uint16 chr); + void setupShadowMode(); + bool useFontRomCharacter(uint16 chr); + void processCharsetColors(); + + uint16 _sjisCurChar; }; +#endif +#endif class CharsetRendererNES : public CharsetRendererCommon { protected: byte *_trTable; - void drawBits1(const Graphics::Surface &s, byte *dst, const byte *src, int drawTop, int width, int height, uint8 bitDepth, bool scale2x = false); + void drawBits1(const Graphics::Surface &s, byte *dst, const byte *src, int drawTop, int width, int height, uint8 bitDepth); public: CharsetRendererNES(ScummEngine *vm) : CharsetRendererCommon(vm) {} @@ -160,6 +168,12 @@ public: class CharsetRendererV3 : public CharsetRendererCommon { protected: + virtual void enableShadow(bool enable); + virtual void drawBits1(const Graphics::Surface &s, byte *dst, const byte *src, int drawTop, int width, int height, uint8 bitDepth); + virtual int getDrawWidthIntern(uint16 chr); + virtual int getDrawHeightIntern(uint16 chr); + virtual void setDrawCharIntern(uint16 chr) {} + const byte *_widthTable; public: @@ -169,16 +183,40 @@ public: void drawChar(int chr, Graphics::Surface &s, int x, int y); void setCurID(int32 id); void setColor(byte color); + virtual int getCharWidth(uint16 chr); +}; + +class CharsetRendererTownsV3 : public CharsetRendererV3 { +public: + CharsetRendererTownsV3(ScummEngine *vm); + int getCharWidth(uint16 chr); + int getFontHeight(); + +private: + void enableShadow(bool enable); + void drawBits1(const Graphics::Surface &s, byte *dst, const byte *src, int drawTop, int width, int height, uint8 bitDepth); +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE + int getDrawWidthIntern(uint16 chr); + int getDrawHeightIntern(uint16 chr); + void setDrawCharIntern(uint16 chr); +#endif + uint16 _sjisCurChar; }; #ifdef USE_RGB_COLOR class CharsetRendererPCE : public CharsetRendererV3 { -protected: - void drawBits1(const Graphics::Surface &s, byte *dst, const byte *src, int drawTop, int width, int height, uint8 bitDepth, bool scale2x = false); +private: + void drawBits1(const Graphics::Surface &s, byte *dst, const byte *src, int drawTop, int width, int height, uint8 bitDepth); + + int getDrawWidthIntern(uint16 chr); + int getDrawHeightIntern(uint16 chr); + void setDrawCharIntern(uint16 chr); + + uint16 _sjisCurChar; public: - CharsetRendererPCE(ScummEngine *vm) : CharsetRendererV3(vm) {} + CharsetRendererPCE(ScummEngine *vm) : CharsetRendererV3(vm), _sjisCurChar(0) {} void setColor(byte color); }; diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h index e510c46cf2..11901f7565 100644 --- a/engines/scumm/detection_tables.h +++ b/engines/scumm/detection_tables.h @@ -243,11 +243,11 @@ static const GameSettings gameVariantsTable[] = { {"monkey", "FM-TOWNS", 0, GID_MONKEY, 5, 0, MDT_TOWNS, GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO_NOSPEECH | GUIO_NOMIDI | GUIO_MIDITOWNS}, {"monkey", "SEGA", 0, GID_MONKEY, 5, 0, MDT_NONE, GF_AUDIOTRACKS, Common::kPlatformSegaCD, GUIO_NOSPEECH | GUIO_NOMIDI}, - {"monkey2", "", 0, GID_MONKEY2, 5, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO_NOSPEECH}, - {"monkey2", "FM-TOWNS", 0, GID_MONKEY2, 5, 0, MDT_TOWNS | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, Common::kPlatformFMTowns, GUIO_NOSPEECH | GUIO_MIDITOWNS | GUIO_MIDIADLIB | GUIO_MIDIMT32}, + {"monkey2", "", 0, GID_MONKEY2, 5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO_NOSPEECH}, + {"monkey2", "FM-TOWNS", 0, GID_MONKEY2, 5, 0, MDT_PCSPK | MDT_TOWNS | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, Common::kPlatformFMTowns, GUIO_NOSPEECH | GUIO_MIDITOWNS | GUIO_MIDIADLIB | GUIO_MIDIMT32}, - {"atlantis", "", 0, GID_INDY4, 5, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO_NONE}, - {"atlantis", "Floppy", 0, GID_INDY4, 5, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO_NOSPEECH}, + {"atlantis", "", 0, GID_INDY4, 5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO_NONE}, + {"atlantis", "Floppy", 0, GID_INDY4, 5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO_NOSPEECH}, {"atlantis", "FM-TOWNS", 0, GID_INDY4, 5, 0, MDT_TOWNS | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, Common::kPlatformFMTowns, GUIO_MIDITOWNS | GUIO_MIDIADLIB | GUIO_MIDIMT32}, {"tentacle", "", 0, GID_TENTACLE, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_GM, GF_USE_KEY, UNK, GUIO_NONE}, diff --git a/engines/scumm/imuse/imuse.cpp b/engines/scumm/imuse/imuse.cpp index 317ef36cb9..27a72c2afe 100644 --- a/engines/scumm/imuse/imuse.cpp +++ b/engines/scumm/imuse/imuse.cpp @@ -44,30 +44,31 @@ namespace Scumm { //////////////////////////////////////// IMuseInternal::IMuseInternal() : -_native_mt32(false), -_enable_gs(false), -_sc55(false), -_midi_adlib(NULL), -_midi_native(NULL), -_sysex(NULL), -_paused(false), -_initialized(false), -_tempoFactor(0), -_player_limit(ARRAYSIZE(_players)), -_recycle_players(false), -_queue_end(0), -_queue_pos(0), -_queue_sound(0), -_queue_adding(0), -_queue_marker(0), -_queue_cleared(0), -_master_volume(0), -_music_volume(0), -_trigger_count(0), -_snm_trigger_index(0) { - memset(_channel_volume,0,sizeof(_channel_volume)); - memset(_channel_volume_eff,0,sizeof(_channel_volume_eff)); - memset(_volchan_table,0,sizeof(_volchan_table)); + _native_mt32(false), + _enable_gs(false), + _sc55(false), + _midi_adlib(NULL), + _midi_native(NULL), + _sysex(NULL), + _paused(false), + _initialized(false), + _tempoFactor(0), + _player_limit(ARRAYSIZE(_players)), + _recycle_players(false), + _queue_end(0), + _queue_pos(0), + _queue_sound(0), + _queue_adding(0), + _queue_marker(0), + _queue_cleared(0), + _master_volume(0), + _music_volume(0), + _trigger_count(0), + _snm_trigger_index(0), + _pcSpeaker(false) { + memset(_channel_volume, 0, sizeof(_channel_volume)); + memset(_channel_volume_eff, 0, sizeof(_channel_volume_eff)); + memset(_volchan_table, 0, sizeof(_volchan_table)); } IMuseInternal::~IMuseInternal() { @@ -119,7 +120,7 @@ byte *IMuseInternal::findStartOfSound(int sound, int ct) { // Check for old-style headers first, like 'RO' int trFlag = (kMThd | kFORM); - if (ptr[0] == 'R' && ptr[1] == 'O'&& ptr[2] != 'L') + if (ptr[0] == 'R' && ptr[1] == 'O' && ptr[2] != 'L') return ct == trFlag ? ptr : 0; if (ptr[4] == 'S' && ptr[5] == 'O') return ct == trFlag ? ptr + 4 : 0; @@ -153,22 +154,22 @@ bool IMuseInternal::isMT32(int sound) { uint32 tag = READ_BE_UINT32(ptr); switch (tag) { - case MKTAG('A','D','L',' '): - case MKTAG('A','S','F','X'): // Special AD class for old AdLib sound effects - case MKTAG('S','P','K',' '): + case MKTAG('A', 'D', 'L', ' '): + case MKTAG('A', 'S', 'F', 'X'): // Special AD class for old AdLib sound effects + case MKTAG('S', 'P', 'K', ' '): return false; - case MKTAG('A','M','I',' '): - case MKTAG('R','O','L',' '): + case MKTAG('A', 'M', 'I', ' '): + case MKTAG('R', 'O', 'L', ' '): return true; - case MKTAG('M','A','C',' '): // Occurs in the Mac version of FOA and MI2 + case MKTAG('M', 'A', 'C', ' '): // Occurs in the Mac version of FOA and MI2 return true; - case MKTAG('G','M','D',' '): + case MKTAG('G', 'M', 'D', ' '): return false; - case MKTAG('M','I','D','I'): // Occurs in Sam & Max + case MKTAG('M', 'I', 'D', 'I'): // Occurs in Sam & Max // HE games use Roland music if (ptr[8] == 'H' && ptr[9] == 'S') return true; @@ -195,20 +196,20 @@ bool IMuseInternal::isMIDI(int sound) { uint32 tag = READ_BE_UINT32(ptr); switch (tag) { - case MKTAG('A','D','L',' '): - case MKTAG('A','S','F','X'): // Special AD class for old AdLib sound effects - case MKTAG('S','P','K',' '): + case MKTAG('A', 'D', 'L', ' '): + case MKTAG('A', 'S', 'F', 'X'): // Special AD class for old AdLib sound effects + case MKTAG('S', 'P', 'K', ' '): return false; - case MKTAG('A','M','I',' '): - case MKTAG('R','O','L',' '): + case MKTAG('A', 'M', 'I', ' '): + case MKTAG('R', 'O', 'L', ' '): return true; - case MKTAG('M','A','C',' '): // Occurs in the Mac version of FOA and MI2 + case MKTAG('M', 'A', 'C', ' '): // Occurs in the Mac version of FOA and MI2 return true; - case MKTAG('G','M','D',' '): - case MKTAG('M','I','D','I'): // Occurs in Sam & Max + case MKTAG('G', 'M', 'D', ' '): + case MKTAG('M', 'I', 'D', 'I'): // Occurs in Sam & Max return true; } @@ -381,7 +382,8 @@ int IMuseInternal::save_or_load(Serializer *ser, ScummEngine *scumm) { for (i = 0; i < ARRAYSIZE(_parts); ++i) _parts[i].saveLoadWithSerializer(ser); - { // Load/save the instrument definitions, which were revamped with V11. + { + // Load/save the instrument definitions, which were revamped with V11. Part *part = &_parts[0]; if (ser->getVersion() >= VER(11)) { for (i = ARRAYSIZE(_parts); i; --i, ++part) { @@ -467,6 +469,10 @@ uint32 IMuseInternal::property(int prop, uint32 value) { case IMuse::PROP_GAME_ID: _game_id = value; break; + + case IMuse::PROP_PC_SPEAKER: + _pcSpeaker = (value != 0); + break; } return 0; @@ -522,7 +528,7 @@ void IMuseInternal::stopAllSounds() { int IMuseInternal::getSoundStatus(int sound) const { Common::StackLock lock(_mutex, "IMuseInternal::getSoundStatus()"); - return getSoundStatus_internal (sound, true); + return getSoundStatus_internal(sound, true); } int IMuseInternal::getMusicTimer() { @@ -565,7 +571,7 @@ bool IMuseInternal::startSound_internal(int sound, int offset) { int i; ImTrigger *trigger = _snm_triggers; for (i = ARRAYSIZE(_snm_triggers); i; --i, ++trigger) { - if (trigger->sound && trigger->id && trigger->command[0] == 8 && trigger->command[1] == sound && getSoundStatus_internal (trigger->sound,true)) + if (trigger->sound && trigger->id && trigger->command[0] == 8 && trigger->command[1] == sound && getSoundStatus_internal(trigger->sound, true)) return false; } @@ -663,9 +669,7 @@ int IMuseInternal::getSoundStatus_internal(int sound, bool ignoreFadeouts) const return (sound == -1) ? 0 : get_queue_sound_status(sound); } -int32 IMuseInternal::doCommand_internal - (int a, int b, int c, int d, int e, int f, int g, int h) -{ +int32 IMuseInternal::doCommand_internal(int a, int b, int c, int d, int e, int f, int g, int h) { int args[8]; args[0] = a; args[1] = b; @@ -733,7 +737,7 @@ int32 IMuseInternal::doCommand_internal(int numargs, int a[]) { } return -1; case 13: - return getSoundStatus_internal (a[1], true); + return getSoundStatus_internal(a[1], true); case 14: // Sam and Max: Parameter fade player = findActivePlayer(a[1]); @@ -779,8 +783,7 @@ int32 IMuseInternal::doCommand_internal(int numargs, int a[]) { a[0] = 0; for (i = 0; i < ARRAYSIZE(_snm_triggers); ++i) { if (_snm_triggers[i].sound == a[1] && _snm_triggers[i].id && - (a[3] == -1 || _snm_triggers[i].id == a[3])) - { + (a[3] == -1 || _snm_triggers[i].id == a[3])) { ++a[0]; } } @@ -1002,9 +1005,9 @@ int IMuseInternal::get_queue_sound_status(int sound) const { i = (i + 1) % ARRAYSIZE(_cmd_queue); } - for (i = 0; i < ARRAYSIZE (_deferredCommands); ++i) { + for (i = 0; i < ARRAYSIZE(_deferredCommands); ++i) { if (_deferredCommands[i].time_left && _deferredCommands[i].a == 8 && - _deferredCommands[i].b == sound) { + _deferredCommands[i].b == sound) { return 2; } } @@ -1213,7 +1216,7 @@ int32 IMuseInternal::ImSetTrigger(int sound, int id, int a, int b, int c, int d, // NOTE: We ONLY do this if the sound that will trigger the command is actually // playing. Otherwise, there's a problem when exiting and re-entering the // Bumpusville mansion. Ref Bug #780918. - if (trig->command[0] == 8 && getSoundStatus_internal(trig->command[1],true) && getSoundStatus_internal(sound,true)) + if (trig->command[0] == 8 && getSoundStatus_internal(trig->command[1], true) && getSoundStatus_internal(sound, true)) stopSound_internal(trig->command[1]); return 0; } @@ -1246,8 +1249,7 @@ int32 IMuseInternal::ImFireAllTriggers(int sound) { return (count > 0) ? 0 : -1; } -int IMuseInternal::set_channel_volume(uint chan, uint vol) -{ +int IMuseInternal::set_channel_volume(uint chan, uint vol) { if (chan >= 8 || vol > 127) return -1; @@ -1427,7 +1429,7 @@ void IMuseInternal::initMT32(MidiDriver *midi) { // Display a welcome message on MT-32 displays. memcpy(&buffer[0], "\x41\x10\x16\x12\x20\x00\x00", 7); memcpy(&buffer[7], " ", 20); - memcpy(buffer + 7 +(20 - len) / 2, info, len); + memcpy(buffer + 7 + (20 - len) / 2, info, len); byte checksum = 0; for (int i = 4; i < 27; ++i) checksum -= buffer[i]; @@ -1473,9 +1475,9 @@ void IMuseInternal::initGM(MidiDriver *midi) { // Set Channels 1-16 to SC-55 Map, then CM-64/32L Variation for (i = 0; i < 16; ++i) { - midi->send(( 127 << 16) | (0 << 8) | (0xB0 | i)); - midi->send(( 1 << 16) | (32 << 8) | (0xB0 | i)); - midi->send(( 0 << 16) | (0 << 8) | (0xC0 | i)); + midi->send((127 << 16) | (0 << 8) | (0xB0 | i)); + midi->send((1 << 16) | (32 << 8) | (0xB0 | i)); + midi->send((0 << 16) | (0 << 8) | (0xC0 | i)); } debug(2, "GS Program Change: CM-64/32L Map Selected"); @@ -1496,7 +1498,7 @@ void IMuseInternal::initGM(MidiDriver *midi) { // Set Channels 1-16 Reverb to 64, which is the // equivalent of MT-32 default Reverb Level 5 for (i = 0; i < 16; ++i) - midi->send(( 64 << 16) | (91 << 8) | (0xB0 | i)); + midi->send((64 << 16) | (91 << 8) | (0xB0 | i)); debug(2, "GM Controller 91 Change: Channels 1-16 Reverb Level is 64"); // Set Channels 1-16 Pitch Bend Sensitivity to @@ -1637,8 +1639,8 @@ void IMuseInternal::reallocateMidiChannels(MidiDriver *midi) { hipart = NULL; for (i = 32, part = _parts; i; i--, part++) { if (part->_player && part->_player->getMidiDriver() == midi && - !part->_percussion && part->_on && - !part->_mc && part->_pri_eff >= hipri) { + !part->_percussion && part->_on && + !part->_mc && part->_pri_eff >= hipri) { hipri = part->_pri_eff; hipart = part; } @@ -1668,16 +1670,35 @@ void IMuseInternal::reallocateMidiChannels(MidiDriver *midi) { } } -void IMuseInternal::setGlobalAdLibInstrument(byte slot, byte *data) { +void IMuseInternal::setGlobalInstrument(byte slot, byte *data) { if (slot < 32) { - _global_adlib_instruments[slot].adlib(data); + if (_pcSpeaker) + _global_instruments[slot].pcspk(data); + else + _global_instruments[slot].adlib(data); } } -void IMuseInternal::copyGlobalAdLibInstrument(byte slot, Instrument *dest) { +void IMuseInternal::copyGlobalInstrument(byte slot, Instrument *dest) { if (slot >= 32) return; - _global_adlib_instruments[slot].copy_to(dest); + + // Both the AdLib code and the PC Speaker code use an all zero instrument + // as default in the original, thus we do the same. + // PC Speaker instrument size is 23, while AdLib instrument size is 30. + // Thus we just use a 30 byte instrument data array as default. + const byte defaultInstr[30] = { 0 }; + + if (_global_instruments[slot].isValid()) { + // In case we have an valid instrument set up, copy it to the part. + _global_instruments[slot].copy_to(dest); + } else if (_pcSpeaker) { + debug(0, "Trying to use non-existant global PC Speaker instrument %d", slot); + dest->pcspk(defaultInstr); + } else { + debug(0, "Trying to use non-existant global AdLib instrument %d", slot); + dest->adlib(defaultInstr); + } } diff --git a/engines/scumm/imuse/imuse.h b/engines/scumm/imuse/imuse.h index 8014b13409..23449e470b 100644 --- a/engines/scumm/imuse/imuse.h +++ b/engines/scumm/imuse/imuse.h @@ -37,7 +37,7 @@ class Player; class ScummEngine; class Serializer; -typedef void (*sysexfunc) (Player *, const byte *, uint16); +typedef void (*sysexfunc)(Player *, const byte *, uint16); /** * iMuse implementation interface. @@ -55,7 +55,8 @@ public: PROP_GS, PROP_LIMIT_PLAYERS, PROP_RECYCLE_PLAYERS, - PROP_GAME_ID + PROP_GAME_ID, + PROP_PC_SPEAKER }; public: @@ -66,7 +67,7 @@ public: virtual int32 doCommand(int numargs, int args[]) = 0; virtual int clear_queue() = 0; virtual uint32 property(int prop, uint32 value) = 0; - virtual void addSysexHandler (byte mfgID, sysexfunc handler) = 0; + virtual void addSysexHandler(byte mfgID, sysexfunc handler) = 0; public: virtual void startSoundWithNoteOffset(int sound, int offset) = 0; diff --git a/engines/scumm/imuse/imuse_internal.h b/engines/scumm/imuse/imuse_internal.h index 6a7b9fc7d9..3b0d36e119 100644 --- a/engines/scumm/imuse/imuse_internal.h +++ b/engines/scumm/imuse/imuse_internal.h @@ -135,7 +135,7 @@ struct ImTrigger { int sound; byte id; uint16 expire; - int command [8]; + int command[8]; ImTrigger() { memset(this, 0, sizeof(ImTrigger)); } }; @@ -153,12 +153,12 @@ struct CommandQueue { ////////////////////////////////////////////////// class Player : public MidiDriver_BASE { -/* - * External SysEx handler functions shall each be defined in - * a separate file. This header file shall be included at the - * top of the file immediately following this special #define: - * #define SYSEX_CALLBACK_FUNCTION nameOfHandlerFunction - */ + /* + * External SysEx handler functions shall each be defined in + * a separate file. This header file shall be included at the + * top of the file immediately following this special #define: + * #define SYSEX_CALLBACK_FUNCTION nameOfHandlerFunction + */ #ifdef SYSEX_CALLBACK_FUNCTION friend void SYSEX_CALLBACK_FUNCTION(Player *, const byte *, uint16); #endif @@ -244,7 +244,7 @@ public: void clear(); void clearLoop(); void fixAfterLoad(); - Part * getActivePart(uint8 part); + Part *getActivePart(uint8 part); uint getBeatIndex(); int8 getDetune() const { return _detune; } byte getEffectiveVolume() const { return _vol_eff; } @@ -252,7 +252,7 @@ public: MidiDriver *getMidiDriver() const { return _midi; } int getParam(int param, byte chan); int8 getPan() const { return _pan; } - Part * getPart(uint8 part); + Part *getPart(uint8 part); byte getPriority() const { return _priority; } uint getTicksPerBeat() const { return TICKS_PER_BEAT; } int8 getTranspose() const { return _transpose; } @@ -342,6 +342,7 @@ struct Part : public Serializable { void off(); void set_instrument(uint b); void set_instrument(byte *data); + void set_instrument_pcspk(byte *data); void load_global_instrument(byte b); void set_transpose(int8 transpose); @@ -375,12 +376,12 @@ class IMuseInternal : public IMuse { friend class Player; friend struct Part; -/* - * External SysEx handler functions shall each be defined in - * a separate file. This header file shall be included at the - * top of the file immediately following this special #define: - * #define SYSEX_CALLBACK_FUNCTION nameOfHandlerFunction - */ + /* + * External SysEx handler functions shall each be defined in + * a separate file. This header file shall be included at the + * top of the file immediately following this special #define: + * #define SYSEX_CALLBACK_FUNCTION nameOfHandlerFunction + */ #ifdef SYSEX_CALLBACK_FUNCTION friend void SYSEX_CALLBACK_FUNCTION(Player *, const byte *, uint16); #endif @@ -433,7 +434,8 @@ protected: Player _players[8]; Part _parts[32]; - Instrument _global_adlib_instruments[32]; + bool _pcSpeaker; + Instrument _global_instruments[32]; CommandQueue _cmd_queue[64]; DeferredCommand _deferredCommands[4]; @@ -449,8 +451,8 @@ protected: enum ChunkType { kMThd = 1, kFORM = 2, - kMDhd = 4, // Used in MI2 and INDY4. Contain certain start parameters (priority, volume, etc. ) for the player. - kMDpg = 8 // These chunks exist in DOTT and SAMNMAX. They don't get processed, however. + kMDhd = 4, // Used in MI2 and INDY4. Contain certain start parameters (priority, volume, etc. ) for the player. + kMDpg = 8 // These chunks exist in DOTT and SAMNMAX. They don't get processed, however. }; byte *findStartOfSound(int sound, int ct = (kMThd | kFORM)); @@ -498,8 +500,8 @@ protected: int setImuseMasterVolume(uint vol); void reallocateMidiChannels(MidiDriver *midi); - void setGlobalAdLibInstrument(byte slot, byte *data); - void copyGlobalAdLibInstrument(byte slot, Instrument *dest); + void setGlobalInstrument(byte slot, byte *data); + void copyGlobalInstrument(byte slot, Instrument *dest); bool isNativeMT32() { return _native_mt32; } protected: diff --git a/engines/scumm/imuse/imuse_part.cpp b/engines/scumm/imuse/imuse_part.cpp index 5df8407a96..73e7704469 100644 --- a/engines/scumm/imuse/imuse_part.cpp +++ b/engines/scumm/imuse/imuse_part.cpp @@ -193,14 +193,18 @@ void Part::set_onoff(bool on) { } } -void Part::set_instrument(byte * data) { - _instrument.adlib(data); +void Part::set_instrument(byte *data) { + if (_se->_pcSpeaker) + _instrument.pcspk(data); + else + _instrument.adlib(data); + if (clearToTransmit()) _instrument.send(_mc); } void Part::load_global_instrument(byte slot) { - _player->_se->copyGlobalAdLibInstrument(slot, &_instrument); + _player->_se->copyGlobalInstrument(slot, &_instrument); if (clearToTransmit()) _instrument.send(_mc); } @@ -234,7 +238,7 @@ void Part::noteOn(byte note, byte velocity) { // should be implemented as a class static var. As it is, using // a function level static var in most cases is arcane and evil. static byte prev_vol_eff = 128; - if (_vol_eff != prev_vol_eff){ + if (_vol_eff != prev_vol_eff) { mc->volume(_vol_eff); prev_vol_eff = _vol_eff; } diff --git a/engines/scumm/imuse/imuse_player.cpp b/engines/scumm/imuse/imuse_player.cpp index 61b9cad2cb..73be2174cd 100644 --- a/engines/scumm/imuse/imuse_player.cpp +++ b/engines/scumm/imuse/imuse_player.cpp @@ -79,7 +79,7 @@ Player::Player() : _isMT32(false), _isMIDI(false), _se(0), - _vol_chan(0){ + _vol_chan(0) { } Player::~Player() { @@ -133,7 +133,7 @@ bool Player::isFadingOut() const { int i; for (i = 0; i < ARRAYSIZE(_parameterFaders); ++i) { if (_parameterFaders[i].param == ParameterFader::pfVolume && - _parameterFaders[i].end == 0) { + _parameterFaders[i].end == 0) { return true; } } @@ -371,11 +371,13 @@ void Player::sysEx(const byte *p, uint16 len) { if (a != IMUSE_SYSEX_ID) { if (a == ROLAND_SYSEX_ID) { // Roland custom instrument definition. - part = getPart(p[0] & 0x0F); - if (part) { - part->_instrument.roland(p - 1); - if (part->clearToTransmit()) - part->_instrument.send(part->_mc); + if (_isMIDI || _isMT32) { + part = getPart(p[0] & 0x0F); + if (part) { + part->_instrument.roland(p - 1); + if (part->clearToTransmit()) + part->_instrument.send(part->_mc); + } } } else if (a == YM2612_SYSEX_ID) { // FM-TOWNS custom instrument definition @@ -399,13 +401,13 @@ void Player::sysEx(const byte *p, uint16 len) { if (!_scanning) { for (a = 0; a < len + 1 && a < 19; ++a) { - sprintf((char *)&buf[a*3], " %02X", p[a]); + sprintf((char *)&buf[a * 3], " %02X", p[a]); } // next for if (a < len + 1) { - buf[a*3] = buf[a*3+1] = buf[a*3+2] = '.'; + buf[a * 3] = buf[a * 3 + 1] = buf[a * 3 + 2] = '.'; ++a; } // end if - buf[a*3] = '\0'; + buf[a * 3] = '\0'; debugC(DEBUG_IMUSE, "[%02d] SysEx:%s", _id, buf); } @@ -814,7 +816,7 @@ int Player::query_part_param(int param, byte chan) { return part->_vol; case 16: // FIXME: Need to know where this occurs... -error("Trying to cast instrument (%d, %d) -- please tell Fingolfin", param, chan); + error("Trying to cast instrument (%d, %d) -- please tell Fingolfin", param, chan); // In old versions of the code, this used to return part->_program. // This was changed in revision 2.29 of imuse.cpp (where this code used // to reside). @@ -845,9 +847,8 @@ void Player::onTimer() { uint beat_index = target_tick / TICKS_PER_BEAT + 1; uint tick_index = target_tick % TICKS_PER_BEAT; - if (_loop_counter &&(beat_index > _loop_from_beat || - (beat_index == _loop_from_beat && tick_index >= _loop_from_tick))) - { + if (_loop_counter && (beat_index > _loop_from_beat || + (beat_index == _loop_from_beat && tick_index >= _loop_from_tick))) { _loop_counter--; jump(_track_index, _loop_to_beat, _loop_to_tick); } @@ -891,15 +892,15 @@ int Player::addParameterFader(int param, int target, int time) { // target = target * 128 / 100; break; - case 127: - { // FIXME? I *think* this clears all parameter faders. - ParameterFader *ptr = &_parameterFaders[0]; - int i; - for (i = ARRAYSIZE(_parameterFaders); i; --i, ++ptr) - ptr->param = 0; - return 0; - } - break; + case 127: { + // FIXME? I *think* this clears all parameter faders. + ParameterFader *ptr = &_parameterFaders[0]; + int i; + for (i = ARRAYSIZE(_parameterFaders); i; --i, ++ptr) + ptr->param = 0; + return 0; + } + break; default: debug(0, "Player::addParameterFader(%d, %d, %d): Unknown parameter", param, target, time); @@ -1085,7 +1086,7 @@ void Player::saveLoadWithSerializer(Serializer *ser) { } ser->saveLoadEntries(this, playerEntries); ser->saveLoadArrayOf(_parameterFaders, ARRAYSIZE(_parameterFaders), - sizeof(ParameterFader), parameterFaderEntries); + sizeof(ParameterFader), parameterFaderEntries); return; } diff --git a/engines/scumm/imuse/instrument.cpp b/engines/scumm/imuse/instrument.cpp index 955700fc2b..11bb4e7605 100644 --- a/engines/scumm/imuse/instrument.cpp +++ b/engines/scumm/imuse/instrument.cpp @@ -114,14 +114,15 @@ roland_to_gm_map[] = { // { "trickle4 ", ??? } }; +// This emulates the percussion bank setup LEC used with the MT-32, +// where notes 24 - 34 were assigned instruments without reverb. +// It also fixes problems on GS devices that map sounds to these +// notes by default. const byte Instrument::_gmRhythmMap[35] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 36, 37, 38, 39, 40, 41, 66, 47, - 65, 48, 56}; - // This emulates the percussion bank setup LEC used with the MT-32, - // where notes 24 - 34 were assigned instruments without reverb. - // It also fixes problems on GS devices that map sounds to these - // notes by default. + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 36, 37, 38, 39, 40, 41, 66, 47, + 65, 48, 56 +}; class Instrument_Program : public InstrumentInternal { private: @@ -136,15 +137,16 @@ public: void copy_to(Instrument *dest) { dest->program(_program, _mt32); } bool is_valid() { return (_program < 128) && - ((_native_mt32 == _mt32) || _native_mt32 - ? (MidiDriver::_gmToMt32[_program] < 128) - : (MidiDriver::_mt32ToGm[_program] < 128)); } + ((_native_mt32 == _mt32) || _native_mt32 + ? (MidiDriver::_gmToMt32[_program] < 128) + : (MidiDriver::_mt32ToGm[_program] < 128)); + } }; class Instrument_AdLib : public InstrumentInternal { private: -#include "common/pack-start.h" // START STRUCT PACKING +#include "common/pack-start.h" // START STRUCT PACKING struct AdLibInstrument { byte flags_1; @@ -159,13 +161,17 @@ private: byte waveform_2; byte feedback; byte flags_a; - struct { byte a,b,c,d,e,f,g,h; } extra_a; + struct { + byte a, b, c, d, e, f, g, h; + } extra_a; byte flags_b; - struct { byte a,b,c,d,e,f,g,h; } extra_b; + struct { + byte a, b, c, d, e, f, g, h; + } extra_b; byte duration; } PACKED_STRUCT; -#include "common/pack-end.h" // END STRUCT PACKING +#include "common/pack-end.h" // END STRUCT PACKING AdLibInstrument _instrument; @@ -181,7 +187,7 @@ public: class Instrument_Roland : public InstrumentInternal { private: -#include "common/pack-start.h" // START STRUCT PACKING +#include "common/pack-start.h" // START STRUCT PACKING struct RolandInstrument { byte roland_id; @@ -242,11 +248,11 @@ private: byte checksum; } PACKED_STRUCT; -#include "common/pack-end.h" // END STRUCT PACKING +#include "common/pack-end.h" // END STRUCT PACKING RolandInstrument _instrument; - char _instrument_name [11]; + char _instrument_name[11]; uint8 getEquivalentGM(); @@ -259,6 +265,19 @@ public: bool is_valid() { return (_native_mt32 ? true : (_instrument_name[0] != '\0')); } }; +class Instrument_PcSpk : public InstrumentInternal { +public: + Instrument_PcSpk(const byte *data); + Instrument_PcSpk(Serializer *s); + void saveOrLoad(Serializer *s); + void send(MidiChannel *mc); + void copy_to(Instrument *dest) { dest->pcspk((byte *)&_instrument); } + bool is_valid() { return true; } + +private: + byte _instrument[23]; +}; + //////////////////////////////////////// // // Instrument class members @@ -299,7 +318,15 @@ void Instrument::roland(const byte *instrument) { _instrument = new Instrument_Roland(instrument); } -void Instrument::saveOrLoad (Serializer *s) { +void Instrument::pcspk(const byte *instrument) { + clear(); + if (!instrument) + return; + _type = itPcSpk; + _instrument = new Instrument_PcSpk(instrument); +} + +void Instrument::saveOrLoad(Serializer *s) { if (s->isSaving()) { s->saveByte(_type); if (_instrument) @@ -319,6 +346,9 @@ void Instrument::saveOrLoad (Serializer *s) { case itRoland: _instrument = new Instrument_Roland(s); break; + case itPcSpk: + _instrument = new Instrument_PcSpk(s); + break; default: warning("No known instrument classification #%d", (int)_type); _type = itNone; @@ -333,8 +363,8 @@ void Instrument::saveOrLoad (Serializer *s) { //////////////////////////////////////// Instrument_Program::Instrument_Program(byte program, bool mt32) : -_program (program), -_mt32 (mt32) { + _program(program), + _mt32(mt32) { if (program > 127) _program = 255; } @@ -413,7 +443,7 @@ Instrument_Roland::Instrument_Roland(const byte *data) { Instrument_Roland::Instrument_Roland(Serializer *s) { _instrument_name[0] = '\0'; if (!s->isSaving()) - saveOrLoad (s); + saveOrLoad(s); else memset(&_instrument, 0, sizeof(_instrument)); } @@ -470,4 +500,32 @@ uint8 Instrument_Roland::getEquivalentGM() { return 255; } +//////////////////////////////////////// +// +// Instrument_PcSpk class members +// +//////////////////////////////////////// + +Instrument_PcSpk::Instrument_PcSpk(const byte *data) { + memcpy(_instrument, data, sizeof(_instrument)); +} + +Instrument_PcSpk::Instrument_PcSpk(Serializer *s) { + if (!s->isSaving()) + saveOrLoad(s); + else + memset(_instrument, 0, sizeof(_instrument)); +} + +void Instrument_PcSpk::saveOrLoad(Serializer *s) { + if (s->isSaving()) + s->saveBytes(_instrument, sizeof(_instrument)); + else + s->loadBytes(_instrument, sizeof(_instrument)); +} + +void Instrument_PcSpk::send(MidiChannel *mc) { + mc->sysEx_customInstrument('SPK ', (byte *)&_instrument); +} + } // End of namespace Scumm diff --git a/engines/scumm/imuse/instrument.h b/engines/scumm/imuse/instrument.h index 3555d319e6..a855c64155 100644 --- a/engines/scumm/imuse/instrument.h +++ b/engines/scumm/imuse/instrument.h @@ -39,7 +39,6 @@ public: virtual void send(MidiChannel *mc) = 0; virtual void copy_to(Instrument *dest) = 0; virtual bool is_valid() = 0; - virtual operator int() { return 255; } }; class Instrument { @@ -52,10 +51,11 @@ public: itNone = 0, itProgram = 1, itAdLib = 2, - itRoland = 3 + itRoland = 3, + itPcSpk = 4 }; - Instrument() : _type (0), _instrument (0) { } + Instrument() : _type(0), _instrument(0) { } ~Instrument() { delete _instrument; } static void nativeMT32(bool native); static const byte _gmRhythmMap[35]; @@ -71,6 +71,7 @@ public: void program(byte program, bool mt32); void adlib(const byte *instrument); void roland(const byte *instrument); + void pcspk(const byte *instrument); byte getType() { return _type; } bool isValid() { return (_instrument ? _instrument->is_valid() : false); } diff --git a/engines/scumm/imuse/pcspk.cpp b/engines/scumm/imuse/pcspk.cpp new file mode 100644 index 0000000000..01e2ab3b7d --- /dev/null +++ b/engines/scumm/imuse/pcspk.cpp @@ -0,0 +1,835 @@ +/* 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. + */ + +#include "scumm/imuse/pcspk.h" + +#include "common/util.h" + +namespace Scumm { + +PcSpkDriver::PcSpkDriver(Audio::Mixer *mixer) + : MidiDriver_Emulated(mixer), _pcSpk(mixer->getOutputRate()) { +} + +PcSpkDriver::~PcSpkDriver() { + close(); +} + +int PcSpkDriver::open() { + if (_isOpen) + return MERR_ALREADY_OPEN; + + MidiDriver_Emulated::open(); + + for (uint i = 0; i < 6; ++i) + _channels[i].init(this, i); + _activeChannel = 0; + _effectTimer = 0; + _randBase = 1; + + // We need to take care we only send note frequencies, when the internal + // settings actually changed, thus we need some extra state to keep track + // of that. + _lastActiveChannel = 0; + _lastActiveOut = 0; + + // We set the output sound type to music here to allow sound volume + // adjustment. The drawback here is that we can not control the music and + // sfx separately here. But the AdLib output has the same issue so it + // should not be that bad. + _mixer->playStream(Audio::Mixer::kMusicSoundType, &_mixerSoundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true); + return 0; +} + +void PcSpkDriver::close() { + if (!_isOpen) + return; + _isOpen = false; + + _mixer->stopHandle(_mixerSoundHandle); +} + +void PcSpkDriver::send(uint32 d) { + assert((d & 0x0F) < 6); + _channels[(d & 0x0F)].send(d); +} + +void PcSpkDriver::sysEx_customInstrument(byte channel, uint32 type, const byte *instr) { + assert(channel < 6); + if (type == 'SPK ') + _channels[channel].sysEx_customInstrument(type, instr); +} + +MidiChannel *PcSpkDriver::allocateChannel() { + for (uint i = 0; i < 6; ++i) { + if (_channels[i].allocate()) + return &_channels[i]; + } + + return 0; +} + +void PcSpkDriver::generateSamples(int16 *buf, int len) { + _pcSpk.readBuffer(buf, len); +} + +void PcSpkDriver::onTimer() { + if (!_activeChannel) + return; + + for (uint i = 0; i < 6; ++i) { + OutputChannel &out = _channels[i]._out; + + if (!out.active) + continue; + + if (out.length == 0 || --out.length != 0) { + if (out.unkB && out.unkC) { + out.unkA += out.unkB; + if (out.instrument) + out.unkE = ((int8)out.instrument[out.unkA] * out.unkC) >> 4; + } + + ++_effectTimer; + if (_effectTimer > 3) { + _effectTimer = 0; + + if (out.effectEnvelopeA.state) + updateEffectGenerator(_channels[i], out.effectEnvelopeA, out.effectDefA); + if (out.effectEnvelopeB.state) + updateEffectGenerator(_channels[i], out.effectEnvelopeB, out.effectDefB); + } + } else { + out.active = 0; + updateNote(); + return; + } + } + + if (_activeChannel->_tl) { + output((_activeChannel->_out.note << 7) + _activeChannel->_pitchBend + _activeChannel->_out.unk60 + _activeChannel->_out.unkE); + } else { + _pcSpk.stop(); + _lastActiveChannel = 0; + _lastActiveOut = 0; + } +} + +void PcSpkDriver::updateNote() { + uint8 priority = 0; + _activeChannel = 0; + for (uint i = 0; i < 6; ++i) { + if (_channels[i]._allocated && _channels[i]._out.active && _channels[i]._priority >= priority) { + priority = _channels[i]._priority; + _activeChannel = &_channels[i]; + } + } + + if (_activeChannel == 0 || _activeChannel->_tl == 0) { + _pcSpk.stop(); + _lastActiveChannel = 0; + _lastActiveOut = 0; + } else { + output(_activeChannel->_pitchBend + (_activeChannel->_out.note << 7)); + } +} + +void PcSpkDriver::output(uint16 out) { + byte v1 = (out >> 7) & 0xFF; + byte v2 = (out >> 2) & 0x1E; + + byte shift = _outputTable1[v1]; + uint16 indexBase = _outputTable2[v1] << 5; + uint16 frequency = _frequencyTable[(indexBase + v2) / 2] >> shift; + + // Only output in case the active channel changed or the frequency changed. + // This is not faithful to the original. Since our timings differ we would + // get distorted sound otherwise though. + if (_lastActiveChannel != _activeChannel || _lastActiveOut != out) { + _pcSpk.play(Audio::PCSpeaker::kWaveFormSquare, 1193180 / frequency, -1); + _lastActiveChannel = _activeChannel; + _lastActiveOut = out; + } +} + +void PcSpkDriver::MidiChannel_PcSpk::init(PcSpkDriver *owner, byte channel) { + _owner = owner; + _channel = channel; + _allocated = false; + memset(&_out, 0, sizeof(_out)); +} + +bool PcSpkDriver::MidiChannel_PcSpk::allocate() { + if (_allocated) + return false; + + memset(&_out, 0, sizeof(_out)); + memset(_instrument, 0, sizeof(_instrument)); + _out.effectDefA.envelope = &_out.effectEnvelopeA; + _out.effectDefB.envelope = &_out.effectEnvelopeB; + + _allocated = true; + return true; +} + +MidiDriver *PcSpkDriver::MidiChannel_PcSpk::device() { + return _owner; +} + +byte PcSpkDriver::MidiChannel_PcSpk::getNumber() { + return _channel; +} + +void PcSpkDriver::MidiChannel_PcSpk::release() { + _out.active = 0; + _allocated = false; + _owner->updateNote(); +} + +void PcSpkDriver::MidiChannel_PcSpk::send(uint32 b) { + uint8 type = b & 0xF0; + uint8 p1 = (b >> 8) & 0xFF; + uint8 p2 = (b >> 16) & 0xFF; + + switch (type) { + case 0x80: + noteOff(p1); + break; + + case 0x90: + if (p2) + noteOn(p1, p2); + else + noteOff(p1); + break; + + case 0xB0: + controlChange(p1, p2); + break; + + case 0xE0: + pitchBend((p1 | (p2 << 7)) - 0x2000); + break; + + default: + break; + } +} + +void PcSpkDriver::MidiChannel_PcSpk::noteOff(byte note) { + if (!_allocated) + return; + + if (_sustain) { + if (_out.note == note) + _out.sustainNoteOff = 1; + } else { + if (_out.note == note) { + _out.active = 0; + _owner->updateNote(); + } + } +} + +void PcSpkDriver::MidiChannel_PcSpk::noteOn(byte note, byte velocity) { + if (!_allocated) + return; + + _out.note = note; + _out.sustainNoteOff = 0; + _out.length = _instrument[0]; + + if (_instrument[4] * 256 < ARRAYSIZE(PcSpkDriver::_outInstrumentData)) + _out.instrument = _owner->_outInstrumentData + _instrument[4] * 256; + else + _out.instrument = 0; + + _out.unkA = 0; + _out.unkB = _instrument[1]; + _out.unkC = _instrument[2]; + _out.unkE = 0; + _out.unk60 = 0; + _out.active = 1; + + // In case we get a note on event on the last active channel, we reset the + // last active channel, thus we assure the frequency is correctly set, even + // when the same note was sent. + if (_owner->_lastActiveChannel == this) { + _owner->_lastActiveChannel = 0; + _owner->_lastActiveOut = 0; + } + _owner->updateNote(); + + _out.unkC += PcSpkDriver::getEffectModifier(_instrument[3] + ((velocity & 0xFE) << 4)); + if (_out.unkC > 63) + _out.unkC = 63; + + if ((_instrument[5] & 0x80) != 0) + _owner->setupEffects(*this, _out.effectEnvelopeA, _out.effectDefA, _instrument[5], _instrument + 6); + + if ((_instrument[14] & 0x80) != 0) + _owner->setupEffects(*this, _out.effectEnvelopeB, _out.effectDefB, _instrument[14], _instrument + 15); +} + +void PcSpkDriver::MidiChannel_PcSpk::programChange(byte program) { + // Nothing to implement here, the iMuse code takes care of passing us the + // instrument data. +} + +void PcSpkDriver::MidiChannel_PcSpk::pitchBend(int16 bend) { + _pitchBend = (bend * _pitchBendFactor) >> 6; +} + +void PcSpkDriver::MidiChannel_PcSpk::controlChange(byte control, byte value) { + switch (control) { + case 1: + if (_out.effectEnvelopeA.state && _out.effectDefA.useModWheel) + _out.effectEnvelopeA.modWheelState = (value >> 2); + if (_out.effectEnvelopeB.state && _out.effectDefB.useModWheel) + _out.effectEnvelopeB.modWheelState = (value >> 2); + break; + + case 7: + _tl = value; + if (_owner->_activeChannel == this) { + if (_tl == 0) { + _owner->_lastActiveChannel = 0; + _owner->_lastActiveOut = 0; + _owner->_pcSpk.stop(); + } else { + _owner->output((_out.note << 7) + _pitchBend + _out.unk60 + _out.unkE); + } + } + break; + + case 64: + _sustain = value; + if (!value && _out.sustainNoteOff) { + _out.active = 0; + _owner->updateNote(); + } + break; + + case 123: + _out.active = 0; + _owner->updateNote(); + break; + + default: + break; + } +} + +void PcSpkDriver::MidiChannel_PcSpk::pitchBendFactor(byte value) { + _pitchBendFactor = value; +} + +void PcSpkDriver::MidiChannel_PcSpk::priority(byte value) { + _priority = value; +} + +void PcSpkDriver::MidiChannel_PcSpk::sysEx_customInstrument(uint32 type, const byte *instr) { + memcpy(_instrument, instr, sizeof(_instrument)); +} + +uint8 PcSpkDriver::getEffectModifier(uint16 level) { + uint8 base = level / 32; + uint8 index = level % 32; + + if (index == 0) + return 0; + + return (base * (index + 1)) >> 5; +} + +int16 PcSpkDriver::getEffectModLevel(int16 level, int8 mod) { + if (!mod) { + return 0; + } else if (mod == 31) { + return level; + } else if (level < -63 || level > 63) { + return (mod * (level + 1)) >> 6; + } else if (mod < 0) { + if (level < 0) + return getEffectModifier(((-level) << 5) - mod); + else + return -getEffectModifier((level << 5) - mod); + } else { + if (level < 0) + return -getEffectModifier(((-level) << 5) + mod); + else + return getEffectModifier(((-level) << 5) + mod); + } +} + +int16 PcSpkDriver::getRandMultipy(int16 input) { + if (_randBase & 1) + _randBase = (_randBase >> 1) ^ 0xB8; + else + _randBase >>= 1; + + return (_randBase * input) >> 8; +} + +void PcSpkDriver::setupEffects(MidiChannel_PcSpk &chan, EffectEnvelope &env, EffectDefinition &def, byte flags, const byte *data) { + def.phase = 0; + def.useModWheel = flags & 0x40; + env.loop = flags & 0x20; + def.type = flags & 0x1F; + + env.modWheelSensitivity = 31; + if (def.useModWheel) + env.modWheelState = chan._modWheel >> 2; + else + env.modWheelState = 31; + + switch (def.type) { + case 0: + env.maxLevel = 767; + env.startLevel = 383; + break; + + case 1: + env.maxLevel = 31; + env.startLevel = 15; + break; + + case 2: + env.maxLevel = 63; + env.startLevel = chan._out.unkB; + break; + + case 3: + env.maxLevel = 63; + env.startLevel = chan._out.unkC; + break; + + case 4: + env.maxLevel = 3; + env.startLevel = chan._instrument[4]; + break; + + case 5: + env.maxLevel = 62; + env.startLevel = 31; + env.modWheelState = 0; + break; + + case 6: + env.maxLevel = 31; + env.startLevel = 0; + env.modWheelSensitivity = 0; + break; + + default: + break; + } + + startEffect(env, data); +} + +void PcSpkDriver::startEffect(EffectEnvelope &env, const byte *data) { + env.state = 1; + env.currentLevel = 0; + env.modWheelLast = 31; + env.duration = data[0] * 63; + + env.stateTargetLevels[0] = data[1]; + env.stateTargetLevels[1] = data[3]; + env.stateTargetLevels[2] = data[5]; + env.stateTargetLevels[3] = data[6]; + + env.stateModWheelLevels[0] = data[2]; + env.stateModWheelLevels[1] = data[4]; + env.stateModWheelLevels[2] = 0; + env.stateModWheelLevels[3] = data[7]; + + initNextEnvelopeState(env); +} + +void PcSpkDriver::initNextEnvelopeState(EffectEnvelope &env) { + uint8 lastState = env.state - 1; + + uint16 stepCount = _effectEnvStepTable[getEffectModifier(((env.stateTargetLevels[lastState] & 0x7F) << 5) + env.modWheelSensitivity)]; + if (env.stateTargetLevels[lastState] & 0x80) + stepCount = getRandMultipy(stepCount); + if (!stepCount) + stepCount = 1; + + env.stateNumSteps = env.stateStepCounter = stepCount; + + int16 totalChange = 0; + if (lastState != 2) { + totalChange = getEffectModLevel(env.maxLevel, (env.stateModWheelLevels[lastState] & 0x7F) - 31); + if (env.stateModWheelLevels[lastState] & 0x80) + totalChange = getRandMultipy(totalChange); + + if (totalChange + env.startLevel > env.maxLevel) + totalChange = env.maxLevel - env.startLevel; + else if (totalChange + env.startLevel < 0) + totalChange = -env.startLevel; + + totalChange -= env.currentLevel; + } + + env.changePerStep = totalChange / stepCount; + if (totalChange < 0) { + totalChange = -totalChange; + env.dir = -1; + } else { + env.dir = 1; + } + env.changePerStepRem = totalChange % stepCount; + env.changeCountRem = 0; +} + +void PcSpkDriver::updateEffectGenerator(MidiChannel_PcSpk &chan, EffectEnvelope &env, EffectDefinition &def) { + if (advanceEffectEnvelope(env, def) & 1) { + switch (def.type) { + case 0: case 1: + chan._out.unk60 = def.phase << 4; + break; + + case 2: + chan._out.unkB = (def.phase & 0xFF) + chan._instrument[1]; + break; + + case 3: + chan._out.unkC = (def.phase & 0xFF) + chan._instrument[2]; + break; + + case 4: + if ((chan._instrument[4] + (def.phase & 0xFF)) * 256 < ARRAYSIZE(_outInstrumentData)) + chan._out.instrument = _outInstrumentData + (chan._instrument[4] + (def.phase & 0xFF)) * 256; + else + chan._out.instrument = 0; + break; + + case 5: + env.modWheelState = (def.phase & 0xFF); + break; + + case 6: + env.modWheelSensitivity = (def.phase & 0xFF); + break; + + default: + break; + } + } +} + +uint8 PcSpkDriver::advanceEffectEnvelope(EffectEnvelope &env, EffectDefinition &def) { + if (env.duration != 0) { + env.duration -= 17; + if (env.duration <= 0) { + env.state = 0; + return 0; + } + } + + uint8 changedFlags = 0; + int16 newLevel = env.currentLevel + env.changePerStep; + env.changeCountRem += env.changePerStepRem; + if (env.changeCountRem >= env.stateNumSteps) { + env.changeCountRem -= env.stateNumSteps; + newLevel += env.dir; + } + + if (env.currentLevel != newLevel || env.modWheelLast != env.modWheelState) { + env.currentLevel = newLevel; + env.modWheelLast = env.modWheelState; + + int16 newPhase = getEffectModLevel(newLevel, env.modWheelState); + if (def.phase != newPhase) { + changedFlags |= 1; + def.phase = newPhase; + } + } + + --env.stateStepCounter; + if (!env.stateStepCounter) { + ++env.state; + if (env.state > 4) { + if (env.loop) { + env.state = 1; + changedFlags |= 2; + } else { + env.state = 0; + return changedFlags; + } + } + + initNextEnvelopeState(env); + } + + return changedFlags; +} + +const byte PcSpkDriver::_outInstrumentData[1024] = { + 0x00, 0x03, 0x06, 0x09, 0x0C, 0x0F, 0x12, 0x15, + 0x18, 0x1B, 0x1E, 0x21, 0x24, 0x27, 0x2A, 0x2D, + 0x30, 0x33, 0x36, 0x39, 0x3B, 0x3E, 0x41, 0x43, + 0x46, 0x49, 0x4B, 0x4E, 0x50, 0x52, 0x55, 0x57, + 0x59, 0x5B, 0x5E, 0x60, 0x62, 0x64, 0x66, 0x67, + 0x69, 0x6B, 0x6C, 0x6E, 0x70, 0x71, 0x72, 0x74, + 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7B, + 0x7C, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7D, 0x7D, + 0x7C, 0x7B, 0x7B, 0x7A, 0x79, 0x78, 0x77, 0x76, + 0x75, 0x74, 0x72, 0x71, 0x70, 0x6E, 0x6C, 0x6B, + 0x69, 0x67, 0x66, 0x64, 0x62, 0x60, 0x5E, 0x5B, + 0x59, 0x57, 0x55, 0x52, 0x50, 0x4E, 0x4B, 0x49, + 0x46, 0x43, 0x41, 0x3E, 0x3B, 0x39, 0x36, 0x33, + 0x30, 0x2D, 0x2A, 0x27, 0x24, 0x21, 0x1E, 0x1B, + 0x18, 0x15, 0x12, 0x0F, 0x0C, 0x09, 0x06, 0x03, + 0x00, 0xFD, 0xFA, 0xF7, 0xF4, 0xF1, 0xEE, 0xEB, + 0xE8, 0xE5, 0xE2, 0xDF, 0xDC, 0xD9, 0xD6, 0xD3, + 0xD0, 0xCD, 0xCA, 0xC7, 0xC5, 0xC2, 0xBF, 0xBD, + 0xBA, 0xB7, 0xB5, 0xB2, 0xB0, 0xAE, 0xAB, 0xA9, + 0xA7, 0xA5, 0xA2, 0xA0, 0x9E, 0x9C, 0x9A, 0x99, + 0x97, 0x95, 0x94, 0x92, 0x90, 0x8F, 0x8E, 0x8C, + 0x8B, 0x8A, 0x89, 0x88, 0x87, 0x86, 0x85, 0x85, + 0x84, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82, 0x82, + 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x83, 0x83, + 0x84, 0x85, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, + 0x8B, 0x8C, 0x8E, 0x8F, 0x90, 0x92, 0x94, 0x95, + 0x97, 0x99, 0x9A, 0x9C, 0x9E, 0xA0, 0xA2, 0xA5, + 0xA7, 0xA9, 0xAB, 0xAE, 0xB0, 0xB2, 0xB5, 0xB7, + 0xBA, 0xBD, 0xBF, 0xC2, 0xC5, 0xC7, 0xCA, 0xCD, + 0xD0, 0xD3, 0xD6, 0xD9, 0xDC, 0xDF, 0xE2, 0xE5, + 0xE8, 0xEB, 0xEE, 0xF1, 0xF4, 0xF7, 0xFA, 0xFD, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, + 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, + 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, + 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, + 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, + 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, + 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, + 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, + 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0x29, 0x23, 0xBE, 0x84, 0xE1, 0x6C, 0xD6, 0xAE, + 0x52, 0x90, 0x49, 0xF1, 0xF1, 0xBB, 0xE9, 0xEB, + 0xB3, 0xA6, 0xDB, 0x3C, 0x87, 0x0C, 0x3E, 0x99, + 0x24, 0x5E, 0x0D, 0x1C, 0x06, 0xB7, 0x47, 0xDE, + 0xB3, 0x12, 0x4D, 0xC8, 0x43, 0xBB, 0x8B, 0xA6, + 0x1F, 0x03, 0x5A, 0x7D, 0x09, 0x38, 0x25, 0x1F, + 0x5D, 0xD4, 0xCB, 0xFC, 0x96, 0xF5, 0x45, 0x3B, + 0x13, 0x0D, 0x89, 0x0A, 0x1C, 0xDB, 0xAE, 0x32, + 0x20, 0x9A, 0x50, 0xEE, 0x40, 0x78, 0x36, 0xFD, + 0x12, 0x49, 0x32, 0xF6, 0x9E, 0x7D, 0x49, 0xDC, + 0xAD, 0x4F, 0x14, 0xF2, 0x44, 0x40, 0x66, 0xD0, + 0x6B, 0xC4, 0x30, 0xB7, 0x32, 0x3B, 0xA1, 0x22, + 0xF6, 0x22, 0x91, 0x9D, 0xE1, 0x8B, 0x1F, 0xDA, + 0xB0, 0xCA, 0x99, 0x02, 0xB9, 0x72, 0x9D, 0x49, + 0x2C, 0x80, 0x7E, 0xC5, 0x99, 0xD5, 0xE9, 0x80, + 0xB2, 0xEA, 0xC9, 0xCC, 0x53, 0xBF, 0x67, 0xD6, + 0xBF, 0x14, 0xD6, 0x7E, 0x2D, 0xDC, 0x8E, 0x66, + 0x83, 0xEF, 0x57, 0x49, 0x61, 0xFF, 0x69, 0x8F, + 0x61, 0xCD, 0xD1, 0x1E, 0x9D, 0x9C, 0x16, 0x72, + 0x72, 0xE6, 0x1D, 0xF0, 0x84, 0x4F, 0x4A, 0x77, + 0x02, 0xD7, 0xE8, 0x39, 0x2C, 0x53, 0xCB, 0xC9, + 0x12, 0x1E, 0x33, 0x74, 0x9E, 0x0C, 0xF4, 0xD5, + 0xD4, 0x9F, 0xD4, 0xA4, 0x59, 0x7E, 0x35, 0xCF, + 0x32, 0x22, 0xF4, 0xCC, 0xCF, 0xD3, 0x90, 0x2D, + 0x48, 0xD3, 0x8F, 0x75, 0xE6, 0xD9, 0x1D, 0x2A, + 0xE5, 0xC0, 0xF7, 0x2B, 0x78, 0x81, 0x87, 0x44, + 0x0E, 0x5F, 0x50, 0x00, 0xD4, 0x61, 0x8D, 0xBE, + 0x7B, 0x05, 0x15, 0x07, 0x3B, 0x33, 0x82, 0x1F, + 0x18, 0x70, 0x92, 0xDA, 0x64, 0x54, 0xCE, 0xB1, + 0x85, 0x3E, 0x69, 0x15, 0xF8, 0x46, 0x6A, 0x04, + 0x96, 0x73, 0x0E, 0xD9, 0x16, 0x2F, 0x67, 0x68, + 0xD4, 0xF7, 0x4A, 0x4A, 0xD0, 0x57, 0x68, 0x76 +}; + +const byte PcSpkDriver::_outputTable1[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7 +}; + +const byte PcSpkDriver::_outputTable2[] = { + 0, 1, 2, 3, + 4, 5, 6, 7, + 8, 9, 10, 11, + 0, 1, 2, 3, + 4, 5, 6, 7, + 8, 9, 10, 11, + 0, 1, 2, 3, + 4, 5, 6, 7, + 8, 9, 10, 11, + 0, 1, 2, 3, + 4, 5, 6, 7, + 8, 9, 10, 11, + 0, 1, 2, 3, + 4, 5, 6, 7, + 8, 9, 10, 11, + 0, 1, 2, 3, + 4, 5, 6, 7, + 8, 9, 10, 11, + 0, 1, 2, 3, + 4, 5, 6, 7, + 8, 9, 10, 11, + 0, 1, 2, 3, + 4, 5, 6, 7, + 8, 9, 10, 11, + 0, 1, 2, 3, + 4, 5, 6, 7, + 8, 9, 10, 11, + 0, 1, 2, 3, + 4, 5, 6, 7, + 8, 9, 10, 11, + 0, 1, 2, 3, + 4, 5, 6, 7 +}; + +const uint16 PcSpkDriver::_effectEnvStepTable[] = { + 1, 2, 4, 5, + 6, 7, 8, 9, + 10, 12, 14, 16, + 18, 21, 24, 30, + 36, 50, 64, 82, + 100, 136, 160, 192, + 240, 276, 340, 460, + 600, 860, 1200, 1600 +}; + +const uint16 PcSpkDriver::_frequencyTable[] = { + 0x8E84, 0x8E00, 0x8D7D, 0x8CFA, + 0x8C78, 0x8BF7, 0x8B76, 0x8AF5, + 0x8A75, 0x89F5, 0x8976, 0x88F7, + 0x8879, 0x87FB, 0x877D, 0x8700, + 0x8684, 0x8608, 0x858C, 0x8511, + 0x8496, 0x841C, 0x83A2, 0x8328, + 0x82AF, 0x8237, 0x81BF, 0x8147, + 0x80D0, 0x8059, 0x7FE3, 0x7F6D, + 0x7EF7, 0x7E82, 0x7E0D, 0x7D99, + 0x7D25, 0x7CB2, 0x7C3F, 0x7BCC, + 0x7B5A, 0x7AE8, 0x7A77, 0x7A06, + 0x7995, 0x7925, 0x78B5, 0x7846, + 0x77D7, 0x7768, 0x76FA, 0x768C, + 0x761F, 0x75B2, 0x7545, 0x74D9, + 0x746D, 0x7402, 0x7397, 0x732C, + 0x72C2, 0x7258, 0x71EF, 0x7186, + 0x711D, 0x70B5, 0x704D, 0x6FE5, + 0x6F7E, 0x6F17, 0x6EB0, 0x6E4A, + 0x6DE5, 0x6D7F, 0x6D1A, 0x6CB5, + 0x6C51, 0x6BED, 0x6B8A, 0x6B26, + 0x6AC4, 0x6A61, 0x69FF, 0x699D, + 0x693C, 0x68DB, 0x687A, 0x681A, + 0x67BA, 0x675A, 0x66FA, 0x669B, + 0x663D, 0x65DF, 0x6581, 0x6523, + 0x64C6, 0x6469, 0x640C, 0x63B0, + 0x6354, 0x62F8, 0x629D, 0x6242, + 0x61E7, 0x618D, 0x6133, 0x60D9, + 0x6080, 0x6027, 0x5FCE, 0x5F76, + 0x5F1E, 0x5EC6, 0x5E6E, 0x5E17, + 0x5DC1, 0x5D6A, 0x5D14, 0x5CBE, + 0x5C68, 0x5C13, 0x5BBE, 0x5B6A, + 0x5B15, 0x5AC1, 0x5A6E, 0x5A1A, + 0x59C7, 0x5974, 0x5922, 0x58CF, + 0x587D, 0x582C, 0x57DA, 0x5789, + 0x5739, 0x56E8, 0x5698, 0x5648, + 0x55F9, 0x55A9, 0x555A, 0x550B, + 0x54BD, 0x546F, 0x5421, 0x53D3, + 0x5386, 0x5339, 0x52EC, 0x52A0, + 0x5253, 0x5207, 0x51BC, 0x5170, + 0x5125, 0x50DA, 0x5090, 0x5046, + 0x4FFB, 0x4FB2, 0x4F68, 0x4F1F, + 0x4ED6, 0x4E8D, 0x4E45, 0x4DFC, + 0x4DB5, 0x4D6D, 0x4D25, 0x4CDE, + 0x4C97, 0x4C51, 0x4C0A, 0x4BC4, + 0x4B7E, 0x4B39, 0x4AF3, 0x4AAE, + 0x4A69, 0x4A24, 0x49E0, 0x499C, + 0x4958, 0x4914, 0x48D1, 0x488E, + 0x484B, 0x4808, 0x47C6, 0x4783 +}; + +} // End of namespace Scumm + diff --git a/engines/scumm/imuse/pcspk.h b/engines/scumm/imuse/pcspk.h new file mode 100644 index 0000000000..e77ac8c1bf --- /dev/null +++ b/engines/scumm/imuse/pcspk.h @@ -0,0 +1,161 @@ +/* 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 SCUMM_IMUSE_PCSPK_H +#define SCUMM_IMUSE_PCSPK_H + +#include "audio/softsynth/emumidi.h" +#include "audio/softsynth/pcspk.h" + +namespace Scumm { + +class PcSpkDriver : public MidiDriver_Emulated { +public: + PcSpkDriver(Audio::Mixer *mixer); + ~PcSpkDriver(); + + virtual int open(); + virtual void close(); + + virtual void send(uint32 d); + virtual void sysEx_customInstrument(byte channel, uint32 type, const byte *instr); + + virtual MidiChannel *allocateChannel(); + virtual MidiChannel *getPercussionChannel() { return 0; } + + bool isStereo() const { return _pcSpk.isStereo(); } + int getRate() const { return _pcSpk.getRate(); } +protected: + void generateSamples(int16 *buf, int len); + void onTimer(); + +private: + Audio::PCSpeaker _pcSpk; + int _effectTimer; + uint8 _randBase; + + void updateNote(); + void output(uint16 out); + + static uint8 getEffectModifier(uint16 level); + int16 getEffectModLevel(int16 level, int8 mod); + int16 getRandMultipy(int16 input); + + struct EffectEnvelope { + uint8 state; + int16 currentLevel; + int16 duration; + int16 maxLevel; + int16 startLevel; + uint8 loop; + uint8 stateTargetLevels[4]; + uint8 stateModWheelLevels[4]; + uint8 modWheelSensitivity; + uint8 modWheelState; + uint8 modWheelLast; + int16 stateNumSteps; + int16 stateStepCounter; + int16 changePerStep; + int8 dir; + int16 changePerStepRem; + int16 changeCountRem; + }; + + struct EffectDefinition { + int16 phase; + uint8 type; + uint8 useModWheel; + EffectEnvelope *envelope; + }; + + struct OutputChannel { + uint8 active; + uint8 note; + uint8 sustainNoteOff; + uint8 length; + const uint8 *instrument; + uint8 unkA; + uint8 unkB; + uint8 unkC; + int16 unkE; + EffectEnvelope effectEnvelopeA; + EffectDefinition effectDefA; + EffectEnvelope effectEnvelopeB; + EffectDefinition effectDefB; + int16 unk60; + }; + + struct MidiChannel_PcSpk : public MidiChannel { + virtual MidiDriver *device(); + virtual byte getNumber(); + virtual void release(); + + virtual void send(uint32 b); + virtual void noteOff(byte note); + virtual void noteOn(byte note, byte velocity); + virtual void programChange(byte program); + virtual void pitchBend(int16 bend); + virtual void controlChange(byte control, byte value); + virtual void pitchBendFactor(byte value); + virtual void priority(byte value); + virtual void sysEx_customInstrument(uint32 type, const byte *instr); + + void init(PcSpkDriver *owner, byte channel); + bool allocate(); + + PcSpkDriver *_owner; + bool _allocated; + byte _channel; + + OutputChannel _out; + uint8 _instrument[23]; + uint8 _programNr; + uint8 _priority; + uint8 _tl; + uint8 _modWheel; + uint8 _sustain; + uint8 _pitchBendFactor; + int16 _pitchBend; + }; + + void setupEffects(MidiChannel_PcSpk &chan, EffectEnvelope &env, EffectDefinition &def, byte flags, const byte *data); + void startEffect(EffectEnvelope &env, const byte *data); + void initNextEnvelopeState(EffectEnvelope &env); + void updateEffectGenerator(MidiChannel_PcSpk &chan, EffectEnvelope &env, EffectDefinition &def); + uint8 advanceEffectEnvelope(EffectEnvelope &env, EffectDefinition &def); + + MidiChannel_PcSpk _channels[6]; + MidiChannel_PcSpk *_activeChannel; + + MidiChannel_PcSpk *_lastActiveChannel; + uint16 _lastActiveOut; + + static const byte _outInstrumentData[1024]; + static const byte _outputTable1[]; + static const byte _outputTable2[]; + static const uint16 _effectEnvStepTable[]; + static const uint16 _frequencyTable[]; +}; + +} // End of namespace Scumm + +#endif + diff --git a/engines/scumm/imuse/sysex_samnmax.cpp b/engines/scumm/imuse/sysex_samnmax.cpp index 4c4219e7bb..a4f525da56 100644 --- a/engines/scumm/imuse/sysex_samnmax.cpp +++ b/engines/scumm/imuse/sysex_samnmax.cpp @@ -53,8 +53,7 @@ void sysexHandler_SamNMax(Player *player, const byte *msg, uint16 len) { // something magical is supposed to happen.... for (a = 0; a < ARRAYSIZE(se->_snm_triggers); ++a) { if (se->_snm_triggers[a].sound == player->_id && - se->_snm_triggers[a].id == *p) - { + se->_snm_triggers[a].id == *p) { se->_snm_triggers[a].sound = se->_snm_triggers[a].id = 0; se->doCommand(8, se->_snm_triggers[a].command); break; diff --git a/engines/scumm/imuse/sysex_scumm.cpp b/engines/scumm/imuse/sysex_scumm.cpp index c3bec93a60..85ffc86f47 100644 --- a/engines/scumm/imuse/sysex_scumm.cpp +++ b/engines/scumm/imuse/sysex_scumm.cpp @@ -49,50 +49,52 @@ void sysexHandler_Scumm(Player *player, const byte *msg, uint16 len) { switch (code = *p++) { case 0: // Allocate new part. - // There are 17 bytes of useful information here. + // There are 8 bytes (after decoding!) of useful information here. // Here is what we know about them so far: - // BYTE 00: Channel # - // BYTE 02: BIT 01(0x01): Part on?(1 = yes) + // BYTE 0: Channel # + // BYTE 1: BIT 01(0x01): Part on?(1 = yes) // BIT 02(0x02): Reverb? (1 = yes) [bug #1088045] - // BYTE 04: Priority adjustment [guessing] - // BYTE 05: Volume(upper 4 bits) [guessing] - // BYTE 06: Volume(lower 4 bits) [guessing] - // BYTE 07: Pan(upper 4 bits) [bug #1088045] - // BYTE 08: Pan(lower 4 bits) [bug #1088045] - // BYTE 09: BIT 04(0x08): Percussion?(1 = yes) - // BYTE 13: Pitchbend range(upper 4 bits) [bug #1088045] - // BYTE 14: Pitchbend range(lower 4 bits) [bug #1088045] - // BYTE 15: Program(upper 4 bits) - // BYTE 16: Program(lower 4 bits) - - // athrxx (05-21-2011): - // BYTE 9, 10: Transpose (if set to 0x80, this means that part->_transpose_eff will be 0 (also ignoring player->_transpose) - // BYTE 11, 12: Detune + // BYTE 2: Priority adjustment + // BYTE 3: Volume [guessing] + // BYTE 4: Pan [bug #1088045] + // BYTE 5: BIT 8(0x80): Percussion?(1 = yes) [guessed?] + // BYTE 5: Transpose, if set to 0x80(=-1) it means no transpose + // BYTE 6: Detune + // BYTE 7: Pitchbend factor [bug #1088045] + // BYTE 8: Program part = player->getPart(p[0] & 0x0F); + player->decode_sysex_bytes(p + 1, buf + 1, len - 1); if (part) { - part->set_onoff(p[2] & 0x01); - part->effectLevel((p[2] & 0x02) ? 127 : 0); - part->set_pri(p[4]); - part->volume((p[5] & 0x0F) << 4 |(p[6] & 0x0F)); - part->set_pan((p[7] & 0x0F) << 4 | (p[8] & 0x0F)); - part->_percussion = player->_isMIDI ? ((p[9] & 0x08) > 0) : false; - part->set_transpose((p[9] & 0x0F) << 4 | (p[10] & 0x0F)); - part->set_detune((p[11] & 0x0F) << 4 | (p[12] & 0x0F)); - part->pitchBendFactor((p[13] & 0x0F) << 4 | (p[14] & 0x0F)); + part->set_onoff(buf[1] & 0x01); + part->effectLevel((buf[1] & 0x02) ? 127 : 0); + part->set_pri(buf[2]); + part->volume(buf[3]); + part->set_pan(buf[4]); + part->_percussion = player->_isMIDI ? ((buf[5] & 0x80) > 0) : false; + part->set_transpose(buf[5]); + part->set_detune(buf[6]); + part->pitchBendFactor(buf[7]); if (part->_percussion) { if (part->_mc) { part->off(); se->reallocateMidiChannels(player->_midi); } } else { - // Even in cases where a program does not seem to be specified, - // i.e. bytes 15 and 16 are 0, we send a program change because - // 0 is a valid program number. MI2 tests show that in such - // cases, a regular program change message always seems to follow - // anyway. - if (player->_isMIDI) - part->_instrument.program((p[15] & 0x0F) << 4 |(p[16] & 0x0F), player->_isMT32); + if (player->_isMIDI) { + // Even in cases where a program does not seem to be specified, + // i.e. bytes 15 and 16 are 0, we send a program change because + // 0 is a valid program number. MI2 tests show that in such + // cases, a regular program change message always seems to follow + // anyway. + part->_instrument.program(buf[8], player->_isMT32); + } else { + // Like the original we set up the instrument data of the + // specified program here too. In case the global + // instrument data is not loaded already, this will take + // care of setting a default instrument too. + se->copyGlobalInstrument(buf[8], &part->_instrument); + } part->sendAll(); } } @@ -113,11 +115,10 @@ void sysexHandler_Scumm(Player *player, const byte *msg, uint16 len) { ++p; // Skip hardware type part = player->getPart(a); if (part) { - if (len == 62) { + if (len == 62 || len == 48) { player->decode_sysex_bytes(p, buf, len - 2); part->set_instrument((byte *)buf); } else { - // SPK tracks have len == 48 here, and are not supported part->programChange(254); // Must be invalid, but not 255 (which is reserved) } } @@ -127,7 +128,8 @@ void sysexHandler_Scumm(Player *player, const byte *msg, uint16 len) { p += 2; // Skip hardware type and... whatever came right before it a = *p++; player->decode_sysex_bytes(p, buf, len - 3); - se->setGlobalAdLibInstrument(a, buf); + if (len == 63 || len == 49) + se->setGlobalInstrument(a, buf); break; case 33: // Parameter adjust @@ -185,10 +187,9 @@ void sysexHandler_Scumm(Player *player, const byte *msg, uint16 len) { case 80: // Loop player->decode_sysex_bytes(p + 1, buf, len - 1); - player->setLoop - (READ_BE_UINT16(buf), READ_BE_UINT16(buf + 2), - READ_BE_UINT16(buf + 4), READ_BE_UINT16(buf + 6), - READ_BE_UINT16(buf + 8)); + player->setLoop(READ_BE_UINT16(buf), READ_BE_UINT16(buf + 2), + READ_BE_UINT16(buf + 4), READ_BE_UINT16(buf + 6), + READ_BE_UINT16(buf + 8)); break; case 81: // End loop diff --git a/engines/scumm/imuse_digi/dimuse_codecs.cpp b/engines/scumm/imuse_digi/dimuse_codecs.cpp index 69cd89320c..6edfe0bd33 100644 --- a/engines/scumm/imuse_digi/dimuse_codecs.cpp +++ b/engines/scumm/imuse_digi/dimuse_codecs.cpp @@ -105,7 +105,9 @@ static const byte imxOtherTable[6][64] = { void releaseImcTables() { free(_destImcTable); + _destImcTable = NULL; free(_destImcTable2); + _destImcTable2 = NULL; } void initializeImcTables() { diff --git a/engines/scumm/module.mk b/engines/scumm/module.mk index 1a60564a9e..99ffdf7f21 100644 --- a/engines/scumm/module.mk +++ b/engines/scumm/module.mk @@ -27,6 +27,7 @@ MODULE_OBJS := \ imuse/imuse_part.o \ imuse/imuse_player.o \ imuse/instrument.o \ + imuse/pcspk.o \ imuse/sysex_samnmax.o \ imuse/sysex_scumm.o \ input.o \ diff --git a/engines/scumm/script_v4.cpp b/engines/scumm/script_v4.cpp index 1302c8c28d..8340f62dbc 100644 --- a/engines/scumm/script_v4.cpp +++ b/engines/scumm/script_v4.cpp @@ -68,6 +68,18 @@ void ScummEngine_v4::o4_ifState() { int a = getVarOrDirectWord(PARAM_1); int b = getVarOrDirectByte(PARAM_2); + // WORKAROUND bug #3306145 (also occurs in original): Some old versions of + // Indy3 sometimes fail to allocate IQ points correctly. To quote: + // "About the points error leaving Castle Brunwald: It seems to "reversed"! + // When you get caught, free yourself and escape, you get 25 IQ points even + // though you're not supposed to. However if you escape WITHOUT getting + // caught, you get 0 IQ points (supposed to get 25 IQ points)." + // This workaround is meant to address that. + if (_game.id == GID_INDY3 && a == 367 && + vm.slot[_currentScript].number == 363 && _currentRoom == 25) { + b = 0; + } + jumpRelative(getState(a) == b); } diff --git a/engines/scumm/script_v5.cpp b/engines/scumm/script_v5.cpp index a6cf504586..02c8d977a5 100644 --- a/engines/scumm/script_v5.cpp +++ b/engines/scumm/script_v5.cpp @@ -2095,6 +2095,20 @@ void ScummEngine_v5::o5_startScript() { if (_game.id == GID_ZAK && _game.platform == Common::kPlatformFMTowns && script == 171) return; + // WORKAROUND bug #3306145 (also occurs in original): Some old versions of + // Indy3 sometimes fail to allocate IQ points correctly. To quote: + // "In the Amiga version you get the 15 points for puzzle 30 if you give the + // book or KO the guy. The PC version correctly gives 10 points for puzzle + // 29 for KO and 15 for puzzle 30 when giving the book." + // This workaround is meant to address that. + if (_game.id == GID_INDY3 && vm.slot[_currentScript].number == 106 && script == 125 && VAR(115) != 2) { + // If Var[115] != 2, then: + // Correct: startScript(125,[29,10]); + // Wrong : startScript(125,[30,15]); + data[0] = 29; + data[1] = 10; + } + // Method used by original games to skip copy protection scheme if (!_copyProtection) { // Copy protection was disabled in LucasArts Classic Adventures (PC Disk) diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index 7b136dc36d..0f01e39459 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -71,6 +71,7 @@ #include "scumm/he/cup_player_he.h" #include "scumm/util.h" #include "scumm/verbs.h" +#include "scumm/imuse/pcspk.h" #include "backends/audiocd/audiocd.h" @@ -283,8 +284,9 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr) _16BitPalette = NULL; #ifndef DISABLE_TOWNS_DUAL_LAYER_MODE _townsScreen = 0; +#ifdef USE_RGB_COLOR _cjkFont = 0; - _cjkChar = 0; +#endif #endif _shadowPalette = NULL; _shadowPaletteSize = 0; @@ -633,8 +635,10 @@ ScummEngine::~ScummEngine() { #ifndef DISABLE_TOWNS_DUAL_LAYER_MODE delete _townsScreen; +#ifdef USE_RGB_COLOR delete _cjkFont; #endif +#endif delete _debugger; @@ -1350,13 +1354,23 @@ void ScummEngine::setupCharsetRenderer() { _charset = new CharsetRendererPCE(this); else #endif + if (_game.platform == Common::kPlatformFMTowns) + _charset = new CharsetRendererTownsV3(this); + else _charset = new CharsetRendererV3(this); #ifdef ENABLE_SCUMM_7_8 } else if (_game.version == 8) { _charset = new CharsetRendererNut(this); #endif } else { - _charset = new CharsetRendererClassic(this); +#ifdef USE_RGB_COLOR +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE + if (_game.platform == Common::kPlatformFMTowns) + _charset = new CharsetRendererTownsClassic(this); + else +#endif +#endif + _charset = new CharsetRendererClassic(this); } } @@ -1857,14 +1871,16 @@ void ScummEngine::setupMusic(int midi) { MidiDriver *nativeMidiDriver = 0; MidiDriver *adlibMidiDriver = 0; - if (_musicType != MDT_ADLIB && _musicType != MDT_TOWNS) + if (_musicType != MDT_ADLIB && _musicType != MDT_TOWNS && _musicType != MDT_PCSPK) nativeMidiDriver = MidiDriver::createMidi(dev); if (nativeMidiDriver != NULL && _native_mt32) nativeMidiDriver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE); - bool multi_midi = ConfMan.getBool("multi_midi") && _musicType != MDT_NONE && (midi & MDT_ADLIB); + bool multi_midi = ConfMan.getBool("multi_midi") && _musicType != MDT_NONE && _musicType != MDT_PCSPK && (midi & MDT_ADLIB); if (_musicType == MDT_ADLIB || _musicType == MDT_TOWNS || multi_midi) { adlibMidiDriver = MidiDriver::createMidi(MidiDriver::detectDevice(_musicType == MDT_TOWNS ? MDT_TOWNS : MDT_ADLIB)); adlibMidiDriver->property(MidiDriver::PROP_OLD_ADLIB, (_game.features & GF_SMALL_HEADER) ? 1 : 0); + } else if (_musicType == MDT_PCSPK) { + adlibMidiDriver = new PcSpkDriver(_mixer); } _imuse = IMuse::create(_system, nativeMidiDriver, adlibMidiDriver); @@ -1893,6 +1909,8 @@ void ScummEngine::setupMusic(int midi) { _imuse->property(IMuse::PROP_LIMIT_PLAYERS, 1); _imuse->property(IMuse::PROP_RECYCLE_PLAYERS, 1); } + if (_musicType == MDT_PCSPK) + _imuse->property(IMuse::PROP_PC_SPEAKER, 1); } } } diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h index 01bde90e1c..e503af750d 100644 --- a/engines/scumm/scumm.h +++ b/engines/scumm/scumm.h @@ -46,9 +46,10 @@ /* This disables the dual layer mode which is used in FM-Towns versions * of SCUMM games and which emulates the behavior of the original code. * The only purpose is code size reduction for certain backends. - * SCUMM 3 (FM-Towns) games will run in normal (DOS VGA) mode, which should - * work just fine in most situations. Some glitches might occur. SCUMM 5 games - * will not work without dual layer (and 16 bit color) support. + * SCUMM 3 (FM-Towns) games will run in English in normal (DOS VGA) mode, + * which should work just fine in most situations. Some glitches might + * occur. Japanese mode and SCUMM 5 FM-Towns games will not work without + * dual layer (and 16 bit color) support. */ #define DISABLE_TOWNS_DUAL_LAYER_MODE #endif @@ -345,6 +346,7 @@ class ResourceManager; class ScummEngine : public Engine { friend class ScummDebugger; friend class CharsetRenderer; + friend class CharsetRendererTownsClassic; friend class ResourceManager; public: @@ -1326,14 +1328,17 @@ public: // Exists both in V7 and in V72HE: byte VAR_NUM_GLOBAL_OBJS; +#ifdef USE_RGB_COLOR + // FM-Towns / PC-Engine specific + Graphics::FontSJIS *_cjkFont; +#endif + // FM-Towns specific #ifndef DISABLE_TOWNS_DUAL_LAYER_MODE public: bool towns_isRectInStringBox(int x1, int y1, int x2, int y2); byte _townsPaletteFlags; - byte _townsCharsetColorMap[16]; - Graphics::FontSJIS *_cjkFont; - uint16 _cjkChar; + byte _townsCharsetColorMap[16]; protected: void towns_drawStripToScreen(VirtScreen *vs, int dstX, int dstY, int srcX, int srcY, int w, int h); diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp index 27e43b3740..c3cad19fdc 100644 --- a/engines/scumm/sound.cpp +++ b/engines/scumm/sound.cpp @@ -1137,14 +1137,27 @@ int ScummEngine::readSoundResource(ResId idx) { break; case MKTAG('S','P','K',' '): pri = -1; -// if (_musicType == MDT_PCSPK || _musicType == MDT_PCJR) -// pri = 11; + if (_musicType == MDT_PCSPK || _musicType == MDT_PCJR) + pri = 11; break; } + // We only allow SPK resources for PC Speaker, PCJr and CMS here + // since other resource would sound horribly with their output + // drivers. if ((_musicType == MDT_PCSPK || _musicType == MDT_PCJR || _musicType == MDT_CMS) && pri != 11) pri = -1; + // We only allow ADL resources when AdLib or FM-Towns is used as + // primary audio output. This fixes some odd sounds when Indy and + // Sophia leave Atlantis with the submarine in Indy4. (Easy to + // check with bootparam 4061 in the CD version). It seems the game + // only contains a ROL resource for sound id 60. Formerly we tried + // to play that via the AdLib or FM-Towns audio driver resulting + // in strange noises. Now we behave like the original did. + if ((_musicType == MDT_ADLIB || _musicType == MDT_TOWNS) && pri != 10) + pri = -1; + debugC(DEBUG_RESOURCE, " tag: %s, total_size=%d, pri=%d", tag2str(tag), size, pri); diff --git a/engines/sword2/controls.cpp b/engines/sword2/controls.cpp index 6ce447a4cc..3611294eb8 100644 --- a/engines/sword2/controls.cpp +++ b/engines/sword2/controls.cpp @@ -477,6 +477,8 @@ void Widget::createSurfaceImage(int state, uint32 res, int x, int y, uint32 pc) // Points to just after frame header, ie. start of sprite data _sprites[state].data = frame + FrameHeader::size(); + _sprites[state].colorTable = colTablePtr; + _sprites[state].isText = false; _vm->_screen->createSurface(&_sprites[state], &_surfaces[state]._surface); _surfaces[state]._original = true; diff --git a/engines/sword2/render.cpp b/engines/sword2/render.cpp index 1e068d6061..8bf9d922d5 100644 --- a/engines/sword2/render.cpp +++ b/engines/sword2/render.cpp @@ -699,8 +699,6 @@ int32 Screen::initializePsxBackgroundLayer(byte *parallax) { */ int32 Screen::initializePsxParallaxLayer(byte *parallax) { - uint16 plxXres, plxYres; - uint16 xTiles, yTiles; uint16 i, j, k; byte *data; byte *dst; @@ -714,10 +712,10 @@ int32 Screen::initializePsxParallaxLayer(byte *parallax) { return RD_OK; } - plxXres = READ_LE_UINT16(parallax); - plxYres = READ_LE_UINT16(parallax + 2); - xTiles = READ_LE_UINT16(parallax + 4); - yTiles = READ_LE_UINT16(parallax + 6); + // uint16 plxXres = READ_LE_UINT16(parallax); + // uint16 plxYres = READ_LE_UINT16(parallax + 2); + uint16 xTiles = READ_LE_UINT16(parallax + 4); + uint16 yTiles = READ_LE_UINT16(parallax + 6); // Beginning of parallax table composed by uint32, // if word is 0, corresponding tile contains no data and must be skipped, diff --git a/engines/sword25/gfx/image/vectorimage.cpp b/engines/sword25/gfx/image/vectorimage.cpp index 45d43c465e..81f4fc2ad5 100644 --- a/engines/sword25/gfx/image/vectorimage.cpp +++ b/engines/sword25/gfx/image/vectorimage.cpp @@ -247,6 +247,9 @@ VectorImage::VectorImage(const byte *pFileData, uint fileSize, bool &success, co return; } + // readout SWF size + flashRectToBSRect(bs); + // Get frame rate and frame count /* uint32 frameRate = */ bs.getUInt16(); diff --git a/engines/sword25/kernel/inputpersistenceblock.cpp b/engines/sword25/kernel/inputpersistenceblock.cpp index 2d45dfb640..cdce539c31 100644 --- a/engines/sword25/kernel/inputpersistenceblock.cpp +++ b/engines/sword25/kernel/inputpersistenceblock.cpp @@ -55,8 +55,8 @@ void InputPersistenceBlock::read(int16 &value) { void InputPersistenceBlock::read(signed int &value) { if (checkMarker(SINT_MARKER)) { - rawRead(&value, sizeof(signed int)); - value = convertEndianessFromStorageToSystem(value); + value = (int32)READ_LE_UINT32(_iter); + _iter += 4; } else { value = 0; } @@ -64,8 +64,8 @@ void InputPersistenceBlock::read(signed int &value) { void InputPersistenceBlock::read(uint &value) { if (checkMarker(UINT_MARKER)) { - rawRead(&value, sizeof(uint)); - value = convertEndianessFromStorageToSystem(value); + value = READ_LE_UINT32(_iter); + _iter += 4; } else { value = 0; } @@ -73,8 +73,10 @@ void InputPersistenceBlock::read(uint &value) { void InputPersistenceBlock::read(float &value) { if (checkMarker(FLOAT_MARKER)) { - rawRead(&value, sizeof(float)); - value = convertEndianessFromStorageToSystem(value); + uint32 tmp[1]; + tmp[0] = READ_LE_UINT32(_iter); + value = ((float *)tmp)[0]; + _iter += 4; } else { value = 0.0f; } @@ -82,12 +84,11 @@ void InputPersistenceBlock::read(float &value) { void InputPersistenceBlock::read(bool &value) { if (checkMarker(BOOL_MARKER)) { - uint uintBool; - rawRead(&uintBool, sizeof(float)); - uintBool = convertEndianessFromStorageToSystem(uintBool); + uint uintBool = READ_LE_UINT32(_iter); + _iter += 4; value = uintBool == 0 ? false : true; } else { - value = 0.0f; + value = false; } } @@ -117,13 +118,6 @@ void InputPersistenceBlock::readByteArray(Common::Array<byte> &value) { } } -void InputPersistenceBlock::rawRead(void *destPtr, size_t size) { - if (checkBlockSize(size)) { - memcpy(destPtr, &*_iter, size); - _iter += size; - } -} - bool InputPersistenceBlock::checkBlockSize(int size) { if (_data.end() - _iter >= size) { return true; diff --git a/engines/sword25/kernel/inputpersistenceblock.h b/engines/sword25/kernel/inputpersistenceblock.h index 7e68137246..2518d7e32c 100644 --- a/engines/sword25/kernel/inputpersistenceblock.h +++ b/engines/sword25/kernel/inputpersistenceblock.h @@ -69,7 +69,6 @@ public: private: bool checkMarker(byte marker); bool checkBlockSize(int size); - void rawRead(void *destPtr, size_t size); Common::Array<byte> _data; Common::Array<byte>::const_iterator _iter; diff --git a/engines/sword25/kernel/outputpersistenceblock.cpp b/engines/sword25/kernel/outputpersistenceblock.cpp index cf28ea401f..e29d956e5f 100644 --- a/engines/sword25/kernel/outputpersistenceblock.cpp +++ b/engines/sword25/kernel/outputpersistenceblock.cpp @@ -43,19 +43,23 @@ OutputPersistenceBlock::OutputPersistenceBlock() { void OutputPersistenceBlock::write(signed int value) { writeMarker(SINT_MARKER); - value = convertEndianessFromSystemToStorage(value); + value = TO_LE_32(value); rawWrite(&value, sizeof(value)); } void OutputPersistenceBlock::write(uint value) { writeMarker(UINT_MARKER); - value = convertEndianessFromSystemToStorage(value); + value = TO_LE_32(value); rawWrite(&value, sizeof(value)); } void OutputPersistenceBlock::write(float value) { writeMarker(FLOAT_MARKER); - value = convertEndianessFromSystemToStorage(value); + uint32 tmp[1]; + + ((float *)tmp)[0] = value; + tmp[0] = TO_LE_32(tmp[0]); + rawWrite(&value, sizeof(value)); } @@ -63,7 +67,7 @@ void OutputPersistenceBlock::write(bool value) { writeMarker(BOOL_MARKER); uint uintBool = value ? 1 : 0; - uintBool = convertEndianessFromSystemToStorage(uintBool); + uintBool = TO_LE_32(uintBool); rawWrite(&uintBool, sizeof(uintBool)); } diff --git a/engines/sword25/kernel/persistenceblock.h b/engines/sword25/kernel/persistenceblock.h index d8440faa50..8ac3e84a41 100644 --- a/engines/sword25/kernel/persistenceblock.h +++ b/engines/sword25/kernel/persistenceblock.h @@ -64,48 +64,6 @@ protected: BLOCK_MARKER }; - // ----------------------------------------------------------------------------- - // Endianess Conversions - // ----------------------------------------------------------------------------- - // - // Everything is stored in Little Endian - // Big Endian Systems will need to be byte swapped during both saving and reading of saved values - // - - template<typename T> - static T convertEndianessFromSystemToStorage(T value) { - if (isBigEndian()) - reverseByteOrder(&value); - return value; - } - - template<typename T> - static T convertEndianessFromStorageToSystem(T value) { - if (isBigEndian()) - reverseByteOrder(&value); - return value; - } - -private: - static bool isBigEndian() { - uint dummy = 1; - byte *dummyPtr = reinterpret_cast<byte *>(&dummy); - return dummyPtr[0] == 0; - } - - template<typename T> - static void swap(T &one, T &two) { - T temp = one; - one = two; - two = temp; - } - - static void reverseByteOrder(void *ptr) { - // Reverses the byte order of the 32-bit word pointed to by Ptr - byte *charPtr = static_cast<byte *>(ptr); - swap(charPtr[0], charPtr[3]); - swap(charPtr[1], charPtr[2]); - } }; #define CTASSERT(ex) typedef char ctassert_type[(ex) ? 1 : -1] diff --git a/engines/toon/character.cpp b/engines/toon/character.cpp index 06c6e21d21..022214157a 100644 --- a/engines/toon/character.cpp +++ b/engines/toon/character.cpp @@ -596,7 +596,8 @@ int32 Character::getId() { void Character::save(Common::WriteStream *stream) { debugC(1, kDebugCharacter, "save(stream)"); - stream->writeSint32LE(_flags); + // we have to save visibility too, put in flags to not invalidate old savegames. + stream->writeSint32LE(_flags | ((_visible == false) ? 0x100 : 0)); stream->writeSint32LE(_x); stream->writeSint32LE(_y); stream->writeSint32LE(_z); @@ -633,6 +634,12 @@ void Character::load(Common::ReadStream *stream) { if (_sceneAnimationId > -1) { setAnimationInstance(_vm->getSceneAnimation(_sceneAnimationId)->_animInstance); } + + // "not visible" flag. + if (_flags & 0x100) { + _flags &= ~0x100; + setVisible(false); + } } void Character::setAnimScript(int32 animScriptId) { diff --git a/engines/toon/movie.cpp b/engines/toon/movie.cpp index 2318eaaac7..7637f4e62f 100644 --- a/engines/toon/movie.cpp +++ b/engines/toon/movie.cpp @@ -94,7 +94,7 @@ void Movie::play(Common::String video, int32 flags) { _vm->getAudioManager()->setMusicVolume(0); _decoder->loadFile(video.c_str()); playVideo(isFirstIntroVideo); - _vm->flushPalette(false); + _vm->flushPalette(true); if (flags & 1) _vm->getAudioManager()->setMusicVolume(_vm->getAudioManager()->isMusicMuted() ? 0 : 255); _decoder->close(); @@ -103,7 +103,6 @@ void Movie::play(Common::String video, int32 flags) { bool Movie::playVideo(bool isFirstIntroVideo) { debugC(1, kDebugMovie, "playVideo(isFirstIntroVideo: %d)", isFirstIntroVideo); - while (!_vm->shouldQuit() && !_decoder->endOfVideo()) { if (_decoder->needsUpdate()) { const Graphics::Surface *frame = _decoder->decodeNextFrame(); diff --git a/engines/toon/picture.cpp b/engines/toon/picture.cpp index 0257964fb5..295e304765 100644 --- a/engines/toon/picture.cpp +++ b/engines/toon/picture.cpp @@ -29,16 +29,14 @@ namespace Toon { -bool Picture::loadPicture(Common::String file, bool totalPalette /*= false*/) { - debugC(1, kDebugPicture, "loadPicture(%s, %d)", file.c_str(), (totalPalette) ? 1 : 0); +bool Picture::loadPicture(Common::String file) { + debugC(1, kDebugPicture, "loadPicture(%s)", file.c_str()); uint32 size = 0; uint8 *fileData = _vm->resources()->getFileData(file, &size); if (!fileData) return false; - _useFullPalette = totalPalette; - uint32 compId = READ_BE_UINT32(fileData); switch (compId) { @@ -57,6 +55,8 @@ bool Picture::loadPicture(Common::String file, bool totalPalette /*= false*/) { // do we have a palette ? _paletteEntries = (dstsize & 0x7ff) / 3; + _useFullPalette = (_paletteEntries == 256); + // _useFullPalette = true; if (_paletteEntries) { _palette = new uint8[_paletteEntries * 3]; memcpy(_palette, _data + dstsize - (dstsize & 0x7ff), _paletteEntries * 3); @@ -70,7 +70,8 @@ bool Picture::loadPicture(Common::String file, bool totalPalette /*= false*/) { uint32 decSize = READ_LE_UINT32(fileData + 10); _data = new uint8[decSize + 100]; _paletteEntries = READ_LE_UINT16(fileData + 14) / 3; - + _useFullPalette = (_paletteEntries == 256); + if (_paletteEntries) { _palette = new uint8[_paletteEntries * 3]; memcpy(_palette, fileData + 16, _paletteEntries * 3); diff --git a/engines/toon/picture.h b/engines/toon/picture.h index 23edbc91da..ee0e006702 100644 --- a/engines/toon/picture.h +++ b/engines/toon/picture.h @@ -38,7 +38,7 @@ class Picture { public: Picture(ToonEngine *vm); ~Picture(); - bool loadPicture(Common::String file, bool totalPalette = false); + bool loadPicture(Common::String file); void setupPalette(); void draw(Graphics::Surface &surface, int32 x, int32 y, int32 dx, int32 dy); void drawWithRectList(Graphics::Surface& surface, int32 x, int32 y, int32 dx, int32 dy, Common::Array<Common::Rect>& rectArray); diff --git a/engines/toon/toon.cpp b/engines/toon/toon.cpp index 26639d71f7..cff6c24469 100644 --- a/engines/toon/toon.cpp +++ b/engines/toon/toon.cpp @@ -614,7 +614,7 @@ struct MainMenuEntry { bool ToonEngine::showMainmenu(bool &loadedGame) { Picture *mainmenuPicture = new Picture(this); - mainmenuPicture->loadPicture("TITLESCR.CPS", true); + mainmenuPicture->loadPicture("TITLESCR.CPS"); mainmenuPicture->setupPalette(); flushPalette(false); @@ -690,6 +690,11 @@ bool ToonEngine::showMainmenu(bool &loadedGame) { } } + if (_needPaletteFlush) { + flushPalette(false); + _needPaletteFlush = false; + } + parseInput(); copyToVirtualScreen(true); _system->delayMillis(17); @@ -1547,7 +1552,7 @@ void ToonEngine::clickEvent() { return; } } else { - if (!_drew->walkTo(_mouseX, _mouseY)) { + if (!_drew->walkTo(_mouseX + _gameState->_currentScrollValue, _mouseY)) { // walk was canceled ? return; } @@ -2600,7 +2605,7 @@ int32 ToonEngine::showInventory() { delete _inventoryPicture; _inventoryPicture = new Picture(this); fadeOut(5); - _inventoryPicture->loadPicture("SACK128.CPS", true); + _inventoryPicture->loadPicture("SACK128.CPS"); _inventoryPicture->setupPalette(); dirtyAllScreen(); @@ -2786,7 +2791,7 @@ void ToonEngine::showCutaway(Common::String cutawayPicture) { if (cutawayPicture == "") { cutawayPicture = Common::String(_gameState->_locations[_gameState->_currentScene]._cutaway) + ".CPS"; } - _currentCutaway->loadPicture(cutawayPicture, false); + _currentCutaway->loadPicture(cutawayPicture); _currentCutaway->setupPalette(); _oldScrollValue = _gameState->_currentScrollValue; _gameState->_currentScrollValue = 0; @@ -3418,7 +3423,7 @@ void ToonEngine::viewInventoryItem(Common::String str, int32 lineId, int32 itemD fadeOut(5); Picture *pic = new Picture(this); - pic->loadPicture(str, false); + pic->loadPicture(str); pic->setupPalette(); dirtyAllScreen(); flushPalette(); diff --git a/engines/tsage/converse.cpp b/engines/tsage/converse.cpp index b475310533..0ae575c557 100644 --- a/engines/tsage/converse.cpp +++ b/engines/tsage/converse.cpp @@ -416,13 +416,13 @@ int ConversationChoiceDialog::execute(const Common::StringArray &choiceList) { // Event handling loop Event event; - while (!_vm->getEventManager()->shouldQuit()) { + while (!_vm->shouldQuit()) { while (!_globals->_events.getEvent(event, EVENT_KEYPRESS | EVENT_BUTTON_DOWN | EVENT_MOUSE_MOVE) && - !_vm->getEventManager()->shouldQuit()) { + !_vm->shouldQuit()) { g_system->delayMillis(10); g_system->updateScreen(); } - if (_vm->getEventManager()->shouldQuit()) + if (_vm->shouldQuit()) break; if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode >= Common::KEYCODE_1) && diff --git a/engines/tsage/core.cpp b/engines/tsage/core.cpp index 76714a6f10..d0075d5acf 100644 --- a/engines/tsage/core.cpp +++ b/engines/tsage/core.cpp @@ -1552,7 +1552,7 @@ void SceneItem::display(int resNum, int lineNum, ...) { Event event; // Keep event on-screen until a mouse or keypress - while (!_vm->getEventManager()->shouldQuit() && !_globals->_events.getEvent(event, + while (!_vm->shouldQuit() && !_globals->_events.getEvent(event, EVENT_BUTTON_DOWN | EVENT_KEYPRESS)) { g_system->updateScreen(); g_system->delayMillis(10); diff --git a/engines/tsage/detection_tables.h b/engines/tsage/detection_tables.h index 8b80edf89d..f9ced562c2 100644 --- a/engines/tsage/detection_tables.h +++ b/engines/tsage/detection_tables.h @@ -24,7 +24,7 @@ namespace tSage { static const tSageGameDescription gameDescriptions[] = { - // Ringworld CD and First Wave versions + // Ringworld English CD and First Wave versions { { "ring", @@ -38,6 +38,20 @@ static const tSageGameDescription gameDescriptions[] = { GType_Ringworld, GF_CD | GF_ALT_REGIONS }, + // Ringworld Spanish CD + { + { + "ring", + "CD", + AD_ENTRY1s("ring.rlb", "cb8bba91b30cd172712371d7123bd763", 7427980), + Common::ES_ESP, + Common::kPlatformPC, + ADGF_UNSTABLE, + Common::GUIO_NOSPEECH | Common::GUIO_NOSFX + }, + GType_Ringworld, + GF_CD | GF_ALT_REGIONS + }, // Ringworld English Floppy version { { diff --git a/engines/tsage/dialogs.cpp b/engines/tsage/dialogs.cpp index 86fbbc8e43..d315ce092b 100644 --- a/engines/tsage/dialogs.cpp +++ b/engines/tsage/dialogs.cpp @@ -243,7 +243,7 @@ void RightClickDialog::execute() { // Dialog event handler loop _gfxManager.activate(); - while (!_vm->getEventManager()->shouldQuit() && (_selectedAction == -1)) { + while (!_vm->shouldQuit() && (_selectedAction == -1)) { Event evt; while (_globals->_events.getEvent(evt, EVENT_MOUSE_MOVE | EVENT_BUTTON_DOWN)) { evt.mousePos.x -= _bounds.left; @@ -465,14 +465,14 @@ void InventoryDialog::execute() { bool lookFlag = false; _gfxManager.activate(); - while (!_vm->getEventManager()->shouldQuit()) { + while (!_vm->shouldQuit()) { // Get events Event event; - while (!_globals->_events.getEvent(event) && !_vm->getEventManager()->shouldQuit()) { + while (!_globals->_events.getEvent(event) && !_vm->shouldQuit()) { g_system->delayMillis(10); g_system->updateScreen(); } - if (_vm->getEventManager()->shouldQuit()) + if (_vm->shouldQuit()) break; hiliteObj = NULL; diff --git a/engines/tsage/events.cpp b/engines/tsage/events.cpp index a24f65421b..010117ec78 100644 --- a/engines/tsage/events.cpp +++ b/engines/tsage/events.cpp @@ -78,7 +78,7 @@ bool EventsClass::pollEvent() { void EventsClass::waitForPress(int eventMask) { Event evt; - while (!_vm->getEventManager()->shouldQuit() && !getEvent(evt, eventMask)) + while (!_vm->shouldQuit() && !getEvent(evt, eventMask)) g_system->delayMillis(10); } @@ -86,7 +86,7 @@ void EventsClass::waitForPress(int eventMask) { * Standard event retrieval, which only returns keyboard and mouse clicks */ bool EventsClass::getEvent(Event &evt, int eventMask) { - while (pollEvent() && !_vm->getEventManager()->shouldQuit()) { + while (pollEvent() && !_vm->shouldQuit()) { evt.handled = false; evt.eventType = EVENT_NONE; evt.mousePos = _event.mouse; diff --git a/engines/tsage/graphics.cpp b/engines/tsage/graphics.cpp index fce9e1317d..87ffdf4494 100644 --- a/engines/tsage/graphics.cpp +++ b/engines/tsage/graphics.cpp @@ -408,7 +408,7 @@ bool GfxSurface::displayText(const Common::String &msg, const Common::Point &pt) // Write for a mouse or keypress Event event; - while (!_globals->_events.getEvent(event, EVENT_BUTTON_DOWN | EVENT_KEYPRESS) && !_vm->getEventManager()->shouldQuit()) + while (!_globals->_events.getEvent(event, EVENT_BUTTON_DOWN | EVENT_KEYPRESS) && !_vm->shouldQuit()) ; // Restore the display area @@ -718,7 +718,7 @@ bool GfxElement::focusedEvent(Event &event) { int xOffset = mousePos.x - _globals->_events._mousePos.x; int yOffset = mousePos.y - _globals->_events._mousePos.y; - while (event.eventType != EVENT_BUTTON_UP && !_vm->getEventManager()->shouldQuit()) { + while (event.eventType != EVENT_BUTTON_UP && !_vm->shouldQuit()) { g_system->delayMillis(10); if (_bounds.contains(mousePos)) { @@ -1029,7 +1029,7 @@ GfxButton *GfxDialog::execute(GfxButton *defaultButton) { GfxButton *selectedButton = NULL; bool breakFlag = false; - while (!_vm->getEventManager()->shouldQuit() && !breakFlag) { + while (!_vm->shouldQuit() && !breakFlag) { Event event; while (_globals->_events.getEvent(event) && !breakFlag) { // Adjust mouse positions to be relative within the dialog diff --git a/engines/tsage/ringworld_logic.cpp b/engines/tsage/ringworld_logic.cpp index 58501172af..070d8afd25 100644 --- a/engines/tsage/ringworld_logic.cpp +++ b/engines/tsage/ringworld_logic.cpp @@ -296,7 +296,7 @@ void SceneArea::draw(bool flag) { void SceneArea::wait() { // Wait until a mouse or keypress Event event; - while (!_vm->getEventManager()->shouldQuit() && !_globals->_events.getEvent(event)) { + while (!_vm->shouldQuit() && !_globals->_events.getEvent(event)) { g_system->updateScreen(); g_system->delayMillis(10); } diff --git a/engines/tsage/ringworld_scenes3.cpp b/engines/tsage/ringworld_scenes3.cpp index 824a96a18b..3f9921b0ad 100644 --- a/engines/tsage/ringworld_scenes3.cpp +++ b/engines/tsage/ringworld_scenes3.cpp @@ -526,7 +526,7 @@ void Scene2100::Action1::signal() { _state = 0; _globals->_events.setCursor(CURSOR_USE); - while (!_state && !_vm->getEventManager()->shouldQuit()) { + while (!_state && !_vm->shouldQuit()) { // Wait for an event Event event; if (!_globals->_events.getEvent(event)) { @@ -2257,7 +2257,7 @@ void Scene2150::Action1::signal() { _state = 0; _globals->_events.setCursor(CURSOR_USE); - while (!_state && !_vm->getEventManager()->shouldQuit()) { + while (!_state && !_vm->shouldQuit()) { // Wait for an event Event event; if (!_globals->_events.getEvent(event)) { @@ -5112,7 +5112,7 @@ void Scene2320::Action3::signal() { _state = 0; _globals->_events.setCursor(CURSOR_USE); - while (!_state && !_vm->getEventManager()->shouldQuit()) { + while (!_state && !_vm->shouldQuit()) { // Wait for an event Event event; if (!_globals->_events.getEvent(event)) { diff --git a/engines/tsage/scenes.cpp b/engines/tsage/scenes.cpp index 18b3da2698..b94e95c696 100644 --- a/engines/tsage/scenes.cpp +++ b/engines/tsage/scenes.cpp @@ -511,7 +511,7 @@ void Game::execute() { activeFlag = true; } } - } while (activeFlag && !_vm->getEventManager()->shouldQuit()); + } while (activeFlag && !_vm->shouldQuit()); } } // End of namespace tSage diff --git a/engines/tsage/sound.cpp b/engines/tsage/sound.cpp index 8dd584ef24..e26b3d1544 100644 --- a/engines/tsage/sound.cpp +++ b/engines/tsage/sound.cpp @@ -2485,7 +2485,10 @@ AdlibSoundDriver::AdlibSoundDriver(): SoundDriver() { _mixer = _vm->_mixer; _sampleRate = _mixer->getOutputRate(); - _opl = makeAdLibOPL(_sampleRate); + _opl = OPL::Config::create(); + assert(_opl); + _opl->init(_sampleRate); + _mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true); Common::set_to(_channelVoiced, _channelVoiced + ADLIB_CHANNEL_COUNT, false); @@ -2504,7 +2507,7 @@ AdlibSoundDriver::AdlibSoundDriver(): SoundDriver() { AdlibSoundDriver::~AdlibSoundDriver() { DEALLOCATE(_patchData); _mixer->stopHandle(_soundHandle); - OPLDestroy(_opl); + delete _opl; } bool AdlibSoundDriver::open() { @@ -2622,7 +2625,7 @@ void AdlibSoundDriver::flush() { while (!_queue.empty()) { RegisterValue v = _queue.pop(); - OPLWriteReg(_opl, v._regNum, v._value); + _opl->writeReg(v._regNum, v._value); } } @@ -2760,7 +2763,7 @@ void AdlibSoundDriver::update(int16 *buf, int len) { } samplesLeft -= count; len -= count; - YM3812UpdateOne(_opl, buf, count); + _opl->readBuffer(buf, count); if (samplesLeft == 0) { flush(); samplesLeft = _sampleRate / 50; diff --git a/engines/tsage/tsage.cpp b/engines/tsage/tsage.cpp index 41f3d58897..23a0193b7c 100644 --- a/engines/tsage/tsage.cpp +++ b/engines/tsage/tsage.cpp @@ -147,4 +147,8 @@ void TSageEngine::syncSoundSettings() { _globals->_soundManager.syncSounds(); } +bool TSageEngine::shouldQuit() { + return getEventManager()->shouldQuit() || getEventManager()->shouldRTL(); +} + } // End of namespace tSage diff --git a/engines/tsage/tsage.h b/engines/tsage/tsage.h index f004c7f625..805461886a 100644 --- a/engines/tsage/tsage.h +++ b/engines/tsage/tsage.h @@ -78,6 +78,7 @@ public: uint32 getGameID() const; uint32 getFeatures() const; Common::String getPrimaryFilename() const; + bool shouldQuit(); virtual Common::Error init(); virtual Common::Error run(); diff --git a/graphics/sjis.cpp b/graphics/sjis.cpp index 10c780b156..be078a4da9 100644 --- a/graphics/sjis.cpp +++ b/graphics/sjis.cpp @@ -40,10 +40,27 @@ FontSJIS *FontSJIS::createFont(const Common::Platform platform) { // Try the font ROM of the specified platform if (platform == Common::kPlatformFMTowns) { ret = new FontTowns(); - if (ret && ret->loadData()) - return ret; + if (ret) { + if (ret->loadData()) + return ret; + } delete ret; - } + } else if (platform == Common::kPlatformPCEngine) { + ret = new FontPCEngine(); + if (ret) { + if (ret->loadData()) + return ret; + } + delete ret; + } // TODO: PC98 font rom support + /* else if (platform == Common::kPlatformPC98) { + ret = new FontPC98(); + if (ret) { + if (ret->loadData()) + return ret; + } + delete ret; + }*/ // Try ScummVM's font. ret = new FontSjisSVM(platform); @@ -59,15 +76,21 @@ void FontSJIS::drawChar(Graphics::Surface &dst, uint16 ch, int x, int y, uint32 } FontSJISBase::FontSJISBase() - : _drawMode(kDefaultMode), _flippedMode(false), _fontWidth(16), _fontHeight(16) { + : _drawMode(kDefaultMode), _flippedMode(false), _fontWidth(16), _fontHeight(16), _bitPosNewLineMask(0) { } void FontSJISBase::setDrawingMode(DrawingMode mode) { - _drawMode = mode; + if (hasFeature(1 << mode)) + _drawMode = mode; + else + warning("Unsupported drawing mode selected"); } void FontSJISBase::toggleFlippedMode(bool enable) { - _flippedMode = enable; + if (hasFeature(kFeatFlipped)) + _flippedMode = enable; + else + warning("Flipped mode unsupported by this font"); } uint FontSJISBase::getFontHeight() const { @@ -98,26 +121,30 @@ uint FontSJISBase::getMaxFontWidth() const { uint FontSJISBase::getCharWidth(uint16 ch) const { if (isASCII(ch)) - return (_drawMode == kOutlineMode) ? 10 : (_drawMode == kDefaultMode ? 8 : 9); + return ((_drawMode == kOutlineMode) ? 10 : (_drawMode == kDefaultMode ? 8 : 9)); else return getMaxFontWidth(); } template<typename Color> void FontSJISBase::blitCharacter(const uint8 *glyph, const int w, const int h, uint8 *dst, int pitch, Color c) const { + uint8 bitPos = 0; + uint8 mask = 0; + for (int y = 0; y < h; ++y) { Color *d = (Color *)dst; dst += pitch; - uint8 mask = 0; + bitPos &= _bitPosNewLineMask; for (int x = 0; x < w; ++x) { - if (!(x % 8)) + if (!(bitPos % 8)) mask = *glyph++; if (mask & 0x80) *d = c; ++d; + ++bitPos; mask <<= 1; } } @@ -176,9 +203,6 @@ const uint8 *FontSJISBase::flipCharacter(const uint8 *glyph, const int w) const 0x0F, 0x8F, 0x4F, 0xC7, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x97, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF }; - // TODO: This code looks like it will only work with 16 pixel wide - // characters we should really take care that we only call it on these - // or we fix this to support a generic width. for (int i = 0; i < w; i++) { _tempGlyph[i] = flipData[glyph[(w * 2 - 1) - i]]; _tempGlyph[(w * 2 - 1) - i] = flipData[glyph[i]]; @@ -225,9 +249,6 @@ void FontSJISBase::drawChar(void *dst, uint16 ch, int pitch, int bpp, uint32 c1, } #ifndef DISABLE_FLIPPED_MODE - // TODO: This code inside flopCharater looks like it will only work with - // 16 pixel wide characters we should really take care that we only call - // it on these or we fix it to support a generic width. if (_flippedMode) glyphSource = flipCharacter(glyphSource, width); #endif @@ -303,7 +324,7 @@ const uint8 *FontTowns::getCharData(uint16 ch) const { uint8 f = ch & 0xFF; uint8 s = ch >> 8; - // copied from scumm\charset.cpp + // moved from scumm\charset.cpp enum { KANA = 0, KANJI = 1, @@ -392,6 +413,98 @@ const uint8 *FontTowns::getCharData(uint16 ch) const { } } +bool FontTowns::hasFeature(int feat) const { + static const int features = kFeatDefault | kFeatOutline | kFeatShadow | kFeatFMTownsShadow | kFeatFlipped; + return (features & feat) ? true : false; +} + +// PC-Engine ROM font + +bool FontPCEngine::loadData() { + Common::SeekableReadStream *data = SearchMan.createReadStreamForMember("pce.cdbios"); + if (!data) + return false; + + data->seek((data->size() & 0x200) ? 0x30200 : 0x30000); + data->read(_fontData12x12, kFont12x12Chars * 18); + + _fontWidth = _fontHeight = 12; + _bitPosNewLineMask = _fontWidth & 7; + + bool retValue = !data->err(); + delete data; + return retValue; +} + +const uint8 *FontPCEngine::getCharData(uint16 ch) const { + // Converts sjis code to pce font offset + // (moved from scumm\charset.cpp). + // rangeTbl maps SJIS char-codes to the PCE System Card font rom. + // Each pair {<upperBound>,<lowerBound>} in the array represents a SJIS range. + const int rangeCnt = 45; + static const uint16 rangeTbl[rangeCnt][2] = { + // Symbols + {0x8140,0x817E},{0x8180,0x81AC}, + // 0-9 + {0x824F,0x8258}, + // Latin upper + {0x8260,0x8279}, + // Latin lower + {0x8281,0x829A}, + // Kana + {0x829F,0x82F1},{0x8340,0x837E},{0x8380,0x8396}, + // Greek upper + {0x839F,0x83B6}, + // Greek lower + {0x83BF,0x83D6}, + // Cyrillic upper + {0x8440,0x8460}, + // Cyrillic lower + {0x8470,0x847E},{0x8480,0x8491}, + // Kanji + {0x889F,0x88FC}, + {0x8940,0x897E},{0x8980,0x89FC}, + {0x8A40,0x8A7E},{0x8A80,0x8AFC}, + {0x8B40,0x8B7E},{0x8B80,0x8BFC}, + {0x8C40,0x8C7E},{0x8C80,0x8CFC}, + {0x8D40,0x8D7E},{0x8D80,0x8DFC}, + {0x8E40,0x8E7E},{0x8E80,0x8EFC}, + {0x8F40,0x8F7E},{0x8F80,0x8FFC}, + {0x9040,0x907E},{0x9080,0x90FC}, + {0x9140,0x917E},{0x9180,0x91FC}, + {0x9240,0x927E},{0x9280,0x92FC}, + {0x9340,0x937E},{0x9380,0x93FC}, + {0x9440,0x947E},{0x9480,0x94FC}, + {0x9540,0x957E},{0x9580,0x95FC}, + {0x9640,0x967E},{0x9680,0x96FC}, + {0x9740,0x977E},{0x9780,0x97FC}, + {0x9840,0x9872} + }; + + ch = (ch << 8) | (ch >> 8); + int offset = 0; + for (int i = 0; i < rangeCnt; ++i) { + if (ch >= rangeTbl[i][0] && ch <= rangeTbl[i][1]) { + return _fontData12x12 + 18 * (offset + ch - rangeTbl[i][0]); + break; + } + offset += rangeTbl[i][1] - rangeTbl[i][0] + 1; + } + + debug(4, "Invalid Char: 0x%x", ch); + return 0; +} + +bool FontPCEngine::hasFeature(int feat) const { + // Outline mode not supported due to use of _bitPosNewLineMask. This could be implemented, + // but is not needed for any particular target at the moment. + // Flipped mode is also not supported since the hard coded table (taken from SCUMM 5 FM-TOWNS) + // is set up for font sizes of 8/16. This mode is also not required at the moment, since + // there aren't any SCUMM 5 PC-Engine games. + static const int features = kFeatDefault | kFeatShadow | kFeatFMTownsShadow; + return (features & feat) ? true : false; +} + // ScummVM SJIS font FontSjisSVM::FontSjisSVM(const Common::Platform platform) @@ -464,6 +577,15 @@ const uint8 *FontSjisSVM::getCharData(uint16 c) const { return getCharDataDefault(c); } +bool FontSjisSVM::hasFeature(int feat) const { + // Flipped mode is not supported since the hard coded table (taken from SCUMM 5 FM-TOWNS) + // is set up for font sizes of 8/16. This mode is also not required at the moment, since + // there aren't any SCUMM 5 PC-Engine games. + static const int features16 = kFeatDefault | kFeatOutline | kFeatShadow | kFeatFMTownsShadow | kFeatFlipped; + static const int features12 = kFeatDefault | kFeatOutline | kFeatShadow | kFeatFMTownsShadow; + return (((_fontWidth == 12) ? features12 : features16) & feat) ? true : false; +} + const uint8 *FontSjisSVM::getCharDataPCE(uint16 c) const { if (isASCII(c)) return 0; diff --git a/graphics/sjis.h b/graphics/sjis.h index 62e68013da..4b54da53b4 100644 --- a/graphics/sjis.h +++ b/graphics/sjis.h @@ -75,7 +75,7 @@ public: virtual bool loadData() = 0; /** - * Enable drawing with outline or shadow. + * Enable drawing with outline or shadow if supported by the Font. * * After changing outline state, getFontHeight and getMaxFontWidth / getCharWidth might return * different values! @@ -90,11 +90,17 @@ public: virtual void setDrawingMode(DrawingMode mode) {} /** - * Enable flipped character drawing (e.g. in the MI1 circus scene after Guybrush gets shot out of the cannon). + * Enable flipped character drawing if supported by the Font (e.g. in the MI1 circus scene after Guybrush gets shot out of the cannon). */ virtual void toggleFlippedMode(bool enable) {} /** + * Set spacing between characters and lines. This affects font height / char width + */ + virtual void setCharSpacing(int spacing) {} + virtual void setLineSpacing(int spacing) {} + + /** * Returns the height of the font. */ virtual uint getFontHeight() const = 0; @@ -162,16 +168,27 @@ protected: DrawingMode _drawMode; bool _flippedMode; int _fontWidth, _fontHeight; - + uint8 _bitPosNewLineMask; + bool isASCII(uint16 ch) const; virtual const uint8 *getCharData(uint16 c) const = 0; + + enum DrawingFeature { + kFeatDefault = 1 << 0, + kFeatOutline = 1 << 1, + kFeatShadow = 1 << 2, + kFeatFMTownsShadow = 1 << 3, + kFeatFlipped = 1 << 4 + }; + + virtual bool hasFeature(int feat) const = 0; }; /** * FM-TOWNS ROM based SJIS compatible font. * - * This is used in KYRA and SCI. + * This is used in KYRA, SCUMM and SCI. */ class FontTowns : public FontSJISBase { public: @@ -189,6 +206,31 @@ private: uint8 _fontData8x16[kFont8x16Chars * 32]; virtual const uint8 *getCharData(uint16 c) const; + + bool hasFeature(int feat) const; +}; + +/** + * PC-Engine System Card based SJIS compatible font. + * + * This is used in LOOM. + */ +class FontPCEngine : public FontSJISBase { +public: + /** + * Loads the ROM data from "pce.cdbios". + */ + bool loadData(); +private: + enum { + kFont12x12Chars = 3418 + }; + + uint8 _fontData12x12[kFont12x12Chars * 18]; + + virtual const uint8 *getCharData(uint16 c) const; + + bool hasFeature(int feat) const; }; /** @@ -215,6 +257,8 @@ private: virtual const uint8 *getCharData(uint16 c) const; + bool hasFeature(int feat) const; + const uint8 *getCharDataPCE(uint16 c) const; const uint8 *getCharDataDefault(uint16 c) const; diff --git a/gui/credits.h b/gui/credits.h index 0ed7fa1e41..cc9698195a 100644 --- a/gui/credits.h +++ b/gui/credits.h @@ -46,6 +46,7 @@ static const char *credits[] = { "C0""Filippos Karapetis", "C0""Pawel Kolodziejski", "C0""Walter van Niftrik", +"C2""(retired)", "C0""Kari Salminen", "C0""Eugene Sandulenko", "C0""David Symonds", @@ -158,6 +159,7 @@ static const char *credits[] = { "C0""Filippos Karapetis", "C0""Martin Kiewitz", "C0""Walter van Niftrik", +"C2""(retired)", "C0""Willem Jan Palenstijn", "C0""Jordi Vilalta Prat", "C0""Lars Skovlund", diff --git a/gui/debugger.h b/gui/debugger.h index b74b0d6f0f..3a587d2723 100644 --- a/gui/debugger.h +++ b/gui/debugger.h @@ -26,6 +26,7 @@ #include "common/ptr.h" #include "common/hashmap.h" #include "common/hash-str.h" +#include "common/array.h" namespace GUI { diff --git a/gui/saveload.cpp b/gui/saveload.cpp index 460246e5fc..02ddf814dc 100644 --- a/gui/saveload.cpp +++ b/gui/saveload.cpp @@ -131,7 +131,7 @@ void SaveLoadChooser::handleCommand(CommandSender *sender, uint32 cmd, uint32 da if (_list->isEditable() || !_list->getSelectedString().empty()) { _list->endEditMode(); if (!_saveList.empty()) { - setResult(atoi(_saveList[selItem].save_slot().c_str())); + setResult(_saveList[selItem].getSaveSlot()); _resultString = _list->getSelectedString(); } close(); @@ -141,7 +141,7 @@ void SaveLoadChooser::handleCommand(CommandSender *sender, uint32 cmd, uint32 da case kChooseCmd: _list->endEditMode(); if (!_saveList.empty()) { - setResult(atoi(_saveList[selItem].save_slot().c_str())); + setResult(_saveList[selItem].getSaveSlot()); _resultString = _list->getSelectedString(); } close(); @@ -154,7 +154,7 @@ void SaveLoadChooser::handleCommand(CommandSender *sender, uint32 cmd, uint32 da MessageDialog alert(_("Do you really want to delete this savegame?"), _("Delete"), _("Cancel")); if (alert.runModal() == GUI::kMessageOK) { - (*_plugin)->removeSaveState(_target.c_str(), atoi(_saveList[selItem].save_slot().c_str())); + (*_plugin)->removeSaveState(_target.c_str(), _saveList[selItem].getSaveSlot()); setResult(-1); _list->setSelected(-1); @@ -241,10 +241,10 @@ void SaveLoadChooser::updateSelection(bool redraw) { _playtime->setLabel(_("No playtime saved")); if (selItem >= 0 && !_list->getSelectedString().empty() && _metaInfoSupport) { - SaveStateDescriptor desc = (*_plugin)->querySaveMetaInfos(_target.c_str(), atoi(_saveList[selItem].save_slot().c_str())); + SaveStateDescriptor desc = (*_plugin)->querySaveMetaInfos(_target.c_str(), _saveList[selItem].getSaveSlot()); - isDeletable = desc.getBool("is_deletable") && _delSupport; - isWriteProtected = desc.getBool("is_write_protected"); + isDeletable = desc.getDeletableFlag() && _delSupport; + isWriteProtected = desc.getWriteProtectedFlag(); // Don't allow the user to change the description of write protected games if (isWriteProtected) @@ -259,16 +259,19 @@ void SaveLoadChooser::updateSelection(bool redraw) { } if (_saveDateSupport) { - if (desc.contains("save_date")) - _date->setLabel(_("Date: ") + desc.getVal("save_date")); + const Common::String &saveDate = desc.getSaveDate(); + if (!saveDate.empty()) + _date->setLabel(_("Date: ") + saveDate); - if (desc.contains("save_time")) - _time->setLabel(_("Time: ") + desc.getVal("save_time")); + const Common::String &saveTime = desc.getSaveTime(); + if (!saveTime.empty()) + _time->setLabel(_("Time: ") + saveTime); } if (_playTimeSupport) { - if (desc.contains("play_time")) - _playtime->setLabel(_("Playtime: ") + desc.getVal("play_time")); + const Common::String &playTime = desc.getPlayTime(); + if (!playTime.empty()) + _playtime->setLabel(_("Playtime: ") + playTime); } } @@ -326,25 +329,25 @@ void SaveLoadChooser::updateSaveList() { ListWidget::ColorList colors; for (SaveStateList::const_iterator x = _saveList.begin(); x != _saveList.end(); ++x) { // Handle gaps in the list of save games - saveSlot = atoi(x->save_slot().c_str()); + saveSlot = x->getSaveSlot(); if (curSlot < saveSlot) { while (curSlot < saveSlot) { SaveStateDescriptor dummySave(curSlot, ""); _saveList.insert_at(curSlot, dummySave); - saveNames.push_back(dummySave.description()); + saveNames.push_back(dummySave.getDescription()); colors.push_back(ThemeEngine::kFontColorNormal); curSlot++; } // Sync the save list iterator for (x = _saveList.begin(); x != _saveList.end(); ++x) { - if (atoi(x->save_slot().c_str()) == saveSlot) + if (x->getSaveSlot() == saveSlot) break; } } // Show "Untitled savestate" for empty/whitespace savegame descriptions - Common::String description = x->description(); + Common::String description = x->getDescription(); Common::String trimmedDescription = description; trimmedDescription.trim(); if (trimmedDescription.empty()) { diff --git a/po/POTFILES b/po/POTFILES index 3ffb587f01..26bbf52d8f 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -63,6 +63,7 @@ backends/keymapper/remap-dialog.cpp backends/midi/windows.cpp backends/platform/ds/arm9/source/dsoptions.cpp backends/platform/iphone/osys_events.cpp +backends/platform/sdl/macosx/appMenu_osx.mm backends/graphics/surfacesdl/surfacesdl-graphics.cpp backends/graphics/opengl/opengl-graphics.cpp backends/graphics/openglsdl/openglsdl-graphics.cpp @@ -143,6 +143,13 @@ osxsnap: bundle cp $(srcdir)/COPYRIGHT ./ScummVM-snapshot/Copyright\ Holders cp $(srcdir)/NEWS ./ScummVM-snapshot/News cp $(srcdir)/README ./ScummVM-snapshot/ScummVM\ ReadMe + mkdir ScummVM-snapshot/doc + cp $(srcdir)/doc/QuickStart ./ScummVM-snapshot/doc/QuickStart + mkdir ScummVM-snapshot/doc/de + cp $(srcdir)/doc/de/Liesmich ./ScummVM-snapshot/doc/de/Liesmich + cp $(srcdir)/doc/de/Schnellstart ./ScummVM-snapshot/doc/de/Schnellstart + mkdir ScummVM-snapshot/doc/fr + cp $(srcdir)/doc/fr/QuickStart_fr ./ScummVM-snapshot/doc/fr/QuickStart_fr /Developer/Tools/SetFile -t ttro -c ttxt ./ScummVM-snapshot/* /Developer/Tools/CpMac -r $(bundle_name) ./ScummVM-snapshot/ cp $(srcdir)/dists/macosx/DS_Store ./ScummVM-snapshot/.DS_Store @@ -166,6 +173,9 @@ scummvmwinres.o: $(srcdir)/icons/scummvm.ico $(DIST_FILES_THEMES) $(DIST_FILES_E win32dist: $(EXECUTABLE) mkdir -p $(WIN32PATH) mkdir -p $(WIN32PATH)/graphics + mkdir -p $(WIN32PATH)/doc + mkdir -p $(WIN32PATH)/doc/de + mkdir -p $(WIN32PATH)/doc/fr $(STRIP) $(EXECUTABLE) -o $(WIN32PATH)/$(EXECUTABLE) cp $(DIST_FILES_THEMES) $(WIN32PATH) ifdef DIST_FILES_ENGINEDATA @@ -177,12 +187,18 @@ endif cp $(srcdir)/COPYRIGHT $(WIN32PATH)/COPYRIGHT.txt cp $(srcdir)/NEWS $(WIN32PATH)/NEWS.txt cp $(srcdir)/README $(WIN32PATH)/README.txt + cp $(srcdir)/doc/QuickStart $(WIN32PATH)/doc/QuickStart.txt + cp $(srcdir)/doc/de/Schnellstart $(WIN32PATH)/doc/de/Schnellstart.txt + cp $(srcdir)/doc/de/Liesmich $(WIN32PATH)/doc/de/Liesmich.txt + cp $(srcdir)/doc/fr/QuickStart_fr $(WIN32PATH)/doc/fr/QuickStart_fr.txt cp /usr/local/README-SDL.txt $(WIN32PATH) cp /usr/local/bin/SDL.dll $(WIN32PATH) cp $(srcdir)/dists/win32/graphics/left.bmp $(WIN32PATH)/graphics cp $(srcdir)/dists/win32/graphics/scummvm-install.ico $(WIN32PATH)/graphics cp $(srcdir)/dists/win32/ScummVM.iss $(WIN32PATH) unix2dos $(WIN32PATH)/*.txt + unix2dos $(WIN32PATH)/doc/de/*.txt + unix2dos $(WIN32PATH)/doc/fr/*.txt # Special target to create a win32 NSIS installer win32setup: $(EXECUTABLE) diff --git a/video/codecs/cdtoons.cpp b/video/codecs/cdtoons.cpp index 9bdc794fa6..528cee8094 100644 --- a/video/codecs/cdtoons.cpp +++ b/video/codecs/cdtoons.cpp @@ -24,6 +24,7 @@ #include "common/rect.h" #include "common/stream.h" #include "common/textconsole.h" +#include "common/array.h" namespace Video { |