X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fmisc.c;h=c02d392067f81401ad910a666f72da1eb9e196f8;hb=a8cefb9b52499f69c69ae796db7f057b4c76b0db;hp=883dd7d2afd7b18cc4b94db45622b2f12f012883;hpb=466733e5fd75e0d705bf80dddb48468c4c9885a7;p=rocksndiamonds.git diff --git a/src/libgame/misc.c b/src/libgame/misc.c index 883dd7d2..c02d3920 100644 --- a/src/libgame/misc.c +++ b/src/libgame/misc.c @@ -38,93 +38,149 @@ /* ========================================================================= */ /* ------------------------------------------------------------------------- */ -/* platform independent wrappers for printf() et al. (newline aware) */ +/* logging functions */ /* ------------------------------------------------------------------------- */ +#define DUPLICATE_LOG_OUTPUT_TO_STDERR TRUE + + #if defined(PLATFORM_ANDROID) static int android_log_prio = ANDROID_LOG_INFO; -#endif +static char *android_log_buffer = NULL; -#if 0 -static void vfPrintLog(FILE *stream, char *format, va_list ap) +static void append_to_android_log_buffer(char *format, va_list ap) { -} + char text_new[MAX_OUTPUT_LINESIZE]; -static void vfPrintLog(FILE *stream, char *format, va_list ap) -{ + // print text to temporary string + vsnprintf(text_new, MAX_OUTPUT_LINESIZE, format, ap); + + if (android_log_buffer == NULL) + { + android_log_buffer = getStringCopy(text_new); + } + else + { + char *android_log_buffer_old = android_log_buffer; + + // append new text to existing text + android_log_buffer = getStringCat2(android_log_buffer, text_new); + + checked_free(android_log_buffer_old); + } } -static void fPrintLog(FILE *stream, char *format, va_list ap) +static void vprintf_log_nonewline(char *format, va_list ap) { + // add log output to buffer until text with newline is printed + append_to_android_log_buffer(format, ap); } -static void fPrintLog(FILE *stream, char *format, va_list ap) +static void vprintf_log(char *format, va_list ap) { + // add log output to buffer + append_to_android_log_buffer(format, ap); + + // __android_log_vprint(android_log_prio, program.program_title, format, ap); + __android_log_write(android_log_prio, program.program_title, + android_log_buffer); + + checked_free(android_log_buffer); + android_log_buffer = NULL; } -#endif -static void vfprintf_nonewline(FILE *stream, char *format, va_list ap) -{ -#if defined(PLATFORM_ANDROID) - // (prefix text of logging output is currently skipped on Android) - //__android_log_vprint(android_log_prio, program.program_title, format, ap); #else - va_list ap2; - va_copy(ap2, ap); - vfprintf(stream, format, ap); - vfprintf(stderr, format, ap2); +static void vprintf_log_nonewline(char *format, va_list ap) +{ + FILE *file = program.error_file; - va_end(ap2); +#if DUPLICATE_LOG_OUTPUT_TO_STDERR + if (file != stderr) + { + va_list ap2; + va_copy(ap2, ap); + + vfprintf(stderr, format, ap2); + + va_end(ap2); + } #endif + + vfprintf(file, format, ap); } -static void vfprintf_newline(FILE *stream, char *format, va_list ap) +static void vprintf_log(char *format, va_list ap) { -#if defined(PLATFORM_ANDROID) - __android_log_vprint(android_log_prio, program.program_title, format, ap); -#else + FILE *file = program.error_file; char *newline = STRING_NEWLINE; - va_list ap2; - va_copy(ap2, ap); - - vfprintf(stream, format, ap); - fprintf(stream, "%s", newline); +#if DUPLICATE_LOG_OUTPUT_TO_STDERR + if (file != stderr) + { + va_list ap2; + va_copy(ap2, ap); - vfprintf(stderr, format, ap2); - fprintf(stderr, "%s", newline); + vfprintf(stderr, format, ap2); + fprintf(stderr, "%s", newline); - va_end(ap2); + va_end(ap2); + } #endif + + vfprintf(file, format, ap); + fprintf(file, "%s", newline); } +#endif -static void fprintf_nonewline(FILE *stream, char *format, ...) +static void printf_log_nonewline(char *format, ...) { va_list ap; va_start(ap, format); - vfprintf_nonewline(stream, format, ap); + vprintf_log_nonewline(format, ap); va_end(ap); } -static void fprintf_newline(FILE *stream, char *format, ...) +static void printf_log(char *format, ...) { va_list ap; va_start(ap, format); - vfprintf_newline(stream, format, ap); + vprintf_log(format, ap); va_end(ap); } -void fprintf_line(FILE *stream, char *line_chars, int line_length) +static void printf_log_line(char *line_chars, int line_length) { int i; for (i = 0; i < line_length; i++) - fprintf_nonewline(stream, "%s", line_chars); + printf_log_nonewline("%s", line_chars); - fprintf_newline(stream, ""); + printf_log(""); +} + + +/* ------------------------------------------------------------------------- */ +/* platform independent wrappers for printf() et al. */ +/* ------------------------------------------------------------------------- */ + +void fprintf_line(FILE *file, char *line_chars, int line_length) +{ + int i; + + for (i = 0; i < line_length; i++) + fprintf(file, "%s", line_chars); + + fprintf(file, "\n"); +} + +void fprintf_line_with_prefix(FILE *file, char *prefix, char *line_chars, + int line_length) +{ + fprintf(file, "%s", prefix); + fprintf_line(file, line_chars, line_length); } void printf_line(char *line_chars, int line_length) @@ -134,8 +190,7 @@ void printf_line(char *line_chars, int line_length) void printf_line_with_prefix(char *prefix, char *line_chars, int line_length) { - fprintf(stdout, "%s", prefix); - fprintf_line(stdout, line_chars, line_length); + fprintf_line_with_prefix(stdout, prefix, line_chars, line_length); } @@ -555,6 +610,9 @@ static char *getProgramMainDataPath() char *getStringCat2WithSeparator(char *s1, char *s2, char *sep) { + if (s1 == NULL || s2 == NULL || sep == NULL) + return NULL; + char *complete_string = checked_malloc(strlen(s1) + strlen(sep) + strlen(s2) + 1); @@ -565,6 +623,9 @@ char *getStringCat2WithSeparator(char *s1, char *s2, char *sep) char *getStringCat3WithSeparator(char *s1, char *s2, char *s3, char *sep) { + if (s1 == NULL || s2 == NULL || s3 == NULL || sep == NULL) + return NULL; + char *complete_string = checked_malloc(strlen(s1) + strlen(sep) + strlen(s2) + strlen(sep) + strlen(s3) + 1); @@ -587,9 +648,11 @@ char *getStringCat3(char *s1, char *s2, char *s3) char *getPath2(char *path1, char *path2) { #if defined(PLATFORM_ANDROID) - // workaround for reading from APK assets directory -- skip leading "./" + // workaround for reading from assets directory -- skip "." subdirs in path if (strEqual(path1, ".")) return getStringCopy(path2); + else if (strEqual(path2, ".")) + return getStringCopy(path1); #endif return getStringCat2WithSeparator(path1, path2, STRING_PATH_SEPARATOR); @@ -598,14 +661,60 @@ char *getPath2(char *path1, char *path2) char *getPath3(char *path1, char *path2, char *path3) { #if defined(PLATFORM_ANDROID) - // workaround for reading from APK assets directory -- skip leading "./" + // workaround for reading from assets directory -- skip "." subdirs in path if (strEqual(path1, ".")) return getStringCat2WithSeparator(path2, path3, STRING_PATH_SEPARATOR); + else if (strEqual(path2, ".")) + return getStringCat2WithSeparator(path1, path3, STRING_PATH_SEPARATOR); + else if (strEqual(path3, ".")) + return getStringCat2WithSeparator(path1, path2, STRING_PATH_SEPARATOR); #endif return getStringCat3WithSeparator(path1, path2, path3, STRING_PATH_SEPARATOR); } +char *getImg2(char *path1, char *path2) +{ + char *filename = getPath2(path1, path2); + + if (!fileExists(filename) && strSuffix(path2, ".png")) + { + // backward compatibility: if PNG file not found, check for PCX file + char *path2pcx = getStringCopy(path2); + + strcpy(&path2pcx[strlen(path2pcx) - 3], "pcx"); + + free(filename); + + filename = getPath2(path1, path2pcx); + + free(path2pcx); + } + + return filename; +} + +char *getImg3(char *path1, char *path2, char *path3) +{ + char *filename = getPath3(path1, path2, path3); + + if (!fileExists(filename) && strSuffix(path3, ".png")) + { + // backward compatibility: if PNG file not found, check for PCX file + char *path3pcx = getStringCopy(path3); + + strcpy(&path3pcx[strlen(path3pcx) - 3], "pcx"); + + free(filename); + + filename = getPath3(path1, path2, path3pcx); + + free(path3pcx); + } + + return filename; +} + char *getStringCopy(const char *s) { char *s_copy; @@ -760,7 +869,6 @@ void GetOptions(char *argv[], options.network = FALSE; options.verbose = FALSE; options.debug = FALSE; - options.debug_x11_sync = FALSE; #if 1 options.verbose = TRUE; @@ -888,10 +996,6 @@ void GetOptions(char *argv[], { options.debug = TRUE; } - else if (strncmp(option, "-debug-x11-sync", option_len) == 0) - { - options.debug_x11_sync = TRUE; - } else if (strncmp(option, "-verbose", option_len) == 0) { options.verbose = TRUE; @@ -984,7 +1088,7 @@ void Error(int mode, char *format, ...) if (mode == ERR_INFO_LINE) { if (!last_line_was_separator) - fprintf_line(program.error_file, format, 79); + printf_log_line(format, 79); last_line_was_separator = TRUE; @@ -1002,16 +1106,20 @@ void Error(int mode, char *format, ...) if (format) { - va_list ap; - - fprintf_nonewline(program.error_file, "%s%s: ", program.command_basename, - process_name); +#if !defined(PLATFORM_ANDROID) + printf_log_nonewline("%s%s: ", program.command_basename, process_name); +#endif if (mode & ERR_WARN) - fprintf_nonewline(program.error_file, "warning: "); + printf_log_nonewline("warning: "); + + if (mode & ERR_EXIT) + printf_log_nonewline("fatal error: "); + + va_list ap; va_start(ap, format); - vfprintf_newline(program.error_file, format, ap); + vprintf_log(format, ap); va_end(ap); if ((mode & ERR_EXIT) && !(mode & ERR_FROM_SERVER)) @@ -1023,13 +1131,11 @@ void Error(int mode, char *format, ...) } if (mode & ERR_HELP) - fprintf_newline(program.error_file, - "%s: Try option '--help' for more information.", - program.command_basename); + printf_log("%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); + printf_log("%s%s: aborting", program.command_basename, process_name); if (mode & ERR_EXIT) { @@ -1418,7 +1524,7 @@ void translate_keyname(Key *keysym, char **x11name, char **name, int mode) { KSYM_braceright, "XK_braceright", "brace right" }, { KSYM_asciitilde, "XK_asciitilde", "~" }, - /* special (non-ASCII) keys (ISO-Latin-1) */ + /* special (non-ASCII) keys */ { KSYM_degree, "XK_degree", "degree" }, { KSYM_Adiaeresis, "XK_Adiaeresis", "A umlaut" }, { KSYM_Odiaeresis, "XK_Odiaeresis", "O umlaut" }, @@ -1699,6 +1805,26 @@ Key getKeyFromX11KeyName(char *x11name) char getCharFromKey(Key key) { + static struct + { + Key key; + byte key_char; + } translate_key_char[] = + { + /* special (non-ASCII) keys (ISO-8859-1) */ + { KSYM_degree, CHAR_BYTE_DEGREE }, + { KSYM_Adiaeresis, CHAR_BYTE_UMLAUT_A }, + { KSYM_Odiaeresis, CHAR_BYTE_UMLAUT_O }, + { KSYM_Udiaeresis, CHAR_BYTE_UMLAUT_U }, + { KSYM_adiaeresis, CHAR_BYTE_UMLAUT_a }, + { KSYM_odiaeresis, CHAR_BYTE_UMLAUT_o }, + { KSYM_udiaeresis, CHAR_BYTE_UMLAUT_u }, + { KSYM_ssharp, CHAR_BYTE_SHARP_S }, + + /* end-of-array identifier */ + { 0, 0 } + }; + char *keyname = getKeyNameFromKey(key); char c = 0; @@ -1706,6 +1832,21 @@ char getCharFromKey(Key key) c = keyname[0]; else if (strEqual(keyname, "space")) c = ' '; + else + { + int i = 0; + + do + { + if (key == translate_key_char[i].key) + { + c = translate_key_char[i].key_char; + + break; + } + } + while (translate_key_char[++i].key_char); + } return c; } @@ -2176,7 +2317,9 @@ boolean directoryExists(char *dir_name) if (dir_name == NULL) return FALSE; - boolean success = (access(dir_name, F_OK) == 0); + struct stat file_status; + boolean success = (stat(dir_name, &file_status) == 0 && + (file_status.st_mode & S_IFMT) == S_IFDIR); #if defined(PLATFORM_ANDROID) if (!success) @@ -2264,40 +2407,37 @@ boolean fileHasSuffix(char *basename, char *suffix) return FALSE; } -static boolean FileCouldBeArtwork(char *basename) +static boolean FileCouldBeArtwork(char *filename) { + char *basename = getBaseNamePtr(filename); + return (!strEqual(basename, ".") && !strEqual(basename, "..") && !fileHasSuffix(basename, "txt") && - !fileHasSuffix(basename, "conf")); + !fileHasSuffix(basename, "conf") && + !directoryExists(filename)); } boolean FileIsGraphic(char *filename) { - char *basename = getBaseNamePtr(filename); - - return FileCouldBeArtwork(basename); + return FileCouldBeArtwork(filename); } boolean FileIsSound(char *filename) { - char *basename = getBaseNamePtr(filename); - - return FileCouldBeArtwork(basename); + return FileCouldBeArtwork(filename); } boolean FileIsMusic(char *filename) { - char *basename = getBaseNamePtr(filename); - - return FileCouldBeArtwork(basename); + return FileCouldBeArtwork(filename); } -boolean FileIsArtworkType(char *basename, int type) +boolean FileIsArtworkType(char *filename, int type) { - if ((type == TREE_TYPE_GRAPHICS_DIR && FileIsGraphic(basename)) || - (type == TREE_TYPE_SOUNDS_DIR && FileIsSound(basename)) || - (type == TREE_TYPE_MUSIC_DIR && FileIsMusic(basename))) + if ((type == TREE_TYPE_GRAPHICS_DIR && FileIsGraphic(filename)) || + (type == TREE_TYPE_SOUNDS_DIR && FileIsSound(filename)) || + (type == TREE_TYPE_MUSIC_DIR && FileIsMusic(filename))) return TRUE; return FALSE; @@ -3354,7 +3494,7 @@ void openErrorFile() void closeErrorFile() { - if (program.error_file != stderr) /* do not close stream 'stderr' */ + if (program.error_file != stderr) /* do not close file 'stderr' */ fclose(program.error_file); }