diff -u2Nr -X../diff-ignore ../freeciv/README.sound ./README.sound --- ../freeciv/README.sound Thu Jan 1 01:00:00 1970 +++ ./README.sound Sun Aug 6 20:20:09 2000 @@ -0,0 +1,54 @@ +---------------------------------------------------------------------- + SOUND SUPPORT +---------------------------------------------------------------------- + ( originally by Per I. Mathisen ) + +There is now sound support for buildings (when they are built, a sound +is played) and some unit operations (moving, failed move, selecting, +attack, nuke). Consideration was given to whether it should be possible +to assign each unit a separate sound for selection and attack, but this +was thought unlikely to work well as the asyncronous movement in +Freeciv (lots of movements happening at the same time, sometimes +outside of view) creates a lot of 'issues'. + +The server sends the client a list of primary and secondary sound tags +for each of the above described operations. The 'primary' tags are +those preferred by the current modpack. The client may not have these +sounds. The 'secondary' tags should refer to standard sounds that all +installations of freeciv should have (if they have sound support). + +Tags are used to give an easy way to change sounds. A specfile is used +to indicate which tags refer to which sound files. A change of spec +file, given as an option at startup, will change sounds. For example, + + civclient --sound civ2sounds + +will use your (legally obtained) sound files from Civ2 instead of +those included with Freeciv. + +---------------------------------------------------------------------- + +For sound creators: + +Please name sound files intelligibly. Include a README where you +credit each artist and present the licensing terms used (if any). + +---------------------------------------------------------------------- + +For modpack makers: + +Please give secondary tags that refer to standard tags so that those +who have not downloaded the latest & greatest sound pack can still +enjoy the game. + +---------------------------------------------------------------------- + +Frequently Asked Questions about sound + +Q: Help, I get "/dev/dsp: Permission denied" ! + +A: Most likely, your dsp device only allows root to write to it. To +change this, find the real dsp device (/dev/dsp is usually a symlink) +and type "chmod o=rw /dev/dsp0", where /dev/dsp0 is your real dsp +device. You must do this as root, of course. + diff -u2Nr -X../diff-ignore ../freeciv/TODO ./TODO --- ../freeciv/TODO Fri Aug 4 20:14:12 2000 +++ ./TODO Sun Aug 6 14:10:50 2000 @@ -11,5 +11,4 @@ ===== -- Sound support. - Server-side player scripting. - Diplomacy: diff -u2Nr -X../diff-ignore ../freeciv/acconfig.h ./acconfig.h --- ../freeciv/acconfig.h Fri Aug 4 20:14:12 2000 +++ ./acconfig.h Sun Aug 6 14:57:47 2000 @@ -52,4 +52,6 @@ #undef PATH_SEPARATOR #undef SOCKET_ZERO_ISNT_STDIN +#undef SOUND +#undef ESOUND #undef NONBLOCKING_SOCKETS #undef HAVE_FCNTL diff -u2Nr -X../diff-ignore ../freeciv/client/Makefile.am ./client/Makefile.am --- ../freeciv/client/Makefile.am Mon May 22 11:02:09 2000 +++ ./client/Makefile.am Mon May 22 11:03:00 2000 @@ -57,5 +57,7 @@ options.h \ tilespec.c \ - tilespec.h + tilespec.h \ + audio.c \ + audio.h civclient_DEPENDENCIES = @gui_sources@/libguiclient.a ../common/libcivcommon.a @INTLDEPS@ diff -u2Nr -X../diff-ignore ../freeciv/client/audio.c ./client/audio.c --- ../freeciv/client/audio.c Thu Jan 1 01:00:00 1970 +++ ./client/audio.c Tue Aug 8 00:16:15 2000 @@ -0,0 +1,168 @@ +/********************************************************************** + Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "mem.h" +#include "shared.h" +#include "support.h" +#include "astring.h" +#include "fcintl.h" +#include "registry.h" +#include "log.h" +#include "capability.h" +#include "game.h" +#include "hash.h" + +#include "esd.h" +#include "audio.h" + +static char *program_name = "civclient"; +int sample_id = -1; +int sock = -1; +char *host = NULL; + +/* keep it open throughout - this is a quick hack */ +struct section_file tagstruct, *tagfile = &tagstruct; + +/************************************************************************** +... +**************************************************************************/ +void audio_check_capabilities(struct section_file *file, const char *which, + const char *us_capstr, const char *filename) +{ + char *file_capstr = secfile_lookup_str(file, "%s.options", which); + + if (!has_capabilities(us_capstr, file_capstr)) { + freelog(LOG_FATAL, _("%s file appears incompatible:"), which); + freelog(LOG_FATAL, _("file: \"%s\""), filename); + freelog(LOG_FATAL, _("file options: %s"), file_capstr); + freelog(LOG_FATAL, _("supported options: %s"), us_capstr); + exit(1); + } + if (!has_capabilities(file_capstr, us_capstr)) { + freelog(LOG_FATAL, _("%s file claims required option(s)" + " which we don't support:"), which); + freelog(LOG_FATAL, _("file: \"%s\""), filename); + freelog(LOG_FATAL, _("file options: %s"), file_capstr); + freelog(LOG_FATAL, _("supported options: %s"), us_capstr); + exit(1); + } +} + +/************************************************************************** +... +**************************************************************************/ +void audio_init(char *load_filename) +{ +/* struct hash_table *hash; */ + char *filename; + + if(load_filename==NULL) { + freelog(LOG_VERBOSE, _("No audio ruleset. Not loading audio subsystem.")); + return; + } + filename = datafilename(load_filename); + if (filename==NULL) { + freelog(LOG_FATAL, _("Cannot find audio spec-file %s"), load_filename); + exit(1); + } + if(!section_file_load(tagfile, filename)) { + freelog(LOG_FATAL, _("Could not load audio spec-file: %s"), filename); + exit(1); + } + /* transform tag strings into filenames by reading sound spec-file */ + audio_check_capabilities(tagfile, "soundspec", "+soundspec2", filename); + + /* add hash later for greater efficiency? + hash = fc_malloc(sizeof(struct hash_table)); + hash = hash_new(hash_fval_string, hash_fcmp_string); */ + + sock = esd_open_sound( host ); + + freelog(LOG_VERBOSE, _("Audio subsystem loaded.")); +} + + +/************************************************************************** +... currently ignores alt tag +**************************************************************************/ +void audio_play(char *tag, char *alt_tag, int format) +{ + char *soundfile; + char *fullpath; + + if (!strcmp(tag,"-")==0) { + soundfile = secfile_lookup_str_default(tagfile, "-", "files.%s", tag); + if (!strcmp(soundfile,"-")==0) { + fullpath = datafilename(soundfile); + if (fullpath!=NULL) { + if (sample_id != -1) { esd_sample_free( sock, sample_id ); } + sample_id = esd_file_cache( sock, program_name, fullpath ); + if ( sample_id < 0 ) { + freelog(LOG_FATAL, "_(error while caching sample <%d>: confirm value != sample_id\n)", + sample_id ); + } + if (format == AU_NORMAL) { + esd_sample_play( sock, sample_id ); + } else if (format == AU_LOOP) { + esd_sample_loop( sock, sample_id ); + } + } else { + freelog(LOG_FATAL, _("Cannot find audio file %s"), soundfile); + exit(1); + } + } else { + freelog(LOG_NORMAL, _("No sound file for %s (found tag %s)"), tag, soundfile); + } + } else { + freelog(LOG_VERBOSE, _("This action has no sound tag")); + } +} + +/************************************************************************** +... +**************************************************************************/ +void audio_stop() +{ + /* stop all currently played sounds */ + if (sample_id != -1) { + esd_sample_stop( sock, sample_id ); + } +} + +/************************************************************************** +... +**************************************************************************/ +void audio_done() +{ + if (sample_id != -1) { esd_sample_free( sock, sample_id ); } + esd_audio_close(); + close( sock ); + + section_file_free(tagfile); +} + + diff -u2Nr -X../diff-ignore ../freeciv/client/audio.h ./client/audio.h --- ../freeciv/client/audio.h Thu Jan 1 01:00:00 1970 +++ ./client/audio.h Tue Aug 8 00:16:03 2000 @@ -0,0 +1,25 @@ +/********************************************************************** + Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. +***********************************************************************/ +#ifndef FC__SOUND_H +#define FC__SOUND_H + +#define AU_NORMAL 0 +#define AU_LOOP 1 + +void audio_init(char *filename);/* initialize sound system */ +void audio_play(char *tag, char *alt_tag, int format); /* play sound */ +void audio_stop(); /* stop all sounds */ +void audio_done(); /* relinquish control of audio device */ + +#endif /* FC__SOUND_H */ + diff -u2Nr -X../diff-ignore ../freeciv/client/civclient.c ./client/civclient.c --- ../freeciv/client/civclient.c Fri Aug 4 20:14:18 2000 +++ ./client/civclient.c Tue Aug 8 00:16:52 2000 @@ -61,4 +61,6 @@ #include "civclient.h" +#include "audio.h" + char metaserver[256]=""; char server_host[512]; @@ -88,4 +90,5 @@ char *logfile=NULL; char *option=NULL; + char sound_set_name[256] = "stdsound.spec"; init_nls(); @@ -111,5 +114,5 @@ fprintf(stderr, _(" -t, --tiles FILE\tUse data file FILE.tilespec for tiles\n")); #ifdef SOUND - fprintf(stderr, _(" -s, --sound FILE\tRead sound information from FILE\n")); + fprintf(stderr, _(" -a, --audio FILE\tRead audio tags from FILE\n")); #endif fprintf(stderr, _(" -m, --meta HOST\tConnect to the metaserver at HOST\n")); @@ -130,4 +133,6 @@ else if ((option = get_option("--metaserver",argv,&i,argc)) != NULL) mystrlcpy(metaserver, option, 256); + else if ((option = get_option("--audio",argv,&i,argc)) != NULL) + mystrlcpy(sound_set_name, option, 256); else if ((option = get_option("--port",argv,&i,argc)) != NULL) server_port=atoi(option); @@ -166,5 +171,9 @@ tilespec_read_toplevel(tile_set_name); /* get tile sizes etc */ + freelog(LOG_VERBOSE, "Initializing sound using %s...", sound_set_name); + audio_init(sound_set_name); + audio_play("startmenu", NULL, AU_LOOP); ui_main(argc, argv); + audio_done(); return 0; } @@ -432,8 +441,14 @@ select dialog.) */ + freelog(LOG_NORMAL, "Currently in state %d going to %d", client_state, newstate); if (client_state==CLIENT_PRE_GAME_STATE && (newstate==CLIENT_SELECT_RACE_STATE || newstate==CLIENT_GAME_RUNNING_STATE)) { translate_data_names(); +#ifdef SOUND + audio_stop(); + audio_play("startgame", NULL, AU_NORMAL); +#endif + } diff -u2Nr -X../diff-ignore ../freeciv/client/gui-gtk/gui_main.c ./client/gui-gtk/gui_main.c --- ../freeciv/client/gui-gtk/gui_main.c Fri Aug 4 20:14:28 2000 +++ ./client/gui-gtk/gui_main.c Tue Aug 8 00:25:34 2000 @@ -57,4 +57,5 @@ #include "resources.h" #include "tilespec.h" +#include "audio.h" #include "gui_main.h" @@ -808,5 +809,9 @@ void sound_bell(void) { +#ifdef SOUND + audio_play("turn_bell", NULL, AU_NORMAL); +#else gdk_beep(); +#endif } diff -u2Nr -X../diff-ignore ../freeciv/client/packhand.c ./client/packhand.c --- ../freeciv/client/packhand.c Fri Aug 4 20:14:20 2000 +++ ./client/packhand.c Tue Aug 8 00:22:14 2000 @@ -1373,4 +1373,6 @@ sz_strlcpy(b->name, p->name); + sz_strlcpy(b->soundtag, p->soundtag); + sz_strlcpy(b->soundtag_alt, p->soundtag_alt); b->tech_req = p->tech_req; b->bldg_req = p->bldg_req; diff -u2Nr -X../diff-ignore ../freeciv/common/city.h ./common/city.h --- ../freeciv/common/city.h Fri Aug 4 20:15:06 2000 +++ ./common/city.h Tue Aug 8 20:56:56 2000 @@ -177,4 +177,6 @@ struct impr_effect *effect; /* list; .type==EFT_LAST terminated */ int variant; /* FIXME: remove when gen-impr obsoletes */ + char soundtag[MAX_LEN_NAME]; + char soundtag_alt[MAX_LEN_NAME]; char *helptext; }; diff -u2Nr -X../diff-ignore ../freeciv/common/packets.c ./common/packets.c --- ../freeciv/common/packets.c Mon Aug 7 22:58:29 2000 +++ ./common/packets.c Tue Aug 8 00:20:51 2000 @@ -2864,4 +2864,6 @@ cptr=put_uint8(cptr, packet->variant); /* FIXME: remove when gen-impr obsoletes */ cptr=put_string(cptr, packet->name); + cptr=put_string(cptr, packet->soundtag); + cptr=put_string(cptr, packet->soundtag_alt); /* This must be last, so client can determine length: */ @@ -2917,4 +2919,6 @@ iget_uint8(&iter, &packet->variant); /* FIXME: remove when gen-impr obsoletes */ iget_string(&iter, packet->name, sizeof(packet->name)); + iget_string(&iter, packet->name, sizeof(packet->soundtag)); + iget_string(&iter, packet->name, sizeof(packet->soundtag_alt)); len = pack_iter_remaining(&iter); diff -u2Nr -X../diff-ignore ../freeciv/common/packets.h ./common/packets.h --- ../freeciv/common/packets.h Fri Aug 4 20:15:25 2000 +++ ./common/packets.h Tue Aug 8 20:55:55 2000 @@ -582,4 +582,6 @@ struct impr_effect *effect; int variant; /* FIXME: remove when gen-impr obsoletes */ + char soundtag[MAX_LEN_NAME]; + char soundtag_alt[MAX_LEN_NAME]; char *helptext; /* same as for packet_ruleset_unit, above */ }; diff -u2Nr -X../diff-ignore ../freeciv/configure.in ./configure.in --- ../freeciv/configure.in Mon Aug 7 22:58:03 2000 +++ ./configure.in Mon Aug 7 22:59:26 2000 @@ -90,4 +90,14 @@ AM_CONDITIONAL(CLIENT, test x$client != xno) +dnl no=no sound, esound=esound support +AC_ARG_ENABLE(sound, +[ --enable-sound[=no/esound] + enable sound support [default=no]], +[case "${enableval}" in + no) sound=no ;; + esound) sound="esound" ;; +esac], [sound=no]) +AM_CONDITIONAL(SOUND, test x$sound != xno) + AC_ARG_WITH(xaw, [ --with-xaw use the Xaw widget set for the xaw client], @@ -345,4 +355,17 @@ elif test "$client" = "stub"; then AC_MSG_ERROR(specified client 'stub' not configurable) + fi + fi + + dnl Add esound support to client + if test "$sound" = esound ; then + AC_PATH_PROG(ESOUND, esd-config, no) + if test "$ESOUND" != "no"; then + CLIENT_CFLAGS="$CLIENT_CFLAGS `esd-config --cflags`" + CLIENT_LIBS="$CLIENT_LIBS `esd-config --libs`" + AC_DEFINE(ESOUND) + AC_DEFINE(SOUND) + else + AC_MSG_ERROR(esound not found) fi fi diff -u2Nr -X../diff-ignore ../freeciv/data/Makefile.am ./data/Makefile.am --- ../freeciv/data/Makefile.am Fri Aug 4 20:15:32 2000 +++ ./data/Makefile.am Fri Aug 4 20:16:51 2000 @@ -10,5 +10,6 @@ helpdata.txt \ civ1.serv \ - civ2.serv + civ2.serv \ + civ2sounds.spec EXTRA_DIST = $(pkgdata_DATA) diff -u2Nr -X../diff-ignore ../freeciv/data/civ2sounds.spec ./data/civ2sounds.spec --- ../freeciv/data/civ2sounds.spec Thu Jan 1 01:00:00 1970 +++ ./data/civ2sounds.spec Tue Aug 8 21:19:01 2000 @@ -0,0 +1,55 @@ +[soundspec] +; Format and options of this spec file: +options = "+soundspec2" + +[info] +artists = " + This spec-file is meant to be used with + original Civilization 2 sounds. Copy your + legally obtained Civ 2 soundfiles from your + Civ 2 sound/ directory and into the Freeciv + data/civ2/ directory. Now run the client + with the --sounds civ2sounds option. +" + +; list of all standard sound tags can be found in stdsound.spec +; you can expect any standard freeciv installation to have sounds +; for these tags + +[files] +b_apollo = "civ2/cheers3.wav" +b_asmith = "civ2/stkmarkt.wav" +b_colossus = "civ2/fanfare1.wav" +b_copernicus = "civ2/fanfare8.wav" +b_cure = "civ2/cheers2.wav" +b_darwins = "civ2/fanfare2.wav" +b_eiffel = "civ2/drumc0.wav" +b_library = "civ2/newonder.wav" +b_wall = "civ2/cheers1.wav" +b_gardens = "civ2/fanfare3.wav" +b_hoover = "civ2/aqueduct.wav" +b_newton = "civ2/fanfare4.wav" +b_jbach = "civ2/cathedral.wav" +b_richard = "civ2/fanfare5.wav" +b_leonardo = "civ2/pompcirc.wav" +b_lighthouse = "civ2/boatsink.wav" +b_magellan = "civ2/fanfare6.wav" +b_manhattan = "civ2/nukexplo.wav" +b_marcopolo = "civ2/fanfare7.wav" +b_michelangelo ="civ2/cathedral.wav" +b_oracle = "civ2/drumal.wav" +b_pyramids = "civ2/drumbl.wav" +b_SETI = "civ2/drumc0.wav" +b_shakespeare = "civ2/fanfare8.wav" +b_statue = "civ2/newgovt.wav" +b_suntzu = "civ2/drumcl.wav" +b_UN = "civ2/newonder.wav" +b_suffrage = "civ2/cheers3.wav" +startmenu = "civ2/menuloop.wav" +startgame = "civ2/menuend.wav" +turn_bell = "civ2/endoturn.wav" +; "u_nuke", "civ2/??" +; "u_moveunit", "civ2/movpiece.wav" +; "u_wrongmove", "civ2/neg1.wav" +; "u_focusunit", "civ2/feedbkxx.wav" + diff -u2Nr -X../diff-ignore ../freeciv/data/default/buildings.ruleset ./data/default/buildings.ruleset --- ../freeciv/data/default/buildings.ruleset Fri Aug 4 20:16:09 2000 +++ ./data/default/buildings.ruleset Sun Aug 6 17:36:27 2000 @@ -195,4 +195,6 @@ ; affects no squares (unless aff_terr allows it to)) ; } (All effects in list(s) are cumulative.) +; sound = optional sound effect associated with building +; sound_alt = optional alternative sound effect ; helptext = optional help text string; should escape all raw ; newlines so that xgettext parsing works @@ -1266,4 +1268,5 @@ "Enable_Space", "World" } +sound = "b_apollo" helptext = _("\ Entire map becomes visible for the player who owns it. \ diff -u2Nr -X../diff-ignore ../freeciv/data/default/units.ruleset ./data/default/units.ruleset --- ../freeciv/data/default/units.ruleset Fri Aug 4 20:16:09 2000 +++ ./data/default/units.ruleset Fri Aug 4 20:17:23 2000 @@ -20,4 +20,12 @@ firepower_factor=1 ; convenient for Civ1 +[sound] +move ="u_moveunit" ; sound of a unit moving +fail ="u_wrongmove" ; sound of unit moving into something +focus ="u_focusunit" ; sound of unit getting focus +move_alt ="u_moveunit" ; alternate sounds +fail_alt ="u_wrongmove" +focus_alt="u_focusunit" + ; Below: The individual units, one per section. ; diff -u2Nr -X../diff-ignore ../freeciv/data/stdsound.spec ./data/stdsound.spec --- ../freeciv/data/stdsound.spec Thu Jan 1 01:00:00 1970 +++ ./data/stdsound.spec Sun Aug 6 16:52:42 2000 @@ -0,0 +1,49 @@ +[soundspec] +; Format and options of this spec file: +options = "+soundspec2" + +[info] +artists = " + To use, run the client with the "--sounds stdsound" option. + Various, mostly unknown artists contributed to this set. +" + +[files] +; if a sound event is missing, use "-" instead +sounds = { "tag", "file" + "b_apollo", "-" + "b_asmith", "-" + "b_colossus", "-" + "b_copernicus", "-" + "b_cure", "-" + "b_darwins", "-" + "b_eiffel", "-" + "b_library", "-" + "b_wall", "-" + "b_gardens", "-" + "b_hoover", "-" + "b_newton", "-" + "b_jbach", "-" + "b_richard", "-" + "b_leonardo", "-" + "b_lighthouse", "-" + "b_magellan", "-" + "b_manhattan", "-" + "b_marcopolo", "-" + "b_michelangelo","-" + "b_oracle", "-" + "b_pyramids", "-" + "b_SETI", "-" + "b_shakespeare","-" + "b_statue", "-" + "b_suntzu", "-" + "b_UN", "-" + "b_suffrage", "-" + "startmenu", "-" + "startgame", "-" +; "u_nuke", "sound/airnuke.wav" +; "u_moveunit", "-" +; "u_wrongmove", "sound/alarm1.wav" +; "u_focusunit", "-" +} + diff -u2Nr -X../diff-ignore ../freeciv/server/ruleset.c ./server/ruleset.c --- ../freeciv/server/ruleset.c Fri Aug 4 20:21:42 2000 +++ ./server/ruleset.c Tue Aug 8 21:04:42 2000 @@ -963,4 +963,7 @@ b->sabotage = secfile_lookup_int(file, "%s.sabotage", sec[i]); + sz_strlcpy(b->soundtag, secfile_lookup_str_default(file, "-", "%s.sound", sec[i])); + sz_strlcpy(b->soundtag_alt, secfile_lookup_str_default(file, "-", "%s.sound_alt", sec[i])); + for (count = 0; secfile_lookup_str_default(file, @@ -2124,4 +2127,6 @@ packet.id = b-improvement_types; sz_strlcpy(packet.name, b->name_orig); + sz_strlcpy(packet.soundtag, b->soundtag); + sz_strlcpy(packet.soundtag_alt, b->soundtag_alt); packet.tech_req = b->tech_req; packet.bldg_req = b->bldg_req;