From 87256747b180895d493f8c92f920fde20ad2ec15 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Thu, 17 Apr 2008 17:46:39 +0000 Subject: Implemented sfx support for Kyra3. svn-id: r31546 --- engines/kyra/kyra_v3.cpp | 16 ++- engines/kyra/kyra_v3.h | 8 ++ engines/kyra/script_v3.cpp | 8 +- engines/kyra/sound.h | 9 +- engines/kyra/sound_digital.cpp | 16 ++- engines/kyra/staticres.cpp | 310 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 359 insertions(+), 8 deletions(-) (limited to 'engines/kyra') diff --git a/engines/kyra/kyra_v3.cpp b/engines/kyra/kyra_v3.cpp index 4567e5777b..8b66955ffe 100644 --- a/engines/kyra/kyra_v3.cpp +++ b/engines/kyra/kyra_v3.cpp @@ -311,7 +311,7 @@ void KyraEngine_v3::playMenuAudioFile() { Common::SeekableReadStream *stream = _res->getFileStream(_menuAudioFile); if (stream) - _musicSoundChannel = _soundDigital->playSound(stream, true); + _musicSoundChannel = _soundDigital->playSound(stream, SoundDigital::kSoundTypeMusic); } void KyraEngine_v3::playMusicTrack(int track, int force) { @@ -334,7 +334,7 @@ void KyraEngine_v3::playMusicTrack(int track, int force) { Common::SeekableReadStream *stream = _res->getFileStream(_soundList[track]); if (stream) - _musicSoundChannel = _soundDigital->playSound(stream); + _musicSoundChannel = _soundDigital->playSound(stream, SoundDigital::kSoundTypeMusic); } _curMusicTrack = track; @@ -386,6 +386,18 @@ void KyraEngine_v3::fadeOutMusic(int ticks) { } } +void KyraEngine_v3::playSoundEffect(uint32 item, int priority) { + debugC(9, kDebugLevelMain, "KyraEngine_v3::playSoundEffect(%d, %d)", item, priority); + if (_sfxFileMap[item*2+0] != 0xFF) { + char filename[16]; + snprintf(filename, 16, "%s.AUD", _sfxFileList[_sfxFileMap[item*2+0]]); + + Common::SeekableReadStream *stream = _res->getFileStream(filename); + if (stream) + _soundDigital->playSound(stream, SoundDigital::kSoundTypeSfx); + } +} + #pragma mark - void KyraEngine_v3::preinit() { diff --git a/engines/kyra/kyra_v3.h b/engines/kyra/kyra_v3.h index 0b56f0da13..96d9f637a8 100644 --- a/engines/kyra/kyra_v3.h +++ b/engines/kyra/kyra_v3.h @@ -120,6 +120,13 @@ private: int musicUpdate(int forceRestart); void fadeOutMusic(int ticks); + void playSoundEffect(uint32 item, int priority); + + static const uint8 _sfxFileMap[]; + static const int _sfxFileMapSize; + static const char *_sfxFileList[]; + static const int _sfxFileListSize; + void snd_playVoiceFile(int) {} // main menu @@ -426,6 +433,7 @@ private: int o3_showMouse(ScriptState *script); int o3_delay(ScriptState *script); int o3_setSceneFilename(ScriptState *script); + int o3_playSoundEffect(ScriptState *script); int o3_getRand(ScriptState *script); int o3_defineRoomEntrance(ScriptState *script); int o3_setSpecialSceneScriptRunTime(ScriptState *script); diff --git a/engines/kyra/script_v3.cpp b/engines/kyra/script_v3.cpp index ab7af51f49..789d2bf06e 100644 --- a/engines/kyra/script_v3.cpp +++ b/engines/kyra/script_v3.cpp @@ -141,6 +141,12 @@ int KyraEngine_v3::o3_setSceneFilename(ScriptState *script) { return 0; } +int KyraEngine_v3::o3_playSoundEffect(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_playSoundEffect(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + playSoundEffect(stackPos(0), stackPos(1)); + return 0; +} + int KyraEngine_v3::o3_getRand(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_getRand(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); assert(stackPos(0) < stackPos(1)); @@ -428,7 +434,7 @@ void KyraEngine_v3::setupOpcodeTable() { OpcodeUnImpl(), // 0x58 OpcodeUnImpl(), - OpcodeUnImpl(), + Opcode(o3_playSoundEffect), OpcodeUnImpl(), OpcodeUnImpl(), // 0x5c diff --git a/engines/kyra/sound.h b/engines/kyra/sound.h index ff61a4f907..4fd36fe437 100644 --- a/engines/kyra/sound.h +++ b/engines/kyra/sound.h @@ -507,18 +507,25 @@ public: bool init() { return true; } + enum kSoundTypes { + kSoundTypeMusic, + kSoundTypeSfx, + kSoundTypeSpeech + }; + /** * Plays a sound. * * @param stream Data stream used for playback * It will be deleted when playback is finished + * @param type type * @param loop true if the sound should loop (endlessly) * @param fadeIn true if the sound should be faded in volume wise * @param channel tell the sound player to use a specific channel for playback * * @return channel playing the sound */ - int playSound(Common::SeekableReadStream *stream, bool loop = false, bool fadeIn = false, int channel = -1); + int playSound(Common::SeekableReadStream *stream, kSoundTypes type, bool loop = false, bool fadeIn = false, int channel = -1); /** * Checks if a given channel is playing a sound. diff --git a/engines/kyra/sound_digital.cpp b/engines/kyra/sound_digital.cpp index d256f9eb6f..e2e5612a1c 100644 --- a/engines/kyra/sound_digital.cpp +++ b/engines/kyra/sound_digital.cpp @@ -327,14 +327,15 @@ SoundDigital::~SoundDigital() { stopSound(i); } -int SoundDigital::playSound(Common::SeekableReadStream *stream, bool loop, bool fadeIn, int channel) { +int SoundDigital::playSound(Common::SeekableReadStream *stream, kSoundTypes type, bool loop, bool fadeIn, int channel) { Sound *use = 0; if (channel != -1 && channel < SOUND_STREAMS) { stopSound(channel); use = &_sounds[channel]; } else { for (channel = 0; channel < SOUND_STREAMS; ++channel) { - if (!_sounds[channel].stream) { + if (!isPlaying(channel)) { + stopSound(channel); use = &_sounds[channel]; break; } @@ -359,8 +360,12 @@ int SoundDigital::playSound(Common::SeekableReadStream *stream, bool loop, bool if (fadeIn) use->stream->beginFadeIn(60 * _vm->tickLength()); - // TODO: set correct sound type from channel id - _mixer->playInputStream(Audio::Mixer::kPlainSoundType, &use->handle, use->stream); + if (type == kSoundTypeMusic) + _mixer->playInputStream(Audio::Mixer::kMusicSoundType, &use->handle, use->stream); + else if (type == kSoundTypeSfx) + _mixer->playInputStream(Audio::Mixer::kSFXSoundType, &use->handle, use->stream); + else if (type == kSoundTypeSpeech) + _mixer->playInputStream(Audio::Mixer::kSpeechSoundType, &use->handle, use->stream); return use - _sounds; } @@ -371,6 +376,9 @@ bool SoundDigital::isPlaying(int channel) { assert(channel >= 0 && channel < SOUND_STREAMS); + if (!_sounds[channel].stream) + return false; + return _mixer->isSoundHandleActive(_sounds[channel].handle); } diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp index eb4466fbc4..d16245ac95 100644 --- a/engines/kyra/staticres.cpp +++ b/engines/kyra/staticres.cpp @@ -1999,6 +1999,316 @@ const uint8 KyraEngine_v3::_characterFrameTable[] = { 0x36, 0x35, 0x35, 0x33, 0x32, 0x32, 0x34, 0x34 }; +const uint8 KyraEngine_v3::_sfxFileMap[] = { + 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x99, 0x00, + 0x46, 0x00, 0xA9, 0x00, 0x33, 0x00, 0x65, 0x00, + 0x9B, 0x00, 0x17, 0x00, 0xBB, 0x00, 0x64, 0x00, + 0x55, 0x00, 0xD5, 0x00, 0x66, 0x00, 0xB9, 0x00, + 0x9A, 0x00, 0xFF, 0x00, 0xCC, 0x00, 0x67, 0x00, + 0x2E, 0x00, 0xA1, 0x00, 0xD0, 0x00, 0x63, 0x00, + 0x89, 0x00, 0xBE, 0x00, 0x80, 0x00, 0x1D, 0x00, + 0x02, 0x00, 0x28, 0x00, 0x91, 0x00, 0x29, 0x00, + 0xCE, 0x00, 0x8F, 0x00, 0x49, 0x00, 0x2B, 0x00, + 0x2D, 0x00, 0x2C, 0x00, 0x3E, 0x00, 0x22, 0x00, + 0x80, 0x00, 0x9C, 0x00, 0x2E, 0x00, 0x04, 0x00, + 0x47, 0x00, 0xA8, 0x00, 0x51, 0x00, 0x52, 0x00, + 0x80, 0x00, 0x48, 0x00, 0x38, 0x0A, 0x0C, 0x00, + 0xD8, 0x00, 0xD1, 0x00, 0xD2, 0x00, 0xD3, 0x00, + 0xD1, 0x00, 0x6A, 0x00, 0x8A, 0x00, 0xC0, 0x00, + 0xC1, 0x00, 0xC2, 0x00, 0x9F, 0x00, 0xA3, 0x00, + 0x90, 0x00, 0xB6, 0x00, 0x37, 0x00, 0x71, 0x00, + 0x13, 0x00, 0x50, 0x00, 0x5A, 0x00, 0x6E, 0x00, + 0x70, 0x00, 0x11, 0x00, 0x16, 0x00, 0x14, 0x00, + 0x43, 0x00, 0xCD, 0x00, 0xAA, 0x00, 0x15, 0x00, + 0x83, 0x00, 0x19, 0x00, 0xB3, 0x00, 0x6F, 0x00, + 0x26, 0x00, 0xC8, 0x00, 0xA7, 0x00, 0x98, 0x00, + 0x87, 0x00, 0xC7, 0x00, 0xA2, 0x00, 0xB0, 0x00, + 0x12, 0x00, 0xD7, 0x00, 0x56, 0x00, 0x45, 0x00, + 0x4B, 0x00, 0xAF, 0x00, 0x3B, 0x00, 0x6C, 0x00, + 0x8E, 0x00, 0x39, 0x00, 0x38, 0x00, 0x92, 0x00, + 0x4B, 0x00, 0xD0, 0x00, 0x4A, 0x00, 0x9D, 0x00, + 0x7F, 0x00, 0x6D, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0x3D, 0x00, 0x72, 0x00, 0x40, 0x00, 0x66, 0x00, + 0x01, 0x00, 0xA5, 0x00, 0x00, 0x00, 0x3C, 0x00, + 0xAC, 0x00, 0x38, 0x00, 0x8B, 0x00, 0xDF, 0x00, + 0x0E, 0x00, 0x54, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0x94, 0x00, 0xAB, 0x00, 0x76, 0x00, 0x58, 0x00, + 0x6B, 0x00, 0x27, 0x00, 0xFF, 0x00, 0x77, 0x00, + 0xA6, 0x00, 0x63, 0x00, 0x9E, 0x00, 0xDE, 0x00, + 0x84, 0x00, 0x85, 0x00, 0x86, 0x00, 0x3F, 0x00, + 0xCC, 0x00, 0xCC, 0x00, 0xCC, 0x00, 0x93, 0x00, + 0x9D, 0x00, 0x75, 0x00, 0x75, 0x00, 0x75, 0x00, + 0x75, 0x00, 0x3A, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0xFF, 0x00, 0xAE, 0x00, 0x8C, 0x00, 0x20, 0x00, + 0xFF, 0x00, 0x32, 0x00, 0x32, 0x00, 0xFF, 0x00, + 0x4D, 0x00, 0xD9, 0x00, 0x88, 0x00, 0x4D, 0x00, + 0x4D, 0x00, 0x4D, 0x00, 0x4D, 0x00, 0xA0, 0x00, + 0x4C, 0x00, 0x8C, 0x00, 0x4C, 0x00, 0x4C, 0x00, + 0x8C, 0x00, 0x8C, 0x00, 0x5C, 0x00, 0x5D, 0x00, + 0x60, 0x00, 0x5F, 0x00, 0xC5, 0x00, 0xBF, 0x00, + 0xFF, 0x00, 0x4F, 0x00, 0x16, 0x00, 0x59, 0x00, + 0xFF, 0x00, 0x24, 0x00, 0xA4, 0x00, 0xCF, 0x00, + 0xFF, 0x00, 0x47, 0x00, 0x95, 0x00, 0x96, 0x00, + 0x7B, 0x00, 0xBD, 0x00, 0xFF, 0x00, 0x34, 0x00, + 0x35, 0x00, 0x36, 0x00, 0xDE, 0x00, 0xFF, 0x00, + 0x4B, 0x00, 0xD6, 0x00, 0xFF, 0x00, 0x61, 0x00, + 0x62, 0x00, 0xFF, 0x00, 0x78, 0x00, 0xFF, 0x00, + 0x44, 0x00, 0xB4, 0x00, 0xB5, 0x00, 0x42, 0x00, + 0x27, 0x00, 0xA2, 0x00, 0x27, 0x00, 0x5D, 0x00, + 0x7A, 0x00, 0x89, 0x00, 0x1A, 0x00, 0x0E, 0x00, + 0x82, 0x00, 0xFF, 0x00, 0x79, 0x00, 0x2A, 0x00, + 0x81, 0x00, 0xFF, 0x00, 0x74, 0x00, 0x4E, 0x00, + 0xB1, 0x00, 0x1B, 0x00, 0x2F, 0x00, 0xBA, 0x00, + 0xBB, 0x00, 0xBC, 0x00, 0xDA, 0x00, 0xDB, 0x00, + 0x18, 0x00, 0x5E, 0x00, 0x0D, 0x0A, 0x88, 0x00, + 0x1E, 0x00, 0x1F, 0x00, 0x20, 0x00, 0x21, 0x00, + 0x69, 0x00, 0x1C, 0x00, 0x7C, 0x00, 0x30, 0x00, + 0xC3, 0x00, 0xC4, 0x00, 0xAD, 0x00, 0x25, 0x00, + 0x53, 0x00, 0xB7, 0x00, 0xB8, 0x00, 0xDC, 0x00, + 0x8D, 0x00, 0xCB, 0x00, 0xD4, 0x00, 0xB2, 0x00, + 0xDD, 0x00, 0x57, 0x00, 0x41, 0x00, 0x10, 0x00, + 0x4C, 0x00, 0xC9, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0x7D, 0x00, 0x7E, 0x00, 0xCA, 0x00, 0x03, 0x00, + 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, + 0x08, 0x00, 0x09, 0x00, 0x0A, 0x00, 0x0B, 0x00, + 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0x23, 0x00, 0x97, 0x00, 0x73, 0x00 +}; + +const int KyraEngine_v3::_sfxFileMapSize = ARRAYSIZE(KyraEngine_v3::_sfxFileMap); + +const char *KyraEngine_v3::_sfxFileList[] = { + "ALARM1", + "ARMOIRE1", + "ARROW1", + "AUDLAFF1", + "AUDLAFF2", + "AUDLAFF3", + "AUDLAFF4", + "AUDLAFF5", + "AUDLAFF6", + "AUDLAFF7", + "AUDLAFF8", + "AUDLAFF9", + "BARK22A", + "BEAM1", + "BEDSQK1", + "BEDSQK2", + "BIGCLOK1", + "BIGDOR2", + "BIRD4", + "BIRD122", + "BIRD222", + "BIRD322", + "BLAST22D", + "BLINK1", + "BOATMIX1", + "BODYFAL1", + "BOTLBLOW", + "BOUNCE3", + "BOUNCE5", + "BOW2", + "BUBL1", + "BUBL2", + "BUBL3", + "BUBL4", + "BUTTON1", + "BUTTON2", + "CANNON1", + "CASHREG1", + "CATHY1", + "CHAIN1", + "CHATTER1", + "CHATTER2", + "CHEESE1", + "CHICHIC2", + "CHIPLAF1", + "CHIPROR1", + "CLANG1", + "CLDOOR1", + "CLEAT1", + "CLOTHES1", + "COIN2", + "COUNTER1", + "CREAK1", + "CREAK2", + "CREAK3", + "CRIKT22A", + "CRMAD1", + "CRNORM1", + "CRUMBLE1", + "CRUNCH1", + "CRYSTAL1", + "DFLY1", + "DIAL1", + "DIGDIRT1", + "DIZZY1", + "DODO1", + "DOORBELL", + "DOORCL1", + "DOOROP1", + "DRIP1", + "DROPITM1", + "EAT22A", + "EATNUT1", + "ELEC1", + "EXPLODE2", + "FALL1", + "FALLM2", + "FALLM3", + "FESTRE1", + "FISHLAF2", + "FLAG22A", + "FLAG22B", + "FLAG22C", + "FLPOOF1", + "FOLDER1", + "FROG1", + "FROGJMP1", + "FSHBUBL1", + "FUNNEL1", + "FUSE1", + "GATE22A", + "GEM1", + "GEMFIRE1", + "GEMLIT1", + "GEMPUT1", + "GEMRAIN1", + "GEMWND1", + "GIRLLAF1", + "GIRLLAF2", + "GLASBRK1", + "GLOWY1", + "GOODK33", + "GROWTWIG", + "GUNTHER3", + "H2ODROP2", + "H2OFALL1", + "HAMMER1", + "HAYFALL2", + "HERMMAG1", + "HIPRES1", + "HITHED22", + "HOWL1", + "HUM1", + "HYPNO1", + "HYPNO2", + "IMPACT1", + "JOHAN1", + "JUNGAMB2", + "KISS1", + "KISS2", + "KNIFE", + "KNIFHIT1", + "KNIFSTAB", + "KNOCK", + "LAND1", + "LEVIBAB1", + "LEVIMAN1", + "LID", + "MACHMIX1", + "MALCFALL", + "MALCYAWN", + "MJUMP1", + "MOO1", + "MOO2", + "MOO3", + "MORPH1", + "MORPH2", + "MORPH3", + "MORPH4", + "MOTHS1", + "MSPLASH1", + "MTLSLAM1", + "MUDBATH1", + "NAIL1", + "NEIGH1", + "NETCATCH", + "NETMAL1", + "NETRIP1", + "OPDOOR1", + "OWL1", + "OWL2", + "PEDAL3", + "PEGWING1", + "PICKUP1", + "PLUCK3", + "POLGULP1", + "POOF1", + "PORTAL1", + "POURH2O1", + "PRIMOR1", + "PUMP1", + "PUNCTRE1", + "RATTLE1", + "REV2", + "RING", + "ROAR3", + "ROWBOAT1", + "RUCKUS1", + "RUMBLE1", + "SCOLD1", + "SCRATCH1", + "SHOVEL1", + "SHOWER2", + "SLOTPUL1", + "SNAKKILL", + "SNAP1", + "SNIFF1", + "SNIFF2", + "SNIFFM1", + "SNIP22B", + "SNORIN1", + "SNOROUT1", + "SNORT1", + "SPITBAL1", + "SPITBAL2", + "SPLASH1", + "SQUEAK1", + "SQUEAK2", + "SQUEAK3", + "STATUE", + "STAMPED1", + "STARS1", + "STONE1", + "STONE2", + "STONE3", + "STRETCH1", + "STRETCH2", + "SUNRISE1", + "SWALLOW1", + "SWALLOW2", + "SWAV22B", + "TELBEL1", + "TELBEL2", + "TENNIS1", + "THROW1", + "THUMP1", + "TOILET1", + "TRAPDOR1", + "TRICKLE", + "TROLGRNT", + "TROLYEL1", + "TROLYEL2", + "TUBEDOR1", + "TWIGSNAP", + "UMBRLA1", + "UNLOK22A", + "VACUUM", + "WAVELT1", + "WHIP1", + "WHIP2", + "WOODHIT1", + "YAWN1", + "ZING", + "ZIPPER1" +}; + +const int KyraEngine_v3::_sfxFileListSize = ARRAYSIZE(KyraEngine_v3::_sfxFileList); + } // End of namespace Kyra -- cgit v1.2.3