Fixed a build problem.
[gljewel.git] / sound.c
blobbf679520c4e7cc7a7ef9c61baecf95e678200cd1
1 /**
2 * @file matrix.c
3 * @brief The implementation of the gljewel sound module.
5 * Copyright 2001, 2008 David Ashley <dashxdr@gmail.com>
6 * Copyright 2008 Stephen M. Webb <stephen.webb@bregmasoft.ca>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of Version 2 of the GNU General Public License as
10 * published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #if defined(_WIN32) && !defined(__CYGWIN__)
23 # define WIN32_LEAN_AND_MEAN 1
24 # include <windows.h>
25 #else
26 # include <unistd.h>
27 # include <sys/ioctl.h>
28 # include <sys/time.h>
29 #endif
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <fcntl.h>
33 #include <signal.h>
34 #include <string.h>
35 #include <errno.h>
37 #include <SDL/SDL.h>
39 #include "misc.h"
41 #define MIXMAX 16
42 #define SNDFRAGMENT 1024
43 #define MAXSOUNDCOMMANDS 32
44 static int soundcommands[MAXSOUNDCOMMANDS];
45 static int soundtake,soundput;
46 static int sndplaying[MIXMAX],sndposition[MIXMAX];
48 static char dirlist[]="data,"DATA_DIR;
50 #define NUMSOUNDS (sizeof(soundnames)/sizeof(char*))
51 #define MIXMAX 16
53 #define SOUND_EXIT -2
54 #define SOUND_QUIET -1
56 static char *soundnames[] =
58 "row.raw", // 0
59 "drop.raw", // 1
60 "bigdrop.raw", // 2
61 "swap.raw", // 3
62 "gameover.raw", // 4
63 "alert.raw", // 5
64 "illegal.raw", // 6
66 typedef struct sample
68 short *data;
69 int len;
70 } sample;
72 static sample samples[NUMSOUNDS];
74 static int soundworking=0;
75 static int fragment;
76 static int *soundbuffer;
77 static int soundbufferlen;
80 static int readsound(int num)
82 char name[256],*p1,*p2,ch;
83 int i,size,len;
84 FILE* file = NULL;
85 p1=dirlist;
86 for(;;)
88 p2=name;
89 while(*p1 && (ch=*p1++)!=',')
90 *p2++=ch;
91 if(p2>name && p2[-1]!='/') *p2++='/';
92 strcpy(p2,soundnames[num]);
93 file=fopen(name,"rb");
94 if(file) break;
95 if(!*p1)
97 samples[num].len=-1;
98 return 0;
101 size=fseek(file,0,SEEK_END);
102 if (size <= 0)
104 samples[num].len=-1;
105 return 0;
107 fseek(file,0,SEEK_SET);
108 size>>=1;
109 len=samples[num].len=(size+fragment-1)/fragment;
110 len*=fragment;
111 p1=(void *)(samples[num].data=malloc(len<<1));
112 if(p1)
114 memset(p1,0,len<<1);
115 i=fread(p1,sizeof(char),size<<1,file);
116 } else
117 samples[num].data=0;
118 fclose(file);
119 return 0;
122 static void fillaudio(void *udata, Uint8 *bp,int len)
124 char com;
125 short *p;
126 int i,j,*ip;
127 int which;
128 Sint16 *buffer = (void *)bp;
130 len/=2;
132 while(soundtake!=soundput)
134 com=soundcommands[soundtake];
135 soundtake=(soundtake+1)&(MAXSOUNDCOMMANDS-1);
136 if(com==SOUND_QUIET) {memset(sndposition,0,sizeof(sndposition));continue;}
137 if(com<NUMSOUNDS)
139 for(i=0;i<MIXMAX;++i)
140 if(!sndposition[i])
142 sndposition[i]=1;
143 sndplaying[i]=com;
144 break;
148 memset(soundbuffer,0,soundbufferlen);
149 for(i=0;i<MIXMAX;++i)
151 if(!sndposition[i]) continue;
152 which=sndplaying[i];
153 if(sndposition[i]==samples[which].len)
155 sndposition[i]=0;
156 continue;
158 p=samples[which].data;
159 if(!p) continue;
160 p+=len*(sndposition[i]++ -1);
161 ip=soundbuffer;
162 j=len;
163 while(j--) *ip++ += *p++;
165 j=len;
166 ip=soundbuffer;;
167 while(j--)
169 int t;
170 t=*ip++;
171 t = (t>0x7fff) ? 0x7fff : (t<-0x8000) ? -0x8000 : t;
172 *buffer++ = t;
177 int soundinit(void)
179 SDL_AudioSpec wanted;
180 int i;
182 soundtake=soundput=0;
183 memset(sndposition,0,sizeof(sndposition));
184 memset(sndplaying,0,sizeof(sndplaying));
185 fragment=SNDFRAGMENT;
186 soundbufferlen=fragment*sizeof(int);
187 soundbuffer=malloc(soundbufferlen);
188 if(!soundbuffer) return -2;
190 memset(&wanted,0,sizeof(wanted));
191 wanted.freq=22050;
192 wanted.channels=1;
193 wanted.format=AUDIO_S16;
194 wanted.samples=fragment;
195 wanted.callback=fillaudio;
196 wanted.userdata=0;
198 if(SDL_OpenAudio(&wanted,0)<0)
200 fprintf(stderr,"Couldn't open audio: %s\n",SDL_GetError());
201 return -1;
203 soundworking=1;
205 for(i=0;i<NUMSOUNDS;++i)
206 readsound(i);
208 SDL_PauseAudio(0);
209 return 0;
212 void soundfree(void)
214 if(soundbuffer)
216 free(soundbuffer);
217 soundbuffer = 0;
219 SDL_PauseAudio(0);
222 void playsound(int n)
224 soundcommands[soundput]=n;
225 soundput=(soundput+1)&(MAXSOUNDCOMMANDS-1);