Crossfire Client, Branch  R11627
sound.c
Go to the documentation of this file.
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 }