Crossfire Client, Branches  R11627
sound.c
Go to the documentation of this file.
1 const char * const rcsid_gtk2_sound_c =
2  "$Id: sound.c 9215 2008-06-02 18:31:04Z anmaster $";
3 
4 /*
5  CrossFire, A Multiplayer game for X-windows
6 
7  Copyright (C) 2005 Mark Wedel & Crossfire Development Team
8 
9  This program is free software; you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation; either version 2 of the License, or
12  (at your option) any later version.
13 
14  This program is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program; if not, write to the Free Software
21  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 
23  The author can be reached via e-mail to crossfire@metalforge.org
24 */
25 
33 #include <config.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <ctype.h>
37 #include <errno.h>
38 #include <client-types.h>
39 #include "client.h"
40 
41 FILE *sound_pipe=NULL;
43 
51 int init_sounds(void)
52 {
53 #ifndef WIN32
54  char sound_path[MAX_BUF];
55 
56  /*
57  * Easy trick - global nosound is set in the arg processing - if set, just
58  * return -1 - this way, the calling function only needs to check the value
59  * of init_sounds, and not worry about checking nosound.
60  */
61  if (!want_config[CONFIG_SOUND]) return -1;
62 
63  if (sound_server[0] == '\0') {
64  LOG(LOG_ERROR,"init_sounds:", "sound-server variable not set to anything");
65  return -1;
66  }
67  /*
68  * If an absolute path is given, we use it unadorned. Otherwise, we use
69  * the path in the BINDIR.
70  */
71  if (sound_server[0] == '/')
72  strcpy(sound_path, sound_server);
73  else
74  snprintf(sound_path, sizeof(sound_path),"%s/%s", BINDIR, sound_server);
75 
76  if (access(sound_path, X_OK)<0) {
77  fprintf(stderr,"Unable to access %s sound server process\n", sound_path);
78  return -1;
79  }
80 
81  sound_process=raiseChild(sound_path,CHILD_STDIN|CHILD_STDOUT|CHILD_STDERR);
83 
84  if (fcntl(sound_process->tube[0], F_SETFL, O_NONBLOCK)<0) {
85  /*
86  * Setting non-blocking isn't 100% critical, but a good thing if
87  * possible.
88  */
89  perror("init_sounds: Warning - unable to set non blocking on sound pipe\n");
90  }
91  sound_pipe=fdopen(sound_process->tube[0],"w");
92  return 0;
93 #else
94  return -1;
95 #endif
96 }
97 
114 static void play_sound(int soundnum, int soundtype, int x, int y)
115 {
116 #ifndef WIN32
117 
118  if (!use_config[CONFIG_SOUND]) return;
119  if ( (fprintf(sound_pipe,"%4x %4x %4x %4x\n",soundnum,soundtype,x,y)<=0) ||
120  (fflush(sound_pipe)!=0) ){
121  LOG(LOG_ERROR,"gtk::play_sound","couldn't write to sound pipe: %d",errno);
123  fclose(sound_pipe);
124  sound_process=NULL;
125  return;
126  }
127 #endif
128 }
129 
136 void SoundCmd(unsigned char *data, int len)
137 {
138 #ifndef WIN32
139  int x, y, num, type;
140 
141  if (len!=5) {
142  LOG(LOG_WARNING,"gtk::SoundCmd","Got invalid length on sound command: %d", len);
143  return;
144  }
145  x = data[0];
146  y = data[1];
147  num = GetShort_String(data+2);
148  type = data[4];
149 
150 #if 0
151  fprintf(stderr,"Playing sound %d (type %d), offset %d, %x\n",
152  num, type, x ,y);
153 #endif
154  play_sound(num, type, x, y);
155 #endif
156 }
157 
158 void Sound2Cmd(unsigned char *data, int len)
159 {
160 #ifndef WIN32
161  uint8 x, y, dir, volume, type, len_action;
162  char* action = NULL;
163  uint8 len_name;
164  char* name = NULL;
165  /* sound2 <x><y><dir><volume><type><len of action>action<len of name>name */
166  /* b b b b b b str b str*/
167  if (len<8) {
168  LOG(LOG_WARNING, "gtk::Sound2Cmd", "Got too short length on sound2 command: %d\n", len);
169  return;
170  }
171  x = data[0];
172  y = data[1];
173  dir = data[2];
174  volume = data[3];
175  type = data[4];
176  len_action = data[5];
177  /* Prevent invald index. */
178  if (len_action >= (len-8)) {
179  LOG(LOG_WARNING, "gtk::Sound2Cmd", "Bad length of \"len of action\" in sound2 command: %d\n", len);
180  return;
181  }
182  if (len_action != 0) {
183  action = (char*)data+6;
184  data[6+len_action]='\0';
185  }
186  /* Lets make it readable, compiler will optimize the addition order anyway*/
187  len_name = data[6+len_action+1];
188  if (len_name >= (len-8-len_action)) {
189  LOG(LOG_WARNING, "gtk::Sound2Cmd", "Bad length of \"len of name\" in sound2 command: %d\n", len);
190  return;
191  }
192  if (len_name != 0) {
193  name = (char*)data+6+len_action+1;
194  data[6+len_action+1+len_name]='\0';
195  }
196  LOG(LOG_WARNING, "gtk::Sound2Cmd", "Playing sound2 x=%hhd y=%hhd dir=%hhd volume=%hhd type=%hhd\n",
197  x, y, dir, volume, type);
198  LOG(LOG_WARNING, "gtk::Sound2Cmd", " len_action=%hhd action=%s\n", len_action, action);
199  LOG(LOG_WARNING, "gtk::Sound2Cmd", " len_name=%hhd name=%s\n", len_name, name);
200  LOG(LOG_WARNING, "gtk::Sound2Cmd", "Please impement sound2!");
201  /* TODO: Play sound here. Can't implement/test as server never actually
202  * sends this yet it seems. As this code is mostly duplicated between the
203  * different clients, make sure to update the other ones too.
204  */
205 #endif
206 }
207 
208 void MusicCmd(const char *data, int len) {
209 #ifndef WIN32
210  if (!strncmp(data, "NONE", len)) {
211  /* TODO stop music */
212  } else {
213  LOG(LOG_WARNING, "gtk::MusicCmd", "music command: %s (Implement me!)\n", data);
214  /* TODO: Play music. Can't impmement/test as server doesn't send this
215  * version of the command yet it seems.
216  */
217  }
218 #endif
219 }
short GetShort_String(const unsigned char *data)
Definition: newsocket.c:162
void Sound2Cmd(unsigned char *data, int len)
Definition: sound.c:151
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 *const rcsid_gtk2_sound_c
Definition: sound.c:1
void LOG(LogLevel level, const char *origin, const char *format,...)
Definition: misc.c:178
ChildProcess * sound_process
Definition: sound.c:42
#define CHILD_STDOUT
Definition: client.h:406
sint16 use_config[CONFIG_NUMS]
Definition: init.c:50
#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
#define MAX_BUF
Definition: client-types.h:128
int tube[3]
Definition: client.h:414
char * sound_server
Definition: client.c:62
static void play_sound(int soundnum, int soundtype, int x, int y)
Definition: sound.c:114
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