diff options
author | Travis Howell | 2006-04-17 12:05:45 +0000 |
---|---|---|
committer | Travis Howell | 2006-04-17 12:05:45 +0000 |
commit | 82dfef4ce2c65dd3c345628eac19cfc3ccb4cbb9 (patch) | |
tree | 5ee3d78362721348b20a51f4f84c605010c9b494 | |
parent | 85158181cf9bd56b6c46c735182391ab3e692932 (diff) | |
download | scummvm-rg350-82dfef4ce2c65dd3c345628eac19cfc3ccb4cbb9.tar.gz scummvm-rg350-82dfef4ce2c65dd3c345628eac19cfc3ccb4cbb9.tar.bz2 scummvm-rg350-82dfef4ce2c65dd3c345628eac19cfc3ccb4cbb9.zip |
Improve sound support in FF and add MoviePlayer class
svn-id: r21975
-rw-r--r-- | engines/simon/animation.cpp | 114 | ||||
-rw-r--r-- | engines/simon/animation.h | 24 | ||||
-rw-r--r-- | engines/simon/debug.h | 2 | ||||
-rw-r--r-- | engines/simon/items.cpp | 7 | ||||
-rw-r--r-- | engines/simon/res.cpp | 17 | ||||
-rw-r--r-- | engines/simon/simon.cpp | 7 | ||||
-rw-r--r-- | engines/simon/simon.h | 11 | ||||
-rw-r--r-- | engines/simon/sound.cpp | 79 | ||||
-rw-r--r-- | engines/simon/sound.h | 8 | ||||
-rw-r--r-- | engines/simon/vga.cpp | 21 |
10 files changed, 191 insertions, 99 deletions
diff --git a/engines/simon/animation.cpp b/engines/simon/animation.cpp index a1fd4ed57f..dd383ca596 100644 --- a/engines/simon/animation.cpp +++ b/engines/simon/animation.cpp @@ -26,17 +26,28 @@ #include "common/system.h" #include "simon/animation.h" +#include "simon/intern.h" +#include "simon/simon.h" + +#include "sound/wave.h" + #ifdef USE_ZLIB #include <zlib.h> #endif +namespace Simon { + +MoviePlayer::MoviePlayer(SimonEngine *vm, Audio::Mixer *mixer) + : _vm(vm), _mixer(mixer) { +} + +MoviePlayer::~MoviePlayer() { +} + bool MoviePlayer::open(const char *filename) { - bool opened = false; char filename2[100]; - - _leftButtonDown = false; - _rightButtonDown = false; + uint32 tag; // Change file extension to dxa strcpy(filename2, filename); @@ -46,38 +57,63 @@ bool MoviePlayer::open(const char *filename) { filename2[len++] = 'x'; filename2[len++] = 'a'; - if (_fd.open(filename2)) { - uint32 tag = _fd.readUint32BE(); - if (tag == MKID_BE('DEXA')) { - _fd.readByte(); - _framesCount = _fd.readUint16BE(); - _frameTicks = _fd.readUint32BE(); - if (_frameTicks > 100) { - _frameTicks = 100; - } - _width = _fd.readUint16BE(); - _height = _fd.readUint16BE(); - debug(5, "frames_count %d width %d height %d ticks %d", _framesCount, _width, _height, _frameTicks); - _frameSize = _width * _height; - _frameBuffer1 = (uint8 *)malloc(_frameSize); - _frameBuffer2 = (uint8 *)malloc(_frameSize); - if (!_frameBuffer1 || !_frameBuffer2) { - error("error allocating frame tables, size %d\n", _frameSize); - close(); - } else { - tag = _fd.readUint32BE(); - if (tag == MKID_BE('WAVE')) { - uint32 size = _fd.readUint32BE(); - debug(5, "Wave_size = %d", size); - // TODO: Preload wave data - _fd.seek(size + 23); - } - _currentFrame = 0; - opened = true; - } - } + if (_fd.open(filename2) == false) + return false; + + _mixer->stopAll(); + + _currentFrame = 0; + + _leftButtonDown = false; + _rightButtonDown = false; + + tag = _fd.readUint32BE(); + assert(tag == MKID_BE('DEXA')); + + _fd.readByte(); + _framesCount = _fd.readUint16BE(); + _frameTicks = _fd.readUint32BE(); + if (_frameTicks > 100) { + _frameTicks = 100; + } + _width = _fd.readUint16BE(); + _height = _fd.readUint16BE(); + debug(5, "frames_count %d width %d height %d ticks %d", _framesCount, _width, _height, _frameTicks); + _frameSize = _width * _height; + _frameBuffer1 = (uint8 *)malloc(_frameSize); + _frameBuffer2 = (uint8 *)malloc(_frameSize); + if (!_frameBuffer1 || !_frameBuffer2) { + error("error allocating frame tables, size %d\n", _frameSize); + } + + tag = _fd.readUint32BE(); + assert(tag == MKID_BE('WAVE')); + + uint32 size = _fd.readUint32BE(); + byte *buffer = (byte *)malloc(size); + _fd.read(buffer, size); + + // TODO: Audio and video sync. + Common::MemoryReadStream stream(buffer, size); + AudioStream *sndStream = makeWAVStream(stream); + _mixer->playInputStream(Audio::Mixer::kSFXSoundType, NULL, sndStream); + + // Resolution is smaller in Amiga verison so always clear screen + if (_width != 640 && _height != 480) + g_system->clearScreen(); + + play(); + close(); + + _vm->o_killAnimate(); + + if (_vm->getBitFlag(41)) { + // TODO + } else { + g_system->clearScreen(); } - return opened; + + return true; } void MoviePlayer::close() { @@ -87,14 +123,10 @@ void MoviePlayer::close() { } void MoviePlayer::play() { - g_system->clearScreen(); - while (_currentFrame < _framesCount) { handleNextFrame(); ++_currentFrame; } - - g_system->clearScreen(); } void MoviePlayer::handleNextFrame() { @@ -214,7 +246,7 @@ void MoviePlayer::delay(uint amount) { } } - if (_leftButtonDown && _rightButtonDown) { + if (_leftButtonDown && _rightButtonDown && !_vm->getBitFlag(40)) { _currentFrame = _framesCount; amount = 0; } @@ -231,3 +263,5 @@ void MoviePlayer::delay(uint amount) { cur = g_system->getMillis(); } while (cur < start + amount); } + +} // End of namespace Simon diff --git a/engines/simon/animation.h b/engines/simon/animation.h index b1fa7cb271..502fc4ee9e 100644 --- a/engines/simon/animation.h +++ b/engines/simon/animation.h @@ -24,8 +24,19 @@ #define ANIMATION_H #include "common/file.h" +#include "common/stream.h" + +#include "sound/mixer.h" + +namespace Simon { + +class SimonEngine; + +class MoviePlayer { + SimonEngine *_vm; + + Audio::Mixer *_mixer; -struct MoviePlayer { bool _playing; bool _leftButtonDown; bool _rightButtonDown; @@ -39,15 +50,22 @@ struct MoviePlayer { uint16 _currentFrame; uint32 _frameTicks; +public: + MoviePlayer(SimonEngine *vm, Audio::Mixer *mixer); + ~MoviePlayer(); + bool open(const char *filename); - void close(); +private: void play(); - void delay(uint amount); + void close(); + void delay(uint amount); void handleNextFrame(); void decodeZlib(uint8 *data, int size, int totalSize); void decode0(uint8 *data, int size); void decode2(uint8 *data, int size, int totalSize); }; +} // End of namespace Simon + #endif diff --git a/engines/simon/debug.h b/engines/simon/debug.h index 24e50c4401..f844adb629 100644 --- a/engines/simon/debug.h +++ b/engines/simon/debug.h @@ -1030,7 +1030,7 @@ static const char *const feeblefiles_opcode_name_table[256] = { NULL, /* 36 */ "VV|MOVE", - NULL, + "|JUMP_OUT", NULL, NULL, /* 40 */ diff --git a/engines/simon/items.cpp b/engines/simon/items.cpp index 7a75bec70f..5f58523fd4 100644 --- a/engines/simon/items.cpp +++ b/engines/simon/items.cpp @@ -1926,18 +1926,13 @@ void SimonEngine::o3_mouseOff() { void SimonEngine::o3_loadSmack() { // 182: load video file _videoName = getStringPtrByID(getNextStringID()); - debug(0,"Load video file: %s", _videoName); } void SimonEngine::o3_playSmack() { // 183: play video debug(0, "Play video %s", _videoName); - MoviePlayer p; - if (p.open((const char *)_videoName)) { - p.play(); - p.close(); - } + _moviePlay->open((const char *)_videoName); } void SimonEngine::o3_centreScroll() { diff --git a/engines/simon/res.cpp b/engines/simon/res.cpp index 8e72318400..f99e6c1fda 100644 --- a/engines/simon/res.cpp +++ b/engines/simon/res.cpp @@ -672,7 +672,9 @@ byte *SimonEngine::read_vga_from_datfile_2(uint id, uint type) { } } -void SimonEngine::loadSound(uint sound, uint pan, uint vol, bool ambient) { +void SimonEngine::loadSound(uint sound, uint pan, uint vol, uint type) { + byte *dst; + if (getFeatures() & GF_ZLIBCOMP) { char filename[15]; @@ -688,13 +690,18 @@ void SimonEngine::loadSound(uint sound, uint pan, uint vol, bool ambient) { else sprintf(filename, "effects.wav"); - byte *dst = (byte *)malloc(dstSize); + dst = (byte *)malloc(dstSize); decompressData(filename, dst, offset, srcSize, dstSize); - _sound->playSoundData(dst, sound, pan, vol, ambient); } else { - int offs = READ_LE_UINT32(_curSfxFile + sound * 4); - _sound->playSoundData(_curSfxFile + offs, sound, pan, vol, ambient); + dst = _curSfxFile + READ_LE_UINT32(_curSfxFile + sound * 4); } + + if (type == 3) + _sound->playSfx5Data(dst, sound, pan, vol); + else if (type == 2) + _sound->playAmbientData(dst, sound, pan, vol); + else + _sound->playSfxData(dst, sound, pan, vol); } void SimonEngine::loadVoice(uint speechId) { diff --git a/engines/simon/simon.cpp b/engines/simon/simon.cpp index a6104c8aa1..8d8d066f88 100644 --- a/engines/simon/simon.cpp +++ b/engines/simon/simon.cpp @@ -434,6 +434,7 @@ SimonEngine::SimonEngine(OSystem *syst) _numScreenUpdates = 0; _vgaTickCounter = 0; + _moviePlay = 0; _sound = 0; _effectsPaused = false; @@ -680,8 +681,9 @@ SimonEngine::~SimonEngine() { delete [] _windowList; - delete _sound; delete _debugger; + delete _moviePlay; + delete _sound; } void SimonEngine::errorString(const char *buf1, char *buf2) { @@ -3494,8 +3496,9 @@ int SimonEngine::go() { setup_vga_file_buf_pointers(); - _sound = new Sound(this, gss, _mixer); _debugger = new Debugger(this); + _moviePlay = new MoviePlayer(this, _mixer); + _sound = new Sound(this, gss, _mixer); if (ConfMan.hasKey("sfx_mute") && ConfMan.getBool("sfx_mute") == 1) { if (getGameId() == GID_SIMON1DOS) diff --git a/engines/simon/simon.h b/engines/simon/simon.h index 3bd8354c6b..204af15c85 100644 --- a/engines/simon/simon.h +++ b/engines/simon/simon.h @@ -30,6 +30,7 @@ #include "common/rect.h" #include "common/util.h" +#include "simon/animation.h" #include "simon/midi.h" #include "simon/sound.h" #include "simon/vga.h" @@ -429,6 +430,8 @@ protected: int _numScreenUpdates; int _vgaTickCounter; + MoviePlayer *_moviePlay; + Sound *_sound; bool _effectsPaused; @@ -481,7 +484,7 @@ protected: void loadGamePcFile(const char *filename); void decompressData(const char *srcName, byte *dst, uint32 offset, uint32 srcSize, uint32 dstSize); void loadOffsets(const char *filename, int number, uint32 &file, uint32 &offset, uint32 &compressedSize, uint32 &size); - void loadSound(uint sound, uint pan, uint vol, bool ambient); + void loadSound(uint sound, uint pan, uint vol, uint type); void loadVoice(uint speechId); void palette_fadeout(uint32 *pal_values, uint num); @@ -710,6 +713,9 @@ protected: void run_vga_script(); public: + bool getBitFlag(uint bit); + void setBitFlag(uint bit, bool value); + // Simon1/Simon2 video script opcodes void vc1_fadeOut(); void vc2_call(); @@ -1016,9 +1022,6 @@ protected: void add_vga_timer(uint num, const byte *code_ptr, uint cur_sprite, uint cur_file); VgaSprite *findCurSprite(); - bool getBitFlag(uint bit); - void setBitFlag(uint bit, bool value); - void expire_vga_timers(); bool isSpriteLoaded(uint16 id, uint16 zoneNum); diff --git a/engines/simon/sound.cpp b/engines/simon/sound.cpp index 87e1151dd0..250baf0487 100644 --- a/engines/simon/sound.cpp +++ b/engines/simon/sound.cpp @@ -247,6 +247,7 @@ Sound::Sound(SimonEngine *vm, const GameSpecificSettings *gss, Audio::Mixer *mix _effectsPaused = false; _ambientPaused = false; + _sfx5Paused = false; _filenums = 0; _lastVoiceFile = 0; @@ -254,7 +255,9 @@ Sound::Sound(SimonEngine *vm, const GameSpecificSettings *gss, Audio::Mixer *mix _hasEffectsFile = false; _hasVoiceFile = false; + _ambientPlaying = 0; + _sfx5Playing = 0; if (_vm->getFeatures() & GF_TALKIE) { loadVoiceFile(gss); @@ -265,6 +268,14 @@ Sound::Sound(SimonEngine *vm, const GameSpecificSettings *gss, Audio::Mixer *mix } +Sound::~Sound() { + delete _voice; + delete _effects; + + free(_filenums); + free(_offsets); +} + void Sound::loadVoiceFile(const GameSpecificSettings *gss) { // Game versions which use separate voice files if (_vm->getGameType() == GType_FF || _vm->getGameId() == GID_SIMON1CD32) @@ -371,14 +382,6 @@ void Sound::loadSfxFile(const GameSpecificSettings *gss) { } } -Sound::~Sound() { - delete _voice; - delete _effects; - - free(_filenums); - free(_offsets); -} - void Sound::readSfxFile(const char *filename) { if (_hasEffectsFile) return; @@ -486,7 +489,7 @@ bool Sound::hasVoice() const { } bool Sound::isVoiceActive() const { - return _mixer->isSoundHandleActive(_voiceHandle) ; + return _mixer->isSoundHandleActive(_voiceHandle); } void Sound::stopVoice() { @@ -496,10 +499,12 @@ void Sound::stopVoice() { void Sound::stopAll() { _mixer->stopAll(); _ambientPlaying = 0; + _sfx5Playing = 0; } void Sound::effectsPause(bool b) { _effectsPaused = b; + _sfx5Paused = b; } void Sound::ambientPause(bool b) { @@ -515,22 +520,42 @@ void Sound::ambientPause(bool b) { } // Feeble Files specific -void Sound::playSoundData(byte *soundData, uint sound, uint pan, uint vol, bool ambient) { - byte flags; - int rate; +void Sound::playAmbientData(byte *soundData, uint sound, uint pan, uint vol) { + if (sound == _ambientPlaying) + return; - if (ambient == true) { - if (sound == _ambientPlaying) - return; + _ambientPlaying = sound; - _ambientPlaying = sound; + if (_ambientPaused) + return; - if (_ambientPaused) - return; - } else { - if (_effectsPaused) - return; - } + _mixer->stopHandle(_ambientHandle); + playSoundData(&_ambientHandle, soundData, sound, pan, vol, true); +} + +void Sound::playSfxData(byte *soundData, uint sound, uint pan, uint vol) { + if (_effectsPaused) + return; + + playSoundData(&_effectsHandle, soundData, sound, pan, vol, false); +} + +void Sound::playSfx5Data(byte *soundData, uint sound, uint pan, uint vol) { + if (sound == _sfx5Playing) + return; + + _sfx5Playing = sound; + + if (_sfx5Paused) + return; + + _mixer->stopHandle(_sfx5Handle); + playSoundData(&_sfx5Handle, soundData, sound, pan, vol, true); +} + +void Sound::playSoundData(Audio::SoundHandle *handle, byte *soundData, uint sound, uint pan, uint vol, bool loop) { + byte flags; + int rate; int size = READ_LE_UINT32(soundData + 4); Common::MemoryReadStream stream(soundData, size); @@ -541,12 +566,10 @@ void Sound::playSoundData(byte *soundData, uint sound, uint pan, uint vol, bool byte *buffer = (byte *)malloc(size); memcpy(buffer, soundData + stream.pos(), size); - if (ambient == true) { - _mixer->stopHandle(_ambientHandle); - _mixer->playRaw(&_ambientHandle, buffer, size, rate, Audio::Mixer::FLAG_LOOP|flags); - } else { - _mixer->playRaw(&_effectsHandle, buffer, size, rate, flags); - } + if (loop == true) + flags |= Audio::Mixer::FLAG_LOOP; + + _mixer->playRaw(handle, buffer, size, rate, flags, sound); } void Sound::playVoiceData(byte *soundData, uint sound) { diff --git a/engines/simon/sound.h b/engines/simon/sound.h index 778a38c1f4..4f45f8691d 100644 --- a/engines/simon/sound.h +++ b/engines/simon/sound.h @@ -41,6 +41,7 @@ private: bool _effectsPaused; bool _ambientPaused; + bool _sfx5Paused; uint16 *_filenums; uint32 *_offsets; @@ -49,10 +50,12 @@ private: Audio::SoundHandle _voiceHandle; Audio::SoundHandle _effectsHandle; Audio::SoundHandle _ambientHandle; + Audio::SoundHandle _sfx5Handle; bool _hasEffectsFile; bool _hasVoiceFile; uint _ambientPlaying; + uint _sfx5Playing; public: Sound(SimonEngine *vm, const GameSpecificSettings *gss, Audio::Mixer *mixer); @@ -70,7 +73,10 @@ public: void playAmbient(uint sound); // Feeble Files specific - void playSoundData(byte *soundData, uint sound, uint pan, uint vol, bool ambient); + void playAmbientData(byte *soundData, uint sound, uint pan, uint vol); + void playSfxData(byte *soundData, uint sound, uint pan, uint vol); + void playSfx5Data(byte *soundData, uint sound, uint pan, uint vol); + void playSoundData(Audio::SoundHandle *handle, byte *soundData, uint sound, uint pan, uint vol, bool loop); void playVoiceData(byte *soundData, uint sound); void switchVoiceFile(uint disc); diff --git a/engines/simon/vga.cpp b/engines/simon/vga.cpp index 6d83508491..48372cfc73 100644 --- a/engines/simon/vga.cpp +++ b/engines/simon/vga.cpp @@ -1966,13 +1966,16 @@ void SimonEngine::vc52_playSound() { if (getGameType() == GType_FF) { uint16 pan = vcReadNextWord(); uint16 vol = vcReadNextWord(); - loadSound(sound, pan, vol, ambient); + + if (ambient) + loadSound(sound, pan, vol, 2); + else + loadSound(sound, pan, vol, 1); } else if (getGameType() == GType_SIMON2) { - if (ambient) { + if (ambient) _sound->playAmbient(sound); - } else { + else _sound->playEffects(sound); - } } else if (getFeatures() & GF_TALKIE) { _sound->playEffects(sound); } else if (getGameId() == GID_SIMON1DOS) { @@ -2468,11 +2471,11 @@ void SimonEngine::vc82_getPathValue() { } void SimonEngine::vc83_playSoundLoop() { - // Start looping sound effect - int snd = vcReadNextWord(); - int vol = vcReadNextWord(); - int pan = vcReadNextWord(); - debug(0, "STUB: vc83_playSoundLoop: snd %d vol %d pan %d", snd, vol, pan); + uint sound = vcReadNextWord(); + uint vol = vcReadNextWord(); + uint pan = vcReadNextWord(); + + loadSound(sound, pan, vol, 3); } void SimonEngine::vc84_stopSoundLoop() { |