aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTravis Howell2006-04-17 12:05:45 +0000
committerTravis Howell2006-04-17 12:05:45 +0000
commit82dfef4ce2c65dd3c345628eac19cfc3ccb4cbb9 (patch)
tree5ee3d78362721348b20a51f4f84c605010c9b494
parent85158181cf9bd56b6c46c735182391ab3e692932 (diff)
downloadscummvm-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.cpp114
-rw-r--r--engines/simon/animation.h24
-rw-r--r--engines/simon/debug.h2
-rw-r--r--engines/simon/items.cpp7
-rw-r--r--engines/simon/res.cpp17
-rw-r--r--engines/simon/simon.cpp7
-rw-r--r--engines/simon/simon.h11
-rw-r--r--engines/simon/sound.cpp79
-rw-r--r--engines/simon/sound.h8
-rw-r--r--engines/simon/vga.cpp21
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() {