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:
hrydgard 2008-09-24 20:47:11 +00:00
parent 3883ce6ee9
commit 08e81eddb9
6 changed files with 116 additions and 165 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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