DSPHLE: Try to make zelda ucode savestates safer (sorry, this'll break your current states, as usual).
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3788 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
48a5c4211c
commit
fda61d91d5
|
@ -82,6 +82,7 @@ IUCode* CDSPHandler::GetUCode()
|
|||
void CDSPHandler::SetUCode(u32 _crc)
|
||||
{
|
||||
delete m_pUCode;
|
||||
|
||||
m_pUCode = NULL;
|
||||
m_MailHandler.Clear();
|
||||
m_pUCode = UCodeFactory(_crc, m_MailHandler);
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
void HLEMixer::MixUCode(short *samples, int numSamples) {
|
||||
// if this was called directly from the HLE, and not by timeout
|
||||
if (g_Config.m_EnableHLEAudio && IsHLEReady()) {
|
||||
IUCode* pUCode = CDSPHandler::GetInstance().GetUCode();
|
||||
IUCode *pUCode = CDSPHandler::GetInstance().GetUCode();
|
||||
if (pUCode && samples)
|
||||
pUCode->MixAdd(samples, numSamples);
|
||||
}
|
||||
|
|
|
@ -93,4 +93,41 @@ void CMailHandler::Update()
|
|||
}
|
||||
}
|
||||
|
||||
void CMailHandler::DoState(PointerWrap &p)
|
||||
{
|
||||
if (p.GetMode() == PointerWrap::MODE_READ)
|
||||
{
|
||||
Clear();
|
||||
int sz;
|
||||
p.Do(sz);
|
||||
for (int i = 0; i < sz; i++)
|
||||
{
|
||||
u32 mail;
|
||||
p.Do(mail);
|
||||
m_Mails.push(mail);
|
||||
}
|
||||
}
|
||||
else // WRITE and MEASURE
|
||||
{
|
||||
std::queue<u32> temp;
|
||||
int sz = m_Mails.size();
|
||||
p.Do(sz);
|
||||
for (int i = 0; i < sz; i++)
|
||||
{
|
||||
u32 value = m_Mails.front();
|
||||
m_Mails.pop();
|
||||
p.Do(value);
|
||||
temp.push(value);
|
||||
}
|
||||
if (!m_Mails.empty())
|
||||
PanicAlert("CMailHandler::DoState - WTF?");
|
||||
|
||||
// Restore queue.
|
||||
for (int i = 0; i < sz; i++)
|
||||
{
|
||||
u32 value = temp.front();
|
||||
temp.pop();
|
||||
m_Mails.push(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <queue>
|
||||
|
||||
#include "Common.h"
|
||||
#include "ChunkFile.h"
|
||||
|
||||
class CMailHandler
|
||||
{
|
||||
|
@ -31,6 +32,7 @@ public:
|
|||
void PushMail(u32 _Mail);
|
||||
void Clear();
|
||||
void Halt(bool _Halt);
|
||||
void DoState(PointerWrap &p);
|
||||
bool IsEmpty();
|
||||
|
||||
u16 ReadDSPMailboxHigh();
|
||||
|
|
|
@ -445,9 +445,16 @@ void CUCode_Zelda::ExecuteList()
|
|||
}
|
||||
|
||||
|
||||
void CUCode_Zelda::DoState(PointerWrap &p) {
|
||||
void CUCode_Zelda::DoState(PointerWrap &p)
|
||||
{
|
||||
// It's bad if we try to save during Mix()
|
||||
m_csMix.Enter();
|
||||
|
||||
p.Do(m_CRC);
|
||||
|
||||
p.Do(m_AFCCoefTable);
|
||||
p.Do(m_MiscTable);
|
||||
|
||||
p.Do(m_bSyncInProgress);
|
||||
p.Do(m_MaxVoice);
|
||||
p.Do(m_SyncFlags);
|
||||
|
@ -483,4 +490,8 @@ void CUCode_Zelda::DoState(PointerWrap &p) {
|
|||
p.Do(m_NumPBs);
|
||||
p.Do(m_PBAddress);
|
||||
p.Do(m_PBAddress2);
|
||||
|
||||
m_rMailHandler.DoState(p);
|
||||
|
||||
m_csMix.Leave();
|
||||
}
|
||||
|
|
|
@ -273,7 +273,9 @@ private:
|
|||
void RenderSynth_RectWave(ZeldaVoicePB &PB, s32* _Buffer, int _Size);
|
||||
void RenderSynth_SawWave(ZeldaVoicePB &PB, s32* _Buffer, int _Size);
|
||||
|
||||
void RenderVoice_PCM8(ZeldaVoicePB& PB, s16* _Buffer, int _Size);
|
||||
void RenderVoice_PCM16(ZeldaVoicePB& PB, s16* _Buffer, int _Size);
|
||||
|
||||
void RenderVoice_AFC(ZeldaVoicePB& PB, s16* _Buffer, int _Size);
|
||||
void RenderVoice_Raw(ZeldaVoicePB& PB, s16* _Buffer, int _Size);
|
||||
|
||||
|
|
|
@ -223,7 +223,7 @@ restart:
|
|||
{
|
||||
PB.ReachedEnd = 0;
|
||||
|
||||
// HACK: Looping doesn't work.
|
||||
// HACK: AFC looping doesn't work.
|
||||
if (true || PB.RepeatMode == 0)
|
||||
{
|
||||
PB.KeyOff = 1;
|
||||
|
@ -252,7 +252,7 @@ restart:
|
|||
|
||||
// Prefill the decode buffer.
|
||||
AFCdecodebuffer(m_AFCCoefTable, (char*)(source + (PB.CurAddr & ram_mask)), outbuf, (short*)&PB.YN2, (short*)&PB.YN1, PB.Format);
|
||||
PB.CurAddr += 9;
|
||||
PB.CurAddr += PB.Format; // 9 or 5
|
||||
|
||||
u32 SamplePosition = PB.Length - PB.RemLength;
|
||||
while (sampleCount < _RealSize)
|
||||
|
@ -275,7 +275,7 @@ restart:
|
|||
prev_addr = PB.CurAddr;
|
||||
|
||||
AFCdecodebuffer(m_AFCCoefTable, (char*)(source + (PB.CurAddr & ram_mask)), outbuf, (short*)&PB.YN2, (short*)&PB.YN1, PB.Format);
|
||||
PB.CurAddr += 9;
|
||||
PB.CurAddr += PB.Format; // 9 or 5
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -310,6 +310,8 @@ void CUCode_Zelda::RenderVoice_Raw(ZeldaVoicePB &PB, s16 *_Buffer, int _Size)
|
|||
// Decoder0x21Core starts here.
|
||||
u32 AX0 = _RealSize;
|
||||
|
||||
// ERROR_LOG(DSPHLE, "0x21 volume mode: %i , stop: %i ", PB.VolumeMode, PB.StopOnSilence);
|
||||
|
||||
// The PB.StopOnSilence check is a hack, we should check the buffers and enter this
|
||||
// only when the buffer is completely 0 (i.e. when the music has finished fading out)
|
||||
if (PB.StopOnSilence || PB.RemLength < _RealSize)
|
||||
|
@ -343,7 +345,7 @@ void CUCode_Zelda::RenderVoice_Raw(ZeldaVoicePB &PB, s16 *_Buffer, int _Size)
|
|||
{
|
||||
// There's something wrong with this looping code.
|
||||
|
||||
// ERROR_LOG(DSPHLE, "Raw loop: ReadAudio size = %04x 34:%04x %08x", PB.Unk36[0], PB.raw[0x34 ^ 1], (int)ACC0);
|
||||
ERROR_LOG(DSPHLE, "Raw loop: ReadAudio size = %04x 34:%04x %08x", PB.Unk36[0], PB.raw[0x34 ^ 1], (int)ACC0);
|
||||
Decoder21_ReadAudio(PB, PB.Unk36[0], _Buffer);
|
||||
|
||||
u32 ACC0 = _Size << 16;
|
||||
|
@ -478,8 +480,9 @@ void CUCode_Zelda::RenderAddVoice(ZeldaVoicePB &PB, s32* _LeftBuffer, s32* _Righ
|
|||
|
||||
// These are more "synth" formats - square wave, saw wave etc.
|
||||
case 0x0002:
|
||||
case 0x0007: // Example: Pikmin 2 in a cave, not sure what sound it is.
|
||||
case 0x000c: // Example: beam of death/yellow force-field in Temple of the Gods, ZWW
|
||||
WARN_LOG(DSPHLE, "Synthesizing 0x%04x", PB.Format);
|
||||
WARN_LOG(DSPHLE, "Not synthesizing unreversed-engineerd format 0x%04x", PB.Format);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -559,7 +562,7 @@ ContinueWithBlock:
|
|||
for (int count = 0; count < 8; count++)
|
||||
{
|
||||
// The 8 buffers to mix to: 0d00, 0d60, 0f40 0ca0 0e80 0ee0 0c00 0c50
|
||||
// We just mix to the first to and call it stereo :p
|
||||
// We just mix to the first two and call it stereo :p
|
||||
int value = b00[0x4 + count];
|
||||
int delta = b00[0xC + count] << 11;
|
||||
|
||||
|
@ -648,7 +651,7 @@ ContinueWithBlock:
|
|||
// size is in stereo samples.
|
||||
void CUCode_Zelda::MixAdd(short *_Buffer, int _Size)
|
||||
{
|
||||
// PanicAlert("mixadd");
|
||||
m_csMix.Enter();
|
||||
// Safety check
|
||||
if (_Size > 256 * 1024 - 8)
|
||||
_Size = 256 * 1024 - 8;
|
||||
|
@ -695,4 +698,5 @@ void CUCode_Zelda::MixAdd(short *_Buffer, int _Size)
|
|||
|
||||
_Buffer += 2;
|
||||
}
|
||||
m_csMix.Leave();
|
||||
}
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "Common.h"
|
||||
#include "ChunkFile.h"
|
||||
#include "Thread.h"
|
||||
|
||||
#define UCODE_ROM 0x0000000
|
||||
#define UCODE_INIT_AUDIO_SYSTEM 0x0000001
|
||||
|
@ -46,6 +47,7 @@ public:
|
|||
|
||||
protected:
|
||||
CMailHandler& m_rMailHandler;
|
||||
Common::CriticalSection m_csMix;
|
||||
};
|
||||
|
||||
extern IUCode* UCodeFactory(u32 _CRC, CMailHandler& _rMailHandler);
|
||||
|
|
Loading…
Reference in New Issue