<URL: http://bugs.freeciv.org/Ticket/Display.html?id=40732 >

This transaction appears to have no content
Hi,

This patch is inspired from an older patch 9490 and add backgound music
in the game. The global idea is: 

1) To have a music style for each age (ie Ancient, Industrial, Modern,
PostModern). Note that Ancient is a regroupement of European, Classical,
Tropical, Asian, Babylonian and Celtic city style. 

2) To adapt the music style if the nation is in peace or war. So there
is a total of 8 different style. 

3) To have a list of songs played randomly for each style. 

4) The implementation can be done like that : 
- Each turn we look if the syle has changed. 
- If the style has changed, a new song of the new style is played 
- The new song is choosen by the style tag and a random number between 0
and 9 (ex music_peace_Industrial_0, music_peace_Industrial_1 ...). If
there is a corresponding tag in soundspec we have found the file. If
there is no tag we look for an other random number. If we don't find
anything after a MAX number of attempt we leave. 
- If the style has not changed during turn, we look if the precedent
track is still playing. If not we choose a new song. 


Here is an example of my stdsounds.soundspec with ogg taken from contrib
directory
music_start = "stdsounds/CullamBruce-Lockhart--Dawning_Fanfare.ogg" 
music_peace_Ancient_0 = "stdsounds/AndrewBeck-Ancient.ogg" 
music_peace_Ancient_1 = "stdsounds/AndrewBeck-Strings.ogg" 
music_peace_Ancient_2 = "stdsounds/AndrewBeck-WarTheme.ogg" 
music_war_Ancient_0 =
"stdsounds/Flash_Gordon_-_A_Space_Odyssey_-_The_City_Escape.ogg" 
music_peace_Industrial_0 =
"stdsounds/RadekSedivy-FreeCiv-Industrial-Demo2.ogg" 
music_war_Industrial_0 =
"stdsounds/Trap_-_A_Space_Odyssey_-_Battle_For_The_Planet_Part_1.ogg" 
music_peace_Modern_0 = "stdsounds/RadekSedivy-FreeCiv-Modern-Demo1.ogg" 
music_peace_Modern_1 =
"stdsounds/RadekSedivy-FreeCiv-Modern2-Demo1.ogg" 
music_peace_Modern_2 =
"stdsounds/RadekSedivy-FreeCiv-Orchestral-Demo.ogg" 
music_war_Modern_0 =
"stdsounds/Trap_-_A_Space_Odyssey_-_Battle_For_Planet_Part_2.ogg" 
music_peace_PostModern_0 =
"stdsounds/RadekSedivy-FreeCiv-PostModern3-Demo1.ogg" 
music_war_PostModern_0 =
"stdsounds/War_-_A_Space_Odyssey_-_First_Steps_Into_Cosmos.ogg" 


Hi,

This patch is inspired from an older patch 9490 and add backgound music in the game. The global idea is:

1) To have a music style for each age (ie Ancient, Industrial, Modern, PostModern). Note that Ancient is a regroupement of European, Classical, Tropical, Asian, Babylonian and Celtic city style.

2) To adapt the music style if the nation is in peace or war. So there is a total of 8 different style.

3) To have a list of songs played randomly for each style.

4) The implementation can be done like that :
- Each turn we look if the syle has changed.
- If the style has changed, a new song of the new style is played
- The new song is choosen by the style tag and a random number between 0 and 9 (ex music_peace_Industrial_0, music_peace_Industrial_1 ...). If there is a corresponding tag in soundspec we have found the file. If there is no tag we look for an other random number. If we don't find anything after a MAX number of attempt we leave.
- If the style has not changed during turn, we look if the precedent track is still playing. If not we choose a new song.


Here is an example of my stdsounds.soundspec with ogg taken from contrib directory
music_start = "stdsounds/CullamBruce-Lockhart--Dawning_Fanfare.ogg"
music_peace_Ancient_0 = "stdsounds/AndrewBeck-Ancient.ogg"
music_peace_Ancient_1 = "stdsounds/AndrewBeck-Strings.ogg"
music_peace_Ancient_2 = "stdsounds/AndrewBeck-WarTheme.ogg"
music_war_Ancient_0 = "stdsounds/Flash_Gordon_-_A_Space_Odyssey_-_The_City_Escape.ogg"
music_peace_Industrial_0 = "stdsounds/RadekSedivy-FreeCiv-Industrial-Demo2.ogg"
music_war_Industrial_0 = "stdsounds/Trap_-_A_Space_Odyssey_-_Battle_For_The_Planet_Part_1.ogg"
music_peace_Modern_0 = "stdsounds/RadekSedivy-FreeCiv-Modern-Demo1.ogg"
music_peace_Modern_1 = "stdsounds/RadekSedivy-FreeCiv-Modern2-Demo1.ogg"
music_peace_Modern_2 = "stdsounds/RadekSedivy-FreeCiv-Orchestral-Demo.ogg"
music_war_Modern_0 = "stdsounds/Trap_-_A_Space_Odyssey_-_Battle_For_Planet_Part_2.ogg"
music_peace_PostModern_0 = "stdsounds/RadekSedivy-FreeCiv-PostModern3-Demo1.ogg"
music_war_PostModern_0 = "stdsounds/War_-_A_Space_Odyssey_-_First_Steps_Into_Cosmos.ogg"


Index: client/packhand.c
===================================================================
--- client/packhand.c	(révision 15505)
+++ client/packhand.c	(copie de travail)
@@ -75,6 +75,8 @@
 
 #include "packhand.h"
 
+#define BUFFER_SIZE             32
+
 static void city_packet_common(struct city *pcity, struct tile *pcenter,
                                struct player *powner, bool is_new,
                                bool popup, bool investigate);
@@ -87,7 +89,6 @@
 /* The dumbest of cities, placeholders for unknown and unseen cities. */
 static struct city_list *invisible_cities = NULL;
 
-
 /****************************************************************************
   Called below, and by client/civclient.c client_game_free()
 ****************************************************************************/
@@ -1014,6 +1015,45 @@
 }
 
 /**************************************************************************
+  Update the music style to play.  It will start a new music in the list tag 
+  if the style has changed or the last one is terminated
+**************************************************************************/
+void update_music_style()
+{
+  char war[BUFFER_SIZE];
+  char buf[BUFFER_SIZE];
+  int    their_unit = 0;
+
+  if (NULL != client.conn.playing) {
+    my_snprintf(war, sizeof(war), "music_peace");
+
+    players_iterate(pother) {
+      if ( ( pother->is_alive)
+            && (pplayer_get_diplstate(client.conn.playing, pother)->type 
+                   == DS_WAR) ) {
+
+        /* We are at war, check if they have units in our territory    */
+        /* Checking our unit in their territory NOT WORKING !!! */
+        their_unit=player_in_territory(client.conn.playing, pother);                      
+        if (their_unit >0) {
+          my_snprintf(war, sizeof(war), "music_war");
+        }
+      }
+    } players_iterate_end;
+
+    /* Find the style of music to play */
+    my_snprintf(buf, sizeof(buf), "%s_Ancient",war);
+    if (client.conn.playing->city_style > 5) {
+	  my_snprintf(buf, sizeof(buf), "%s_%s", 
+                         war, city_style_rule_name(client.conn.playing->city_style));
+    }
+
+    /* Play one of the music in the list tag if necessary */
+    audio_play_list_music(buf, NULL); 
+  }
+}
+
+/**************************************************************************
   Called by the network code when an start-phase packet is received.  This
   may be the start of our phase or someone else's phase.
 **************************************************************************/
@@ -1058,6 +1098,9 @@
     } unit_list_iterate_end;
 
     update_map_canvas_visible();
+
+     /* Find the new style of music to play */
+     update_music_style();                   
   }
 
   update_info_label();
@@ -1073,7 +1116,7 @@
 
   /* probably duplicate insurance */
   update_client_state(C_S_RUNNING);
-
+   
   /* Possibly replace wait cursor with something else */
   set_server_busy(FALSE);
 }
@@ -1147,6 +1190,7 @@
       || event != E_BROADCAST_REPORT) {
     popup_notify_dialog(caption, headline, lines);
     play_sound_for_event(event);
+
   }
 }
 
Index: client/packhand.h
===================================================================
--- client/packhand.h	(révision 15505)
+++ client/packhand.h	(copie de travail)
@@ -33,5 +33,6 @@
 void target_government_init(void);
 void set_government_choice(struct government *government);
 void start_revolution(void);
+void update_music_style(void);
 
 #endif /* FC__PACKHAND_H */
Index: client/audio_none.c
===================================================================
--- client/audio_none.c	(révision 15505)
+++ client/audio_none.c	(copie de travail)
@@ -49,7 +49,7 @@
   Play sound sample
 **************************************************************************/
 static bool my_play(const char *const tag, const char *const fullpath,
-		    bool repeat)
+		    bool repeat, bool ismusic)
 {
   if (strcmp(tag, "e_turn_bell") == 0) {
     sound_bell();
Index: client/audio.c
===================================================================
--- client/audio.c	(révision 15505)
+++ client/audio.c	(copie de travail)
@@ -24,6 +24,7 @@
 #include "fcintl.h"
 #include "log.h"
 #include "mem.h"
+#include "rand.h" /* myrand() */
 #include "registry.h"
 #include "shared.h"
 #include "support.h"
@@ -37,7 +38,12 @@
 
 #define MAX_NUM_PLUGINS		2
 #define SNDSPEC_SUFFIX		".soundspec"
+#define BUFFER_SIZE             32
+#define MAX_MUSIC_TRACK   10
 
+/* The current music tag */
+static char cur_music_tag[BUFFER_SIZE] ="\0";
+
 /* keep it open throughout */
 static struct section_file tagstruct, *tagfile = &tagstruct;
 
@@ -260,7 +266,7 @@
 /**************************************************************************
   INTERNAL. Returns TRUE for success.
 **************************************************************************/
-static bool audio_play_tag(const char *tag, bool repeat)
+static bool audio_play_tag(const char *tag, bool repeat, bool ismusic)
 {
   char *soundfile, *fullpath = NULL;
 
@@ -281,7 +287,7 @@
     }
   }
 
-  return plugins[selected_plugin].play(tag, fullpath, repeat);
+  return plugins[selected_plugin].play(tag, fullpath, repeat, ismusic);
 }
 
 /**************************************************************************
@@ -296,7 +302,7 @@
   freelog(LOG_DEBUG, "audio_play_sound('%s', '%s')", tag, pretty_alt_tag);
 
   /* try playing primary tag first, if not go to alternative tag */
-  if (!audio_play_tag(tag, FALSE) && !audio_play_tag(alt_tag, FALSE)) {
+  if (!audio_play_tag(tag, FALSE, FALSE) && !audio_play_tag(alt_tag, FALSE, FALSE)) {
     freelog(LOG_VERBOSE, "Neither of tags %s or %s found", tag,
 	    pretty_alt_tag);
   }
@@ -314,13 +320,81 @@
   freelog(LOG_DEBUG, "audio_play_music('%s', '%s')", tag, pretty_alt_tag);
 
   /* try playing primary tag first, if not go to alternative tag */
-  if (!audio_play_tag(tag, TRUE) && !audio_play_tag(alt_tag, TRUE)) {
+  if (!audio_play_tag(tag, TRUE, TRUE) && !audio_play_tag(alt_tag, TRUE, TRUE)) {
     freelog(LOG_VERBOSE, "Neither of tags %s or %s found", tag,
 	    pretty_alt_tag);
   }
 }
 
 /**************************************************************************
+  Check if music is playing
+**************************************************************************/
+bool audio_is_playing_music()
+{
+  return plugins[selected_plugin].is_playing_music();
+}
+
+/**************************************************************************
+  Find a random music number as suggested by sound tags.
+  If the tag has changed, a new music will be played
+  Otherwise the curent song will be terminated first
+**************************************************************************/
+void audio_play_list_music(const char *const tag, char *const alt_tag)
+{
+  char *pretty_alt_tag = alt_tag ? alt_tag : "(null)";
+  int tag_number = -1;
+  int i = 0, max_try = MAX_MUSIC_TRACK;
+  char buf[BUFFER_SIZE];
+  char alt_buf[BUFFER_SIZE];
+  bool tag_exist = FALSE;
+    
+  assert(tag != NULL);
+
+  freelog(LOG_DEBUG, "audio_play_list_music('%s', '%s')", tag, pretty_alt_tag);
+
+  /* tag has change, force to new tag */
+  if ( strcmp(cur_music_tag, tag) != 0 ) {
+    strcpy (cur_music_tag, tag);
+  }
+  else {    
+    /* Same tag, check if there is a music track playing */
+    if ( audio_is_playing_music() )  {
+      freelog(LOG_VERBOSE, "Already playing a track");
+      return;
+    }
+  }
+
+  /* Tag has changed or music track is terminated, play an other track */
+  /* If we don't found any valid track in max_try attenpt, we leave */
+  while ( (!tag_exist) 
+               && (i <= max_try)) {
+    if (i == max_try) {
+      /* Last attempt, myrand has not found a valid track yet */
+      /* we take the first track ie number 0 */
+      tag_number=0;
+    }
+    else {
+      /* Take a ramdom track */
+      tag_number=myrand(MAX_MUSIC_TRACK);
+    }
+    my_snprintf(buf, sizeof(buf), ("%s_%d"), tag, tag_number);
+    my_snprintf(alt_buf, sizeof(alt_buf), ("%s_%d"), alt_tag, tag_number);
+
+    /* Try playing primary tag first, if not go to alternative tag */
+    if (!audio_play_tag(buf, FALSE, TRUE) 
+         && !audio_play_tag(alt_buf, FALSE, TRUE)) {
+      tag_exist = FALSE;
+      freelog(LOG_VERBOSE, "Neither of tags %s or %s found", tag,
+                  pretty_alt_tag);
+    }
+    else {
+      tag_exist = TRUE;
+    }          
+    i++;
+  }     
+}
+
+/**************************************************************************
   Stop looping sound. Music should die down in a few seconds.
 **************************************************************************/
 void audio_stop()
Index: client/audio_sdl.c
===================================================================
--- client/audio_sdl.c	(révision 15505)
+++ client/audio_sdl.c	(copie de travail)
@@ -67,7 +67,7 @@
   Play sound
 **************************************************************************/
 static bool my_play(const char *const tag, const char *const fullpath,
-		    bool repeat)
+		    bool repeat, bool ismusic)
 {
   int i, j;
   Mix_Chunk *wave = NULL;
@@ -76,7 +76,7 @@
     return FALSE;
   }
 
-  if (repeat) {
+  if (ismusic) {
     /* unload previous */
     Mix_HaltMusic();
     Mix_FreeMusic(mus);
@@ -87,7 +87,12 @@
       freelog(LOG_ERROR, "Can't open file \"%s\"", fullpath);
     }
 
-    Mix_PlayMusic(mus, -1);	/* -1 means loop forever */
+    if (repeat) {
+      Mix_PlayMusic(mus, -1);	/* -1 means loop forever */
+    }
+    else {
+      Mix_PlayMusic(mus, 1);
+    }
     freelog(LOG_VERBOSE, "Playing file \"%s\" on music channel", fullpath);
     /* in case we did a my_stop() recently; add volume controls later */
     Mix_VolumeMusic(MIX_MAX_VOLUME);
@@ -134,6 +139,14 @@
 }
 
 /**************************************************************************
+ Is music playing
+**************************************************************************/
+static bool my_is_playing_music(void)
+{
+  return Mix_PlayingMusic();
+}
+
+/**************************************************************************
   Stop music
 **************************************************************************/
 static void my_stop(void)
@@ -253,6 +266,7 @@
   self.stop = my_stop;
   self.wait = my_wait;
   self.play = my_play;
+  self.is_playing_music = my_is_playing_music;
   self.set_volume = my_set_volume;
   self.get_volume = my_get_volume;
   audio_add_plugin(&self);
Index: client/audio.h
===================================================================
--- client/audio.h	(révision 15505)
+++ client/audio.h	(copie de travail)
@@ -27,7 +27,9 @@
   void (*wait) (void);
   double (*get_volume) (void);
   void (*set_volume) (double volume);
-  bool (*play) (const char *const tag, const char *const path, bool repeat);
+  bool (*play) (const char *const tag, const char *const path, 
+                        bool repeat, bool ismusic);
+  bool (*is_playing_music) (void);
 };
 
 const char **get_soundplugin_list(void);
@@ -42,6 +44,8 @@
 
 void audio_play_sound(const char *const tag, char *const alt_tag);
 void audio_play_music(const char *const tag, char *const alt_tag);
+bool audio_is_playing_music(void);
+void audio_play_list_music(const char *const tag, char *const alt_tag);
 
 double audio_get_volume(void);
 void audio_set_volume(double volume);
Index: client/client_main.c
===================================================================
--- client/client_main.c	(révision 15505)
+++ client/client_main.c	(copie de travail)
@@ -551,6 +551,11 @@
 	&& C_S_RUNNING == newstate) {
       audio_stop();		/* stop intro sound loop */
     }
+    /* If changing from running state to pre-game state */
+    if (C_S_PREPARING == newstate
+	&& C_S_RUNNING == civclient_state) {
+      audio_stop();		/* stop game sound loop */
+    }
       
     civclient_state = newstate;
 
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to