X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fmisc.c;h=a81f15532538efaa163fb591c1261108fc7dd53c;hb=a4e95e0a6d4b53732ea0a585be0b6df55ae41e42;hp=b50abca74f18ac64e7e8580d93d7c131acace21c;hpb=466240bdd432835656962afbc3ab9ed9f9d5797a;p=rocksndiamonds.git diff --git a/src/libgame/misc.c b/src/libgame/misc.c index b50abca7..a81f1553 100644 --- a/src/libgame/misc.c +++ b/src/libgame/misc.c @@ -786,7 +786,12 @@ static char *get_corrected_real_name(char *real_name) #if defined(PLATFORM_UNIX) static struct passwd *getPasswdEntry(void) { +#if defined(PLATFORM_EMSCRIPTEN) + // currently not fully supported; force fallback to default values + return NULL; +#else return getpwuid(getuid()); +#endif } char *getUnixLoginName(void) @@ -883,6 +888,53 @@ char *getRealName(void) return real_name; } +char *getFixedUserName(char *name) +{ + // needed because player name must be a fixed length string + char *name_new = checked_malloc(MAX_PLAYER_NAME_LEN + 1); + + strncpy(name_new, name, MAX_PLAYER_NAME_LEN); + name_new[MAX_PLAYER_NAME_LEN] = '\0'; + + if (strlen(name) > MAX_PLAYER_NAME_LEN) // name has been cut + if (strchr(name_new, ' ')) + *strchr(name_new, ' ') = '\0'; + + return name_new; +} + +char *getDefaultUserName(int nr) +{ + static char *user_name[MAX_PLAYER_NAMES] = { NULL }; + + nr = MIN(MAX(0, nr), MAX_PLAYER_NAMES - 1); + + if (user_name[nr] == NULL) + { + user_name[nr] = (nr == 0 ? getLoginName() : EMPTY_PLAYER_NAME); + user_name[nr] = getFixedUserName(user_name[nr]); + } + + return user_name[nr]; +} + +char *getTimestampFromEpoch(time_t epoch_seconds) +{ + struct tm *now = localtime(&epoch_seconds); + static char timestamp[20]; + + sprintf(timestamp, "%04d%02d%02d-%02d%02d%02d", + now->tm_year + 1900, now->tm_mon + 1, now->tm_mday, + now->tm_hour, now->tm_min, now->tm_sec); + + return timestamp; +} + +char *getCurrentTimestamp(void) +{ + return getTimestampFromEpoch(time(NULL)); +} + time_t getFileTimestampEpochSeconds(char *filename) { struct stat file_status; @@ -1126,6 +1178,22 @@ boolean strEqualN(char *s1, char *s2, int n) strncmp(s1, s2, n) == 0); } +boolean strEqualCase(char *s1, char *s2) +{ + return (s1 == NULL && s2 == NULL ? TRUE : + s1 == NULL && s2 != NULL ? FALSE : + s1 != NULL && s2 == NULL ? FALSE : + strcasecmp(s1, s2) == 0); +} + +boolean strEqualCaseN(char *s1, char *s2, int n) +{ + return (s1 == NULL && s2 == NULL ? TRUE : + s1 == NULL && s2 != NULL ? FALSE : + s1 != NULL && s2 == NULL ? FALSE : + strncasecmp(s1, s2, n) == 0); +} + boolean strPrefix(char *s, char *prefix) { return (s == NULL && prefix == NULL ? TRUE : @@ -1173,7 +1241,6 @@ void GetOptions(int argc, char *argv[], void (*print_version_function)(void)) { char *ro_base_path = getProgramMainDataPath(argv[0], RO_BASE_PATH); - char *rw_base_path = getProgramMainDataPath(argv[0], RW_BASE_PATH); char **argvplus = checked_calloc((argc + 1) * sizeof(char **)); char **options_left = &argvplus[1]; @@ -1186,7 +1253,6 @@ void GetOptions(int argc, char *argv[], options.server_port = 0; options.ro_base_directory = ro_base_path; - options.rw_base_directory = rw_base_path; options.level_directory = getPath2(ro_base_path, LEVELS_DIRECTORY); options.graphics_directory = getPath2(ro_base_path, GRAPHICS_DIRECTORY); options.sounds_directory = getPath2(ro_base_path, SOUNDS_DIRECTORY); @@ -1266,9 +1332,7 @@ void GetOptions(int argc, char *argv[], if (option_arg == NULL) FailWithHelp("option '%s' requires an argument", option_str); - // this should be extended to separate options for ro and rw data options.ro_base_directory = ro_base_path = getStringCopy(option_arg); - options.rw_base_directory = rw_base_path = getStringCopy(option_arg); if (option_arg == next_option) options_left++; @@ -1657,6 +1721,124 @@ void WriteUnusedBytesToFile(FILE *file, unsigned int bytes) } +// ---------------------------------------------------------------------------- +// functions to convert between ISO-8859-1 and UTF-8 +// ---------------------------------------------------------------------------- + +char *getUTF8FromLatin1(char *latin1) +{ + int max_utf8_size = 2 * strlen(latin1) + 1; + char *utf8 = checked_calloc(max_utf8_size); + unsigned char *src = (unsigned char *)latin1; + unsigned char *dst = (unsigned char *)utf8; + + while (*src) + { + if (*src < 128) // pure 7-bit ASCII + { + *dst++ = *src; + } + else if (*src >= 160) // non-ASCII characters + { + *dst++ = 194 + (*src >= 192); + *dst++ = 128 + (*src & 63); + } + else // undefined in ISO-8859-1 + { + *dst++ = '?'; + } + + src++; + } + + // only use the smallest possible string buffer size + utf8 = checked_realloc(utf8, strlen(utf8) + 1); + + return utf8; +} + +char *getLatin1FromUTF8(char *utf8) +{ + int max_latin1_size = strlen(utf8) + 1; + char *latin1 = checked_calloc(max_latin1_size); + unsigned char *src = (unsigned char *)utf8; + unsigned char *dst = (unsigned char *)latin1; + + while (*src) + { + if (*src < 128) // pure 7-bit ASCII + { + *dst++ = *src++; + } + else if (src[0] == 194 && + src[1] >= 128 && src[1] < 192) // non-ASCII characters + { + *dst++ = src[1]; + src += 2; + } + else if (src[0] == 195 && + src[1] >= 128 && src[1] < 192) // non-ASCII characters + { + *dst++ = src[1] + 64; + src += 2; + } + + // all other UTF-8 characters are undefined in ISO-8859-1 + + else if (src[0] >= 192 && src[0] < 224 && + src[1] >= 128 && src[1] < 192) + { + *dst++ = '?'; + src += 2; + } + else if (src[0] >= 224 && src[0] < 240 && + src[1] >= 128 && src[1] < 192 && + src[2] >= 128 && src[2] < 192) + { + *dst++ = '?'; + src += 3; + } + else if (src[0] >= 240 && src[0] < 248 && + src[1] >= 128 && src[1] < 192 && + src[2] >= 128 && src[2] < 192 && + src[3] >= 128 && src[3] < 192) + { + *dst++ = '?'; + src += 4; + } + else if (src[0] >= 248 && src[0] < 252 && + src[1] >= 128 && src[1] < 192 && + src[2] >= 128 && src[2] < 192 && + src[3] >= 128 && src[3] < 192 && + src[4] >= 128 && src[4] < 192) + { + *dst++ = '?'; + src += 5; + } + else if (src[0] >= 252 && src[0] < 254 && + src[1] >= 128 && src[1] < 192 && + src[2] >= 128 && src[2] < 192 && + src[3] >= 128 && src[3] < 192 && + src[4] >= 128 && src[4] < 192 && + src[5] >= 128 && src[5] < 192) + { + *dst++ = '?'; + src += 6; + } + else + { + *dst++ = '?'; + src++; + } + } + + // only use the smallest possible string buffer size + latin1 = checked_realloc(latin1, strlen(latin1) + 1); + + return latin1; +} + + // ---------------------------------------------------------------------------- // functions to translate key identifiers between different format // ---------------------------------------------------------------------------- @@ -3756,14 +3938,14 @@ void FreeCustomArtworkLists(struct ArtworkListInfo *artwork_info) char *getLogFilename(char *basename) { - return getPath2(getUserGameDataDir(), basename); + return getPath2(getMainUserGameDataDir(), basename); } void OpenLogFiles(void) { int i; - InitUserDataDirectory(); + InitMainUserDataDirectory(); for (i = 0; i < NUM_LOGS; i++) {