aboutsummaryrefslogtreecommitdiff
path: root/engines/cine
diff options
context:
space:
mode:
Diffstat (limited to 'engines/cine')
-rw-r--r--engines/cine/cine.cpp4
-rw-r--r--engines/cine/detection.cpp2
-rw-r--r--engines/cine/detection_tables.h68
-rw-r--r--engines/cine/main_loop.cpp2
-rw-r--r--engines/cine/saveload.cpp2
-rw-r--r--engines/cine/sound.cpp269
-rw-r--r--engines/cine/various.cpp5
7 files changed, 282 insertions, 70 deletions
diff --git a/engines/cine/cine.cpp b/engines/cine/cine.cpp
index 6f34b0f860..6b94c33c31 100644
--- a/engines/cine/cine.cpp
+++ b/engines/cine/cine.cpp
@@ -141,11 +141,11 @@ void CineEngine::initialize() {
// Resize zone data table to its correct size and reset all its elements
g_cine->_zoneData.resize(NUM_MAX_ZONE);
- Common::set_to(g_cine->_zoneData.begin(), g_cine->_zoneData.end(), 0);
+ Common::fill(g_cine->_zoneData.begin(), g_cine->_zoneData.end(), 0);
// Resize zone query table to its correct size and reset all its elements
g_cine->_zoneQuery.resize(NUM_MAX_ZONE);
- Common::set_to(g_cine->_zoneQuery.begin(), g_cine->_zoneQuery.end(), 0);
+ Common::fill(g_cine->_zoneQuery.begin(), g_cine->_zoneQuery.end(), 0);
_timerDelayMultiplier = 12; // Set default speed
setupOpcodes();
diff --git a/engines/cine/detection.cpp b/engines/cine/detection.cpp
index ba0251520b..ed656682ee 100644
--- a/engines/cine/detection.cpp
+++ b/engines/cine/detection.cpp
@@ -65,7 +65,7 @@ class CineMetaEngine : public AdvancedMetaEngine {
public:
CineMetaEngine() : AdvancedMetaEngine(Cine::gameDescriptions, sizeof(Cine::CINEGameDescription), cineGames) {
_singleid = "cine";
- _guioptions = Common::GUIO_NOSPEECH | Common::GUIO_NOMIDI;
+ _guioptions = GUIO1(GUIO_NOSPEECH);
}
virtual GameDescriptor findGame(const char *gameid) const {
diff --git a/engines/cine/detection_tables.h b/engines/cine/detection_tables.h
index 4b293deb62..0ec2768bae 100644
--- a/engines/cine/detection_tables.h
+++ b/engines/cine/detection_tables.h
@@ -22,8 +22,6 @@
namespace Cine {
-using Common::GUIO_NONE;
-
static const CINEGameDescription gameDescriptions[] = {
{
{
@@ -33,7 +31,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO0()
},
GType_FW,
0,
@@ -53,7 +51,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::EN_USA,
Common::kPlatformPC,
ADGF_CD,
- GUIO_NONE
+ GUIO0()
},
GType_FW,
GF_CD | GF_CRYPTED_BOOT_PRC,
@@ -68,7 +66,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO0()
},
GType_FW,
0,
@@ -82,7 +80,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO0()
},
GType_FW,
GF_ALT_FONT,
@@ -96,7 +94,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO0()
},
GType_FW,
GF_ALT_FONT,
@@ -110,7 +108,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO0()
},
GType_FW,
0,
@@ -124,7 +122,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO1(GUIO_NOMIDI)
},
GType_FW,
0,
@@ -138,7 +136,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::EN_USA,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO1(GUIO_NOMIDI)
},
GType_FW,
0,
@@ -152,7 +150,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO1(GUIO_NOMIDI)
},
GType_FW,
GF_ALT_FONT,
@@ -166,7 +164,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO1(GUIO_NOMIDI)
},
GType_FW,
0,
@@ -180,7 +178,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO1(GUIO_NOMIDI)
},
GType_FW,
0,
@@ -194,7 +192,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO1(GUIO_NOMIDI)
},
GType_FW,
0,
@@ -212,7 +210,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAmiga,
ADGF_DEMO,
- GUIO_NONE
+ GUIO1(GUIO_NOMIDI)
},
GType_FW,
0,
@@ -226,7 +224,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAtariST,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO1(GUIO_NOMIDI)
},
GType_FW,
0,
@@ -240,7 +238,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformAtariST,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO1(GUIO_NOMIDI)
},
GType_FW,
0,
@@ -254,7 +252,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::EN_GRB,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO0()
},
GType_OS,
0,
@@ -270,7 +268,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::EN_GRB,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO0()
},
GType_OS,
0,
@@ -284,7 +282,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::EN_USA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO0()
},
GType_OS,
0,
@@ -298,7 +296,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::EN_USA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO0()
},
GType_OS,
GF_CD,
@@ -312,7 +310,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO0()
},
GType_OS,
0,
@@ -326,7 +324,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO0()
},
GType_OS,
0,
@@ -344,7 +342,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO0()
},
GType_OS,
GF_CD,
@@ -358,7 +356,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO0()
},
GType_OS,
0,
@@ -372,7 +370,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO0()
},
GType_OS,
0,
@@ -386,7 +384,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::EN_GRB,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO1(GUIO_NOMIDI)
},
GType_OS,
0,
@@ -400,7 +398,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::EN_GRB,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO1(GUIO_NOMIDI)
},
GType_OS,
0,
@@ -414,7 +412,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::EN_USA,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO1(GUIO_NOMIDI)
},
GType_OS,
0,
@@ -428,7 +426,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO1(GUIO_NOMIDI)
},
GType_OS,
0,
@@ -442,7 +440,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO1(GUIO_NOMIDI)
},
GType_OS,
0,
@@ -456,7 +454,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO1(GUIO_NOMIDI)
},
GType_OS,
0,
@@ -470,7 +468,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::EN_GRB,
Common::kPlatformAmiga,
ADGF_DEMO,
- GUIO_NONE
+ GUIO1(GUIO_NOMIDI)
},
GType_OS,
GF_DEMO,
@@ -484,7 +482,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::EN_GRB,
Common::kPlatformAtariST,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO1(GUIO_NOMIDI)
},
GType_OS,
0,
@@ -498,7 +496,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformAtariST,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO1(GUIO_NOMIDI)
},
GType_OS,
0,
diff --git a/engines/cine/main_loop.cpp b/engines/cine/main_loop.cpp
index bb0545db72..971830ce8f 100644
--- a/engines/cine/main_loop.cpp
+++ b/engines/cine/main_loop.cpp
@@ -345,7 +345,7 @@ void CineEngine::mainLoop(int bootScriptIdx) {
// Clear the zoneQuery table (Operation Stealth specific)
if (g_cine->getGameType() == Cine::GType_OS) {
- Common::set_to(g_cine->_zoneQuery.begin(), g_cine->_zoneQuery.end(), 0);
+ Common::fill(g_cine->_zoneQuery.begin(), g_cine->_zoneQuery.end(), 0);
}
if (g_cine->getGameType() == Cine::GType_OS) {
diff --git a/engines/cine/saveload.cpp b/engines/cine/saveload.cpp
index 0ea1a23e8f..223099a587 100644
--- a/engines/cine/saveload.cpp
+++ b/engines/cine/saveload.cpp
@@ -1034,7 +1034,7 @@ void loadResourcesFromSave(Common::SeekableReadStream &fHandle, enum CineSaveGam
}
// Alright, the animation entry looks to be valid so let's start handling it...
- if (strcmp(currentPartName, name)) {
+ if (strcmp(currentPartName, name) != 0) {
closePart();
loadPart(name);
}
diff --git a/engines/cine/sound.cpp b/engines/cine/sound.cpp
index 0c3541fae7..0328466e76 100644
--- a/engines/cine/sound.cpp
+++ b/engines/cine/sound.cpp
@@ -25,12 +25,16 @@
#include "common/memstream.h"
#include "common/system.h"
#include "common/textconsole.h"
+#include "common/timer.h"
+#include "common/mutex.h"
+#include "common/config-manager.h"
#include "cine/cine.h"
#include "cine/sound.h"
#include "audio/audiostream.h"
#include "audio/fmopl.h"
+#include "audio/mididrv.h"
#include "audio/decoders/raw.h"
#include "audio/mods/soundfx.h"
@@ -48,14 +52,13 @@ public:
virtual void playSample(const byte *data, int size, int channel, int volume) = 0;
virtual void stopAll() = 0;
virtual const char *getInstrumentExtension() const { return ""; }
+ virtual void notifyInstrumentLoad(const byte *data, int size, int channel) {}
- void setUpdateCallback(UpdateCallback upCb, void *ref);
+ virtual void setUpdateCallback(UpdateCallback upCb, void *ref) = 0;
void resetChannel(int channel);
void findNote(int freq, int *note, int *oct) const;
protected:
- UpdateCallback _upCb;
- void *_upRef;
static const int _noteTable[];
static const int _noteTableCount;
@@ -104,6 +107,7 @@ public:
virtual ~AdLibSoundDriver();
// PCSoundDriver interface
+ virtual void setUpdateCallback(UpdateCallback upCb, void *ref);
virtual void setupChannel(int channel, const byte *data, int instrument, int volume);
virtual void stopChannel(int channel);
virtual void stopAll();
@@ -121,6 +125,9 @@ public:
virtual void loadInstrument(const byte *data, AdLibSoundInstrument *asi) = 0;
protected:
+ UpdateCallback _upCb;
+ void *_upRef;
+
FM_OPL *_opl;
int _sampleRate;
Audio::Mixer *_mixer;
@@ -177,6 +184,30 @@ public:
virtual void playSample(const byte *data, int size, int channel, int volume);
};
+// (Future Wars) MIDI driver
+class MidiSoundDriverH32 : public PCSoundDriver {
+public:
+ MidiSoundDriverH32(MidiDriver *output);
+ ~MidiSoundDriverH32();
+
+ virtual void setUpdateCallback(UpdateCallback upCb, void *ref);
+ virtual void setupChannel(int channel, const byte *data, int instrument, int volume);
+ virtual void setChannelFrequency(int channel, int frequency);
+ virtual void stopChannel(int channel);
+ virtual void playSample(const byte *data, int size, int channel, int volume);
+ virtual void stopAll() {}
+ virtual const char *getInstrumentExtension() const { return ".H32"; }
+ virtual void notifyInstrumentLoad(const byte *data, int size, int channel);
+
+private:
+ MidiDriver *_output;
+ UpdateCallback _callback;
+ Common::Mutex _mutex;
+
+ void writeInstrument(int offset, const byte *data, int size);
+ void selectInstrument(int channel, int unk, int instrument, int volume);
+};
+
class PCSoundFxPlayer {
public:
@@ -213,23 +244,35 @@ private:
byte *_sfxData;
byte *_instrumentsData[NUM_INSTRUMENTS];
PCSoundDriver *_driver;
+ Common::Mutex _mutex;
};
-void PCSoundDriver::setUpdateCallback(UpdateCallback upCb, void *ref) {
- _upCb = upCb;
- _upRef = ref;
-}
-
void PCSoundDriver::findNote(int freq, int *note, int *oct) const {
- *note = _noteTableCount - 1;
- for (int i = 0; i < _noteTableCount; ++i) {
- if (_noteTable[i] <= freq) {
+ if (freq > 0x777)
+ *oct = 0;
+ else if (freq > 0x3BB)
+ *oct = 1;
+ else if (freq > 0x1DD)
+ *oct = 2;
+ else if (freq > 0x0EE)
+ *oct = 3;
+ else if (freq > 0x077)
+ *oct = 4;
+ else if (freq > 0x03B)
+ *oct = 5;
+ else if (freq > 0x01D)
+ *oct = 6;
+ else
+ *oct = 7;
+
+ *note = 11;
+ for (int i = 0; i < 12; ++i) {
+ if (_noteTable[*oct * 12 + i] <= freq) {
*note = i;
break;
}
}
- *oct = *note / 12;
}
void PCSoundDriver::resetChannel(int channel) {
@@ -252,6 +295,11 @@ AdLibSoundDriver::~AdLibSoundDriver() {
OPLDestroy(_opl);
}
+void AdLibSoundDriver::setUpdateCallback(UpdateCallback upCb, void *ref) {
+ _upCb = upCb;
+ _upRef = ref;
+}
+
void AdLibSoundDriver::setupChannel(int channel, const byte *data, int instrument, int volume) {
assert(channel < 4);
if (data) {
@@ -441,12 +489,11 @@ void AdLibSoundDriverINS::setChannelFrequency(int channel, int frequency) {
if (ins->mode == 0 || ins->channel == 6) {
int freq, note, oct;
findNote(frequency, &note, &oct);
- if (channel == 6) {
- note %= 12;
- }
+ if (channel == 6)
+ oct = 0;
freq = _freqTable[note % 12];
OPLWriteReg(_opl, 0xA0 | channel, freq);
- freq = ((note / 12) << 2) | ((freq & 0x300) >> 8);
+ freq = (oct << 2) | ((freq & 0x300) >> 8);
if (ins->mode == 0) {
freq |= 0x20;
}
@@ -509,14 +556,16 @@ void AdLibSoundDriverADL::setChannelFrequency(int channel, int frequency) {
findNote(frequency, &note, &oct);
if (ins->amDepth) {
note = ins->amDepth;
+ oct = note / 12;
}
if (note < 0) {
note = 0;
+ oct = 0;
}
freq = _freqTable[note % 12];
OPLWriteReg(_opl, 0xA0 | channel, freq);
- freq = ((note / 12) << 2) | ((freq & 0x300) >> 8);
+ freq = (oct << 2) | ((freq & 0x300) >> 8);
if (ins->mode == 0) {
freq |= 0x20;
}
@@ -564,8 +613,147 @@ void AdLibSoundDriverADL::playSample(const byte *data, int size, int channel, in
}
}
+MidiSoundDriverH32::MidiSoundDriverH32(MidiDriver *output)
+ : _output(output), _callback(0), _mutex() {
+}
+
+MidiSoundDriverH32::~MidiSoundDriverH32() {
+ if (_callback)
+ g_system->getTimerManager()->removeTimerProc(_callback);
+
+ _output->close();
+ delete _output;
+}
+
+void MidiSoundDriverH32::setUpdateCallback(UpdateCallback upCb, void *ref) {
+ Common::StackLock lock(_mutex);
+
+ Common::TimerManager *timer = g_system->getTimerManager();
+ assert(timer);
+
+ if (_callback)
+ timer->removeTimerProc(_callback);
+
+ _callback = upCb;
+ if (_callback)
+ timer->installTimerProc(_callback, 1000000 / 50, ref, "MidiSoundDriverH32");
+}
+
+void MidiSoundDriverH32::setupChannel(int channel, const byte *data, int instrument, int volume) {
+ Common::StackLock lock(_mutex);
+
+ if (volume < 0 || volume > 100)
+ volume = 0;
+
+ if (!data)
+ selectInstrument(channel, 0, 0, volume);
+ else if (data[0] < 0x80)
+ selectInstrument(channel, data[0] / 0x40, data[0] % 0x40, volume);
+ else
+ selectInstrument(channel, 2, instrument, volume);
+}
+
+void MidiSoundDriverH32::setChannelFrequency(int channel, int frequency) {
+ Common::StackLock lock(_mutex);
+
+ int note, oct;
+ findNote(frequency, &note, &oct);
+ note %= 12;
+ note = oct * 12 + note + 12;
+
+ _output->send(0x91 + channel, note, 0x7F);
+}
+
+void MidiSoundDriverH32::stopChannel(int channel) {
+ Common::StackLock lock(_mutex);
+
+ _output->send(0xB1 + channel, 0x7B, 0x00);
+}
+
+void MidiSoundDriverH32::playSample(const byte *data, int size, int channel, int volume) {
+ Common::StackLock lock(_mutex);
+
+ stopChannel(channel);
+
+ volume = volume * 8 / 5;
+
+ if (data[0] < 0x80) {
+ selectInstrument(channel, data[0] / 0x40, data[0] % 0x40, volume);
+ } else {
+ writeInstrument(channel * 512 + 0x80000, data + 1, 256);
+ selectInstrument(channel, 2, channel, volume);
+ }
+
+ _output->send(0x91 + channel, 12, 0x7F);
+}
+
+void MidiSoundDriverH32::notifyInstrumentLoad(const byte *data, int size, int channel) {
+ Common::StackLock lock(_mutex);
+
+ if (data[0] < 0x80 || data[0] > 0xC0)
+ return;
+
+ writeInstrument(channel * 512 + 0x80000, data + 1, size - 1);
+}
+
+void MidiSoundDriverH32::writeInstrument(int offset, const byte *data, int size) {
+ byte sysEx[254];
+
+ sysEx[0] = 0x41;
+ sysEx[1] = 0x10;
+ sysEx[2] = 0x16;
+ sysEx[3] = 0x12;
+ sysEx[4] = (offset >> 16) & 0xFF;
+ sysEx[5] = (offset >> 8) & 0xFF;
+ sysEx[6] = (offset >> 0) & 0xFF;
+ int copySize = MIN(246, size);
+ memcpy(&sysEx[7], data, copySize);
+
+ byte checkSum = 0;
+ for (int i = 0; i < copySize + 3; ++i)
+ checkSum += sysEx[4 + i];
+ sysEx[7 + copySize] = 0x80 - (checkSum & 0x7F);
+
+ _output->sysEx(sysEx, copySize + 8);
+}
+
+void MidiSoundDriverH32::selectInstrument(int channel, int unk, int instrument, int volume) {
+ const int offset = channel * 16 + 0x30000;
+
+ byte sysEx[24] = {
+ 0x41, 0x10, 0x16, 0x12,
+ 0x00, 0x00, 0x00, // offset
+ 0x00, // unk
+ 0x00, // instrument
+ 0x18, 0x32, 0x0C, 0x03, 0x01, 0x00,
+ 0x00, // volume
+ 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00 // checksum
+ };
+
+
+ sysEx[4] = (offset >> 16) & 0xFF;
+ sysEx[5] = (offset >> 8) & 0xFF;
+ sysEx[6] = (offset >> 0) & 0xFF;
+
+ sysEx[7] = unk;
+
+ sysEx[8] = instrument;
+
+ sysEx[15] = volume;
+
+ byte checkSum = 0;
+
+ for (int i = 4; i < 23; ++i)
+ checkSum += sysEx[i];
+
+ sysEx[23] = 0x80 - (checkSum & 0x7F);
+
+ _output->sysEx(sysEx, 24);
+}
+
PCSoundFxPlayer::PCSoundFxPlayer(PCSoundDriver *driver)
- : _playing(false), _driver(driver) {
+ : _playing(false), _driver(driver), _mutex() {
memset(_instrumentsData, 0, sizeof(_instrumentsData));
_sfxData = NULL;
_fadeOutCounter = 0;
@@ -573,12 +761,15 @@ PCSoundFxPlayer::PCSoundFxPlayer(PCSoundDriver *driver)
}
PCSoundFxPlayer::~PCSoundFxPlayer() {
+ Common::StackLock lock(_mutex);
+
_driver->setUpdateCallback(NULL, NULL);
stop();
}
bool PCSoundFxPlayer::load(const char *song) {
debug(9, "PCSoundFxPlayer::load('%s')", song);
+ Common::StackLock lock(_mutex);
/* stop (w/ fade out) the previous song */
while (_fadeOutCounter != 0 && _fadeOutCounter < 100) {
@@ -602,15 +793,18 @@ bool PCSoundFxPlayer::load(const char *song) {
memcpy(instrument, _sfxData + 20 + i * 30, 12);
instrument[63] = '\0';
- if (strlen(instrument) != 0) {
+ if (instrument[0] != '\0') {
char *dot = strrchr(instrument, '.');
if (dot) {
*dot = '\0';
}
strcat(instrument, _driver->getInstrumentExtension());
- _instrumentsData[i] = readBundleSoundFile(instrument);
+ uint32 instrumentSize;
+ _instrumentsData[i] = readBundleSoundFile(instrument, &instrumentSize);
if (!_instrumentsData[i]) {
warning("Unable to load soundfx instrument '%s'", instrument);
+ } else {
+ _driver->notifyInstrumentLoad(_instrumentsData[i], instrumentSize, i);
}
}
}
@@ -619,6 +813,7 @@ bool PCSoundFxPlayer::load(const char *song) {
void PCSoundFxPlayer::play() {
debug(9, "PCSoundFxPlayer::play()");
+ Common::StackLock lock(_mutex);
if (_sfxData) {
for (int i = 0; i < NUM_CHANNELS; ++i) {
_instrumentsChannelTable[i] = -1;
@@ -633,6 +828,7 @@ void PCSoundFxPlayer::play() {
}
void PCSoundFxPlayer::stop() {
+ Common::StackLock lock(_mutex);
if (_playing || _fadeOutCounter != 0) {
_fadeOutCounter = 0;
_playing = false;
@@ -645,6 +841,7 @@ void PCSoundFxPlayer::stop() {
}
void PCSoundFxPlayer::fadeOut() {
+ Common::StackLock lock(_mutex);
if (_playing) {
_fadeOutCounter = 1;
_playing = false;
@@ -656,6 +853,7 @@ void PCSoundFxPlayer::updateCallback(void *ref) {
}
void PCSoundFxPlayer::update() {
+ Common::StackLock lock(_mutex);
if (_playing || (_fadeOutCounter != 0 && _fadeOutCounter < 100)) {
++_updateTicksCounter;
if (_updateTicksCounter > _eventsDelay) {
@@ -717,12 +915,33 @@ void PCSoundFxPlayer::unload() {
PCSound::PCSound(Audio::Mixer *mixer, CineEngine *vm)
- : Sound(mixer, vm) {
- if (_vm->getGameType() == GType_FW) {
- _soundDriver = new AdLibSoundDriverINS(_mixer);
- } else {
- _soundDriver = new AdLibSoundDriverADL(_mixer);
+ : Sound(mixer, vm), _soundDriver(0) {
+
+ const MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB);
+ const MusicType musicType = MidiDriver::getMusicType(dev);
+ if (musicType == MT_MT32 || musicType == MT_GM) {
+ const bool isMT32 = (musicType == MT_MT32 || ConfMan.getBool("native_mt32"));
+ if (isMT32) {
+ MidiDriver *driver = MidiDriver::createMidi(dev);
+ if (driver && driver->open() == 0) {
+ driver->sendMT32Reset();
+ _soundDriver = new MidiSoundDriverH32(driver);
+ } else {
+ warning("Could not create MIDI output, falling back to AdLib");
+ }
+ } else {
+ warning("General MIDI output devices are not supported, falling back to AdLib");
+ }
}
+
+ if (!_soundDriver) {
+ if (_vm->getGameType() == GType_FW) {
+ _soundDriver = new AdLibSoundDriverINS(_mixer);
+ } else {
+ _soundDriver = new AdLibSoundDriverADL(_mixer);
+ }
+ }
+
_player = new PCSoundFxPlayer(_soundDriver);
}
diff --git a/engines/cine/various.cpp b/engines/cine/various.cpp
index 2f0c13740f..9b73ae1101 100644
--- a/engines/cine/various.cpp
+++ b/engines/cine/various.cpp
@@ -685,7 +685,6 @@ int16 makeMenuChoice(const CommandeType commandList[], uint16 height, uint16 X,
int16 paramY;
uint16 button;
int16 var_A;
- int16 di;
uint16 j;
int16 mouseX, mouseY;
int16 currentSelection, oldSelection;
@@ -721,8 +720,6 @@ int16 makeMenuChoice(const CommandeType commandList[], uint16 height, uint16 X,
currentSelection = 0;
- di = currentSelection * 9 + Y + 4;
-
menu->setSelection(currentSelection);
renderer->drawFrame();
@@ -772,8 +769,6 @@ int16 makeMenuChoice(const CommandeType commandList[], uint16 height, uint16 X,
hideMouse();
}
- di = currentSelection * 9 + Y + 4;
-
menu->setSelection(currentSelection);
renderer->drawFrame();