diff options
Diffstat (limited to 'engines/scumm/player/apple2.h')
-rw-r--r-- | engines/scumm/player/apple2.h | 297 |
1 files changed, 0 insertions, 297 deletions
diff --git a/engines/scumm/player/apple2.h b/engines/scumm/player/apple2.h deleted file mode 100644 index e1ec9d8946..0000000000 --- a/engines/scumm/player/apple2.h +++ /dev/null @@ -1,297 +0,0 @@ -/* 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_PLAYER_APPLEII_H -#define SCUMM_PLAYER_APPLEII_H - -#include "common/mutex.h" -#include "common/scummsys.h" -#include "common/memstream.h" -#include "scumm/music.h" -#include "audio/audiostream.h" -#include "audio/mixer.h" -#include "audio/softsynth/sid.h" - -namespace Scumm { - -class ScummEngine; - -/* - * Optimized for use with periodical read/write phases when the buffer - * is filled in a write phase and completely read in a read phase. - * The growing strategy is optimized for repeated small (e.g. 2 bytes) - * single writes resulting in large buffers - * (avg.: 4KB, max: 18KB @ 16bit/22.050kHz (MM sound21)). - */ -class SampleBuffer { -public: - SampleBuffer() : _data(0) { - clear(); - } - - ~SampleBuffer() { - free(_data); - } - - void clear() { - free(_data); - _data = 0; - _capacity = 0; - _writePos = 0; - _readPos = 0; - } - - void ensureFree(uint32 needed) { - // if data was read completely, reset read/write pos to front - if ((_writePos != 0) && (_writePos == _readPos)) { - _writePos = 0; - _readPos = 0; - } - - // check for enough space at end of buffer - uint32 freeEndCnt = _capacity - _writePos; - if (needed <= freeEndCnt) - return; - - uint32 avail = availableSize(); - - // check for enough space at beginning and end of buffer - if (needed <= _readPos + freeEndCnt) { - // move unread data to front of buffer - memmove(_data, _data + _readPos, avail); - _writePos = avail; - _readPos = 0; - } else { // needs a grow - byte *old_data = _data; - uint32 new_len = avail + needed; - - _capacity = new_len + 2048; - _data = (byte *)malloc(_capacity); - - if (old_data) { - // copy old unread data to front of new buffer - memcpy(_data, old_data + _readPos, avail); - free(old_data); - _writePos = avail; - _readPos = 0; - } - } - } - - uint32 availableSize() const { - if (_readPos >= _writePos) - return 0; - return _writePos - _readPos; - } - - uint32 write(const void *dataPtr, uint32 dataSize) { - ensureFree(dataSize); - memcpy(_data + _writePos, dataPtr, dataSize); - _writePos += dataSize; - return dataSize; - } - - uint32 read(byte *dataPtr, uint32 dataSize) { - uint32 avail = availableSize(); - if (avail == 0) - return 0; - if (dataSize > avail) - dataSize = avail; - memcpy(dataPtr, _data + _readPos, dataSize); - _readPos += dataSize; - return dataSize; - } - -private: - uint32 _writePos; - uint32 _readPos; - uint32 _capacity; - byte *_data; -}; - -// CPU_CLOCK according to AppleWin -static const double APPLEII_CPU_CLOCK = 1020484.5; // ~ 1.02 MHz - -/* - * Converts the 1-bit speaker state values into audio samples. - * This is done by aggregation of the speaker states at each - * CPU cycle in a sampling period into an audio sample. - */ -class SampleConverter { -private: - void addSampleToBuffer(int sample) { - int16 value = sample * _volume / _maxVolume; - _buffer.write(&value, sizeof(value)); - } - -public: - SampleConverter() : - _cyclesPerSampleFP(0), - _missingCyclesFP(0), - _sampleCyclesSumFP(0), - _volume(_maxVolume) - {} - - ~SampleConverter() {} - - void reset() { - _missingCyclesFP = 0; - _sampleCyclesSumFP = 0; - _buffer.clear(); - } - - uint32 availableSize() const { - return _buffer.availableSize(); - } - - void setMusicVolume(int vol) { - assert(vol >= 0 && vol <= _maxVolume); - _volume = vol; - } - - void setSampleRate(int rate) { - /* ~46 CPU cycles per sample @ 22.05kHz */ - _cyclesPerSampleFP = int(APPLEII_CPU_CLOCK * (1 << PREC_SHIFT) / rate); - reset(); - } - - void addCycles(byte level, const int cycles) { - /* convert to fixed precision floats */ - int cyclesFP = cycles << PREC_SHIFT; - - // step 1: if cycles are left from the last call, process them first - if (_missingCyclesFP > 0) { - int n = (_missingCyclesFP < cyclesFP) ? _missingCyclesFP : cyclesFP; - if (level) - _sampleCyclesSumFP += n; - cyclesFP -= n; - _missingCyclesFP -= n; - if (_missingCyclesFP == 0) { - addSampleToBuffer(2*32767 * _sampleCyclesSumFP / _cyclesPerSampleFP - 32767); - } else { - return; - } - } - - _sampleCyclesSumFP = 0; - - // step 2: process blocks of cycles fitting into a whole sample - while (cyclesFP >= _cyclesPerSampleFP) { - addSampleToBuffer(level ? 32767 : -32767); - cyclesFP -= _cyclesPerSampleFP; - } - - // step 3: remember cycles left for next call - if (cyclesFP > 0) { - _missingCyclesFP = _cyclesPerSampleFP - cyclesFP; - if (level) - _sampleCyclesSumFP = cyclesFP; - } - } - - uint32 readSamples(void *buffer, int numSamples) { - return _buffer.read((byte *)buffer, numSamples * 2) / 2; - } - -private: - static const int PREC_SHIFT = 7; - -private: - int _cyclesPerSampleFP; /* (fixed precision) */ - int _missingCyclesFP; /* (fixed precision) */ - int _sampleCyclesSumFP; /* (fixed precision) */ - int _volume; /* 0 - 256 */ - static const int _maxVolume = 256; - SampleBuffer _buffer; -}; - -class Player_AppleII; - -class AppleII_SoundFunction { -public: - AppleII_SoundFunction() {} - virtual ~AppleII_SoundFunction() {} - virtual void init(Player_AppleII *player, const byte *params) = 0; - /* returns true if finished */ - virtual bool update() = 0; -protected: - Player_AppleII *_player; -}; - -class Player_AppleII : public Audio::AudioStream, public MusicEngine { -public: - Player_AppleII(ScummEngine *scumm, Audio::Mixer *mixer); - virtual ~Player_AppleII(); - - virtual void setMusicVolume(int vol) { _sampleConverter.setMusicVolume(vol); } - void setSampleRate(int rate) { - _sampleRate = rate; - _sampleConverter.setSampleRate(rate); - } - virtual void startSound(int sound); - virtual void stopSound(int sound); - virtual void stopAllSounds(); - virtual int getSoundStatus(int sound) const; - virtual int getMusicTimer(); - - // AudioStream API - int readBuffer(int16 *buffer, const int numSamples); - bool isStereo() const { return false; } - bool endOfData() const { return false; } - int getRate() const { return _sampleRate; } - -public: - void speakerToggle(); - void generateSamples(int cycles); - void wait(int interval, int count); - -private: - // sound number - int _soundNr; - // type of sound - int _type; - // number of loops left - int _loop; - // global sound param list - const byte *_params; - // speaker toggle state (0 / 1) - byte _speakerState; - // sound function - AppleII_SoundFunction *_soundFunc; - // cycle to sample converter - SampleConverter _sampleConverter; - -private: - ScummEngine *_vm; - Audio::Mixer *_mixer; - Audio::SoundHandle _soundHandle; - int _sampleRate; - Common::Mutex _mutex; - -private: - void resetState(); - bool updateSound(); -}; - -} // End of namespace Scumm - -#endif |