You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

191 lines
3.4KB

  1. #include <unistd.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <fcntl.h>
  5. #include <SDL_audio.h>
  6. #include <SDL_error.h>
  7. #include "sound.h"
  8. #ifndef DATADIR
  9. #define DATADIR "data"
  10. #endif
  11. int sound_enabled = 1;
  12. static char dirlist[]=DATADIR;
  13. static int readsound(int num);
  14. #define NUMSOUNDS ((int)(sizeof(soundnames)/sizeof(char*)))
  15. #define MIXMAX 16
  16. #define SOUND_QUIET -1
  17. static const char *soundnames[] = {
  18. "bomb1.raw",
  19. "power1.raw",
  20. "death.raw",
  21. "drop.raw",
  22. "bomb2.raw",
  23. "power2.raw",
  24. };
  25. typedef struct sample
  26. {
  27. char *data;
  28. int len;
  29. } sample;
  30. #define SNDFRAGMENT 1024
  31. static sample samples[NUMSOUNDS];
  32. static int soundworking=0;
  33. static int fragment;
  34. // static int soundwrite,soundread;
  35. static int *soundbuffer;
  36. static int soundbufferlen;
  37. static unsigned char sndclip[8192];
  38. #define MAXSOUNDCOMMANDS 32
  39. static char soundcommands[MAXSOUNDCOMMANDS];
  40. static int soundtake,soundput;
  41. static int sndplaying[MIXMAX],sndposition[MIXMAX];
  42. static void fillaudio(void *udata,Uint8 *buffer,int len)
  43. {
  44. char com,*p;
  45. int i,j,*ip;
  46. int which;
  47. while(soundtake!=soundput)
  48. {
  49. com=soundcommands[soundtake];
  50. soundtake=(soundtake+1)&(MAXSOUNDCOMMANDS-1);
  51. if(com==SOUND_QUIET) {memset(sndposition,0,sizeof(sndposition));continue;}
  52. if(com<NUMSOUNDS)
  53. {
  54. for(i=0;i<MIXMAX;++i)
  55. if(!sndposition[i])
  56. {
  57. sndposition[i]=1;
  58. sndplaying[i]=com;
  59. break;
  60. }
  61. }
  62. }
  63. memset(soundbuffer,0,soundbufferlen);
  64. for(i=0;i<MIXMAX;++i)
  65. {
  66. if(!sndposition[i]) continue;
  67. which=sndplaying[i];
  68. if(sndposition[i]==samples[which].len)
  69. {
  70. sndposition[i]=0;
  71. continue;
  72. }
  73. p=samples[which].data;
  74. if(!p) continue;
  75. p+=len*(sndposition[i]++ -1);
  76. ip=soundbuffer;
  77. j=len;
  78. while(j--) *ip++ += *p++;
  79. }
  80. j=len;
  81. ip=soundbuffer;;
  82. while(j--) *buffer++ = sndclip[4096+*ip++];
  83. }
  84. int soundopen(void) {
  85. SDL_AudioSpec wanted;
  86. int i,j;
  87. soundtake=soundput=0;
  88. memset(sndposition,0,sizeof(sndposition));
  89. memset(sndplaying,0,sizeof(sndplaying));
  90. fragment=SNDFRAGMENT<<1;
  91. soundbufferlen=fragment*sizeof(int);
  92. soundbuffer=malloc(soundbufferlen);
  93. if(!soundbuffer) return -2;
  94. memset(&wanted,0,sizeof(wanted));
  95. wanted.freq=22050;
  96. wanted.channels=2;
  97. wanted.format=AUDIO_U8;
  98. wanted.samples=fragment>>1;
  99. wanted.callback=fillaudio;
  100. wanted.userdata=0;
  101. if(SDL_OpenAudio(&wanted,0)<0)
  102. {
  103. fprintf(stderr,"Couldn't open audio: %s\n",SDL_GetError());
  104. return -1;
  105. }
  106. soundworking=1;
  107. for(i=0;i<8192;i++)
  108. {
  109. j=i-4096;
  110. sndclip[i]=j > 127 ? 255 : (j<-128 ? 0 : j+128);
  111. }
  112. for(i=0;i<NUMSOUNDS;++i)
  113. readsound(i);
  114. SDL_PauseAudio(0);
  115. return 0;
  116. }
  117. void soundclose(void) {
  118. if(soundworking)
  119. {
  120. SDL_CloseAudio();
  121. soundworking=0;
  122. }
  123. }
  124. int readsound(int num) {
  125. char name[256],*p1,*p2,ch;
  126. int i,file,size,len;
  127. p1=dirlist;
  128. for(;;)
  129. {
  130. p2=name;
  131. while(*p1 && (ch=*p1++)!=',')
  132. *p2++=ch;
  133. if(p2>name && p2[-1]!='/') *p2++='/';
  134. strcpy(p2,soundnames[num]);
  135. file=open(name,O_RDONLY);
  136. if(file>=0) break;
  137. if(!*p1)
  138. {
  139. samples[num].len=-1;
  140. return 0;
  141. }
  142. }
  143. size=lseek(file,0,SEEK_END);
  144. lseek(file,0,SEEK_SET);
  145. len=samples[num].len=(size+fragment-1)/fragment;
  146. len*=fragment;
  147. p1=samples[num].data=malloc(len);
  148. if(p1)
  149. {
  150. i=read(file,p1,size);
  151. if(len-size) memset(p1+size,0,len-size);
  152. while(size--) *p1++ ^= 0x80;
  153. } else
  154. samples[num].data=0;
  155. close(file);
  156. return 0;
  157. }
  158. void playsound(int n) {
  159. if (sound_enabled) {
  160. soundcommands[soundput]=n;
  161. soundput=(soundput+1)&(MAXSOUNDCOMMANDS-1);
  162. }
  163. }