HD Packs: Save states now save audio state (for ogg bgm)
This commit is contained in:
parent
7e50f2aee1
commit
2d53bc05a5
9 changed files with 85 additions and 14 deletions
|
@ -551,6 +551,11 @@ void Console::SaveState(ostream &saveStream)
|
|||
Instance->_apu->SaveSnapshot(&saveStream);
|
||||
Instance->_controlManager->SaveSnapshot(&saveStream);
|
||||
Instance->_mapper->SaveSnapshot(&saveStream);
|
||||
if(Instance->_hdAudioDevice) {
|
||||
Instance->_hdAudioDevice->SaveSnapshot(&saveStream);
|
||||
} else {
|
||||
Snapshotable::WriteEmptyBlock(&saveStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -567,6 +572,11 @@ void Console::LoadState(istream &loadStream)
|
|||
Instance->_apu->LoadSnapshot(&loadStream);
|
||||
Instance->_controlManager->LoadSnapshot(&loadStream);
|
||||
Instance->_mapper->LoadSnapshot(&loadStream);
|
||||
if(Instance->_hdAudioDevice) {
|
||||
Instance->_hdAudioDevice->LoadSnapshot(&loadStream);
|
||||
} else {
|
||||
Snapshotable::SkipBlock(&loadStream);
|
||||
}
|
||||
|
||||
MessageManager::SendNotification(ConsoleNotificationType::StateLoaded);
|
||||
}
|
||||
|
@ -636,11 +646,11 @@ bool Console::IsHdPpu()
|
|||
void Console::LoadHdPack(VirtualFile &romFile, VirtualFile &patchFile)
|
||||
{
|
||||
_hdData.reset();
|
||||
_hdAudioDevice.reset();
|
||||
if(EmulationSettings::CheckFlag(EmulationFlags::UseHdPacks)) {
|
||||
_hdData.reset(new HdPackData());
|
||||
if(!HdPackLoader::LoadHdNesPack(romFile, *_hdData.get())) {
|
||||
_hdData.reset();
|
||||
_hdAudioDevice.reset();
|
||||
} else {
|
||||
auto result = _hdData->PatchesByHash.find(romFile.GetSha1Hash());
|
||||
if(result != _hdData->PatchesByHash.end()) {
|
||||
|
|
|
@ -11,22 +11,43 @@ HdAudioDevice::HdAudioDevice(HdPackData * hdData)
|
|||
_oggMixer = SoundMixer::GetOggMixer();
|
||||
}
|
||||
|
||||
bool HdAudioDevice::PlayBgmTrack(uint8_t track)
|
||||
void HdAudioDevice::StreamState(bool saving)
|
||||
{
|
||||
auto result = _hdData->BgmFilesById.find(_album * 256 + track);
|
||||
int32_t trackOffset = 0;
|
||||
if(saving) {
|
||||
trackOffset = _oggMixer->GetBgmOffset();
|
||||
if(trackOffset < 0) {
|
||||
_lastBgmTrack = -1;
|
||||
}
|
||||
Stream(_album, _lastBgmTrack, trackOffset);
|
||||
} else {
|
||||
Stream(_album, _lastBgmTrack, trackOffset);
|
||||
if(_lastBgmTrack != -1 && trackOffset > 0) {
|
||||
PlayBgmTrack(_lastBgmTrack, trackOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool HdAudioDevice::PlayBgmTrack(uint8_t track, uint32_t startOffset)
|
||||
{
|
||||
int trackId = _album * 256 + track;
|
||||
auto result = _hdData->BgmFilesById.find(trackId);
|
||||
if(result != _hdData->BgmFilesById.end()) {
|
||||
return !_oggMixer->Play(result->second, false);
|
||||
if(_oggMixer->Play(result->second, false, startOffset)) {
|
||||
_lastBgmTrack = trackId;
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
MessageManager::Log("[HDPack] Invalid album+track combination: " + std::to_string(_album) + ":" + std::to_string(track));
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HdAudioDevice::PlaySfx(uint8_t sfxNumber)
|
||||
{
|
||||
auto result = _hdData->SfxFilesById.find(_album * 256 + sfxNumber);
|
||||
if(result != _hdData->SfxFilesById.end()) {
|
||||
return !_oggMixer->Play(result->second, true);
|
||||
return !_oggMixer->Play(result->second, true, 0);
|
||||
} else {
|
||||
MessageManager::Log("[HDPack] Invalid album+sfx number combination: " + std::to_string(_album) + ":" + std::to_string(sfxNumber));
|
||||
return false;
|
||||
|
@ -98,7 +119,7 @@ void HdAudioDevice::WriteRAM(uint16_t addr, uint8_t value)
|
|||
|
||||
//Play BGM track (0-255 = track number)
|
||||
//Stop the current BGM and starts a new track
|
||||
case 5: _trackError = PlayBgmTrack(value); break;
|
||||
case 5: _trackError = PlayBgmTrack(value, 0); break;
|
||||
|
||||
//Play sound effect (0-255 = sfx number)
|
||||
//Plays a new sound effect (no limit to the number of simultaneous sound effects)
|
||||
|
|
|
@ -3,10 +3,11 @@
|
|||
#include "IMemoryHandler.h"
|
||||
#include "SoundMixer.h"
|
||||
#include "OggMixer.h"
|
||||
#include "Snapshotable.h"
|
||||
|
||||
struct HdPackData;
|
||||
|
||||
class HdAudioDevice : public IMemoryHandler
|
||||
class HdAudioDevice : public IMemoryHandler, public Snapshotable
|
||||
{
|
||||
private:
|
||||
HdPackData *_hdData;
|
||||
|
@ -14,11 +15,15 @@ private:
|
|||
uint8_t _flags;
|
||||
bool _trackError;
|
||||
OggMixer* _oggMixer;
|
||||
int32_t _lastBgmTrack;
|
||||
|
||||
bool PlayBgmTrack(uint8_t track);
|
||||
bool PlayBgmTrack(uint8_t track, uint32_t startOffset);
|
||||
bool PlaySfx(uint8_t sfxNumber);
|
||||
void ProcessControlFlags(uint8_t flags);
|
||||
|
||||
protected:
|
||||
void StreamState(bool saving) override;
|
||||
|
||||
public:
|
||||
HdAudioDevice(HdPackData *hdData);
|
||||
|
||||
|
|
|
@ -80,11 +80,11 @@ void OggMixer::SetSampleRate(int sampleRate)
|
|||
}
|
||||
}
|
||||
|
||||
bool OggMixer::Play(string filename, bool isSfx)
|
||||
bool OggMixer::Play(string filename, bool isSfx, uint32_t startOffset)
|
||||
{
|
||||
shared_ptr<OggReader> reader(new OggReader());
|
||||
bool loop = !isSfx && (_options & (int)OggPlaybackOptions::Loop) != 0;
|
||||
if(reader->Init(filename, loop, _sampleRate)) {
|
||||
if(reader->Init(filename, loop, _sampleRate, startOffset)) {
|
||||
if(isSfx) {
|
||||
_sfx.push_back(reader);
|
||||
} else {
|
||||
|
@ -108,3 +108,12 @@ void OggMixer::ApplySamples(int16_t * buffer, size_t sampleCount)
|
|||
}
|
||||
_sfx.erase(std::remove_if(_sfx.begin(), _sfx.end(), [](const shared_ptr<OggReader>& o) { return o->IsPlaybackOver(); }), _sfx.end());
|
||||
}
|
||||
|
||||
int OggMixer::GetBgmOffset()
|
||||
{
|
||||
if(_bgm) {
|
||||
return _bgm->GetOffset();
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
|
@ -22,7 +22,7 @@ public:
|
|||
void ApplySamples(int16_t* buffer, size_t sampleCount);
|
||||
|
||||
void Reset();
|
||||
bool Play(string filename, bool isSfx);
|
||||
bool Play(string filename, bool isSfx, uint32_t startOffset);
|
||||
void SetPlaybackOptions(uint8_t options);
|
||||
void SetPausedFlag(bool paused);
|
||||
void StopBgm();
|
||||
|
@ -31,4 +31,5 @@ public:
|
|||
void SetSfxVolume(uint8_t volume);
|
||||
bool IsBgmPlaying();
|
||||
bool IsSfxPlaying();
|
||||
int32_t GetBgmOffset();
|
||||
};
|
||||
|
|
|
@ -22,7 +22,7 @@ OggReader::~OggReader()
|
|||
}
|
||||
}
|
||||
|
||||
bool OggReader::Init(string filename, bool loop, int sampleRate)
|
||||
bool OggReader::Init(string filename, bool loop, uint32_t sampleRate, uint32_t startOffset)
|
||||
{
|
||||
int error;
|
||||
VirtualFile file = filename;
|
||||
|
@ -32,6 +32,9 @@ bool OggReader::Init(string filename, bool loop, int sampleRate)
|
|||
if(_vorbis) {
|
||||
_loop = loop;
|
||||
_oggSampleRate = stb_vorbis_get_info(_vorbis).sample_rate;
|
||||
if(startOffset > 0) {
|
||||
stb_vorbis_seek(_vorbis, startOffset);
|
||||
}
|
||||
blip_set_rates(_blipLeft, _oggSampleRate, sampleRate);
|
||||
blip_set_rates(_blipRight, _oggSampleRate, sampleRate);
|
||||
return true;
|
||||
|
@ -100,3 +103,8 @@ void OggReader::ApplySamples(int16_t * buffer, size_t sampleCount, uint8_t volum
|
|||
buffer[i] += (int16_t)(_outputBuffer[i] * (EmulationSettings::GetMasterVolume() * volume / 255 / 10));
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t OggReader::GetOffset()
|
||||
{
|
||||
return stb_vorbis_get_file_offset(_vorbis);
|
||||
}
|
|
@ -31,9 +31,10 @@ public:
|
|||
OggReader();
|
||||
~OggReader();
|
||||
|
||||
bool Init(string filename, bool loop, int sampleRate);
|
||||
bool Init(string filename, bool loop, uint32_t sampleRate, uint32_t startOffset = 0);
|
||||
bool IsPlaybackOver();
|
||||
void SetSampleRate(int sampleRate);
|
||||
void SetLoopFlag(bool loop);
|
||||
void ApplySamples(int16_t* buffer, size_t sampleCount, uint8_t volume);
|
||||
uint32_t GetOffset();
|
||||
};
|
||||
|
|
|
@ -97,4 +97,17 @@ void Snapshotable::LoadSnapshot(istream* file)
|
|||
if(_blockBuffer) {
|
||||
throw new std::runtime_error("A call to StreamEndBlock is missing.");
|
||||
}
|
||||
}
|
||||
|
||||
void Snapshotable::WriteEmptyBlock(ostream* file)
|
||||
{
|
||||
int blockSize = 0;
|
||||
file->write((char*)&blockSize, sizeof(blockSize));
|
||||
}
|
||||
|
||||
void Snapshotable::SkipBlock(istream* file)
|
||||
{
|
||||
int blockSize = 0;
|
||||
file->read((char*)&blockSize, sizeof(blockSize));
|
||||
file->seekg(blockSize, ios::cur);
|
||||
}
|
|
@ -158,4 +158,7 @@ protected:
|
|||
public:
|
||||
void SaveSnapshot(ostream* file);
|
||||
void LoadSnapshot(istream* file);
|
||||
|
||||
static void WriteEmptyBlock(ostream* file);
|
||||
static void SkipBlock(istream* file);
|
||||
};
|
Loading…
Add table
Reference in a new issue