mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-20 08:48:13 +00:00
LASTEXPRESS: Move more entry-related functions to Entry class
This commit is contained in:
parent
3384f4bf82
commit
d1341387e3
@ -161,15 +161,15 @@ void SoundManager::handleTimer() {
|
||||
|
||||
for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
|
||||
SoundEntry *entry = (*i);
|
||||
if (entry->stream == NULL) {
|
||||
if (entry->_stream == NULL) {
|
||||
SAFE_DELETE(*i);
|
||||
i = _soundList.reverse_erase(i);
|
||||
continue;
|
||||
} else if (!entry->soundStream) {
|
||||
entry->soundStream = new StreamedSound();
|
||||
} else if (!entry->_soundStream) {
|
||||
entry->_soundStream = new StreamedSound();
|
||||
|
||||
// TODO: stream any sound in the queue after filtering
|
||||
entry->soundStream->load(entry->stream);
|
||||
entry->_soundStream->load(entry->_stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -189,7 +189,7 @@ void SoundManager::resetQueue(SoundType type1, SoundType type2) {
|
||||
Common::StackLock locker(_mutex);
|
||||
|
||||
for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
|
||||
if ((*i)->type != type1 && (*i)->type != type2)
|
||||
if ((*i)->getType() != type1 && (*i)->getType() != type2)
|
||||
(*i)->reset();
|
||||
}
|
||||
}
|
||||
@ -226,7 +226,7 @@ void SoundManager::clearQueue() {
|
||||
SoundEntry *entry = (*i);
|
||||
|
||||
// Delete entry
|
||||
removeEntry(entry);
|
||||
entry->close();
|
||||
SAFE_DELETE(entry);
|
||||
|
||||
i = _soundList.reverse_erase(i);
|
||||
@ -247,7 +247,7 @@ bool SoundManager::isBuffered(Common::String filename, bool testForEntity) {
|
||||
SoundEntry *entry = getEntry(filename);
|
||||
|
||||
if (testForEntity)
|
||||
return entry != NULL && !entry->entity;
|
||||
return entry != NULL && entry->getEntity() != kEntityPlayer;
|
||||
|
||||
return (entry != NULL);
|
||||
}
|
||||
@ -255,96 +255,8 @@ bool SoundManager::isBuffered(Common::String filename, bool testForEntity) {
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Entry
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void SoundManager::setupEntry(SoundEntry *entry, Common::String name, SoundFlag flag, int priority) {
|
||||
if (!entry)
|
||||
error("SoundManager::setupEntry: Invalid entry!");
|
||||
|
||||
entry->priority = priority;
|
||||
setEntryType(entry, flag);
|
||||
entry->setStatus(flag);
|
||||
|
||||
// Add entry to sound list
|
||||
_soundList.push_back(entry);
|
||||
|
||||
// TODO Add entry to cache and load sound data
|
||||
//setupCache(entry);
|
||||
loadSoundData(entry, name);
|
||||
}
|
||||
|
||||
void SoundManager::setEntryType(SoundEntry *entry, SoundFlag flag) {
|
||||
switch (flag & kFlagType9) {
|
||||
default:
|
||||
case kFlagNone:
|
||||
entry->type = _currentType;
|
||||
_currentType = (SoundType)(_currentType + 1);
|
||||
break;
|
||||
|
||||
case kFlagType1_2: {
|
||||
SoundEntry *previous2 = getEntry(kSoundType2);
|
||||
if (previous2)
|
||||
previous2->update(0);
|
||||
|
||||
SoundEntry *previous = getEntry(kSoundType1);
|
||||
if (previous) {
|
||||
previous->type = kSoundType2;
|
||||
previous->update(0);
|
||||
}
|
||||
|
||||
entry->type = kSoundType1;
|
||||
}
|
||||
break;
|
||||
|
||||
case kFlagType3: {
|
||||
SoundEntry *previous = getEntry(kSoundType3);
|
||||
if (previous) {
|
||||
previous->type = kSoundType4;
|
||||
previous->update(0);
|
||||
}
|
||||
|
||||
entry->type = kSoundType11;
|
||||
}
|
||||
break;
|
||||
|
||||
case kFlagType7: {
|
||||
SoundEntry *previous = getEntry(kSoundType7);
|
||||
if (previous)
|
||||
previous->type = kSoundType8;
|
||||
|
||||
entry->type = kSoundType7;
|
||||
}
|
||||
break;
|
||||
|
||||
case kFlagType9: {
|
||||
SoundEntry *previous = getEntry(kSoundType9);
|
||||
if (previous)
|
||||
previous->type = kSoundType10;
|
||||
|
||||
entry->type = kSoundType9;
|
||||
}
|
||||
break;
|
||||
|
||||
case kFlagType11: {
|
||||
SoundEntry *previous = getEntry(kSoundType11);
|
||||
if (previous)
|
||||
previous->type = kSoundType14;
|
||||
|
||||
entry->type = kSoundType11;
|
||||
}
|
||||
break;
|
||||
|
||||
case kFlagType13: {
|
||||
SoundEntry *previous = getEntry(kSoundType13);
|
||||
if (previous)
|
||||
previous->type = kSoundType14;
|
||||
|
||||
entry->type = kSoundType13;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool SoundManager::setupCache(SoundEntry *entry) {
|
||||
if (entry->soundData)
|
||||
if (entry->_soundData)
|
||||
return true;
|
||||
|
||||
if (_soundCache.size() >= SOUNDCACHE_MAX_SIZE) {
|
||||
@ -353,8 +265,8 @@ bool SoundManager::setupCache(SoundEntry *entry) {
|
||||
uint32 size = 1000;
|
||||
|
||||
for (Common::List<SoundEntry *>::iterator i = _soundCache.begin(); i != _soundCache.end(); ++i) {
|
||||
if (!((*i)->status.status & kSoundStatus_180)) {
|
||||
uint32 newSize = (*i)->priority + ((*i)->status.status & kSoundStatusClear1);
|
||||
if (!((*i)->_status.status & kSoundStatus_180)) {
|
||||
uint32 newSize = (*i)->_priority + ((*i)->_status.status & kSoundStatusClear1);
|
||||
|
||||
if (newSize < size) {
|
||||
cacheEntry = (*i);
|
||||
@ -363,7 +275,7 @@ bool SoundManager::setupCache(SoundEntry *entry) {
|
||||
}
|
||||
}
|
||||
|
||||
if (entry->priority <= size)
|
||||
if (entry->_priority <= size)
|
||||
return false;
|
||||
|
||||
if (!cacheEntry)
|
||||
@ -372,17 +284,17 @@ bool SoundManager::setupCache(SoundEntry *entry) {
|
||||
cacheEntry->setInCache();
|
||||
|
||||
// TODO: Wait until the cache entry is ready to be removed
|
||||
while (!(cacheEntry->status.status1 & 1))
|
||||
while (!(cacheEntry->_status.status1 & 1))
|
||||
;
|
||||
|
||||
if (cacheEntry->soundData)
|
||||
if (cacheEntry->_soundData)
|
||||
removeFromCache(cacheEntry);
|
||||
|
||||
_soundCache.push_back(entry);
|
||||
entry->soundData = (char *)_soundCacheData + SOUNDCACHE_ENTRY_SIZE * (_soundCache.size() - 1);
|
||||
entry->_soundData = (char *)_soundCacheData + SOUNDCACHE_ENTRY_SIZE * (_soundCache.size() - 1);
|
||||
} else {
|
||||
_soundCache.push_back(entry);
|
||||
entry->soundData = (char *)_soundCacheData + SOUNDCACHE_ENTRY_SIZE * (_soundCache.size() - 1);
|
||||
entry->_soundData = (char *)_soundCacheData + SOUNDCACHE_ENTRY_SIZE * (_soundCache.size() - 1);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -392,7 +304,7 @@ void SoundManager::removeFromCache(SoundEntry *entry) {
|
||||
for (Common::List<SoundEntry *>::iterator i = _soundCache.begin(); i != _soundCache.end(); ++i) {
|
||||
if ((*i) == entry) {
|
||||
// Remove sound buffer
|
||||
entry->soundData = NULL;
|
||||
entry->_soundData = NULL;
|
||||
|
||||
// Remove entry from sound cache
|
||||
i = _soundCache.reverse_erase(i);
|
||||
@ -404,48 +316,7 @@ void SoundManager::clearStatus() {
|
||||
Common::StackLock locker(_mutex);
|
||||
|
||||
for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
|
||||
(*i)->status.status |= kSoundStatusClear3;
|
||||
}
|
||||
|
||||
void SoundManager::loadSoundData(SoundEntry *entry, Common::String name) {
|
||||
entry->name2 = name;
|
||||
|
||||
// Load sound data
|
||||
entry->stream = getArchive(name);
|
||||
|
||||
if (!entry->stream)
|
||||
entry->stream = getArchive("DEFAULT.SND");
|
||||
|
||||
if (entry->stream) {
|
||||
warning("Sound::loadSoundData: not implemented!");
|
||||
} else {
|
||||
entry->status.status = kSoundStatusRemoved;
|
||||
}
|
||||
}
|
||||
|
||||
void SoundManager::removeEntry(SoundEntry *entry) {
|
||||
entry->status.status |= kSoundStatusRemoved;
|
||||
|
||||
// Loop until ready
|
||||
while (!(entry->status.status1 & 4) && !(_flag & 8) && (_flag & 1))
|
||||
; // empty loop body
|
||||
|
||||
// The original game remove the entry from the cache here,
|
||||
// but since we are called from within an iterator loop
|
||||
// we will remove the entry there
|
||||
// removeFromCache(entry);
|
||||
|
||||
if (entry->subtitle) {
|
||||
entry->subtitle->draw();
|
||||
SAFE_DELETE(entry->subtitle);
|
||||
}
|
||||
|
||||
if (entry->entity) {
|
||||
if (entry->entity == kEntitySteam)
|
||||
playLoopingSound(2);
|
||||
else if (entry->entity != kEntityTrain)
|
||||
getSavePoints()->push(kEntityPlayer, entry->entity, kActionEndSound);
|
||||
}
|
||||
(*i)->_status.status |= kSoundStatusClear3;
|
||||
}
|
||||
|
||||
void SoundManager::processEntry(EntityIndex entity) {
|
||||
@ -454,7 +325,7 @@ void SoundManager::processEntry(EntityIndex entity) {
|
||||
SoundEntry *entry = getEntry(entity);
|
||||
if (entry) {
|
||||
entry->update(0);
|
||||
entry->entity = kEntityPlayer;
|
||||
entry->setEntity(kEntityPlayer);
|
||||
}
|
||||
}
|
||||
|
||||
@ -471,7 +342,7 @@ void SoundManager::setupEntry(SoundType type, EntityIndex index) {
|
||||
|
||||
SoundEntry *entry = getEntry(type);
|
||||
if (entry)
|
||||
entry->entity = index;
|
||||
entry->setEntity(index);
|
||||
}
|
||||
|
||||
void SoundManager::processEntry(Common::String filename) {
|
||||
@ -480,7 +351,7 @@ void SoundManager::processEntry(Common::String filename) {
|
||||
SoundEntry *entry = getEntry(filename);
|
||||
if (entry) {
|
||||
entry->update(0);
|
||||
entry->entity = kEntityPlayer;
|
||||
entry->setEntity(kEntityPlayer);
|
||||
}
|
||||
}
|
||||
|
||||
@ -496,7 +367,7 @@ uint32 SoundManager::getEntryTime(EntityIndex index) {
|
||||
|
||||
SoundEntry *entry = getEntry(index);
|
||||
if (entry)
|
||||
return entry->time;
|
||||
return entry->_time;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -515,7 +386,7 @@ void SoundManager::unknownFunction4() {
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
SoundEntry *SoundManager::getEntry(EntityIndex index) {
|
||||
for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
|
||||
if ((*i)->entity == index)
|
||||
if ((*i)->getEntity() == index)
|
||||
return *i;
|
||||
}
|
||||
|
||||
@ -527,7 +398,7 @@ SoundEntry *SoundManager::getEntry(Common::String name) {
|
||||
name += ".SND";
|
||||
|
||||
for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
|
||||
if ((*i)->name2 == name)
|
||||
if ((*i)->_name2 == name)
|
||||
return *i;
|
||||
}
|
||||
|
||||
@ -536,7 +407,7 @@ SoundEntry *SoundManager::getEntry(Common::String name) {
|
||||
|
||||
SoundEntry *SoundManager::getEntry(SoundType type) {
|
||||
for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
|
||||
if ((*i)->type == type)
|
||||
if ((*i)->getType() == type)
|
||||
return *i;
|
||||
}
|
||||
|
||||
@ -547,6 +418,8 @@ SoundEntry *SoundManager::getEntry(SoundType type) {
|
||||
// Savegame
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void SoundManager::saveLoadWithSerializer(Common::Serializer &s) {
|
||||
Common::StackLock locker(_mutex);
|
||||
|
||||
s.syncAsUint32LE(_state);
|
||||
s.syncAsUint32LE(_currentType);
|
||||
|
||||
@ -554,39 +427,12 @@ void SoundManager::saveLoadWithSerializer(Common::Serializer &s) {
|
||||
uint32 numEntries = count();
|
||||
s.syncAsUint32LE(numEntries);
|
||||
|
||||
Common::StackLock locker(_mutex);
|
||||
|
||||
// Save or load each entry data
|
||||
if (s.isSaving()) {
|
||||
for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
|
||||
SoundEntry *entry = *i;
|
||||
if (entry->name2.matchString("NISSND?") && (entry->status.status & kFlagType7) != kFlag3) {
|
||||
s.syncAsUint32LE(entry->status.status); // status;
|
||||
s.syncAsUint32LE(entry->type); // type;
|
||||
s.syncAsUint32LE(entry->blockCount); // field_8;
|
||||
s.syncAsUint32LE(entry->time); // time;
|
||||
s.syncAsUint32LE(entry->field_34); // field_10;
|
||||
s.syncAsUint32LE(entry->field_38); // field_14;
|
||||
s.syncAsUint32LE(entry->entity); // entity;
|
||||
|
||||
uint32 blockCount = (uint32)entry->field_48 - _data2;
|
||||
if (blockCount > kFlag8)
|
||||
blockCount = 0;
|
||||
s.syncAsUint32LE(blockCount); // blockCount;
|
||||
|
||||
s.syncAsUint32LE(entry->priority); // field_20;
|
||||
|
||||
char name1[16];
|
||||
strcpy((char *)&name1, entry->name1.c_str());
|
||||
s.syncBytes((byte *)&name1, 16);
|
||||
|
||||
char name2[16];
|
||||
strcpy((char *)&name2, entry->name2.c_str());
|
||||
s.syncBytes((byte *)&name2, 16);
|
||||
}
|
||||
}
|
||||
for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
|
||||
(*i)->saveLoadWithSerializer(s);
|
||||
} else {
|
||||
warning("Sound::saveLoadWithSerializer: not implemented!");
|
||||
warning("Sound::saveLoadWithSerializer: loading not implemented");
|
||||
s.skip(numEntries * 64);
|
||||
}
|
||||
}
|
||||
@ -600,7 +446,7 @@ uint32 SoundManager::count() {
|
||||
|
||||
uint32 numEntries = 0;
|
||||
for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
|
||||
if ((*i)->name2.matchString("NISSND?"))
|
||||
if ((*i)->_name2.matchString("NISSND?"))
|
||||
++numEntries;
|
||||
|
||||
return numEntries;
|
||||
@ -629,12 +475,12 @@ bool SoundManager::playSoundWithSubtitles(Common::String filename, SoundFlag fla
|
||||
|
||||
Common::StackLock locker(_mutex);
|
||||
|
||||
setupEntry(entry, filename, flag, 30);
|
||||
entry->entity = entity;
|
||||
entry->open(filename, flag, 30);
|
||||
entry->_entity = entity;
|
||||
|
||||
if (a4) {
|
||||
entry->field_48 = _data2 + 2 * a4;
|
||||
entry->status.status |= kSoundStatus_8000;
|
||||
entry->_field_48 = _data2 + 2 * a4;
|
||||
entry->_status.status |= kSoundStatus_8000;
|
||||
} else {
|
||||
// Get subtitles name
|
||||
while (filename.size() > 4)
|
||||
@ -644,7 +490,7 @@ bool SoundManager::playSoundWithSubtitles(Common::String filename, SoundFlag fla
|
||||
entry->updateState();
|
||||
}
|
||||
|
||||
return (entry->type != kSoundTypeNone);
|
||||
return (entry->getType() != kSoundTypeNone);
|
||||
}
|
||||
|
||||
void SoundManager::playSoundEvent(EntityIndex entity, byte action, byte a3) {
|
||||
@ -1763,16 +1609,16 @@ void SoundManager::updateSubtitles() {
|
||||
for (Common::List<SubtitleEntry *>::iterator i = _subtitles.begin(); i != _subtitles.end(); ++i) {
|
||||
uint32 current_index = 0;
|
||||
SoundEntry *soundEntry = (*i)->getSoundEntry();
|
||||
SoundStatus status = (SoundStatus)soundEntry->status.status;
|
||||
SoundStatus status = (SoundStatus)soundEntry->_status.status;
|
||||
|
||||
if (!(status & kSoundStatus_40)
|
||||
|| status & 0x180
|
||||
|| soundEntry->time == 0
|
||||
|| (status & 0x1F) < 6
|
||||
|| ((getFlags()->nis & 0x8000) && soundEntry->priority < 90)) {
|
||||
|| status & kSoundStatus_180
|
||||
|| soundEntry->_time == 0
|
||||
|| (status & kSoundStatusClear1) < 6
|
||||
|| ((getFlags()->nis & 0x8000) && soundEntry->_priority < 90)) {
|
||||
current_index = 0;
|
||||
} else {
|
||||
current_index = soundEntry->priority + (status & 0x1F);
|
||||
current_index = soundEntry->_priority + (status & kSoundStatusClear1);
|
||||
|
||||
if (_currentSubtitle == (*i))
|
||||
current_index += 4;
|
||||
@ -1808,15 +1654,15 @@ void SoundManager::playLoopingSound(int param) {
|
||||
char tmp[80];
|
||||
|
||||
for (snd = _soundList.begin(); snd != _soundList.end(); ++snd) {
|
||||
if ((*snd)->type == kSoundType1)
|
||||
if ((*snd)->getType() == kSoundType1)
|
||||
break;
|
||||
}
|
||||
|
||||
byte numLoops[8];
|
||||
static const EntityPosition positions[8] = { kPosition_8200, kPosition_7500,
|
||||
kPosition_6470, kPosition_5790,
|
||||
kPosition_4840, kPosition_4070,
|
||||
kPosition_3050, kPosition_2740 };
|
||||
kPosition_6470, kPosition_5790,
|
||||
kPosition_4840, kPosition_4070,
|
||||
kPosition_3050, kPosition_2740 };
|
||||
|
||||
numLoops[1] = 4;
|
||||
numLoops[2] = 2;
|
||||
@ -1889,7 +1735,7 @@ void SoundManager::playLoopingSound(int param) {
|
||||
if (getFlags()->flag_3)
|
||||
fnameLen = 5;
|
||||
|
||||
if (!*snd || scumm_strnicmp((*snd)->name2.c_str(), tmp, fnameLen)) {
|
||||
if (!*snd || scumm_strnicmp((*snd)->_name2.c_str(), tmp, fnameLen)) {
|
||||
_loopingSoundDuration = _engine->getRandom().getRandomNumber(319) + 260;
|
||||
|
||||
if (partNumber != 99) {
|
||||
@ -1899,7 +1745,7 @@ void SoundManager::playLoopingSound(int param) {
|
||||
(*snd)->update(0);
|
||||
|
||||
for (snd = _soundList.begin(); snd != _soundList.end(); ++snd) {
|
||||
if ((*snd)->type == kSoundType1) {
|
||||
if ((*snd)->getType() == kSoundType1) {
|
||||
(*snd)->update(7);
|
||||
break;
|
||||
}
|
||||
@ -1913,7 +1759,7 @@ void SoundManager::stopAllSound() {
|
||||
Common::StackLock locker(_mutex);
|
||||
|
||||
for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
|
||||
(*i)->soundStream->stop();
|
||||
(*i)->_soundStream->stop();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -2232,12 +2078,12 @@ static const int p2s[17] = { 0, 1, 1, 3, 1, 5, 3, 7, 1, 9, 5, 11, 3, 13, 7, 15,
|
||||
static void soundFilter(byte *data, int16 *buffer, int p1, int p2);
|
||||
|
||||
void SoundManager::applyFilter(SoundEntry *entry, int16 *buffer) {
|
||||
if ((((byte *)entry->soundData)[1] << 6) > 0x1600) {
|
||||
entry->status.status |= 0x20000000;
|
||||
if ((((byte *)entry->_soundData)[1] << 6) > 0x1600) {
|
||||
entry->_status.status |= 0x20000000;
|
||||
} else {
|
||||
int variant = entry->status.status & 0x1f;
|
||||
int variant = entry->_status.status & 0x1f;
|
||||
|
||||
soundFilter((byte *)entry->soundData, buffer, p1s[variant], p2s[variant]);
|
||||
soundFilter((byte *)entry->_soundData, buffer, p1s[variant], p2s[variant]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,6 +84,8 @@ public:
|
||||
void playLocomotiveSound();
|
||||
void playWarningCompartment(EntityIndex entity, ObjectIndex compartment);
|
||||
|
||||
void playLoopingSound(int param);
|
||||
|
||||
// Dialog & Letters
|
||||
void readText(int id);
|
||||
const char *getDialogName(EntityIndex entity) const;
|
||||
@ -109,6 +111,9 @@ public:
|
||||
uint32 getFlag() { return _flag; }
|
||||
int getSubtitleFlag() { return _subtitlesFlag; }
|
||||
void setSubtitleFlag(int flag) { _subtitlesFlag = flag; }
|
||||
SoundType getCurrentType() { return _currentType; }
|
||||
void setCurrentType(SoundType type) { _currentType = type; }
|
||||
uint32 getData2() { return _data2; }
|
||||
|
||||
// Subtitles
|
||||
void addSubtitle(SubtitleEntry *entry) { _subtitles.push_back(entry); }
|
||||
@ -116,6 +121,12 @@ public:
|
||||
void setCurrentSubtitle(SubtitleEntry *entry) { _currentSubtitle = entry; }
|
||||
SubtitleEntry *getCurrentSubtitle() { return _currentSubtitle; }
|
||||
|
||||
// Queue
|
||||
bool setupCache(SoundEntry *entry);
|
||||
void addToQueue(SoundEntry *entry) { _soundList.push_back(entry); }
|
||||
|
||||
SoundEntry *getEntry(SoundType type);
|
||||
|
||||
private:
|
||||
typedef int32 *SoundBuffer;
|
||||
|
||||
@ -149,7 +160,6 @@ private:
|
||||
uint32 _lastWarning[12];
|
||||
|
||||
// Looping sound
|
||||
void playLoopingSound(int param);
|
||||
int _loopingSoundDuration;
|
||||
|
||||
// Sound entries
|
||||
@ -159,14 +169,8 @@ private:
|
||||
|
||||
SoundEntry *getEntry(EntityIndex index);
|
||||
SoundEntry *getEntry(Common::String name);
|
||||
SoundEntry *getEntry(SoundType type);
|
||||
|
||||
void setupEntry(SoundEntry *entry, Common::String name, SoundFlag flag, int priority);
|
||||
void setEntryType(SoundEntry *entry, SoundFlag flag);
|
||||
bool setupCache(SoundEntry *entry);
|
||||
void removeFromCache(SoundEntry *entry);
|
||||
void loadSoundData(SoundEntry *entry, Common::String name);
|
||||
void removeEntry(SoundEntry *entry);
|
||||
|
||||
// Subtitles
|
||||
int _subtitlesFlag;
|
||||
|
@ -22,7 +22,10 @@
|
||||
|
||||
#include "lastexpress/sound/entry.h"
|
||||
|
||||
#include "lastexpress/game/logic.h"
|
||||
#include "lastexpress/game/savepoint.h"
|
||||
#include "lastexpress/game/sound.h"
|
||||
#include "lastexpress/game/state.h"
|
||||
|
||||
#include "lastexpress/graphics.h"
|
||||
#include "lastexpress/helpers.h"
|
||||
@ -37,114 +40,267 @@ namespace LastExpress {
|
||||
// SoundEntry
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
SoundEntry::SoundEntry(LastExpressEngine *engine) : _engine(engine) {
|
||||
type = kSoundTypeNone;
|
||||
_type = kSoundTypeNone;
|
||||
|
||||
currentDataPtr = 0;
|
||||
soundData = NULL;
|
||||
_currentDataPtr = 0;
|
||||
_soundData = NULL;
|
||||
|
||||
blockCount = 0;
|
||||
time = 0;
|
||||
_blockCount = 0;
|
||||
_time = 0;
|
||||
|
||||
stream = NULL;
|
||||
_stream = NULL;
|
||||
|
||||
field_34 = 0;
|
||||
field_38 = 0;
|
||||
field_3C = 0;
|
||||
field_40 = 0;
|
||||
entity = kEntityPlayer;
|
||||
field_48 = 0;
|
||||
priority = 0;
|
||||
_field_34 = 0;
|
||||
_field_38 = 0;
|
||||
_field_3C = 0;
|
||||
_field_40 = 0;
|
||||
_entity = kEntityPlayer;
|
||||
_field_48 = 0;
|
||||
_priority = 0;
|
||||
|
||||
subtitle = NULL;
|
||||
_subtitle = NULL;
|
||||
|
||||
soundStream = NULL;
|
||||
_soundStream = NULL;
|
||||
}
|
||||
|
||||
SoundEntry::~SoundEntry() {
|
||||
// Entries that have been queued would have their streamed disposed automatically
|
||||
if (!soundStream)
|
||||
SAFE_DELETE(stream);
|
||||
if (!_soundStream)
|
||||
SAFE_DELETE(_stream);
|
||||
|
||||
delete soundStream;
|
||||
delete _soundStream;
|
||||
|
||||
_engine = NULL;
|
||||
}
|
||||
|
||||
void SoundEntry::open(Common::String name, SoundFlag flag, int priority) {
|
||||
_priority = priority;
|
||||
setType(flag);
|
||||
setStatus(flag);
|
||||
|
||||
// Add entry to sound list
|
||||
getSound()->addToQueue(this);
|
||||
|
||||
// Add entry to cache and load sound data
|
||||
getSound()->setupCache(this);
|
||||
loadSoundData(name);
|
||||
}
|
||||
|
||||
void SoundEntry::close() {
|
||||
_status.status |= kSoundStatusRemoved;
|
||||
|
||||
// Loop until ready
|
||||
while (!(_status.status1 & 4) && !(getSound()->getFlag() & 8) && (getSound()->getFlag() & 1))
|
||||
; // empty loop body
|
||||
|
||||
// The original game remove the entry from the cache here,
|
||||
// but since we are called from within an iterator loop
|
||||
// we will remove the entry there
|
||||
// removeFromCache(entry);
|
||||
|
||||
if (_subtitle) {
|
||||
_subtitle->draw();
|
||||
SAFE_DELETE(_subtitle);
|
||||
}
|
||||
|
||||
if (_entity) {
|
||||
if (_entity == kEntitySteam)
|
||||
getSound()->playLoopingSound(2);
|
||||
else if (_entity != kEntityTrain)
|
||||
getSavePoints()->push(kEntityPlayer, _entity, kActionEndSound);
|
||||
}
|
||||
}
|
||||
|
||||
void SoundEntry::setType(SoundFlag flag) {
|
||||
switch (flag & kFlagType9) {
|
||||
default:
|
||||
case kFlagNone:
|
||||
_type = getSound()->getCurrentType();
|
||||
getSound()->setCurrentType((SoundType)(_type + 1));
|
||||
break;
|
||||
|
||||
case kFlagType1_2: {
|
||||
SoundEntry *previous2 = getSound()->getEntry(kSoundType2);
|
||||
if (previous2)
|
||||
previous2->update(0);
|
||||
|
||||
SoundEntry *previous = getSound()->getEntry(kSoundType1);
|
||||
if (previous) {
|
||||
previous->setType(kSoundType2);
|
||||
previous->update(0);
|
||||
}
|
||||
|
||||
_type = kSoundType1;
|
||||
}
|
||||
break;
|
||||
|
||||
case kFlagType3: {
|
||||
SoundEntry *previous = getSound()->getEntry(kSoundType3);
|
||||
if (previous) {
|
||||
previous->setType(kSoundType4);
|
||||
previous->update(0);
|
||||
}
|
||||
|
||||
_type = kSoundType11;
|
||||
}
|
||||
break;
|
||||
|
||||
case kFlagType7: {
|
||||
SoundEntry *previous = getSound()->getEntry(kSoundType7);
|
||||
if (previous)
|
||||
previous->setType(kSoundType8);
|
||||
|
||||
_type = kSoundType7;
|
||||
}
|
||||
break;
|
||||
|
||||
case kFlagType9: {
|
||||
SoundEntry *previous = getSound()->getEntry(kSoundType9);
|
||||
if (previous)
|
||||
previous->setType(kSoundType10);
|
||||
|
||||
_type = kSoundType9;
|
||||
}
|
||||
break;
|
||||
|
||||
case kFlagType11: {
|
||||
SoundEntry *previous = getSound()->getEntry(kSoundType11);
|
||||
if (previous)
|
||||
previous->setType(kSoundType14);
|
||||
|
||||
_type = kSoundType11;
|
||||
}
|
||||
break;
|
||||
|
||||
case kFlagType13: {
|
||||
SoundEntry *previous = getSound()->getEntry(kSoundType13);
|
||||
if (previous)
|
||||
previous->setType(kSoundType14);
|
||||
|
||||
_type = kSoundType13;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SoundEntry::setStatus(SoundFlag flag) {
|
||||
SoundStatus statusFlag = (SoundStatus)flag;
|
||||
if (!((statusFlag & 0xFF) & kSoundStatusClear1))
|
||||
statusFlag = (SoundStatus)(statusFlag | kSoundStatusClear2);
|
||||
|
||||
if (((statusFlag & 0xFF00) >> 8) & kSoundStatusClear0)
|
||||
status.status = (uint32)statusFlag;
|
||||
_status.status = (uint32)statusFlag;
|
||||
else
|
||||
status.status = (statusFlag | kSoundStatusClear4);
|
||||
_status.status = (statusFlag | kSoundStatusClear4);
|
||||
}
|
||||
|
||||
void SoundEntry::setInCache() {
|
||||
status.status |= kSoundStatusClear2;
|
||||
_status.status |= kSoundStatusClear2;
|
||||
}
|
||||
|
||||
void SoundEntry::loadSoundData(Common::String name) {
|
||||
_name2 = name;
|
||||
|
||||
// Load sound data
|
||||
_stream = getArchive(name);
|
||||
|
||||
if (!_stream)
|
||||
_stream = getArchive("DEFAULT.SND");
|
||||
|
||||
if (_stream) {
|
||||
warning("Sound::loadSoundData: not implemented!");
|
||||
} else {
|
||||
_status.status = kSoundStatusRemoved;
|
||||
}
|
||||
}
|
||||
|
||||
void SoundEntry::update(uint val) {
|
||||
if (!(status.status3 & 64)) {
|
||||
if (!(_status.status3 & 64)) {
|
||||
int value2 = val;
|
||||
|
||||
status.status |= kSoundStatus_100000;
|
||||
_status.status |= kSoundStatus_100000;
|
||||
|
||||
if (val) {
|
||||
if (getSound()->getFlag() & 32) {
|
||||
field_40 = val;
|
||||
_field_40 = val;
|
||||
value2 = val * 2 + 1;
|
||||
}
|
||||
|
||||
field_3C = value2;
|
||||
_field_3C = value2;
|
||||
} else {
|
||||
field_3C = 0;
|
||||
status.status |= kSoundStatus_40000000;
|
||||
_field_3C = 0;
|
||||
_status.status |= kSoundStatus_40000000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SoundEntry::updateState() {
|
||||
if (getSound()->getFlag() & 32) {
|
||||
if (type != kSoundType9 && type != kSoundType7 && type != kSoundType5) {
|
||||
uint32 newStatus = status.status & kSoundStatusClear1;
|
||||
if (_type != kSoundType9 && _type != kSoundType7 && _type != kSoundType5) {
|
||||
uint32 newStatus = _status.status & kSoundStatusClear1;
|
||||
|
||||
status.status &= kSoundStatusClearAll;
|
||||
_status.status &= kSoundStatusClearAll;
|
||||
|
||||
field_40 = newStatus;
|
||||
status.status |= newStatus * 2 + 1;
|
||||
_field_40 = newStatus;
|
||||
_status.status |= newStatus * 2 + 1;
|
||||
}
|
||||
}
|
||||
|
||||
status.status |= kSoundStatus_20;
|
||||
_status.status |= kSoundStatus_20;
|
||||
}
|
||||
|
||||
void SoundEntry::reset() {
|
||||
status.status |= kSoundStatusRemoved;
|
||||
entity = kEntityPlayer;
|
||||
_status.status |= kSoundStatusRemoved;
|
||||
_entity = kEntityPlayer;
|
||||
|
||||
if (stream) {
|
||||
if (!soundStream) {
|
||||
SAFE_DELETE(stream);
|
||||
if (_stream) {
|
||||
if (!_soundStream) {
|
||||
SAFE_DELETE(_stream);
|
||||
} else {
|
||||
soundStream->stop();
|
||||
SAFE_DELETE(soundStream);
|
||||
_soundStream->stop();
|
||||
SAFE_DELETE(_soundStream);
|
||||
}
|
||||
|
||||
stream = NULL;
|
||||
_stream = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void SoundEntry::showSubtitle(Common::String filename) {
|
||||
subtitle = new SubtitleEntry(_engine);
|
||||
subtitle->load(filename, this);
|
||||
_subtitle = new SubtitleEntry(_engine);
|
||||
_subtitle->load(filename, this);
|
||||
|
||||
if (subtitle->getStatus().status2 & 4) {
|
||||
subtitle->draw();
|
||||
SAFE_DELETE(subtitle);
|
||||
if (_subtitle->getStatus().status2 & 4) {
|
||||
_subtitle->draw();
|
||||
SAFE_DELETE(_subtitle);
|
||||
} else {
|
||||
status.status |= kSoundStatus_20000;
|
||||
_status.status |= kSoundStatus_20000;
|
||||
}
|
||||
}
|
||||
|
||||
void SoundEntry::saveLoadWithSerializer(Common::Serializer &s) {
|
||||
if (_name2.matchString("NISSND?") && (_status.status & kFlagType7) != kFlag3) {
|
||||
s.syncAsUint32LE(_status.status);
|
||||
s.syncAsUint32LE(_type);
|
||||
s.syncAsUint32LE(_blockCount); // field_8;
|
||||
s.syncAsUint32LE(_time);
|
||||
s.syncAsUint32LE(_field_34); // field_10;
|
||||
s.syncAsUint32LE(_field_38); // field_14;
|
||||
s.syncAsUint32LE(_entity);
|
||||
|
||||
uint32 delta = (uint32)_field_48 - getSound()->getData2();
|
||||
if (delta > kFlag8)
|
||||
delta = 0;
|
||||
s.syncAsUint32LE(delta);
|
||||
|
||||
s.syncAsUint32LE(_priority);
|
||||
|
||||
char name1[16];
|
||||
strcpy((char *)&name1, _name1.c_str());
|
||||
s.syncBytes((byte *)&name1, 16);
|
||||
|
||||
char name2[16];
|
||||
strcpy((char *)&name2, _name2.c_str());
|
||||
s.syncBytes((byte *)&name2, 16);
|
||||
}
|
||||
}
|
||||
|
||||
@ -193,10 +349,10 @@ void SubtitleEntry::setupAndDraw() {
|
||||
_data->load(getArchive(_filename));
|
||||
}
|
||||
|
||||
if (_data->getMaxTime() > _sound->time) {
|
||||
if (_data->getMaxTime() > _sound->_time) {
|
||||
_status.status = kSoundStatus_400;
|
||||
} else {
|
||||
_data->setTime((uint16)_sound->time);
|
||||
_data->setTime((uint16)_sound->_time);
|
||||
|
||||
if (getSound()->getSubtitleFlag() & 1)
|
||||
drawOnScreen();
|
||||
|
@ -24,30 +24,30 @@
|
||||
#define LASTEXPRESS_SOUND_ENTRY_H
|
||||
|
||||
/*
|
||||
Sound entry: 68 bytes (this is what appears in the savegames)
|
||||
uint32 {4} - ??
|
||||
uint32 {4} - ??
|
||||
uint32 {4} - ??
|
||||
uint32 {4} - ??
|
||||
Sound entry: 68 bytes (this is what appears in savegames)
|
||||
uint32 {4} - status
|
||||
uint32 {4} - type
|
||||
uint32 {4} - blockCount
|
||||
uint32 {4} - time
|
||||
uint32 {4} - ??
|
||||
uint32 {4} - ??
|
||||
uint32 {4} - entity
|
||||
uint32 {4} - ??
|
||||
uint32 {4} - ??
|
||||
uint32 {4} - priority
|
||||
char {16} - name 1
|
||||
char {16} - name 2
|
||||
|
||||
Sound queue entry: 120 bytes
|
||||
uint16 {2} - status
|
||||
byte {1} - ??
|
||||
byte {1} - type
|
||||
byte {1} - ??
|
||||
uint32 {4} - ??
|
||||
uint32 {4} - ??
|
||||
uint32 {4} - ??
|
||||
uint32 {4} - file data pointer
|
||||
uint32 {4} - ??
|
||||
uint32 {4} - ??
|
||||
uint32 {4} - ??
|
||||
uint32 {4} - currentDataPtr
|
||||
uint32 {4} - soundData
|
||||
uint32 {4} - currentBufferPtr
|
||||
uint32 {4} - blockCount
|
||||
uint32 {4} - time
|
||||
uint32 {4} - size
|
||||
uint32 {4} - ??
|
||||
uint32 {4} - archive structure pointer
|
||||
uint32 {4} - ??
|
||||
@ -57,7 +57,7 @@
|
||||
uint32 {4} - ??
|
||||
uint32 {4} - entity
|
||||
uint32 {4} - ??
|
||||
uint32 {4} - ??
|
||||
uint32 {4} - priority
|
||||
char {16} - name 1
|
||||
char {16} - name 2
|
||||
uint32 {4} - pointer to next entry in the queue
|
||||
@ -69,6 +69,8 @@
|
||||
|
||||
#include "lastexpress/shared.h"
|
||||
|
||||
#include "common/serializer.h"
|
||||
|
||||
namespace LastExpress {
|
||||
|
||||
class LastExpressEngine;
|
||||
@ -109,13 +111,18 @@ union SoundStatusUnion {
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// SoundEntry
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
class SoundEntry {
|
||||
class SoundEntry : Common::Serializable {
|
||||
public:
|
||||
SoundEntry(LastExpressEngine *engine);
|
||||
~SoundEntry();
|
||||
|
||||
void open(Common::String name, SoundFlag flag, int priority);
|
||||
void close();
|
||||
|
||||
void setStatus(SoundFlag flag);
|
||||
void setType(SoundFlag flag);
|
||||
void setInCache();
|
||||
void loadSoundData(Common::String name);
|
||||
void update(uint val);
|
||||
void updateState();
|
||||
void reset();
|
||||
@ -123,37 +130,47 @@ public:
|
||||
// Subtitles
|
||||
void showSubtitle(Common::String filename);
|
||||
|
||||
// Serializable
|
||||
void saveLoadWithSerializer(Common::Serializer &ser);
|
||||
|
||||
// Accessors
|
||||
void setType(SoundType type) { _type = type; }
|
||||
SoundType getType() { return _type; }
|
||||
|
||||
void setEntity(EntityIndex entity) { _entity = entity; }
|
||||
EntityIndex getEntity() { return _entity; }
|
||||
|
||||
private:
|
||||
LastExpressEngine *_engine;
|
||||
|
||||
public:
|
||||
SoundStatusUnion status;
|
||||
SoundType type; // int
|
||||
//int data;
|
||||
//int endOffset;
|
||||
int currentDataPtr;
|
||||
void *soundData;
|
||||
//int currentBufferPtr;
|
||||
int blockCount;
|
||||
uint32 time;
|
||||
//int size;
|
||||
//int field_28;
|
||||
Common::SeekableReadStream *stream; // int
|
||||
//int field_30;
|
||||
int field_34;
|
||||
int field_38;
|
||||
int field_3C;
|
||||
int field_40;
|
||||
EntityIndex entity;
|
||||
int field_48;
|
||||
uint32 priority;
|
||||
Common::String name1; //char[16];
|
||||
Common::String name2; //char[16];
|
||||
//int next; // offset to the next structure in the list (not used)
|
||||
SubtitleEntry *subtitle;
|
||||
SoundStatusUnion _status;
|
||||
SoundType _type; // int
|
||||
//int _data;
|
||||
//int _endOffset;
|
||||
int _currentDataPtr;
|
||||
void *_soundData;
|
||||
//int _currentBufferPtr;
|
||||
int _blockCount;
|
||||
uint32 _time;
|
||||
//int _size;
|
||||
//int _field_28;
|
||||
Common::SeekableReadStream *_stream; // int
|
||||
//int _field_30;
|
||||
int _field_34;
|
||||
int _field_38;
|
||||
int _field_3C;
|
||||
int _field_40;
|
||||
EntityIndex _entity;
|
||||
int _field_48;
|
||||
uint32 _priority;
|
||||
Common::String _name1; //char[16];
|
||||
Common::String _name2; //char[16];
|
||||
// original has pointer to the next structure in the list (not used)
|
||||
SubtitleEntry *_subtitle;
|
||||
|
||||
// Sound stream
|
||||
StreamedSound *soundStream;
|
||||
StreamedSound *_soundStream;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
Loading…
Reference in New Issue
Block a user