version number set to 4.0.0.0 RC1
[rocksndiamonds.git] / src / main.c
index 94c442547aa4a9bcd7d8493db46ea74b7ce4a553..c33369729d47972a43a70f223f99cb7df4d3285e 100644 (file)
@@ -16,6 +16,7 @@
 #include "game.h"
 #include "tape.h"
 #include "tools.h"
+#include "files.h"
 #include "events.h"
 #include "config.h"
 
@@ -30,6 +31,7 @@ DrawBuffer           *fieldbuffer;
 DrawBuffer            *drawto_field;
 
 int                    game_status = -1;
+boolean                        game_status_last_screen = -1;
 boolean                        level_editor_test_game = FALSE;
 boolean                        network_playing = FALSE;
 
@@ -40,9 +42,6 @@ SDL_Thread           *server_thread;
 
 int                    key_joystick_mapping = 0;
 
-boolean                        redraw[2 + MAX_LEV_FIELDX + 2][2 + MAX_LEV_FIELDY + 2];
-int                    redraw_x1 = 0, redraw_y1 = 0;
-
 short                  Feld[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 short                  MovPos[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 short                  MovDir[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
@@ -85,18 +84,28 @@ int                 ActiveFont[NUM_FONTS];
 int                    lev_fieldx, lev_fieldy;
 int                    scroll_x, scroll_y;
 
-int                    WIN_XSIZE = 672, WIN_YSIZE = 560;
-int                    SCR_FIELDX = 17, SCR_FIELDY = 17;
+int                    WIN_XSIZE = WIN_XSIZE_DEFAULT;
+int                    WIN_YSIZE = WIN_YSIZE_DEFAULT;
+
+int                    SCR_FIELDX = SCR_FIELDX_DEFAULT;
+int                    SCR_FIELDY = SCR_FIELDY_DEFAULT;
+
 int                    REAL_SX = 6, REAL_SY = 6;
 int                    SX = 8, SY = 8;
 int                    DX = 566, DY = 60;
 int                    VX = 566, VY = 400;
 int                    EX = 566, EY = 356;
 int                    dDX, dDY;
-int                    FULL_SXSIZE = 2 + 17 * TILEX + 2; /* 2 + SXSIZE + 2 */
-int                    FULL_SYSIZE = 2 + 17 * TILEY + 2; /* 2 + SYSIZE + 2 */
-int                    SXSIZE = 17 * TILEX;    /* SCR_FIELDX * TILEX */
-int                    SYSIZE = 17 * TILEY;    /* SCR_FIELDY * TILEY */
+
+int                    FULL_SXSIZE = 2 + SXSIZE_DEFAULT + 2;
+int                    FULL_SYSIZE = 2 + SYSIZE_DEFAULT + 2;
+int                    SXSIZE = SXSIZE_DEFAULT;
+int                    SYSIZE = SYSIZE_DEFAULT;
+
+int                    FADE_SX = 6, FADE_SY = 6;
+int                    FADE_SXSIZE = 2 + SXSIZE_DEFAULT + 2;
+int                    FADE_SYSIZE = 2 + SXSIZE_DEFAULT + 2;
+
 int                    DXSIZE = 100;
 int                    DYSIZE = 280;
 int                    VXSIZE = 100;
@@ -137,9 +146,17 @@ struct ViewportInfo        viewport;
 struct TitleFadingInfo fading;
 struct TitleFadingInfo title_initial_default;
 struct TitleFadingInfo title_default;
+struct TitleMessageInfo        titlescreen_initial_default;
+struct TitleMessageInfo        titlescreen_initial_first[MAX_NUM_TITLE_IMAGES];
+struct TitleMessageInfo        titlescreen_initial[MAX_NUM_TITLE_IMAGES];
+struct TitleMessageInfo        titlescreen_default;
+struct TitleMessageInfo        titlescreen_first[MAX_NUM_TITLE_IMAGES];
+struct TitleMessageInfo        titlescreen[MAX_NUM_TITLE_IMAGES];
 struct TitleMessageInfo        titlemessage_initial_default;
+struct TitleMessageInfo        titlemessage_initial_first[MAX_NUM_TITLE_MESSAGES];
 struct TitleMessageInfo        titlemessage_initial[MAX_NUM_TITLE_MESSAGES];
 struct TitleMessageInfo        titlemessage_default;
+struct TitleMessageInfo        titlemessage_first[MAX_NUM_TITLE_MESSAGES];
 struct TitleMessageInfo        titlemessage[MAX_NUM_TITLE_MESSAGES];
 struct TitleMessageInfo        readme;
 struct InitInfo                init, init_last;
@@ -5423,6 +5440,14 @@ struct ElementActionInfo element_action_info[NUM_ACTIONS + 1 + 1] =
   { ".page[30]",               ACTION_PAGE_30,                 FALSE   },
   { ".page[31]",               ACTION_PAGE_31,                 FALSE   },
   { ".page[32]",               ACTION_PAGE_32,                 FALSE   },
+  { ".part_1",                 ACTION_PART_1,                  FALSE   },
+  { ".part_2",                 ACTION_PART_2,                  FALSE   },
+  { ".part_3",                 ACTION_PART_3,                  FALSE   },
+  { ".part_4",                 ACTION_PART_4,                  FALSE   },
+  { ".part_5",                 ACTION_PART_5,                  FALSE   },
+  { ".part_6",                 ACTION_PART_6,                  FALSE   },
+  { ".part_7",                 ACTION_PART_7,                  FALSE   },
+  { ".part_8",                 ACTION_PART_8,                  FALSE   },
   { ".other",                  ACTION_OTHER,                   FALSE   },
 
   /* empty suffix always matches -- check as last entry in InitSoundInfo() */
@@ -5450,7 +5475,17 @@ struct SpecialSuffixInfo special_suffix_info[NUM_SPECIAL_GFX_ARGS + 1 + 1] =
   { ".[DEFAULT]",              GFX_SPECIAL_ARG_DEFAULT,                },
   { ".LOADING",                        GFX_SPECIAL_ARG_LOADING,                },
   { ".TITLE_INITIAL",          GFX_SPECIAL_ARG_TITLE_INITIAL,          },
+  { ".TITLE_INITIAL_1",                GFX_SPECIAL_ARG_TITLE_INITIAL_1,        },
+  { ".TITLE_INITIAL_2",                GFX_SPECIAL_ARG_TITLE_INITIAL_2,        },
+  { ".TITLE_INITIAL_3",                GFX_SPECIAL_ARG_TITLE_INITIAL_3,        },
+  { ".TITLE_INITIAL_4",                GFX_SPECIAL_ARG_TITLE_INITIAL_4,        },
+  { ".TITLE_INITIAL_5",                GFX_SPECIAL_ARG_TITLE_INITIAL_5,        },
   { ".TITLE",                  GFX_SPECIAL_ARG_TITLE,                  },
+  { ".TITLE_1",                        GFX_SPECIAL_ARG_TITLE_1,                },
+  { ".TITLE_2",                        GFX_SPECIAL_ARG_TITLE_2,                },
+  { ".TITLE_3",                        GFX_SPECIAL_ARG_TITLE_3,                },
+  { ".TITLE_4",                        GFX_SPECIAL_ARG_TITLE_4,                },
+  { ".TITLE_5",                        GFX_SPECIAL_ARG_TITLE_5,                },
   { ".MAIN",                   GFX_SPECIAL_ARG_MAIN,                   },
   { ".LEVELS",                 GFX_SPECIAL_ARG_LEVELS                  },
   { ".LEVELNR",                        GFX_SPECIAL_ARG_LEVELNR                 },
@@ -5464,6 +5499,13 @@ struct SpecialSuffixInfo special_suffix_info[NUM_SPECIAL_GFX_ARGS + 1 + 1] =
   { ".PANEL",                  GFX_SPECIAL_ARG_PANEL,                  },
   { ".PREVIEW",                        GFX_SPECIAL_ARG_PREVIEW,                },
   { ".CRUMBLED",               GFX_SPECIAL_ARG_CRUMBLED,               },
+  { ".MAINONLY",               GFX_SPECIAL_ARG_MAINONLY,               },
+  { ".TYPENAME",               GFX_SPECIAL_ARG_TYPENAME,               },
+  { ".SUBMENU",                        GFX_SPECIAL_ARG_SUBMENU,                },
+  { ".MENU",                   GFX_SPECIAL_ARG_MENU,                   },
+  { ".TOONS",                  GFX_SPECIAL_ARG_TOONS,                  },
+  { ".FADING",                 GFX_SPECIAL_ARG_FADING,                 },
+  { ".QUIT",                   GFX_SPECIAL_ARG_QUIT,                   },
 
   /* empty suffix always matches -- check as last entry in InitMusicInfo() */
   { "",                                GFX_SPECIAL_ARG_DEFAULT,                },
@@ -5511,11 +5553,14 @@ struct FontInfo font_info[NUM_FONTS + 1] =
   { "font.input_2.active"      },
   { "font.input_1"             },
   { "font.input_2"             },
+  { "font.option_off_narrow"   },
   { "font.option_off"          },
+  { "font.option_on_narrow"    },
   { "font.option_on"           },
   { "font.value_1"             },
   { "font.value_2"             },
   { "font.value_old"           },
+  { "font.value_narrow"                },
   { "font.level_number.active" },
   { "font.level_number"                },
   { "font.tape_recorder"       },
@@ -5526,6 +5571,31 @@ struct FontInfo font_info[NUM_FONTS + 1] =
   { NULL                       }
 };
 
+struct GlobalAnimInfo global_anim_info[NUM_GLOBAL_ANIM_TOKENS + 1] =
+{
+  /* (real) graphic definitions used to define animation graphics */
+  { "global.anim_1.gfx",       },
+  { "global.anim_2.gfx",       },
+  { "global.anim_3.gfx",       },
+  { "global.anim_4.gfx",       },
+  { "global.anim_5.gfx",       },
+  { "global.anim_6.gfx",       },
+  { "global.anim_7.gfx",       },
+  { "global.anim_8.gfx",       },
+
+  /* (dummy) graphic definitions used to define animation controls */
+  { "global.anim_1",           },
+  { "global.anim_2",           },
+  { "global.anim_3",           },
+  { "global.anim_4",           },
+  { "global.anim_5",           },
+  { "global.anim_6",           },
+  { "global.anim_7",           },
+  { "global.anim_8",           },
+
+  { NULL                       }
+};
+
 
 /* ------------------------------------------------------------------------- */
 /* music token prefix definitions                                            */
@@ -5545,90 +5615,151 @@ struct MusicPrefixInfo music_prefix_info[NUM_MUSIC_PREFIXES + 1] =
 
 static void print_usage()
 {
-  printf("\n"
-        "Usage: %s [OPTION]... [HOSTNAME [PORT]]\n"
-        "\n"
-        "Options:\n"
-        "  -d, --display HOSTNAME[:SCREEN]  specify X server display\n"
-        "  -b, --basepath DIRECTORY         alternative base DIRECTORY\n"
-        "  -l, --level DIRECTORY            alternative level DIRECTORY\n"
-        "  -g, --graphics DIRECTORY         alternative graphics DIRECTORY\n"
-        "  -s, --sounds DIRECTORY           alternative sounds DIRECTORY\n"
-        "  -m, --music DIRECTORY            alternative music DIRECTORY\n"
-        "  -n, --network                    network multiplayer game\n"
-        "      --serveronly                 only start network server\n"
-        "  -v, --verbose                    verbose mode\n"
-        "  -V, --version                    show program version\n"
-        "      --debug                      display debugging information\n"
-        "  -e, --execute COMMAND            execute batch COMMAND\n"
-        "\n"
-        "Valid commands for '--execute' option:\n"
-        "  \"print graphicsinfo.conf\"        print default graphics config\n"
-        "  \"print soundsinfo.conf\"          print default sounds config\n"
-        "  \"print musicinfo.conf\"           print default music config\n"
-        "  \"print editorsetup.conf\"         print default editor config\n"
-        "  \"print helpanim.conf\"            print default helpanim config\n"
-        "  \"print helptext.conf\"            print default helptext config\n"
-        "  \"dump level FILE\"                dump level data from FILE\n"
-        "  \"dump tape FILE\"                 dump tape data from FILE\n"
-        "  \"autoplay LEVELDIR [NR ...]\"     play level tapes for LEVELDIR\n"
-        "  \"convert LEVELDIR [NR]\"          convert levels in LEVELDIR\n"
-        "  \"create images DIRECTORY\"        write BMP images to DIRECTORY\n"
-        "\n",
-        program.command_basename);
+  Print("\n"
+       "Usage: %s [OPTION]... [HOSTNAME [PORT]]\n"
+       "\n"
+       "Options:\n"
+       "  -b, --basepath DIRECTORY         alternative base DIRECTORY\n"
+       "  -l, --level DIRECTORY            alternative level DIRECTORY\n"
+       "  -g, --graphics DIRECTORY         alternative graphics DIRECTORY\n"
+       "  -s, --sounds DIRECTORY           alternative sounds DIRECTORY\n"
+       "  -m, --music DIRECTORY            alternative music DIRECTORY\n"
+       "  -n, --network                    network multiplayer game\n"
+       "      --serveronly                 only start network server\n"
+       "  -v, --verbose                    verbose mode\n"
+       "  -V, --version                    show program version\n"
+       "      --debug                      display debugging information\n"
+       "  -e, --execute COMMAND            execute batch COMMAND\n"
+       "\n"
+       "Valid commands for '--execute' option:\n"
+       "  \"print graphicsinfo.conf\"        print default graphics config\n"
+       "  \"print soundsinfo.conf\"          print default sounds config\n"
+       "  \"print musicinfo.conf\"           print default music config\n"
+       "  \"print editorsetup.conf\"         print default editor config\n"
+       "  \"print helpanim.conf\"            print default helpanim config\n"
+       "  \"print helptext.conf\"            print default helptext config\n"
+       "  \"dump level FILE\"                dump level data from FILE\n"
+       "  \"dump tape FILE\"                 dump tape data from FILE\n"
+       "  \"autotest LEVELDIR [NR ...]\"     test level tapes for LEVELDIR\n"
+       "  \"autoplay LEVELDIR [NR ...]\"     play level tapes for LEVELDIR\n"
+       "  \"autoffwd LEVELDIR [NR ...]\"     ffwd level tapes for LEVELDIR\n"
+       "  \"convert LEVELDIR [NR]\"          convert levels in LEVELDIR\n"
+       "  \"create images DIRECTORY\"        write BMP images to DIRECTORY\n"
+       "  \"create CE image DIRECTORY\"      write BMP image to DIRECTORY\n"
+       "\n",
+       program.command_basename);
 }
 
 static void print_version()
 {
-  printf("%s %d.%d.%d.%d\n",
-        PROGRAM_TITLE_STRING,
-        PROGRAM_VERSION_MAJOR,
-        PROGRAM_VERSION_MINOR,
-        PROGRAM_VERSION_PATCH,
-        PROGRAM_VERSION_BUILD);
+  Print("%s %d.%d.%d.%d%s\n",
+       PROGRAM_TITLE_STRING,
+       PROGRAM_VERSION_MAJOR,
+       PROGRAM_VERSION_MINOR,
+       PROGRAM_VERSION_PATCH,
+       PROGRAM_VERSION_BUILD,
+       PROGRAM_VERSION_EXTRA);
 
   if (options.debug)
   {
     SDL_version sdl_version;
 
     SDL_VERSION(&sdl_version);
-    printf("- SDL %d.%d.%d\n",
-          sdl_version.major,
-          sdl_version.minor,
-          sdl_version.patch);
+    Print("- SDL %d.%d.%d\n",
+         sdl_version.major,
+         sdl_version.minor,
+         sdl_version.patch);
 
     SDL_IMAGE_VERSION(&sdl_version);
-    printf("- SDL_image %d.%d.%d\n",
-          sdl_version.major,
-          sdl_version.minor,
-          sdl_version.patch);
+    Print("- SDL_image %d.%d.%d\n",
+         sdl_version.major,
+         sdl_version.minor,
+         sdl_version.patch);
 
     SDL_MIXER_VERSION(&sdl_version);
-    printf("- SDL_mixer %d.%d.%d\n",
-          sdl_version.major,
-          sdl_version.minor,
-          sdl_version.patch);
+    Print("- SDL_mixer %d.%d.%d\n",
+         sdl_version.major,
+         sdl_version.minor,
+         sdl_version.patch);
 
     SDL_NET_VERSION(&sdl_version);
-    printf("- SDL_net %d.%d.%d\n",
-          sdl_version.major,
-          sdl_version.minor,
-          sdl_version.patch);
+    Print("- SDL_net %d.%d.%d\n",
+         sdl_version.major,
+         sdl_version.minor,
+         sdl_version.patch);
   }
 }
 
+static void InitProgramConfig(char *command_filename)
+{
+  char *program_title = PROGRAM_TITLE_STRING;
+  char *program_icon_file = PROGRAM_ICON_FILENAME;
+  char *config_filename = getProgramConfigFilename(command_filename);
+  char *userdata_basename = getBaseNameNoSuffix(command_filename);
+  char *userdata_subdir;
+  char *userdata_subdir_unix;
+
+  // read default program config, if existing
+  if (fileExists(config_filename))
+  {
+    // if program config file exists, derive Unix user data directory from it
+    userdata_basename = getBaseName(config_filename);
+
+    if (strSuffix(userdata_basename, ".conf"))
+      userdata_basename[strlen(userdata_basename) - 5] = '\0';
+
+    LoadSetupFromFilename(config_filename);
+  }
+
+  // set user data directory for Linux/Unix (but not Mac OS X)
+  userdata_subdir_unix = getStringCat2(".", userdata_basename);
+
+  // set program title from potentially redefined program title
+  if (setup.internal.program_title != NULL &&
+      strlen(setup.internal.program_title) > 0)
+    program_title = getStringCopy(setup.internal.program_title);
+
+  // set program icon file from potentially redefined program icon file
+  if (setup.internal.program_icon_file != NULL &&
+      strlen(setup.internal.program_icon_file) > 0)
+    program_icon_file = getStringCopy(setup.internal.program_icon_file);
+
+#if defined(PLATFORM_WIN32) || defined(PLATFORM_MACOSX)
+  userdata_subdir = program_title;
+#elif defined(PLATFORM_UNIX)
+  userdata_subdir = userdata_subdir_unix;
+#else
+  userdata_subdir = USERDATA_DIRECTORY_OTHER;
+#endif
+
+  // set default window size (only relevant on program startup)
+  if (setup.internal.default_window_width  != 0 &&
+      setup.internal.default_window_height != 0)
+  {
+    WIN_XSIZE = setup.internal.default_window_width;
+    WIN_YSIZE = setup.internal.default_window_height;
+  }
+
+  InitProgramInfo(command_filename,
+                 config_filename,
+                 userdata_subdir,
+                 program_title,
+                 program_title,
+                 program_icon_file,
+                 COOKIE_PREFIX,
+                 GAME_VERSION_ACTUAL);
+}
+
 int main(int argc, char *argv[])
 {
-  InitProgramInfo(argv[0], USERDATA_DIRECTORY, USERDATA_DIRECTORY_UNIX,
-                 PROGRAM_TITLE_STRING, ICON_TITLE_STRING, SDL_ICON_FILENAME,
-                 COOKIE_PREFIX, GAME_VERSION_ACTUAL);
+  InitProgramConfig(argv[0]);
 
   InitWindowTitleFunction(getWindowTitleString);
   InitExitMessageFunction(DisplayExitMessage);
   InitExitFunction(CloseAllAndExit);
   InitPlatformDependentStuff();
 
-  GetOptions(argv, print_usage, print_version);
+  GetOptions(argc, argv, print_usage, print_version);
   OpenAll();
 
   EventLoop();