aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorRobert Göffringmann2007-03-18 14:08:34 +0000
committerRobert Göffringmann2007-03-18 14:08:34 +0000
commit3f6745a2f43fc2e017a9268c06d11e6278b5bb2f (patch)
tree05e49a0dce8a552b4137e28adb75340668b00afb /engines
parent612e7a3eeb1b1e4b6c0500b8801544e19f2d7d55 (diff)
downloadscummvm-rg350-3f6745a2f43fc2e017a9268c06d11e6278b5bb2f.tar.gz
scummvm-rg350-3f6745a2f43fc2e017a9268c06d11e6278b5bb2f.tar.bz2
scummvm-rg350-3f6745a2f43fc2e017a9268c06d11e6278b5bb2f.zip
Applied eriktorbjorn's patch for bug #1657466:
"BASS: wrong music slider behavior" and did some cleanup. svn-id: r26208
Diffstat (limited to 'engines')
-rw-r--r--engines/sky/control.cpp2
-rw-r--r--engines/sky/music/adlibchannel.cpp106
-rw-r--r--engines/sky/music/adlibchannel.h25
-rw-r--r--engines/sky/music/adlibmusic.cpp29
-rw-r--r--engines/sky/music/adlibmusic.h9
-rw-r--r--engines/sky/music/gmchannel.cpp54
-rw-r--r--engines/sky/music/gmchannel.h11
-rw-r--r--engines/sky/music/gmmusic.cpp26
-rw-r--r--engines/sky/music/gmmusic.h3
-rw-r--r--engines/sky/music/mt32music.cpp34
-rw-r--r--engines/sky/music/mt32music.h4
-rw-r--r--engines/sky/music/musicbase.cpp41
-rw-r--r--engines/sky/music/musicbase.h16
13 files changed, 183 insertions, 177 deletions
diff --git a/engines/sky/control.cpp b/engines/sky/control.cpp
index 3d34ed9e36..f90a98c865 100644
--- a/engines/sky/control.cpp
+++ b/engines/sky/control.cpp
@@ -1605,7 +1605,7 @@ void Control::delay(unsigned int amount) {
void Control::showGameQuitMsg(void) {
- _skyText->fnSetFont(1);
+ _skyText->fnSetFont(0);
uint8 *textBuf1 = (uint8 *)malloc(GAME_SCREEN_WIDTH * 14 + sizeof(dataFileHeader));
uint8 *textBuf2 = (uint8 *)malloc(GAME_SCREEN_WIDTH * 14 + sizeof(dataFileHeader));
uint8 *screenData;
diff --git a/engines/sky/music/adlibchannel.cpp b/engines/sky/music/adlibchannel.cpp
index 181c96dae6..59d144feea 100644
--- a/engines/sky/music/adlibchannel.cpp
+++ b/engines/sky/music/adlibchannel.cpp
@@ -31,10 +31,9 @@ namespace Sky {
AdlibChannel::AdlibChannel(FM_OPL *opl, uint8 *pMusicData, uint16 startOfData) {
_opl = opl;
_musicData = pMusicData;
- _channelData.startOfData = startOfData;
+ _channelData.loopPoint = startOfData;
_channelData.eventDataPtr = startOfData;
- _channelData.channelActive = 1;
- _channelData.freqDataSize = 2;
+ _channelData.channelActive = true;
_channelData.tremoVibro = 0;
_channelData.assignedInstrument = 0xFF;
_channelData.channelVolume = 0x7F;
@@ -75,20 +74,19 @@ AdlibChannel::AdlibChannel(FM_OPL *opl, uint8 *pMusicData, uint16 startOfData) {
_instrumentMap = _musicData+instrumentDataLoc;
_instruments = (InstrumentStruct*)(_instrumentMap+0x80);
+}
- _musicVolume = 0x100;
+AdlibChannel::~AdlibChannel(void) {
+ stopNote();
}
bool AdlibChannel::isActive(void) {
- return _channelData.channelActive != 0;
+ return _channelData.channelActive;
}
void AdlibChannel::updateVolume(uint16 pVolume) {
- pVolume = (pVolume * 3) >> 1;
- if (pVolume > 0x7F)
- pVolume = 0x7F;
- _musicVolume = pVolume | 128;
+ // Do nothing. The mixer handles the music volume for us.
}
/* This class uses the same area for the register mirror as the original
@@ -118,12 +116,13 @@ int32 AdlibChannel::getNextEventTime(void) {
lVal = _musicData[_channelData.eventDataPtr];
_channelData.eventDataPtr++;
retV = (retV << 7) | (lVal & 0x7F);
- if (!(lVal & 0x80)) break;
+ if (!(lVal & 0x80))
+ break;
}
- if (lVal & 0x80) { // should never happen
- return -1;
- } else return retV;
-
+ if (lVal & 0x80) {
+ return -1; // should never happen
+ } else
+ return retV;
}
uint8 AdlibChannel::process(uint16 aktTime) {
@@ -153,27 +152,19 @@ uint8 AdlibChannel::process(uint16 aktTime) {
case 5: com90_getFreqOffset(); break;
case 6: com90_getChannelVolume(); break;
case 7: com90_getTremoVibro(); break;
- case 8: com90_rewindMusic(); break;
+ case 8: com90_loopMusic(); break;
case 9: com90_keyOff(); break;
- case 12: com90_setStartOfData(); break;
- case 4: //com90_dummy();
- case 10: //com90_error();
- case 11: //com90_doLodsb();
- case 13: //com90_do_two_Lodsb();
- error("Channel: dummy music routine 0x%02X was called",opcode);
- _channelData.channelActive = 0;
- break;
+ case 12: com90_setLoopPoint(); break;
+
default:
- // these opcodes aren't implemented in original music driver
- error("Channel: Not existent routine 0x%02X was called",opcode);
- _channelData.channelActive = 0;
+ error("AdlibChannel: Unknown music opcode 0x%02X", opcode);
break;
}
} else {
// new adlib channel assignment
- _channelData.adlibChannelNumber = opcode&0xF;
- _channelData.adlibReg1 = _registerTable[(opcode&0xF)<<1];
- _channelData.adlibReg2 = _registerTable[((opcode&0xF)<<1)|1];
+ _channelData.adlibChannelNumber = opcode & 0xF;
+ _channelData.adlibReg1 = _registerTable[((opcode & 0xF) << 1) | 0];
+ _channelData.adlibReg2 = _registerTable[((opcode & 0xF) << 1) | 1];
}
} else {
_channelData.lastCommand = opcode;
@@ -186,7 +177,8 @@ uint8 AdlibChannel::process(uint16 aktTime) {
opcode = _musicData[_channelData.eventDataPtr];
_channelData.eventDataPtr++;
setupChannelVolume(opcode);
- } else _channelData.eventDataPtr++;
+ } else
+ _channelData.eventDataPtr++;
}
if (_channelData.channelActive)
_channelData.nextEventTime += getNextEventTime();
@@ -220,20 +212,19 @@ void AdlibChannel::setupChannelVolume(uint8 volume) {
uint8 resultOp;
uint32 resVol = ((volume + 1) * (_channelData.instrumentData->totOutLev_Op2 + 1)) << 1;
resVol &= 0xFFFF;
- resVol *= (_channelData.channelVolume+1)<<1;
- resVol >>= 8;
- resVol *= _musicVolume;
+ resVol *= (_channelData.channelVolume + 1) << 1;
resVol >>= 16;
+ assert(resVol < 0x81);
resultOp = ((_channelData.instrumentData->scalingLevel << 6) & 0xC0) | _opOutputTable[resVol];
setRegister(0x40 | _channelData.adlibReg2, resultOp);
if (_channelData.instrumentData->feedBack & 1) {
resVol = ((volume + 1) * (_channelData.instrumentData->totOutLev_Op1 + 1)) << 1;
resVol &= 0xFFFF;
- resVol *= (_channelData.channelVolume + 1)<<1;
- resVol >>= 8;
- resVol *= (_musicVolume & 0xFF);
+ resVol *= (_channelData.channelVolume + 1) << 1;
resVol >>= 16;
- } else resVol = _channelData.instrumentData->totOutLev_Op1;
+ } else
+ resVol = _channelData.instrumentData->totOutLev_Op1;
+ assert(resVol < 0x81);
resultOp = ((_channelData.instrumentData->scalingLevel << 2) & 0xC0) | _opOutputTable[resVol];
setRegister(0x40 | _channelData.adlibReg1, resultOp);
}
@@ -251,20 +242,15 @@ void AdlibChannel::adlibSetupInstrument(void) {
setRegister(0x20 | _channelData.adlibReg2, _channelData.instrumentData->ampMod_Op2);
}
-#ifdef SCUMM_BIG_ENDIAN
-#define ENDIAN16(x) ((x >> 8) | ((x & 0xFF) << 8))
-#else
-#define ENDIAN16(x) (x)
-#endif
-
uint16 AdlibChannel::getNextNote(uint8 param) {
int16 freqIndex = ((int16)_channelData.freqOffset) - 0x40;
- if (freqIndex >= 0x3F) freqIndex++;
- freqIndex *= _channelData.freqDataSize;
- freqIndex += param<<6;
- uint16 freqData = ENDIAN16(_frequenceTable[freqIndex % 0x300]);
- if ((freqIndex%0x300 >= 0x1C0) || (freqIndex/0x300 > 0)) {
+ if (freqIndex >= 0x3F)
+ freqIndex++;
+ freqIndex *= 2;
+ freqIndex += param << 6;
+ uint16 freqData = FROM_LE_16(_frequenceTable[freqIndex % 0x300]);
+ if ((freqIndex % 0x300 >= 0x1C0) || (freqIndex / 0x300 > 0)) {
return (((freqIndex / 0x300) - 1) << 10) + (freqData & 0x7FF);
} else {
// looks like a bug. dunno why. It's what the ASM code says.
@@ -284,7 +270,7 @@ void AdlibChannel::com90_caseNoteOff(void) {
void AdlibChannel::com90_stopChannel(void) {
stopNote();
- _channelData.channelActive = 0;
+ _channelData.channelActive = false;
}
void AdlibChannel::com90_setupInstrument(void) {
@@ -298,16 +284,12 @@ void AdlibChannel::com90_setupInstrument(void) {
}
uint8 AdlibChannel::com90_updateTempo(void) {
-
- uint8 retV = _musicData[_channelData.eventDataPtr];
- _channelData.eventDataPtr++;
- return retV;
+ return _musicData[_channelData.eventDataPtr++];
}
void AdlibChannel::com90_getFreqOffset(void) {
- _channelData.freqOffset = _musicData[_channelData.eventDataPtr];
- _channelData.eventDataPtr++;
+ _channelData.freqOffset = _musicData[_channelData.eventDataPtr++];
if (_channelData.note & 0x20) {
uint16 nextNote = getNextNote(
_channelData.lastCommand - 0x18 + _channelData.instrumentData->bindedEffect);
@@ -319,19 +301,17 @@ void AdlibChannel::com90_getFreqOffset(void) {
void AdlibChannel::com90_getChannelVolume(void) {
- _channelData.channelVolume = _musicData[_channelData.eventDataPtr];
- _channelData.eventDataPtr++;
+ _channelData.channelVolume = _musicData[_channelData.eventDataPtr++];
}
void AdlibChannel::com90_getTremoVibro(void) {
- _channelData.tremoVibro = _musicData[_channelData.eventDataPtr];
- _channelData.eventDataPtr++;
+ _channelData.tremoVibro = _musicData[_channelData.eventDataPtr++];
}
-void AdlibChannel::com90_rewindMusic(void) {
+void AdlibChannel::com90_loopMusic(void) {
- _channelData.eventDataPtr = _channelData.startOfData;
+ _channelData.eventDataPtr = _channelData.loopPoint;
}
void AdlibChannel::com90_keyOff(void) {
@@ -339,9 +319,9 @@ void AdlibChannel::com90_keyOff(void) {
stopNote();
}
-void AdlibChannel::com90_setStartOfData(void) {
+void AdlibChannel::com90_setLoopPoint(void) {
- _channelData.startOfData = _channelData.eventDataPtr;
+ _channelData.loopPoint = _channelData.eventDataPtr;
}
} // End of namespace Sky
diff --git a/engines/sky/music/adlibchannel.h b/engines/sky/music/adlibchannel.h
index 16f8f82b17..5dbf5564f5 100644
--- a/engines/sky/music/adlibchannel.h
+++ b/engines/sky/music/adlibchannel.h
@@ -1,5 +1,5 @@
/* ScummVM - Scumm Interpreter
- * Copyright (C) 2003-2006 The ScummVM project
+ * Copyright (C) 2003-2007 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -43,10 +43,10 @@ typedef struct {
typedef struct {
uint16 eventDataPtr;
int32 nextEventTime;
- uint16 startOfData;
+ uint16 loopPoint;
uint8 adlibChannelNumber;
uint8 lastCommand;
- uint8 channelActive;
+ bool channelActive;
uint8 note;
uint8 adlibReg1, adlibReg2;
InstrumentStruct *instrumentData;
@@ -54,7 +54,6 @@ typedef struct {
uint8 channelVolume;
uint8 padding; // field_12 / not used by original driver
uint8 tremoVibro;
- uint8 freqDataSize;
uint8 freqOffset;
uint16 frequency;
} AdlibChannelType;
@@ -62,42 +61,44 @@ typedef struct {
class AdlibChannel : public ChannelBase {
public:
AdlibChannel (FM_OPL *opl, uint8 *pMusicData, uint16 startOfData);
- virtual void stopNote(void);
+ virtual ~AdlibChannel(void);
virtual uint8 process(uint16 aktTime);
virtual void updateVolume(uint16 pVolume);
virtual bool isActive(void);
private:
FM_OPL *_opl;
uint8 *_musicData;
- uint16 _musicVolume;
AdlibChannelType _channelData;
- //-
+
InstrumentStruct *_instruments;
uint16 *_frequenceTable;
uint8 *_instrumentMap;
uint8 *_registerTable, *_opOutputTable;
uint8 *_adlibRegMirror;
- //- normal subs
+
+ // normal subs
void setRegister(uint8 regNum, uint8 value);
int32 getNextEventTime(void);
uint16 getNextNote(uint8 param);
void adlibSetupInstrument(void);
void setupInstrument(uint8 opcode);
void setupChannelVolume(uint8 volume);
- //- Streamfunctions from Command90hTable
+ void stopNote(void);
+
+ // Streamfunctions from Command90hTable
void com90_caseNoteOff(void); // 0
void com90_stopChannel(void); // 1
void com90_setupInstrument(void); // 2
- uint8 com90_updateTempo(void); // 3
+ uint8 com90_updateTempo(void); // 3
//void com90_dummy(void); // 4
void com90_getFreqOffset(void); // 5
void com90_getChannelVolume(void); // 6
void com90_getTremoVibro(void); // 7
- void com90_rewindMusic(void); // 8
+ void com90_loopMusic(void); // 8
void com90_keyOff(void); // 9
//void com90_error(void); // 10
//void com90_doLodsb(void); // 11
- void com90_setStartOfData(void); // 12
+ void com90_setLoopPoint(void); // 12
//void com90_do_two_Lodsb(void); // 13
};
diff --git a/engines/sky/music/adlibmusic.cpp b/engines/sky/music/adlibmusic.cpp
index 1ebd6fa15d..5955a504df 100644
--- a/engines/sky/music/adlibmusic.cpp
+++ b/engines/sky/music/adlibmusic.cpp
@@ -1,5 +1,5 @@
/* ScummVM - Scumm Interpreter
- * Copyright (C) 2003-2006 The ScummVM project
+ * Copyright (C) 2003-2007 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -39,7 +39,7 @@ AdlibMusic::AdlibMusic(Audio::Mixer *pMixer, Disk *pDisk)
_opl = makeAdlibOPL(_sampleRate);
- _mixer->playInputStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, false, true);
+ _mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, false, true);
}
AdlibMusic::~AdlibMusic(void) {
@@ -100,20 +100,35 @@ void AdlibMusic::setupChannels(uint8 *channelData) {
_numberOfChannels = channelData[0];
channelData++;
for (uint8 cnt = 0; cnt < _numberOfChannels; cnt++) {
- uint16 chDataStart = ((channelData[(cnt << 1) | 1] << 8) | channelData[cnt << 1]) + _musicDataLoc;
+ uint16 chDataStart = READ_LE_UINT16((uint16 *)channelData + cnt) + _musicDataLoc;
_channels[cnt] = new AdlibChannel(_opl, _musicData, chDataStart);
- _channels[cnt]->updateVolume(_musicVolume);
}
}
void AdlibMusic::startDriver(void) {
uint16 cnt = 0;
- while (_initSequence[cnt] || _initSequence[cnt+1]) {
- OPLWriteReg (_opl, _initSequence[cnt], _initSequence[cnt+1]);
+ while (_initSequence[cnt] || _initSequence[cnt + 1]) {
+ OPLWriteReg (_opl, _initSequence[cnt], _initSequence[cnt + 1]);
cnt += 2;
}
- _allowedCommands = 0xD;
+}
+
+void AdlibMusic::setVolume(uint16 param) {
+ _musicVolume = param;
+ _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, 2 * param);
+}
+
+bool AdlibMusic::isStereo(void) const {
+ return false;
+}
+
+bool AdlibMusic::endOfData(void) const {
+ return false;
+}
+
+int AdlibMusic::getRate(void) const {
+ return _sampleRate;
}
} // End of namespace Sky
diff --git a/engines/sky/music/adlibmusic.h b/engines/sky/music/adlibmusic.h
index ee98229b61..152fcc0df5 100644
--- a/engines/sky/music/adlibmusic.h
+++ b/engines/sky/music/adlibmusic.h
@@ -1,5 +1,5 @@
/* ScummVM - Scumm Interpreter
- * Copyright (C) 2003-2006 The ScummVM project
+ * Copyright (C) 2003-2007 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -37,9 +37,10 @@ public:
// AudioStream API
int readBuffer(int16 *buffer, const int numSamples);
- bool isStereo() const { return false; }
- bool endOfData() const { return false; }
- int getRate() const { return _sampleRate; }
+ bool isStereo(void) const;
+ bool endOfData(void) const;
+ int getRate(void) const;
+ virtual void setVolume(uint16 param);
private:
FM_OPL *_opl;
diff --git a/engines/sky/music/gmchannel.cpp b/engines/sky/music/gmchannel.cpp
index 66fbdfb69f..3ba6d46969 100644
--- a/engines/sky/music/gmchannel.cpp
+++ b/engines/sky/music/gmchannel.cpp
@@ -1,5 +1,5 @@
/* ScummVM - Scumm Interpreter
- * Copyright (C) 2003-2006 The ScummVM project
+ * Copyright (C) 2003-2007 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -31,9 +31,9 @@ GmChannel::GmChannel(uint8 *pMusicData, uint16 startOfData, MidiDriver *pMidiDrv
_musicData = pMusicData;
_midiDrv = pMidiDrv;
_channelData.midiChannelNumber = 0;
- _channelData.startOfData = startOfData;
+ _channelData.loopPoint = startOfData;
_channelData.eventDataPtr = startOfData;
- _channelData.channelActive = 1;
+ _channelData.channelActive = true;
_channelData.nextEventTime = getNextEventTime();
_instMap = pInstMap;
_veloTab = veloTab;
@@ -42,9 +42,12 @@ GmChannel::GmChannel(uint8 *pMusicData, uint16 startOfData, MidiDriver *pMidiDrv
_lastVolume = 0xFF;
}
-bool GmChannel::isActive(void) {
+GmChannel::~GmChannel(void) {
+ stopNote();
+}
- return _channelData.channelActive != 0;
+bool GmChannel::isActive(void) {
+ return _channelData.channelActive;
}
void GmChannel::updateVolume(uint16 pVolume) {
@@ -74,11 +77,13 @@ int32 GmChannel::getNextEventTime(void) {
lVal = _musicData[_channelData.eventDataPtr];
_channelData.eventDataPtr++;
retV = (retV << 7) | (lVal & 0x7F);
- if (!(lVal & 0x80)) break;
+ if (!(lVal & 0x80))
+ break;
}
if (lVal & 0x80) { // should never happen
return -1;
- } else return retV;
+ } else
+ return retV;
}
@@ -108,21 +113,14 @@ uint8 GmChannel::process(uint16 aktTime) {
break;
case 5: com90_getPitch(); break;
case 6: com90_getChannelVolume(); break;
- case 8: com90_rewindMusic(); break;
+ case 8: com90_loopMusic(); break;
case 9: com90_keyOff(); break;
case 11: com90_getChannelPanValue(); break;
- case 12: com90_setStartOfData(); break;
+ case 12: com90_setLoopPoint(); break;
case 13: com90_getChannelControl(); break;
- case 4: //com90_dummy();
- case 7: //com90_skipTremoVibro();
- case 10: //com90_error();
- error("Channel: dummy music routine 0x%02X was called",opcode);
- _channelData.channelActive = 0;
- break;
+
default:
- // these opcodes aren't implemented in original music driver
- error("Channel: Not existent routine 0x%02X was called",opcode);
- _channelData.channelActive = 0;
+ error("GmChannel: Unknown music opcode 0x%02X", opcode);
break;
}
} else {
@@ -154,7 +152,7 @@ void GmChannel::com90_caseNoteOff(void) {
void GmChannel::com90_stopChannel(void) {
stopNote();
- _channelData.channelActive = 0;
+ _channelData.channelActive = false;
}
void GmChannel::com90_setupInstrument(void) {
@@ -166,10 +164,7 @@ void GmChannel::com90_setupInstrument(void) {
}
uint8 GmChannel::com90_updateTempo(void) {
-
- uint8 retV = _musicData[_channelData.eventDataPtr];
- _channelData.eventDataPtr++;
- return retV;
+ return _musicData[_channelData.eventDataPtr++];
}
void GmChannel::com90_getPitch(void) {
@@ -185,9 +180,9 @@ void GmChannel::com90_getChannelVolume(void) {
_midiDrv->send((0xB0 | _channelData.midiChannelNumber) | 0x700 | (newVol << 16));
}
-void GmChannel::com90_rewindMusic(void) {
+void GmChannel::com90_loopMusic(void) {
- _channelData.eventDataPtr = _channelData.startOfData;
+ _channelData.eventDataPtr = _channelData.loopPoint;
}
void GmChannel::com90_keyOff(void) {
@@ -195,9 +190,9 @@ void GmChannel::com90_keyOff(void) {
_midiDrv->send((0x90 | _channelData.midiChannelNumber) | (_channelData.note << 8) | 0);
}
-void GmChannel::com90_setStartOfData(void) {
+void GmChannel::com90_setLoopPoint(void) {
- _channelData.startOfData = _channelData.eventDataPtr;
+ _channelData.loopPoint = _channelData.eventDataPtr;
}
void GmChannel::com90_getChannelPanValue(void) {
@@ -208,9 +203,8 @@ void GmChannel::com90_getChannelPanValue(void) {
void GmChannel::com90_getChannelControl(void) {
- uint8 conNum = _musicData[_channelData.eventDataPtr];
- uint8 conDat = _musicData[_channelData.eventDataPtr + 1];
- _channelData.eventDataPtr += 2;
+ uint8 conNum = _musicData[_channelData.eventDataPtr++];
+ uint8 conDat = _musicData[_channelData.eventDataPtr++];
_midiDrv->send((0xB0 | _channelData.midiChannelNumber) | (conNum << 8) | (conDat << 16));
}
diff --git a/engines/sky/music/gmchannel.h b/engines/sky/music/gmchannel.h
index b62a8f4b6f..c3031d73f2 100644
--- a/engines/sky/music/gmchannel.h
+++ b/engines/sky/music/gmchannel.h
@@ -1,5 +1,5 @@
/* ScummVM - Scumm Interpreter
- * Copyright (C) 2003-2006 The ScummVM project
+ * Copyright (C) 2003-2007 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -32,15 +32,16 @@ namespace Sky {
typedef struct {
uint16 eventDataPtr;
int32 nextEventTime;
- uint16 startOfData;
+ uint16 loopPoint;
uint8 midiChannelNumber;
uint8 note;
- uint8 channelActive;
+ bool channelActive;
} MidiChannelType;
class GmChannel : public ChannelBase {
public:
GmChannel(uint8 *pMusicData, uint16 startOfData, MidiDriver *pMidiDrv, const byte *pInstMap, const byte *veloTab);
+ ~GmChannel(void);
virtual void stopNote(void);
virtual uint8 process(uint16 aktTime);
virtual void updateVolume(uint16 pVolume);
@@ -69,11 +70,11 @@ private:
void com90_getPitch(void); // 5
void com90_getChannelVolume(void); // 6
//void com90_skipTremoVibro(void); // 7
- void com90_rewindMusic(void); // 8
+ void com90_loopMusic(void); // 8
void com90_keyOff(void); // 9
//void com90_error(void); // 10
void com90_getChannelPanValue(void); // 11
- void com90_setStartOfData(void); // 12
+ void com90_setLoopPoint(void); // 12
void com90_getChannelControl(void); // 13
};
diff --git a/engines/sky/music/gmmusic.cpp b/engines/sky/music/gmmusic.cpp
index 6e01126231..ff9bc14263 100644
--- a/engines/sky/music/gmmusic.cpp
+++ b/engines/sky/music/gmmusic.cpp
@@ -1,5 +1,5 @@
/* ScummVM - Scumm Interpreter
- * Copyright (C) 2003-2006 The ScummVM project
+ * Copyright (C) 2003-2007 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -24,6 +24,7 @@
#include "sky/music/gmchannel.h"
#include "sky/sky.h"
#include "common/util.h"
+#include "common/endian.h"
#include "sound/mididrv.h"
namespace Sky {
@@ -51,7 +52,7 @@ GmMusic::~GmMusic(void) {
if (_currentMusic)
stopMusic();
// Send All Sound Off and All Notes Off (for external synths)
- for (int i = 0; i < 16; ++i) {
+ for (int i = 0; i < 16; i++) {
_midiDrv->send ((120 << 8) | 0xB0 | i);
_midiDrv->send ((123 << 8) | 0xB0 | i);
}
@@ -59,11 +60,18 @@ GmMusic::~GmMusic(void) {
delete _midiDrv;
}
+void GmMusic::setVolume(uint16 param) {
+
+ _musicVolume = param;
+ for (uint8 cnt = 0; cnt < _numberOfChannels; cnt++)
+ _channels[cnt]->updateVolume(_musicVolume);
+}
+
void GmMusic::timerCall(void) {
_timerCount += _midiDrv->getBaseTempo();
- if (_timerCount > (1000000 / 50)) {
+ if (_timerCount > (1000 * 1000 / 50)) {
// call pollMusic() 50 times per second
- _timerCount -= 1000000 / 50;
+ _timerCount -= 1000 * 1000 / 50;
if (_musicData != NULL)
pollMusic();
}
@@ -72,11 +80,11 @@ void GmMusic::timerCall(void) {
void GmMusic::setupPointers(void) {
if (SkyEngine::_systemVars.gameVersion == 109) {
- _musicDataLoc = (_musicData[0x79C] << 8) | _musicData[0x79B];
+ _musicDataLoc = READ_LE_UINT16(_musicData + 0x79B);
_sysExSequence = _musicData + 0x1EF2;
} else {
- _musicDataLoc = (_musicData[0x7DD] << 8) | _musicData[0x7DC];
- _sysExSequence = ((_musicData[0x7E1] << 8) | _musicData[0x7E0]) + _musicData;
+ _musicDataLoc = READ_LE_UINT16(_musicData + 0x7DC);
+ _sysExSequence = READ_LE_UINT16(_musicData + 0x7E0) + _musicData;
}
}
@@ -85,7 +93,7 @@ void GmMusic::setupChannels(uint8 *channelData) {
_numberOfChannels = channelData[0];
channelData++;
for (uint8 cnt = 0; cnt < _numberOfChannels; cnt++) {
- uint16 chDataStart = ((channelData[(cnt << 1) | 1] << 8) | channelData[cnt << 1]) + _musicDataLoc;
+ uint16 chDataStart = READ_LE_UINT16((uint16 *)channelData + cnt) + _musicDataLoc;
_channels[cnt] = new GmChannel(_musicData, chDataStart, _midiDrv, MidiDriver::_mt32ToGm, _veloTab);
_channels[cnt]->updateVolume(_musicVolume);
}
@@ -93,7 +101,7 @@ void GmMusic::setupChannels(uint8 *channelData) {
void GmMusic::startDriver(void) {
// Send GM System On to reset channel parameters etc.
- uint8 sysEx[] = {0x7e, 0x7f, 0x09, 0x01};
+ uint8 sysEx[] = { 0x7e, 0x7f, 0x09, 0x01 };
_midiDrv->sysEx(sysEx, sizeof(sysEx));
//_midiDrv->send(0xFF); //ALSA can't handle this.
// skip all sysEx as it can't be handled anyways.
diff --git a/engines/sky/music/gmmusic.h b/engines/sky/music/gmmusic.h
index f0ee444760..214dfd810f 100644
--- a/engines/sky/music/gmmusic.h
+++ b/engines/sky/music/gmmusic.h
@@ -1,5 +1,5 @@
/* ScummVM - Scumm Interpreter
- * Copyright (C) 2003-2006 The ScummVM project
+ * Copyright (C) 2003-2007 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -33,6 +33,7 @@ class GmMusic : public MusicBase {
public:
GmMusic(MidiDriver *pMidiDrv, Disk *pDisk);
~GmMusic(void);
+ virtual void setVolume(uint16 param);
private:
static void passTimerFunc(void *param);
void timerCall(void);
diff --git a/engines/sky/music/mt32music.cpp b/engines/sky/music/mt32music.cpp
index a6bcbf4d05..322e5e77fe 100644
--- a/engines/sky/music/mt32music.cpp
+++ b/engines/sky/music/mt32music.cpp
@@ -1,5 +1,5 @@
/* ScummVM - Scumm Interpreter
- * Copyright (C) 2003-2006 The ScummVM project
+ * Copyright (C) 2003-2007 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -24,6 +24,7 @@
#include "sky/music/gmchannel.h"
#include "common/util.h"
#include "common/system.h"
+#include "common/endian.h"
#include "sound/mididrv.h"
namespace Sky {
@@ -62,10 +63,10 @@ void MT32Music::timerCall(void) {
}
}
-void MT32Music::setVolume(uint8 volume) {
+void MT32Music::setVolume(uint16 volume) {
uint8 sysEx[10] = "\x41\x10\x16\x12\x10\x00\x16\x00\x00";
_musicVolume = volume;
- sysEx[7] = (volume > 100) ? 100 : volume;
+ sysEx[7] = (volume > 100) ? 100 : (uint8)volume;
sysEx[8] = 0x00;
for (uint8 cnt = 4; cnt < 8; cnt++)
sysEx[8] -= sysEx[cnt];
@@ -75,8 +76,8 @@ void MT32Music::setVolume(uint8 volume) {
void MT32Music::setupPointers(void) {
- _musicDataLoc = (_musicData[0x7DD] << 8) | _musicData[0x7DC];
- _sysExSequence = ((_musicData[0x7E1] << 8) | _musicData[0x7E0]) + _musicData;
+ _musicDataLoc = READ_LE_UINT16(_musicData + 0x7DC);
+ _sysExSequence = READ_LE_UINT16(_musicData + 0x7E0) + _musicData;
}
void MT32Music::setupChannels(uint8 *channelData) {
@@ -84,7 +85,7 @@ void MT32Music::setupChannels(uint8 *channelData) {
_numberOfChannels = channelData[0];
channelData++;
for (uint8 cnt = 0; cnt < _numberOfChannels; cnt++) {
- uint16 chDataStart = ((channelData[(cnt << 1) | 1] << 8) | channelData[cnt << 1]) + _musicDataLoc;
+ uint16 chDataStart = READ_LE_UINT16((uint16 *)channelData + cnt) + _musicDataLoc;
_channels[cnt] = new GmChannel(_musicData, chDataStart, _midiDrv, NULL, NULL);
_channels[cnt]->updateVolume(_musicVolume);
}
@@ -98,12 +99,16 @@ bool MT32Music::processPatchSysEx(uint8 *sysExData) {
return false;
// decompress data from stream
- sysExBuf[0] = 0x41; sysExBuf[1] = 0x10; sysExBuf[2] = 0x16; sysExBuf[3] = 0x12; sysExBuf[4] = 0x5;
- sysExBuf[5] = sysExData[0] >> 4; // patch offset part 1
- sysExBuf[6] = (sysExData[0] & 0xF) << 3; // patch offset part 2
- sysExBuf[7] = sysExData[1] >> 6; // timbre group
- sysExBuf[8] = sysExData[1] & 0x3F; // timbre num
- sysExBuf[9] = sysExData[2] & 0x3F; // key shift
+ sysExBuf[ 0] = 0x41;
+ sysExBuf[ 1] = 0x10;
+ sysExBuf[ 2] = 0x16;
+ sysExBuf[ 3] = 0x12;
+ sysExBuf[ 4] = 0x5;
+ sysExBuf[ 5] = sysExData[0] >> 4; // patch offset part 1
+ sysExBuf[ 6] = (sysExData[0] & 0xF) << 3; // patch offset part 2
+ sysExBuf[ 7] = sysExData[1] >> 6; // timbre group
+ sysExBuf[ 8] = sysExData[1] & 0x3F; // timbre num
+ sysExBuf[ 9] = sysExData[2] & 0x3F; // key shift
sysExBuf[10] = sysExData[3] & 0x7F; // fine tune
sysExBuf[11] = sysExData[4] & 0x7F; // bender range
sysExBuf[12] = sysExData[2] >> 6; // assign mode
@@ -125,7 +130,10 @@ void MT32Music::startDriver(void) {
sysExData++;
uint8 sendBuf[256];
uint8 len;
- sendBuf[0] = 0x41; sendBuf[1] = 0x10; sendBuf[2] = 0x16; sendBuf[3] = 0x12;
+ sendBuf[0] = 0x41;
+ sendBuf[1] = 0x10;
+ sendBuf[2] = 0x16;
+ sendBuf[3] = 0x12;
for (cnt = 0; cnt < timbreNum; cnt++) {
len = 7;
crc = 0;
diff --git a/engines/sky/music/mt32music.h b/engines/sky/music/mt32music.h
index 663cf9118a..eb312136db 100644
--- a/engines/sky/music/mt32music.h
+++ b/engines/sky/music/mt32music.h
@@ -1,5 +1,5 @@
/* ScummVM - Scumm Interpreter
- * Copyright (C) 2003-2006 The ScummVM project
+ * Copyright (C) 2003-2007 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -37,7 +37,7 @@ private:
static void passTimerFunc(void *param);
void timerCall(void);
bool processPatchSysEx(uint8 *sysExData);
- virtual void setVolume(uint8 volume);
+ virtual void setVolume(uint16 volume);
uint32 _timerCount;
uint8 *_sysExSequence;
diff --git a/engines/sky/music/musicbase.cpp b/engines/sky/music/musicbase.cpp
index e296c72827..80eeaf7637 100644
--- a/engines/sky/music/musicbase.cpp
+++ b/engines/sky/music/musicbase.cpp
@@ -1,5 +1,5 @@
/* ScummVM - Scumm Interpreter
- * Copyright (C) 2003-2006 The ScummVM project
+ * Copyright (C) 2003-2007 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -23,13 +23,13 @@
#include "sky/music/musicbase.h"
#include "sky/disk.h"
#include "common/util.h"
+#include "common/endian.h"
namespace Sky {
MusicBase::MusicBase(Disk *pDisk) {
_musicData = NULL;
- _allowedCommands = 0;
_skyDisk = pDisk;
_currentMusic = 0;
_musicVolume = 127;
@@ -52,11 +52,9 @@ void MusicBase::loadSection(uint8 pSection) {
free(_musicData);
_currentSection = pSection;
_musicData = _skyDisk->loadFile(_driverFileBase + FILES_PER_SECTION * pSection);
- _allowedCommands = 0;
+
_musicTempo0 = 0x78; // init constants taken from idb file, area ~0x1060
_musicTempo1 = 0xC0;
- _onNextPoll.doReInit = false;
- _onNextPoll.doStopMusic = false;
_onNextPoll.musicToProcess = 0;
_tempo = _aktTime = 0x10001;
_numberOfChannels = _currentMusic = 0;
@@ -73,13 +71,6 @@ bool MusicBase::musicIsPlaying(void) {
return false;
}
-void MusicBase::setVolume(uint16 param) {
-
- _musicVolume = param;
- for (uint8 cnt = 0; cnt < _numberOfChannels; cnt++)
- _channels[cnt]->updateVolume(_musicVolume);
-}
-
void MusicBase::stopMusic(void) {
_mutex.lock();
@@ -89,10 +80,8 @@ void MusicBase::stopMusic(void) {
void MusicBase::stopMusicInternal(void) {
- for (uint8 cnt = 0; cnt < _numberOfChannels; cnt++) {
- _channels[cnt]->stopNote();
+ for (uint8 cnt = 0; cnt < _numberOfChannels; cnt++)
delete _channels[cnt];
- }
_numberOfChannels = 0;
}
@@ -101,7 +90,7 @@ void MusicBase::updateTempo(void) {
uint16 tempoMul = _musicTempo0 * _musicTempo1;
uint16 divisor = 0x4446390/ 23864;
_tempo = (tempoMul / divisor) << 16;
- _tempo |= (((tempoMul%divisor) << 16) | (tempoMul / divisor)) / divisor;
+ _tempo |= (((tempoMul % divisor) << 16) | (tempoMul / divisor)) / divisor;
}
void MusicBase::loadNewMusic(void) {
@@ -117,9 +106,9 @@ void MusicBase::loadNewMusic(void) {
_currentMusic = _onNextPoll.musicToProcess;
if (_currentMusic != 0) {
- musicPos = (_musicData[_musicDataLoc + 2] << 8) | _musicData[_musicDataLoc+1];
- musicPos += _musicDataLoc+((_currentMusic-1) << 1);
- musicPos = ((_musicData[musicPos+1] << 8) | _musicData[musicPos]) + _musicDataLoc;
+ musicPos = READ_LE_UINT16(_musicData + _musicDataLoc + 1);
+ musicPos += _musicDataLoc + ((_currentMusic - 1) << 1);
+ musicPos = READ_LE_UINT16(_musicData + musicPos) + _musicDataLoc;
_musicTempo0 = _musicData[musicPos];
_musicTempo1 = _musicData[musicPos+1];
@@ -134,8 +123,6 @@ void MusicBase::pollMusic(void) {
_mutex.lock();
uint8 newTempo;
- if (_onNextPoll.doReInit) startDriver();
- if (_onNextPoll.doStopMusic) stopMusicInternal();
if (_onNextPoll.musicToProcess != _currentMusic)
loadNewMusic();
@@ -152,4 +139,16 @@ void MusicBase::pollMusic(void) {
_aktTime &= 0xFFFF;
}
+void MusicBase::startMusic(uint16 param) {
+ _onNextPoll.musicToProcess = param & 0xF;
+}
+
+uint8 MusicBase::giveVolume(void) {
+ return (uint8)_musicVolume;
+}
+
+uint8 MusicBase::giveCurrentMusic(void) {
+ return _currentMusic;
+}
+
} // End of namespace Sky
diff --git a/engines/sky/music/musicbase.h b/engines/sky/music/musicbase.h
index 4cab755ac1..1f2bd58740 100644
--- a/engines/sky/music/musicbase.h
+++ b/engines/sky/music/musicbase.h
@@ -1,5 +1,5 @@
/* ScummVM - Scumm Interpreter
- * Copyright (C) 2003-2006 The ScummVM project
+ * Copyright (C) 2003-2007 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -34,14 +34,12 @@ class Disk;
#define FILES_PER_SECTION 4
typedef struct {
- bool doReInit, doStopMusic;
uint8 musicToProcess;
} Actions;
class ChannelBase {
public:
virtual ~ChannelBase() {};
- virtual void stopNote(void) = 0;
virtual uint8 process(uint16 aktTime) = 0;
virtual void updateVolume(uint16 pVolume) = 0;
virtual bool isActive(void) = 0;
@@ -53,18 +51,18 @@ public:
MusicBase(Disk *pDisk);
virtual ~MusicBase(void);
void loadSection(uint8 pSection);
- void startMusic(uint16 param) { _onNextPoll.musicToProcess = param & 0xF; }; // 4
- void stopMusic(); // 7
+ void startMusic(uint16 param);
+ void stopMusic();
bool musicIsPlaying(void);
- uint8 giveVolume(void) { return (uint8)_musicVolume; };
- uint8 giveCurrentMusic(void) { return _currentMusic; };
- void setVolume(uint16 param);
+ uint8 giveVolume(void);
+ uint8 giveCurrentMusic(void);
+ virtual void setVolume(uint16 param) = 0;
protected:
Disk *_skyDisk;
uint8 *_musicData;
- uint8 _allowedCommands;
+
uint16 _musicDataLoc;
uint16 _driverFileBase;