rnd-20020824-2-src
[rocksndiamonds.git] / src / init.c
index 70604f2a9392854cd4bda2dc4fc30ad16bcb6105..38aec9ae656aab1e178dc3bd8fb376a431eb44ca 100644 (file)
@@ -1,7 +1,7 @@
 /***********************************************************
 * Rocks'n'Diamonds -- McDuffin Strikes Back!               *
 *----------------------------------------------------------*
-* (c) 1995-2001 Artsoft Entertainment                      *
+* (c) 1995-2002 Artsoft Entertainment                      *
 *               Holger Schemel                             *
 *               Detmolder Strasse 189                      *
 *               33604 Bielefeld                            *
@@ -23,6 +23,8 @@
 #include "files.h"
 #include "network.h"
 #include "netserv.h"
+#include "cartoons.h"
+#include "config.h"
 
 static char *image_filename[NUM_PICTURES] =
 {
@@ -38,18 +40,29 @@ static char *image_filename[NUM_PICTURES] =
   "RocksFont3.pcx"
 }; 
 
+static void InitSetup(void);
 static void InitPlayerInfo(void);
 static void InitLevelInfo(void);
+static void InitArtworkInfo(void);
+static void InitLevelArtworkInfo(void);
 static void InitNetworkServer(void);
+static void InitMixer(void);
 static void InitSound(void);
 static void InitGfx(void);
-static void InitCustomGraphics(void);
 static void InitGfxBackground(void);
 static void InitGadgets(void);
 static void InitElementProperties(void);
+static void Execute_Debug_Command(char *);
 
 void OpenAll(void)
 {
+  if (options.debug_command)
+  {
+    Execute_Debug_Command(options.debug_command);
+
+    exit(0);
+  }
+
   if (options.serveronly)
   {
 #if defined(PLATFORM_UNIX)
@@ -61,15 +74,17 @@ void OpenAll(void)
   }
 
   InitProgramInfo(UNIX_USERDATA_DIRECTORY,
-                 PROGRAM_TITLE_STRING, WINDOW_TITLE_STRING,
+                 PROGRAM_TITLE_STRING, getWindowTitleString(),
                  ICON_TITLE_STRING, X11_ICON_FILENAME, X11_ICONMASK_FILENAME,
                  MSDOS_POINTER_FILENAME,
                  COOKIE_PREFIX, FILENAME_PREFIX, GAME_VERSION_ACTUAL);
 
+  InitSetup();
   InitPlayerInfo();
+  InitArtworkInfo();           /* needed before loading gfx, sound & music */
 
   InitCounter();
-  InitSound();
+  InitMixer();
   InitJoysticks();
   InitRND(NEW_RANDOMIZE);
 
@@ -83,16 +98,23 @@ void OpenAll(void)
   InitElementProperties();     /* initializes IS_CHAR() for el2gfx() */
 
   InitLevelInfo();
+  InitLevelArtworkInfo();
   InitGadgets();               /* needs to know number of level series */
-
-  InitCustomGraphics();
+  InitSound();                 /* needs to know current level directory */
 
   InitGfxBackground();
+  InitToons();
+
   DrawMainMenu();
 
   InitNetworkServer();
 }
 
+void InitSetup()
+{
+  LoadSetup();                                 /* global setup info */
+}
+
 void InitPlayerInfo()
 {
   int i;
@@ -104,8 +126,6 @@ void InitPlayerInfo()
     stored_player[i].connected = FALSE;
 
   local_player->connected = TRUE;
-
-  LoadSetup();                                 /* global setup info */
 }
 
 void InitLevelInfo()
@@ -115,6 +135,16 @@ void InitLevelInfo()
   LoadLevelSetup_SeriesInfo();                 /* last played level info */
 }
 
+void InitArtworkInfo()
+{
+  LoadArtworkInfo();
+}
+
+void InitLevelArtworkInfo()
+{
+  LoadLevelArtworkInfo();
+}
+
 void InitNetworkServer()
 {
 #if defined(PLATFORM_UNIX)
@@ -138,38 +168,33 @@ void InitNetworkServer()
 #endif
 }
 
-void InitSound()
+static void InitMixer()
 {
-  int i;
-
   OpenAudio();
+  InitSoundList(sound_effects, NUM_SOUND_EFFECTS);
 
-  for(i=0; i<NUM_SOUNDS; i++)
-  {
-    if (!LoadSound(sound_name[i]))
-    {
-      audio.sound_available = FALSE;
-      audio.loops_available = FALSE;
-      audio.sound_enabled = FALSE;
-
-      return;
-    }
-  }
+  StartMixer();
+}
 
-  num_bg_loops = LoadMusic();
+static void InitSound()
+{
+  /* load custom sounds and music */
+  InitReloadSounds(artwork.snd_current->identifier);
+  InitReloadMusic(artwork.mus_current->identifier);
 
-  StartSoundserver();
+  /* initialize sound effect lookup table for element actions */
+  InitGameSound();
 }
 
-void InitTileClipmasks()
+static void InitTileClipmasks()
 {
 #if defined(TARGET_X11)
-  GC copy_clipmask_gc;
   XGCValues clip_gc_values;
   unsigned long clip_gc_valuemask;
-#endif
 
 #if defined(TARGET_X11_NATIVE)
+  GC copy_clipmask_gc;
+
   static struct
   {
     int start;
@@ -221,7 +246,8 @@ void InitTileClipmasks()
     { GFX2_SHIELD_ACTIVE, 3 },
     { -1, 0 }
   };
-#endif
+#endif /* TARGET_X11_NATIVE */
+#endif /* TARGET_X11 */
 
   int i;
 
@@ -235,13 +261,6 @@ void InitTileClipmasks()
      To prevent this, create small (tile-sized) mask Pixmaps which will then
      be set much faster with XSetClipOrigin() and speed things up a lot. */
 
-  /* create graphic context structures needed for clipping */
-  clip_gc_values.graphics_exposures = False;
-  clip_gc_valuemask = GCGraphicsExposures;
-  copy_clipmask_gc =
-    XCreateGC(display, pix[PIX_BACK]->clip_mask,
-             clip_gc_valuemask, &clip_gc_values);
-
   clip_gc_values.graphics_exposures = False;
   clip_gc_valuemask = GCGraphicsExposures;
   tile_clip_gc =
@@ -255,11 +274,19 @@ void InitTileClipmasks()
       clip_gc_values.clip_mask = pix[i]->clip_mask;
       clip_gc_valuemask = GCGraphicsExposures | GCClipMask;
       pix[i]->stored_clip_gc = XCreateGC(display, window->drawable,
-                                        clip_gc_valuemask,&clip_gc_values);
+                                        clip_gc_valuemask, &clip_gc_values);
     }
   }
 
 #if defined(TARGET_X11_NATIVE)
+
+  /* create graphic context structures needed for clipping */
+  clip_gc_values.graphics_exposures = False;
+  clip_gc_valuemask = GCGraphicsExposures;
+  copy_clipmask_gc =
+    XCreateGC(display, pix[PIX_BACK]->clip_mask,
+             clip_gc_valuemask, &clip_gc_values);
+
   /* create only those clipping Pixmaps we really need */
   for(i=0; tile_needs_clipping[i].start>=0; i++)
   {
@@ -283,13 +310,44 @@ void InitTileClipmasks()
                src_x, src_y, TILEX, TILEY, 0, 0);
     }
   }
+
+  XFreeGC(display, copy_clipmask_gc);
+
 #endif /* TARGET_X11_NATIVE */
 #endif /* TARGET_X11 */
 }
 
+void FreeTileClipmasks()
+{
+#if defined(TARGET_X11)
+  int i;
+
+  for(i=0; i<NUM_TILES; i++)
+  {
+    if (tile_clipmask[i] != None)
+    {
+      XFreePixmap(display, tile_clipmask[i]);
+      tile_clipmask[i] = None;
+    }
+  }
+
+  if (tile_clip_gc)
+    XFreeGC(display, tile_clip_gc);
+  tile_clip_gc = None;
+
+  for(i=0; i<NUM_BITMAPS; i++)
+  {
+    if (pix[i] != NULL && pix[i]->stored_clip_gc)
+    {
+      XFreeGC(display, pix[i]->stored_clip_gc);
+      pix[i]->stored_clip_gc = None;
+    }
+  }
+#endif /* TARGET_X11 */
+}
+
 void InitGfx()
 {
-  char *filename;
   int i;
 
   /* initialize some global variables */
@@ -308,21 +366,14 @@ void InitGfx()
   pix[PIX_DB_DOOR] = CreateBitmap(3 * DXSIZE, DYSIZE + VYSIZE, DEFAULT_DEPTH);
   pix[PIX_DB_FIELD] = CreateBitmap(FXSIZE, FYSIZE, DEFAULT_DEPTH);
 
-  filename = getImageFilename(image_filename[PIX_SMALLFONT]);
-  if ((pix_default[PIX_SMALLFONT] = LoadImage(filename)) == NULL)
-    Error(ERR_EXIT, "LoadImage() failed: %s", GetError());
-  pix_custom[PIX_SMALLFONT] = NULL;
-  pix[PIX_SMALLFONT] = pix_default[PIX_SMALLFONT];
+  pix[PIX_SMALLFONT] = LoadCustomImage(image_filename[PIX_SMALLFONT]);
 
   InitFontInfo(NULL, NULL, pix[PIX_SMALLFONT]);
 
   DrawInitText(WINDOW_TITLE_STRING, 20, FC_YELLOW);
   DrawInitText(WINDOW_SUBTITLE_STRING, 50, FC_RED);
-#if defined(PLATFORM_MSDOS)
-  DrawInitText(PROGRAM_DOS_PORT_STRING, 210, FC_BLUE);
-  rest(200);
-#endif
-  DrawInitText("Loading graphics:",120,FC_GREEN);
+
+  DrawInitText("Loading graphics:", 120, FC_GREEN);
 
   for(i=0; i<NUM_PICTURES; i++)
   {
@@ -330,11 +381,7 @@ void InitGfx()
     {
       DrawInitText(image_filename[i], 150, FC_YELLOW);
 
-      filename = getImageFilename(image_filename[i]);
-      if ((pix_default[i] = LoadImage(filename)) == NULL)
-       Error(ERR_EXIT, "LoadImage() failed: %s", GetError());
-      pix_custom[i] = NULL;
-      pix[i] = pix_default[i];
+      pix[i] = LoadCustomImage(image_filename[i]);
     }
   }
 
@@ -343,66 +390,152 @@ void InitGfx()
   InitTileClipmasks();
 }
 
-void LoadCustomGraphics()
+void InitGfxBackground()
 {
-#if 0
-  int i;
+  int x, y;
 
-  for(i=0; i<NUM_PICTURES; i++)
-  {
-    Bitmap *new_pic = 
-    pix_custom[i] = LoadImage(image_filename[i]);
-  }
-#endif
+  drawto = backbuffer;
+  fieldbuffer = pix[PIX_DB_FIELD];
+  SetDrawtoField(DRAW_BACKBUFFER);
+
+  BlitBitmap(pix[PIX_BACK], backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
+  ClearRectangle(backbuffer, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
+  ClearRectangle(pix[PIX_DB_DOOR], 0, 0, 3 * DXSIZE, DYSIZE + VYSIZE);
+
+  for(x=0; x<MAX_BUF_XSIZE; x++)
+    for(y=0; y<MAX_BUF_YSIZE; y++)
+      redraw[x][y] = 0;
+  redraw_tiles = 0;
+  redraw_mask = REDRAW_ALL;
 }
 
-void InitCustomGraphics()
+void ReloadCustomArtwork()
 {
+  static char *leveldir_current_identifier = NULL;
+  static boolean last_override_level_graphics = FALSE;
+  static boolean last_override_level_sounds = FALSE;
+  static boolean last_override_level_music = FALSE;
+
+  /* identifier for new artwork; default: artwork configured in setup */
+  char *gfx_new_identifier = artwork.gfx_current->identifier;
+  char *snd_new_identifier = artwork.snd_current->identifier;
+  char *mus_new_identifier = artwork.mus_current->identifier;
+
+#if 0
+  printf("graphics --> '%s' ('%s')\n",
+        artwork.gfx_current_identifier, artwork.gfx_current->filename);
+  printf("sounds   --> '%s' ('%s')\n",
+        artwork.snd_current_identifier, artwork.snd_current->filename);
+  printf("music    --> '%s' ('%s')\n",
+        artwork.mus_current_identifier, artwork.mus_current->filename);
+#endif
+
+  /* leveldir_current may be invalid (level group, parent link) */
+  if (!validLevelSeries(leveldir_current))
+    return;
+
 #if 0
-  static char *filename = NULL;
+  printf("--> '%s'\n", artwork.gfx_current_identifier);
+#endif
+
+  /* when a new level series was selected, check if there was a change
+     in custom artwork stored in level series directory */
+  if (leveldir_current_identifier != leveldir_current->identifier)
+  {
+    char *identifier_old = leveldir_current_identifier;
+    char *identifier_new = leveldir_current->identifier;
+
+    if (getTreeInfoFromIdentifier(artwork.gfx_first, identifier_old) !=
+       getTreeInfoFromIdentifier(artwork.gfx_first, identifier_new))
+      gfx_new_identifier = identifier_new;
+    if (getTreeInfoFromIdentifier(artwork.snd_first, identifier_old) !=
+       getTreeInfoFromIdentifier(artwork.snd_first, identifier_new))
+      snd_new_identifier = identifier_new;
+    if (getTreeInfoFromIdentifier(artwork.mus_first, identifier_new) !=
+       getTreeInfoFromIdentifier(artwork.mus_first, identifier_new))
+      artwork.mus_current_identifier = NULL;
+
+    leveldir_current_identifier = leveldir_current->identifier;
+  }
 
-  /* look for optional directory ~/.<program>/graphics */
-  filename = getPath2(getUserDataDir(), GRAPHICS_DIRECTORY);
-  if (access(dir, F_OK) == 0)
+  /* custom level artwork configured in level series configuration file
+     always overrides custom level artwork stored in level series directory
+     and (level independant) custom artwork configured in setup menue
+     (the path entry is needed to send it to the sound child process) */
+  if (leveldir_current->graphics_set != NULL)
+  {
+    if (leveldir_current->graphics_path)
+      free(leveldir_current->graphics_path);
+    leveldir_current->graphics_path = NULL;
+    leveldir_current->graphics_path =
+      getStringCopy(getLevelArtworkDir(artwork.gfx_first));
+    gfx_new_identifier = leveldir_current->graphics_set;
+  }
+  if (leveldir_current->sounds_set != NULL)
   {
+    if (leveldir_current->sounds_path)
+      free(leveldir_current->sounds_path);
+    leveldir_current->sounds_path = NULL;
+    leveldir_current->sounds_path =
+      getStringCopy(getLevelArtworkDir(artwork.snd_first));
+    snd_new_identifier = leveldir_current->sounds_set;
+  }
+  if (leveldir_current->music_set != NULL)
+  {
+    if (leveldir_current->music_path)
+      free(leveldir_current->music_path);
+    leveldir_current->music_path = NULL;
+    leveldir_current->music_path =
+      getStringCopy(getLevelArtworkDir(artwork.mus_first));
+    mus_new_identifier = leveldir_current->music_set;
   }
 
+  if (strcmp(artwork.gfx_current_identifier, gfx_new_identifier) != 0 ||
+      last_override_level_graphics != setup.override_level_graphics)
+  {
+    int i;
 
+    ClearRectangle(window, 0, 0, WIN_XSIZE, WIN_YSIZE);
 
+    for(i=0; i<NUM_PICTURES; i++)
+    {
+      DrawInitText(image_filename[i], 150, FC_YELLOW);
+      ReloadCustomImage(pix[i], image_filename[i]);
+    }
 
-(leveldir_current->user_defined ?
-                      getUserLevelDir("") :
-                      options.level_directory),
-                     leveldir_current->fullpath,
-                     basename);
+    FreeTileClipmasks();
+    InitTileClipmasks();
+    InitGfxBackground();
 
+    /* force redraw of (open or closed) door graphics */
+    SetDoorState(DOOR_OPEN_ALL);
+    CloseDoor(DOOR_CLOSE_ALL | DOOR_NO_DELAY);
 
+    artwork.gfx_current_identifier = gfx_new_identifier;
+    last_override_level_graphics = setup.override_level_graphics;
+  }
 
-  filename = getPath3((leveldir_current->user_defined ?
-                      getUserLevelDir("") :
-                      options.level_directory),
-                     leveldir_current->fullpath,
-                     basename);
-#endif
-}
+  if (strcmp(artwork.snd_current_identifier, snd_new_identifier) != 0 ||
+      last_override_level_sounds != setup.override_level_sounds)
+  {
+    InitReloadSounds(snd_new_identifier);
 
-void InitGfxBackground()
-{
-  int x, y;
+    artwork.snd_current_identifier = snd_new_identifier;
+    last_override_level_sounds = setup.override_level_sounds;
+  }
 
-  drawto = backbuffer;
-  fieldbuffer = pix[PIX_DB_FIELD];
-  SetDrawtoField(DRAW_BACKBUFFER);
+  if (strcmp(artwork.mus_current_identifier, mus_new_identifier) != 0 ||
+      last_override_level_music != setup.override_level_music)
+  {
+    InitReloadMusic(mus_new_identifier);
 
-  BlitBitmap(pix[PIX_BACK], backbuffer, 0,0, WIN_XSIZE,WIN_YSIZE, 0,0);
-  ClearRectangle(backbuffer, REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE);
-  ClearRectangle(pix[PIX_DB_DOOR], 0,0, 3*DXSIZE,DYSIZE+VYSIZE);
+    artwork.mus_current_identifier = mus_new_identifier;
+    last_override_level_music = setup.override_level_music;
+  }
 
-  for(x=0; x<MAX_BUF_XSIZE; x++)
-    for(y=0; y<MAX_BUF_YSIZE; y++)
-      redraw[x][y] = 0;
-  redraw_tiles = 0;
-  redraw_mask = REDRAW_ALL;
+#if 0
+  printf("<-- '%s'\n", artwork.gfx_current_identifier);
+#endif
 }
 
 void InitGadgets()
@@ -469,9 +602,13 @@ void InitElementProperties()
     EL_EM_GATE_3X,
     EL_EM_GATE_4X,
     EL_SWITCHGATE_OPEN,
+    EL_SWITCHGATE_OPENING,
     EL_SWITCHGATE_CLOSED,
+    EL_SWITCHGATE_CLOSING,
     EL_TIMEGATE_OPEN,
+    EL_TIMEGATE_OPENING,
     EL_TIMEGATE_CLOSED,
+    EL_TIMEGATE_CLOSING,
     EL_TUBE_CROSS,
     EL_TUBE_VERTICAL,
     EL_TUBE_HORIZONTAL,
@@ -510,11 +647,15 @@ void InitElementProperties()
     EL_QUICKSAND_EMPTYING,
     EL_MAGIC_WALL_OFF,
     EL_MAGIC_WALL_EMPTY,
+    EL_MAGIC_WALL_EMPTYING,
+    EL_MAGIC_WALL_FILLING,
     EL_MAGIC_WALL_FULL,
     EL_MAGIC_WALL_DEAD,
     EL_MAGIC_WALL_BD_OFF,
     EL_MAGIC_WALL_BD_EMPTY,
+    EL_MAGIC_WALL_BD_EMPTYING,
     EL_MAGIC_WALL_BD_FULL,
+    EL_MAGIC_WALL_BD_FILLING,
     EL_MAGIC_WALL_BD_DEAD,
     EL_LIFE,
     EL_LIFE_ASYNC,
@@ -540,6 +681,7 @@ void InitElementProperties()
     EL_SP_HARD_BASE5,
     EL_SP_HARD_BASE6,
     EL_SP_TERMINAL,
+    EL_SP_TERMINAL_ACTIVE,
     EL_SP_EXIT,
     EL_INVISIBLE_STEEL,
     EL_BELT1_SWITCH_LEFT,
@@ -588,6 +730,30 @@ void InitElementProperties()
     EL_CRYSTAL,
     EL_WALL_PEARL,
     EL_WALL_CRYSTAL,
+    EL_PFORTE1,
+    EL_PFORTE2,
+    EL_PFORTE3,
+    EL_PFORTE4,
+    EL_PFORTE1X,
+    EL_PFORTE2X,
+    EL_PFORTE3X,
+    EL_PFORTE4X,
+    EL_EM_GATE_1,
+    EL_EM_GATE_2,
+    EL_EM_GATE_3,
+    EL_EM_GATE_4,
+    EL_EM_GATE_1X,
+    EL_EM_GATE_2X,
+    EL_EM_GATE_3X,
+    EL_EM_GATE_4X,
+    EL_SWITCHGATE_OPEN,
+    EL_SWITCHGATE_OPENING,
+    EL_SWITCHGATE_CLOSED,
+    EL_SWITCHGATE_CLOSING,
+    EL_TIMEGATE_OPEN,
+    EL_TIMEGATE_OPENING,
+    EL_TIMEGATE_CLOSED,
+    EL_TIMEGATE_CLOSING,
     EL_TUBE_CROSS,
     EL_TUBE_VERTICAL,
     EL_TUBE_HORIZONTAL,
@@ -611,26 +777,6 @@ void InitElementProperties()
     EL_BADEWANNE3,
     EL_BADEWANNE4,
     EL_BADEWANNE5,
-    EL_PFORTE1,
-    EL_PFORTE2,
-    EL_PFORTE3,
-    EL_PFORTE4,
-    EL_PFORTE1X,
-    EL_PFORTE2X,
-    EL_PFORTE3X,
-    EL_PFORTE4X,
-    EL_EM_GATE_1,
-    EL_EM_GATE_2,
-    EL_EM_GATE_3,
-    EL_EM_GATE_4,
-    EL_EM_GATE_1X,
-    EL_EM_GATE_2X,
-    EL_EM_GATE_3X,
-    EL_EM_GATE_4X,
-    EL_SWITCHGATE_OPEN,
-    EL_SWITCHGATE_CLOSED,
-    EL_TIMEGATE_OPEN,
-    EL_TIMEGATE_CLOSED,
     EL_SP_HARD_GRAY,
     EL_SP_HARD_GREEN,
     EL_SP_HARD_BLUE,
@@ -675,6 +821,30 @@ void InitElementProperties()
     EL_EMC_STEEL_WALL_3,
     EL_EMC_STEEL_WALL_4,
     EL_CRYSTAL,
+    EL_PFORTE1,
+    EL_PFORTE2,
+    EL_PFORTE3,
+    EL_PFORTE4,
+    EL_PFORTE1X,
+    EL_PFORTE2X,
+    EL_PFORTE3X,
+    EL_PFORTE4X,
+    EL_EM_GATE_1,
+    EL_EM_GATE_2,
+    EL_EM_GATE_3,
+    EL_EM_GATE_4,
+    EL_EM_GATE_1X,
+    EL_EM_GATE_2X,
+    EL_EM_GATE_3X,
+    EL_EM_GATE_4X,
+    EL_SWITCHGATE_OPEN,
+    EL_SWITCHGATE_OPENING,
+    EL_SWITCHGATE_CLOSED,
+    EL_SWITCHGATE_CLOSING,
+    EL_TIMEGATE_OPEN,
+    EL_TIMEGATE_OPENING,
+    EL_TIMEGATE_CLOSED,
+    EL_TIMEGATE_CLOSING,
     EL_TUBE_CROSS,
     EL_TUBE_VERTICAL,
     EL_TUBE_HORIZONTAL,
@@ -788,6 +958,7 @@ void InitElementProperties()
     EL_SP_HARD_BASE5,
     EL_SP_HARD_BASE6,
     EL_SP_TERMINAL,
+    EL_SP_TERMINAL_ACTIVE,
     EL_SP_EXIT,
     EL_INVISIBLE_STEEL,
     EL_STEEL_SLANTED,
@@ -1563,19 +1734,55 @@ void InitElementProperties()
     Elementeigenschaften1[i] |= (EP_BIT_CHAR | EP_BIT_INACTIVE);
 }
 
+void Execute_Debug_Command(char *command)
+{
+  if (strcmp(command, "create graphicsinfo.conf") == 0)
+  {
+    printf("# (Currently only \"name\" and \"sort_priority\" recognized.)\n");
+    printf("\n");
+    printf("%s\n", getFormattedSetupEntry("name", "Classic Graphics"));
+    printf("\n");
+    printf("%s\n", getFormattedSetupEntry("sort_priority", "100"));
+  }
+  else if (strcmp(command, "create soundsinfo.conf") == 0)
+  {
+    int i;
+
+    printf("# You can configure additional/alternative sound effects here\n");
+    printf("# (The sounds below are default and therefore commented out.)\n");
+    printf("\n");
+    printf("%s\n", getFormattedSetupEntry("name", "Classic Sounds"));
+    printf("\n");
+    printf("%s\n", getFormattedSetupEntry("sort_priority", "100"));
+    printf("\n");
+
+    for (i=0; i<NUM_SOUND_EFFECTS; i++)
+      printf("# %s\n",
+            getFormattedSetupEntry(sound_effects[i].text,
+                                   sound_effects[i].default_filename));
+  }
+  else if (strcmp(command, "create musicinfo.conf") == 0)
+  {
+    printf("# (Currently only \"name\" and \"sort_priority\" recognized.)\n");
+    printf("\n");
+    printf("%s\n", getFormattedSetupEntry("name", "Classic Music"));
+    printf("\n");
+    printf("%s\n", getFormattedSetupEntry("sort_priority", "100"));
+  }
+}
+
 void CloseAllAndExit(int exit_value)
 {
   int i;
 
   StopSounds();
-  FreeSounds(NUM_SOUNDS);
-  CloseAudio();
+  FreeAllSounds();
+  FreeAllMusic();
+  CloseAudio();                /* called after freeing sounds (needed for SDL) */
 
+  FreeTileClipmasks();
   for(i=0; i<NUM_BITMAPS; i++)
-  {
-    FreeBitmap(pix_default[i]);
-    FreeBitmap(pix_custom[i]);
-  }
+    FreeBitmap(pix[i]);
 
   CloseVideoDisplay();
   ClosePlatformDependantStuff();