Preliminary preparation for new YM2612 FM emulator.
All the hooks are in, but actual implementation needs to be checked for portability. svn-id: r10615
This commit is contained in:
parent
7174a32c8e
commit
a722d0601e
16 changed files with 154 additions and 60 deletions
1
README
1
README
|
@ -570,6 +570,7 @@ choices of output, depending on your operating system and configuration.
|
||||||
adlib - Uses internal Adlib Emulation (default)
|
adlib - Uses internal Adlib Emulation (default)
|
||||||
pcjr - Uses internal PCjr Emulation
|
pcjr - Uses internal PCjr Emulation
|
||||||
pcspk - Uses internal PC Speaker Emulation
|
pcspk - Uses internal PC Speaker Emulation
|
||||||
|
towns - Uses FM-Towns YM2612 Emulation
|
||||||
windows - Windows MIDI. Uses built-in sequencer, for Windows users
|
windows - Windows MIDI. Uses built-in sequencer, for Windows users
|
||||||
seq - Uses /dev/sequencer for MIDI, *nix users. See below.
|
seq - Uses /dev/sequencer for MIDI, *nix users. See below.
|
||||||
qt - Quicktime sound, for Macintosh users.
|
qt - Quicktime sound, for Macintosh users.
|
||||||
|
|
31
backends/midi/ym2612.cpp
Normal file
31
backends/midi/ym2612.cpp
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/* ScummVM - Scumm Interpreter
|
||||||
|
* Copyright (C) 2001-2003 The ScummVM project
|
||||||
|
*
|
||||||
|
* YM2612 tone generation code written by Tomoaki Hayasaka.
|
||||||
|
* Used under the terms of the GNU General Public License.
|
||||||
|
* Adpated to ScummVM by Jamieson Christian.
|
||||||
|
*
|
||||||
|
* 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 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* $Header$
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Real implementation coming soon! :)
|
||||||
|
|
||||||
|
#include "sound/mididrv.h"
|
||||||
|
|
||||||
|
MidiDriver *MidiDriver_YM2612_create(SoundMixer *mixer) {
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -11,7 +11,8 @@ MODULE_OBJS := \
|
||||||
backends/midi/quicktime.o \
|
backends/midi/quicktime.o \
|
||||||
backends/midi/seq.o \
|
backends/midi/seq.o \
|
||||||
backends/midi/alsa.o \
|
backends/midi/alsa.o \
|
||||||
backends/midi/windows.o
|
backends/midi/windows.o \
|
||||||
|
backends/midi/ym2612.o
|
||||||
|
|
||||||
MODULE_DIRS += \
|
MODULE_DIRS += \
|
||||||
backends \
|
backends \
|
||||||
|
|
|
@ -676,12 +676,15 @@ bool GameDetector::detectMain() {
|
||||||
if (_game.midi & MDT_PREFER_NATIVE)
|
if (_game.midi & MDT_PREFER_NATIVE)
|
||||||
_midi_driver = getMidiDriverType();
|
_midi_driver = getMidiDriverType();
|
||||||
else
|
else
|
||||||
_midi_driver = MD_ADLIB;
|
_midi_driver = MD_TOWNS;
|
||||||
}
|
}
|
||||||
bool nativeMidiDriver =
|
bool nativeMidiDriver =
|
||||||
(_midi_driver != MD_NULL && _midi_driver != MD_ADLIB &&
|
(_midi_driver != MD_NULL && _midi_driver != MD_ADLIB &&
|
||||||
_midi_driver != MD_PCSPK && _midi_driver != MD_PCJR);
|
_midi_driver != MD_PCSPK && _midi_driver != MD_PCJR &&
|
||||||
|
_midi_driver != MD_TOWNS);
|
||||||
if (nativeMidiDriver && !(_game.midi & MDT_NATIVE))
|
if (nativeMidiDriver && !(_game.midi & MDT_NATIVE))
|
||||||
|
_midi_driver = MD_TOWNS;
|
||||||
|
if (_midi_driver == MD_TOWNS && !(_game.midi & MDT_TOWNS))
|
||||||
_midi_driver = MD_ADLIB;
|
_midi_driver = MD_ADLIB;
|
||||||
if (_midi_driver == MD_ADLIB && !(_game.midi & MDT_ADLIB))
|
if (_midi_driver == MD_ADLIB && !(_game.midi & MDT_ADLIB))
|
||||||
_midi_driver = MD_PCJR;
|
_midi_driver = MD_PCJR;
|
||||||
|
@ -770,12 +773,15 @@ MidiDriver *GameDetector::createMidi() {
|
||||||
|
|
||||||
switch(drv) {
|
switch(drv) {
|
||||||
case MD_NULL: return MidiDriver_NULL_create();
|
case MD_NULL: return MidiDriver_NULL_create();
|
||||||
|
|
||||||
// In the case of Adlib, we won't specify anything.
|
// In the case of Adlib, we won't specify anything.
|
||||||
// IMuse is designed to set up its own Adlib driver
|
// IMuse is designed to set up its own Adlib driver
|
||||||
// if need be, and we only have to specify a native
|
// if need be, and we only have to specify a native
|
||||||
// driver.
|
// driver.
|
||||||
case MD_ADLIB: return NULL;
|
case MD_ADLIB: return NULL;
|
||||||
|
|
||||||
|
case MD_TOWNS: return MidiDriver_YM2612_create(g_engine->_mixer);
|
||||||
|
|
||||||
// Right now PC Speaker and PCjr are handled
|
// Right now PC Speaker and PCjr are handled
|
||||||
// outside the MidiDriver architecture, so
|
// outside the MidiDriver architecture, so
|
||||||
// don't create anything for now.
|
// don't create anything for now.
|
||||||
|
|
|
@ -70,8 +70,9 @@ enum MidiDriverType {
|
||||||
MDT_NONE = 0,
|
MDT_NONE = 0,
|
||||||
MDT_PCSPK = 1, // MD_PCSPK and MD_PCJR
|
MDT_PCSPK = 1, // MD_PCSPK and MD_PCJR
|
||||||
MDT_ADLIB = 2, // MD_ADLIB
|
MDT_ADLIB = 2, // MD_ADLIB
|
||||||
MDT_NATIVE = 4, // Everything else
|
MDT_TOWNS = 4, // MD_TOWNS
|
||||||
MDT_PREFER_NATIVE = 8
|
MDT_NATIVE = 8, // Everything else
|
||||||
|
MDT_PREFER_NATIVE = 16
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TargetSettings {
|
struct TargetSettings {
|
||||||
|
|
|
@ -540,6 +540,10 @@ SOURCE=..\..\backends\midi\null.cpp
|
||||||
|
|
||||||
SOURCE=..\..\backends\midi\windows.cpp
|
SOURCE=..\..\backends\midi\windows.cpp
|
||||||
# End Source File
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\backends\midi\ym2612.cpp
|
||||||
|
# End Source File
|
||||||
# End Group
|
# End Group
|
||||||
# End Group
|
# End Group
|
||||||
# End Group
|
# End Group
|
||||||
|
|
|
@ -355,6 +355,9 @@
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\backends\midi\windows.cpp">
|
RelativePath="..\..\backends\midi\windows.cpp">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\backends\midi\ym2612.cpp">
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
|
|
|
@ -54,6 +54,7 @@ _initialized(false),
|
||||||
_tempoFactor(0),
|
_tempoFactor(0),
|
||||||
_player_limit(ARRAYSIZE(_players)),
|
_player_limit(ARRAYSIZE(_players)),
|
||||||
_recycle_players(false),
|
_recycle_players(false),
|
||||||
|
_direct_passthrough(false),
|
||||||
_queue_end(0),
|
_queue_end(0),
|
||||||
_queue_pos(0),
|
_queue_pos(0),
|
||||||
_queue_sound(0),
|
_queue_sound(0),
|
||||||
|
@ -250,7 +251,7 @@ bool IMuseInternal::startSound(int sound) {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
player->clear();
|
player->clear();
|
||||||
return player->startSound(sound, driver);
|
return player->startSound(sound, driver, _direct_passthrough);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1117,10 +1118,14 @@ uint32 IMuseInternal::property(int prop, uint32 value) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IMuse::PROP_RECYCLE_PLAYERS:
|
case IMuse::PROP_RECYCLE_PLAYERS:
|
||||||
if (value > 0 && value <= ARRAYSIZE(_players))
|
|
||||||
_recycle_players = (value != 0);
|
_recycle_players = (value != 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case IMuse::PROP_DIRECT_PASSTHROUGH:
|
||||||
|
_direct_passthrough = (value != 0);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,12 +51,13 @@ public:
|
||||||
~IMuse();
|
~IMuse();
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_TEMPO_BASE = 1,
|
PROP_TEMPO_BASE,
|
||||||
PROP_NATIVE_MT32 = 2,
|
PROP_NATIVE_MT32,
|
||||||
PROP_MULTI_MIDI = 3,
|
PROP_MULTI_MIDI,
|
||||||
PROP_OLD_ADLIB_INSTRUMENTS = 4,
|
PROP_OLD_ADLIB_INSTRUMENTS,
|
||||||
PROP_LIMIT_PLAYERS = 5,
|
PROP_LIMIT_PLAYERS,
|
||||||
PROP_RECYCLE_PLAYERS = 6
|
PROP_RECYCLE_PLAYERS,
|
||||||
|
PROP_DIRECT_PASSTHROUGH
|
||||||
};
|
};
|
||||||
|
|
||||||
void on_timer(MidiDriver *midi);
|
void on_timer(MidiDriver *midi);
|
||||||
|
|
|
@ -60,10 +60,6 @@ class ScummEngine;
|
||||||
|
|
||||||
#define TICKS_PER_BEAT 480
|
#define TICKS_PER_BEAT 480
|
||||||
|
|
||||||
#define IMUSE_SYSEX_ID 0x7D
|
|
||||||
#define ROLAND_SYSEX_ID 0x41
|
|
||||||
#define PERCUSSION_CHANNEL 9
|
|
||||||
|
|
||||||
#define TRIGGER_ID 0
|
#define TRIGGER_ID 0
|
||||||
#define COMMAND_ID 1
|
#define COMMAND_ID 1
|
||||||
|
|
||||||
|
@ -158,6 +154,7 @@ protected:
|
||||||
protected:
|
protected:
|
||||||
MidiDriver *_midi;
|
MidiDriver *_midi;
|
||||||
MidiParser *_parser;
|
MidiParser *_parser;
|
||||||
|
bool _passThrough; // Only respond to EOT, all else direct to MidiDriver
|
||||||
|
|
||||||
Part *_parts;
|
Part *_parts;
|
||||||
bool _active;
|
bool _active;
|
||||||
|
@ -259,7 +256,7 @@ public:
|
||||||
void setSpeed(byte speed);
|
void setSpeed(byte speed);
|
||||||
int setTranspose(byte relative, int b);
|
int setTranspose(byte relative, int b);
|
||||||
int setVolume(byte vol);
|
int setVolume(byte vol);
|
||||||
bool startSound(int sound, MidiDriver *midi);
|
bool startSound(int sound, MidiDriver *midi, bool passThrough);
|
||||||
int getMusicTimer() const;
|
int getMusicTimer() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -368,6 +365,7 @@ protected:
|
||||||
|
|
||||||
int _player_limit; // Limits how many simultaneous music tracks are played
|
int _player_limit; // Limits how many simultaneous music tracks are played
|
||||||
bool _recycle_players; // Can we stop a player in order to start another one?
|
bool _recycle_players; // Can we stop a player in order to start another one?
|
||||||
|
bool _direct_passthrough; // Pass data direct to MidiDriver (no interactivity)
|
||||||
|
|
||||||
uint _queue_end, _queue_pos, _queue_sound;
|
uint _queue_end, _queue_pos, _queue_sound;
|
||||||
byte _queue_adding;
|
byte _queue_adding;
|
||||||
|
|
|
@ -39,6 +39,11 @@ namespace Scumm {
|
||||||
//
|
//
|
||||||
////////////////////////////////////////
|
////////////////////////////////////////
|
||||||
|
|
||||||
|
#define IMUSE_SYSEX_ID 0x7D
|
||||||
|
#define YM2612_SYSEX_ID 0x7C
|
||||||
|
#define ROLAND_SYSEX_ID 0x41
|
||||||
|
#define PERCUSSION_CHANNEL 9
|
||||||
|
|
||||||
extern MidiParser *MidiParser_createRO();
|
extern MidiParser *MidiParser_createRO();
|
||||||
extern MidiParser *MidiParser_createEUP();
|
extern MidiParser *MidiParser_createEUP();
|
||||||
|
|
||||||
|
@ -85,7 +90,7 @@ Player::~Player() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Player::startSound(int sound, MidiDriver *midi) {
|
bool Player::startSound(int sound, MidiDriver *midi, bool passThrough) {
|
||||||
void *ptr;
|
void *ptr;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -111,6 +116,7 @@ bool Player::startSound(int sound, MidiDriver *midi) {
|
||||||
_pan = 0;
|
_pan = 0;
|
||||||
_transpose = 0;
|
_transpose = 0;
|
||||||
_detune = 0;
|
_detune = 0;
|
||||||
|
_passThrough = passThrough;
|
||||||
|
|
||||||
for (i = 0; i < ARRAYSIZE(_parameterFaders); ++i)
|
for (i = 0; i < ARRAYSIZE(_parameterFaders); ++i)
|
||||||
_parameterFaders[i].init();
|
_parameterFaders[i].init();
|
||||||
|
@ -152,8 +158,11 @@ void Player::clear() {
|
||||||
debug (0, "Stopping music %d", _id);
|
debug (0, "Stopping music %d", _id);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (_parser)
|
if (_parser) {
|
||||||
_parser->unloadMusic();
|
_parser->unloadMusic();
|
||||||
|
delete _parser;
|
||||||
|
_parser = 0;
|
||||||
|
}
|
||||||
uninit_parts();
|
uninit_parts();
|
||||||
_se->ImFireAllTriggers(_id);
|
_se->ImFireAllTriggers(_id);
|
||||||
_active = false;
|
_active = false;
|
||||||
|
@ -224,6 +233,11 @@ void Player::setSpeed(byte speed) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::send(uint32 b) {
|
void Player::send(uint32 b) {
|
||||||
|
if (_passThrough) {
|
||||||
|
_midi->send (b);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
byte cmd = (byte)(b & 0xF0);
|
byte cmd = (byte)(b & 0xF0);
|
||||||
byte chan = (byte)(b & 0x0F);
|
byte chan = (byte)(b & 0x0F);
|
||||||
byte param1 = (byte)((b >> 8) & 0xFF);
|
byte param1 = (byte)((b >> 8) & 0xFF);
|
||||||
|
@ -333,8 +347,12 @@ void Player::sysEx(byte *p, uint16 len) {
|
||||||
byte buf[128];
|
byte buf[128];
|
||||||
Part *part;
|
Part *part;
|
||||||
|
|
||||||
|
if (_passThrough) {
|
||||||
|
_midi->sysEx (p, len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Check SysEx manufacturer.
|
// Check SysEx manufacturer.
|
||||||
// Roland is 0x41
|
|
||||||
a = *p++;
|
a = *p++;
|
||||||
--len;
|
--len;
|
||||||
if (a != IMUSE_SYSEX_ID) {
|
if (a != IMUSE_SYSEX_ID) {
|
||||||
|
@ -346,6 +364,9 @@ void Player::sysEx(byte *p, uint16 len) {
|
||||||
if (part->clearToTransmit())
|
if (part->clearToTransmit())
|
||||||
part->_instrument.send(part->_mc);
|
part->_instrument.send(part->_mc);
|
||||||
}
|
}
|
||||||
|
} else if (a == YM2612_SYSEX_ID) {
|
||||||
|
// FM-Towns custom instrument definition
|
||||||
|
_midi->sysEx_customInstrument (p[0], 'EUP ', p + 1);
|
||||||
} else {
|
} else {
|
||||||
warning("Unknown SysEx manufacturer 0x%02X", (int) a);
|
warning("Unknown SysEx manufacturer 0x%02X", (int) a);
|
||||||
}
|
}
|
||||||
|
@ -1124,10 +1145,8 @@ uint32 Player::getBaseTempo() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::metaEvent(byte type, byte *msg, uint16 len) {
|
void Player::metaEvent(byte type, byte *msg, uint16 len) {
|
||||||
if (type == 0x2F) {
|
if (type == 0x2F)
|
||||||
_parser->unloadMusic();
|
|
||||||
clear();
|
clear();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,8 @@ namespace Scumm {
|
||||||
*/
|
*/
|
||||||
class MidiParser_EUP : public MidiParser {
|
class MidiParser_EUP : public MidiParser {
|
||||||
protected:
|
protected:
|
||||||
|
byte _instruments[6][50]; // Two extra bytes for SysEx ID and channel #
|
||||||
|
byte _channel_instr[16];
|
||||||
struct {
|
struct {
|
||||||
byte *enable;
|
byte *enable;
|
||||||
int8 *channel;
|
int8 *channel;
|
||||||
|
@ -69,14 +71,22 @@ void MidiParser_EUP::parseNextEvent (EventInfo &info) {
|
||||||
// program changes to get a reasonable "one-size-
|
// program changes to get a reasonable "one-size-
|
||||||
// fits-all" sound until we actually support the
|
// fits-all" sound until we actually support the
|
||||||
// FM synthesis capabilities of FM Towns.
|
// FM synthesis capabilities of FM Towns.
|
||||||
if (_presend) {
|
for (; _presend < 32; ++_presend) {
|
||||||
--_presend;
|
if (_channel_instr[_presend >> 1] == 0xFF) continue;
|
||||||
info.start = pos;
|
info.start = pos;
|
||||||
info.delta = 0;
|
info.delta = 0;
|
||||||
info.event = ((_presend & 1) ? 0xB0 : 0xC0) | (_presend >> 1);
|
if (_presend & 1) {
|
||||||
info.basic.param1 = ((_presend & 1) ? 7 : 0x38);
|
info.event = 0xB0;
|
||||||
info.basic.param2 = ((_presend & 1) ? 127 : 0);
|
info.basic.param1 = 7;
|
||||||
_presend = (_presend + 2) % 32;
|
info.basic.param2 = 127;
|
||||||
|
} else {
|
||||||
|
byte *data = &_instruments[_channel_instr[_presend >> 1]][0];
|
||||||
|
data[1] = _presend >> 1;
|
||||||
|
info.event = 0xF0;
|
||||||
|
info.ext.data = data;
|
||||||
|
info.length = 48;
|
||||||
|
}
|
||||||
|
++_presend;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +99,17 @@ void MidiParser_EUP::parseNextEvent (EventInfo &info) {
|
||||||
channel = cmd & 0x0F;
|
channel = cmd & 0x0F;
|
||||||
uint16 tick = (pos[2] | ((uint16) pos[3] << 7)) + _base_tick;
|
uint16 tick = (pos[2] | ((uint16) pos[3] << 7)) + _base_tick;
|
||||||
int note = (int) pos[4] + _presets.transpose[preset];
|
int note = (int) pos[4] + _presets.transpose[preset];
|
||||||
int volume = (int) pos[5] + _presets.volume[preset];
|
int volume = (int) pos[5];
|
||||||
|
// HACK: Loom-Towns distaff tracks seem to
|
||||||
|
// contain zero-volume note events, so change
|
||||||
|
// those to full volume.
|
||||||
|
if (!volume)
|
||||||
|
volume = 127;
|
||||||
|
volume += _presets.volume[preset];
|
||||||
|
if (volume > 127)
|
||||||
|
volume = 127;
|
||||||
|
else if (volume < 0)
|
||||||
|
volume = 0;
|
||||||
pos += 6;
|
pos += 6;
|
||||||
if (_presets.enable[preset]) {
|
if (_presets.enable[preset]) {
|
||||||
uint16 duration = pos[1] | (pos[2] << 4);
|
uint16 duration = pos[1] | (pos[2] << 4);
|
||||||
|
@ -148,7 +168,12 @@ bool MidiParser_EUP::loadMusic (byte *data, uint32 size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
byte numInstruments = pos[16];
|
byte numInstruments = pos[16];
|
||||||
pos += (16 + 2 + numInstruments * 48);
|
pos += 16 + 2;
|
||||||
|
for (int i = 0; i < numInstruments; ++i) {
|
||||||
|
_instruments[i][0] = 0x7C;
|
||||||
|
memcpy (&_instruments[i][2], pos, 48);
|
||||||
|
pos += 48;
|
||||||
|
}
|
||||||
|
|
||||||
// Load the prest pointers
|
// Load the prest pointers
|
||||||
_presets.enable = pos;
|
_presets.enable = pos;
|
||||||
|
@ -161,6 +186,10 @@ bool MidiParser_EUP::loadMusic (byte *data, uint32 size) {
|
||||||
pos += 32;
|
pos += 32;
|
||||||
|
|
||||||
pos += 8; // Unknown bytes
|
pos += 8; // Unknown bytes
|
||||||
|
for (i = 0; i < 16; ++i)
|
||||||
|
_channel_instr[i] = 0xFF;
|
||||||
|
for (i = 0; i < 6; ++i)
|
||||||
|
_channel_instr[pos[i]] = i;
|
||||||
pos += 6; // Instrument-to-channel mapping (not supported yet)
|
pos += 6; // Instrument-to-channel mapping (not supported yet)
|
||||||
pos += 4; // Skip the music size for now.
|
pos += 4; // Skip the music size for now.
|
||||||
pos++; // Unknown byte
|
pos++; // Unknown byte
|
||||||
|
@ -183,7 +212,7 @@ bool MidiParser_EUP::loadMusic (byte *data, uint32 size) {
|
||||||
|
|
||||||
void MidiParser_EUP::resetTracking() {
|
void MidiParser_EUP::resetTracking() {
|
||||||
MidiParser::resetTracking();
|
MidiParser::resetTracking();
|
||||||
_presend = 1;
|
_presend = 0;
|
||||||
_base_tick = 0;
|
_base_tick = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,15 +92,15 @@ static const TargetSettings scumm_settings[] = {
|
||||||
/* Scumm Version 3 */
|
/* Scumm Version 3 */
|
||||||
{"indy3EGA", "Indiana Jones and the Last Crusade", GID_INDY3, 3, MDT_PCSPK | MDT_ADLIB,
|
{"indy3EGA", "Indiana Jones and the Last Crusade", GID_INDY3, 3, MDT_PCSPK | MDT_ADLIB,
|
||||||
GF_SMALL_HEADER | GF_SMALL_NAMES | GF_NO_SCALING | GF_USE_KEY | GF_16COLOR | GF_OLD_BUNDLE, "00.LFL"},
|
GF_SMALL_HEADER | GF_SMALL_NAMES | GF_NO_SCALING | GF_USE_KEY | GF_16COLOR | GF_OLD_BUNDLE, "00.LFL"},
|
||||||
{"indy3Towns", "Indiana Jones and the Last Crusade (FM Towns)", GID_INDY3, 3, MDT_ADLIB,
|
{"indy3Towns", "Indiana Jones and the Last Crusade (FM Towns)", GID_INDY3, 3, MDT_TOWNS,
|
||||||
GF_SMALL_HEADER | GF_SMALL_NAMES | GF_NO_SCALING | GF_OLD256 | GF_FEW_LOCALS | GF_FMTOWNS | GF_AUDIOTRACKS, "00.LFL"},
|
GF_SMALL_HEADER | GF_SMALL_NAMES | GF_NO_SCALING | GF_OLD256 | GF_FEW_LOCALS | GF_FMTOWNS | GF_AUDIOTRACKS, "00.LFL"},
|
||||||
{"indy3", "Indiana Jones and the Last Crusade (256)", GID_INDY3, 3, MDT_PCSPK | MDT_ADLIB,
|
{"indy3", "Indiana Jones and the Last Crusade (256)", GID_INDY3, 3, MDT_PCSPK | MDT_ADLIB,
|
||||||
GF_SMALL_HEADER | GF_SMALL_NAMES | GF_NO_SCALING | GF_OLD256 | GF_FEW_LOCALS, "00.LFL"},
|
GF_SMALL_HEADER | GF_SMALL_NAMES | GF_NO_SCALING | GF_OLD256 | GF_FEW_LOCALS, "00.LFL"},
|
||||||
{"zak256", "Zak McKracken and the Alien Mindbenders (256)", GID_ZAK256, 3, MDT_ADLIB,
|
{"zak256", "Zak McKracken and the Alien Mindbenders (256)", GID_ZAK256, 3, MDT_TOWNS,
|
||||||
GF_SMALL_HEADER | GF_SMALL_NAMES | GF_NO_SCALING | GF_OLD256 | GF_FMTOWNS | GF_AUDIOTRACKS, "00.LFL"},
|
GF_SMALL_HEADER | GF_SMALL_NAMES | GF_NO_SCALING | GF_OLD256 | GF_FMTOWNS | GF_AUDIOTRACKS, "00.LFL"},
|
||||||
{"loom", "Loom", GID_LOOM, 3, MDT_PCSPK | MDT_ADLIB | MDT_NATIVE,
|
{"loom", "Loom", GID_LOOM, 3, MDT_PCSPK | MDT_ADLIB | MDT_NATIVE,
|
||||||
GF_SMALL_HEADER | GF_SMALL_NAMES | GF_NO_SCALING | GF_USE_KEY | GF_16COLOR | GF_OLD_BUNDLE, "00.LFL"},
|
GF_SMALL_HEADER | GF_SMALL_NAMES | GF_NO_SCALING | GF_USE_KEY | GF_16COLOR | GF_OLD_BUNDLE, "00.LFL"},
|
||||||
{"loomTowns", "Loom (FM Towns)", GID_LOOM, 3, MDT_ADLIB,
|
{"loomTowns", "Loom (FM Towns)", GID_LOOM, 3, MDT_TOWNS,
|
||||||
GF_SMALL_HEADER | GF_SMALL_NAMES | GF_NO_SCALING | GF_OLD256 | GF_FMTOWNS | GF_AUDIOTRACKS, "00.LFL"},
|
GF_SMALL_HEADER | GF_SMALL_NAMES | GF_NO_SCALING | GF_OLD256 | GF_FMTOWNS | GF_AUDIOTRACKS, "00.LFL"},
|
||||||
|
|
||||||
/* Scumm Version 4 */
|
/* Scumm Version 4 */
|
||||||
|
@ -696,6 +696,8 @@ ScummEngine::ScummEngine(GameDetector *detector, OSystem *syst)
|
||||||
_imuse->property(IMuse::PROP_LIMIT_PLAYERS, 1);
|
_imuse->property(IMuse::PROP_LIMIT_PLAYERS, 1);
|
||||||
_imuse->property(IMuse::PROP_RECYCLE_PLAYERS, 1);
|
_imuse->property(IMuse::PROP_RECYCLE_PLAYERS, 1);
|
||||||
}
|
}
|
||||||
|
if (_features & GF_FMTOWNS)
|
||||||
|
_imuse->property(IMuse::PROP_DIRECT_PASSTHROUGH, 1);
|
||||||
_imuse->set_music_volume(_sound->_sound_volume_music);
|
_imuse->set_music_volume(_sound->_sound_volume_music);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@ static const struct MidiDriverDescription midiDrivers[] = {
|
||||||
{"adlib", "Adlib", MD_ADLIB},
|
{"adlib", "Adlib", MD_ADLIB},
|
||||||
{"pcspk", "PC Speaker", MD_PCSPK},
|
{"pcspk", "PC Speaker", MD_PCSPK},
|
||||||
{"pcjr", "IBM PCjr", MD_PCJR},
|
{"pcjr", "IBM PCjr", MD_PCJR},
|
||||||
|
{"towns", "FM Towns", MD_TOWNS},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__PALM_OS__)
|
#if defined(__PALM_OS__)
|
||||||
|
|
|
@ -44,8 +44,8 @@ enum {
|
||||||
MD_ADLIB = 10,
|
MD_ADLIB = 10,
|
||||||
MD_PCSPK = 11,
|
MD_PCSPK = 11,
|
||||||
MD_PCJR = 12,
|
MD_PCJR = 12,
|
||||||
|
MD_TOWNS = 13,
|
||||||
MD_YPA1 = 100 // palmos
|
MD_YPA1 = 14 // PalmOS
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -144,16 +144,16 @@ public:
|
||||||
|
|
||||||
// Control Change messages
|
// Control Change messages
|
||||||
virtual void controlChange (byte control, byte value) = 0;
|
virtual void controlChange (byte control, byte value) = 0;
|
||||||
virtual void modulationWheel (byte value) = 0;
|
virtual void modulationWheel (byte value) { controlChange (1, value); }
|
||||||
virtual void volume (byte value) = 0;
|
virtual void volume (byte value) { controlChange (7, value); }
|
||||||
virtual void panPosition (byte value) = 0;
|
virtual void panPosition (byte value) { controlChange (10, value); }
|
||||||
virtual void pitchBendFactor (byte value) = 0;
|
virtual void pitchBendFactor (byte value) = 0;
|
||||||
virtual void detune (byte value) = 0;
|
virtual void detune (byte value) { controlChange (17, value); }
|
||||||
virtual void priority (byte value) = 0;
|
virtual void priority (byte value) { controlChange (18, value); }
|
||||||
virtual void sustain (bool value) = 0;
|
virtual void sustain (bool value) { controlChange (64, value ? 1 : 0); }
|
||||||
virtual void effectLevel (byte value) = 0;
|
virtual void effectLevel (byte value) { controlChange (91, value); }
|
||||||
virtual void chorusLevel (byte value) = 0;
|
virtual void chorusLevel (byte value) { controlChange (93, value); }
|
||||||
virtual void allNotesOff() = 0;
|
virtual void allNotesOff() { controlChange (123, 0); }
|
||||||
|
|
||||||
// SysEx messages
|
// SysEx messages
|
||||||
virtual void sysEx_customInstrument (uint32 type, byte *instr) = 0;
|
virtual void sysEx_customInstrument (uint32 type, byte *instr) = 0;
|
||||||
|
@ -169,6 +169,7 @@ extern MidiDriver *MidiDriver_QT_create();
|
||||||
extern MidiDriver *MidiDriver_CORE_create();
|
extern MidiDriver *MidiDriver_CORE_create();
|
||||||
extern MidiDriver *MidiDriver_ETUDE_create();
|
extern MidiDriver *MidiDriver_ETUDE_create();
|
||||||
extern MidiDriver *MidiDriver_ALSA_create();
|
extern MidiDriver *MidiDriver_ALSA_create();
|
||||||
|
extern MidiDriver *MidiDriver_YM2612_create(SoundMixer *mixer);
|
||||||
extern MidiDriver *MidiDriver_YamahaPa1_create();
|
extern MidiDriver *MidiDriver_YamahaPa1_create();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -59,16 +59,7 @@ public:
|
||||||
|
|
||||||
// Control Change messages
|
// Control Change messages
|
||||||
void controlChange (byte control, byte value);
|
void controlChange (byte control, byte value);
|
||||||
void modulationWheel (byte value) { controlChange (1, value); }
|
|
||||||
void volume (byte value) { controlChange (7, value); }
|
|
||||||
void panPosition (byte value) { controlChange (10, value); }
|
|
||||||
void pitchBendFactor (byte value);
|
void pitchBendFactor (byte value);
|
||||||
void detune (byte value) { controlChange (17, value); }
|
|
||||||
void priority (byte value) { controlChange (18, value); }
|
|
||||||
void sustain (bool value) { controlChange (64, value ? 1 : 0); }
|
|
||||||
void effectLevel (byte value) { controlChange (91, value); }
|
|
||||||
void chorusLevel (byte value) { controlChange (93, value); }
|
|
||||||
void allNotesOff() { controlChange (123, 0); }
|
|
||||||
|
|
||||||
// SysEx messages
|
// SysEx messages
|
||||||
void sysEx_customInstrument (uint32 type, byte *instr);
|
void sysEx_customInstrument (uint32 type, byte *instr);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue