bugfix for SIMPLE_WRITE_SOUND
[picodrive.git] / platform / win32 / GenaDrive / DSound.cpp
CommitLineData
cc68a136 1\r
2#include "app.h"\r
3\r
4#ifndef _XBOX\r
5#pragma warning (disable:4201)\r
6#include <mmsystem.h>\r
7#include <dsound.h>\r
8#endif\r
9\r
10static IDirectSound *DSound=NULL;\r
11static IDirectSoundBuffer *LoopBuffer=NULL;\r
12static int LoopLen=0,LoopWrite=0; // Next position in loop to write\r
13\r
14short *DSoundNext=NULL; // Buffer for next sound data to put in loop\r
cc68a136 15\r
16static int LoopBlank()\r
17{\r
18 void *mema=NULL,*memb=NULL;\r
19 DWORD sizea=0,sizeb=0;\r
20\r
21 LoopBuffer->Lock(0,LoopLen<<2, &mema,&sizea, &memb,&sizeb, 0);\r
22 \r
23 if (mema) memset(mema,0,sizea);\r
24\r
25 LoopBuffer->Unlock(mema,sizea, memb,sizeb);\r
26\r
27 return 0;\r
28}\r
29\r
30int DSoundInit()\r
31{\r
32 DSBUFFERDESC dsbd;\r
33 WAVEFORMATEX wfx;\r
34\r
35 memset(&dsbd,0,sizeof(dsbd));\r
36 memset(&wfx,0,sizeof(wfx));\r
37\r
38 // Make wave format:\r
39 wfx.wFormatTag=WAVE_FORMAT_PCM;\r
40 wfx.nChannels=(unsigned short)((PicoOpt&8) ? 2 : 1); // Stereo/mono\r
41 wfx.nSamplesPerSec=PsndRate;\r
42 wfx.wBitsPerSample=16;\r
43\r
44 wfx.nBlockAlign=(WORD)((wfx.nChannels*wfx.wBitsPerSample)>>3);\r
45 wfx.nAvgBytesPerSec=wfx.nBlockAlign*wfx.nSamplesPerSec;\r
46\r
47 // Make buffer for the next seg to put into the loop:\r
03a265e5 48 DSoundNext=(short *)malloc((PsndLen<<2)+64); if (DSoundNext==NULL) return 1;\r
cc68a136 49 memset(DSoundNext,0,PsndLen<<2);\r
50\r
51 // Create the DirectSound interface:\r
52 DirectSoundCreate(NULL,&DSound,NULL);\r
53 if (DSound==NULL) return 1;\r
54\r
55 LoopLen=PsndLen<<1; // 2 segs\r
56\r
57#ifndef _XBOX\r
58 LoopLen<<=1; // 4 segs\r
59 DSound->SetCooperativeLevel(FrameWnd,DSSCL_PRIORITY);\r
60 dsbd.dwFlags=DSBCAPS_GLOBALFOCUS; // Play in background\r
61#endif\r
62\r
63 // Create the looping buffer:\r
64 dsbd.dwSize=sizeof(dsbd);\r
65 dsbd.dwBufferBytes=LoopLen<<wfx.nChannels; // 16bit stereo?\r
66 dsbd.lpwfxFormat=&wfx;\r
67\r
68 DSound->CreateSoundBuffer(&dsbd,&LoopBuffer,NULL);\r
69 if (LoopBuffer==NULL) return 1;\r
70\r
71 LoopBlank();\r
72 LoopBuffer->Play(0,0,DSBPLAY_LOOPING);\r
73 return 0;\r
74}\r
75\r
76void DSoundExit()\r
77{\r
78 if (LoopBuffer) LoopBuffer->Stop();\r
79 RELEASE(LoopBuffer)\r
80 RELEASE(DSound)\r
81 free(DSoundNext); DSoundNext=NULL;\r
82}\r
83\r
84static int WriteSeg()\r
85{\r
86 void *mema=NULL,*memb=NULL;\r
87 DWORD sizea=0,sizeb=0;\r
88\r
89 // Lock the segment at 'LoopWrite' and copy the next segment in\r
90 LoopBuffer->Lock(LoopWrite<<((PicoOpt&8) ? 2 : 1),PsndLen<<((PicoOpt&8) ? 2 : 1), &mema,&sizea, &memb,&sizeb, 0);\r
91 \r
92 if (mema) memcpy(mema,DSoundNext,sizea);\r
03a265e5 93// if (memb) memcpy(memb,DSoundNext+sizea,sizeb);\r
e0978fa8 94 if (sizeb != 0) dprintf2("sizeb is not 0! (%i)\n", sizeb);\r
cc68a136 95\r
96 LoopBuffer->Unlock(mema,sizea, memb,0);\r
97\r
98 return 0;\r
99}\r
100\r
101int DSoundUpdate()\r
102{\r
103 DWORD play=0;\r
104 int pos=0;\r
105\r
8831ef19 106 if (LoopBuffer==NULL) return -1;\r
cc68a136 107\r
108 LoopBuffer->GetCurrentPosition(&play,NULL);\r
109 pos=play>>((PicoOpt&8) ? 2 : 1);\r
110\r
111 // 'LoopWrite' is the next seg in the loop that we want to write\r
112 // First check that the sound 'play' pointer has moved out of it:\r
113 if (pos>=LoopWrite && pos<LoopWrite+PsndLen) return 1; // No, it hasn't\r
114\r
115 WriteSeg();\r
116\r
117 // Advance LoopWrite to next seg:\r
118 LoopWrite+=PsndLen; if (LoopWrite+PsndLen>LoopLen) LoopWrite=0;\r
119\r
120 return 0;\r
121}\r
122\r
123void DSoundMute()\r
124{\r
8831ef19 125 if (LoopBuffer==NULL) return;\r
cc68a136 126 LoopBuffer->Stop();\r
127}\r
128\r
129void DSoundUnMute()\r
130{\r
8831ef19 131 if (LoopBuffer==NULL) return;\r
cc68a136 132 LoopBuffer->Play(0,0,DSBPLAY_LOOPING);\r
133}\r