Port to MS Windows
[gljewel.git] / sound.c
blobd73cca32dbcf1580b4d811e5d3ddb3610b865d52
1 #if defined(_WIN32) && !defined(__CYGWIN__)
2 # define WIN32_LEAN_AND_MEAN 1
3 # include <windows.h>
4 #else
5 # include <unistd.h>
6 # include <sys/ioctl.h>
7 # include <sys/time.h>
8 #endif
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <fcntl.h>
12 #include <signal.h>
13 #include <string.h>
14 #include <errno.h>
16 #include <SDL/SDL.h>
18 #include "misc.h"
20 #define MIXMAX 16
21 #define SNDFRAGMENT 1024
22 #define MAXSOUNDCOMMANDS 32
23 static int soundcommands[MAXSOUNDCOMMANDS];
24 static int soundtake,soundput;
25 static int sndplaying[MIXMAX],sndposition[MIXMAX];
27 static char dirlist[]="data";
29 #define NUMSOUNDS (sizeof(soundnames)/sizeof(char*))
30 #define MIXMAX 16
32 #define SOUND_EXIT -2
33 #define SOUND_QUIET -1
35 static char *soundnames[] =
37 "row.raw", // 0
38 "drop.raw", // 1
39 "bigdrop.raw", // 2
40 "swap.raw", // 3
41 "gameover.raw", // 4
42 "alert.raw", // 5
43 "illegal.raw", // 6
45 typedef struct sample
47 short *data;
48 int len;
49 } sample;
51 static sample samples[NUMSOUNDS];
53 static int soundworking=0;
54 static int fragment;
55 static int *soundbuffer;
56 static int soundbufferlen;
59 static int readsound(int num)
61 char name[256],*p1,*p2,ch;
62 int i,size,len;
63 FILE* file = NULL;
64 p1=dirlist;
65 for(;;)
67 p2=name;
68 while(*p1 && (ch=*p1++)!=',')
69 *p2++=ch;
70 if(p2>name && p2[-1]!='/') *p2++='/';
71 strcpy(p2,soundnames[num]);
72 file=fopen(name,"r");
73 if(file) break;
74 if(!*p1)
76 samples[num].len=-1;
77 return 0;
80 size=fseek(file,0,SEEK_END);
81 fseek(file,0,SEEK_SET);
82 size>>=1;
83 len=samples[num].len=(size+fragment-1)/fragment;
84 len*=fragment;
85 p1=(void *)(samples[num].data=malloc(len<<1));
86 if(p1)
88 memset(p1,0,len<<1);
89 i=fread(p1,sizeof(char),size<<1,file);
90 } else
91 samples[num].data=0;
92 fclose(file);
93 return 0;
96 static void fillaudio(void *udata, Uint8 *bp,int len)
98 char com;
99 short *p;
100 int i,j,*ip;
101 int which;
102 Sint16 *buffer = (void *)bp;
104 len/=2;
106 while(soundtake!=soundput)
108 com=soundcommands[soundtake];
109 soundtake=(soundtake+1)&(MAXSOUNDCOMMANDS-1);
110 if(com==SOUND_QUIET) {memset(sndposition,0,sizeof(sndposition));continue;}
111 if(com<NUMSOUNDS)
113 for(i=0;i<MIXMAX;++i)
114 if(!sndposition[i])
116 sndposition[i]=1;
117 sndplaying[i]=com;
118 break;
122 memset(soundbuffer,0,soundbufferlen);
123 for(i=0;i<MIXMAX;++i)
125 if(!sndposition[i]) continue;
126 which=sndplaying[i];
127 if(sndposition[i]==samples[which].len)
129 sndposition[i]=0;
130 continue;
132 p=samples[which].data;
133 if(!p) continue;
134 p+=len*(sndposition[i]++ -1);
135 ip=soundbuffer;
136 j=len;
137 while(j--) *ip++ += *p++;
139 j=len;
140 ip=soundbuffer;;
141 while(j--)
143 int t;
144 t=*ip++;
145 t = (t>0x7fff) ? 0x7fff : (t<-0x8000) ? -0x8000 : t;
146 *buffer++ = t;
151 int soundinit(void)
153 SDL_AudioSpec wanted;
154 int i;
156 soundtake=soundput=0;
157 memset(sndposition,0,sizeof(sndposition));
158 memset(sndplaying,0,sizeof(sndplaying));
159 fragment=SNDFRAGMENT;
160 soundbufferlen=fragment*sizeof(int);
161 soundbuffer=malloc(soundbufferlen);
162 if(!soundbuffer) return -2;
164 memset(&wanted,0,sizeof(wanted));
165 wanted.freq=22050;
166 wanted.channels=1;
167 wanted.format=AUDIO_S16;
168 wanted.samples=fragment;
169 wanted.callback=fillaudio;
170 wanted.userdata=0;
172 if(SDL_OpenAudio(&wanted,0)<0)
174 fprintf(stderr,"Couldn't open audio: %s\n",SDL_GetError());
175 return -1;
177 soundworking=1;
179 for(i=0;i<NUMSOUNDS;++i)
180 readsound(i);
182 SDL_PauseAudio(0);
183 return 0;
186 void soundfree(void)
188 if(soundbuffer)
190 free(soundbuffer);
191 soundbuffer = 0;
193 SDL_PauseAudio(0);
196 void playsound(int n)
198 soundcommands[soundput]=n;
199 soundput=(soundput+1)&(MAXSOUNDCOMMANDS-1);