Added the response for audio streaming disc offset requests. Generate an AI interrupt at the end of the audio streaming loop. Fixes Pac-man Fever and the background music in Eternal Darkness.
This commit is contained in:
parent
7038a841bd
commit
f0a5214a3f
|
@ -234,8 +234,8 @@ void Write32(const u32 _Value, const u32 _Address)
|
||||||
m_Control.PSTAT = tmpAICtrl.PSTAT;
|
m_Control.PSTAT = tmpAICtrl.PSTAT;
|
||||||
g_LastCPUTime = CoreTiming::GetTicks();
|
g_LastCPUTime = CoreTiming::GetTicks();
|
||||||
|
|
||||||
// Tell Drive Interface to stop streaming
|
// Tell Drive Interface to start/stop streaming
|
||||||
if (!tmpAICtrl.PSTAT) DVDInterface::g_bStream = false;
|
DVDInterface::g_bStream = tmpAICtrl.PSTAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// AI Interrupt
|
// AI Interrupt
|
||||||
|
@ -293,6 +293,11 @@ static void GenerateAudioInterrupt()
|
||||||
UpdateInterrupts();
|
UpdateInterrupts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GenerateAISInterrupt()
|
||||||
|
{
|
||||||
|
GenerateAudioInterrupt();
|
||||||
|
}
|
||||||
|
|
||||||
void Callback_GetSampleRate(unsigned int &_AISampleRate, unsigned int &_DACSampleRate)
|
void Callback_GetSampleRate(unsigned int &_AISampleRate, unsigned int &_DACSampleRate)
|
||||||
{
|
{
|
||||||
_AISampleRate = g_AISSampleRate;
|
_AISampleRate = g_AISSampleRate;
|
||||||
|
|
|
@ -43,6 +43,8 @@ void Write32(const u32 _iValue, const u32 _iAddress);
|
||||||
// Get the audio rates (48000 or 32000 only)
|
// Get the audio rates (48000 or 32000 only)
|
||||||
unsigned int GetAIDSampleRate();
|
unsigned int GetAIDSampleRate();
|
||||||
|
|
||||||
|
void GenerateAISInterrupt();
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "Thread.h"
|
#include "Thread.h"
|
||||||
#include "Memmap.h"
|
#include "Memmap.h"
|
||||||
#include "../VolumeHandler.h"
|
#include "../VolumeHandler.h"
|
||||||
|
#include "AudioInterface.h"
|
||||||
|
|
||||||
// Disc transfer rate measured in bytes per second
|
// Disc transfer rate measured in bytes per second
|
||||||
static const u32 DISC_TRANSFER_RATE_GC = 3125 * 1024;
|
static const u32 DISC_TRANSFER_RATE_GC = 3125 * 1024;
|
||||||
|
@ -201,10 +202,10 @@ static UDICR m_DICR;
|
||||||
static UDIIMMBUF m_DIIMMBUF;
|
static UDIIMMBUF m_DIIMMBUF;
|
||||||
static UDICFG m_DICFG;
|
static UDICFG m_DICFG;
|
||||||
|
|
||||||
static u32 AudioStart;
|
static u32 LoopStart;
|
||||||
static u32 AudioPos;
|
static u32 AudioPos;
|
||||||
static u32 CurrentStart;
|
static u32 CurrentStart;
|
||||||
static u32 AudioLength;
|
static u32 LoopLength;
|
||||||
static u32 CurrentLength;
|
static u32 CurrentLength;
|
||||||
|
|
||||||
u32 g_ErrorCode = 0;
|
u32 g_ErrorCode = 0;
|
||||||
|
@ -240,12 +241,15 @@ void DoState(PointerWrap &p)
|
||||||
p.Do(m_DIIMMBUF);
|
p.Do(m_DIIMMBUF);
|
||||||
p.Do(m_DICFG);
|
p.Do(m_DICFG);
|
||||||
|
|
||||||
p.Do(AudioStart);
|
p.Do(LoopStart);
|
||||||
p.Do(AudioPos);
|
p.Do(AudioPos);
|
||||||
p.Do(AudioLength);
|
p.Do(LoopLength);
|
||||||
|
|
||||||
p.Do(g_ErrorCode);
|
p.Do(g_ErrorCode);
|
||||||
p.Do(g_bDiscInside);
|
p.Do(g_bDiscInside);
|
||||||
|
|
||||||
|
p.Do(CurrentStart);
|
||||||
|
p.Do(CurrentLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TransferComplete(u64 userdata, int cyclesLate)
|
void TransferComplete(u64 userdata, int cyclesLate)
|
||||||
|
@ -268,9 +272,11 @@ void Init()
|
||||||
m_DICFG.Hex = 0;
|
m_DICFG.Hex = 0;
|
||||||
m_DICFG.CONFIG = 1; // Disable bootrom descrambler
|
m_DICFG.CONFIG = 1; // Disable bootrom descrambler
|
||||||
|
|
||||||
AudioStart = 0;
|
AudioPos = 0;
|
||||||
AudioPos = 0;
|
LoopStart = 0;
|
||||||
AudioLength = 0;
|
LoopLength = 0;
|
||||||
|
CurrentStart = 0;
|
||||||
|
CurrentLength = 0;
|
||||||
|
|
||||||
ejectDisc = CoreTiming::RegisterEvent("EjectDisc", EjectDiscCallback);
|
ejectDisc = CoreTiming::RegisterEvent("EjectDisc", EjectDiscCallback);
|
||||||
insertDisc = CoreTiming::RegisterEvent("InsertDisc", InsertDiscCallback);
|
insertDisc = CoreTiming::RegisterEvent("InsertDisc", InsertDiscCallback);
|
||||||
|
@ -372,20 +378,20 @@ bool DVDReadADPCM(u8* _pDestBuffer, u32 _iNumSamples)
|
||||||
|
|
||||||
if (AudioPos >= CurrentStart + CurrentLength)
|
if (AudioPos >= CurrentStart + CurrentLength)
|
||||||
{
|
{
|
||||||
if (AudioStart == 0 || AudioLength == 0)
|
if (LoopStart == 0)
|
||||||
{
|
{
|
||||||
AudioPos = 0;
|
AudioPos = 0;
|
||||||
CurrentStart = 0;
|
CurrentStart = 0;
|
||||||
CurrentLength = 0;
|
CurrentLength = 0;
|
||||||
g_bStream = false; // Starfox Adventures
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AudioPos = AudioStart;
|
AudioPos = LoopStart;
|
||||||
CurrentStart = AudioStart;
|
CurrentStart = LoopStart;
|
||||||
CurrentLength = AudioLength;
|
CurrentLength = LoopLength;
|
||||||
NGCADPCM::InitFilter();
|
|
||||||
}
|
}
|
||||||
|
NGCADPCM::InitFilter();
|
||||||
|
AudioInterface::GenerateAISInterrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
//WARN_LOG(DVDINTERFACE,"ReadADPCM");
|
//WARN_LOG(DVDINTERFACE,"ReadADPCM");
|
||||||
|
@ -828,27 +834,69 @@ void ExecuteCommand(UDICR& _DICR)
|
||||||
// m_DICMDBUF[2].Hex = Length of the stream
|
// m_DICMDBUF[2].Hex = Length of the stream
|
||||||
case 0xE1:
|
case 0xE1:
|
||||||
{
|
{
|
||||||
if (!g_bStream)
|
u32 pos = m_DICMDBUF[1].Hex << 2;
|
||||||
|
u32 length = m_DICMDBUF[2].Hex;
|
||||||
|
|
||||||
|
// Start playing
|
||||||
|
if (!g_bStream && m_DICMDBUF[0].CMDBYTE1 == 0 && pos != 0 && length != 0)
|
||||||
{
|
{
|
||||||
AudioPos = m_DICMDBUF[1].Hex << 2;
|
AudioPos = pos;
|
||||||
CurrentStart = AudioPos;
|
CurrentStart = pos;
|
||||||
CurrentLength = m_DICMDBUF[2].Hex;
|
CurrentLength = length;
|
||||||
NGCADPCM::InitFilter();
|
NGCADPCM::InitFilter();
|
||||||
g_bStream = true;
|
g_bStream = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioStart = m_DICMDBUF[1].Hex << 2;
|
LoopStart = pos;
|
||||||
AudioLength = m_DICMDBUF[2].Hex;
|
LoopLength = length;
|
||||||
|
g_bStream = (m_DICMDBUF[0].CMDBYTE1 == 0); // This command can start/stop the stream
|
||||||
|
|
||||||
WARN_LOG(DVDINTERFACE, "(Audio) Stream subcmd = %02x offset = %08x length=%08x",
|
// Stop stream
|
||||||
m_DICMDBUF[0].CMDBYTE1, AudioPos, AudioLength);
|
if (m_DICMDBUF[0].CMDBYTE1 == 1)
|
||||||
|
{
|
||||||
|
AudioPos = 0;
|
||||||
|
LoopStart = 0;
|
||||||
|
LoopLength = 0;
|
||||||
|
CurrentStart = 0;
|
||||||
|
CurrentLength = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
WARN_LOG(DVDINTERFACE, "(Audio) Stream subcmd = %08x offset = %08x length=%08x",
|
||||||
|
m_DICMDBUF[0].Hex, m_DICMDBUF[1].Hex << 2, m_DICMDBUF[2].Hex);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Request Audio Status (Immediate)
|
// Request Audio Status (Immediate)
|
||||||
case 0xE2:
|
case 0xE2:
|
||||||
m_DIIMMBUF.Hex = g_bStream ? 1 : 0;
|
{
|
||||||
//WARN_LOG(DVDINTERFACE, "(Audio): Request Audio status %s", g_bStream? "on":"off");
|
switch (m_DICMDBUF[0].CMDBYTE1)
|
||||||
|
{
|
||||||
|
case 0x00: // Returns streaming status
|
||||||
|
m_DIIMMBUF.Hex = (AudioPos == 0) ? 0 : 1;
|
||||||
|
break;
|
||||||
|
case 0x01: // Returns the current offset
|
||||||
|
if (g_bStream)
|
||||||
|
m_DIIMMBUF.Hex = (AudioPos - CurrentStart) >> 2;
|
||||||
|
else
|
||||||
|
m_DIIMMBUF.Hex = 0;
|
||||||
|
break;
|
||||||
|
case 0x02: // Returns the start offset
|
||||||
|
if (g_bStream)
|
||||||
|
m_DIIMMBUF.Hex = CurrentStart >> 2;
|
||||||
|
else
|
||||||
|
m_DIIMMBUF.Hex = 0;
|
||||||
|
break;
|
||||||
|
case 0x03: // Returns the total length
|
||||||
|
if (g_bStream)
|
||||||
|
m_DIIMMBUF.Hex = CurrentLength;
|
||||||
|
else
|
||||||
|
m_DIIMMBUF.Hex = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
WARN_LOG(DVDINTERFACE, "(Audio): Subcommand: %02x Request Audio status %s", m_DICMDBUF[0].CMDBYTE1, g_bStream? "on":"off");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DVDLowStopMotor:
|
case DVDLowStopMotor:
|
||||||
|
|
Loading…
Reference in New Issue