mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 15:27:46 -04:00

git-svn-id: file:///home/notaz/opt/svn/PicoDrive@450 be3aeb3a-fb24-0410-a615-afba39da0efa
148 lines
3.6 KiB
C++
148 lines
3.6 KiB
C++
|
|
#include "app.h"
|
|
|
|
#ifndef _XBOX
|
|
#pragma warning (disable:4201)
|
|
#include <mmsystem.h>
|
|
#include <dsound.h>
|
|
#endif
|
|
|
|
static IDirectSound *DSound=NULL;
|
|
static IDirectSoundBuffer *LoopBuffer=NULL;
|
|
static int LoopLen=0,LoopWrite=0; // Next position in loop to write
|
|
|
|
short *DSoundNext=NULL; // Buffer for next sound data to put in loop
|
|
|
|
static int LoopBlank()
|
|
{
|
|
void *mema=NULL,*memb=NULL;
|
|
DWORD sizea=0,sizeb=0;
|
|
|
|
LoopBuffer->Lock(0,LoopLen<<((PicoOpt&8) ? 2 : 1), &mema,&sizea, &memb,&sizeb, 0);
|
|
|
|
if (mema) memset(mema,0,sizea);
|
|
|
|
LoopBuffer->Unlock(mema,sizea, memb,sizeb);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int DSoundInit()
|
|
{
|
|
DSBUFFERDESC dsbd;
|
|
WAVEFORMATEX wfx;
|
|
|
|
memset(&dsbd,0,sizeof(dsbd));
|
|
memset(&wfx,0,sizeof(wfx));
|
|
|
|
// Make wave format:
|
|
wfx.wFormatTag=WAVE_FORMAT_PCM;
|
|
wfx.nChannels=(unsigned short)((PicoOpt&8) ? 2 : 1); // Stereo/mono
|
|
wfx.nSamplesPerSec=PsndRate;
|
|
wfx.wBitsPerSample=16;
|
|
|
|
wfx.nBlockAlign=(WORD)((wfx.nChannels*wfx.wBitsPerSample)>>3);
|
|
wfx.nAvgBytesPerSec=wfx.nBlockAlign*wfx.nSamplesPerSec;
|
|
|
|
// Make buffer for the next seg to put into the loop:
|
|
DSoundNext=(short *)malloc((PsndLen<<2)+64); if (DSoundNext==NULL) return 1;
|
|
memset(DSoundNext,0,PsndLen<<2);
|
|
// lprintf("p %p\n", DSoundNext);
|
|
|
|
// Create the DirectSound interface:
|
|
DirectSoundCreate(NULL,&DSound,NULL);
|
|
if (DSound==NULL) return 1;
|
|
|
|
LoopLen=PsndLen<<1; // 2 segs
|
|
|
|
#ifndef _XBOX
|
|
LoopLen<<=1; // 4 segs
|
|
DSound->SetCooperativeLevel(FrameWnd,DSSCL_PRIORITY);
|
|
dsbd.dwFlags=DSBCAPS_GLOBALFOCUS; // Play in background
|
|
#endif
|
|
|
|
// Create the looping buffer:
|
|
dsbd.dwSize=sizeof(dsbd);
|
|
dsbd.dwBufferBytes=LoopLen<<wfx.nChannels; // 16bit stereo?
|
|
dsbd.lpwfxFormat=&wfx;
|
|
|
|
DSound->CreateSoundBuffer(&dsbd,&LoopBuffer,NULL);
|
|
if (LoopBuffer==NULL) return 1;
|
|
|
|
LoopBlank();
|
|
LoopBuffer->Play(0,0,DSBPLAY_LOOPING);
|
|
return 0;
|
|
}
|
|
|
|
void DSoundExit()
|
|
{
|
|
if (LoopBuffer) LoopBuffer->Stop();
|
|
RELEASE(LoopBuffer)
|
|
RELEASE(DSound)
|
|
DSound=0;
|
|
if (DSoundNext) free(DSoundNext); DSoundNext=NULL;
|
|
}
|
|
|
|
static int WriteSeg()
|
|
{
|
|
void *mema=NULL,*memb=NULL;
|
|
DWORD sizea=0,sizeb=0;
|
|
int ret;
|
|
|
|
// Lock the segment at 'LoopWrite' and copy the next segment in
|
|
ret = LoopBuffer->Lock(LoopWrite<<((PicoOpt&8) ? 2 : 1),PsndLen<<((PicoOpt&8) ? 2 : 1), &mema,&sizea, &memb,&sizeb, 0);
|
|
if (ret) lprintf("LoopBuffer->Lock() failed: %i\n", ret);
|
|
|
|
if (mema) memcpy(mema,DSoundNext,sizea);
|
|
// if (memb) memcpy(memb,DSoundNext+sizea,sizeb);
|
|
if (sizeb != 0) lprintf("sizeb is not 0! (%i)\n", sizeb);
|
|
|
|
ret = LoopBuffer->Unlock(mema,sizea, memb,0);
|
|
if (ret) lprintf("LoopBuffer->Unlock() failed: %i\n", ret);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int DSoundFake()
|
|
{
|
|
static int ticks_old = 0;
|
|
int ticks = GetTickCount() * 1000;
|
|
int diff;
|
|
|
|
diff = ticks - ticks_old;
|
|
if (diff >= 0 && diff < 1000000/60*4)
|
|
{
|
|
while (diff >= 0 && diff < 1000000/60)
|
|
{
|
|
Sleep(1);
|
|
diff = GetTickCount()*1000 - ticks_old;
|
|
}
|
|
ticks_old += 1000000/60;
|
|
}
|
|
else
|
|
ticks_old = ticks;
|
|
return 0;
|
|
}
|
|
|
|
int DSoundUpdate()
|
|
{
|
|
DWORD play=0;
|
|
int pos=0;
|
|
|
|
if (LoopBuffer==NULL) return DSoundFake();
|
|
|
|
LoopBuffer->GetCurrentPosition(&play,NULL);
|
|
pos=play>>((PicoOpt&8) ? 2 : 1);
|
|
|
|
// 'LoopWrite' is the next seg in the loop that we want to write
|
|
// First check that the sound 'play' pointer has moved out of it:
|
|
if (pos>=LoopWrite && pos<LoopWrite+PsndLen) return 1; // No, it hasn't
|
|
|
|
WriteSeg();
|
|
|
|
// Advance LoopWrite to next seg:
|
|
LoopWrite+=PsndLen; if (LoopWrite+PsndLen>LoopLen) LoopWrite=0;
|
|
|
|
return 0;
|
|
}
|
|
|