mirror of
https://github.com/scummvm/scummvm.git
synced 2026-06-20 05:45:29 +00:00
DARKSEED: Add CD version music player
This commit is contained in:
1 parent
70b1b16a93
commit
bcdd54ee8d
12 files changed
+741
-11
No files matched your search
+46
-1
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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:
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -151,6 +151,8 @@ public:
|
||||
|
||||
void wait();
|
||||
|
||||
void syncSoundSettings() override;
|
||||
|
||||
public:
|
||||
DarkseedEngine(OSystem *syst, const ADGameDescription *gameDesc);
|
||||
~DarkseedEngine() override;
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in new issue
Block a user