From c96ec85dbba1f6bb9e369cd698cc6cbd6cff2873 Mon Sep 17 00:00:00 2001 From: Eugene Sandulenko Date: Wed, 17 Jun 2009 23:16:21 +0000 Subject: Preliminary support for CoCo3 music. svn-id: r41618 --- engines/agi/agi.cpp | 2 +- engines/agi/sound.cpp | 35 +++++++++++++++++++++++++++++- engines/agi/sound.h | 59 +++++++++++++++++++++++++++++++++------------------ 3 files changed, 73 insertions(+), 23 deletions(-) (limited to 'engines/agi') diff --git a/engines/agi/agi.cpp b/engines/agi/agi.cpp index 218d2f117d..e373dd3e6d 100644 --- a/engines/agi/agi.cpp +++ b/engines/agi/agi.cpp @@ -730,7 +730,7 @@ void AgiEngine::initialize() { if (getPlatform() == Common::kPlatformApple2GS) { _soundemu = SOUND_EMU_APPLE2GS; } else if (getPlatform() == Common::kPlatformCoCo3) { - _soundemu = 0; // FIXME: Implement CoCo3 sound support + _soundemu = SOUND_EMU_COCO3; } else { switch (MidiDriver::detectMusicDriver(MDT_PCSPK)) { case MD_PCSPK: diff --git a/engines/agi/sound.cpp b/engines/agi/sound.cpp index eabe2f1dba..40f8dacf9b 100644 --- a/engines/agi/sound.cpp +++ b/engines/agi/sound.cpp @@ -367,7 +367,7 @@ void SoundMgr::startSound(int resnum, int flag) { _vm->_game.sounds[resnum]->play(); _playingSound = resnum; - debugC(3, kDebugLevelSound, "startSound(resnum = %d, flag = %d)", resnum, flag); + debugC(3, kDebugLevelSound, "startSound(resnum = %d, flag = %d) type = %d", resnum, flag, type); switch (type) { case AGI_SOUND_SAMPLE: { @@ -477,6 +477,8 @@ int SoundMgr::initSound() { case SOUND_EMU_APPLE2GS: _disabledMidi = !loadInstruments(); break; + case SOUND_EMU_COCO3: + break; } report("Initializing sound:\n"); @@ -822,6 +824,35 @@ void SoundMgr::playSampleSound() { _playing = _gsSound.activeSounds() > 0; } +static int cocoFrequencies[] = { + 130, 138, 146, 155, 164, 174, 184, 195, 207, 220, 233, 246, + 261, 277, 293, 311, 329, 349, 369, 391, 415, 440, 466, 493, + 523, 554, 587, 622, 659, 698, 739, 783, 830, 880, 932, 987, + 1046, 1108, 1174, 1244, 1318, 1396, 1479, 1567, 1661, 1760, 1864, 1975, + 2093, 2217, 2349, 2489, 2637, 2793, 2959, 3135, 3322, 3520, 3729, 3951 +}; + +void SoundMgr::playCoCoSound() { + int i; + CoCoNote note; + + do { + note.read(_chn[i].ptr); + + if (note.freq != 0xff) { + playNote(0, cocoFrequencies[note.freq], note.volume); + + uint32 start_time = _vm->_system->getMillis(); + + while (_vm->_system->getMillis() < start_time + note.duration) { + _vm->_system->updateScreen(); + + _vm->_system->delayMillis(10); + } + } + } while (note.freq != 0xff); +} + void SoundMgr::playAgiSound() { int i; AgiNote note; @@ -878,6 +909,8 @@ void SoundMgr::playSound() { playSampleSound(); } } + } else if (_vm->_soundemu == SOUND_EMU_COCO3) { + playCoCoSound(); } else { //debugC(3, kDebugLevelSound, "playSound: Trying to play a PCjr 4-channel sound"); playAgiSound(); diff --git a/engines/agi/sound.h b/engines/agi/sound.h index fd178e3a1d..a24a665b2a 100644 --- a/engines/agi/sound.h +++ b/engines/agi/sound.h @@ -51,6 +51,7 @@ namespace Agi { #define SOUND_EMU_MAC 3 #define SOUND_EMU_AMIGA 4 #define SOUND_EMU_APPLE2GS 5 +#define SOUND_EMU_COCO3 6 #define WAVEFORM_SIZE 64 #define ENV_ATTACK 10000 /**< envelope attack rate */ @@ -228,27 +229,42 @@ struct IIgsChannelInfo { bool playing(); ///< Is there a note playing on this channel? }; - /** - * AGI sound resource types. - * It's probably coincidence that all the values here are powers of two - * as they're simply the different used values in AGI sound resources' - * starts (The first 16-bit little endian word, to be precise). - */ - enum AgiSoundType { - AGI_SOUND_SAMPLE = 0x0001, - AGI_SOUND_MIDI = 0x0002, - AGI_SOUND_4CHN = 0x0008 - }; - enum AgiSoundFlags { - AGI_SOUND_LOOP = 0x0001, - AGI_SOUND_ENVELOPE = 0x0002 - }; - enum AgiSoundEnv { - AGI_SOUND_ENV_ATTACK = 3, - AGI_SOUND_ENV_DECAY = 2, - AGI_SOUND_ENV_SUSTAIN = 1, - AGI_SOUND_ENV_RELEASE = 0 - }; +struct CoCoNote { + uint8 freq; + uint8 volume; + uint16 duration; ///< Note duration + + /** Reads a CoCoNote through the given pointer. */ + void read(const uint8 *ptr) { + freq = *ptr; + volume = *(ptr + 1); + duration = READ_LE_UINT16(ptr + 2); + } +}; + +/** + * AGI sound resource types. + * It's probably coincidence that all the values here are powers of two + * as they're simply the different used values in AGI sound resources' + * starts (The first 16-bit little endian word, to be precise). + */ +enum AgiSoundType { + AGI_SOUND_SAMPLE = 0x0001, + AGI_SOUND_MIDI = 0x0002, + AGI_SOUND_4CHN = 0x0008 +}; +enum AgiSoundFlags { + AGI_SOUND_LOOP = 0x0001, + AGI_SOUND_ENVELOPE = 0x0002 +}; +enum AgiSoundEnv { + AGI_SOUND_ENV_ATTACK = 3, + AGI_SOUND_ENV_DECAY = 2, + AGI_SOUND_ENV_SUSTAIN = 1, + AGI_SOUND_ENV_RELEASE = 0 +}; + + /** * AGI engine sound channel structure. */ @@ -485,6 +501,7 @@ public: void stopNote(int i); void playNote(int i, int freq, int vol); void playAgiSound(); + void playCoCoSound(); uint32 mixSound(); bool loadInstruments(); void playMidiSound(); -- cgit v1.2.3