[Scummvm-git-logs] scummvm master -> 4077a9d82d327972a98c592c87da7d41de1a9972
athrxx
noreply at scummvm.org
Tue Jun 13 22:40:28 UTC 2023
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
e8d21cf93a KYRA: avoid possible nullptr deref
4077a9d82d KYRA: (EOB II/PC98) - sound improvements
Commit: e8d21cf93aa4b616d177535e5e30da60c7e04299
https://github.com/scummvm/scummvm/commit/e8d21cf93aa4b616d177535e5e30da60c7e04299
Author: athrxx (athrxx at scummvm.org)
Date: 2023-06-14T00:38:51+02:00
Commit Message:
KYRA: avoid possible nullptr deref
Changed paths:
engines/kyra/graphics/screen_eob.cpp
diff --git a/engines/kyra/graphics/screen_eob.cpp b/engines/kyra/graphics/screen_eob.cpp
index 1cd3c6748ad..25b8fdaf4bd 100644
--- a/engines/kyra/graphics/screen_eob.cpp
+++ b/engines/kyra/graphics/screen_eob.cpp
@@ -208,11 +208,12 @@ void Screen_EoB::setClearScreenDim(int dim) {
void Screen_EoB::clearCurDim() {
static const uint8 amigaColorMap[16] = { 0x00, 0x06, 0x1d, 0x1b, 0x1a, 0x17, 0x18, 0x0e, 0x19, 0x1c, 0x1c, 0x1e, 0x13, 0x0a, 0x11, 0x1f };
- fillRect(_curDim->sx << 3, _curDim->sy, ((_curDim->sx + _curDim->w) << 3) - 1, (_curDim->sy + _curDim->h) - 1, _isAmiga ? amigaColorMap[_curDim->col2] : _use16ColorMode ? 0 : _curDim->col2);
+ if (_curDim)
+ fillRect(_curDim->sx << 3, _curDim->sy, ((_curDim->sx + _curDim->w) << 3) - 1, (_curDim->sy + _curDim->h) - 1, _isAmiga ? amigaColorMap[_curDim->col2] : _use16ColorMode ? 0 : _curDim->col2);
}
void Screen_EoB::clearCurDimOvl(int pageNum) {
- if (pageNum > 1 || !_useOverlays)
+ if (pageNum > 1 || !_useOverlays || !_curDim)
return;
addDirtyRect(_curDim->sx << 3, _curDim->sy, _curDim->w << 3, _curDim->h);
clearOverlayRect(pageNum, _curDim->sx << 3, _curDim->sy, _curDim->w << 3, _curDim->h);
Commit: 4077a9d82d327972a98c592c87da7d41de1a9972
https://github.com/scummvm/scummvm/commit/4077a9d82d327972a98c592c87da7d41de1a9972
Author: athrxx (athrxx at scummvm.org)
Date: 2023-06-14T00:38:58+02:00
Commit Message:
KYRA: (EOB II/PC98) - sound improvements
Changed paths:
engines/kyra/engine/chargen.cpp
engines/kyra/sequence/sequences_darkmoon.cpp
engines/kyra/sound/drivers/capcom98.cpp
engines/kyra/sound/drivers/capcom98.h
engines/kyra/sound/sound_intern.h
engines/kyra/sound/sound_pc98_darkmoon.cpp
diff --git a/engines/kyra/engine/chargen.cpp b/engines/kyra/engine/chargen.cpp
index 3cd03201112..0d029b041d7 100644
--- a/engines/kyra/engine/chargen.cpp
+++ b/engines/kyra/engine/chargen.cpp
@@ -592,7 +592,7 @@ void CharacterGenerator::drawButton(int index, int buttonState) {
_screen->copyRegion(160, 0, c->destX << 3, c->destY, p->w << 3, p->h, 2, 0, Screen::CR_NO_P_CHECK);
_screen->updateScreen();
- }
+}
void CharacterGenerator::processButtonClick(int index) {
drawButton(index, 1);
diff --git a/engines/kyra/sequence/sequences_darkmoon.cpp b/engines/kyra/sequence/sequences_darkmoon.cpp
index 93a604a900e..83a95b4064e 100644
--- a/engines/kyra/sequence/sequences_darkmoon.cpp
+++ b/engines/kyra/sequence/sequences_darkmoon.cpp
@@ -346,7 +346,7 @@ void DarkMoonEngine::seq_playIntro() {
sq.printText(3, textColor1); // The message was urgent.
- if (_flags.platform == Common::kPlatformPC98)
+ if (!skipFlag() && !shouldQuit() && _flags.platform == Common::kPlatformPC98)
snd_playSong(55);
sq.loadScene(1, 2);
@@ -447,7 +447,7 @@ void DarkMoonEngine::seq_playIntro() {
sq.animCommand(16);
- if (_flags.platform == Common::kPlatformPC98)
+ if (!skipFlag() && !shouldQuit() && _flags.platform == Common::kPlatformPC98)
snd_playSong(56);
sq.printText(7, textColor2); // Thank you for coming so quickly
@@ -594,7 +594,7 @@ void DarkMoonEngine::seq_playIntro() {
sq.animCommand(20);
sq.animCommand(18);
- if (_flags.platform == Common::kPlatformPC98)
+ if (!skipFlag() && !shouldQuit() && _flags.platform == Common::kPlatformPC98)
snd_playSong(57);
sq.fadeText();
diff --git a/engines/kyra/sound/drivers/capcom98.cpp b/engines/kyra/sound/drivers/capcom98.cpp
index 5ac992da59b..e8de05ec2a3 100644
--- a/engines/kyra/sound/drivers/capcom98.cpp
+++ b/engines/kyra/sound/drivers/capcom98.cpp
@@ -40,7 +40,7 @@ public:
kSavedState = 1 << 10
};
- CapcomPC98Player(bool playerPrio, uint16 playerFlag, uint16 reservedChanFlags);
+ CapcomPC98Player(bool playerPrio, uint16 playFlags, uint16 chanReserveFlags, uint16 chanDisableFlags);
virtual ~CapcomPC98Player() {}
virtual bool init() = 0;
@@ -51,16 +51,21 @@ public:
void startSound(const uint8 *data, uint8 volume, bool loop);
void stopSound();
uint8 getMarker(uint8 id) const { return _soundMarkers[id & 0x0F]; }
- static uint16 getPlayerStatus() { return _flags; }
+ static uint16 getStatus() { return _flags; }
+
+ void fadeOut(uint16 speed);
+ void allNotesOff(uint16 chanFlags = 0xFFFF);
virtual void setMasterVolume (int vol) = 0;
void nextTick();
- virtual void processSounds() {}
+ virtual void processSounds() = 0;
protected:
uint16 _soundMarkers[16];
- const uint16 _reservedChanFlags;
+ uint8 _fadeState;
+ const uint16 _chanReserveFlags;
+ const uint16 _chanDisableFlags;
private:
virtual void send(uint32 evt) = 0;
@@ -68,9 +73,9 @@ private:
void storeEvent(uint32 evt);
void restorePlayer();
virtual void restoreStateIntern() {}
- uint16 playFlag() const { return _playerFlag & (kStdPlay | kPrioPlay); }
- uint16 extraFlag() const { return _playerFlag & kPrioClaim; }
- uint16 stopFlag() const { return (_playerFlag & (kStdPlay | kPrioPlay)) << 8; }
+ uint16 playFlag() const { return _playFlags & (kStdPlay | kPrioPlay); }
+ uint16 extraFlag() const { return _playFlags & kPrioClaim; }
+ uint16 stopFlag() const { return (_playFlags & (kStdPlay | kPrioPlay)) << 8; }
const uint8 *_data;
const uint8 *_curPos;
@@ -82,10 +87,13 @@ private:
static uint16 _flags;
bool _loop;
+ uint16 _fadeSpeed;
+ uint16 _fadeTicker;
+
Common::Array<uint32> _storedEvents;
const bool _playerPrio;
- const uint16 _playerFlag;
+ const uint16 _playFlags;
};
class CapcomPC98_MIDI final : public CapcomPC98Player {
@@ -96,11 +104,13 @@ public:
~CapcomPC98_MIDI();
bool init() override;
- void deinit() override;
+ void deinit() override {}
void reset() override;
void setMasterVolume (int vol) override;
+ void processSounds() override;
+
private:
void send(uint32 evt) override;
PC98AudioCore::MutexLock lockMutex() override;
@@ -109,6 +119,8 @@ private:
const bool _isMT32;
const uint8 *_programMapping;
+ uint8 _chanVolume[16];
+
static const uint8 _programMapping_mt32ToGM[128];
MutexProc &_mproc;
@@ -116,7 +128,7 @@ private:
class CapcomPC98_FM_Channel {
public:
- CapcomPC98_FM_Channel(uint8 id, PC98AudioCore *&ac, const Common::Array<const uint8*>&instruments);
+ CapcomPC98_FM_Channel(uint8 id, PC98AudioCore *&ac, const Common::Array<const uint8*>&instruments, const uint8 &fadeState);
~CapcomPC98_FM_Channel();
void reset();
@@ -203,10 +215,12 @@ private:
PC98AudioCore *&_ac;
const Common::Array<const uint8*>&_instruments;
+ const uint8 &_fadeState;
+
static const uint16 _freqMSBTable[12];
static const uint8 _freqLSBTables[12][64];
static const uint8 _volTablesInst[4][128];
- static const uint8 _volTableOut[128];
+ static const uint8 _volTableCarrier[128];
static const uint8 _volTablePara[128];
};
@@ -214,7 +228,7 @@ class CapcomPC98_FM final : public CapcomPC98Player, PC98AudioPluginDriver {
public:
typedef Common::Functor0Mem<void, CapcomPC98AudioDriverInternal> CBProc;
- CapcomPC98_FM(Audio::Mixer *mixer, CBProc &cbproc, bool playerPrio, uint16 playerFlag, uint8 reservedChanFlags, bool needsTimer);
+ CapcomPC98_FM(Audio::Mixer *mixer, CBProc &cbproc, bool playerPrio, uint16 playFlags, uint8 chanReserveFlags, uint8 chanDisableFlags, bool needsTimer);
~CapcomPC98_FM() override;
bool init() override;
@@ -228,7 +242,7 @@ public:
private:
void send(uint32 evt) override;
- void timerCallbackB() override;
+ void timerCallbackA() override;
void processSounds() override;
void controlChange(uint8 ch, uint8 control, uint8 val);
@@ -262,10 +276,14 @@ public:
void stopSong();
void startSoundEffect(const uint8 *data, uint8 volume);
void stopSoundEffect();
+
int checkSoundMarker() const;
bool songIsPlaying() const;
bool soundEffectIsPlaying() const;
+ void fadeOut();
+ void allNotesOff();
+
void setMusicVolume(int volume);
void setSoundEffectVolume(int volume);
@@ -292,7 +310,8 @@ private:
uint16 CapcomPC98Player::_flags = 0;
-CapcomPC98Player::CapcomPC98Player(bool playerPrio, uint16 playerFlag, uint16 reservedChanFlags) : _playerPrio(playerPrio), _playerFlag(playerFlag), _reservedChanFlags(reservedChanFlags), _data(nullptr), _curPos(nullptr), _numEventsTotal(0), _numEventsLeft(0), _volume(0), _midiTicker(0), _loop(false) {
+CapcomPC98Player::CapcomPC98Player(bool playerPrio, uint16 playFlags, uint16 chanReserveFlags, uint16 chanDisableFlags) : _playerPrio(playerPrio), _playFlags(playFlags), _chanReserveFlags(chanReserveFlags), _chanDisableFlags(chanDisableFlags),
+ _data(nullptr), _curPos(nullptr), _numEventsTotal(0), _numEventsLeft(0), _volume(0), _midiTicker(0), _loop(false), _fadeState(0), _fadeSpeed(1), _fadeTicker(0) {
memset(_soundMarkers, 0, sizeof(_soundMarkers));
_flags = 0;
}
@@ -303,15 +322,13 @@ void CapcomPC98Player::startSound(const uint8 *data, uint8 volume, bool loop) {
PC98AudioCore::MutexLock lock = lockMutex();
_numEventsTotal = _numEventsLeft = READ_LE_UINT16(data);
_data = _curPos = data + 2;
- _volume = volume & 0x7f;
+ _volume = volume & 0x7F;
_loop = loop;
_midiTicker = 0;
- if (_volume != 0x7f) {
- for (int i = 0; i < 16; ++i) {
- if ((1 << i) & _reservedChanFlags)
- send(0x0007B0 | i | (_volume << 16));
- }
+ for (int i = 0; i < 16; ++i) {
+ if ((1 << i) & _chanReserveFlags)
+ send(0x0007B0 | i | (_volume << 16));
}
_flags &= ~(stopFlag() | kFadeOut);
@@ -320,22 +337,50 @@ void CapcomPC98Player::startSound(const uint8 *data, uint8 volume, bool loop) {
void CapcomPC98Player::stopSound() {
while (_flags & playFlag()) {
- g_system->delayMillis(5);
+ g_system->delayMillis(4);
PC98AudioCore::MutexLock lock = lockMutex();
_flags |= stopFlag();
}
+ g_system->delayMillis(8);
+}
+
+void CapcomPC98Player::fadeOut(uint16 speed) {
+ if (speed) {
+ _fadeTicker =_fadeSpeed = speed;
+ _fadeState = 0;
+ _flags |= kFadeOut;
+ } else {
+ stopSound();
+ }
+}
+
+void CapcomPC98Player::allNotesOff(uint16 chanFlags) {
+ for (int i = 0; i < 16; ++i) {
+ if ((1 << i) & chanFlags)
+ send(0x007BB0 | i);
+ }
}
void CapcomPC98Player::nextTick() {
if (_flags & playFlag()) {
+ if (_flags & kFadeOut) {
+ if (_fadeTicker) {
+ --_fadeTicker;
+ } else {
+ _fadeTicker = _fadeSpeed;
+ if (++_fadeState == 100)
+ _flags |= stopFlag();
+ }
+ } else {
+ _fadeState = 0;
+ _fadeTicker = _fadeSpeed;
+ }
+
if (!_playerPrio) {
if (_flags & kPrioClaim) {
_flags &= ~kPrioClaim;
_flags |= kSavedState;
- for (int i = 0; i < 16; ++i) {
- if ((1 << i) & ~_reservedChanFlags)
- send(0x007BB0 | i);
- }
+ allNotesOff(~_chanReserveFlags);
} else if (((_flags & kPrioStop) || !(_flags & kPrioPlay)) && (_flags & kSavedState)) {
_flags &= ~kSavedState;
restorePlayer();
@@ -343,11 +388,10 @@ void CapcomPC98Player::nextTick() {
}
if (_flags & stopFlag()) {
- for (int i = 0; i < 16; ++i) {
- if ((1 << i) & _reservedChanFlags)
- send(0x007BB0 | i);
- }
+ allNotesOff((_playerPrio || (_flags & kPrioPlay)) ? _chanReserveFlags : 0xFFFF);
_flags &= ~playFlag();
+ if (!(_flags & (kStdPlay | kPrioPlay)))
+ _flags &= ~kFadeOut;
} else if (_numEventsLeft) {
bool eot = false;
@@ -360,12 +404,17 @@ void CapcomPC98Player::nextTick() {
break;
_midiTicker -= (in & 0xFF);
- if (_playerPrio || !(_flags & kPrioPlay) || ((_flags & kPrioPlay) && ((1 << ((in >> 8) & 0x0f)) & _reservedChanFlags))) {
- if (_volume == 0x7f || ((in >> 12) & 0xfff) != 0x70B)
- send(in >> 8);
- } else {
- storeEvent(in >> 8);
+ uint8 chanFlag = 1 << ((in >> 8) & 0x0F);
+
+ if (!(chanFlag & _chanDisableFlags)) {
+ if (_playerPrio || !(_flags & kPrioPlay) || ((_flags & kPrioPlay) && (chanFlag & _chanReserveFlags))) {
+ if (_volume == 0x7F || ((in >> 12) & 0xFFF) != 0x07B)
+ send(in >> 8);
+ } else {
+ storeEvent(in >> 8);
+ }
}
+
_curPos += 4;
eot = (--_numEventsLeft == 0);
}
@@ -374,12 +423,8 @@ void CapcomPC98Player::nextTick() {
if (_loop) {
_numEventsLeft = _numEventsTotal;
_curPos = _data;
- } else if (_playerPrio || !(_flags & kPrioPlay)) {
- for (int i = 0; i < 16; ++i) {
- if ((1 << i) & _reservedChanFlags)
- send(0x007BB0 | i);
- }
-
+ } else {
+ allNotesOff((_playerPrio || (_flags & kPrioPlay)) ? _chanReserveFlags : 0xFFFF);
_flags &= ~playFlag();
}
}
@@ -392,13 +437,13 @@ void CapcomPC98Player::nextTick() {
}
void CapcomPC98Player::storeEvent(uint32 evt) {
- if ((1 << (evt & 0x0f)) & _reservedChanFlags)
+ if ((1 << (evt & 0x0F)) & _chanReserveFlags)
return;
- uint8 st = evt & 0xff;
+ uint8 st = evt & 0xFF;
for (Common::Array<uint32>::iterator i = _storedEvents.begin(); i != _storedEvents.end(); ++i) {
- if ((*i & 0xff) == st) {
+ if ((*i & 0xFF) == st) {
*i = evt;
return;
}
@@ -406,7 +451,7 @@ void CapcomPC98Player::storeEvent(uint32 evt) {
st >>= 4;
- if (st == 0x0b || st == 0x0c || st == 0x0e)
+ if (st == 0x0B || st == 0x0C || st == 0x0E)
_storedEvents.push_back(evt);
}
@@ -417,7 +462,7 @@ void CapcomPC98Player::restorePlayer() {
_storedEvents.clear();
}
-CapcomPC98_MIDI::CapcomPC98_MIDI(MidiDriver::DeviceHandle dev, bool isMT32, MutexProc &mutexProc) : CapcomPC98Player(true, kStdPlay, 0xffff), _isMT32(isMT32), _mproc(mutexProc), _midi(nullptr), _programMapping(nullptr) {
+CapcomPC98_MIDI::CapcomPC98_MIDI(MidiDriver::DeviceHandle dev, bool isMT32, MutexProc &mutexProc) : CapcomPC98Player(true, kStdPlay, 0xFFFF, 0), _isMT32(isMT32), _mproc(mutexProc), _midi(nullptr), _programMapping(nullptr) {
_midi = MidiDriver::createMidi(dev);
uint8 *map = new uint8[128];
assert(map);
@@ -430,6 +475,7 @@ CapcomPC98_MIDI::CapcomPC98_MIDI(MidiDriver::DeviceHandle dev, bool isMT32, Mute
}
_programMapping = map;
+ memset(_chanVolume, 0, sizeof(_chanVolume));
}
CapcomPC98_MIDI::~CapcomPC98_MIDI() {
@@ -458,20 +504,25 @@ bool CapcomPC98_MIDI::init() {
return true;
}
-void CapcomPC98_MIDI::deinit() {
-
-}
-
void CapcomPC98_MIDI::reset() {
-
+ memset(_chanVolume, 0x7F, sizeof(_chanVolume));
}
void CapcomPC98_MIDI::send(uint32 evt) {
- if ((evt & 0xF0) == 0xC0) {
- evt = (evt & 0xFF) | (_programMapping[(evt >> 8) & 0xFF] << 8);
- } else if ((evt & 0xF0) == 0xB0 && ((evt >> 8) & 0xFF) == 3) {
- _soundMarkers[evt & 0x0F] = (evt >> 16) & 0xFF;
- return;
+ uint8 cmd = evt & 0xF0;
+ uint8 ch = evt & 0x0F;
+ uint8 p1 = (evt >> 8) & 0xFF;
+ uint8 p2 = (evt >> 16) & 0xFF;
+
+ if (cmd == 0xC0) {
+ evt = (evt & 0xFF) | (_programMapping[p1] << 8);
+ } else if (cmd == 0xB0) {
+ if (p1 == 3) {
+ _soundMarkers[ch] = p2;
+ return;
+ } else if (((evt >> 8) & 0xFF) == 7) {
+ _chanVolume[ch] = p2;
+ }
}
_midi->send(evt);
}
@@ -480,6 +531,13 @@ void CapcomPC98_MIDI::setMasterVolume (int vol) {
}
+void CapcomPC98_MIDI::processSounds() {
+ if (_fadeState) {
+ for (int i = 0; i < 16; ++i)
+ _midi->send(0x0007B0 | i | (CLIP<int>(_chanVolume[i] - _fadeState, 0, 127) << 16));
+ }
+}
+
PC98AudioCore::MutexLock CapcomPC98_MIDI::lockMutex() {
if (!_mproc.isValid())
error("CapcomPC98_MIDI::lockMutex(): Invalid call");
@@ -498,10 +556,10 @@ const uint8 CapcomPC98_MIDI::_programMapping_mt32ToGM[128] = {
0x70, 0x71, 0x72, 0x76, 0x75, 0x74, 0x73, 0x77, 0x78, 0x79, 0x7a, 0x7c, 0x7b, 0x7d, 0x7e, 0x7f
};
-CapcomPC98_FM_Channel::CapcomPC98_FM_Channel(uint8 id, PC98AudioCore *&ac, const Common::Array<const uint8*>&instruments) : _regOffset(id), _ac(ac), _instruments(instruments),
+CapcomPC98_FM_Channel::CapcomPC98_FM_Channel(uint8 id, PC98AudioCore *&ac, const Common::Array<const uint8*>&instruments, const uint8 &fadeState) : _regOffset(id), _ac(ac), _instruments(instruments),
_isPlaying(false), _note(0), _carrier(0), _volume(0), _velocity(0), _noteEffCur(0), _program(0), _noteEffPrev(0), _breathControl(0), _frequency(0), _modWheel(0), _pitchBendSensitivity(0),
_pitchBendPara(0), _pitchBendEff(0), _vbrState(0), _vbrStep(0), _vbrCycleTicker(0), _vbrDelayTicker(0), _vbrHandler(nullptr), _prtEnable(false),
- _prtTime(0), _prtState(0), _prtStep(0), _prtCycleLength(0) {
+ _prtTime(0), _prtState(0), _prtStep(0), _prtCycleLength(0), _fadeState(fadeState) {
typedef void (CapcomPC98_FM_Channel::*Proc)();
static const Proc procs[] = {
&CapcomPC98_FM_Channel::vbrHandler0,
@@ -533,7 +591,7 @@ CapcomPC98_FM_Channel::~CapcomPC98_FM_Channel() {
void CapcomPC98_FM_Channel::reset() {
_vbrHandler = _vbrHandlers[4];
- _frequency = 0xffff;
+ _frequency = 0xFFFF;
_vbrState = 0;
_prtState = 0;
_prtCycleLength = 0;
@@ -542,8 +600,8 @@ void CapcomPC98_FM_Channel::reset() {
_pitchBendEff = 0;
_pitchBendPara = 0;
_isPlaying = false;
- _note = 0xff;
- _volume = 0x7f;
+ _note = 0xFF;
+ _volume = 0x7F;
_velocity = _breathControl = 0x40;
_noteEffCur = 60;
_modWheel = 0;
@@ -580,10 +638,10 @@ void CapcomPC98_FM_Channel::noteOn(uint8 note, uint8 velo) {
if (!_isPlaying) {
updateVolume();
- _ac->writeReg(0, 0x28, _regOffset | 0xf0);
+ _ac->writeReg(0, 0x28, _regOffset | 0xF0);
}
- _isPlaying = true;
+ _isPlaying = true;
}
void CapcomPC98_FM_Channel::programChange(uint8 prg) {
@@ -591,10 +649,9 @@ void CapcomPC98_FM_Channel::programChange(uint8 prg) {
return;
_program = prg;
-
loadInstrument(_instruments[prg]);
- _ac->writeReg(0, 0xb0 + _regOffset, _instrument.fbl_alg);
+ _ac->writeReg(0, 0xB0 + _regOffset, _instrument.fbl_alg);
static const uint8 carriers[] = { 0x08, 0x08, 0x08, 0x08, 0x0C, 0x0E, 0x0E, 0x0F };
_carrier = carriers[_instrument.fbl_alg & 7];
@@ -620,6 +677,7 @@ void CapcomPC98_FM_Channel::pitchBend(uint16 pb) {
void CapcomPC98_FM_Channel::restore() {
programChange(_program);
+ _frequency = 0xFFFF;
}
void CapcomPC98_FM_Channel::modWheel(uint8 mw) {
@@ -642,7 +700,8 @@ void CapcomPC98_FM_Channel::portamentoTime(uint8 pt) {
void CapcomPC98_FM_Channel::volume(uint8 vol) {
_volume = vol;
- updateVolume();
+ if (_isPlaying)
+ updateVolume();
}
void CapcomPC98_FM_Channel::togglePortamento(uint8 enable) {
@@ -652,8 +711,8 @@ void CapcomPC98_FM_Channel::togglePortamento(uint8 enable) {
void CapcomPC98_FM_Channel::allNotesOff() {
_isPlaying = false;
for (int i = _regOffset; i < 16 + _regOffset; i += 4) {
- _ac->writeReg(0, 0x40 + i, 0x7f);
- _ac->writeReg(0, 0x80 + i, 0xff);
+ _ac->writeReg(0, 0x40 + i, 0x7F);
+ _ac->writeReg(0, 0x80 + i, 0xFF);
}
_ac->writeReg(0, 0x28, _regOffset);
}
@@ -666,6 +725,9 @@ void CapcomPC98_FM_Channel::processSounds() {
(*_vbrHandler)();
updatePortamento();
updateFrequency();
+
+ if (_fadeState)
+ updateVolume();
}
void CapcomPC98_FM_Channel::loadInstrument(const uint8 *in) {
@@ -694,44 +756,50 @@ void CapcomPC98_FM_Channel::updatePitchBend() {
void CapcomPC98_FM_Channel::updateVolume() {
uint8 cr = _carrier;
-
+ uint8 dbg[4];
const uint8 *s = _instrument.regData;
for (int i = _regOffset; i < 16 + _regOffset; i += 4) {
uint16 vol = 0;
if (cr & 1) {
- vol += _volTableOut[_volume];
- //vol += _fadeState;
+ vol += _volTableCarrier[_volume];
+ vol += _fadeState;
}
uint8 a = _breathControl;
uint8 b = s[10];
if (b & 0x80) {
- a = ~a & 0x7f;
- b &= 0x7f;
+ a = ~a & 0x7F;
+ b &= 0x7F;
}
- vol += (((_volTablePara[a] * b) & 0x7fff) >> 7);
+ vol += (((_volTablePara[a] * b) & 0x7FFF) >> 7);
a = _velocity;
b = s[7];
if (b & 0x80) {
- a = ~a & 0x7f;
- b &= 0x7f;
+ a = ~a & 0x7F;
+ b &= 0x7F;
}
- vol += (((_volTablePara[a] * b) & 0x7fff) >> 7);
+ vol += (((_volTablePara[a] * b) & 0x7FFF) >> 7);
a = _volTablesInst[s[8] & 3][_noteEffCur];
b = s[9];
if (b & 0x80) {
- a = ~a & 0x7f;
- b &= 0x7f;
+ a = ~a & 0x7F;
+ b &= 0x7F;
}
- vol += (((a * b) & 0x7fff) >> 7);
+ vol += (((a * b) & 0x7FFF) >> 7);
vol += s[1];
- vol = MIN<uint16>(vol, 0x7f);
- _ac->writeReg(0, 0x40 + i, vol & 0xff);
+ if (vol > 0x7f)
+ vol=vol;
+
+ vol = MIN<uint16>(vol, 0x7F);
+
+ _ac->writeReg(0, 0x40 + i, vol & 0xFF);
s += 13;
cr >>= 1;
+
+ dbg[i >> 2] = vol & 0xff;
}
}
@@ -746,21 +814,21 @@ void CapcomPC98_FM_Channel::updatePortamento() {
void CapcomPC98_FM_Channel::updateFrequency() {
int16 tone = (MIN<int16>(_modWheel + _instrument.vbrSensitivity, 255) * (_vbrState >> 16)) >> 8;
- tone = CLIP<int16>(tone + (_noteEffCur << 8), 0, 0x5fff);
- tone = CLIP<int16>(tone + _pitchBendEff, 0, 0x5fff);
- tone = CLIP<int16>(tone + (_prtState >> 16), 0, 0x5fff);
+ tone = CLIP<int16>(tone + (_noteEffCur << 8), 0, 0x5FFF);
+ tone = CLIP<int16>(tone + _pitchBendEff, 0, 0x5FFF);
+ tone = CLIP<int16>(tone + (_prtState >> 16), 0, 0x5FFF);
uint8 block = ((tone >> 8) / 12) & 7;
uint8 msb = (tone >> 8) % 12;
- uint8 lsb = (tone & 0xff) >> 2;
+ uint8 lsb = (tone & 0xFF) >> 2;
uint16 freq = (block << 11) + _freqMSBTable[msb] + _freqLSBTables[msb][lsb];
if (_frequency == freq)
return;
_frequency = freq;
- _ac->writeReg(0, 0xa4 + _regOffset, freq >> 8);
- _ac->writeReg(0, 0xa0 + _regOffset, freq & 0xff);
+ _ac->writeReg(0, 0xA4 + _regOffset, freq >> 8);
+ _ac->writeReg(0, 0xA0 + _regOffset, freq & 0xFF);
}
void CapcomPC98_FM_Channel::setupPortamento() {
@@ -770,7 +838,7 @@ void CapcomPC98_FM_Channel::setupPortamento() {
return;
}
- int16 diff = (_noteEffCur << 8) - CLIP<int16>((_prtState >> 16) | (_noteEffPrev << 8), 0, 0x5fff);
+ int16 diff = (_noteEffCur << 8) - CLIP<int16>((_prtState >> 16) | (_noteEffPrev << 8), 0, 0x5FFF);
_prtCycleLength = _prtTime;
_prtStep = (diff << 16) / _prtTime;
_prtState = (-diff << 16);
@@ -991,7 +1059,7 @@ const uint8 CapcomPC98_FM_Channel::_volTablesInst[4][128] = {
}
};
-const uint8 CapcomPC98_FM_Channel::_volTableOut[] = {
+const uint8 CapcomPC98_FM_Channel::_volTableCarrier[] = {
0x2a, 0x2a, 0x29, 0x29, 0x29, 0x28, 0x28, 0x28, 0x27, 0x27, 0x27, 0x26, 0x26, 0x26, 0x25, 0x25,
0x25, 0x24, 0x24, 0x24, 0x23, 0x23, 0x23, 0x22, 0x22, 0x22, 0x21, 0x21, 0x21, 0x20, 0x20, 0x20,
0x1f, 0x1f, 0x1f, 0x1e, 0x1e, 0x1e, 0x1d, 0x1d, 0x1d, 0x1c, 0x1c, 0x1c, 0x1b, 0x1b, 0x1b, 0x1a,
@@ -1013,13 +1081,13 @@ const uint8 CapcomPC98_FM_Channel::_volTablePara[] = {
0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00
};
-CapcomPC98_FM::CapcomPC98_FM(Audio::Mixer *mixer, CBProc &proc, bool playerPrio, uint16 playerFlag, uint8 reservedChanFlags, bool needsTimer) : CapcomPC98Player(playerPrio, playerFlag, reservedChanFlags), PC98AudioPluginDriver(), _cbProc(proc), _ac(nullptr), _chan(nullptr), _ready(false) {
+CapcomPC98_FM::CapcomPC98_FM(Audio::Mixer *mixer, CBProc &proc, bool playerPrio, uint16 playFlags, uint8 chanReserveFlags, uint8 chanDisableFlags, bool needsTimer) : CapcomPC98Player(playerPrio, playFlags, chanReserveFlags, chanDisableFlags), PC98AudioPluginDriver(), _cbProc(proc), _ac(nullptr), _chan(nullptr), _ready(false) {
_ac = new PC98AudioCore(mixer, needsTimer ? this : nullptr, kType26);
assert(_ac);
_chan = new CapcomPC98_FM_Channel*[3];
assert(_chan);
for (int i = 0; i < 3; ++i)
- _chan[i] = new CapcomPC98_FM_Channel(i, _ac, _instruments);
+ _chan[i] = new CapcomPC98_FM_Channel(i, _ac, _instruments, _fadeState);
}
CapcomPC98_FM::~CapcomPC98_FM() {
@@ -1052,8 +1120,9 @@ bool CapcomPC98_FM::init() {
for (int i = 0; i < 3; ++i)
_ac->writeReg(0, 0xB0 + i, 0xC0);
- _ac->writeReg(0, 0x26, 230);
- _ac->writeReg(0, 0x27, 0x2a);
+ _ac->writeReg(0, 0x24, 0x91);
+ _ac->writeReg(0, 0x25, 0x00);
+ _ac->writeReg(0, 0x27, 0x15);
loadInstruments(_initData, 1);
@@ -1099,14 +1168,14 @@ PC98AudioCore::MutexLock CapcomPC98_FM::lockMutex() {
}
void CapcomPC98_FM::send(uint32 evt) {
- uint8 ch = evt & 0x0f;
- uint8 p1 = (evt >> 8) & 0xff;
- uint8 p2 = (evt >> 16) & 0xff;
+ uint8 ch = evt & 0x0F;
+ uint8 p1 = (evt >> 8) & 0xFF;
+ uint8 p2 = (evt >> 16) & 0xFF;
if (ch > 2)
return;
- switch (evt & 0xf0) {
+ switch (evt & 0xF0) {
case 0x80:
_chan[ch]->noteOff(p1);
break;
@@ -1116,14 +1185,14 @@ void CapcomPC98_FM::send(uint32 evt) {
else
_chan[ch]->noteOff(p1);
break;
- case 0xb0:
+ case 0xB0:
controlChange(ch, p1, p2);
break;
- case 0xc0:
+ case 0xC0:
_chan[ch]->programChange(p1);
break;
- case 0xe0:
- _chan[ch]->pitchBend(((p2 & 0x7f) << 7) | (p1 & 0x7f));
+ case 0xE0:
+ _chan[ch]->pitchBend(((p2 & 0x7F) << 7) | (p1 & 0x7F));
break;
default:
break;
@@ -1131,7 +1200,7 @@ void CapcomPC98_FM::send(uint32 evt) {
}
-void CapcomPC98_FM::timerCallbackB() {
+void CapcomPC98_FM::timerCallbackA() {
if (_ready && _cbProc.isValid()) {
PC98AudioCore::MutexLock lock = _ac->stackLockMutex();
_cbProc();
@@ -1179,7 +1248,7 @@ void CapcomPC98_FM::controlChange(uint8 ch, uint8 control, uint8 val) {
void CapcomPC98_FM::restoreStateIntern() {
for (int i = 0; i < 3; ++i) {
- if ((1 << i) & _reservedChanFlags)
+ if ((1 << i) & _chanReserveFlags)
continue;
_chan[i]->restore();
}
@@ -1204,11 +1273,11 @@ CapcomPC98AudioDriverInternal::CapcomPC98AudioDriverInternal(Audio::Mixer *mixer
if (type == MT_MT32 || type == MT_GM) {
_players[0] = new CapcomPC98_MIDI(dev, type == MT_MT32, *_mutexProc);
- _players[1] = _fmDevice = new CapcomPC98_FM(mixer, *_timerProc, true, CapcomPC98Player::kPrioPlay, 7, true);
+ _players[1] = _fmDevice = new CapcomPC98_FM(mixer, *_timerProc, true, CapcomPC98Player::kPrioPlay, 4, (uint8)~4, true);
_marker = 1;
} else {
- _players[0] = new CapcomPC98_FM(mixer, *_timerProc, false, CapcomPC98Player::kStdPlay, 3, false);
- _players[1] = _fmDevice = new CapcomPC98_FM(mixer, *_timerProc, true, CapcomPC98Player::kPrioPlay | CapcomPC98Player::kPrioClaim, 4, true);
+ _players[0] = new CapcomPC98_FM(mixer, *_timerProc, false, CapcomPC98Player::kStdPlay, 3, 0, false);
+ _players[1] = _fmDevice = new CapcomPC98_FM(mixer, *_timerProc, true, CapcomPC98Player::kPrioPlay | CapcomPC98Player::kPrioClaim, 4, (uint8)~4, true);
}
bool ready = true;
@@ -1293,11 +1362,25 @@ int CapcomPC98AudioDriverInternal::checkSoundMarker() const {
}
bool CapcomPC98AudioDriverInternal::songIsPlaying() const {
- return CapcomPC98Player::getPlayerStatus() & CapcomPC98Player::kStdPlay;
+ return CapcomPC98Player::getStatus() & CapcomPC98Player::kStdPlay;
}
bool CapcomPC98AudioDriverInternal::soundEffectIsPlaying() const {
- return CapcomPC98Player::getPlayerStatus() & CapcomPC98Player::kPrioPlay;
+ return CapcomPC98Player::getStatus() & CapcomPC98Player::kPrioPlay;
+}
+
+void CapcomPC98AudioDriverInternal::fadeOut() {
+ if (!_ready)
+ return;
+ for (int i = 0; i < 2; ++i)
+ _players[i]->fadeOut(1);
+}
+
+void CapcomPC98AudioDriverInternal::allNotesOff() {
+ if (!_ready)
+ return;
+ for (int i = 0; i < 2; ++i)
+ _players[i]->allNotesOff();
}
void CapcomPC98AudioDriverInternal::setMusicVolume(int volume) {
@@ -1384,6 +1467,16 @@ bool CapcomPC98AudioDriver::soundEffectIsPlaying() const {
return _drv ? _drv->soundEffectIsPlaying() : false;
}
+void CapcomPC98AudioDriver::fadeOut() {
+ if (_drv)
+ _drv->fadeOut();
+}
+
+void CapcomPC98AudioDriver::allNotesOff() {
+ if (_drv)
+ _drv->allNotesOff();
+}
+
void CapcomPC98AudioDriver::setMusicVolume(int volume) {
if (_drv)
_drv->setMusicVolume(volume);
diff --git a/engines/kyra/sound/drivers/capcom98.h b/engines/kyra/sound/drivers/capcom98.h
index 869f1ac0da3..95c8617d11d 100644
--- a/engines/kyra/sound/drivers/capcom98.h
+++ b/engines/kyra/sound/drivers/capcom98.h
@@ -49,10 +49,14 @@ public:
void stopSong();
void startSoundEffect(const uint8 *data, uint8 volume);
void stopSoundEffect();
+
int checkSoundMarker() const;
bool songIsPlaying() const;
bool soundEffectIsPlaying() const;
+ void fadeOut();
+ void allNotesOff();
+
void setMusicVolume(int volume);
void setSoundEffectVolume(int volume);
diff --git a/engines/kyra/sound/sound_intern.h b/engines/kyra/sound/sound_intern.h
index aa0dc70c679..f31cb36a69e 100644
--- a/engines/kyra/sound/sound_intern.h
+++ b/engines/kyra/sound/sound_intern.h
@@ -559,11 +559,12 @@ public:
void beginFadeOut() override;
+ void pause(bool paused) override;
+
void updateVolumeSettings() override;
int checkTrigger() override;
-
- void resetTrigger() override;
+ void resetTrigger() override {} // This sound class is for EOB II only, this method is not needed there.
private:
void restartBackgroundMusic();
diff --git a/engines/kyra/sound/sound_pc98_darkmoon.cpp b/engines/kyra/sound/sound_pc98_darkmoon.cpp
index 0b56e627d9f..1b70b0395e8 100644
--- a/engines/kyra/sound/sound_pc98_darkmoon.cpp
+++ b/engines/kyra/sound/sound_pc98_darkmoon.cpp
@@ -182,16 +182,16 @@ void SoundPC98_Darkmoon::stopAllSoundEffects() {
}
void SoundPC98_Darkmoon::beginFadeOut() {
- haltTrack();
- stopAllSoundEffects();
+ _driver->fadeOut();
}
-int SoundPC98_Darkmoon::checkTrigger() {
- return _driver ? _driver->checkSoundMarker() : 99;
+void SoundPC98_Darkmoon::pause(bool paused) {
+ if (_ready && paused)
+ _driver->allNotesOff();
}
-void SoundPC98_Darkmoon::resetTrigger() {
-
+int SoundPC98_Darkmoon::checkTrigger() {
+ return _driver ? _driver->checkSoundMarker() : 99;
}
void SoundPC98_Darkmoon::restartBackgroundMusic() {
More information about the Scummvm-git-logs
mailing list