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