X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fmisc.c;h=1ea2a2edb823e909267815575b6eb3121ddb6dba;hb=8cea50fbd1b74a2bc164a79cbd26bdbb3abd6689;hp=c04c256dd4989c54d363fb06fb958e90732f581b;hpb=f2d0f3fed679ea3573f51aa298adce2d9a78d8be;p=rocksndiamonds.git diff --git a/src/libgame/misc.c b/src/libgame/misc.c index c04c256d..1ea2a2ed 100644 --- a/src/libgame/misc.c +++ b/src/libgame/misc.c @@ -33,32 +33,61 @@ #include "image.h" -/* ------------------------------------------------------------------------- */ +/* ========================================================================= */ /* some generic helper functions */ +/* ========================================================================= */ + /* ------------------------------------------------------------------------- */ +/* platform independent wrappers for printf() et al. (newline aware) */ +/* ------------------------------------------------------------------------- */ + +static void vfprintf_newline(FILE *stream, char *format, va_list ap) +{ + char *newline = STRING_NEWLINE; + + vfprintf(stream, format, ap); + + fprintf(stream, "%s", newline); +} -void fprintf_line(FILE *stream, char *line_string, int line_length) +static void fprintf_newline(FILE *stream, char *format, ...) +{ + if (format) + { + va_list ap; + + va_start(ap, format); + vfprintf_newline(stream, format, ap); + va_end(ap); + } +} + +void fprintf_line(FILE *stream, char *line_chars, int line_length) { int i; for (i = 0; i < line_length; i++) - fprintf(stream, "%s", line_string); + fprintf(stream, "%s", line_chars); - fprintf(stream, "\n"); + fprintf_newline(stream, ""); } -void printf_line(char *line_string, int line_length) +void printf_line(char *line_chars, int line_length) { - fprintf_line(stdout, line_string, line_length); + fprintf_line(stdout, line_chars, line_length); } -void printf_line_with_prefix(char *prefix, char *line_string, int line_length) +void printf_line_with_prefix(char *prefix, char *line_chars, int line_length) { fprintf(stdout, "%s", prefix); - fprintf_line(stdout, line_string, line_length); + fprintf_line(stdout, line_chars, line_length); } +/* ------------------------------------------------------------------------- */ +/* string functions */ +/* ------------------------------------------------------------------------- */ + /* 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; @@ -421,38 +450,6 @@ char *getRealName() return real_name; } -char *getHomeDir() -{ - static char *dir = NULL; - -#if defined(PLATFORM_WIN32) - if (dir == NULL) - { - dir = checked_malloc(MAX_PATH + 1); - - if (!SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, dir))) - strcpy(dir, "."); - } -#elif defined(PLATFORM_UNIX) - if (dir == NULL) - { - if ((dir = getenv("HOME")) == NULL) - { - struct passwd *pwd; - - if ((pwd = getpwuid(getuid())) != NULL) - dir = getStringCopy(pwd->pw_dir); - else - dir = "."; - } - } -#else - dir = "."; -#endif - - return dir; -} - /* ------------------------------------------------------------------------- */ /* path manipulation functions */ @@ -460,17 +457,15 @@ char *getHomeDir() static char *getLastPathSeparatorPtr(char *filename) { - char *last_separator = strrchr(filename, '/'); + char *last_separator = strrchr(filename, CHAR_PATH_SEPARATOR_UNIX); -#if !defined(PLATFORM_UNIX) if (last_separator == NULL) /* also try DOS/Windows variant */ - last_separator = strrchr(filename, '\\'); -#endif + last_separator = strrchr(filename, CHAR_PATH_SEPARATOR_DOS); return last_separator; } -static char *getBaseNamePtr(char *filename) +char *getBaseNamePtr(char *filename) { char *last_separator = getLastPathSeparatorPtr(filename); @@ -505,21 +500,23 @@ char *getBasePath(char *filename) char *getPath2(char *path1, char *path2) { + char *sep = STRING_PATH_SEPARATOR; char *complete_path = checked_malloc(strlen(path1) + 1 + strlen(path2) + 1); - sprintf(complete_path, "%s/%s", path1, path2); + sprintf(complete_path, "%s%s%s", path1, sep, path2); return complete_path; } char *getPath3(char *path1, char *path2, char *path3) { + char *sep = STRING_PATH_SEPARATOR; char *complete_path = checked_malloc(strlen(path1) + 1 + strlen(path2) + 1 + strlen(path3) + 1); - sprintf(complete_path, "%s/%s/%s", path1, path2, path3); + sprintf(complete_path, "%s%s%s%s%s", path1, sep, path2, sep, path3); return complete_path; } @@ -793,6 +790,71 @@ char *GetError() return internal_error; } +#if 1 + +void Error(int mode, char *format, ...) +{ + static boolean last_line_was_separator = FALSE; + char *process_name = ""; + + /* display warnings only when running in verbose mode */ + if (mode & ERR_WARN && !options.verbose) + return; + + if (mode == ERR_RETURN_LINE) + { + if (!last_line_was_separator) + fprintf_line(program.error_file, format, 79); + + last_line_was_separator = TRUE; + + return; + } + + last_line_was_separator = FALSE; + + if (mode & ERR_SOUND_SERVER) + process_name = " sound server"; + else if (mode & ERR_NETWORK_SERVER) + process_name = " network server"; + else if (mode & ERR_NETWORK_CLIENT) + process_name = " network client **"; + + if (format) + { + va_list ap; + + fprintf(program.error_file, "%s%s: ", program.command_basename, + process_name); + + if (mode & ERR_WARN) + fprintf(program.error_file, "warning: "); + + va_start(ap, format); + vfprintf_newline(program.error_file, format, ap); + va_end(ap); + } + + if (mode & ERR_HELP) + fprintf_newline(program.error_file, + "%s: Try option '--help' for more information.", + program.command_basename); + + if (mode & ERR_EXIT) + fprintf_newline(program.error_file, "%s%s: aborting", + program.command_basename, process_name); + + if (mode & ERR_EXIT) + { + if (mode & ERR_FROM_SERVER) + exit(1); /* child process: normal exit */ + else + program.exit_function(1); /* main process: clean up stuff */ + } +} + +#else + void Error(int mode, char *format, ...) { static boolean last_line_was_separator = FALSE; @@ -816,12 +878,13 @@ void Error(int mode, char *format, ...) last_line_was_separator = FALSE; -#if defined(PLATFORM_MSDOS) +#if defined(PLATFORM_WIN32) || defined(PLATFORM_MSDOS) newline = "\r\n"; if ((error = openErrorFile()) == NULL) { printf("Cannot write to error output file!%s", newline); + program.exit_function(1); } #endif @@ -869,6 +932,8 @@ void Error(int mode, char *format, ...) } } +#endif + /* ------------------------------------------------------------------------- */ /* checked memory allocation and freeing functions */ @@ -1835,6 +1900,29 @@ int get_auto_parameter_value(char *token, char *value_raw) return get_parameter_value(value_raw, suffix, TYPE_INTEGER); } +struct ScreenModeInfo *get_screen_mode_from_string(char *screen_mode_string) +{ + static struct ScreenModeInfo screen_mode; + char *screen_mode_string_x = strchr(screen_mode_string, 'x'); + char *screen_mode_string_copy; + char *screen_mode_string_pos_w; + char *screen_mode_string_pos_h; + + if (screen_mode_string_x == NULL) /* invalid screen mode format */ + return NULL; + + screen_mode_string_copy = getStringCopy(screen_mode_string); + + screen_mode_string_pos_w = screen_mode_string_copy; + screen_mode_string_pos_h = strchr(screen_mode_string_copy, 'x'); + *screen_mode_string_pos_h++ = '\0'; + + screen_mode.width = atoi(screen_mode_string_pos_w); + screen_mode.height = atoi(screen_mode_string_pos_h); + + return &screen_mode; +} + static void FreeCustomArtworkList(struct ArtworkListInfo *, struct ListNodeInfo ***, int *); @@ -2697,25 +2785,35 @@ void FreeCustomArtworkLists(struct ArtworkListInfo *artwork_info) /* ------------------------------------------------------------------------- */ /* functions only needed for non-Unix (non-command-line) systems */ /* (MS-DOS only; SDL/Windows creates files "stdout.txt" and "stderr.txt") */ +/* (now also added for Windows, to create files in user data directory) */ /* ------------------------------------------------------------------------- */ -#if defined(PLATFORM_MSDOS) - -#define ERROR_FILENAME "stderr.txt" +char *getErrorFilename(char *basename) +{ + return getPath2(getUserGameDataDir(), basename); +} -void initErrorFile() +void openErrorFile() { - unlink(ERROR_FILENAME); + /* always start with reliable default values */ + program.error_file = stderr; + +#if defined(PLATFORM_WIN32) || defined(PLATFORM_MSDOS) + if ((program.error_file = fopen(program.error_filename, MODE_WRITE)) == NULL) + fprintf_newline(stderr, "ERROR: cannot open file '%s' for writing!", + program.error_filename); +#endif } -FILE *openErrorFile() +void closeErrorFile() { - return fopen(ERROR_FILENAME, MODE_APPEND); + if (program.error_file != stderr) /* do not close stream 'stderr' */ + fclose(program.error_file); } void dumpErrorFile() { - FILE *error_file = fopen(ERROR_FILENAME, MODE_READ); + FILE *error_file = fopen(program.error_filename, MODE_READ); if (error_file != NULL) { @@ -2725,7 +2823,18 @@ void dumpErrorFile() fclose(error_file); } } + +void NotifyUserAboutErrorFile() +{ +#if defined(PLATFORM_WIN32) + char *title_text = getStringCat2(program.program_title, " Error Message"); + char *error_text = getStringCat2("The program was aborted due to an error; " + "for details, see the following error file:" + STRING_NEWLINE, program.error_filename); + + MessageBox(NULL, error_text, title_text, MB_OK); #endif +} /* ------------------------------------------------------------------------- */