Crossfire Client, Branch
R11627
|
00001 const char * const rcsid_gtk2_sound_c = 00002 "$Id: sound.c 9215 2008-06-02 18:31:04Z anmaster $"; 00003 00004 /* 00005 CrossFire, A Multiplayer game for X-windows 00006 00007 Copyright (C) 2005 Mark Wedel & Crossfire Development Team 00008 00009 This program is free software; you can redistribute it and/or modify 00010 it under the terms of the GNU General Public License as published by 00011 the Free Software Foundation; either version 2 of the License, or 00012 (at your option) any later version. 00013 00014 This program is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 GNU General Public License for more details. 00018 00019 You should have received a copy of the GNU General Public License 00020 along with this program; if not, write to the Free Software 00021 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00022 00023 The author can be reached via e-mail to crossfire@metalforge.org 00024 */ 00025 00033 #include <config.h> 00034 #include <stdio.h> 00035 #include <stdlib.h> 00036 #include <ctype.h> 00037 #include <errno.h> 00038 #include <client-types.h> 00039 #include "client.h" 00040 00041 FILE *sound_pipe=NULL; 00042 ChildProcess* sound_process; 00043 00051 int init_sounds(void) 00052 { 00053 #ifndef WIN32 00054 char sound_path[MAX_BUF]; 00055 00056 /* 00057 * Easy trick - global nosound is set in the arg processing - if set, just 00058 * return -1 - this way, the calling function only needs to check the value 00059 * of init_sounds, and not worry about checking nosound. 00060 */ 00061 if (!want_config[CONFIG_SOUND]) return -1; 00062 00063 if (sound_server[0] == '\0') { 00064 LOG(LOG_ERROR,"init_sounds:", "sound-server variable not set to anything"); 00065 return -1; 00066 } 00067 /* 00068 * If an absolute path is given, we use it unadorned. Otherwise, we use 00069 * the path in the BINDIR. 00070 */ 00071 if (sound_server[0] == '/') 00072 strcpy(sound_path, sound_server); 00073 else 00074 snprintf(sound_path, sizeof(sound_path),"%s/%s", BINDIR, sound_server); 00075 00076 if (access(sound_path, X_OK)<0) { 00077 fprintf(stderr,"Unable to access %s sound server process\n", sound_path); 00078 return -1; 00079 } 00080 00081 sound_process=raiseChild(sound_path,CHILD_STDIN|CHILD_STDOUT|CHILD_STDERR); 00082 logChildPipe(sound_process, LOG_INFO, CHILD_STDOUT|CHILD_STDERR); 00083 00084 if (fcntl(sound_process->tube[0], F_SETFL, O_NONBLOCK)<0) { 00085 /* 00086 * Setting non-blocking isn't 100% critical, but a good thing if 00087 * possible. 00088 */ 00089 perror("init_sounds: Warning - unable to set non blocking on sound pipe\n"); 00090 } 00091 sound_pipe=fdopen(sound_process->tube[0],"w"); 00092 return 0; 00093 #else 00094 return -1; 00095 #endif 00096 } 00097 00114 static void play_sound(int soundnum, int soundtype, int x, int y) 00115 { 00116 #ifndef WIN32 00117 00118 if (!use_config[CONFIG_SOUND]) return; 00119 if ( (fprintf(sound_pipe,"%4x %4x %4x %4x\n",soundnum,soundtype,x,y)<=0) || 00120 (fflush(sound_pipe)!=0) ){ 00121 LOG(LOG_ERROR,"gtk::play_sound","couldn't write to sound pipe: %d",errno); 00122 use_config[CONFIG_SOUND]=0; 00123 fclose(sound_pipe); 00124 sound_process=NULL; 00125 return; 00126 } 00127 #endif 00128 } 00129 00136 void SoundCmd(unsigned char *data, int len) 00137 { 00138 #ifndef WIN32 00139 int x, y, num, type; 00140 00141 if (len!=5) { 00142 LOG(LOG_WARNING,"gtk::SoundCmd","Got invalid length on sound command: %d", len); 00143 return; 00144 } 00145 x = data[0]; 00146 y = data[1]; 00147 num = GetShort_String(data+2); 00148 type = data[4]; 00149 00150 #if 0 00151 fprintf(stderr,"Playing sound %d (type %d), offset %d, %x\n", 00152 num, type, x ,y); 00153 #endif 00154 play_sound(num, type, x, y); 00155 #endif 00156 } 00157 00158 void Sound2Cmd(unsigned char *data, int len) 00159 { 00160 #ifndef WIN32 00161 uint8 x, y, dir, volume, type, len_action; 00162 char* action = NULL; 00163 uint8 len_name; 00164 char* name = NULL; 00165 /* sound2 <x><y><dir><volume><type><len of action>action<len of name>name */ 00166 /* b b b b b b str b str*/ 00167 if (len<8) { 00168 LOG(LOG_WARNING, "gtk::Sound2Cmd", "Got too short length on sound2 command: %d\n", len); 00169 return; 00170 } 00171 x = data[0]; 00172 y = data[1]; 00173 dir = data[2]; 00174 volume = data[3]; 00175 type = data[4]; 00176 len_action = data[5]; 00177 /* Prevent invald index. */ 00178 if (len_action >= (len-8)) { 00179 LOG(LOG_WARNING, "gtk::Sound2Cmd", "Bad length of \"len of action\" in sound2 command: %d\n", len); 00180 return; 00181 } 00182 if (len_action != 0) { 00183 action = (char*)data+6; 00184 data[6+len_action]='\0'; 00185 } 00186 /* Lets make it readable, compiler will optimize the addition order anyway*/ 00187 len_name = data[6+len_action+1]; 00188 if (len_name >= (len-8-len_action)) { 00189 LOG(LOG_WARNING, "gtk::Sound2Cmd", "Bad length of \"len of name\" in sound2 command: %d\n", len); 00190 return; 00191 } 00192 if (len_name != 0) { 00193 name = (char*)data+6+len_action+1; 00194 data[6+len_action+1+len_name]='\0'; 00195 } 00196 LOG(LOG_WARNING, "gtk::Sound2Cmd", "Playing sound2 x=%hhd y=%hhd dir=%hhd volume=%hhd type=%hhd\n", 00197 x, y, dir, volume, type); 00198 LOG(LOG_WARNING, "gtk::Sound2Cmd", " len_action=%hhd action=%s\n", len_action, action); 00199 LOG(LOG_WARNING, "gtk::Sound2Cmd", " len_name=%hhd name=%s\n", len_name, name); 00200 LOG(LOG_WARNING, "gtk::Sound2Cmd", "Please impement sound2!"); 00201 /* TODO: Play sound here. Can't implement/test as server never actually 00202 * sends this yet it seems. As this code is mostly duplicated between the 00203 * different clients, make sure to update the other ones too. 00204 */ 00205 #endif 00206 } 00207 00208 void MusicCmd(const char *data, int len) { 00209 #ifndef WIN32 00210 if (!strncmp(data, "NONE", len)) { 00211 /* TODO stop music */ 00212 } else { 00213 LOG(LOG_WARNING, "gtk::MusicCmd", "music command: %s (Implement me!)\n", data); 00214 /* TODO: Play music. Can't impmement/test as server doesn't send this 00215 * version of the command yet it seems. 00216 */ 00217 } 00218 #endif 00219 }