X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fmisc.c;h=ec16eeee4568f1b7c95a23b5d810a64c1edfcad9;hb=1786288765edb99711ec0eb06520969879d62cc2;hp=2cf6bd84e8b7a8f7b335a0f76e238ce4e223dabb;hpb=94514e77176075d9f654599f4ff1c018d66b7c1e;p=rocksndiamonds.git diff --git a/src/libgame/misc.c b/src/libgame/misc.c index 2cf6bd84..ec16eeee 100644 --- a/src/libgame/misc.c +++ b/src/libgame/misc.c @@ -1,7 +1,7 @@ /*********************************************************** * Artsoft Retro-Game Library * *----------------------------------------------------------* -* (c) 1994-2002 Artsoft Entertainment * +* (c) 1994-2006 Artsoft Entertainment * * Holger Schemel * * Detmolder Strasse 189 * * 33604 Bielefeld * @@ -33,32 +33,61 @@ #include "image.h" -/* ------------------------------------------------------------------------- */ +/* ========================================================================= */ /* some generic helper functions */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* platform independent wrappers for printf() et al. (newline aware) */ /* ------------------------------------------------------------------------- */ -void fprintf_line(FILE *stream, char *line_string, int line_length) +static void vfprintf_newline(FILE *stream, char *format, va_list ap) +{ + char *newline = STRING_NEWLINE; + + vfprintf(stream, format, ap); + + fprintf(stream, "%s", newline); +} + +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; } @@ -797,8 +794,6 @@ void Error(int mode, char *format, ...) { static boolean last_line_was_separator = FALSE; char *process_name = ""; - FILE *error = stderr; - char *newline = "\n"; /* display warnings only when running in verbose mode */ if (mode & ERR_WARN && !options.verbose) @@ -807,7 +802,7 @@ void Error(int mode, char *format, ...) if (mode == ERR_RETURN_LINE) { if (!last_line_was_separator) - fprintf_line(error, format, 79); + fprintf_line(program.error_file, format, 79); last_line_was_separator = TRUE; @@ -816,16 +811,6 @@ void Error(int mode, char *format, ...) last_line_was_separator = FALSE; -#if defined(PLATFORM_MSDOS) - newline = "\r\n"; - - if ((error = openErrorFile()) == NULL) - { - printf("Cannot write to error output file!%s", newline); - program.exit_function(1); - } -#endif - if (mode & ERR_SOUND_SERVER) process_name = " sound server"; else if (mode & ERR_NETWORK_SERVER) @@ -837,28 +822,25 @@ void Error(int mode, char *format, ...) { va_list ap; - fprintf(error, "%s%s: ", program.command_basename, process_name); + fprintf(program.error_file, "%s%s: ", program.command_basename, + process_name); if (mode & ERR_WARN) - fprintf(error, "warning: "); + fprintf(program.error_file, "warning: "); va_start(ap, format); - vfprintf(error, format, ap); + vfprintf_newline(program.error_file, format, ap); va_end(ap); - - fprintf(error, "%s", newline); } if (mode & ERR_HELP) - fprintf(error, "%s: Try option '--help' for more information.%s", - program.command_basename, newline); + fprintf_newline(program.error_file, + "%s: Try option '--help' for more information.", + program.command_basename); if (mode & ERR_EXIT) - fprintf(error, "%s%s: aborting%s", - program.command_basename, process_name, newline); - - if (error != stderr) - fclose(error); + fprintf_newline(program.error_file, "%s%s: aborting", + program.command_basename, process_name); if (mode & ERR_EXIT) { @@ -1041,17 +1023,27 @@ boolean getFileChunk(FILE *file, char *chunk_name, int *chunk_size, return (feof(file) || ferror(file) ? FALSE : TRUE); } -void putFileChunk(FILE *file, char *chunk_name, int chunk_size, - int byte_order) +int putFileChunk(FILE *file, char *chunk_name, int chunk_size, + int byte_order) { + int num_bytes = 0; + /* write chunk name */ - fputs(chunk_name, file); + if (file != NULL) + fputs(chunk_name, file); + + num_bytes += strlen(chunk_name); if (chunk_size >= 0) { /* write chunk size */ - putFile32BitInteger(file, chunk_size, byte_order); + if (file != NULL) + putFile32BitInteger(file, chunk_size, byte_order); + + num_bytes += 4; } + + return num_bytes; } int getFileVersion(FILE *file) @@ -1065,17 +1057,22 @@ int getFileVersion(FILE *file) version_build); } -void putFileVersion(FILE *file, int version) +int putFileVersion(FILE *file, int version) { - int version_major = VERSION_MAJOR(version); - int version_minor = VERSION_MINOR(version); - int version_patch = VERSION_PATCH(version); - int version_build = VERSION_BUILD(version); + if (file != NULL) + { + int version_major = VERSION_MAJOR(version); + int version_minor = VERSION_MINOR(version); + int version_patch = VERSION_PATCH(version); + int version_build = VERSION_BUILD(version); + + fputc(version_major, file); + fputc(version_minor, file); + fputc(version_patch, file); + fputc(version_build, file); + } - fputc(version_major, file); - fputc(version_minor, file); - fputc(version_patch, file); - fputc(version_build, file); + return 4; } void ReadBytesFromFile(FILE *file, byte *buffer, unsigned long bytes) @@ -1240,13 +1237,8 @@ void translate_keyname(Key *keysym, char **x11name, char **name, int mode) sprintf(name_buffer, "%c", '0' + (char)(key - KSYM_0)); else if (key >= KSYM_KP_0 && key <= KSYM_KP_9) sprintf(name_buffer, "keypad %c", '0' + (char)(key - KSYM_KP_0)); -#if 1 else if (key >= KSYM_FKEY_FIRST && key <= KSYM_FKEY_LAST) sprintf(name_buffer, "F%d", (int)(key - KSYM_FKEY_FIRST + 1)); -#else - else if (key >= KSYM_FKEY_FIRST && key <= KSYM_FKEY_LAST) - sprintf(name_buffer, "function F%d", (int)(key - KSYM_FKEY_FIRST + 1)); -#endif else if (key == KSYM_UNDEFINED) strcpy(name_buffer, "(undefined)"); else @@ -1552,7 +1544,7 @@ void deleteNodeFromList(ListNode **node_first, char *key, if (strEqual((*node_first)->key, key)) { - free((*node_first)->key); + checked_free((*node_first)->key); if (destructor_function) destructor_function((*node_first)->content); *node_first = (*node_first)->next; @@ -1769,6 +1761,12 @@ int get_parameter_value(char *value_raw, char *suffix, int type) strEqual(value, "up") ? MV_UP : strEqual(value, "down") ? MV_DOWN : MV_NONE); } + else if (strEqual(suffix, ".align")) + { + result = (strEqual(value, "left") ? ALIGN_LEFT : + strEqual(value, "right") ? ALIGN_RIGHT : + strEqual(value, "center") ? ALIGN_CENTER : ALIGN_DEFAULT); + } else if (strEqual(suffix, ".anim_mode")) { result = (string_has_parameter(value, "none") ? ANIM_NONE : @@ -1779,8 +1777,10 @@ int get_parameter_value(char *value_raw, char *suffix, int type) string_has_parameter(value, "random") ? ANIM_RANDOM : string_has_parameter(value, "ce_value") ? ANIM_CE_VALUE : string_has_parameter(value, "ce_score") ? ANIM_CE_SCORE : + string_has_parameter(value, "ce_delay") ? ANIM_CE_DELAY : string_has_parameter(value, "horizontal") ? ANIM_HORIZONTAL : string_has_parameter(value, "vertical") ? ANIM_VERTICAL : + string_has_parameter(value, "centered") ? ANIM_CENTERED : ANIM_DEFAULT); if (string_has_parameter(value, "reverse")) @@ -1819,6 +1819,48 @@ 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; +} + +void get_aspect_ratio_from_screen_mode(struct ScreenModeInfo *screen_mode, + int *x, int *y) +{ + float aspect_ratio = (float)screen_mode->width / (float)screen_mode->height; + float aspect_ratio_new; + int i = 1; + + do + { + *x = i * aspect_ratio + 0.000001; + *y = i; + + aspect_ratio_new = (float)*x / (float)*y; + + i++; + } + while (aspect_ratio_new != aspect_ratio && *y < screen_mode->height); +} + static void FreeCustomArtworkList(struct ArtworkListInfo *, struct ListNodeInfo ***, int *); @@ -2681,25 +2723,32 @@ 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); + InitUserDataDirectory(); + + if ((program.error_file = fopen(program.error_filename, MODE_WRITE)) == NULL) + fprintf_newline(stderr, "ERROR: cannot open file '%s' for writing!", + program.error_filename); } -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) { @@ -2709,7 +2758,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 +} /* ------------------------------------------------------------------------- */