aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/groovie/detection.cpp14
-rw-r--r--engines/groovie/groovie.cpp41
-rw-r--r--engines/groovie/groovie.h8
-rw-r--r--engines/groovie/music.cpp73
-rw-r--r--engines/groovie/music.h19
-rw-r--r--engines/groovie/player.cpp19
-rw-r--r--engines/groovie/player.h8
-rw-r--r--engines/groovie/resource.cpp2
-rw-r--r--engines/groovie/resource.h3
-rw-r--r--engines/groovie/script.cpp6
-rw-r--r--engines/groovie/script.h1
-rw-r--r--engines/groovie/vdx.cpp8
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;