aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2015-03-05 12:16:24 -0500
committerPaul Gilbert2015-03-05 12:16:24 -0500
commit3fae9f17dacaa4f8253c2f6b47adb9845cdb52b0 (patch)
tree44b593f739f45450ceef60aa89ddf456a136abee
parentf501e91ed1490fde5227015dc02fbe6c0cee2b5f (diff)
downloadscummvm-rg350-3fae9f17dacaa4f8253c2f6b47adb9845cdb52b0.tar.gz
scummvm-rg350-3fae9f17dacaa4f8253c2f6b47adb9845cdb52b0.tar.bz2
scummvm-rg350-3fae9f17dacaa4f8253c2f6b47adb9845cdb52b0.zip
MADS: Show a warning if sound code reads beyond end of sound data blocks
-rw-r--r--engines/mads/nebular/sound_nebular.cpp24
-rw-r--r--engines/mads/nebular/sound_nebular.h20
2 files changed, 40 insertions, 4 deletions
diff --git a/engines/mads/nebular/sound_nebular.cpp b/engines/mads/nebular/sound_nebular.cpp
index 0a054440b2..d41d0075eb 100644
--- a/engines/mads/nebular/sound_nebular.cpp
+++ b/engines/mads/nebular/sound_nebular.cpp
@@ -36,6 +36,7 @@ namespace Nebular {
bool AdlibChannel::_channelsEnabled;
AdlibChannel::AdlibChannel() {
+ _owner = nullptr;
_activeCount = 0;
_field1 = 0;
_field2 = 0;
@@ -55,6 +56,7 @@ AdlibChannel::AdlibChannel() {
_pSrc = nullptr;
_ptr3 = nullptr;
_ptr4 = nullptr;
+ _ptrEnd = nullptr;
_field17 = 0;
_field19 = 0;
_soundData = nullptr;
@@ -108,6 +110,9 @@ void AdlibChannel::load(byte *pData) {
_fieldB = 0;
_field17 = 0;
_field19 = 0;
+
+ CachedDataEntry &cacheEntry = _owner->getCachedData(pData);
+ _ptrEnd = cacheEntry._dataEnd;
}
void AdlibChannel::check(byte *nullPtr) {
@@ -192,6 +197,9 @@ ASound::ASound(Audio::Mixer *mixer, FM_OPL *opl, const Common::String &filename,
_channelData[i]._freqBase = 0;
_channelData[i]._field6 = 0;
}
+
+ for (int i = 0; i < ADLIB_CHANNEL_COUNT; ++i)
+ _channels[i]._owner = this;
AdlibChannel::_channelsEnabled = false;
@@ -283,6 +291,17 @@ void ASound::noise() {
}
}
+CachedDataEntry &ASound::getCachedData(byte *pData) {
+ Common::List<CachedDataEntry>::iterator i;
+ for (i = _dataCache.begin(); i != _dataCache.end(); ++i) {
+ CachedDataEntry &e = *i;
+ if (e._data == pData)
+ return e;
+ }
+
+ error("Could not find previously loaded data");
+}
+
void ASound::write(int reg, int val) {
_queue.push(RegisterValue(reg, val));
}
@@ -331,6 +350,7 @@ byte *ASound::loadData(int offset, int size) {
CachedDataEntry rec;
rec._offset = offset;
rec._data = new byte[size];
+ rec._dataEnd = rec._data + size - 1;
_soundFile.seek(_dataOffset + offset);
_soundFile.read(rec._data, size);
_dataCache.push_back(rec);
@@ -449,6 +469,10 @@ void ASound::pollActiveChannel() {
warning("pollActiveChannel(): No data found for sound channel");
break;
}
+ if (pSrc > chan->_ptrEnd) {
+ warning("Read beyond end of loaded sound data");
+ }
+
if (!(*pSrc & 0x80) || (*pSrc <= 0xF0)) {
if (updateFlag)
updateActiveChannel();
diff --git a/engines/mads/nebular/sound_nebular.h b/engines/mads/nebular/sound_nebular.h
index ccfd40ad52..cfacb211a4 100644
--- a/engines/mads/nebular/sound_nebular.h
+++ b/engines/mads/nebular/sound_nebular.h
@@ -37,11 +37,15 @@ class SoundManager;
namespace Nebular {
+class ASound;
+
/**
* Represents the data for a channel on the Adlib
*/
class AdlibChannel {
public:
+ ASound *_owner;
+
int _activeCount;
int _field1;
int _field2;
@@ -61,6 +65,7 @@ public:
byte *_pSrc;
byte *_ptr3;
byte *_ptr4;
+ byte *_ptrEnd;
int _field17;
int _field19;
byte *_soundData;
@@ -128,15 +133,17 @@ struct RegisterValue {
#define ADLIB_CHANNEL_MIDWAY 5
#define CALLBACKS_PER_SECOND 60
+struct CachedDataEntry {
+ int _offset;
+ byte *_data;
+ byte *_dataEnd;
+};
+
/**
* Base class for the sound player resource files
*/
class ASound : public Audio::AudioStream {
private:
- struct CachedDataEntry {
- int _offset;
- byte *_data;
- };
Common::List<CachedDataEntry> _dataCache;
uint16 _randomSeed;
@@ -350,6 +357,11 @@ public:
*/
int getFrameCounter() { return _frameCounter; }
+ /**
+ * Return the cached data block record for previously loaded sound data
+ */
+ CachedDataEntry &getCachedData(byte *pData);
+
// AudioStream interface
/**
* Main buffer read