Crossfire Client, Branch
R11627
|
00001 const char * const rcsid_gtk_sound_c = 00002 "$Id: sound.c 9719 2008-08-04 18:57:47Z ryo_saeba $"; 00003 00004 /* 00005 CrossFire, A Multiplayer game for X-windows 00006 00007 Copyright (C) 2001 Mark Wedel & Crossfire Development Team 00008 Copyright (C) 1992 Frank Tore Johansen 00009 00010 This program is free software; you can redistribute it and/or modify 00011 it under the terms of the GNU General Public License as published by 00012 the Free Software Foundation; either version 2 of the License, or 00013 (at your option) any later version. 00014 00015 This program is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 GNU General Public License for more details. 00019 00020 You should have received a copy of the GNU General Public License 00021 along with this program; if not, write to the Free Software 00022 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00023 00024 The author can be reached via e-mail to crossfire-devel@real-time.com 00025 */ 00026 00027 00035 #include <config.h> 00036 #include <stdio.h> 00037 #include <stdlib.h> 00038 #include <ctype.h> 00039 #include <signal.h> 00040 #include <errno.h> 00041 #include <client-types.h> 00042 #include "client.h" 00043 00044 00045 /* Got a pipe signal. As of now, only thing we are piped to is the 00046 * sound client. 00047 */ 00048 static void signal_pipe(int i) { 00049 /* do nothing, but perhaps do something more in the future */ 00050 } 00051 00052 static FILE *sound_pipe = NULL; 00053 static ChildProcess *sound_process; 00054 /* init_sounds open the audio device, and reads any configuration files 00055 * that need to be. It returns 0 on success. On failure, the calling 00056 * function will likely disable sound support/requests from the server. 00057 */ 00058 00059 #ifndef WIN32 00060 int init_sounds(void) 00061 { 00062 char sound_path[MAX_BUF]; 00063 00064 /* Easy trick - global nosound is set in the arg processing - if set, 00065 * just return -1 - this way, the calling function only needs to check 00066 * the value of init_sounds, and not worry about checking nosound. 00067 */ 00068 if (!want_config[CONFIG_SOUND]) return -1; 00069 00070 if (sound_server[0] == '\0') { 00071 LOG(LOG_ERROR,"init_sounds:", "sound-server variable not set to anything"); 00072 return -1; 00073 } 00074 /* if an absolute path is given, we use it unadorned. Otherwise, we 00075 * use the path in the BINDIR. 00076 */ 00077 if (sound_server[0] == '/') 00078 strcpy(sound_path, sound_server); 00079 else 00080 sprintf(sound_path, "%s/%s", BINDIR, sound_server); 00081 00082 if (access(sound_path, X_OK)<0) { 00083 fprintf(stderr,"Unable to access %s sound server process\n", sound_path); 00084 return -1; 00085 } 00086 00087 sound_process=raiseChild(sound_path,CHILD_STDIN|CHILD_STDOUT|CHILD_STDERR); 00088 logChildPipe(sound_process, LOG_INFO, CHILD_STDOUT|CHILD_STDERR); 00089 00090 if (fcntl(sound_process->tube[0], F_SETFL, O_NONBLOCK)<0) { 00091 /* setting non blocking isn't 100% critical, but a good thing if 00092 * we can do it 00093 */ 00094 perror("init_sounds: Warning - unable to set non blocking on sound pipe\n"); 00095 } 00096 sound_pipe=fdopen(sound_process->tube[0],"w"); 00097 signal(SIGPIPE, signal_pipe);/*perhaps throwing this out :\*/ 00098 return 0; 00099 } 00100 #endif 00101 00102 00103 /* Plays sound 'soundnum'. soundtype is 0 for normal sounds, 1 for 00104 * spell_sounds. This might get extended in the future. x,y are offset 00105 * (assumed from player) to play sound. This information is used to 00106 * determine value and left vs right speaker balance. 00107 * 00108 * This procedure seems to be very slow - much slower than I would 00109 * expect. Might need to run this is a thread or fork off. 00110 */ 00111 00112 static void play_sound(int soundnum, int soundtype, int x, int y) 00113 { 00114 #ifndef WIN32 00115 00116 if (!use_config[CONFIG_SOUND]) return; 00117 if ( (fprintf(sound_pipe,"%4x %4x %4x %4x\n",soundnum,soundtype,x,y)<=0) || 00118 (fflush(sound_pipe)!=0) ){ 00119 LOG(LOG_ERROR,"gtk::play_sound","couldn't write to sound pipe: %d",errno); 00120 use_config[CONFIG_SOUND]=0; 00121 fclose(sound_pipe); 00122 sound_process=NULL; 00123 return; 00124 } 00125 #endif 00126 } 00127 00128 00129 #ifndef WIN32 00130 void SoundCmd(unsigned char *data, int len) 00131 { 00132 int x, y, num, type; 00133 00134 if (len!=5) { 00135 LOG(LOG_WARNING,"gtk::SoundCmd","Got invalid length on sound command: %d", len); 00136 return; 00137 } 00138 x = data[0]; 00139 y = data[1]; 00140 num = GetShort_String(data+2); 00141 type = data[4]; 00142 00143 #if 0 00144 fprintf(stderr,"Playing sound %d (type %d), offset %d, %x\n", 00145 num, type, x ,y); 00146 #endif 00147 play_sound(num, type, x, y); 00148 } 00149 #endif 00150 00151 void Sound2Cmd(unsigned char *data, int len) 00152 { 00153 uint8 x, y, dir, volume, type, len_action; 00154 char* action = NULL; 00155 uint8 len_name; 00156 char* name = NULL; 00157 /* sound2 <x><y><dir><volume><type><len of action>action<len of name>name */ 00158 /* b b b b b b str b str*/ 00159 if (len<8) { 00160 LOG(LOG_WARNING,"gtk::Sound2Cmd","Got too short length on sound2 command: %d\n", len); 00161 return; 00162 } 00163 x = data[0]; 00164 y = data[1]; 00165 dir = data[2]; 00166 volume = data[3]; 00167 type = data[4]; 00168 len_action = data[5]; 00169 /* Prevent invald index. */ 00170 if (len_action >= (len-8)) { 00171 LOG(LOG_WARNING, "gtk::Sound2Cmd", "Bad length of \"len of action\" in sound2 command: %d\n", len); 00172 return; 00173 } 00174 if (len_action != 0) { 00175 action = (char*)data+6; 00176 data[6+len_action]='\0'; 00177 } 00178 /* Lets make it readable, compiler will optimize the addition order anyway*/ 00179 len_name = data[6+len_action+1]; 00180 if (len_name >= (len-8-len_action)) { 00181 LOG(LOG_WARNING, "gtk::Sound2Cmd", "Bad length of \"len of name\" in sound2 command: %d\n", len); 00182 return; 00183 } 00184 if (len_name != 0) { 00185 name = (char*)data+6+len_action+1; 00186 data[6+len_action+1+len_name]='\0'; 00187 } 00188 LOG(LOG_WARNING, "gtk::Sound2Cmd", "Playing sound2 x=%hhd y=%hhd dir=%hhd volume=%hhd type=%hhd\n", 00189 x, y, dir, volume, type); 00190 LOG(LOG_WARNING, "gtk::Sound2Cmd", " len_action=%hhd action=%s\n", len_action, action); 00191 LOG(LOG_WARNING, "gtk::Sound2Cmd", " len_name=%hhd name=%s\n", len_name, name); 00192 LOG(LOG_WARNING, "gtk::Sound2Cmd", "Please impement sound2!"); 00193 /* TODO: Play sound here. Can't implement/test as server never actually 00194 * sends this yet it seems. As this code is mostly duplicated between the 00195 * different clients, make sure to update the other ones too. 00196 */ 00197 } 00198 00199 void MusicCmd(const char *data, int len) { 00200 if (!strncmp(data, "NONE", len)) { 00201 /* TODO stop music */ 00202 } else { 00203 LOG(LOG_WARNING, "gtk::MusicCmd", "music command: %s (Implement me!)\n", data); 00204 /* TODO: Play music. Can't impmement/test as server doesn't send this 00205 * version of the command yet it seems. 00206 */ 00207 } 00208 }