source: abuse/trunk/src/sndserver.cpp @ 124

Last change on this file since 124 was 124, checked in by Sam Hocevar, 12 years ago
  • Get rid of ugly tabs and trailing spaces everywhere.
File size: 7.8 KB
RevLine 
[56]1/*
2 *  Abuse - dark 2D side-scrolling platform game
3 *  Copyright (c) 1995 Crack dot Com
4 *
5 *  This software was released into the Public Domain. As with most public
6 *  domain software, no warranty is made or implied by Crack dot Com or
7 *  Jonathan Clark.
8 */
9
10#include "config.h"
11
[2]12extern "C"
13{
14#include <sys/types.h>
15#include <stdio.h>
16#include <fcntl.h>
17#include <sys/ioctl.h>
18#include <unistd.h>
19#include <stdlib.h>
20#include <malloc.h>
21#include <sys/stat.h>
22#include <linux/soundcard.h>
23#include <sys/time.h>
24#include "DoomDef.h"
25};
26
27#include "sndserver.h"
28#include "wadread.h"
29
30#define SOUNDDIR LIBDIR "/sfx/"
31
32typedef struct wadinfo_struct
33{
[124]34  char    identification[4];        // should be IWAD
35  int    numlumps;
36  int    infotableofs;
[2]37} wadinfo_t;
38
39typedef struct filelump_struct
40{
[124]41  int    filepos;
42  int    size;
43  char    name[8];
[2]44} filelump_t;
45
[124]46static int mytime = 0;        // an internal time keeper
47int numsounds;            // number of sound effects
48int longsound;            // longest sound effect
49int lengths[NUMSFX];        // lengths of all sound effects
50uint8_t mixbuffer[MIXBUFFERSIZE];    // mixing buffer
51int sfxdevice;            // file descriptor of sfx device
52int musdevice;            // file descriptor of music device
53uint8_t *channels[8];    // the channel data pointers
54uint8_t *channelsend[8];    // the channel data end pointers
55int channelstart[8];        // time that the channel started playing
56int channelhandles[8];        // the channel handles
[2]57
58static void derror(char *msg)
59{
60  fprintf(stderr, "error: %s\n", msg);
61  exit(-1);
62}
63
64int mix(void)
65{
66
67  register int i, j, d;
68
69//  if (channels[0]) fprintf(stderr, ".");
70
71//  for (d=i=0 ; i<8 ; i++)
72//    d |= (int) channels[i];
73//  if (!d) return 0;
74
75  // mix into the mixing buffer
76  for (i=0 ; i<MIXBUFFERSIZE ; i++)
77  {
78    d = 0;
79    j = 8;
80    do {
81      if (channels[--j])
82      {
83        d += *channels[j]++ - 128;
84      }
85    } while (j);
86    if (d > 127) mixbuffer[i] = 255;
87    else if (d < -128) mixbuffer[i] = 0;
[17]88    else mixbuffer[i] = (uint8_t) (d+128);
[2]89//    if (d > 127) mixbuffer[i] = 0;
90//    else if (d < -128) mixbuffer[i] = 255;
[17]91//    else mixbuffer[i] = (uint8_t) (-d+127);
[2]92  }
93
94  // check for freed channels
95  for (j=0 ; j<8 ; j++)
96  {
97    if (channels[j] == channelsend[j]) channels[j] = 0;
98  }
99
100  return 1;
101
102}
103
104void grabdata(int c, char **v)
105{
106
107  int i;
108
109  numsounds = NUMSFX;
110  longsound = 0;
111
112  openwad("../frame/doom.wad");
113
114  for (i=1 ; i<NUMSFX ; i++)
115  {
116    if (!S_sfx[i].link)
117    {
118      S_sfx[i].data = getsfx(S_sfx[i].name, &lengths[i]);
119      if (longsound < lengths[i]) longsound = lengths[i];
120    } else {
121      S_sfx[i].data = S_sfx[i].link->data;
122      lengths[i] = lengths[(S_sfx[i].link - S_sfx)/sizeof(struct sfxinfo_t)];
123    }
124    /*
125    // test only
126    {
127      int fd;
128      char name[10];
129      sprintf(name, "sfx%d", i);
130      fd = open(name, O_WRONLY|O_CREAT, 0644);
131      write(fd, S_sfx[i].data, lengths[i]);
132      close(fd);
133    }
134    */
135  }
136
137}
138
139void opensfxdev(int c, char **v)
140{
141
142  int i, rc;
143
144  // open the sound device
145  sfxdevice = open("/dev/dsp", O_WRONLY, 0);
146  if (sfxdevice < 0) derror("Could not open /dev/dsp");
147
148  // set it up for the proper sound format
149  i = 8;
150  rc = ioctl(sfxdevice, SNDCTL_DSP_SAMPLESIZE, &i);
151  if (rc < 0) fprintf(stderr, "SAMPLESIZE failed\n");
152  i = 11111;
153  rc = ioctl(sfxdevice, SNDCTL_DSP_SPEED, &i);
154  if (rc < 0) fprintf(stderr, "SPEED failed\n");
155  i = 0;
156  rc = ioctl(sfxdevice, SNDCTL_DSP_STEREO, &i);
157  if (rc < 0) fprintf(stderr, "STEREO failed\n");
158//  i = 2;
159//  rc = ioctl(sfxdevice, SNDCTL_DSP_SUBDIVIDE, &i);
160//  if (rc < 0) fprintf(stderr, "SUBDIVIDE failed\n");
161
162}
163
164void closesfxdev(void)
165{
166  close(sfxdevice);
167}
168
169void openmusdev(int c, char **v)
170{
171}
172
173void closemusdev(void)
174{
175}
176
177static struct timeval last={0,0}, now;
178static struct timezone whocares;
179
180void updatesounds(void)
181{
182  int deltatime;
183  int rc;
184
185  rc = mix();
186  rc = ioctl(sfxdevice, SNDCTL_DSP_POST, 0);
187//  rc = ioctl(sfxdevice, SNDCTL_DSP_SYNC, 0);
188  if (rc < 0) fprintf(stderr, "SYNC failed?!\n");
189  write(sfxdevice, mixbuffer, MIXBUFFERSIZE);
190/*
191  gettimeofday(&now, &whocares);
192  deltatime = (now.tv_sec - last.tv_sec)*1000000 + now.tv_usec - last.tv_usec;
193  deltatime = deltatime - (1 * MIXBUFFERSIZE * 1000000) / (1 * SPEED);
194  last = now;
195  if (deltatime < 0)
196    usleep (-deltatime);
197  if (rc)
198  {
199    write(sfxdevice, mixbuffer, MIXBUFFERSIZE);
200    fprintf(stderr, ".");
201  }
202*/
203}
204
205int addsfx(int sfxid, int volume)
206{
207
208  int i;
209  int rc = -1;
[17]210  static uint16_t handlenums = 0;
[2]211  int oldest = mytime;
212  int oldestnum = 0;
213
214  for (i=0 ; i<8 ; i++)
215  {
216    if (!channels[i])
217    {
218      channelsend[i] =
[17]219        (channels[i] = (uint8_t *) S_sfx[sfxid].data) + lengths[sfxid];
[2]220      if (!handlenums) handlenums = 100;
221      channelhandles[i] = rc = handlenums++;
222      channelstart[i] = mytime;
223      break;
224    }
225    else
226    {
227      if (channelstart[i] < oldest)
228      {
229        oldestnum = i;
[124]230    oldest = channelstart[i];
[2]231      }
232    }
233  }
234
235  // if no channels were available, kill oldest sound and replace it
236  if (i == 8)
237  {
238    channelsend[oldestnum] =
[17]239      (channels[oldestnum] = (uint8_t *) S_sfx[sfxid].data)
[2]240       + lengths[sfxid];
241    if (!handlenums) handlenums = 100;
242    channelhandles[oldestnum] = rc = handlenums++;
243    channelstart[i] = mytime;
244  }
245
246  return rc;
247
248}
249
[17]250void output_uint16(int num)
[2]251{
252
[17]253  static uint8_t buff[5] = { 0, 0, 0, 0, '\n' };
[2]254  static char *badbuff = "xxxx\n";
255
256  // outputs a 16-bit # in hex or "xxxx" if -1.
257  if (num < 0)
258  {
259    write(1, badbuff, 5);
260  } else {
261    buff[0] = num>>12;
262    buff[0] += buff[0] > 9 ? 'a'-10 : '0';
263    buff[1] = (num>>8) & 0xf;
264    buff[1] += buff[1] > 9 ? 'a'-10 : '0';
265    buff[2] = (num>>4) & 0xf;
266    buff[2] += buff[2] > 9 ? 'a'-10 : '0';
267    buff[3] = num & 0xf;
268    buff[3] += buff[3] > 9 ? 'a'-10 : '0';
269    write(1, buff, 5);
270  }
271
272}
273
274void initdata(void)
275{
276  int i;
[17]277  for (i=0 ; i<sizeof(channels)/sizeof(uint8_t *) ; i++) channels[i] = 0;
[2]278  gettimeofday(&last, &whocares);
279  usleep(100000);
280}
281
282int main(int c, char **v)
283{
284
285  int done = 0;
286  int rc, nrc, sndnum, handle = 0;
[17]287  uint8_t commandbuf[10];
[2]288  fd_set fdset, scratchset;
289  struct timeval zerowait = { 0, 0 };
290
[124]291  grabdata(c, v);    // get sound data
292  initdata();        // init any data
[2]293
[124]294  opensfxdev(c, v);    // open sfx device
295  openmusdev(c, v);    // open music device
[2]296  fprintf(stderr, "ready\n");
297
298  // parse commands and play sounds until done
299  FD_ZERO(&fdset);
300  FD_SET(0, &fdset);
301  while (!done)
302  {
303    mytime++;
304    do {
305      scratchset = fdset;
306      rc = select(FD_SETSIZE, &scratchset, 0, 0, &zerowait);
307      if (rc > 0)
308      {
309  //      fprintf(stderr, "select is true\n");
[124]310    // got a command
311    nrc = read(0, commandbuf, 1);
312    if (!nrc) { done = 1; rc = 0; }
313    else {
314      switch (commandbuf[0])
315      {
316        case 'p':         // play a new sound effect
317          read(0, commandbuf, 3);
318          commandbuf[0] -= commandbuf[0]>='a' ? 'a'-10 : '0';
319          commandbuf[1] -= commandbuf[1]>='a' ? 'a'-10 : '0';
320          sndnum = (commandbuf[0]<<4) + commandbuf[1];
321  //        fprintf(stderr, "cmd: play sound %d\n", sndnum);
322          handle = addsfx(sndnum, 127); // returns the handle
323//          outputushort(handle);
324          break;
325        case 'q':
326          read(0, commandbuf, 1);
327          done = 1; rc = 0;
328          break;
329        case 's':
330          {
331            int fd;
332        read(0, commandbuf, 3);
333        commandbuf[2] = 0;
334        fd = open((char*)commandbuf, O_CREAT|O_WRONLY, 0644);
335        commandbuf[0] -= commandbuf[0]>='a' ? 'a'-10 : '0';
336        commandbuf[1] -= commandbuf[1]>='a' ? 'a'-10 : '0';
337        sndnum = (commandbuf[0]<<4) + commandbuf[1];
338        write(fd, S_sfx[sndnum].data, lengths[sndnum]);
339        close(fd);
340          }
341          break;
342        default:
343          fprintf(stderr, "Did not recognize command\n");
344          break;
[2]345      }
[124]346    }
347      }
[2]348    } while (rc > 0);
349    updatesounds();
350  }
351
352  closesfxdev();
353  closemusdev();
354
355}
Note: See TracBrowser for help on using the repository browser.