rnd-19981108-2
authorHolger Schemel <info@artsoft.org>
Sun, 8 Nov 1998 14:56:25 +0000 (15:56 +0100)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:31:35 +0000 (10:31 +0200)
12 files changed:
src/Makefile
src/files.c
src/files.h
src/game.c
src/init.c
src/main.c
src/main.h
src/misc.c
src/msdos.h
src/network.c
src/screens.c
src/sound.c

index a4f4571..50502fa 100644 (file)
@@ -1,32 +1,59 @@
-#
-# Makefile fuer "Rocks'n'Diamonds -- McDuffin Strikes Back"
-#
+#=============================================================================#
+# Makefile for Rocks'n'Diamonds 1.2                                           #
+# (c) 1995-98 Holger Schemel, aeglos@valinor.owl.de                           #
+#=============================================================================#
 
-PROGNAME = rocksndiamonds
-# SERVNAME = rnd_server
+#-----------------------------------------------------------------------------#
+# configuration section                                                       #
+#-----------------------------------------------------------------------------#
 
-RM = rm -f
+# change this to your favorite ANSI C compiler
 CC = gcc
-CPP = $(CC) -E
-# CC = cc                              # for HP-UX and others
 
-GAME_DIR = -DGAME_DIR=\".\"            # path of the game and its data
-# JOYSTICK = -DNO_JOYSTICK             # no joystick
-# SOUNDS = -DNO_SOUNDS                 # no sounds
-# SCORE_ENTRIES = -DONE_PER_NAME       # only one score entry per name
-SCORE_ENTRIES = -DMANY_PER_NAME                # many score entries per name
+# on Solaris and similar systems, you'll need to uncomment this
+# EXTRA_LIBS = -lnsl -lsocket 
+
+# specify X11 library path on your system
+XLIB_PATH = /usr/X11/lib
+
+# change this to the directory where you want to install game data like levels
+GAME_DIR = .
+
+# uncomment this if your system has no joystick include file
+# JOYSTICK = -DNO_JOYSTICK
+
+# uncomment this if your system has no sound
+# SOUNDS = -DNO_SOUNDS
+
+# choose if you want to allow many global score file entries for one player
+# when installing the game in a multi user environment, choose this
+# SCORE_ENTRIES = ONE_PER_NAME
+# when installing the game in a single user environment, choose this
+SCORE_ENTRIES = MANY_PER_NAME
 
 # The XPM-Library is no longer needed to build this program,
 # but is used to load graphics if XPM_INCLUDE_FILE is defined,
 # because the GIF loading routines are still a bit beta.
-# If you use the Xpm library, convert the GIF files to Xpm
-# files (and the mask files ('*Maske.gif') to xbm files).
+# If you want to use the Xpm library, convert the GIF files to Xpm
+# files (and you need corresponding mask files in xbm format).
 
 # XPM_INCLUDE_FILE = -DXPM_INCLUDE_FILE="<X11/xpm.h>"
 # EXTRA_X11_LIBS = -lXpm
 
-CONFIG = $(GAME_DIR) $(SOUNDS) $(JOYSTICK)     \
-        $(SCORE_ENTRIES) $(XPM_INCLUDE_FILE)
+#-----------------------------------------------------------------------------#
+# you shouldn't need to change anything below                                 #
+#-----------------------------------------------------------------------------#
+
+PROGNAME = rocksndiamonds
+
+RM = rm -f
+CPP = $(CC) -E
+
+CONFIG_GAME_DIR = -DGAME_DIR="\"$(GAME_DIR)\""
+CONFIG_SCORE_ENTRIES = -D$(SCORE_ENTRIES)
+
+CONFIG = $(CONFIG_GAME_DIR) $(SOUNDS) $(JOYSTICK)      \
+        $(CONFIG_SCORE_ENTRIES) $(XPM_INCLUDE_FILE)
 
 # DEBUG = -DDEBUG -g -ansi -pedantic -Wall
 DEBUG = -DDEBUG -g -Wall
@@ -44,7 +71,8 @@ DEBUG = -DDEBUG -g -Wall
 # LIBS = -L/usr/X11R6/lib -lXpm -lX11 -lm
 # LIBS = -L/usr/X11R6/lib -lX11 -lm
 
-LIBS = -L/usr/X11R6/lib $(EXTRA_X11_LIBS) -lX11 -lm
+# LIBS = -L/usr/X11R6/lib $(EXTRA_X11_LIBS) -lX11 -lm $(EXTRA_LIBS)
+LIBS = -L$(XLIB_PATH) $(EXTRA_X11_LIBS) -lX11 -lm $(EXTRA_LIBS)
 
 # CFLAGS = -O2 $(CONFIG) $(SYSTEM)
 CFLAGS = $(DEBUG) $(CONFIG) $(SYSTEM) $(INCL)
@@ -93,15 +121,11 @@ OBJS =     main.o          \
        network.o       \
        netserv.o
 
-# all: $(PROGNAME) $(SERVNAME)
 all:   $(PROGNAME)
 
 $(PROGNAME):   $(OBJS)
        $(CC) $(CFLAGS) $(OBJS) $(LIBS) -o $(PROGNAME)
 
-# $(SERVNAME): $(SERVNAME).c
-#      $(CC) $(CFLAGS) $(SERVNAME).c $(LIBS) -o $(SERVNAME)
-
 .c.o:
        $(CC) $(CFLAGS) -c $*.c
 
index bdd8b54..fc7d7a9 100644 (file)
 #include "tape.h"
 #include "joystick.h"
 
-static char *getUserdataDir()
+#define MAX_LINE_LEN                   1000
+
+static char *getGlobalDataDir()
+{
+  return GAME_DIR;
+}
+
+static char *getUserDataDir()
 {
   static char *userdata_dir = NULL;
 
@@ -37,14 +44,14 @@ static char *getUserdataDir()
 
 static char *getSetupDir()
 {
-  return getUserdataDir();
+  return getUserDataDir();
 }
 
 static char *getTapeDir(char *level_subdir)
 {
   static char *tape_dir = NULL;
-  char *data_dir = getUserdataDir();
-  char *tape_subdir = TAPEDATA_DIRECTORY;
+  char *data_dir = getUserDataDir();
+  char *tape_subdir = TAPES_DIRECTORY;
 
   if (tape_dir)
     free(tape_dir);
@@ -57,6 +64,23 @@ static char *getTapeDir(char *level_subdir)
   return tape_dir;
 }
 
+static char *getScoreDir(char *level_subdir)
+{
+  static char *score_dir = NULL;
+  char *data_dir = getGlobalDataDir();
+  char *score_subdir = SCORES_DIRECTORY;
+
+  if (score_dir)
+    free(score_dir);
+
+  score_dir = checked_malloc(strlen(data_dir) + strlen(score_subdir) +
+                            strlen(level_subdir) + 3);
+  sprintf(score_dir, "%s/%s%s%s", data_dir, score_subdir,
+         (strlen(level_subdir) > 0 ? "/" : ""), level_subdir);
+
+  return score_dir;
+}
+
 static void createDirectory(char *dir, char *text)
 {
   if (access(dir, F_OK) != 0)
@@ -64,15 +88,21 @@ static void createDirectory(char *dir, char *text)
       Error(ERR_WARN, "cannot create %s directory '%s'", text, dir);
 }
 
-void InitUserdataDirectory()
+static void InitUserDataDirectory()
 {
-  createDirectory(getUserdataDir(), "user data");
+  createDirectory(getUserDataDir(), "user data");
 }
 
 static void InitTapeDirectory(char *level_subdir)
 {
-  createDirectory(getTapeDir(""), "main tape data");
-  createDirectory(getTapeDir(level_subdir), "level tape data");
+  createDirectory(getTapeDir(""), "main tape");
+  createDirectory(getTapeDir(level_subdir), "level tape");
+}
+
+static void InitScoreDirectory(char *level_subdir)
+{
+  createDirectory(getScoreDir(""), "main score");
+  createDirectory(getScoreDir(level_subdir), "level score");
 }
 
 boolean LoadLevelInfo()
@@ -82,16 +112,16 @@ boolean LoadLevelInfo()
   char cookie[MAX_FILENAME_LEN];
   FILE *file;
 
-  sprintf(filename,"%s/%s",level_directory,LEVDIR_FILENAME);
+  sprintf(filename, "%s/%s", options.level_directory, LEVDIR_FILENAME);
 
-  if (!(file=fopen(filename,"r")))
+  if (!(file = fopen(filename, "r")))
   {
     Error(ERR_WARN, "cannot read level info '%s'", filename);
     return(FALSE);
   }
 
-  fscanf(file,"%s\n",cookie);
-  if (strcmp(cookie,LEVELDIR_COOKIE))  /* ungültiges Format? */
+  fscanf(file, "%s\n", cookie);
+  if (strcmp(cookie, LEVELDIR_COOKIE))
   {
     Error(ERR_WARN, "wrong format of level info file");
     fclose(file);
@@ -100,12 +130,12 @@ boolean LoadLevelInfo()
 
   num_leveldirs = 0;
   leveldir_nr = 0;
-  for(i=0;i<MAX_LEVDIR_ENTRIES;i++)
+  for(i=0; i<MAX_LEVDIR_ENTRIES; i++)
   {
-    fscanf(file,"%s",leveldir[i].filename);
-    fscanf(file,"%s",leveldir[i].name);
-    fscanf(file,"%d",&leveldir[i].levels);
-    fscanf(file,"%d",&leveldir[i].readonly);
+    fscanf(file, "%s", leveldir[i].filename);
+    fscanf(file, "%s", leveldir[i].name);
+    fscanf(file, "%d", &leveldir[i].levels);
+    fscanf(file, "%d", &leveldir[i].readonly);
     if (feof(file))
       break;
 
@@ -123,22 +153,22 @@ boolean LoadLevelInfo()
 
 void LoadLevel(int level_nr)
 {
-  int i,x,y;
+  int i, x, y;
   char filename[MAX_FILENAME_LEN];
   char cookie[MAX_FILENAME_LEN];
   FILE *file;
 
-  sprintf(filename,"%s/%s/%d",
-         level_directory,leveldir[leveldir_nr].filename,level_nr);
+  sprintf(filename, "%s/%s/%d",
+         options.level_directory, leveldir[leveldir_nr].filename, level_nr);
 
-  if (!(file = fopen(filename,"r")))
+  if (!(file = fopen(filename, "r")))
     Error(ERR_WARN, "cannot read level '%s' - creating new level", filename);
   else
   {
-    fgets(cookie,LEVEL_COOKIE_LEN,file);
+    fgets(cookie, LEVEL_COOKIE_LEN, file);
     fgetc(file);
 
-    if (strcmp(cookie,LEVEL_COOKIE))   /* ungültiges Format? */
+    if (strcmp(cookie,LEVEL_COOKIE))
     {
       Error(ERR_WARN, "wrong format of level file '%s'", filename);
       fclose(file);
@@ -153,34 +183,34 @@ void LoadLevel(int level_nr)
 
     level.time         = (fgetc(file)<<8) | fgetc(file);
     level.edelsteine   = (fgetc(file)<<8) | fgetc(file);
-    for(i=0;i<MAX_LEVNAMLEN;i++)
+    for(i=0; i<MAX_LEVNAMLEN; i++)
       level.name[i]    = fgetc(file);
     level.name[MAX_LEVNAMLEN-1] = 0;
-    for(i=0;i<MAX_LEVSCORE_ENTRIES;i++)
+    for(i=0; i<MAX_LEVSCORE_ENTRIES; i++)
       level.score[i]   = fgetc(file);
-    for(i=0;i<4;i++)
-      for(y=0;y<3;y++)
-       for(x=0;x<3;x++)
+    for(i=0; i<4; i++)
+      for(y=0; y<3; y++)
+       for(x=0; x<3; x++)
          level.mampfer_inhalt[i][x][y] = fgetc(file);
     level.tempo_amoebe = fgetc(file);
     level.dauer_sieb   = fgetc(file);
     level.dauer_ablenk = fgetc(file);
     level.amoebe_inhalt = fgetc(file);
 
-    for(i=0;i<NUM_FREE_LVHD_BYTES;i++) /* Rest frei / Headergröße 80 Bytes */
+    for(i=0; i<NUM_FREE_LVHD_BYTES; i++) /* Rest frei / Headergröße 80 Bytes */
       fgetc(file);
 
-    for(y=0;y<MAX_LEV_FIELDY;y++) 
-      for(x=0;x<MAX_LEV_FIELDX;x++) 
+    for(y=0; y<MAX_LEV_FIELDY; y++) 
+      for(x=0; x<MAX_LEV_FIELDX; x++) 
        Feld[x][y] = Ur[x][y] = EL_ERDREICH;
 
-    for(y=0;y<lev_fieldy;y++) 
-      for(x=0;x<lev_fieldx;x++) 
+    for(y=0; y<lev_fieldy; y++) 
+      for(x=0; x<lev_fieldx; x++) 
        Feld[x][y] = Ur[x][y] = fgetc(file);
 
     fclose(file);
 
-    if (level.time<=10)        /* Mindestspieldauer */
+    if (level.time <= 10)      /* Mindestspieldauer */
       level.time = 10;
   }
   else
@@ -190,20 +220,20 @@ void LoadLevel(int level_nr)
 
     level.time         = 100;
     level.edelsteine   = 0;
-    strncpy(level.name,"Nameless Level",MAX_LEVNAMLEN-1);
-    for(i=0;i<MAX_LEVSCORE_ENTRIES;i++)
+    strcpy(level.name, "Nameless Level");
+    for(i=0; i<MAX_LEVSCORE_ENTRIES; i++)
       level.score[i]   = 10;
-    for(i=0;i<4;i++)
-      for(y=0;y<3;y++)
-       for(x=0;x<3;x++)
+    for(i=0; i<4; i++)
+      for(y=0; y<3; y++)
+       for(x=0; x<3; x++)
          level.mampfer_inhalt[i][x][y] = EL_FELSBROCKEN;
     level.tempo_amoebe = 10;
     level.dauer_sieb   = 10;
     level.dauer_ablenk = 10;
     level.amoebe_inhalt = EL_DIAMANT;
 
-    for(y=0;y<STD_LEV_FIELDY;y++) 
-      for(x=0;x<STD_LEV_FIELDX;x++) 
+    for(y=0; y<STD_LEV_FIELDY; y++) 
+      for(x=0; x<STD_LEV_FIELDX; x++) 
        Feld[x][y] = Ur[x][y] = EL_ERDREICH;
     Feld[0][0] = Ur[0][0] = EL_SPIELFIGUR;
     Feld[STD_LEV_FIELDX-1][STD_LEV_FIELDY-1] =
@@ -213,55 +243,55 @@ void LoadLevel(int level_nr)
 
 void SaveLevel(int level_nr)
 {
-  int i,x,y;
+  int i, x, y;
   char filename[MAX_FILENAME_LEN];
   FILE *file;
 
-  sprintf(filename,"%s/%s/%d",
-         level_directory,leveldir[leveldir_nr].filename,level_nr);
+  sprintf(filename, "%s/%s/%d",
+         options.level_directory, leveldir[leveldir_nr].filename, level_nr);
 
-  if (!(file=fopen(filename,"w")))
+  if (!(file = fopen(filename, "w")))
   {
     Error(ERR_WARN, "cannot save level file '%s'", filename);
     return;
   }
 
   fputs(LEVEL_COOKIE,file);            /* Formatkennung */
-  fputc(0x0a,file);
-
-  fputc(level.fieldx,file);
-  fputc(level.fieldy,file);
-  fputc(level.time / 256,file);
-  fputc(level.time % 256,file);
-  fputc(level.edelsteine / 256,file);
-  fputc(level.edelsteine % 256,file);
-
-  for(i=0;i<MAX_LEVNAMLEN;i++)
-    fputc(level.name[i],file);
-  for(i=0;i<MAX_LEVSCORE_ENTRIES;i++)
-    fputc(level.score[i],file);
-  for(i=0;i<4;i++)
-    for(y=0;y<3;y++)
-      for(x=0;x<3;x++)
-       fputc(level.mampfer_inhalt[i][x][y],file);
-  fputc(level.tempo_amoebe,file);
-  fputc(level.dauer_sieb,file);
-  fputc(level.dauer_ablenk,file);
-  fputc(level.amoebe_inhalt,file);
-
-  for(i=0;i<NUM_FREE_LVHD_BYTES;i++)   /* Rest frei / Headergröße 80 Bytes */
-    fputc(0,file);
-
-  for(y=0;y<lev_fieldy;y++) 
-    for(x=0;x<lev_fieldx;x++) 
-      fputc(Ur[x][y],file);
+  fputc(0x0a, file);
+
+  fputc(level.fieldx, file);
+  fputc(level.fieldy, file);
+  fputc(level.time / 256, file);
+  fputc(level.time % 256, file);
+  fputc(level.edelsteine / 256, file);
+  fputc(level.edelsteine % 256, file);
+
+  for(i=0; i<MAX_LEVNAMLEN; i++)
+    fputc(level.name[i], file);
+  for(i=0; i<MAX_LEVSCORE_ENTRIES; i++)
+    fputc(level.score[i], file);
+  for(i=0; i<4; i++)
+    for(y=0; y<3; y++)
+      for(x=0; x<3; x++)
+       fputc(level.mampfer_inhalt[i][x][y], file);
+  fputc(level.tempo_amoebe, file);
+  fputc(level.dauer_sieb, file);
+  fputc(level.dauer_ablenk, file);
+  fputc(level.amoebe_inhalt, file);
+
+  for(i=0; i<NUM_FREE_LVHD_BYTES; i++) /* Rest frei / Headergröße 80 Bytes */
+    fputc(0, file);
+
+  for(y=0; y<lev_fieldy; y++) 
+    for(x=0; x<lev_fieldx; x++) 
+      fputc(Ur[x][y], file);
 
   fclose(file);
 
   chmod(filename, LEVEL_PERMS);
 }
 
-void LoadLevelTape(int level_nr)
+void LoadTape(int level_nr)
 {
   int i;
   char filename[MAX_FILENAME_LEN];
@@ -364,7 +394,7 @@ void LoadLevelTape(int level_nr)
   tape.length_seconds = GetTapeLength();
 }
 
-void SaveLevelTape(int level_nr)
+void SaveTape(int level_nr)
 {
   int i;
   char filename[MAX_FILENAME_LEN];
@@ -431,121 +461,90 @@ void SaveLevelTape(int level_nr)
     Request("tape saved !",REQ_CONFIRM);
 }
 
-boolean CreateNewScoreFile()
+void LoadScore(int level_nr)
 {
-  int i,j,k;
+  int i;
   char filename[MAX_FILENAME_LEN];
-  char empty_alias[MAX_NAMELEN];
+  char cookie[MAX_FILENAME_LEN];
+  char line[MAX_LINE_LEN];
+  char *line_ptr;
   FILE *file;
 
-  sprintf(filename,"%s/%s/%s",
-         level_directory,leveldir[leveldir_nr].filename,SCORE_FILENAME);
-
-  if (!(file=fopen(filename,"w")))
-    return(FALSE);
-
-  for(i=0;i<MAX_NAMELEN;i++)
-    empty_alias[i] = 0;
-  strncpy(empty_alias,EMPTY_ALIAS,MAX_NAMELEN-1);
-
-  fputs(SCORE_COOKIE,file);            /* Formatkennung */
-  for(i=0;i<leveldir[leveldir_nr].levels;i++)
+  /* start with empty score table */
+  for(i=0; i<MAX_SCORE_ENTRIES; i++)
   {
-    for(j=0;j<MAX_SCORE_ENTRIES;j++)
-    {
-      for(k=0;k<MAX_NAMELEN;k++)
-       fputc(empty_alias[k],file);
-      fputc(0,file);
-      fputc(0,file);
-    }
+    strcpy(highscore[i].Name, EMPTY_ALIAS);
+    highscore[i].Score = 0;
   }
-  fclose(file);
 
-  chmod(filename, SCORE_PERMS);
-  return(TRUE);
-}
+  sprintf(filename, "%s/%d.%s",
+         getScoreDir(leveldir[leveldir_nr].filename),
+         level_nr, SCOREFILE_EXTENSION);
 
-void LoadScore(int level_nr)
-{
-  int i,j;
-  char filename[MAX_FILENAME_LEN];
-  char cookie[MAX_FILENAME_LEN];
-  FILE *file;
+  if (!(file = fopen(filename, "r")))
+    return;
 
-  sprintf(filename,"%s/%s/%s",
-         level_directory,leveldir[leveldir_nr].filename,SCORE_FILENAME);
+  fgets(cookie, SCORE_COOKIE_LEN, file);
 
-  if (!(file = fopen(filename,"r")))
+  if (strcmp(cookie, SCORE_COOKIE) != 0)
   {
-    if (!CreateNewScoreFile())
-      Error(ERR_WARN, "cannot create score file '%s'", filename);
-    else if (!(file = fopen(filename,"r"))) 
-      Error(ERR_WARN, "cannot read score for level %d", level_nr);
+    Error(ERR_WARN, "wrong format of score file '%s'", filename);
+    fclose(file);
+    return;
   }
 
-  if (file)
+  for(i=0; i<MAX_SCORE_ENTRIES; i++)
   {
-    fgets(cookie,SCORE_COOKIE_LEN,file);
-    if (strcmp(cookie,SCORE_COOKIE))   /* ungültiges Format? */
-    {
-      Error(ERR_WARN, "wrong format of score file '%s'", filename);
-      fclose(file);
-      file = NULL;
-    }
-  }
+    int position_nr;
 
-  if (file)
-  {
-    fseek(file,
-         SCORE_COOKIE_LEN-1+level_nr*(MAX_SCORE_ENTRIES*(MAX_NAMELEN+2)),
-         SEEK_SET);
-    for(i=0;i<MAX_SCORE_ENTRIES;i++)
-    {
-      for(j=0;j<MAX_NAMELEN;j++)
-       highscore[i].Name[j] = fgetc(file);
-      highscore[i].Score = (fgetc(file)<<8) | fgetc(file);
-    }
-    fclose(file);
-  }
-  else
-  {
-    for(i=0;i<MAX_SCORE_ENTRIES;i++)
+    fscanf(file, "%d", &position_nr);
+    fscanf(file, "%d", &highscore[i].Score);
+    fgets(line, MAX_LINE_LEN, file);
+
+    if (line[strlen(line)-1] == '\n')
+      line[strlen(line)-1] = '\0';
+
+    for (line_ptr = line; *line_ptr; line_ptr++)
     {
-      strcpy(highscore[i].Name,EMPTY_ALIAS);
-      highscore[i].Score = 0;
+      if (*line_ptr != ' ' && *line_ptr != '\t' && *line_ptr != '\0')
+      {
+       strncpy(highscore[i].Name, line_ptr, MAX_NAMELEN - 1);
+       highscore[i].Name[MAX_NAMELEN - 1] = '\0';
+       break;
+      }
     }
   }
+
+  fclose(file);
 }
 
 void SaveScore(int level_nr)
 {
-  int i,j;
+  int i;
   char filename[MAX_FILENAME_LEN];
   FILE *file;
 
-  sprintf(filename,"%s/%s/%s",
-         level_directory,leveldir[leveldir_nr].filename,SCORE_FILENAME);
+  sprintf(filename, "%s/%d.%s",
+         getScoreDir(leveldir[leveldir_nr].filename),
+         level_nr, SCOREFILE_EXTENSION);
 
-  if (!(file=fopen(filename,"r+")))
+  InitScoreDirectory(leveldir[leveldir_nr].filename);
+
+  if (!(file = fopen(filename, "w")))
   {
     Error(ERR_WARN, "cannot save score for level %d", level_nr);
     return;
   }
 
-  fseek(file,
-       SCORE_COOKIE_LEN-1+level_nr*(MAX_SCORE_ENTRIES*(MAX_NAMELEN+2)),
-       SEEK_SET);
-  for(i=0;i<MAX_SCORE_ENTRIES;i++)
-  {
-    for(j=0;j<MAX_NAMELEN;j++)
-      fputc(highscore[i].Name[j],file);
-    fputc(highscore[i].Score / 256,file);
-    fputc(highscore[i].Score % 256,file);
-  }
+  fprintf(file, "%s\n\n", SCORE_COOKIE);
+
+  for(i=0; i<MAX_SCORE_ENTRIES; i++)
+    fprintf(file, "%d %d %s\n", i+1, highscore[i].Score, highscore[i].Name);
+
   fclose(file);
-}
 
-#define MAX_LINE_LEN                   1000
+  chmod(filename, SCORE_PERMS);
+}
 
 #define TOKEN_STR_FILE_IDENTIFIER      "file_identifier"
 #define TOKEN_STR_LAST_LEVEL_SERIES    "last_level_series"
@@ -1139,6 +1138,8 @@ void SaveSetup()
 
   sprintf(filename, "%s/%s", getSetupDir(), SETUP_FILENAME);
 
+  InitUserDataDirectory();
+
   if (!(file = fopen(filename, "w")))
   {
     Error(ERR_WARN, "cannot write setup file '%s'", filename);
@@ -1222,6 +1223,8 @@ void SaveLevelSetup()
 
   sprintf(filename, "%s/%s", getSetupDir(), LEVELSETUP_FILENAME);
 
+  InitUserDataDirectory();
+
   if (!(file = fopen(filename, "w")))
   {
     Error(ERR_WARN, "cannot write setup file '%s'", filename);
index 2c1acbd..a8dd277 100644 (file)
 
 #include "main.h"
 
-void InitUserdataDirectory();
-
 boolean LoadLevelInfo(void);
+
 void LoadLevel(int);
 void SaveLevel(int);
-void LoadLevelTape(int);
-void SaveLevelTape(int);
 
-boolean CreateNewScoreFile(void);
+void LoadTape(int);
+void SaveTape(int);
+
 void LoadScore(int);
 void SaveScore(int);
 
index d9c9ba2..017adc4 100644 (file)
@@ -544,7 +544,7 @@ void GameWon()
   if (tape.recording)
   {
     TapeStop();
-    SaveLevelTape(tape.level_nr);      /* Ask to save tape */
+    SaveTape(tape.level_nr);           /* Ask to save tape */
   }
 
   if ((hi_pos=NewHiScore()) >= 0) 
index 52facad..8e60cfe 100644 (file)
@@ -65,7 +65,6 @@ void OpenAll(int argc, char *argv[])
     exit(0);
   }
 
-  InitUserdataDirectory();
   InitLevelAndPlayerInfo();
 
   InitCounter();
@@ -357,14 +356,18 @@ void InitWindow(int argc, char *argv[])
     XChangeProperty(display, window, proto_atom, XA_ATOM, 32,
                    PropModePrepend, (unsigned char *) &delete_atom, 1);
 
-  sprintf(icon_filename,"%s/%s",GFX_PATH,icon_pic.picture_filename);
+  sprintf(icon_filename, "%s/%s/%s",
+         options.base_directory, GRAPHICS_DIRECTORY,
+         icon_pic.picture_filename);
   XReadBitmapFile(display,window,icon_filename,
                  &icon_width,&icon_height,
                  &icon_pixmap,&icon_hot_x,&icon_hot_y);
   if (!icon_pixmap)
     Error(ERR_EXIT, "cannot read icon bitmap file '%s'", icon_filename);
 
-  sprintf(icon_filename,"%s/%s",GFX_PATH,icon_pic.picturemask_filename);
+  sprintf(icon_filename, "%s/%s/%s",
+         options.base_directory, GRAPHICS_DIRECTORY,
+         icon_pic.picturemask_filename);
   XReadBitmapFile(display,window,icon_filename,
                  &icon_width,&icon_height,
                  &iconmask_pixmap,&icon_hot_x,&icon_hot_y);
@@ -649,9 +652,10 @@ void LoadGfx(int pos, struct PictureFileInfo *pic)
   /* Grafik laden */
   if (pic->picture_filename)
   {
-    sprintf(basefilename,"%s%s",pic->picture_filename,picture_ext);
-    DrawInitText(basefilename,150,FC_YELLOW);
-    sprintf(filename,"%s/%s",GFX_PATH,basefilename);
+    sprintf(basefilename, "%s%s", pic->picture_filename, picture_ext);
+    DrawInitText(basefilename, 150, FC_YELLOW);
+    sprintf(filename, "%s/%s/%s",
+           options.base_directory, GRAPHICS_DIRECTORY, basefilename);
 
 #ifdef MSDOS
     rest(100);
@@ -729,9 +733,10 @@ void LoadGfx(int pos, struct PictureFileInfo *pic)
 
 #ifdef XPM_INCLUDE_FILE
 
-    sprintf(basefilename,"%s%s",pic->picture_filename,picturemask_ext);
-    DrawInitText(basefilename,150,FC_YELLOW);
-    sprintf(filename,"%s/%s",GFX_PATH,basefilename);
+    sprintf(basefilename, "%s%s", pic->picture_filename, picturemask_ext);
+    DrawInitText(basefilename, 150, FC_YELLOW);
+    sprintf(filename, "%s/%s/%s",
+           options.base_directory, GRAPHICS_DIRECTORY, basefilename);
 
 #ifdef DEBUG_TIMING
     count1 = Counter();
index 8cd26a1..be179b5 100644 (file)
@@ -50,7 +50,6 @@ char         *joystick_device_name[MAX_PLAYERS] =
   DEV_JOYSTICK_3
 };
 
-char          *level_directory = LEVEL_PATH;
 int            width, height;
 
 char          *program_name = NULL;
index d63a289..d698ffd 100644 (file)
@@ -195,7 +195,7 @@ typedef unsigned char byte;
 #define MAX_LEVDIR_FILENAME    (64+1)
 #define MAX_LEVDIR_NAME                (16+1)
 #define MAX_LEVDIR_ENTRIES     15
-#define MAX_SCORE_ENTRIES      15
+#define MAX_SCORE_ENTRIES      100
 
 #define MAX_OPTION_LEN         256
 #define MAX_FILENAME_LEN       256
@@ -213,6 +213,8 @@ struct OptionInfo
   char *display_name;
   char *server_host;
   int server_port;
+  char *base_directory;
+  char *level_directory;
   boolean serveronly;
   boolean network;
   boolean verbose;
@@ -379,7 +381,6 @@ extern int          sound_device;
 extern char           *sound_device_name;
 extern int             joystick_device;
 extern char           *joystick_device_name[];
-extern char           *level_directory;
 extern int                     width, height;
 
 extern char           *program_name;
@@ -1068,58 +1069,34 @@ extern int              num_bg_loops;
 #define EMU_BOULDERDASH                1
 #define EMU_SOKOBAN            2
 
-
 #ifndef GAME_DIR
 #define GAME_DIR               "."
 #endif
 
-#ifndef GFX_PATH
-#define GFX_PATH               GAME_DIR "/graphics"
-#endif
-#ifndef SND_PATH
-#define SND_PATH               GAME_DIR "/sounds"
-#endif
-#ifndef LEVEL_PATH
-#define LEVEL_PATH             GAME_DIR "/levels"
-#endif
-#ifndef SCORE_PATH
-#define SCORE_PATH             LEVEL_PATH
-#endif
-#ifndef NAMES_PATH
-#define NAMES_PATH             LEVEL_PATH
-#endif
-#ifndef CONFIG_PATH
-#define CONFIG_PATH            GAME_DIR
-#endif
-#ifndef JOYDAT_PATH
-#define JOYDAT_PATH            GAME_DIR
-#endif
-#ifndef SETUP_PATH
-#define SETUP_PATH             GAME_DIR
-#endif
+#define BASE_PATH              GAME_DIR
+
+#define GRAPHICS_DIRECTORY     "graphics"
+#define SOUNDS_DIRECTORY       "sounds"
+#define LEVELS_DIRECTORY       "levels"
+#define TAPES_DIRECTORY                "tapes"
+#define SCORES_DIRECTORY       "scores"
 
 #ifndef MSDOS
 #define USERDATA_DIRECTORY     ".rocksndiamonds"
-#define TAPEDATA_DIRECTORY     "tapes"
-#define SCORE_FILENAME         "ROCKS.score"
 #define LEVDIR_FILENAME                "ROCKS.levelinfo"
-#define JOYDAT_FILENAME                "ROCKS.joystick"
 #define SETUP_FILENAME         "setup"
 #define LEVELSETUP_FILENAME    "setup.level"
 #define TAPEFILE_EXTENSION     "tape"
+#define SCOREFILE_EXTENSION    "score"
 #else
 #define USERDATA_DIRECTORY     "userdata"
-#define TAPEDATA_DIRECTORY     "tapes"
-#define SCORE_FILENAME         "ROCKS.sco"
 #define LEVDIR_FILENAME                "ROCKS.lev"
-#define JOYDAT_FILENAME                "ROCKS.joy"
 #define SETUP_FILENAME         "setup"
 #define LEVELSETUP_FILENAME    "setup.lev"
 #define TAPEFILE_EXTENSION     "rec"
+#define SCOREFILE_EXTENSION    "sco"
 #endif
 
-#define JOYDAT_FILE            JOYDAT_PATH "/" JOYDAT_FILENAME
-
 #define MODE_R_ALL             (S_IRUSR | S_IRGRP | S_IROTH)
 #define MODE_W_ALL             (S_IWUSR | S_IWGRP | S_IWOTH)
 #define MODE_X_ALL             (S_IXUSR | S_IXGRP | S_IXOTH)
@@ -1133,12 +1110,10 @@ extern int              num_bg_loops;
 #define SETUP_PERMS            LEVEL_PERMS
 
 /* old cookies */
-#define NAMES_COOKIE_10                "ROCKSNDIAMONDS_NAMES_FILE_VERSION_1.0"
 #define LEVELREC_COOKIE_10     "ROCKSNDIAMONDS_LEVELREC_FILE_VERSION_1.0"
 
 #define LEVEL_COOKIE           "ROCKSNDIAMONDS_LEVEL_FILE_VERSION_1.0"
-#define SCORE_COOKIE           "ROCKSNDIAMONDS_SCORE_FILE_VERSION_1.0"
-#define NAMES_COOKIE           "ROCKSNDIAMONDS_NAMES_FILE_VERSION_1.1"
+#define SCORE_COOKIE           "ROCKSNDIAMONDS_SCORE_FILE_VERSION_1.2"
 #define LEVELDIR_COOKIE                "ROCKSNDIAMONDS_LEVELDIR_FILE_VERSION_1.0"
 #define LEVELREC_COOKIE                "ROCKSNDIAMONDS_LEVELREC_FILE_VERSION_1.2"
 #define JOYSTICK_COOKIE                "ROCKSNDIAMONDS_JOYSTICK_FILE_VERSION_1.0"
@@ -1146,7 +1121,6 @@ extern int                num_bg_loops;
 #define LEVELSETUP_COOKIE      "ROCKSNDIAMONDS_LEVELSETUP_FILE_VERSION_1.2"
 #define LEVEL_COOKIE_LEN       (strlen(LEVEL_COOKIE)+1)
 #define SCORE_COOKIE_LEN       (strlen(SCORE_COOKIE)+1)
-#define NAMES_COOKIE_LEN       (strlen(NAMES_COOKIE)+1)
 #define LEVELDIR_COOKIE_LEN    (strlen(LEVELDIR_COOKIE)+1)
 #define LEVELREC_COOKIE_LEN    (strlen(LEVELREC_COOKIE)+1)
 #define JOYSTICK_COOKIE_LEN    (strlen(JOYSTICK_COOKIE)+1)
index 7d0a7fd..c560ae4 100644 (file)
@@ -230,6 +230,8 @@ void GetOptions(char *argv[])
   options.display_name = NULL;
   options.server_host = NULL;
   options.server_port = 0;
+  options.base_directory = BASE_PATH;
+  options.level_directory = BASE_PATH "/" LEVELS_DIRECTORY;
   options.serveronly = FALSE;
   options.network = FALSE;
   options.verbose = FALSE;
@@ -273,6 +275,7 @@ void GetOptions(char *argv[])
       printf("Usage: %s [options] [server.name [port]]\n"
             "Options:\n"
             "  -d, --display machine:0       X server display\n"
+            "  -b, --basepath directory      alternative base directory\n"
             "  -l, --levels directory        alternative level directory\n"
             "  -s, --serveronly              only start network server\n"
             "  -n, --network                 network multiplayer game\n"
@@ -291,16 +294,33 @@ void GetOptions(char *argv[])
 
       printf("--display == '%s'\n", options.display_name);
     }
+    else if (strncmp(option, "-basepath", option_len) == 0)
+    {
+      if (option_arg == NULL)
+       Error(ERR_EXIT_HELP, "option '%s' requires an argument", option_str);
+
+      options.base_directory = option_arg;
+      if (option_arg == next_option)
+       options_left++;
+
+      printf("--basepath == '%s'\n", options.base_directory);
+
+      /* adjust path for level directory accordingly */
+      options.level_directory = checked_malloc(strlen(options.base_directory) +
+                                              strlen(LEVELS_DIRECTORY) + 2);
+      sprintf(options.level_directory, "%s/%s",
+             options.base_directory, LEVELS_DIRECTORY);
+    }
     else if (strncmp(option, "-levels", option_len) == 0)
     {
       if (option_arg == NULL)
        Error(ERR_EXIT_HELP, "option '%s' requires an argument", option_str);
 
-      level_directory = option_arg;
+      options.level_directory = option_arg;
       if (option_arg == next_option)
        options_left++;
 
-      printf("--levels == '%s'\n", level_directory);
+      printf("--levels == '%s'\n", options.level_directory);
     }
     else if (strncmp(option, "-network", option_len) == 0)
     {
index b09c4ce..f4f7a5a 100644 (file)
 #include <allegro.h>
 #include <time.h>
 
-// Allegro keyboard mapping
+/* some file path definitions */
+
+#define JOYDAT_PATH            GAME_DIR
+#define JOYDAT_FILENAME                "ROCKS.joy"
+#define JOYDAT_FILE            JOYDAT_PATH "/" JOYDAT_FILENAME
+
+/* Allegro keyboard mapping */
 
 #define OSD_KEY_ESC         1        /* keyboard scan codes */
 #define OSD_KEY_1           2        /* (courtesy of allegro.h) */
 
 #define OSD_MAX_KEY         115
 
-// X11 keyboard mapping
+/* X11 keyboard mapping */
 
 #define XK_KP_Enter    OSD_KEY_ENTER_PAD
 #define XK_KP_0                OSD_KEY_0_PAD
@@ -439,33 +445,33 @@ typedef union _XEvent {
 
 
 extern void XMapWindow(Display*, Window);
-//extern void XFlush(Display*);
+// extern void XFlush(Display*);
 extern Display *XOpenDisplay(char*);
-//extern char *XDisplayName(char*);
+// extern char *XDisplayName(char*);
 extern Window XCreateSimpleWindow(Display*, Window, int, int, unsigned int, unsigned int, unsigned int, unsigned long, unsigned long);
 extern int XReadBitmapFile(Display*, Drawable, char*, unsigned int*, unsigned int*, Pixmap*, int*, int*);
 extern Status XStringListToTextProperty(char**, int, XTextProperty*);
-//extern void XSetWMProperties(Display*, Window, XTextProperty*, XTextProperty*, char**, int, XSizeHints*, XWMHints*, XClassHint*);
+// extern void XSetWMProperties(Display*, Window, XTextProperty*, XTextProperty*, char**, int, XSizeHints*, XWMHints*, XClassHint*);
 extern void XFree(void*);
-//extern void XSelectInput(Display*, Window, long);
+// extern void XSelectInput(Display*, Window, long);
 extern GC XCreateGC(Display*, Drawable, unsigned long, XGCValues*);
 extern void XFillRectangle(Display*, Drawable, GC, int, int, unsigned int, unsigned int);
 extern Pixmap XCreatePixmap(Display*, Drawable, unsigned int, unsigned int, unsigned int);
-//extern int XDefaultDepth(Display*, int);
+// extern int XDefaultDepth(Display*, int);
 extern inline void XCopyArea(Display*, Drawable, Drawable, GC, int, int, unsigned int, unsigned int, int, int);
 extern int XpmReadFileToPixmap(Display*, Drawable, char*, Pixmap*, Pixmap*, XpmAttributes*);
-//extern void XFreeColors(Display*, Colormap, unsigned long*, int, unsigned long);
-//extern void XpmFreeAttributes(XpmAttributes*);
+// extern void XFreeColors(Display*, Colormap, unsigned long*, int, unsigned long);
+// extern void XpmFreeAttributes(XpmAttributes*);
 extern void XFreePixmap(Display*, Pixmap);
 extern void XFreeGC(Display*, GC);
 extern void XCloseDisplay(Display*);
 extern int XPending(Display*);
 extern void XNextEvent(Display*, XEvent*);
-//extern void XSync(Display*, Bool);
-//extern void XAutoRepeatOn(Display*);
-//extern void XAutoRepeatOff(Display*);
+// extern void XSync(Display*, Bool);
+// extern void XAutoRepeatOn(Display*);
+// extern void XAutoRepeatOff(Display*);
 extern KeySym XLookupKeysym(XKeyEvent*, int);
-//extern void XSetClipOrigin(Display*, GC, int, int);
-//extern XImage *XGetImage(Display*, Drawable, int, int, unsigned int, unsigned int, unsigned long, int);
+// extern void XSetClipOrigin(Display*, GC, int, int);
+// extern XImage *XGetImage(Display*, Drawable, int, int, unsigned int, unsigned int, unsigned long, int);
 
 BITMAP *load_gif(char *filename, RGB *pal);
index 65d1869..890f405 100644 (file)
@@ -500,7 +500,7 @@ static void Handle_OP_START_PLAYING()
   level_nr = new_level_nr;
 
   TapeErase();
-  LoadLevelTape(level_nr);
+  LoadTape(level_nr);
 
   /*
   GetPlayerConfig();
index a0a06db..139c6d9 100644 (file)
@@ -89,7 +89,7 @@ void DrawMainMenu()
 
   TapeStop();
   if (TAPE_IS_EMPTY(tape))
-    LoadLevelTape(level_nr);
+    LoadTape(level_nr);
   DrawCompleteVideoDisplay();
 
   OpenDoor(DOOR_CLOSE_1 | DOOR_OPEN_2);
@@ -168,7 +168,7 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button)
     DrawMicroLevel(MICROLEV_XPOS,MICROLEV_YPOS);
 
     TapeErase();
-    LoadLevelTape(level_nr);
+    LoadTape(level_nr);
     DrawCompleteVideoDisplay();
 
     /* needed because DrawMicroLevel() takes some time */
@@ -822,7 +822,7 @@ void HandleChooseLevel(int mx, int my, int dx, int dy, int button)
       SaveLevelSetup();
 
       TapeErase();
-      LoadLevelTape(level_nr);
+      LoadTape(level_nr);
 
       game_status = MAINMENU;
       DrawMainMenu();
@@ -849,7 +849,7 @@ void DrawHallOfFame(int pos)
   DrawText(SX+64,SY+10,"Hall Of Fame",FS_BIG,FC_YELLOW);
   sprintf(txt,"HighScores of Level %d",level_nr);
   DrawText(SX+256-strlen(txt)*7,SY+48,txt,FS_SMALL,FC_RED);
-  for(y=0;y<MAX_SCORE_ENTRIES;y++)
+  for(y=0; y<15; y++)
   {
     DrawText(SX,SY+64+y*32,".................",FS_BIG,
             (y==pos ? FC_RED : FC_GREEN));
@@ -1946,14 +1946,14 @@ void HandleVideoButtons(int mx, int my, int button)
       TapeStop();
       if (TAPE_IS_EMPTY(tape))
       {
-       LoadLevelTape(level_nr);
+       LoadTape(level_nr);
        if (TAPE_IS_EMPTY(tape))
          Request("No tape for this level !",REQ_CONFIRM);
       }
       else
       {
        if (tape.changed)
-         SaveLevelTape(tape.level_nr);
+         SaveTape(tape.level_nr);
        TapeErase();
       }
       DrawCompleteVideoDisplay();
index 8938750..e4ac24c 100644 (file)
@@ -627,7 +627,8 @@ boolean LoadSound(struct SoundInfo *snd_info)
   struct SoundHeader_8SVX *sound_header;
   unsigned char *ptr;
 
-  sprintf(filename,"%s/%s.%s",SND_PATH,snd_info->name,sound_ext);
+  sprintf(filename, "%s/%s/%s.%s",
+         options.base_directory, SOUNDS_DIRECTORY, snd_info->name, sound_ext);
 
 #ifndef MSDOS
   if (!(file=fopen(filename,"r")))