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.cpp103
-rw-r--r--engines/groovie/music.h20
-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.h4
-rw-r--r--engines/groovie/script.cpp10
-rw-r--r--engines/groovie/script.h3
-rw-r--r--engines/groovie/vdx.cpp8
12 files changed, 222 insertions, 18 deletions
diff --git a/engines/groovie/detection.cpp b/engines/groovie/detection.cpp
index 78ecac8dbb..87ad534c96 100644
--- a/engines/groovie/detection.cpp
+++ b/engines/groovie/detection.cpp
@@ -111,6 +111,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 508049e1a0..9027262a0c 100644
--- a/engines/groovie/groovie.cpp
+++ b/engines/groovie/groovie.cpp
@@ -54,6 +54,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");
@@ -141,10 +150,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();
@@ -207,17 +226,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 0ac9c4b956..eb64cfc60a 100644
--- a/engines/groovie/groovie.h
+++ b/engines/groovie/groovie.h
@@ -72,6 +72,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 {
@@ -110,6 +116,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 b8a78d9f56..26b3458037 100644
--- a/engines/groovie/music.cpp
+++ b/engines/groovie/music.cpp
@@ -31,6 +31,7 @@
#include "common/macresman.h"
#include "common/memstream.h"
#include "common/textconsole.h"
+#include "audio/audiostream.h"
#include "audio/midiparser.h"
namespace Groovie {
@@ -92,6 +93,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 +126,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 +228,20 @@ void MusicPlayer::unload() {
_isPlaying = false;
}
+void MusicPlayer::playCreditsIOS() {
+ Audio::AudioStream *stream = Audio::SeekableAudioStream::openStreamFile("7th_Guest_Dolls_from_Hell_OC_ReMix");
+
+ if (!stream) {
+ warning("Could not find '7th_Guest_Dolls_from_Hell_OC_ReMix' audio file");
+ return;
+ }
+
+ _vm->_system->getMixer()->playStream(Audio::Mixer::kMusicSoundType, &_handleCreditsIOS, stream);
+}
+
+void MusicPlayer::stopCreditsIOS() {
+ _vm->_system->getMixer()->stopHandle(_handleCreditsIOS);
+}
// MusicPlayerMidi
@@ -747,4 +765,89 @@ Common::SeekableReadStream *MusicPlayerMac::decompressMidi(Common::SeekableReadS
return new Common::MemoryReadStream(output, size, DisposeAfterUse::YES);
}
+MusicPlayerMPEG4::MusicPlayerMPEG4(GroovieEngine *vm) : MusicPlayer(vm) {
+ vm->getTimerManager()->installTimerProc(&onTimer, 50 * 1000, this);
+}
+
+MusicPlayerMPEG4::~MusicPlayerMPEG4() {
+ _vm->getTimerManager()->removeTimerProc(&onTimer);
+}
+
+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
+ /*
+ 19462 door
+ 19463 ??
+ 19464 ??
+ 19465 puzzle?
+ 19466 cake
+ 19467 maze
+ 19468 ambient (but not 69, amb b. odd)
+ 19470 puzzle
+ 19471
+ 19473
+ 19475 coffins or blood pump
+ 19476 blood pump or coffins
+ 19493
+ 19499 chapel
+ 19509 downstair ambient
+ 19510 bedroom 'skip 3 and 5' puzzle (should loop from partway?)
+ 19514
+ 19515 bathroom drain teeth
+ */
+ if ((fileref >= 19462 && fileref <= 19468) ||
+ fileref == 19470 || fileref == 19471 ||
+ fileref == 19473 || fileref == 19475 ||
+ fileref == 19476 || fileref == 19493 ||
+ fileref == 19499 || fileref == 19509 ||
+ fileref == 19510 || fileref == 19514 ||
+ fileref == 19515)
+ loop = true; // XMIs for these refs self-loop
+
+ // iOS port provides alternative intro sequence music
+ if (info.filename == "gu39.xmi") {
+ info.filename = "intro";
+ } else if (info.filename == "gu32.xmi") {
+ info.filename = "foyer";
+ } else {
+ // Remove the extension
+ info.filename.deleteLastChar();
+ info.filename.deleteLastChar();
+ info.filename.deleteLastChar();
+ info.filename.deleteLastChar();
+ }
+
+ // Create the audio stream
+ Audio::AudioStream *audStream = Audio::SeekableAudioStream::openStreamFile(info.filename);
+
+ if (!audStream) {
+ warning("Could not play audio file '%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 fa4150a83b..5ef6a8e076 100644
--- a/engines/groovie/music.h
+++ b/engines/groovie/music.h
@@ -26,6 +26,7 @@
#include "common/array.h"
#include "common/mutex.h"
#include "audio/mididrv.h"
+#include "audio/mixer.h"
class MidiParser;
@@ -59,6 +60,11 @@ private:
uint16 _backgroundDelay;
+ // T7G iOS credits mp3 stream
+ void playCreditsIOS();
+ void stopCreditsIOS();
+ Audio::SoundHandle _handleCreditsIOS;
+
// Volume fading
uint32 _fadingStartTime;
uint16 _fadingStartVolume;
@@ -157,6 +163,20 @@ private:
Common::SeekableReadStream *decompressMidi(Common::SeekableReadStream *stream);
};
+class MusicPlayerMPEG4 : public MusicPlayer {
+public:
+ MusicPlayerMPEG4(GroovieEngine *vm);
+ ~MusicPlayerMPEG4();
+
+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 11318d2e94..e2a1ff3d56 100644
--- a/engines/groovie/player.cpp
+++ b/engines/groovie/player.cpp
@@ -28,18 +28,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 {
@@ -48,6 +49,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 c6d927f2c0..d8135a99b2 100644
--- a/engines/groovie/player.h
+++ b/engines/groovie/player.h
@@ -45,15 +45,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 05359342f8..10cf24a589 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();
@@ -281,6 +282,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 2c215917cc..33e15e6b98 100644
--- a/engines/groovie/resource.h
+++ b/engines/groovie/resource.h
@@ -33,6 +33,7 @@ struct ResInfo {
uint16 gjd;
uint32 offset;
uint32 size;
+ Common::String filename;
};
class ResMan {
@@ -40,11 +41,12 @@ public:
virtual ~ResMan() {}
Common::SeekableReadStream *open(uint32 fileRef);
+
virtual uint32 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 3bd90a042e..b52a8723fc 100644
--- a/engines/groovie/script.cpp
+++ b/engines/groovie/script.cpp
@@ -65,8 +65,9 @@ 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),
- _random("GroovieScripts") {
+ _videoFile(NULL), _videoRef(0), _staufsMove(NULL), _lastCursor(0xff),
+ _version(version), _random("GroovieScripts") {
+
// Initialize the opcode set depending on the engine version
switch (version) {
case kGroovieT7G:
@@ -385,6 +386,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;
}
}
@@ -584,6 +586,10 @@ bool Script::playvideofromref(uint32 fileref) {
if (_videoFile) {
_videoRef = fileref;
+ // If teeth cursor, and in main script, mark video prefer low-speed
+ // filename check as sometimes teeth used for puzzle movements (bishops)
+ if (_version == kGroovieT7G && _lastCursor == 7 && _scriptFile == "script.grv")
+ _bitflags |= (1 << 15);
_vm->_videoPlayer->load(_videoFile, _bitflags);
} else {
error("Couldn't open file");
diff --git a/engines/groovie/script.h b/engines/groovie/script.h
index 95da96487e..8cd790af5e 100644
--- a/engines/groovie/script.h
+++ b/engines/groovie/script.h
@@ -72,6 +72,9 @@ private:
Common::RandomSource _random;
bool _firstbit;
+ uint8 _lastCursor;
+
+ EngineVersion _version;
// Script filename (for debugging purposes)
Common::String _scriptFile;
diff --git a/engines/groovie/vdx.cpp b/engines/groovie/vdx.cpp
index ae1e9eebb3..b3fcf462b2 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 *colors, uint16 imageWidth)
}
void VDXPlayer::chunkSound(Common::ReadStream *in) {
+ if (getOverrideSpeed())
+ setOverrideSpeed(false);
+
if (!_audioStream) {
_audioStream = Audio::makeQueuingAudioStream(22050, false);
Audio::SoundHandle sound_handle;