Crossfire Client, Branches  R11627
sound.c
Go to the documentation of this file.
1 const char *rcsid_x11_sound_c =
2  "$Id: sound.c 9215 2008-06-02 18:31:04Z anmaster $";
3 /*
4  Crossfire client, a client program for the crossfire program.
5 
6  Copyright (C) 2001 Mark Wedel & Crossfire Development Team
7 
8  This program is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 2 of the License, or
11  (at your option) any later version.
12 
13  This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 
22  The author can be reached via e-mail to crossfire-devel@real-time.com
23 */
24 
31 #include <config.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <ctype.h>
35 #include <signal.h>
36 #include <client-types.h>
37 #include "client.h"
38 
39 
40 int nosound=0;
41 
42 /* Got a pipe signal. As of now, only thing we are piped to is the
43  * sound client.
44  */
45 void signal_pipe(int i) {
46  /* do nothing, but perhaps do something more in the future */
47 }
48 
49 FILE *sound_pipe;
51 
52 
53 /* init_sounds open the audio device, and reads any configuration files
54  * that need to be. It returns 0 on success. On failure, the calling
55  * function will likely disable sound support/requests from the server.
56  */
57 
58 int init_sounds(void)
59 {
60  /* Easy trick - global nosound is set in the arg processing - if set,
61  * just return -1 - this way, the calling function only needs to check
62  * the value of init_sounds, and not worry about checking nosound.
63  */
64  if (!want_config[CONFIG_SOUND]) return -1;
65 
66  /*if (sound_process) //kill*/
67 
68  sound_process=raiseChild(BINDIR "/cfsndserv",CHILD_STDIN|CHILD_STDOUT|CHILD_STDERR);
70  sound_pipe=fdopen(sound_process->tube[0],"w");
71  signal(SIGPIPE, signal_pipe);/*perhaps throwing this out :\*/
72  return 0;
73 }
74 
75 
76 
77 /* Plays sound 'soundnum'. soundtype is 0 for normal sounds, 1 for
78  * spell_sounds. This might get extended in the future. x,y are offset
79  * (assumed from player) to play sound. This information is used to
80  * determine value and left vs right speaker balance.
81  *
82  * This procedure seems to be very slow - much slower than I would
83  * expect. Might need to run this is a thread or fork off.
84  */
85 
86 static void play_sound(int soundnum, int soundtype, int x, int y)
87 {
88  if (nosound) return;
89 
90  if (fprintf(sound_pipe,"%4x %4x %4x %4x\n",soundnum,soundtype,x,y)<=0) {
91  nosound=1;
92  fclose(sound_pipe);
93  return;
94  }
95  if (fflush(sound_pipe)!=0) {
96  nosound=1;
97  fclose(sound_pipe);
98  return;
99  }
100 }
101 
102 
103 void SoundCmd(unsigned char *data, int len)
104 {
105  int x, y, num, type;
106 
107  if (len!=5) {
108  fprintf(stderr,"Got invalid length on sound command: %d\n", len);
109  return;
110  }
111  x = data[0];
112  y = data[1];
113  num = GetShort_String(data+2);
114  type = data[4];
115 
116 #if 0
117  fprintf(stderr,"Playing sound %d (type %d), offset %d, %x\n",
118  num, type, x ,y);
119 #endif
120  play_sound(num, type, x, y);
121 }
122 
123 void Sound2Cmd(unsigned char *data, int len)
124 {
125  uint8 x, y, dir, volume, type, len_action;
126  char* action = NULL;
127  uint8 len_name;
128  char* name = NULL;
129  /* sound2 <x><y><dir><volume><type><len of action>action<len of name>name */
130  /* b b b b b b str b str*/
131  if (len<8) {
132  fprintf(stderr, "Got too short length on sound2 command: %d\n", len);
133  return;
134  }
135  x = data[0];
136  y = data[1];
137  dir = data[2];
138  volume = data[3];
139  type = data[4];
140  len_action = data[5];
141  /* Prevent invald index. */
142  if (len_action >= (len-8)) {
143  fprintf(stderr, "Bad length of \"len of action\" in sound2 command: %d\n", len);
144  return;
145  }
146  if (len_action != 0) {
147  action = (char*)data+6;
148  data[6+len_action]='\0';
149  }
150  /* Lets make it readable, compiler will optimize the addition order anyway*/
151  len_name = data[6+len_action+1];
152  if (len_name >= (len-8-len_action)) {
153  fprintf(stderr, "Bad length of \"len of name\" in sound2 command: %d\n", len);
154  return;
155  }
156  if (len_name != 0) {
157  name = (char*)data+6+len_action+1;
158  data[6+len_action+1+len_name]='\0';
159  }
160 
161  fprintf(stderr, "Playing sound2 x=%hhd y=%hhd dir=%hhd volume=%hhd type=%hhd\n",
162  x, y, dir, volume, type);
163  fprintf(stderr, " len_action=%hhd action=%s\n", len_action, action);
164  fprintf(stderr, " len_name=%hhd name=%s\n", len_name, name);
165  fprintf(stderr, "Please impement sound2!");
166  /* TODO: Play sound here. Can't implement/test as server never actually
167  * sends this yet it seems. As this code is mostly duplicated between the
168  * different clients, make sure to update the other ones too.
169  */
170 }
171 
172 
173 void MusicCmd(const char *data, int len) {
174  if (!strncmp(data, "NONE", len)) {
175  /* TODO stop music */
176  } else {
177  fprintf(stderr, "gtk::MusicCmd", "music command: %s (Implement me!)\n", data);
178  /* TODO: Play music. Can't impmement/test as server doesn't send this
179  * version of the command yet it seems.
180  */
181  }
182 }
short GetShort_String(const unsigned char *data)
Definition: newsocket.c:162
void Sound2Cmd(unsigned char *data, int len)
Definition: sound.c:151
static void play_sound(int soundnum, int soundtype, int x, int y)
Definition: sound.c:86
void logChildPipe(ChildProcess *child, LogLevel level, int flag)
Definition: misc.c:290
sint16 want_config[CONFIG_NUMS]
Definition: init.c:50
FILE * sound_pipe
Definition: sound.c:41
const char * rcsid_x11_sound_c
Definition: sound.c:1
ChildProcess * sound_process
Definition: sound.c:42
#define CHILD_STDOUT
Definition: client.h:406
void signal_pipe(int i)
Definition: sound.c:45
#define CHILD_STDERR
Definition: client.h:407
char * name
Definition: image.c:61
int init_sounds(void)
Definition: sound.c:60
#define CHILD_STDIN
Definition: client.h:405
ChildProcess * raiseChild(char *name, int flag)
Definition: misc.c:297
int tube[3]
Definition: client.h:414
int nosound
Definition: sound.c:40
void MusicCmd(const char *data, int len)
Definition: sound.c:199
unsigned char uint8
Definition: client-types.h:81
#define CONFIG_SOUND
Definition: client.h:164
void SoundCmd(unsigned char *data, int len)
Definition: sound.c:130