mirror of
				https://github.com/RaySollium99/picodrive.git
				synced 2025-10-28 05:48:52 +01:00 
			
		
		
		
	 8f7ed1b8e1
			
		
	
	
		8f7ed1b8e1
		
	
	
	
	
		
			
			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;
 | |
| }
 | |
| 
 |