From 08e81eddb97614a4e286a6f35092fe56c16a3113 Mon Sep 17 00:00:00 2001 From: hrydgard Date: Wed, 24 Sep 2008 20:47:11 +0000 Subject: [PATCH] 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 --- Source/Core/Common/Src/Thread.h | 33 +++++----- Source/Core/Core/Src/HW/DVDInterface.cpp | 63 ++++++++++--------- Source/Core/DiscIO/Src/VolumeGC.cpp | 55 +++++----------- Source/Core/DiscIO/Src/VolumeGC.h | 38 ++++------- Source/Core/DiscIO/Src/VolumeWiiCrypted.h | 46 ++++++-------- .../Plugin_DSP_HLE/Src/PCHW/DSoundStream.cpp | 46 ++++++-------- 6 files changed, 116 insertions(+), 165 deletions(-) diff --git a/Source/Core/Common/Src/Thread.h b/Source/Core/Common/Src/Thread.h index 6043215eef..9e351bc839 100644 --- a/Source/Core/Common/Src/Thread.h +++ b/Source/Core/Common/Src/Thread.h @@ -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 }; diff --git a/Source/Core/Core/Src/HW/DVDInterface.cpp b/Source/Core/Core/Src/HW/DVDInterface.cpp index 66d32b0492..7b7aae4220 100644 --- a/Source/Core/Core/Src/HW/DVDInterface.cpp +++ b/Source/Core/Core/Src/HW/DVDInterface.cpp @@ -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 diff --git a/Source/Core/DiscIO/Src/VolumeGC.cpp b/Source/Core/DiscIO/Src/VolumeGC.cpp index 3092f405c3..f942898e42 100644 --- a/Source/Core/DiscIO/Src/VolumeGC.cpp +++ b/Source/Core/DiscIO/Src/VolumeGC.cpp @@ -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(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 diff --git a/Source/Core/DiscIO/Src/VolumeGC.h b/Source/Core/DiscIO/Src/VolumeGC.h index d481c7818b..a29f30db29 100644 --- a/Source/Core/DiscIO/Src/VolumeGC.h +++ b/Source/Core/DiscIO/Src/VolumeGC.h @@ -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 diff --git a/Source/Core/DiscIO/Src/VolumeWiiCrypted.h b/Source/Core/DiscIO/Src/VolumeWiiCrypted.h index aef579b0e8..63e9cad76e 100644 --- a/Source/Core/DiscIO/Src/VolumeWiiCrypted.h +++ b/Source/Core/DiscIO/Src/VolumeWiiCrypted.h @@ -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 diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/PCHW/DSoundStream.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/PCHW/DSoundStream.cpp index 9ee20ea6e5..1541d20cd0 100644 --- a/Source/Plugins/Plugin_DSP_HLE/Src/PCHW/DSoundStream.cpp +++ b/Source/Plugins/Plugin_DSP_HLE/Src/PCHW/DSoundStream.cpp @@ -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