X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fmisc.c;h=9fc0cf0405cfb3bdc3e6e4308e1ddf43bfd2c092;hb=41e8d55b767c898f20c29a1b0b8d2ef8840be2f5;hp=bfc6d454d9652253e9766676960913783c469a9c;hpb=da14f69fd95c7bd5a0d70cdf4935af06f1f20a04;p=rocksndiamonds.git diff --git a/src/libgame/misc.c b/src/libgame/misc.c index bfc6d454..9fc0cf04 100644 --- a/src/libgame/misc.c +++ b/src/libgame/misc.c @@ -1,34 +1,38 @@ /*********************************************************** -* Rocks'n'Diamonds -- McDuffin Strikes Back! * +* Artsoft Retro-Game Library * *----------------------------------------------------------* -* (c) 1995-98 Artsoft Entertainment * -* Holger Schemel * -* Oststrasse 11a * -* 33604 Bielefeld * -* phone: ++49 +521 290471 * -* email: aeglos@valinor.owl.de * +* (c) 1994-2001 Artsoft Entertainment * +* Holger Schemel * +* Detmolder Strasse 189 * +* 33604 Bielefeld * +* Germany * +* e-mail: info@artsoft.org * *----------------------------------------------------------* -* misc.c * +* misc.c * ***********************************************************/ #include #include #include +/* +#include +*/ #include #include +#include +#include + +#include "platform.h" #if !defined(PLATFORM_WIN32) #include #include #endif -#include "libgame.h" - -#include "main_TMP.h" - #include "misc.h" +#include "setup.h" +#include "random.h" -#include "joystick_TMP.h" #if defined(PLATFORM_MSDOS) volatile unsigned long counter = 0; @@ -413,37 +417,6 @@ char *getStringToLower(char *s) return s_copy; } -void MarkTileDirty(int x, int y) -{ - int xx = redraw_x1 + x; - int yy = redraw_y1 + y; - - if (!redraw[xx][yy]) - redraw_tiles++; - - redraw[xx][yy] = TRUE; - redraw_mask |= REDRAW_TILES; -} - -void SetBorderElement() -{ - int x, y; - - BorderElement = EL_LEERRAUM; - - for(y=0; y[:] X server display\n" + " -b, --basepath alternative base directory\n" + " -l, --level alternative level directory\n" + " -g, --graphics alternative graphics directory\n" + " -s, --sounds alternative graphics directory\n" + " -m, --music alternative graphics directory\n" " -n, --network network multiplayer game\n" - " -v, --verbose verbose mode\n", - program_name); + " --serveronly only start network server\n" + " -v, --verbose verbose mode\n" + " --debug display debugging information\n", + program.command_basename); exit(0); } else if (strncmp(option, "-display", option_len) == 0) @@ -545,6 +520,33 @@ void GetOptions(char *argv[]) if (option_arg == next_option) options_left++; } + else if (strncmp(option, "-graphics", option_len) == 0) + { + if (option_arg == NULL) + Error(ERR_EXIT_HELP, "option '%s' requires an argument", option_str); + + options.graphics_directory = option_arg; + if (option_arg == next_option) + options_left++; + } + else if (strncmp(option, "-sounds", option_len) == 0) + { + if (option_arg == NULL) + Error(ERR_EXIT_HELP, "option '%s' requires an argument", option_str); + + options.sounds_directory = option_arg; + if (option_arg == next_option) + options_left++; + } + else if (strncmp(option, "-music", option_len) == 0) + { + if (option_arg == NULL) + Error(ERR_EXIT_HELP, "option '%s' requires an argument", option_str); + + options.music_directory = option_arg; + if (option_arg == next_option) + options_left++; + } else if (strncmp(option, "-network", option_len) == 0) { options.network = TRUE; @@ -586,16 +588,19 @@ void Error(int mode, char *format, ...) { char *process_name = ""; FILE *error = stderr; + char *newline = "\n"; /* display warnings only when running in verbose mode */ if (mode & ERR_WARN && !options.verbose) return; #if !defined(PLATFORM_UNIX) + newline = "\r\n"; + if ((error = openErrorFile()) == NULL) { - printf("Cannot write to error output file!\n"); - CloseAllAndExit(1); + printf("Cannot write to error output file!%s", newline); + program.exit_function(1); } #endif @@ -610,7 +615,7 @@ void Error(int mode, char *format, ...) { va_list ap; - fprintf(error, "%s%s: ", program_name, process_name); + fprintf(error, "%s%s: ", program.command_basename, process_name); if (mode & ERR_WARN) fprintf(error, "warning: "); @@ -619,15 +624,16 @@ void Error(int mode, char *format, ...) vfprintf(error, format, ap); va_end(ap); - fprintf(error, "\n"); + fprintf(error, "%s", newline); } if (mode & ERR_HELP) - fprintf(error, "%s: Try option '--help' for more information.\n", - program_name); + fprintf(error, "%s: Try option '--help' for more information.%s", + program.command_basename, newline); if (mode & ERR_EXIT) - fprintf(error, "%s%s: aborting\n", program_name, process_name); + fprintf(error, "%s%s: aborting%s", + program.command_basename, process_name, newline); if (error != stderr) fclose(error); @@ -637,7 +643,7 @@ void Error(int mode, char *format, ...) if (mode & ERR_FROM_SERVER) exit(1); /* child process: normal exit */ else - CloseAllAndExit(1); /* main process: clean up stuff */ + program.exit_function(1); /* main process: clean up stuff */ } } @@ -665,6 +671,36 @@ void *checked_calloc(unsigned long size) return ptr; } +void *checked_realloc(void *ptr, unsigned long size) +{ + ptr = realloc(ptr, size); + + if (ptr == NULL) + Error(ERR_EXIT, "cannot allocate %d bytes -- out of memory", size); + + return ptr; +} + +inline void swap_numbers(int *i1, int *i2) +{ + int help = *i1; + + *i1 = *i2; + *i2 = help; +} + +inline void swap_number_pairs(int *x1, int *y1, int *x2, int *y2) +{ + int help_x = *x1; + int help_y = *y1; + + *x1 = *x2; + *x2 = help_x; + + *y1 = *y2; + *y2 = help_y; +} + short getFile16BitInteger(FILE *file, int byte_order) { if (byte_order == BYTE_ORDER_BIG_ENDIAN) @@ -721,26 +757,46 @@ void putFile32BitInteger(FILE *file, int value, int byte_order) } } -void getFileChunk(FILE *file, char *chunk_buffer, int *chunk_length, - int byte_order) +boolean getFileChunk(FILE *file, char *chunk_name, int *chunk_size, + int byte_order) { - const int chunk_identifier_length = 4; + const int chunk_name_length = 4; + + /* read chunk name */ + fgets(chunk_name, chunk_name_length + 1, file); - /* read chunk identifier */ - fgets(chunk_buffer, chunk_identifier_length + 1, file); + if (chunk_size != NULL) + { + /* read chunk size */ + *chunk_size = getFile32BitInteger(file, byte_order); + } - /* read chunk length */ - *chunk_length = getFile32BitInteger(file, byte_order); + return (feof(file) || ferror(file) ? FALSE : TRUE); } -void putFileChunk(FILE *file, char *chunk_name, int chunk_length, +void putFileChunk(FILE *file, char *chunk_name, int chunk_size, int byte_order) { - /* write chunk identifier */ + /* write chunk name */ fputs(chunk_name, file); - /* write chunk length */ - putFile32BitInteger(file, chunk_length, byte_order); + if (chunk_size >= 0) + { + /* write chunk size */ + putFile32BitInteger(file, chunk_size, byte_order); + } +} + +void ReadUnusedBytesFromFile(FILE *file, unsigned long bytes) +{ + while (bytes--) + fgetc(file); +} + +void WriteUnusedBytesToFile(FILE *file, unsigned long bytes) +{ + while (bytes--) + fputc(0, file); } #define TRANSLATE_KEYSYM_TO_KEYNAME 0 @@ -1056,320 +1112,61 @@ char getCharFromKey(Key key) return letter; } -#define TRANSLATE_JOYSYMBOL_TO_JOYNAME 0 -#define TRANSLATE_JOYNAME_TO_JOYSYMBOL 1 -void translate_joyname(int *joysymbol, char **name, int mode) -{ - static struct - { - int joysymbol; - char *name; - } translate_joy[] = - { - { JOY_LEFT, "joystick_left" }, - { JOY_RIGHT, "joystick_right" }, - { JOY_UP, "joystick_up" }, - { JOY_DOWN, "joystick_down" }, - { JOY_BUTTON_1, "joystick_button_1" }, - { JOY_BUTTON_2, "joystick_button_2" }, - }; - - int i; - - if (mode == TRANSLATE_JOYSYMBOL_TO_JOYNAME) - { - *name = "[undefined]"; +/* ========================================================================= */ +/* functions only needed for non-Unix (non-command-line) systems */ +/* ========================================================================= */ - for (i=0; i<6; i++) - { - if (*joysymbol == translate_joy[i].joysymbol) - { - *name = translate_joy[i].name; - break; - } - } - } - else if (mode == TRANSLATE_JOYNAME_TO_JOYSYMBOL) - { - *joysymbol = 0; - - for (i=0; i<6; i++) - { - if (strcmp(*name, translate_joy[i].name) == 0) - { - *joysymbol = translate_joy[i].joysymbol; - break; - } - } - } -} - -char *getJoyNameFromJoySymbol(int joysymbol) -{ - char *name; - - translate_joyname(&joysymbol, &name, TRANSLATE_JOYSYMBOL_TO_JOYNAME); - return name; -} - -int getJoySymbolFromJoyName(char *name) -{ - int joysymbol; - - translate_joyname(&joysymbol, &name, TRANSLATE_JOYNAME_TO_JOYSYMBOL); - return joysymbol; -} - -int getJoystickNrFromDeviceName(char *device_name) -{ - char c; - int joystick_nr = 0; - - if (device_name == NULL || device_name[0] == '\0') - return 0; - - c = device_name[strlen(device_name) - 1]; - - if (c >= '0' && c <= '9') - joystick_nr = (int)(c - '0'); - - if (joystick_nr < 0 || joystick_nr >= MAX_PLAYERS) - joystick_nr = 0; - - return joystick_nr; -} - -/* ------------------------------------------------------------------------- */ -/* some functions to handle lists of level directories */ -/* ------------------------------------------------------------------------- */ - -struct LevelDirInfo *newLevelDirInfo() -{ - return checked_calloc(sizeof(struct LevelDirInfo)); -} - -void pushLevelDirInfo(struct LevelDirInfo **node_first, - struct LevelDirInfo *node_new) -{ - node_new->next = *node_first; - *node_first = node_new; -} - -int numLevelDirInfo(struct LevelDirInfo *node) -{ - int num = 0; - - while (node) - { - num++; - node = node->next; - } - - return num; -} - -boolean validLevelSeries(struct LevelDirInfo *node) -{ - return (node != NULL && !node->node_group && !node->parent_link); -} - -struct LevelDirInfo *getFirstValidLevelSeries(struct LevelDirInfo *node) -{ - if (node == NULL) - { - if (leveldir_first) /* start with first level directory entry */ - return getFirstValidLevelSeries(leveldir_first); - else - return NULL; - } - else if (node->node_group) /* enter level group (step down into tree) */ - return getFirstValidLevelSeries(node->node_group); - else if (node->parent_link) /* skip start entry of level group */ - { - if (node->next) /* get first real level series entry */ - return getFirstValidLevelSeries(node->next); - else /* leave empty level group and go on */ - return getFirstValidLevelSeries(node->node_parent->next); - } - else /* this seems to be a regular level series */ - return node; -} - -struct LevelDirInfo *getLevelDirInfoFirstGroupEntry(struct LevelDirInfo *node) -{ - if (node == NULL) - return NULL; - - if (node->node_parent == NULL) /* top level group */ - return leveldir_first; - else /* sub level group */ - return node->node_parent->node_group; -} - -int numLevelDirInfoInGroup(struct LevelDirInfo *node) -{ - return numLevelDirInfo(getLevelDirInfoFirstGroupEntry(node)); -} - -int posLevelDirInfo(struct LevelDirInfo *node) -{ - struct LevelDirInfo *node_cmp = getLevelDirInfoFirstGroupEntry(node); - int pos = 0; - - while (node_cmp) - { - if (node_cmp == node) - return pos; - - pos++; - node_cmp = node_cmp->next; - } - - return 0; -} - -struct LevelDirInfo *getLevelDirInfoFromPos(struct LevelDirInfo *node, int pos) -{ - struct LevelDirInfo *node_default = node; - int pos_cmp = 0; - - while (node) - { - if (pos_cmp == pos) - return node; - - pos_cmp++; - node = node->next; - } +#if !defined(PLATFORM_UNIX) - return node_default; -} +#define ERROR_FILENAME "error.out" -struct LevelDirInfo *getLevelDirInfoFromFilenameExt(struct LevelDirInfo *node, - char *filename) +void initErrorFile() { - if (filename == NULL) - return NULL; - - while (node) - { - if (node->node_group) - { - struct LevelDirInfo *node_group; - - node_group = getLevelDirInfoFromFilenameExt(node->node_group, filename); - - if (node_group) - return node_group; - } - else if (!node->parent_link) - { - if (strcmp(filename, node->filename) == 0) - return node; - } + char *filename; - node = node->next; - } + InitUserDataDirectory(); - return NULL; + filename = getPath2(getUserDataDir(), ERROR_FILENAME); + unlink(filename); + free(filename); } -struct LevelDirInfo *getLevelDirInfoFromFilename(char *filename) +FILE *openErrorFile() { - return getLevelDirInfoFromFilenameExt(leveldir_first, filename); -} - -void dumpLevelDirInfo(struct LevelDirInfo *node, int depth) -{ - int i; - - while (node) - { - for (i=0; ifilename); + char *filename; + FILE *error_file; - if (node->node_group != NULL) - dumpLevelDirInfo(node->node_group, depth + 1); + filename = getPath2(getUserDataDir(), ERROR_FILENAME); + error_file = fopen(filename, MODE_APPEND); + free(filename); - node = node->next; - } + return error_file; } -void sortLevelDirInfo(struct LevelDirInfo **node_first, - int (*compare_function)(const void *, const void *)) +void dumpErrorFile() { - int num_nodes = numLevelDirInfo(*node_first); - struct LevelDirInfo **sort_array; - struct LevelDirInfo *node = *node_first; - int i = 0; + char *filename; + FILE *error_file; - if (num_nodes == 0) - return; + filename = getPath2(getUserDataDir(), ERROR_FILENAME); + error_file = fopen(filename, MODE_READ); + free(filename); - /* allocate array for sorting structure pointers */ - sort_array = checked_calloc(num_nodes * sizeof(struct LevelDirInfo *)); - - /* writing structure pointers to sorting array */ - while (i < num_nodes && node) /* double boundary check... */ + if (error_file != NULL) { - sort_array[i] = node; + while (!feof(error_file)) + fputc(fgetc(error_file), stderr); - i++; - node = node->next; + fclose(error_file); } - - /* sorting the structure pointers in the sorting array */ - qsort(sort_array, num_nodes, sizeof(struct LevelDirInfo *), - compare_function); - - /* update the linkage of list elements with the sorted node array */ - for (i=0; inext = sort_array[i + 1]; - sort_array[num_nodes - 1]->next = NULL; - - /* update the linkage of the main list anchor pointer */ - *node_first = sort_array[0]; - - free(sort_array); - - /* now recursively sort the level group structures */ - node = *node_first; - while (node) - { - if (node->node_group != NULL) - sortLevelDirInfo(&node->node_group, compare_function); - - node = node->next; - } -} - -inline void swap_numbers(int *i1, int *i2) -{ - int help = *i1; - - *i1 = *i2; - *i2 = help; -} - -inline void swap_number_pairs(int *x1, int *y1, int *x2, int *y2) -{ - int help_x = *x1; - int help_y = *y1; - - *x1 = *x2; - *x2 = help_x; - - *y1 = *y2; - *y2 = help_y; } +#endif -/* ------------------------------------------------------------------------- */ +/* ========================================================================= */ /* the following is only for debugging purpose and normally not used */ -/* ------------------------------------------------------------------------- */ +/* ========================================================================= */ #define DEBUG_NUM_TIMESTAMPS 3