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:
skidau 2012-04-23 04:47:31 +10:00
parent 7038a841bd
commit f0a5214a3f
3 changed files with 80 additions and 25 deletions

View File

@ -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;

View File

@ -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

View File

@ -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: