[Scummvm-git-logs] scummvm master -> bcdd54ee8d34bdecd4e8189d0eca6795f23dc78c
NMIError
noreply at scummvm.org
Sun Oct 27 20:34:15 UTC 2024
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
bcdd54ee8d DARKSEED: Add CD version music player
Commit: bcdd54ee8d34bdecd4e8189d0eca6795f23dc78c
https://github.com/scummvm/scummvm/commit/bcdd54ee8d34bdecd4e8189d0eca6795f23dc78c
Author: Coen Rampen (crampen at gmail.com)
Date: 2024-10-27T21:34:06+01:00
Commit Message:
DARKSEED: Add CD version music player
Changed paths:
A engines/darkseed/adlib_worx.cpp
A engines/darkseed/adlib_worx.h
A engines/darkseed/music.cpp
A engines/darkseed/music.h
audio/adlib_ms.cpp
audio/adlib_ms.h
engines/darkseed/cutscene.cpp
engines/darkseed/darkseed.cpp
engines/darkseed/darkseed.h
engines/darkseed/module.mk
engines/darkseed/sound.cpp
engines/darkseed/sound.h
diff --git a/audio/adlib_ms.cpp b/audio/adlib_ms.cpp
index e2284c15047..8ecec4052cc 100644
--- a/audio/adlib_ms.cpp
+++ b/audio/adlib_ms.cpp
@@ -93,6 +93,50 @@ void AdLibBnkInstrumentDefinition::toOplInstrumentDefinition(OplInstrumentDefini
instrumentDef.rhythmType = RHYTHM_TYPE_UNDEFINED;
}
+void AdLibIbkInstrumentDefinition::toOplInstrumentDefinition(OplInstrumentDefinition &instrumentDef) {
+ instrumentDef.fourOperator = false;
+
+ instrumentDef.operator0.freqMultMisc = o0FreqMultMisc;
+ instrumentDef.operator0.level = o0Level;
+ instrumentDef.operator0.decayAttack = o0DecayAttack;
+ instrumentDef.operator0.releaseSustain = o0ReleaseSustain;
+ instrumentDef.operator0.waveformSelect = o0WaveformSelect;
+
+ instrumentDef.operator1.freqMultMisc = o1FreqMultMisc;
+ instrumentDef.operator1.level = o1Level;
+ instrumentDef.operator1.decayAttack = o1DecayAttack;
+ instrumentDef.operator1.releaseSustain = o1ReleaseSustain;
+ instrumentDef.operator1.waveformSelect = o1WaveformSelect;
+
+ instrumentDef.connectionFeedback0 = connectionFeedback;
+
+ instrumentDef.rhythmNote = rhythmNote;
+ OplInstrumentRhythmType convRhythmType;
+ switch (rhythmType) {
+ case 6:
+ convRhythmType = RHYTHM_TYPE_BASS_DRUM;
+ break;
+ case 7:
+ convRhythmType = RHYTHM_TYPE_SNARE_DRUM;
+ break;
+ case 8:
+ convRhythmType = RHYTHM_TYPE_TOM_TOM;
+ break;
+ case 9:
+ convRhythmType = RHYTHM_TYPE_CYMBAL;
+ break;
+ case 10:
+ convRhythmType = RHYTHM_TYPE_HI_HAT;
+ break;
+ case 0:
+ default:
+ convRhythmType = RHYTHM_TYPE_UNDEFINED;
+ break;
+ }
+ instrumentDef.rhythmType = convRhythmType;
+ // TODO Add support for transpose
+}
+
// These are the melodic instrument definitions used by the Win95 SB16 driver.
OplInstrumentDefinition MidiDriver_ADLIB_Multisource::OPL_INSTRUMENT_BANK[128] = {
// 0x00
@@ -402,6 +446,7 @@ MidiDriver_ADLIB_Multisource::MidiDriver_ADLIB_Multisource(OPL::Config::OplType
_allocationMode(ALLOCATION_MODE_DYNAMIC),
_instrumentWriteMode(INSTRUMENT_WRITE_MODE_NOTE_ON),
_rhythmModeIgnoreNoteOffs(false),
+ _channel10Melodic(false),
_defaultChannelVolume(0),
_noteSelect(NOTE_SELECT_MODE_0),
_modulationDepth(MODULATION_DEPTH_HIGH),
@@ -1317,7 +1362,7 @@ void MidiDriver_ADLIB_Multisource::recalculateVolumes(uint8 channel, uint8 sourc
MidiDriver_ADLIB_Multisource::InstrumentInfo MidiDriver_ADLIB_Multisource::determineInstrument(uint8 channel, uint8 source, uint8 note) {
InstrumentInfo instrument = { 0, nullptr, 0 };
- if (channel == MIDI_RHYTHM_CHANNEL) {
+ if (!_channel10Melodic && channel == MIDI_RHYTHM_CHANNEL) {
// On the rhythm channel, the note played indicates which instrument
// should be used.
if (note < _rhythmBankFirstNote || note > _rhythmBankLastNote)
diff --git a/audio/adlib_ms.h b/audio/adlib_ms.h
index 3e9a8459ee4..115fe87b10b 100644
--- a/audio/adlib_ms.h
+++ b/audio/adlib_ms.h
@@ -212,6 +212,45 @@ struct AdLibBnkInstrumentDefinition {
void toOplInstrumentDefinition(OplInstrumentDefinition &instrumentDef);
} PACKED_STRUCT;
+/**
+ * Instrument definition for an OPL2 chip in the format used by the IBK
+ * instrument bank file format. This format is also used by the SBI and CMF
+ * file formats.
+ */
+struct AdLibIbkInstrumentDefinition {
+ uint8 o0FreqMultMisc;
+ uint8 o1FreqMultMisc;
+ uint8 o0Level;
+ uint8 o1Level;
+ uint8 o0DecayAttack;
+ uint8 o1DecayAttack;
+ uint8 o0ReleaseSustain;
+ uint8 o1ReleaseSustain;
+ uint8 o0WaveformSelect;
+ uint8 o1WaveformSelect;
+ uint8 connectionFeedback;
+ /**
+ * Rhythm note type. 0: melodic, 6: bass drum, 7: snare drum, 8: tom tom, 9: cymbal, 10: hi hat
+ */
+ uint8 rhythmType;
+ /**
+ * Number of semitones to transpose a note using this instrument.
+ */
+ int8 transpose;
+ uint8 rhythmNote;
+ uint8 padding1;
+ uint8 padding2;
+
+ /**
+ * Copies the data in this AdLib BNK instrument definition to the specified
+ * OplInstrumentDefinition struct.
+ *
+ * @param instrumentDef The instrument definition to which the data should
+ * be copied.
+ */
+ void toOplInstrumentDefinition(OplInstrumentDefinition &instrumentDef);
+} PACKED_STRUCT;
+
#include "common/pack-end.h" // END STRUCT PACKING
/**
@@ -1150,6 +1189,9 @@ protected:
InstrumentWriteMode _instrumentWriteMode;
// Controls response to rhythm note off events when rhythm mode is active.
bool _rhythmModeIgnoreNoteOffs;
+ // Controls whether MIDI channel 10 is treated as the rhythm channel or as
+ // a melodic channel.
+ bool _channel10Melodic;
// The default MIDI channel volume (set when opening the driver).
uint8 _defaultChannelVolume;
diff --git a/engines/darkseed/adlib_worx.cpp b/engines/darkseed/adlib_worx.cpp
new file mode 100644
index 00000000000..d705eabfbd7
--- /dev/null
+++ b/engines/darkseed/adlib_worx.cpp
@@ -0,0 +1,235 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "darkseed/adlib_worx.h"
+
+namespace Darkseed {
+
+AdLibIbkInstrumentDefinition MidiDriver_Worx_AdLib::WORX_INSTRUMENT_BANK[128] = {
+ // 0x00
+ { 0x01, 0x01, 0x4f, 0x12, 0xf1, 0xd3, 0x50, 0x7c, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x02, 0x01, 0x50, 0x12, 0xf1, 0xd2, 0x50, 0x76, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x01, 0x01, 0x4b, 0x17, 0xf1, 0xd2, 0x50, 0x76, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x13, 0x01, 0x50, 0x11, 0xf1, 0xd2, 0x50, 0x76, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x32, 0x01, 0x92, 0x8f, 0xff, 0xff, 0x11, 0x13, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x34, 0x03, 0x92, 0x0f, 0xff, 0xff, 0x10, 0x04, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x34, 0x03, 0x92, 0x14, 0xff, 0xff, 0x10, 0x04, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x53, 0x51, 0x4e, 0x00, 0xf1, 0xd2, 0x00, 0x86, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ // 0x08
+ { 0x28, 0x21, 0xcf, 0x0d, 0xf8, 0xc0, 0xe5, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0xe2, 0xe1, 0xca, 0x15, 0xf8, 0xc0, 0xe5, 0x0e, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x2c, 0xa1, 0xd4, 0x1c, 0xf9, 0xc0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x2b, 0x21, 0xca, 0x13, 0xf8, 0xc0, 0xe5, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x29, 0x21, 0xcd, 0x14, 0xf0, 0xe0, 0x91, 0x86, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x24, 0x21, 0xd0, 0x14, 0xf0, 0xe0, 0x01, 0x86, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x23, 0x21, 0xc8, 0x10, 0xf0, 0xe0, 0x01, 0x86, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x64, 0x61, 0xc9, 0x14, 0xb0, 0xf0, 0x01, 0x86, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ // 0x10
+ { 0x33, 0x15, 0x85, 0x94, 0xa1, 0x72, 0x10, 0x23, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x31, 0x15, 0x85, 0x94, 0xa1, 0x73, 0x10, 0x33, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x31, 0x16, 0x81, 0x94, 0xa1, 0xc2, 0x30, 0x74, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x03, 0x02, 0x8a, 0x94, 0xf0, 0xf4, 0x7b, 0x7b, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x03, 0x01, 0x8a, 0x99, 0xf0, 0xf4, 0x7b, 0x7b, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x23, 0x01, 0x8a, 0x94, 0xf2, 0xf4, 0x7b, 0x7b, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x32, 0x12, 0x80, 0x95, 0x01, 0x72, 0x10, 0x33, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x32, 0x14, 0x80, 0x90, 0x01, 0x73, 0x10, 0x33, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ // 0x18
+ { 0x31, 0x21, 0x16, 0x14, 0x73, 0x80, 0x8e, 0x9e, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x30, 0x21, 0x16, 0x10, 0x73, 0x80, 0x7e, 0x9e, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x31, 0x21, 0x94, 0x15, 0x33, 0xa0, 0x73, 0x97, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x31, 0x21, 0x94, 0x13, 0xd3, 0xa0, 0x73, 0x97, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x31, 0x32, 0x45, 0x11, 0xf1, 0xf2, 0x53, 0x27, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x13, 0x15, 0x0c, 0x1a, 0xf2, 0xf2, 0x01, 0xb6, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x11, 0x11, 0x0c, 0x15, 0xf2, 0xf2, 0x01, 0xb6, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x11, 0x11, 0x0a, 0x10, 0xfe, 0xf2, 0x04, 0xbd, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ // 0x20
+ { 0x16, 0xe1, 0x4d, 0x11, 0xfa, 0xf1, 0x11, 0xf1, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x16, 0xf1, 0x40, 0x17, 0xba, 0x24, 0x11, 0x31, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x61, 0xe1, 0xa7, 0x8e, 0x72, 0x50, 0x8e, 0x1a, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x18, 0xe1, 0x4d, 0x13, 0x32, 0x51, 0x13, 0xe3, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x17, 0x31, 0xc0, 0x92, 0x12, 0x13, 0x41, 0x31, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x03, 0x21, 0x8f, 0x90, 0xf5, 0xf3, 0x55, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x13, 0xe1, 0x4d, 0x12, 0xfa, 0xf1, 0x11, 0xf1, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x11, 0xf1, 0x43, 0x10, 0x20, 0x31, 0x15, 0xf8, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ // 0x28
+ { 0x11, 0xe4, 0x03, 0x52, 0x82, 0xf0, 0x97, 0xf2, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x05, 0x14, 0x40, 0x0f, 0xd1, 0x51, 0x53, 0x71, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0xf1, 0x21, 0x01, 0x12, 0x77, 0x81, 0x17, 0x18, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0xf1, 0xe1, 0x18, 0x17, 0x32, 0xf1, 0x11, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x73, 0x71, 0x48, 0x13, 0xf1, 0xf1, 0x53, 0x06, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x71, 0x61, 0x8d, 0x53, 0x71, 0x72, 0x11, 0x15, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0xd7, 0xd2, 0x4f, 0x14, 0xf2, 0xf1, 0x61, 0xb2, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x01, 0x01, 0x11, 0x13, 0xf0, 0xf0, 0xff, 0xf8, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ // 0x30
+ { 0x31, 0x61, 0x8b, 0x10, 0x41, 0x22, 0x11, 0x13, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x31, 0x61, 0x8b, 0x10, 0xff, 0x44, 0x21, 0x15, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x31, 0x61, 0x8b, 0x10, 0x41, 0x32, 0x11, 0x15, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x71, 0x21, 0x1c, 0x10, 0xfd, 0xe7, 0x13, 0xd6, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x71, 0x21, 0x1c, 0x10, 0x51, 0x54, 0x03, 0x67, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x71, 0x21, 0x1c, 0x10, 0x51, 0x54, 0x03, 0x17, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x71, 0x21, 0x1c, 0x10, 0x54, 0x53, 0x15, 0x49, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x71, 0x61, 0x56, 0x10, 0x51, 0x54, 0x03, 0x17, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ // 0x38
+ { 0x71, 0x21, 0x1c, 0x10, 0x51, 0x54, 0x03, 0x17, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x02, 0x01, 0x29, 0x90, 0xf5, 0xf2, 0x75, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x02, 0x01, 0x29, 0x90, 0xf0, 0xf4, 0x75, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x01, 0x11, 0x49, 0x10, 0xf1, 0xf1, 0x53, 0x74, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x01, 0x11, 0x89, 0x10, 0xf1, 0xf1, 0x53, 0x74, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x02, 0x11, 0x89, 0x10, 0xf1, 0xf1, 0x53, 0x74, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x02, 0x11, 0x80, 0x10, 0xf1, 0xf1, 0x53, 0x74, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x01, 0x08, 0x40, 0x50, 0xf1, 0xf1, 0x53, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ // 0x40
+ { 0x21, 0x21, 0x15, 0x90, 0xd3, 0xc3, 0x2c, 0x2c, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x01, 0x21, 0x18, 0x90, 0xd4, 0xc4, 0xf2, 0x8a, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x01, 0x11, 0x4e, 0x10, 0xf0, 0xf4, 0x7b, 0xc8, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x01, 0x11, 0x44, 0x10, 0xf0, 0xf3, 0xab, 0xab, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x53, 0x11, 0x0e, 0x10, 0xf4, 0xf1, 0xc8, 0xbb, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x53, 0x11, 0x0b, 0x10, 0xf2, 0xf2, 0xc8, 0xc5, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x21, 0x21, 0x15, 0x10, 0xb4, 0x94, 0x4c, 0xac, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x21, 0x21, 0x15, 0x10, 0x94, 0x64, 0x1c, 0xac, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ // 0x48
+ { 0x21, 0xa1, 0x16, 0x90, 0x77, 0x60, 0x8f, 0x2a, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x21, 0xa1, 0x19, 0x90, 0x77, 0x60, 0xbf, 0x2a, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0xa1, 0xe2, 0x13, 0x90, 0xd6, 0x60, 0xaf, 0x2a, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0xa2, 0xe2, 0x1d, 0x90, 0x95, 0x60, 0x24, 0x2a, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x32, 0x61, 0x9a, 0x90, 0x51, 0x60, 0x19, 0x39, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0xa4, 0xe2, 0x12, 0x90, 0xf4, 0x60, 0x30, 0x2a, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x21, 0x21, 0x16, 0x10, 0x63, 0x63, 0x0e, 0x0e, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x31, 0x21, 0x16, 0x10, 0x63, 0x63, 0x0a, 0x0b, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ // 0x50
+ { 0x21, 0x21, 0x1b, 0x10, 0x63, 0x63, 0x0a, 0x0b, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x20, 0x21, 0x1b, 0x10, 0x63, 0x63, 0x0a, 0x0b, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x32, 0x61, 0x1c, 0x90, 0x82, 0x60, 0x18, 0x07, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x32, 0xe1, 0x18, 0x90, 0x51, 0x62, 0x14, 0x36, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x31, 0x22, 0xc3, 0x10, 0x87, 0x8b, 0x17, 0x0e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x71, 0x22, 0xc3, 0x14, 0x8e, 0x8b, 0x17, 0x0e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x70, 0x22, 0x8d, 0x10, 0x6e, 0x6b, 0x17, 0x0e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x24, 0x31, 0x4f, 0x10, 0xf2, 0x52, 0x06, 0x06, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ // 0x58
+ { 0x31, 0x61, 0x1b, 0x10, 0x64, 0xd0, 0x07, 0x67, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x31, 0x61, 0x1b, 0x10, 0x61, 0xd2, 0x06, 0x36, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x31, 0x61, 0x1f, 0x10, 0x31, 0x50, 0x06, 0x36, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x31, 0x61, 0x1f, 0x10, 0x41, 0xa0, 0x06, 0x36, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x21, 0x21, 0x9a, 0x90, 0x53, 0xa0, 0x56, 0x16, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x21, 0x21, 0x9a, 0x90, 0x53, 0xa0, 0x56, 0x16, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x61, 0x21, 0x19, 0x10, 0x53, 0xa0, 0x58, 0x18, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x61, 0x21, 0x19, 0x10, 0x73, 0xa0, 0x57, 0x17, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ // 0x60
+ { 0x21, 0x21, 0x1b, 0x10, 0x71, 0xa1, 0xa6, 0x96, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x85, 0xa1, 0x91, 0x10, 0xf5, 0xf0, 0x44, 0x45, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x07, 0x61, 0x51, 0x10, 0xf5, 0xf0, 0x33, 0x25, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x13, 0x11, 0x8c, 0x90, 0xff, 0xff, 0x21, 0x03, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x38, 0xb1, 0x8c, 0x50, 0xf3, 0xf5, 0x0d, 0x33, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x87, 0x22, 0x91, 0x10, 0xf5, 0xf0, 0x55, 0x54, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0xb3, 0x90, 0x4a, 0x10, 0xb6, 0xd1, 0x32, 0x31, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x04, 0xc2, 0x00, 0x10, 0xfe, 0xf6, 0xf0, 0xb5, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ // 0x68
+ { 0x05, 0x01, 0x4e, 0x90, 0xda, 0xf0, 0x15, 0x13, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x31, 0x32, 0x44, 0x10, 0xf2, 0xf0, 0x9a, 0x27, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0xb0, 0xd7, 0xc4, 0x90, 0xa4, 0x40, 0x02, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0xca, 0xcc, 0x84, 0x10, 0xf0, 0x59, 0xf0, 0x62, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x30, 0x35, 0x35, 0x10, 0xf5, 0xf0, 0xf0, 0x9b, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0xb4, 0xd7, 0x87, 0x90, 0xa4, 0x40, 0x02, 0x42, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x07, 0x05, 0x40, 0x00, 0x09, 0xf6, 0x53, 0x96, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x09, 0x01, 0x4e, 0x10, 0xda, 0xf1, 0x25, 0x15, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ // 0x70
+ { 0x06, 0x00, 0x09, 0x10, 0xf4, 0xf6, 0xa0, 0x46, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x07, 0x00, 0x00, 0x10, 0xf0, 0x5c, 0xf0, 0xdc, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x1c, 0x0c, 0x1e, 0x10, 0xe5, 0x5d, 0x5b, 0xfa, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x11, 0x01, 0x8a, 0x50, 0xf1, 0xf1, 0x11, 0xb3, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x00, 0x00, 0x40, 0x10, 0xd1, 0xf2, 0x53, 0x56, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x32, 0x11, 0x44, 0x10, 0xf8, 0xf5, 0xff, 0x7f, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x00, 0x02, 0x40, 0x10, 0x09, 0xf7, 0x53, 0x94, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x11, 0x01, 0x86, 0x90, 0xf2, 0xa0, 0xa8, 0xa8, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ // 0x78
+ { 0x00, 0x13, 0x50, 0x10, 0xf2, 0xf2, 0x70, 0x72, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0xf0, 0xe0, 0x00, 0xd0, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x07, 0x12, 0x4f, 0x10, 0xf2, 0xf2, 0x60, 0x72, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x00, 0x00, 0x0b, 0x10, 0xa8, 0xd6, 0x4c, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x00, 0x00, 0x0d, 0x10, 0xe8, 0xa5, 0xef, 0xff, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x31, 0x16, 0x87, 0x90, 0xa1, 0x7d, 0x11, 0x46, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x30, 0x10, 0x90, 0x10, 0xf4, 0xf4, 0x49, 0x33, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x24, 0x31, 0x54, 0x10, 0x55, 0x50, 0xfd, 0x2d, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 }
+};
+
+MidiDriver_Worx_AdLib::MidiDriver_Worx_AdLib(OPL::Config::OplType oplType, int timerFrequency) :
+ MidiDriver_ADLIB_Multisource::MidiDriver_ADLIB_Multisource(oplType, timerFrequency) {
+
+ _instrumentBank = new OplInstrumentDefinition[128];
+
+ for (int i = 0; i < 128; i++) {
+ WORX_INSTRUMENT_BANK[i].toOplInstrumentDefinition(_instrumentBank[i]);
+ }
+
+ _defaultChannelVolume = 0x7F;
+ _channel10Melodic = true;
+}
+
+MidiDriver_Worx_AdLib::~MidiDriver_Worx_AdLib() {
+ delete[] _instrumentBank;
+}
+
+uint8 MidiDriver_Worx_AdLib::allocateOplChannel(uint8 channel, uint8 source, uint8 instrumentId) {
+ uint8 allocatedChannel = 0xFF;
+
+ _allocationMutex.lock();
+
+ uint8 unusedChannel = 0xFF, unallocatedChannel = 0xFF, unusedAllocatedChannel = 0xFF;
+ for (int i = 0; i < _numMelodicChannels; i++) {
+ uint8 oplChannel = _melodicChannels[i];
+ if (_activeNotes[oplChannel].channelAllocated && _activeNotes[oplChannel].source == source && _activeNotes[oplChannel].channel == channel &&
+ !_activeNotes[oplChannel].noteActive && unusedChannel == 0xFF) {
+ unusedChannel = oplChannel;
+ break;
+ }
+ if (!_activeNotes[oplChannel].channelAllocated && unallocatedChannel == 0xFF) {
+ unallocatedChannel = oplChannel;
+ }
+ if (_activeNotes[oplChannel].channelAllocated && !(_activeNotes[oplChannel].source == source && _activeNotes[oplChannel].channel == channel) &&
+ !_activeNotes[oplChannel].noteActive && unusedAllocatedChannel == 0xFF) {
+ unusedAllocatedChannel = oplChannel;
+ }
+ }
+
+ if (unusedChannel != 0xFF) {
+ allocatedChannel = unusedChannel;
+ }
+ else if (unallocatedChannel != 0xFF) {
+ allocatedChannel = unallocatedChannel;
+ }
+ else if (unusedAllocatedChannel != 0xFF) {
+ allocatedChannel = unusedAllocatedChannel;
+ }
+ else {
+ _allocationMutex.unlock();
+ return allocatedChannel;
+ }
+
+ _activeNotes[allocatedChannel].channelAllocated = true;
+ _activeNotes[allocatedChannel].source = source;
+ _activeNotes[allocatedChannel].channel = channel;
+
+ _allocationMutex.unlock();
+
+ return allocatedChannel;
+}
+
+} // namespace Darkseed
diff --git a/engines/darkseed/adlib_worx.h b/engines/darkseed/adlib_worx.h
new file mode 100644
index 00000000000..46f581cd2e3
--- /dev/null
+++ b/engines/darkseed/adlib_worx.h
@@ -0,0 +1,43 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef DARKSEED_ADLIB_WORX_H
+#define DARKSEED_ADLIB_WORX_H
+
+#include "audio/adlib_ms.h"
+
+namespace Darkseed {
+
+class MidiDriver_Worx_AdLib : public MidiDriver_ADLIB_Multisource {
+private:
+ static AdLibIbkInstrumentDefinition WORX_INSTRUMENT_BANK[];
+
+public:
+ MidiDriver_Worx_AdLib(OPL::Config::OplType oplType, int timerFrequency);
+ ~MidiDriver_Worx_AdLib();
+
+protected:
+ uint8 allocateOplChannel(uint8 channel, uint8 source, uint8 instrumentId) override;
+};
+
+} // namespace Darkseed
+
+#endif // DARKSEED_ADLIB_WORX_H
diff --git a/engines/darkseed/cutscene.cpp b/engines/darkseed/cutscene.cpp
index 40afb2900d5..8fd0368b65a 100644
--- a/engines/darkseed/cutscene.cpp
+++ b/engines/darkseed/cutscene.cpp
@@ -167,6 +167,7 @@ bool Cutscene::introScene() {
}
break;
case 15: {
+ g_engine->_sound->playMusic(StartMusicId::kCredits);
g_engine->_screen->clear();
g_engine->_screen->clearPalette();
g_engine->_screen->makeAllDirty();
@@ -396,9 +397,17 @@ bool Cutscene::introScene() {
return true;
}
break;
- case 50: // TODO wait for music.
+ case 50:
+ if (g_engine->_sound->isPlayingMusic()) {
+ if (g_engine->_isLeftMouseClicked || g_engine->_isRightMouseClicked) {
+ g_engine->zeroMouseButtons();
+ _movieStep = 51;
+ }
+ return true;
+ }
break;
case 51:
+ g_engine->_sound->stopMusic();
g_engine->fadeOut();
break;
case 52:
@@ -448,7 +457,7 @@ bool Cutscene::embryoInsertedScene() {
break;
}
case 6:
- // TODO play implant music here.
+ g_engine->_sound->playMusic(StartMusicId::kImplant);
registTime();
g_engine->fadeIn(_palette);
break;
@@ -511,6 +520,7 @@ bool Cutscene::embryoInsertedScene() {
}
break;
case 16:
+ g_engine->_sound->stopMusic();
g_engine->fadeOut();
break;
case 17:
diff --git a/engines/darkseed/darkseed.cpp b/engines/darkseed/darkseed.cpp
index 9cc98fd9c94..263c41cc88f 100644
--- a/engines/darkseed/darkseed.cpp
+++ b/engines/darkseed/darkseed.cpp
@@ -59,6 +59,9 @@ Common::String DarkseedEngine::getGameId() const {
Common::Error DarkseedEngine::run() {
initGraphics(640, 350);
_sound = new Sound(_mixer);
+ if (_sound->init() > 0) {
+ return Common::kAudioDeviceInitFailed;
+ }
_screen = new Graphics::Screen();
_tosText = new TosText();
_tosText->load();
@@ -377,6 +380,12 @@ void DarkseedEngine::wait() {
}
}
+void DarkseedEngine::syncSoundSettings() {
+ Engine::syncSoundSettings();
+
+ _sound->syncSoundSettings();
+}
+
static constexpr uint8 walkToDirTbl[] = {
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
diff --git a/engines/darkseed/darkseed.h b/engines/darkseed/darkseed.h
index f3a1da0434c..4e191547ece 100644
--- a/engines/darkseed/darkseed.h
+++ b/engines/darkseed/darkseed.h
@@ -151,6 +151,8 @@ public:
void wait();
+ void syncSoundSettings() override;
+
public:
DarkseedEngine(OSystem *syst, const ADGameDescription *gameDesc);
~DarkseedEngine() override;
diff --git a/engines/darkseed/module.mk b/engines/darkseed/module.mk
index c6fa3787ed1..9408516237e 100644
--- a/engines/darkseed/module.mk
+++ b/engines/darkseed/module.mk
@@ -1,6 +1,7 @@
MODULE := engines/darkseed
MODULE_OBJS = \
+ adlib_worx.o \
animation.o \
anm.o \
console.o \
@@ -13,6 +14,7 @@ MODULE_OBJS = \
inventory.o \
metaengine.o \
morph.o \
+ music.o \
nsp.o \
objects.o \
pal.o \
diff --git a/engines/darkseed/music.cpp b/engines/darkseed/music.cpp
new file mode 100644
index 00000000000..898ae548add
--- /dev/null
+++ b/engines/darkseed/music.cpp
@@ -0,0 +1,196 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "darkseed/music.h"
+#include "darkseed/darkseed.h"
+
+namespace Darkseed {
+
+MusicPlayer::MusicPlayer(DarkseedEngine* vm) :
+ _vm(vm),
+ _driver(nullptr),
+ _paused(false),
+ _deviceType(MT_NULL),
+ _parser(nullptr),
+ _musicData(nullptr) {
+}
+
+MusicPlayer::~MusicPlayer() {
+ stop();
+ if (_driver) {
+ _driver->setTimerCallback(nullptr, nullptr);
+ _driver->close();
+ }
+
+ Common::StackLock lock(_mutex);
+
+ if (_parser)
+ delete _parser;
+ if (_musicData)
+ delete[] _musicData;
+ if (_driver) {
+ delete _driver;
+ _driver = nullptr;
+ }
+}
+
+int MusicPlayer::open() {
+ assert(!_driver);
+
+ int devFlags = MDT_ADLIB; // | MDT_PCSPK;
+ MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(devFlags);
+ _deviceType = MidiDriver::getMusicType(dev);
+
+ if (!_vm->isCdVersion()) {
+ // TODO Initialize driver and parser for floppy version
+ _driver = new MidiDriver_NULL_Multisource();
+ } else {
+ switch (_deviceType) {
+ case MT_ADLIB:
+ // TODO Verify timer frequency
+ _driver = new MidiDriver_Worx_AdLib(OPL::Config::kOpl2, 250);
+ // Some tracks do not set instruments and expect instrument 0
+ // to be set on each channel. Make sure this is done every time
+ // a track starts.
+ _driver->setControllerDefault(MidiDriver_Multisource::CONTROLLER_DEFAULT_PROGRAM);
+ break;
+ case MT_PCSPK:
+ // TODO Implement PC speaker driver
+ default:
+ _driver = new MidiDriver_NULL_Multisource();
+ break;
+ }
+
+ _parser = MidiParser::createParser_SMF(0);
+ }
+
+ _driver->property(MidiDriver::PROP_USER_VOLUME_SCALING, true);
+ if (_parser)
+ _parser->property(MidiParser::mpDisableAutoStartPlayback, true);
+
+ int returnCode = _driver->open();
+ if (returnCode != 0)
+ error("MusicPlayer::open - Failed to open MIDI driver - error code %d.", returnCode);
+
+ syncSoundSettings();
+
+ if (_parser) {
+ _parser->setMidiDriver(_driver);
+ _parser->setTimerRate(_driver->getBaseTempo());
+ _driver->setTimerCallback(_parser, &_parser->timerCallback);
+ }
+
+ return 0;
+}
+
+void MusicPlayer::onTimer(void *data) {
+ MusicPlayer *p = (MusicPlayer *)data;
+ Common::StackLock lock(p->_mutex);
+
+ if (p->_parser) {
+ p->_parser->onTimer();
+ }
+}
+
+bool MusicPlayer::isPlaying() {
+ Common::StackLock lock(_mutex);
+ return _parser && _parser->isPlaying();
+}
+
+void MusicPlayer::stop() {
+ Common::StackLock lock(_mutex);
+
+ if (_parser) {
+ _parser->stopPlaying();
+ if (_driver) {
+ _driver->deinitSource(0);
+ }
+ }
+}
+
+void MusicPlayer::pause(bool pause) {
+ Common::StackLock lock(_mutex);
+
+ if (_paused == pause || !_parser)
+ return;
+
+ _paused = pause;
+
+ if (_paused) {
+ _parser->pausePlaying();
+ } else {
+ _parser->resumePlaying();
+ }
+}
+
+void MusicPlayer::syncSoundSettings() {
+ if (_driver)
+ _driver->syncSoundSettings();
+}
+
+void MusicPlayer::setLoop(bool loop) {
+ Common::StackLock lock(_mutex);
+
+ if (_parser)
+ _parser->property(MidiParser::mpAutoLoop, loop);
+}
+
+void MusicPlayer::load(Common::SeekableReadStream *in, int32 size) {
+ Common::StackLock lock(_mutex);
+
+ if (!_parser)
+ return;
+
+ if (size < 0) {
+ // Use the parser to determine the size of the MIDI data.
+ int64 startPos = in->pos();
+ size = _parser->determineDataSize(in);
+ if (size < 0) {
+ warning("MusicPlayer::load - Could not determine size of music data");
+ return;
+ }
+ // determineDataSize might move the stream position, so return it to
+ // the original position.
+ in->seek(startPos);
+ }
+
+ _parser->unloadMusic();
+ if (_musicData) {
+ delete[] _musicData;
+ }
+
+ _musicData = new byte[size];
+ in->read(_musicData, size);
+
+ _parser->loadMusic(_musicData, size);
+}
+
+void MusicPlayer::play(bool loop) {
+ Common::StackLock lock(_mutex);
+
+ if (!_parser)
+ return;
+
+ _parser->property(MidiParser::mpAutoLoop, loop);
+ _parser->startPlaying();
+}
+
+} // namespace Darkseed
diff --git a/engines/darkseed/music.h b/engines/darkseed/music.h
new file mode 100644
index 00000000000..b04184e10f0
--- /dev/null
+++ b/engines/darkseed/music.h
@@ -0,0 +1,72 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef DARKSEED_MUSIC_H
+#define DARKSEED_MUSIC_H
+
+#include "darkseed/adlib_worx.h"
+
+#include "audio/mididrv_ms.h"
+#include "audio/midiparser.h"
+#include "common/mutex.h"
+
+namespace Darkseed {
+
+class DarkseedEngine;
+
+class MusicPlayer {
+protected:
+ DarkseedEngine *_vm;
+
+ Common::Mutex _mutex;
+ MidiDriver_Multisource *_driver;
+
+ MidiParser *_parser;
+ byte *_musicData;
+
+ bool _paused;
+
+ static void onTimer(void *data);
+
+public:
+ MusicPlayer(DarkseedEngine *vm);
+ ~MusicPlayer();
+
+ int open();
+
+ void load(Common::SeekableReadStream *in, int32 size = -1);
+
+ void play(bool loop = false);
+ void setLoop(bool loop);
+ bool isPlaying();
+ void stop();
+ void pause(bool pause);
+
+ void syncSoundSettings();
+
+private:
+ // The type of the music device selected for playback.
+ MusicType _deviceType;
+};
+
+} // namespace Darkseed
+
+#endif // DARKSEED_MUSIC_H
diff --git a/engines/darkseed/sound.cpp b/engines/darkseed/sound.cpp
index c585fd86cf5..2008193ad23 100644
--- a/engines/darkseed/sound.cpp
+++ b/engines/darkseed/sound.cpp
@@ -57,11 +57,42 @@ static constexpr char musicDosCDFilenameTbl[][14] = {
"walktown.mid"
};
+static constexpr char startMusicDosFloppyFilenameTbl[][14] = {
+ "credits",
+ "alien",
+ "implant",
+ "launch",
+ "night2",
+ "night3",
+ "book",
+ "doll"
+};
+
+static constexpr char startMusicDosCDFilenameTbl[][14] = {
+ "openingt.mid",
+ "alienmou.mid",
+ "mindfuck.mid",
+ "spaceshi.mid",
+ "mindfuck.mid",
+ "zombie.mid",
+ "booktran.mid",
+ "babydoll.mid"
+};
+
Sound::Sound(Audio::Mixer *mixer) : _mixer(mixer) {
+ _musicPlayer = new MusicPlayer(g_engine);
_didSpeech.resize(978);
resetSpeech();
}
+Sound::~Sound() {
+ delete _musicPlayer;
+}
+
+int Sound::init() {
+ return _musicPlayer->open();
+}
+
void Sound::playTosSpeech(int tosIdx) {
if (!g_engine->isCdVersion() || _didSpeech[tosIdx] == 1) {
return;
@@ -84,7 +115,7 @@ bool Sound::isPlayingSpeech() const {
}
bool Sound::isPlayingMusic() {
- return _isPlayingMusic;
+ return _musicPlayer->isPlaying();
}
void Sound::waitForSpeech() {
@@ -106,17 +137,42 @@ void Sound::playMusic(MusicId musicId) {
int filenameIdx = static_cast<uint8>(musicId) - 1;
playMusic(g_engine->isCdVersion()
? musicDosCDFilenameTbl[filenameIdx]
- : musicDosFloppyFilenameTbl[filenameIdx]);
+ : musicDosFloppyFilenameTbl[filenameIdx],
+ true);
}
-void Sound::playMusic(Common::String const &filename) {
+void Sound::playMusic(StartMusicId musicId) {
+ int filenameIdx = static_cast<uint8>(musicId);
+ playMusic(g_engine->isCdVersion()
+ ? startMusicDosCDFilenameTbl[filenameIdx]
+ : startMusicDosFloppyFilenameTbl[filenameIdx]);
+}
+
+void Sound::playMusic(Common::String const &filename, bool loop) {
debug("Loading music: %s", filename.c_str());
- _isPlayingMusic = true;
- // TODO load music.
+ Common::File file;
+ Common::Path path;
+ if (!g_engine->isCdVersion()) {
+ path = Common::Path(filename);
+ } else {
+ path = Common::Path("sound").join(filename);
+ }
+ if (!file.open(path)) {
+ debug("Failed to load %s", path.toString().c_str());
+ return;
+ }
+ _musicPlayer->load(&file, file.size());
+ file.close();
+
+ _musicPlayer->play(loop);
}
void Sound::stopMusic() {
- _isPlayingMusic = false;
+ _musicPlayer->stop();
+}
+
+void Sound::syncSoundSettings() {
+ _musicPlayer->syncSoundSettings();
}
Common::Error Sound::sync(Common::Serializer &s) {
diff --git a/engines/darkseed/sound.h b/engines/darkseed/sound.h
index 7f3836e8c73..e90662e9854 100644
--- a/engines/darkseed/sound.h
+++ b/engines/darkseed/sound.h
@@ -22,6 +22,8 @@
#ifndef DARKSEED_SOUND_H
#define DARKSEED_SOUND_H
+#include "darkseed/music.h"
+
#include "audio/mixer.h"
#include "common/array.h"
#include "common/error.h"
@@ -44,14 +46,28 @@ enum class MusicId : uint8 {
kTown,
};
+enum class StartMusicId : uint8 {
+ kCredits = 0,
+ kAlien,
+ kImplant,
+ kLaunch,
+ kNight2,
+ kNight3,
+ kBook,
+ kDoll
+};
+
class Sound {
Audio::Mixer *_mixer;
Audio::SoundHandle _speechHandle;
+ MusicPlayer *_musicPlayer;
Common::Array<uint8> _didSpeech;
- bool _isPlayingMusic = false;
public:
explicit Sound(Audio::Mixer *mixer);
+ ~Sound();
+
+ int init();
Common::Error sync(Common::Serializer &s);
@@ -61,8 +77,10 @@ public:
void waitForSpeech();
void resetSpeech();
void playMusic(MusicId musicId);
- void playMusic(Common::String const &filename);
+ void playMusic(StartMusicId musicId);
+ void playMusic(Common::String const &filename, bool loop = false);
void stopMusic();
+ void syncSoundSettings();
};
} // namespace Darkseed
More information about the Scummvm-git-logs
mailing list