/* int2str() returns a number converted to a string;
the used memory is static, but will be overwritten by later calls,
so if you want to save the result, copy it to a private string buffer;
/* int2str() returns a number converted to a string;
the used memory is static, but will be overwritten by later calls,
so if you want to save the result, copy it to a private string buffer;
+/* something similar to "int2str()" above, but allocates its own memory
+ and has a different interface; we cannot use "itoa()", because this
+ seems to be already defined when cross-compiling to the win32 target */
+
+char *i_to_a(unsigned int i)
+{
+ static char *a = NULL;
+
+ checked_free(a);
+
+ if (i > 2147483647) /* yes, this is a kludge */
+ i = 2147483647;
+
+ a = checked_malloc(10 + 1);
+
+ sprintf(a, "%d", i);
+
+ return a;
+}
+
+
+/* calculate base-2 logarithm of argument (rounded down to integer;
+ this function returns the number of the highest bit set in argument) */
+
+int log_2(unsigned int x)
+{
+ int e = 0;
+
+ while ((1 << e) < x)
+ {
+ x -= (1 << e); /* for rounding down (rounding up: remove this line) */
+ e++;
+ }
+
+ return e;
+}
+
+
-#if 0
-unsigned int SimpleRND(unsigned int max)
-{
- return (random_linux_libc(RND_FREE) % max);
-}
-
-unsigned int InitSimpleRND(long seed)
-{
- if (seed == NEW_RANDOMIZE)
- {
- struct timeval current_time;
-
- gettimeofday(¤t_time, NULL);
- seed = (long)current_time.tv_usec;
- }
-
- srandom_linux_libc(RND_FREE, (unsigned int) seed);
-
- return (unsigned int) seed;
-}
-
-unsigned int RND(unsigned int max)
-{
- return (random_linux_libc(RND_GAME) % max);
-}
-
-unsigned int InitRND(long seed)
-{
- if (seed == NEW_RANDOMIZE)
- {
- struct timeval current_time;
-
- gettimeofday(¤t_time, NULL);
- seed = (long)current_time.tv_usec;
- }
-
- srandom_linux_libc(RND_GAME, (unsigned int) seed);
-
- return (unsigned int) seed;
-}
-#endif
-
-static void printUsage()
-{
- 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"
- " --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"
- " \"dump level FILE\" dump level data from FILE\n"
- " \"dump tape FILE\" dump tape data from FILE\n"
- " \"autoplay LEVELDIR\" play level tapes for LEVELDIR\n"
- "\n",
- program.command_basename);
-}
-
-void GetOptions(char *argv[])
+void GetOptions(char *argv[], void (*print_usage_function)(void))
+ options.graphics_directory =
+ getPath2(options.ro_base_directory, GRAPHICS_DIRECTORY);
+ options.sounds_directory =
+ getPath2(options.ro_base_directory, SOUNDS_DIRECTORY);
+ options.music_directory =
+ getPath2(options.ro_base_directory, MUSIC_DIRECTORY);
+ options.docs_directory =
+ getPath2(options.ro_base_directory, DOCS_DIRECTORY);
- int version_major, version_minor, version_patch, version_release;
-
- version_major = fgetc(file);
- version_minor = fgetc(file);
- version_patch = fgetc(file);
- version_release = fgetc(file);
+ int version_major = fgetc(file);
+ int version_minor = fgetc(file);
+ int version_patch = fgetc(file);
+ int version_build = fgetc(file);
- fputc(version_major, file);
- fputc(version_minor, file);
- fputc(version_patch, file);
- fputc(version_release, file);
+ fputc(version_major, file);
+ fputc(version_minor, file);
+ fputc(version_patch, file);
+ fputc(version_build, file);
- { "0", "zero", "null", },
- { "1", "one", "first" },
- { "2", "two", "second" },
- { "3", "three", "third" },
- { "4", "four", "fourth" },
- { "5", "five", "fifth" },
- { "6", "six", "sixth" },
- { "7", "seven", "seventh" },
- { "8", "eight", "eighth" },
- { "9", "nine", "ninth" },
- { "10", "ten", "tenth" },
- { "11", "eleven", "eleventh" },
- { "12", "twelve", "twelfth" },
+ { "0", "zero", "null", },
+ { "1", "one", "first" },
+ { "2", "two", "second" },
+ { "3", "three", "third" },
+ { "4", "four", "fourth" },
+ { "5", "five", "fifth" },
+ { "6", "six", "sixth" },
+ { "7", "seven", "seventh" },
+ { "8", "eight", "eighth" },
+ { "9", "nine", "ninth" },
+ { "10", "ten", "tenth" },
+ { "11", "eleven", "eleventh" },
+ { "12", "twelve", "twelfth" },
+
+ { NULL, NULL, NULL },
- if (strlen(filename) > 4 &&
- strcmp(&filename[strlen(filename) - 4], ".pcx") == 0)
+ static char *basename_lower = NULL;
+ int basename_length, prefix_length;
+
+ checked_free(basename_lower);
+
+ if (basename == NULL || prefix == NULL)
+ return FALSE;
+
+ basename_lower = getStringToLower(basename);
+ basename_length = strlen(basename_lower);
+ prefix_length = strlen(prefix);
+
+ if (basename_length > prefix_length + 1 &&
+ basename_lower[prefix_length] == '.' &&
+ strncmp(basename_lower, prefix, prefix_length) == 0)
- if (strlen(basename) > 4 &&
- strcmp(&basename[strlen(basename) - 4], ".wav") == 0)
+ static char *basename_lower = NULL;
+ int basename_length, suffix_length;
+
+ checked_free(basename_lower);
+
+ if (basename == NULL || suffix == NULL)
+ return FALSE;
+
+ basename_lower = getStringToLower(basename);
+ basename_length = strlen(basename_lower);
+ suffix_length = strlen(suffix);
+
+ if (basename_length > suffix_length + 1 &&
+ basename_lower[basename_length - suffix_length - 1] == '.' &&
+ strcmp(&basename_lower[basename_length - suffix_length], suffix) == 0)
-boolean FileIsMusic(char *basename)
+boolean FileIsGraphic(char *filename)
+{
+ char *basename = strrchr(filename, '/');
+
+ basename = (basename != NULL ? basename + 1 : filename);
+
+ return fileHasSuffix(basename, "pcx");
+}
+
+boolean FileIsSound(char *filename)
+{
+ char *basename = strrchr(filename, '/');
+
+ basename = (basename != NULL ? basename + 1 : filename);
+
+ return fileHasSuffix(basename, "wav");
+}
+
+boolean FileIsMusic(char *filename)
- if (strlen(basename) > 4 &&
- (strcmp(&basename[strlen(basename) - 4], ".mod") == 0 ||
- strcmp(&basename[strlen(basename) - 4], ".MOD") == 0 ||
- strncmp(basename, "mod.", 4) == 0 ||
- strncmp(basename, "MOD.", 4) == 0))
+ if (fileHasPrefix(basename, "mod") ||
+ fileHasSuffix(basename, "mod") ||
+ fileHasSuffix(basename, "s3m") ||
+ fileHasSuffix(basename, "it") ||
+ fileHasSuffix(basename, "xm") ||
+ fileHasSuffix(basename, "midi") ||
+ fileHasSuffix(basename, "mid") ||
+ fileHasSuffix(basename, "mp3") ||
+ fileHasSuffix(basename, "ogg"))
{
result = (strcmp(value, "left") == 0 ? MV_LEFT :
strcmp(value, "right") == 0 ? MV_RIGHT :
strcmp(value, "up") == 0 ? MV_UP :
strcmp(value, "down") == 0 ? MV_DOWN : MV_NO_MOVING);
}
{
result = (strcmp(value, "left") == 0 ? MV_LEFT :
strcmp(value, "right") == 0 ? MV_RIGHT :
strcmp(value, "up") == 0 ? MV_UP :
strcmp(value, "down") == 0 ? MV_DOWN : MV_NO_MOVING);
}
- else if (strcmp(token, ".anim_mode") == 0)
- {
- result = (string_has_parameter(value, "loop") ? ANIM_LOOP :
- string_has_parameter(value, "linear") ? ANIM_LINEAR :
- string_has_parameter(value, "pingpong") ? ANIM_PINGPONG :
- string_has_parameter(value, "pingpong2") ? ANIM_PINGPONG2 :
- string_has_parameter(value, "random") ? ANIM_RANDOM :
- string_has_parameter(value, "none") ? ANIM_NONE :
- ANIM_LOOP);
+ else if (strcmp(suffix, ".anim_mode") == 0)
+ {
+ result = (string_has_parameter(value, "none") ? ANIM_NONE :
+ string_has_parameter(value, "loop") ? ANIM_LOOP :
+ string_has_parameter(value, "linear") ? ANIM_LINEAR :
+ string_has_parameter(value, "pingpong") ? ANIM_PINGPONG :
+ string_has_parameter(value, "pingpong2") ? ANIM_PINGPONG2 :
+ string_has_parameter(value, "random") ? ANIM_RANDOM :
+ string_has_parameter(value, "horizontal") ? ANIM_HORIZONTAL :
+ string_has_parameter(value, "vertical") ? ANIM_VERTICAL :
+ ANIM_DEFAULT);
+ /* separate valid (defined) from empty (undefined) config token values */
+ valid_file_hash = newSetupFileHash();
+ empty_file_hash = newSetupFileHash();
+ BEGIN_HASH_ITERATION(setup_file_hash, itr)
+ {
+ char *value = HASH_ITERATION_VALUE(itr);
+
+ setHashEntry(*value ? valid_file_hash : empty_file_hash,
+ HASH_ITERATION_TOKEN(itr), value);
+ }
+ END_HASH_ITERATION(setup_file_hash, itr)
+
+ /* at this point, we do not need the setup file hash anymore -- free it */
+ freeSetupFileHash(setup_file_hash);
+
- if (strcmp(HASH_ITERATION_VALUE(itr), known_token_value) != 0)
- setHashEntry(extra_file_hash,
- HASH_ITERATION_TOKEN(itr), HASH_ITERATION_VALUE(itr));
+ char *value = HASH_ITERATION_VALUE(itr);
+
+ if (strcmp(value, known_token_value) != 0)
+ setHashEntry(extra_file_hash, HASH_ITERATION_TOKEN(itr), value);
+ if (undefined_values_found)
+ {
+ Error(ERR_RETURN_LINE, "-");
+ Error(ERR_RETURN, "warning: undefined values found in config file:");
+ Error(ERR_RETURN, "- config file: '%s'", filename);
+
+ for (list = setup_file_list; list != NULL; list = list->next)
+ {
+ char *value = getHashEntry(empty_file_hash, list->token);
+
+ if (value != NULL)
+ Error(ERR_RETURN, "- undefined value for token: '%s'", list->token);
+ }
+
+ Error(ERR_RETURN_LINE, "-");
+ }
+