diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/groovie/detection.cpp | 14 | ||||
-rw-r--r-- | engines/groovie/groovie.cpp | 41 | ||||
-rw-r--r-- | engines/groovie/groovie.h | 8 | ||||
-rw-r--r-- | engines/groovie/music.cpp | 73 | ||||
-rw-r--r-- | engines/groovie/music.h | 19 | ||||
-rw-r--r-- | engines/groovie/player.cpp | 19 | ||||
-rw-r--r-- | engines/groovie/player.h | 8 | ||||
-rw-r--r-- | engines/groovie/resource.cpp | 2 | ||||
-rw-r--r-- | engines/groovie/resource.h | 3 | ||||
-rw-r--r-- | engines/groovie/script.cpp | 6 | ||||
-rw-r--r-- | engines/groovie/script.h | 1 | ||||
-rw-r--r-- | engines/groovie/vdx.cpp | 8 |
12 files changed, 185 insertions, 17 deletions
diff --git a/engines/groovie/detection.cpp b/engines/groovie/detection.cpp index cf3a035354..00116d6e00 100644 --- a/engines/groovie/detection.cpp +++ b/engines/groovie/detection.cpp @@ -114,6 +114,20 @@ static const GroovieGameDescription gameDescriptions[] = { kGroovieT7G, 0 }, + { + { + "t7g", "", + { + { "script.grv", 0, "d1b8033b40aa67c076039881eccce90d", 16659}, + { "gu16.m4a", 0, NULL, 2051214 }, + { NULL, 0, NULL, 0} + }, + Common::EN_ANY, Common::kPlatformIOS, ADGF_NO_FLAGS, + Common::GUIO_NOMIDI + }, + kGroovieT7G, 0 + }, + #ifdef ENABLE_GROOVIE2 // The 11th Hour DOS English { diff --git a/engines/groovie/groovie.cpp b/engines/groovie/groovie.cpp index 67c8f3dbc7..552aec6128 100644 --- a/engines/groovie/groovie.cpp +++ b/engines/groovie/groovie.cpp @@ -55,6 +55,15 @@ GroovieEngine::GroovieEngine(OSystem *syst, const GroovieGameDescription *gd) : SearchMan.addSubDirectoryMatching(gameDataDir, "media"); SearchMan.addSubDirectoryMatching(gameDataDir, "system"); + _modeSpeed = kGroovieSpeedNormal; + if (ConfMan.hasKey("t7g_speed")) { + Common::String speed = ConfMan.get("t7g_speed"); + if (speed.equals("im_an_ios")) + _modeSpeed = kGroovieSpeediOS; + else if (speed.equals("tweaked")) + _modeSpeed = kGroovieSpeedTweaked; + } + // Initialize the custom debug levels DebugMan.addDebugChannel(kGroovieDebugAll, "All", "Debug everything"); DebugMan.addDebugChannel(kGroovieDebugVideo, "Video", "Debug video and audio playback"); @@ -142,10 +151,20 @@ Common::Error GroovieEngine::run() { } // Create the music player - if (getPlatform() == Common::kPlatformMacintosh) + switch (getPlatform()) { + case Common::kPlatformMacintosh: + // TODO: The 11th Hour Mac uses QuickTime MIDI files + // Right now, since the XMIDI are present and it is still detected as + // the DOS version, we don't have to do anything here. _musicPlayer = new MusicPlayerMac(this); - else + break; + case Common::kPlatformIOS: + _musicPlayer = new MusicPlayerMPEG4(this); + break; + default: _musicPlayer = new MusicPlayerXMI(this, _gameDescription->version == kGroovieT7G ? "fat" : "sample"); + break; + } // Load volume levels syncSoundSettings(); @@ -208,17 +227,19 @@ Common::Error GroovieEngine::run() { _script->directGameLoad(slot); } - // Check that the game files and the audio tracks aren't together run from - // the same cd - checkCD(); - // Game timer counter uint16 tmr = 0; - // Initialize the CD - int cd_num = ConfMan.getInt("cdrom"); - if (cd_num >= 0) - _system->getAudioCDManager()->openCD(cd_num); + // Check that the game files and the audio tracks aren't together run from + // the same cd + if (getPlatform() != Common::kPlatformIOS) { + checkCD(); + + // Initialize the CD + int cd_num = ConfMan.getInt("cdrom"); + if (cd_num >= 0) + _system->getAudioCDManager()->openCD(cd_num); + } while (!shouldQuit()) { // Give the debugger a chance to act diff --git a/engines/groovie/groovie.h b/engines/groovie/groovie.h index f8fad8d91f..bd376db0d2 100644 --- a/engines/groovie/groovie.h +++ b/engines/groovie/groovie.h @@ -75,6 +75,12 @@ enum DebugLevels { // the current limitation is 32 debug levels (1 << 31 is the last one) }; +enum GameSpeed { + kGroovieSpeedNormal, + kGroovieSpeediOS, + kGroovieSpeedTweaked +}; + struct GroovieGameDescription; class GroovieEngine : public Engine { @@ -113,6 +119,8 @@ public: Common::MacResManager *_macResFork; + GameSpeed _modeSpeed; + private: const GroovieGameDescription *_gameDescription; Debugger *_debugger; diff --git a/engines/groovie/music.cpp b/engines/groovie/music.cpp index 45f9800211..24306c8bfd 100644 --- a/engines/groovie/music.cpp +++ b/engines/groovie/music.cpp @@ -31,7 +31,10 @@ #include "common/config-manager.h" #include "common/macresman.h" #include "common/memstream.h" +#include "audio/audiostream.h" #include "audio/midiparser.h" +#include "audio/decoders/mp3.h" +#include "audio/decoders/quicktime.h" namespace Groovie { @@ -92,6 +95,7 @@ void MusicPlayer::playCD(uint8 track) { } else if ((track == 98) && (_prevCDtrack == 3)) { // Track 98 is used as a hack to stop the credits song g_system->getAudioCDManager()->stop(); + stopCreditsIOS(); return; } @@ -124,6 +128,8 @@ void MusicPlayer::playCD(uint8 track) { playSong((19 << 10) | 36); // XMI.GJD, file 36 } else if (track == 3) { // TODO: Credits MIDI fallback + if (_vm->getPlatform() == Common::kPlatformIOS) + playCreditsIOS(); } } } @@ -224,6 +230,22 @@ void MusicPlayer::unload() { _isPlaying = false; } +void MusicPlayer::playCreditsIOS() { +#ifdef USE_MAD + Common::File *f = new Common::File(); + f->open("7th_Guest_Dolls_from_Hell_OC_ReMix.mp3"); + Audio::AudioStream *stream = Audio::makeMP3Stream(f, DisposeAfterUse::YES); + _vm->_system->getMixer()->playStream(Audio::Mixer::kMusicSoundType, &_handleCreditsIOS, stream); +#else + warning("MAD library required for credits music"); +#endif +} + +void MusicPlayer::stopCreditsIOS() { +#ifdef USE_MAD + _vm->_system->getMixer()->stopHandle(_handleCreditsIOS); +#endif +} // MusicPlayerMidi @@ -747,4 +769,55 @@ Common::SeekableReadStream *MusicPlayerMac::decompressMidi(Common::SeekableReadS return new Common::MemoryReadStream(output, size, DisposeAfterUse::YES); } +MusicPlayerMPEG4::MusicPlayerMPEG4(GroovieEngine *vm) : MusicPlayer(vm) { +} + +void MusicPlayerMPEG4::updateVolume() { + // Just set the mixer volume for the music sound type + _vm->_system->getMixer()->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, _userVolume * _gameVolume / 100); +} + +void MusicPlayerMPEG4::unload() { + MusicPlayer::unload(); + + _vm->_system->getMixer()->stopHandle(_handle); +} + +bool MusicPlayerMPEG4::load(uint32 fileref, bool loop) { + // Find correct filename + ResInfo info; + _vm->_resMan->getResInfo(fileref, info); + uint len = info.filename.size(); + if (len < 4) + return false; // This shouldn't actually occur + + // iOS port provides alternative intro sequence music + if (info.filename == "gu39.xmi") { + info.filename = "intro.m4a"; + } else if (info.filename == "gu32.xmi") { + info.filename = "foyer.m4a"; + } else { + // RL still says xmi, but we're after external m4a + info.filename.setChar('m', len-3); + info.filename.setChar('4', len-2); + info.filename.setChar('a', len-1); + } + + // Create the audio stream + Audio::AudioStream *audStream = Audio::makeQuickTimeStream(info.filename); + + if (!audStream) { + warning("Could not play MPEG-4 sound '%s'", info.filename.c_str()); + return false; + } + + // Loop if requested + if (loop) + audStream = Audio::makeLoopingAudioStream((Audio::RewindableAudioStream *)audStream, 0); + + // Play! + _vm->_system->getMixer()->playStream(Audio::Mixer::kMusicSoundType, &_handle, audStream); + return true; +} + } // End of Groovie namespace diff --git a/engines/groovie/music.h b/engines/groovie/music.h index bde0a7a16f..cdf67cab44 100644 --- a/engines/groovie/music.h +++ b/engines/groovie/music.h @@ -29,6 +29,7 @@ #include "common/array.h" #include "common/mutex.h" #include "audio/mididrv.h" +#include "audio/mixer.h" class MidiParser; @@ -62,6 +63,11 @@ private: uint16 _backgroundDelay; + // T7G iOS credits mp3 stream + void playCreditsIOS(); + void stopCreditsIOS(); + Audio::SoundHandle _handleCreditsIOS; + // Volume fading uint32 _fadingStartTime; uint16 _fadingStartVolume; @@ -160,6 +166,19 @@ private: Common::SeekableReadStream *decompressMidi(Common::SeekableReadStream *stream); }; +class MusicPlayerMPEG4 : public MusicPlayer { +public: + MusicPlayerMPEG4(GroovieEngine *vm); + +protected: + void updateVolume(); + bool load(uint32 fileref, bool loop); + void unload(); + +private: + Audio::SoundHandle _handle; +}; + } // End of Groovie namespace #endif // GROOVIE_MUSIC_H diff --git a/engines/groovie/player.cpp b/engines/groovie/player.cpp index 8badd90012..92590d420c 100644 --- a/engines/groovie/player.cpp +++ b/engines/groovie/player.cpp @@ -29,18 +29,19 @@ namespace Groovie { VideoPlayer::VideoPlayer(GroovieEngine *vm) : - _vm(vm), _syst(vm->_system), _file(NULL), _audioStream(NULL) { + _vm(vm), _syst(vm->_system), _file(NULL), _audioStream(NULL), _fps(0), _overrideSpeed(false) { } bool VideoPlayer::load(Common::SeekableReadStream *file, uint16 flags) { _file = file; _flags = flags; + _overrideSpeed = false; _audioStream = NULL; - uint16 fps = loadInternal(); + _fps = loadInternal(); - if (fps != 0) { - _millisBetweenFrames = 1000 / fps; + if (_fps != 0) { + setOverrideSpeed(_overrideSpeed); _begunPlaying = false; return true; } else { @@ -49,6 +50,16 @@ bool VideoPlayer::load(Common::SeekableReadStream *file, uint16 flags) { } } +void VideoPlayer::setOverrideSpeed(bool isOverride) { + _overrideSpeed = isOverride; + if (_fps != 0) { + if (isOverride) + _millisBetweenFrames = 1000 / 26; + else + _millisBetweenFrames = 1000 / _fps; + } +} + bool VideoPlayer::playFrame() { bool end = true; diff --git a/engines/groovie/player.h b/engines/groovie/player.h index c9f47b8100..e75a5fc3c0 100644 --- a/engines/groovie/player.h +++ b/engines/groovie/player.h @@ -48,15 +48,21 @@ protected: virtual uint16 loadInternal() = 0; virtual bool playFrameInternal() = 0; + void setOverrideSpeed(bool isOverride); + bool getOverrideSpeed() const { return _overrideSpeed; } + GroovieEngine *_vm; OSystem *_syst; Common::SeekableReadStream *_file; uint16 _flags; Audio::QueuingAudioStream *_audioStream; - + + private: // Synchronization stuff bool _begunPlaying; + bool _overrideSpeed; + uint16 _fps; uint16 _millisBetweenFrames; uint32 _lastFrameTime; diff --git a/engines/groovie/resource.cpp b/engines/groovie/resource.cpp index 5d4ccf7d91..2cb571b4cc 100644 --- a/engines/groovie/resource.cpp +++ b/engines/groovie/resource.cpp @@ -173,6 +173,7 @@ bool ResMan_t7g::getResInfo(uint32 fileRef, ResInfo &resInfo) { char resname[12]; rlFile->read(resname, 12); debugC(2, kGroovieDebugResource | kGroovieDebugAll, "Groovie::Resource: Resource name: %12s", resname); + resInfo.filename = resname; // Read the resource information resInfo.offset = rlFile->readUint32LE(); @@ -247,6 +248,7 @@ bool ResMan_v2::getResInfo(uint32 fileRef, ResInfo &resInfo) { char resname[12]; rlFile.read(resname, 12); debugC(2, kGroovieDebugResource | kGroovieDebugAll, "Groovie::Resource: Resource name: %12s", resname); + resInfo.filename = resname; // 6 padding bytes? (it looks like they're always 0) diff --git a/engines/groovie/resource.h b/engines/groovie/resource.h index ca2ea177cb..c87658999a 100644 --- a/engines/groovie/resource.h +++ b/engines/groovie/resource.h @@ -36,6 +36,7 @@ struct ResInfo { uint16 gjd; uint32 offset; uint32 size; + Common::String filename; }; class ResMan { @@ -44,10 +45,10 @@ public: Common::SeekableReadStream *open(uint32 fileRef); virtual uint16 getRef(Common::String name, Common::String scriptname = "") = 0; + virtual bool getResInfo(uint32 fileRef, ResInfo &resInfo) = 0; protected: Common::Array<Common::String> _gjds; - virtual bool getResInfo(uint32 fileRef, ResInfo &resInfo) = 0; uint16 _lastGjd; }; diff --git a/engines/groovie/script.cpp b/engines/groovie/script.cpp index 4abfff74f2..782391dd78 100644 --- a/engines/groovie/script.cpp +++ b/engines/groovie/script.cpp @@ -65,7 +65,7 @@ static void debugScript(int level, bool nl, const char *s, ...) { Script::Script(GroovieEngine *vm, EngineVersion version) : _code(NULL), _savedCode(NULL), _stacktop(0), _debugger(NULL), _vm(vm), - _videoFile(NULL), _videoRef(0), _staufsMove(NULL) { + _videoFile(NULL), _videoRef(0), _staufsMove(NULL), _lastCursor(0xff) { // Initialize the opcode set depending on the engine version switch (version) { case kGroovieT7G: @@ -387,6 +387,7 @@ bool Script::hotspot(Common::Rect rect, uint16 address, uint8 cursor) { // If clicked with the mouse, jump to the specified address if (_mouseClicked) { + _lastCursor = cursor; _inputAction = address; } } @@ -579,11 +580,14 @@ bool Script::playvideofromref(uint32 fileref) { if (_videoFile) { _videoRef = fileref; + if (_lastCursor == 7) + _bitflags |= (1 << 15); _vm->_videoPlayer->load(_videoFile, _bitflags); } else { error("Couldn't open file"); return true; } + _lastCursor = 0xff; _bitflags = 0; diff --git a/engines/groovie/script.h b/engines/groovie/script.h index cda87a8917..2360d45744 100644 --- a/engines/groovie/script.h +++ b/engines/groovie/script.h @@ -75,6 +75,7 @@ private: Common::RandomSource _random; bool _firstbit; + uint8 _lastCursor; // Script filename (for debugging purposes) Common::String _scriptFile; diff --git a/engines/groovie/vdx.cpp b/engines/groovie/vdx.cpp index 1b4a2b7800..61e5e3f6d7 100644 --- a/engines/groovie/vdx.cpp +++ b/engines/groovie/vdx.cpp @@ -86,6 +86,11 @@ uint16 VDXPlayer::loadInternal() { _flagEight = ((_flags & (1 << 8)) != 0); _flagNine = ((_flags & (1 << 9)) != 0); + // Enable highspeed if we're not obeying fps, and not marked as special + // This will be disabled in chunk audio if we're actually an audio vdx + if ( _vm->_modeSpeed == kGroovieSpeediOS || (_vm->_modeSpeed == kGroovieSpeedTweaked && ((_flags & (1 << 15)) == 0))) + setOverrideSpeed(true); + if (_flagOnePrev && !_flagOne && !_flagEight) { _flagSeven = true; } @@ -522,6 +527,9 @@ void VDXPlayer::decodeBlockDelta(uint32 offset, byte *colours, uint16 imageWidth } void VDXPlayer::chunkSound(Common::ReadStream *in) { + if (getOverrideSpeed()) + setOverrideSpeed(false); + if (!_audioStream) { _audioStream = Audio::makeQueuingAudioStream(22050, false); Audio::SoundHandle sound_handle; |