aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--base/gameDetector.cpp10
-rw-r--r--doc/05_01.tex5
-rw-r--r--doc/07_03.tex30
-rw-r--r--doc/08.tex6
-rw-r--r--gui/launcher.cpp31
-rw-r--r--gui/options.cpp87
-rw-r--r--gui/options.h10
-rw-r--r--scumm/imuse.cpp165
-rw-r--r--scumm/imuse.h1
-rw-r--r--scumm/imuse_internal.h3
-rw-r--r--scumm/scumm.cpp5
-rw-r--r--scumm/scumm.h1
-rw-r--r--sound/mididrv.h2
13 files changed, 320 insertions, 36 deletions
diff --git a/base/gameDetector.cpp b/base/gameDetector.cpp
index bd0920a9ab..c7fb0aceb8 100644
--- a/base/gameDetector.cpp
+++ b/base/gameDetector.cpp
@@ -92,10 +92,11 @@ static const char USAGE_STRING[] =
" --platform=WORD Specify version of game (allowed values: amiga,\n"
" atari, fmtowns, nes, mac, pc, windows)\n"
" --savepath=PATH Path to where savegames are stored\n"
- " --soundfont=FILE Select the SoundFont for MIDI playback. (Only\n"
- " supported by some MIDI drivers.)\n"
+ " --soundfont=FILE Select the SoundFont for MIDI playback (Only\n"
+ " supported by some MIDI drivers)\n"
" --multi-midi Enable combination Adlib and native MIDI\n"
" --native-mt32 True Roland MT-32 (disable GM emulation)\n"
+ " --enable-gs Enable Roland GS mode for MIDI playback\n"
" --output-rate=RATE Select output sample rate in Hz (e.g. 22050)\n"
" --aspect-ratio Enable aspect ratio correction\n"
" --render-mode=MODE Enable additional render modes (cga, ega, hercGreen,\n"
@@ -136,6 +137,7 @@ GameDetector::GameDetector() {
ConfMan.registerDefault("multi_midi", false);
ConfMan.registerDefault("native_mt32", false);
+ ConfMan.registerDefault("enable_gs", false);
// ConfMan.registerDefault("music_driver", ???);
ConfMan.registerDefault("cdrom", 0);
@@ -486,6 +488,10 @@ void GameDetector::parseCommandLine(int argc, char **argv) {
ConfMan.set("native_mt32", cmdValue, kTransientDomain);
END_OPTION
+ DO_LONG_OPTION_BOOL("enable-gs")
+ ConfMan.set("enable_gs", cmdValue, kTransientDomain);
+ END_OPTION
+
DO_LONG_OPTION_BOOL("aspect-ratio")
ConfMan.set("aspect_ratio", cmdValue, kTransientDomain);
END_OPTION
diff --git a/doc/05_01.tex b/doc/05_01.tex
index 2afc462e53..ebd671b7a6 100644
--- a/doc/05_01.tex
+++ b/doc/05_01.tex
@@ -36,9 +36,10 @@ Usage: scummvm [OPTIONS]... [GAME]\\
&atari, fmtowns, mac, pc, windows)\\
--savepath=PATH &Path to where savegames are stored\\
--multi-midi &Enable combination of Adlib and native MIDI\\
- --soundfont &Select the SoundFont for MIDI playback. (Only\\
- &supported by some MIDI drivers.)\\
+ --soundfont &Select the SoundFont for MIDI playback (Only\\
+ &supported by some MIDI drivers)\\
--native-mt32 &True Roland MT-32 (disable GM emulation)\\
+ --enable-gs &Enable Roland GS mode for MIDI playback\\
--output-rate=RATE &Select output sample rate in Hz (e.g. 22050)\\
--aspect-ratio &Enable aspect ratio correction\\
--render-mode=MODE &Enable additional render modes (cga, ega, hercGreen, hercAmber, amiga)\\
diff --git a/doc/07_03.tex b/doc/07_03.tex
index 347a2bd427..bd754bf9ee 100644
--- a/doc/07_03.tex
+++ b/doc/07_03.tex
@@ -9,3 +9,33 @@
Use the appropriate -e<mode> command line option from the list above to
select your preferred MIDI device. For example, if you wish to use the
Windows MIDI driver, use the -ewindows option.
+
+\subsubsection{Using MIDI options to customize Native MIDI output}
+ScummVM supports a variety of MIDI modes, depending on the capabilities
+of your MIDI device.
+
+If --native-mt32 is specified, ScummVM will treat your device as a real
+MT-32. Because the instrument mappings and system exclusive commands of
+the MT-32 vary from those of General MIDI devices, you should only
+enable this option if you are using an actual Roland MT-32, LAPC-I, CM-64,
+CM-32L, CM-500, or GS device with an MT-32 map.
+
+If --enable-gs is specified, ScummVM will initialize your GS-compatible
+device with settings that mimic the MT-32's reverb, (lack of) chorus,
+pitch bend sensitivity, etc. If it is specified in conjunction with
+--native-mt32, ScummVM will select the MT-32-compatible map and drumset on
+your GS device. This setting works better than default GM or GS emulation
+with games that do not have custom instrument mappings (Loom and Monkey1).
+You should only specify both settings if you are using a GS device that
+has an MT-32 map, such as an SC-55, SC-88, SC-88 Pro, SC-8820, SC-8850, etc.
+Please note that --enable-gs is automatically disabled in both DOTT and
+Samnmax, since they use General MIDI natively.
+
+If neither of the above settings is enabled, ScummVM will initialize your
+device in General MIDI mode and use GM emulation in games with MT-32
+soundtracks.
+
+Some games contain sound effects that are exclusive to the Adlib soundtrack.
+For these games, you may wish to specify --multi-midi in order to combine
+MIDI music with Adlib sound effects.
+
diff --git a/doc/08.tex b/doc/08.tex
index 56e829415d..84cdf3285f 100644
--- a/doc/08.tex
+++ b/doc/08.tex
@@ -102,11 +102,15 @@ The following keywords are recognized:
& supported by some MIDI drivers.)\\
native\_mt32 &bool If true, disable GM emulation and assume that\\
& there is a true Roland MT-32 available.\\
+ enable\_gs &bool If true, enable Roland GS-specific features to\\
+ & enhance GM emulation. If native\_mt32 is also\\
+ & true, the GS device will select an MT-32 map\\
+ & to play the correct instruments.\\
sfx\_volume &number The sfx volume setting (0-255)\\
tempo &number The music tempo (50-200) (default: 100)\\
speech\_volume &number The speech volume setting (0-255)\\
\\
- copy\_protection&bool Enable copy protection in SCUMM games ,when\\
+ copy\_protection&bool Enable copy protection in SCUMM games, when\\
& ScummVM disables it by default.\\
demo\_mode &bool Start demo in Maniac Mansion\\
alt\_intro &bool Use alternative intro for CD versions of \\
diff --git a/gui/launcher.cpp b/gui/launcher.cpp
index e9b784ef45..67b562dfd8 100644
--- a/gui/launcher.cpp
+++ b/gui/launcher.cpp
@@ -61,6 +61,7 @@ enum {
kCmdGlobalGraphicsOverride = 'OGFX',
kCmdGlobalAudioOverride = 'OSFX',
+ kCmdGlobalMIDIOverride = 'OMID',
kCmdGlobalVolumeOverride = 'OVOL',
kCmdExtraBrowser = 'PEXT',
@@ -128,6 +129,7 @@ protected:
CheckboxWidget *_globalGraphicsOverride;
CheckboxWidget *_globalAudioOverride;
+ CheckboxWidget *_globalMIDIOverride;
CheckboxWidget *_globalVolumeOverride;
};
@@ -215,7 +217,7 @@ EditGameDialog::EditGameDialog(const String &domain, GameSettings target)
yoffset += 18;
//
- // 2) The graphics tab
+ // 3) The graphics tab
//
tab->addTab("Gfx");
yoffset = vBorder;
@@ -226,7 +228,7 @@ EditGameDialog::EditGameDialog(const String &domain, GameSettings target)
yoffset = addGraphicControls(tab, yoffset);
//
- // 3) The audio tab
+ // 4) The audio tab
//
tab->addTab("Audio");
yoffset = vBorder;
@@ -234,10 +236,21 @@ EditGameDialog::EditGameDialog(const String &domain, GameSettings target)
_globalAudioOverride = new CheckboxWidget(tab, x, yoffset, w, 16, "Override global audio settings", kCmdGlobalAudioOverride);
yoffset += 16;
+ yoffset = addAudioControls(tab, yoffset);
+
+ //
+ // 5) The MIDI tab
+ //
+ tab->addTab("MIDI");
+ yoffset = vBorder;
+
+ _globalMIDIOverride = new CheckboxWidget(tab, x, yoffset, w, 16, "Override global MIDI settings", kCmdGlobalMIDIOverride);
+ yoffset += 16;
+
yoffset = addMIDIControls(tab, yoffset);
//
- // 3) The volume tab
+ // 6) The volume tab
//
tab->addTab("Volume");
yoffset = vBorder;
@@ -269,10 +282,14 @@ void EditGameDialog::open() {
_globalGraphicsOverride->setState(e);
e = ConfMan.hasKey("music_driver", _domain) ||
- ConfMan.hasKey("multi_midi", _domain) ||
- ConfMan.hasKey("native_mt32", _domain);
+ ConfMan.hasKey("subtitles", _domain);
_globalAudioOverride->setState(e);
+ e = ConfMan.hasKey("multi_midi", _domain) ||
+ ConfMan.hasKey("native_mt32", _domain)||
+ ConfMan.hasKey("enable_gs", _domain);
+ _globalMIDIOverride->setState(e);
+
e = ConfMan.hasKey("music_volume", _domain) ||
ConfMan.hasKey("sfx_volume", _domain) ||
ConfMan.hasKey("speech_volume", _domain);
@@ -342,6 +359,10 @@ void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
setAudioSettingsState(data != 0);
draw();
break;
+ case kCmdGlobalMIDIOverride:
+ setMIDISettingsState(data != 0);
+ draw();
+ break;
case kCmdGlobalVolumeOverride:
setVolumeSettingsState(data != 0);
draw();
diff --git a/gui/options.cpp b/gui/options.cpp
index 040fafc9d0..1544730c89 100644
--- a/gui/options.cpp
+++ b/gui/options.cpp
@@ -78,7 +78,9 @@ OptionsDialog::OptionsDialog(const String &domain, int x, int y, int w, int h)
_enableGraphicSettings(false),
_gfxPopUp(0), _renderModePopUp(0), _fullscreenCheckbox(0), _aspectCheckbox(0),
_enableAudioSettings(false),
- _multiMidiCheckbox(0), _mt32Checkbox(0), _subCheckbox(0),
+ _subCheckbox(0),
+ _enableMIDISettings(false),
+ _multiMidiCheckbox(0), _mt32Checkbox(0), _enableGSCheckbox(0),
_enableVolumeSettings(false),
_musicVolumeSlider(0), _musicVolumeLabel(0),
_sfxVolumeSlider(0), _sfxVolumeLabel(0),
@@ -131,7 +133,7 @@ void OptionsDialog::open() {
#endif
}
- if (_multiMidiCheckbox) {
+ if (_subCheckbox) {
// Music driver
const MidiDriverDescription *md = MidiDriver::getAvailableMidiDrivers();
int i = 0;
@@ -145,15 +147,22 @@ void OptionsDialog::open() {
}
_midiPopUp->setSelected(md->name ? i : 0);
+ // Subtitles setting
+ _subCheckbox->setState(ConfMan.getBool("subtitles", _domain));
+ }
+
+ if (_multiMidiCheckbox) {
+
// Multi midi setting
_multiMidiCheckbox->setState(ConfMan.getBool("multi_midi", _domain));
// Native mt32 setting
_mt32Checkbox->setState(ConfMan.getBool("native_mt32", _domain));
- // Subtitles setting
- _subCheckbox->setState(ConfMan.getBool("subtitles", _domain));
+ // GS extensions setting
+ _enableGSCheckbox->setState(ConfMan.getBool("enable_gs", _domain));
}
+
if (_musicVolumeSlider) {
int vol;
@@ -204,10 +213,8 @@ void OptionsDialog::close() {
}
}
- if (_multiMidiCheckbox) {
+ if (_subCheckbox) {
if (_enableAudioSettings) {
- ConfMan.set("multi_midi", _multiMidiCheckbox->getState(), _domain);
- ConfMan.set("native_mt32", _mt32Checkbox->getState(), _domain);
ConfMan.set("subtitles", _subCheckbox->getState(), _domain);
const MidiDriverDescription *md = MidiDriver::getAvailableMidiDrivers();
while (md->name && md->id != (int)_midiPopUp->getSelectedTag())
@@ -217,13 +224,23 @@ void OptionsDialog::close() {
else
ConfMan.removeKey("music_driver", _domain);
} else {
- ConfMan.removeKey("multi_midi", _domain);
- ConfMan.removeKey("native_mt32", _domain);
ConfMan.removeKey("music_driver", _domain);
ConfMan.removeKey("subtitles", _domain);
}
}
+ if (_multiMidiCheckbox) {
+ if (_enableMIDISettings) {
+ ConfMan.set("multi_midi", _multiMidiCheckbox->getState(), _domain);
+ ConfMan.set("native_mt32", _mt32Checkbox->getState(), _domain);
+ ConfMan.set("enable_gs", _enableGSCheckbox->getState(), _domain);
+ } else {
+ ConfMan.removeKey("multi_midi", _domain);
+ ConfMan.removeKey("native_mt32", _domain);
+ ConfMan.removeKey("enable_gs", _domain);
+ }
+ }
+
// Save config file
ConfMan.flushToDisk();
}
@@ -269,9 +286,15 @@ void OptionsDialog::setAudioSettingsState(bool enabled) {
_enableAudioSettings = enabled;
_midiPopUp->setEnabled(enabled);
+ _subCheckbox->setEnabled(enabled);
+}
+
+void OptionsDialog::setMIDISettingsState(bool enabled) {
+ _enableMIDISettings = enabled;
+
_multiMidiCheckbox->setEnabled(enabled);
_mt32Checkbox->setEnabled(enabled);
- _subCheckbox->setEnabled(enabled);
+ _enableGSCheckbox->setEnabled(enabled);
}
void OptionsDialog::setVolumeSettingsState(bool enabled) {
@@ -330,13 +353,13 @@ int OptionsDialog::addGraphicControls(GuiObject *boss, int yoffset) {
return yoffset;
}
-int OptionsDialog::addMIDIControls(GuiObject *boss, int yoffset) {
+int OptionsDialog::addAudioControls(GuiObject *boss, int yoffset) {
const int x = 10;
const int w = _w - 20;
// The MIDI mode popup & a label
_midiPopUp = new PopUpWidget(boss, x-5, yoffset, w+5, kLineHeight, "Music driver: ", 100);
- yoffset += 16;
+ yoffset += 18;
// Populate it
const MidiDriverDescription *md = MidiDriver::getAvailableMidiDrivers();
@@ -345,25 +368,39 @@ int OptionsDialog::addMIDIControls(GuiObject *boss, int yoffset) {
md++;
}
+ // Subtitles on/off
+ _subCheckbox = new CheckboxWidget(boss, x, yoffset, w, 16, "Display subtitles");
+ yoffset += 16;
+
+ yoffset += 18;
+
+ _enableAudioSettings = true;
+
+ return yoffset;
+}
+
+int OptionsDialog::addMIDIControls(GuiObject *boss, int yoffset) {
+ const int x = 10;
+ const int w = _w - 20;
+
// SoundFont
new ButtonWidget(boss, x, yoffset, kButtonWidth + 14, 16, "SoundFont: ", kChooseSoundFontCmd, 0);
_soundFont = new StaticTextWidget(boss, x + kButtonWidth + 20, yoffset + 3, _w - (x + kButtonWidth + 20) - 10, kLineHeight, "None", kTextAlignLeft);
-
yoffset += 18;
-
+
// Multi midi setting
_multiMidiCheckbox = new CheckboxWidget(boss, x, yoffset, w, 16, "Mixed Adlib/MIDI mode");
- yoffset += 15;
+ yoffset += 16;
// Native mt32 setting
_mt32Checkbox = new CheckboxWidget(boss, x, yoffset, w, 16, "True Roland MT-32 (disable GM emulation)");
- yoffset += 15;
+ yoffset += 16;
- // Subtitles on/off
- _subCheckbox = new CheckboxWidget(boss, x, yoffset, w, 16, "Display subtitles");
- yoffset += 15;
+ // GS Extensions setting
+ _enableGSCheckbox = new CheckboxWidget(boss, x, yoffset, w, 16, "Enable Roland GS Mode");
+ yoffset += 16;
- _enableAudioSettings = true;
+ _enableMIDISettings = true;
return yoffset;
}
@@ -417,13 +454,19 @@ GlobalOptionsDialog::GlobalOptionsDialog(GameDetector &detector)
//
tab->addTab("Audio");
yoffset = vBorder;
- yoffset = addMIDIControls(tab, yoffset);
+ yoffset = addAudioControls(tab, yoffset);
yoffset = addVolumeControls(tab, yoffset);
// TODO: cd drive setting
+ //
+ // 3) The MIDI tab
+ //
+ tab->addTab("MIDI");
+ yoffset = vBorder;
+ yoffset = addMIDIControls(tab, yoffset);
//
- // 3) The miscellaneous tab
+ // 4) The miscellaneous tab
//
tab->addTab("Paths");
yoffset = vBorder;
diff --git a/gui/options.h b/gui/options.h
index 5797a62494..cbe6817be1 100644
--- a/gui/options.h
+++ b/gui/options.h
@@ -59,11 +59,13 @@ protected:
StaticTextWidget *_soundFont;
int addGraphicControls(GuiObject *boss, int yoffset);
+ int addAudioControls(GuiObject *boss, int yoffset);
int addMIDIControls(GuiObject *boss, int yoffset);
int addVolumeControls(GuiObject *boss, int yoffset);
void setGraphicSettingsState(bool enabled);
void setAudioSettingsState(bool enabled);
+ void setMIDISettingsState(bool enabled);
void setVolumeSettingsState(bool enabled);
private:
@@ -81,9 +83,15 @@ private:
//
bool _enableAudioSettings;
PopUpWidget *_midiPopUp;
+ CheckboxWidget *_subCheckbox;
+
+ //
+ // MIDI controls
+ //
+ bool _enableMIDISettings;
CheckboxWidget *_multiMidiCheckbox;
CheckboxWidget *_mt32Checkbox;
- CheckboxWidget *_subCheckbox;
+ CheckboxWidget *_enableGSCheckbox;
//
// Volume controls
diff --git a/scumm/imuse.cpp b/scumm/imuse.cpp
index 2f12865ff1..1777eb5247 100644
--- a/scumm/imuse.cpp
+++ b/scumm/imuse.cpp
@@ -46,6 +46,8 @@ namespace Scumm {
IMuseInternal::IMuseInternal() :
_native_mt32(false),
+_enable_gs(false),
+_sc55(false),
_midi_adlib(0),
_midi_native(0),
_base_sounds(0),
@@ -1071,11 +1073,24 @@ uint32 IMuseInternal::property(int prop, uint32 value) {
case IMuse::PROP_NATIVE_MT32:
_native_mt32 = (value > 0);
- Instrument::nativeMT32(value > 0);
- if (value > 0 && _midi_native)
+ Instrument::nativeMT32(_native_mt32);
+ if (_midi_native && _native_mt32)
initMT32(_midi_native);
break;
+ case IMuse::PROP_GS:
+ _enable_gs = (value > 0);
+
+ // If True Roland MT-32 is not selected, run in GM or GS mode.
+ // If it is selected, change the Roland GS synth to MT-32 mode.
+ if (_midi_native && !_native_mt32)
+ initGM(_midi_native);
+ else if (_midi_native && _native_mt32 && _enable_gs) {
+ _sc55 = true;
+ initGM(_midi_native);
+ }
+ break;
+
case IMuse::PROP_LIMIT_PLAYERS:
if (value > 0 && value <= ARRAYSIZE(_players))
_player_limit = (int) value;
@@ -1171,12 +1186,156 @@ void IMuseInternal::initMT32(MidiDriver *midi) {
midi->sysEx(buffer, 31);
g_system->delayMillis (250);
- // Setup rythm part
+ // Map percussion to notes 24 - 34 without reverb
memcpy(&buffer[4], "\x03\x01\x10\x40\x64\x07\x00\x4a\x64\x06\x00\x41\x64\x07\x00\x4b\x64\x08\x00\x45\x64\x06\x00\x44\x64\x0b\x00\x51\x64\x05\x00\x43\x64\x08\x00\x50\x64\x07\x00\x42\x64\x03\x00\x4c\x64\x07\x00\x44", 48);
midi->sysEx(buffer, 52);
g_system->delayMillis (250);
}
+void IMuseInternal::initGM(MidiDriver *midi) {
+ byte buffer[11];
+
+ // General MIDI System On message
+ // Resets all GM devices to default settings
+ memcpy(&buffer[0], "\xF0\x7E\x7F\x09\x01\xF7", 6);
+ midi->sysEx(buffer, 6);
+ debug(2, "GM SysEx: GM System On");
+ g_system->delayMillis (200);
+
+ if (_enable_gs) {
+
+ // All GS devices recognize the GS Reset command,
+ // even with Roland's ID. It is impractical to
+ // support other manufacturers' devices for
+ // further GS settings, as there are limitless
+ // numbers of them out there that would each
+ // require individual SysEx commands with unique IDs.
+
+ // Roland GS SysEx ID
+ memcpy(&buffer[0], "\xF0\x41\x10\x42\x12", 5);
+
+ // GS Reset
+ memcpy(&buffer[5], "\x40\x00\x7F\x00\x41\xF7", 6);
+ midi->sysEx(buffer, 11);
+ debug(2, "GS SysEx: GS Reset");
+ g_system->delayMillis (200);
+
+ if (_sc55) {
+
+ // This mode is for GS devices that support an MT-32-compatible
+ // Map, such as the Roland Sound Canvas line of modules. It
+ // will allow them to work with True MT-32 mode, but will
+ // obviously still ignore MT-32 SysEx (and thus custom
+ // instruments).
+
+ // Set Channels 1-16 to SC-55 Map, then CM-64/32L Variation
+ for (int i = 0; i < 16; ++i) {
+ midi->send(( 127 << 16) | (0 << 8) | (0xB0 | i));
+ midi->send(( 1 << 16) | (32 << 8) | (0xB0 | i));
+ midi->send(( 0 << 16) | (0 << 8) | (0xC0 | i));
+ }
+ debug(2, "GS Program Change: CM-64/32L Map Selected");
+
+ // Set Percussion Channel to SC-55 Map (CC#32, 01H), then
+ // Switch Drum Map to CM-64/32L (MT-32 Compatible Drums)
+ midi->getPercussionChannel()->controlChange(0, 0);
+ midi->getPercussionChannel()->controlChange(32, 1);
+ midi->send (127 << 8 | 0xC0 | 9);
+ debug(2, "GS Program Change: Drum Map is CM-64/32L");
+
+ }
+
+ // Set Master Chorus to 0. The MT-32 has no chorus capability.
+ memcpy(&buffer[5], "\x40\x01\x3A\x00\x05\xF7", 6);
+ midi->sysEx(buffer, 11);
+ debug(2, "GS SysEx: Master Chorus Level is 0");
+
+ // Set Channels 1-16 Reverb to 64, which is the
+ // equivalent of MT-32 default Reverb Level 5
+ for (int i = 0; i < 16; ++i)
+ midi->send(( 64 << 16) | (91 << 8) | (0xB0 | i));
+ debug(2, "GM Controller 91 Change: Channels 1-16 Reverb Level is 64");
+
+ // Set Channels 1-16 Pitch Bend Sensitivity to
+ // 12 semitones; then lock the RPN by setting null.
+ for (int i = 0; i < 16; ++i) {
+ midi->send(( 0 << 16) | (100 << 8) | (0xB0 | i));
+ midi->send(( 0 << 16) | (101 << 8) | (0xB0 | i));
+ midi->send(( 12 << 16) | (6 << 8) | (0xB0 | i));
+ midi->send(( 0 << 16) | (38 << 8) | (0xB0 | i));
+ midi->send(( 127 << 16) | (100 << 8) | (0xB0 | i));
+ midi->send(( 127 << 16) | (101 << 8) | (0xB0 | i));
+ }
+ debug(2, "GM Controller 6 Change: Channels 1-16 Pitch Bend Sensitivity is 12 semitones");
+
+ // Set channels 1-16 Mod. LFO1 Pitch Depth to 4
+ memcpy(&buffer[5], "\x40\x20\x04\x04\x18\xF7", 6);
+ midi->sysEx(buffer, 11);
+ memcpy(&buffer[5], "\x40\x21\x04\x04\x17\xF7", 6);
+ midi->sysEx(buffer, 11);
+ memcpy(&buffer[5], "\x40\x22\x04\x04\x16\xF7", 6);
+ midi->sysEx(buffer, 11);
+ memcpy(&buffer[5], "\x40\x23\x04\x04\x15\xF7", 6);
+ midi->sysEx(buffer, 11);
+ memcpy(&buffer[5], "\x40\x24\x04\x04\x14\xF7", 6);
+ midi->sysEx(buffer, 11);
+ memcpy(&buffer[5], "\x40\x25\x04\x04\x13\xF7", 6);
+ midi->sysEx(buffer, 11);
+ memcpy(&buffer[5], "\x40\x26\x04\x04\x12\xF7", 6);
+ midi->sysEx(buffer, 11);
+ memcpy(&buffer[5], "\x40\x27\x04\x04\x11\xF7", 6);
+ midi->sysEx(buffer, 11);
+ memcpy(&buffer[5], "\x40\x28\x04\x04\x10\xF7", 6);
+ midi->sysEx(buffer, 11);
+ memcpy(&buffer[5], "\x40\x29\x04\x04\x0F\xF7", 6);
+ midi->sysEx(buffer, 11);
+ memcpy(&buffer[5], "\x40\x2A\x04\x04\x0E\xF7", 6);
+ midi->sysEx(buffer, 11);
+ memcpy(&buffer[5], "\x40\x2B\x04\x04\x0D\xF7", 6);
+ midi->sysEx(buffer, 11);
+ memcpy(&buffer[5], "\x40\x2C\x04\x04\x0C\xF7", 6);
+ midi->sysEx(buffer, 11);
+ memcpy(&buffer[5], "\x40\x2D\x04\x04\x0B\xF7", 6);
+ midi->sysEx(buffer, 11);
+ memcpy(&buffer[5], "\x40\x2E\x04\x04\x0A\xF7", 6);
+ midi->sysEx(buffer, 11);
+ memcpy(&buffer[5], "\x40\x2F\x04\x04\x09\xF7", 6);
+ midi->sysEx(buffer, 11);
+ debug(2, "GS SysEx: Channels 1-16 Mod. LFO1 Pitch Depth Level is 4");
+
+ // Set Percussion Channel Expression to 80
+ midi->getPercussionChannel()->controlChange(11, 80);
+ debug(2, "GM Controller 11 Change: Percussion Channel Expression Level is 80");
+
+ // Turn off Percussion Channel Rx. Expression so that
+ // Expression cannot be modified. I don't know why, but
+ // Roland does it this way.
+ memcpy(&buffer[5], "\x40\x10\x0E\x00\x22\xF7", 6);
+ midi->sysEx(buffer, 11);
+ debug(2, "GS SysEx: Percussion Channel Rx. Expression is OFF");
+
+ // Change Reverb Character to 0. I don't think this
+ // sounds most like MT-32, but apparently Roland does.
+ memcpy(&buffer[5], "\x40\x01\x31\x00\x0E\xF7", 6);
+ midi->sysEx(buffer, 11);
+ debug(2, "GS SysEx: Reverb Character is 0");
+
+ // Change Reverb Pre-LF to 4, which is similar to
+ // what MT-32 reverb does.
+ memcpy(&buffer[5], "\x40\x01\x32\x04\x09\xF7", 6);
+ midi->sysEx(buffer, 11);
+ debug(2, "GS SysEx: Reverb Pre-LF is 4");
+
+ // Change Reverb Time to 106; the decay on Hall 2
+ // Reverb is too fast compared to the MT-32's
+ memcpy(&buffer[5], "\x40\x01\x34\x6A\x21\xF7", 6);
+ midi->sysEx(buffer, 11);
+ debug(2, "GS SysEx: Reverb Time is 106");
+
+ }
+
+}
+
void IMuseInternal::init_queue() {
_queue_adding = false;
_queue_pos = 0;
diff --git a/scumm/imuse.h b/scumm/imuse.h
index a9da34247b..cb78db7b5f 100644
--- a/scumm/imuse.h
+++ b/scumm/imuse.h
@@ -52,6 +52,7 @@ public:
enum {
PROP_TEMPO_BASE,
PROP_NATIVE_MT32,
+ PROP_GS,
PROP_LIMIT_PLAYERS,
PROP_RECYCLE_PLAYERS,
PROP_DIRECT_PASSTHROUGH
diff --git a/scumm/imuse_internal.h b/scumm/imuse_internal.h
index 04414ead08..a0e05db9fb 100644
--- a/scumm/imuse_internal.h
+++ b/scumm/imuse_internal.h
@@ -346,6 +346,8 @@ class IMuseInternal {
protected:
bool _native_mt32;
+ bool _enable_gs;
+ bool _sc55;
MidiDriver *_midi_adlib;
MidiDriver *_midi_native;
@@ -392,6 +394,7 @@ protected:
void handle_marker(uint id, byte data);
int get_channel_volume(uint a);
void initMidiDriver(MidiDriver *midi);
+ void initGM(MidiDriver *midi);
void initMT32(MidiDriver *midi);
void init_players();
void init_parts();
diff --git a/scumm/scumm.cpp b/scumm/scumm.cpp
index 98d968a8c7..bacc0a1020 100644
--- a/scumm/scumm.cpp
+++ b/scumm/scumm.cpp
@@ -1672,6 +1672,10 @@ void ScummEngine_v99he::scummInit() {
void ScummEngine::setupMusic(int midi) {
_midiDriver = MidiDriver::detectMusicDriver(midi);
_native_mt32 = (ConfMan.getBool("native_mt32") || (_midiDriver == MD_MT32));
+ if ((_gameId == GID_TENTACLE) || (_gameId == GID_SAMNMAX))
+ _enable_gs = false;
+ else
+ _enable_gs = ConfMan.getBool("enable_gs");
#ifndef __GP32__ //ph0x FIXME, "quick dirty hack"
/* Bind the mixer to the system => mixer will be invoked
@@ -1720,6 +1724,7 @@ void ScummEngine::setupMusic(int midi) {
if (ConfMan.hasKey("tempo"))
_imuse->property(IMuse::PROP_TEMPO_BASE, ConfMan.getInt("tempo"));
_imuse->property(IMuse::PROP_NATIVE_MT32, _native_mt32);
+ _imuse->property(IMuse::PROP_GS, _enable_gs);
if (_features & GF_HUMONGOUS || midi == MDT_TOWNS) {
_imuse->property(IMuse::PROP_LIMIT_PLAYERS, 1);
_imuse->property(IMuse::PROP_RECYCLE_PLAYERS, 1);
diff --git a/scumm/scumm.h b/scumm/scumm.h
index b8e2ed8e11..fd80ab2118 100644
--- a/scumm/scumm.h
+++ b/scumm/scumm.h
@@ -1111,6 +1111,7 @@ protected:
int _tempMusic;
int _saveSound;
bool _native_mt32;
+ bool _enable_gs;
int _midi;
int _midiDriver; // Use the MD_ values from mididrv.h
bool _copyProtection;
diff --git a/sound/mididrv.h b/sound/mididrv.h
index 3f9db6a664..af538d096a 100644
--- a/sound/mididrv.h
+++ b/sound/mididrv.h
@@ -137,6 +137,8 @@ public:
send(( 0 << 16) | (100 << 8) | (0xB0 | channel));
send((range << 16) | ( 6 << 8) | (0xB0 | channel));
send(( 0 << 16) | ( 38 << 8) | (0xB0 | channel));
+ send(( 127 << 16) | (101 << 8) | (0xB0 | channel));
+ send(( 127 << 16) | (100 << 8) | (0xB0 | channel));
}
virtual void sysEx (byte *msg, uint16 length) { }