Protect dvdread with a critical section, should fix crashes when running ikaruga from a compressed iso. Some coding standard stuff.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@672 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
3883ce6ee9
commit
08e81eddb9
|
@ -49,13 +49,13 @@ class CriticalSection
|
|||
#elif __GNUC__
|
||||
pthread_mutex_t mutex;
|
||||
#endif
|
||||
public:
|
||||
public:
|
||||
|
||||
CriticalSection(int spincount = 1000);
|
||||
~CriticalSection();
|
||||
void Enter();
|
||||
bool TryEnter();
|
||||
void Leave();
|
||||
CriticalSection(int spincount = 1000);
|
||||
~CriticalSection();
|
||||
void Enter();
|
||||
bool TryEnter();
|
||||
void Leave();
|
||||
};
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@ -66,23 +66,22 @@ typedef void* (*ThreadFunc)(void* arg);
|
|||
|
||||
class Thread
|
||||
{
|
||||
public:
|
||||
public:
|
||||
Thread(ThreadFunc entry, void* arg);
|
||||
~Thread();
|
||||
|
||||
Thread(ThreadFunc entry, void* arg);
|
||||
~Thread();
|
||||
|
||||
void WaitForDeath();
|
||||
void SetAffinity(int mask);
|
||||
static void SetCurrentThreadAffinity(int mask);
|
||||
void WaitForDeath();
|
||||
void SetAffinity(int mask);
|
||||
static void SetCurrentThreadAffinity(int mask);
|
||||
|
||||
|
||||
private:
|
||||
private:
|
||||
|
||||
#ifdef _WIN32
|
||||
HANDLE m_hThread;
|
||||
DWORD m_threadId;
|
||||
HANDLE m_hThread;
|
||||
DWORD m_threadId;
|
||||
#elif __GNUC__
|
||||
pthread_t thread_id;
|
||||
pthread_t thread_id;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -24,31 +24,32 @@
|
|||
#include "../PowerPC/PowerPC.h"
|
||||
#include "PeripheralInterface.h"
|
||||
#include "Memmap.h"
|
||||
#include "Thread.h"
|
||||
|
||||
#include "../VolumeHandler.h"
|
||||
|
||||
namespace DVDInterface
|
||||
{
|
||||
|
||||
/*
|
||||
20975: 00000000 DVD (zzz_80146b84 ??, 0x80146bf8) : DVD(r): 0xcc006004
|
||||
20976: 00000000 DVD (zzz_80146b84 ??, 0x80146c00) : DVD(w): 0x00000000 @ 0xcc006004
|
||||
20977: 00000000 DVD (DVDLowRead, 0x801448a8) : DVD(w): 0x00000020 @ 0xcc006018
|
||||
20978: 00000000 DVD (Read, 0x80144744) : DVD(w): 0xa8000000 @ 0xcc006008
|
||||
20979: 00000000 DVD (Read, 0x80144750) : DVD(w): 0x01094227 @ 0xcc00600c
|
||||
20980: 00000000 DVD (Read, 0x80144758) : DVD(w): 0x00000020 @ 0xcc006010
|
||||
20981: 00000000 DVD (Read, 0x8014475c) : DVD(w): 0x8167cc80 @ 0xcc006014
|
||||
20982: 00000000 DVD (Read, 0x80144760) : DVD(w): 0x00000020 @ 0xcc006018
|
||||
20983: 00000000 DVD (Read, 0x80144768) : DVD(w): 0x00000003 @ 0xcc00601c
|
||||
20984: 00000000 DVD: DVD: Read ISO: DVDOffset=0425089c, DMABuffer=0167cc80, SrcLength=00000020, DMALength=00000020
|
||||
20989: 00000000 DVD (zzz_801442fc ??, 0x80144388) : DVD(r): 0xcc006000
|
||||
20990: 00000000 DVD (zzz_801442fc ??, 0x801443d8) : DVD(w): 0x0000003a @ 0xcc006000
|
||||
20992: 00000000 DVD (zzz_801442fc ??, 0x801444d0) : DVD(w): 0x00000000 @ 0xcc006004
|
||||
20993: 00000000 DVD (zzz_80146e44 ??, 0x80146fcc) : DVD(r): 0xcc006018
|
||||
/*
|
||||
20975: 00000000 DVD (zzz_80146b84 ??, 0x80146bf8) : DVD(r): 0xcc006004
|
||||
20976: 00000000 DVD (zzz_80146b84 ??, 0x80146c00) : DVD(w): 0x00000000 @ 0xcc006004
|
||||
20977: 00000000 DVD (DVDLowRead, 0x801448a8) : DVD(w): 0x00000020 @ 0xcc006018
|
||||
20978: 00000000 DVD (Read, 0x80144744) : DVD(w): 0xa8000000 @ 0xcc006008
|
||||
20979: 00000000 DVD (Read, 0x80144750) : DVD(w): 0x01094227 @ 0xcc00600c
|
||||
20980: 00000000 DVD (Read, 0x80144758) : DVD(w): 0x00000020 @ 0xcc006010
|
||||
20981: 00000000 DVD (Read, 0x8014475c) : DVD(w): 0x8167cc80 @ 0xcc006014
|
||||
20982: 00000000 DVD (Read, 0x80144760) : DVD(w): 0x00000020 @ 0xcc006018
|
||||
20983: 00000000 DVD (Read, 0x80144768) : DVD(w): 0x00000003 @ 0xcc00601c
|
||||
20984: 00000000 DVD: DVD: Read ISO: DVDOffset=0425089c, DMABuffer=0167cc80, SrcLength=00000020, DMALength=00000020
|
||||
20989: 00000000 DVD (zzz_801442fc ??, 0x80144388) : DVD(r): 0xcc006000
|
||||
20990: 00000000 DVD (zzz_801442fc ??, 0x801443d8) : DVD(w): 0x0000003a @ 0xcc006000
|
||||
20992: 00000000 DVD (zzz_801442fc ??, 0x801444d0) : DVD(w): 0x00000000 @ 0xcc006004
|
||||
20993: 00000000 DVD (zzz_80146e44 ??, 0x80146fcc) : DVD(r): 0xcc006018
|
||||
|
||||
After this, Cubivore infinitely calls DVDGetDriveStatus, which does not even
|
||||
bother to check any DVD regs. Waiting for interrupt?
|
||||
*/
|
||||
After this, Cubivore infinitely calls DVDGetDriveStatus, which does not even
|
||||
bother to check any DVD regs. Waiting for interrupt?
|
||||
*/
|
||||
|
||||
// internal hardware addresses
|
||||
enum
|
||||
|
@ -178,6 +179,8 @@ DVDMemStruct dvdMem;
|
|||
u32 g_ErrorCode = 0x00;
|
||||
bool g_bDiscInside = true;
|
||||
|
||||
Common::CriticalSection dvdread_section;
|
||||
|
||||
void DoState(PointerWrap &p)
|
||||
{
|
||||
p.Do(dvdMem);
|
||||
|
@ -238,7 +241,11 @@ bool IsLidOpen()
|
|||
|
||||
bool DVDRead(u32 _iDVDOffset, u32 _iRamAddress, u32 _iLength)
|
||||
{
|
||||
return VolumeHandler::ReadToPtr(Memory::GetPointer(_iRamAddress), _iDVDOffset, _iLength);
|
||||
// We won't need the crit sec when DTK streaming has been rewritten correctly.
|
||||
dvdread_section.Enter();
|
||||
bool retval = VolumeHandler::ReadToPtr(Memory::GetPointer(_iRamAddress), _iDVDOffset, _iLength);
|
||||
dvdread_section.Leave();
|
||||
return retval;
|
||||
}
|
||||
|
||||
bool DVDReadADPCM(u8* _pDestBuffer, u32 _iNumSamples)
|
||||
|
@ -430,7 +437,7 @@ void ExecuteCommand(UDIDMAControlRegister& _DMAControlReg)
|
|||
// u32 sourcelength = dvdMem.Command[2];
|
||||
#endif
|
||||
u32 destbuffer = dvdMem.DMAAddress.Address;
|
||||
u32 destlength = dvdMem.DMALength.Length;
|
||||
u32 destlength = dvdMem.DMALength.Length;
|
||||
dvdMem.DMALength.Length = 0;
|
||||
|
||||
LOG(DVDINTERFACE, "[WARNING] DVD: Get drive info offset=%08x, destbuffer=%08x, destlength=%08x", offset * 4, destbuffer, destlength);
|
||||
|
@ -455,12 +462,12 @@ void ExecuteCommand(UDIDMAControlRegister& _DMAControlReg)
|
|||
if (g_bDiscInside)
|
||||
{
|
||||
u32 iDVDOffset = dvdMem.Command[1] << 2;
|
||||
u32 iSrcLength = dvdMem.Command[2];
|
||||
if (false) { iSrcLength++; } // avoid warning
|
||||
u32 iSrcLength = dvdMem.Command[2];
|
||||
if (false) { iSrcLength++; } // avoid warning << wtf is this?
|
||||
LOG(DVDINTERFACE, "DVD: Read ISO: DVDOffset=%08x, DMABuffer=%08x, SrcLength=%08x, DMALength=%08x",iDVDOffset,dvdMem.DMAAddress.Address,iSrcLength,dvdMem.DMALength.Length);
|
||||
_dbg_assert_(DVDINTERFACE, iSrcLength == dvdMem.DMALength.Length);
|
||||
|
||||
if (VolumeHandler::ReadToPtr(Memory::GetPointer(dvdMem.DMAAddress.Address), iDVDOffset, dvdMem.DMALength.Length) != true)
|
||||
if (DVDRead(iDVDOffset, dvdMem.DMAAddress.Address, dvdMem.DMALength.Length) != true)
|
||||
{
|
||||
PanicAlert("Cant read from DVD_Plugin - DVD-Interface: Fatal Error");
|
||||
}
|
||||
|
@ -481,9 +488,9 @@ void ExecuteCommand(UDIDMAControlRegister& _DMAControlReg)
|
|||
// Command0 <- Position on DVD shr 2
|
||||
//=========================================================================================================
|
||||
case 0xAB:
|
||||
{
|
||||
{
|
||||
#ifdef LOGGING
|
||||
u32 offset = dvdMem.Command[1] << 2;
|
||||
u32 offset = dvdMem.Command[1] << 2;
|
||||
#endif
|
||||
LOG(DVDINTERFACE, "DVD: Trying to seek: offset=%08x", offset);
|
||||
}
|
||||
|
@ -514,9 +521,9 @@ void ExecuteCommand(UDIDMAControlRegister& _DMAControlReg)
|
|||
|
||||
// ugly hack to catch the disable command
|
||||
if (dvdMem.Command[1]!=0)
|
||||
{
|
||||
{
|
||||
#ifdef LOGGING
|
||||
u8 subCommand = (dvdMem.Command[0] & 0x00FF0000) >> 16;
|
||||
u8 subCommand = (dvdMem.Command[0] & 0x00FF0000) >> 16;
|
||||
#endif
|
||||
|
||||
dvdMem.AudioPos = dvdMem.Command[1] << 2;
|
||||
|
@ -587,4 +594,4 @@ void ExecuteCommand(UDIDMAControlRegister& _DMAControlReg)
|
|||
g_ErrorCode = 0x00;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
|
|
@ -26,55 +26,37 @@ CVolumeGC::CVolumeGC(IBlobReader* _pReader)
|
|||
: m_pReader(_pReader)
|
||||
{}
|
||||
|
||||
|
||||
CVolumeGC::~CVolumeGC()
|
||||
{
|
||||
delete m_pReader;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CVolumeGC::Read(u64 _Offset, u64 _Length, u8* _pBuffer) const
|
||||
bool CVolumeGC::Read(u64 _Offset, u64 _Length, u8* _pBuffer) const
|
||||
{
|
||||
if (m_pReader == NULL)
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
return(m_pReader->Read(_Offset, _Length, _pBuffer));
|
||||
return false;
|
||||
return m_pReader->Read(_Offset, _Length, _pBuffer);
|
||||
}
|
||||
|
||||
|
||||
std::string
|
||||
CVolumeGC::GetName() const
|
||||
std::string CVolumeGC::GetName() const
|
||||
{
|
||||
if (m_pReader == NULL)
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
return false;
|
||||
|
||||
char Name[128];
|
||||
|
||||
if (!Read(0x20, 0x60, (u8*)&Name))
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
return false;
|
||||
|
||||
return(Name);
|
||||
return Name;
|
||||
}
|
||||
|
||||
|
||||
std::string
|
||||
CVolumeGC::GetUniqueID() const
|
||||
std::string CVolumeGC::GetUniqueID() const
|
||||
{
|
||||
static const std::string NO_UID("NO_UID");
|
||||
if (m_pReader == NULL)
|
||||
{
|
||||
return NO_UID;
|
||||
}
|
||||
|
||||
char id[6];
|
||||
|
||||
if (!Read(0, sizeof(id), reinterpret_cast<u8*>(id)))
|
||||
{
|
||||
PanicAlert("Failed to read unique ID from disc image");
|
||||
|
@ -84,14 +66,10 @@ CVolumeGC::GetUniqueID() const
|
|||
return std::string(id, sizeof(id));
|
||||
}
|
||||
|
||||
|
||||
IVolume::ECountry
|
||||
CVolumeGC::GetCountry() const
|
||||
IVolume::ECountry CVolumeGC::GetCountry() const
|
||||
{
|
||||
if (!m_pReader)
|
||||
{
|
||||
return(COUNTRY_UNKNOWN);
|
||||
}
|
||||
return COUNTRY_UNKNOWN;
|
||||
|
||||
u8 CountryCode;
|
||||
m_pReader->Read(3, 1, &CountryCode);
|
||||
|
@ -141,17 +119,12 @@ CVolumeGC::GetCountry() const
|
|||
return(country);
|
||||
}
|
||||
|
||||
|
||||
u64
|
||||
CVolumeGC::GetSize() const
|
||||
u64 CVolumeGC::GetSize() const
|
||||
{
|
||||
if (m_pReader)
|
||||
{
|
||||
return((size_t)m_pReader->GetDataSize());
|
||||
}
|
||||
return (size_t)m_pReader->GetDataSize();
|
||||
else
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -20,35 +20,23 @@
|
|||
#include "Volume.h"
|
||||
#include "Blob.h"
|
||||
|
||||
//
|
||||
// --- this volume type is used for GC and for decrypted Wii images ---
|
||||
//
|
||||
// --- this volume type is used for GC disc images ---
|
||||
|
||||
namespace DiscIO
|
||||
{
|
||||
class CVolumeGC
|
||||
: public IVolume
|
||||
class CVolumeGC : public IVolume
|
||||
{
|
||||
public:
|
||||
public:
|
||||
CVolumeGC(IBlobReader* _pReader);
|
||||
~CVolumeGC();
|
||||
bool Read(u64 _Offset, u64 _Length, u8* _pBuffer) const;
|
||||
std::string GetName() const;
|
||||
std::string GetUniqueID() const;
|
||||
ECountry GetCountry() const;
|
||||
u64 GetSize() const;
|
||||
|
||||
CVolumeGC(IBlobReader* _pReader);
|
||||
|
||||
~CVolumeGC();
|
||||
|
||||
bool Read(u64 _Offset, u64 _Length, u8* _pBuffer) const;
|
||||
|
||||
std::string GetName() const;
|
||||
|
||||
std::string GetUniqueID() const;
|
||||
|
||||
ECountry GetCountry() const;
|
||||
|
||||
u64 GetSize() const;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
IBlobReader* m_pReader;
|
||||
private:
|
||||
IBlobReader* m_pReader;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -22,43 +22,33 @@
|
|||
#include "Blob.h"
|
||||
#include "AES/aes.h"
|
||||
|
||||
//
|
||||
// --- this volume type is used for encrypted Wii images ---
|
||||
//
|
||||
|
||||
namespace DiscIO
|
||||
{
|
||||
class CVolumeWiiCrypted
|
||||
: public IVolume
|
||||
class CVolumeWiiCrypted : public IVolume
|
||||
{
|
||||
public:
|
||||
public:
|
||||
CVolumeWiiCrypted(IBlobReader* _pReader, u64 _VolumeOffset, const unsigned char* _pVolumeKey);
|
||||
~CVolumeWiiCrypted();
|
||||
bool Read(u64 _Offset, u64 _Length, u8* _pBuffer) const;
|
||||
std::string GetName() const;
|
||||
std::string GetUniqueID() const;
|
||||
ECountry GetCountry() const;
|
||||
u64 GetSize() const;
|
||||
|
||||
CVolumeWiiCrypted(IBlobReader* _pReader, u64 _VolumeOffset, const unsigned char* _pVolumeKey);
|
||||
private:
|
||||
IBlobReader* m_pReader;
|
||||
|
||||
~CVolumeWiiCrypted();
|
||||
u8* m_pBuffer;
|
||||
AES_KEY m_AES_KEY;
|
||||
|
||||
bool Read(u64 _Offset, u64 _Length, u8* _pBuffer) const;
|
||||
u64 m_VolumeOffset;
|
||||
|
||||
std::string GetName() const;
|
||||
|
||||
std::string GetUniqueID() const;
|
||||
|
||||
ECountry GetCountry() const;
|
||||
|
||||
u64 GetSize() const;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
IBlobReader* m_pReader;
|
||||
|
||||
u8* m_pBuffer;
|
||||
AES_KEY m_AES_KEY;
|
||||
|
||||
u64 m_VolumeOffset;
|
||||
|
||||
mutable u64 m_LastDecryptedBlockOffset;
|
||||
mutable unsigned char m_LastDecryptedBlock[0x8000];
|
||||
mutable u64 m_LastDecryptedBlockOffset;
|
||||
mutable unsigned char m_LastDecryptedBlock[0x8000];
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
namespace DSound
|
||||
{
|
||||
|
||||
#define BUFSIZE 32768
|
||||
#define MAXWAIT 70 //ms
|
||||
|
||||
|
@ -33,31 +34,33 @@ HANDLE hThread;
|
|||
|
||||
StreamCallback callback;
|
||||
|
||||
//lite mojs
|
||||
IDirectSound8* ds;
|
||||
IDirectSoundBuffer* dsBuffer;
|
||||
|
||||
//tja.. behövs
|
||||
int bufferSize; //i bytes
|
||||
int totalRenderedBytes;
|
||||
int sampleRate;
|
||||
|
||||
//med den här synkar vi stängning..
|
||||
//0=vi spelar oväsen, 1=stäng tråden NU!
|
||||
// playback position
|
||||
int currentPos;
|
||||
int lastPos;
|
||||
short realtimeBuffer[1024 * 1024];
|
||||
|
||||
// We set this to shut down the sound thread.
|
||||
// 0=keep playing, 1=stop playing NOW.
|
||||
volatile int threadData;
|
||||
|
||||
|
||||
inline int FIX128(int x)
|
||||
{
|
||||
return(x & (~127));
|
||||
}
|
||||
|
||||
|
||||
int DSound_GetSampleRate()
|
||||
{
|
||||
return(sampleRate);
|
||||
}
|
||||
|
||||
|
||||
bool CreateBuffer()
|
||||
{
|
||||
PCMWAVEFORMAT pcmwf;
|
||||
|
@ -92,7 +95,6 @@ bool CreateBuffer()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
bool WriteDataToBuffer(DWORD dwOffset, // Our own write cursor.
|
||||
char* soundData, // Start of our data.
|
||||
DWORD dwSoundBytes) // Size of block to copy.
|
||||
|
@ -126,18 +128,12 @@ bool WriteDataToBuffer(DWORD dwOffset, // Our own write cursor.
|
|||
return(false);
|
||||
}
|
||||
|
||||
|
||||
inline int ModBufferSize(int x)
|
||||
{
|
||||
return((x + bufferSize) % bufferSize);
|
||||
}
|
||||
|
||||
|
||||
int currentPos;
|
||||
int lastPos;
|
||||
short realtimeBuffer[1024 * 1024];
|
||||
|
||||
//Själva tråden
|
||||
// The audio thread.
|
||||
DWORD WINAPI soundThread(void*)
|
||||
{
|
||||
currentPos = 0;
|
||||
|
@ -157,6 +153,8 @@ DWORD WINAPI soundThread(void*)
|
|||
|
||||
if (numBytesToRender >= 256)
|
||||
{
|
||||
if (numBytesToRender > sizeof(realtimeBuffer))
|
||||
MessageBox(0,"soundThread: too big render call",0,0);
|
||||
(*callback)(realtimeBuffer, numBytesToRender >> 2, 16, sampleRate, 2);
|
||||
|
||||
WriteDataToBuffer(lastPos, (char*)realtimeBuffer, numBytesToRender);
|
||||
|
@ -174,7 +172,6 @@ DWORD WINAPI soundThread(void*)
|
|||
return(0); //hurra!
|
||||
}
|
||||
|
||||
|
||||
bool DSound_StartSound(HWND window, int _sampleRate, StreamCallback _callback)
|
||||
{
|
||||
callback = _callback;
|
||||
|
@ -189,15 +186,13 @@ bool DSound_StartSound(HWND window, int _sampleRate, StreamCallback _callback)
|
|||
|
||||
//vi vill ha access till DSOUND så...
|
||||
if (FAILED(DirectSoundCreate8(0, &ds, 0)))
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
return false;
|
||||
|
||||
ds->SetCooperativeLevel(window, DSSCL_NORMAL);
|
||||
|
||||
if (!CreateBuffer())
|
||||
{
|
||||
return(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD num1;
|
||||
|
@ -209,21 +204,19 @@ bool DSound_StartSound(HWND window, int _sampleRate, StreamCallback _callback)
|
|||
DWORD h;
|
||||
hThread = CreateThread(0, 0, soundThread, 0, 0, &h);
|
||||
SetThreadPriority(hThread, THREAD_PRIORITY_ABOVE_NORMAL);
|
||||
return(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void DSound_UpdateSound()
|
||||
{
|
||||
SetEvent(soundSyncEvent);
|
||||
}
|
||||
|
||||
|
||||
void DSound_StopSound()
|
||||
{
|
||||
EnterCriticalSection(&soundCriticalSection);
|
||||
threadData = 1;
|
||||
//kick the thread if it's waiting
|
||||
// kick the thread if it's waiting
|
||||
SetEvent(soundSyncEvent);
|
||||
LeaveCriticalSection(&soundCriticalSection);
|
||||
WaitForSingleObject(hThread, INFINITE);
|
||||
|
@ -233,9 +226,10 @@ void DSound_StopSound()
|
|||
ds->Release();
|
||||
|
||||
CloseHandle(soundSyncEvent);
|
||||
soundSyncEvent = INVALID_HANDLE_VALUE;
|
||||
hThread = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
|
||||
int DSound_GetCurSample()
|
||||
{
|
||||
EnterCriticalSection(&soundCriticalSection);
|
||||
|
@ -246,9 +240,9 @@ int DSound_GetCurSample()
|
|||
return(playCursor);
|
||||
}
|
||||
|
||||
|
||||
float DSound_GetTimer()
|
||||
{
|
||||
return((float)DSound_GetCurSample() * (1.0f / (4.0f * sampleRate)));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
Loading…
Reference in New Issue