637 |
637 |
638 DIR *opendir(const char *path) |
638 DIR *opendir(const char *path) |
639 { |
639 { |
640 DIR *d; |
640 DIR *d; |
641 UINT sem = SetErrorMode(SEM_FAILCRITICALERRORS); // disable 'no-disk' message box |
641 UINT sem = SetErrorMode(SEM_FAILCRITICALERRORS); // disable 'no-disk' message box |
642 DWORD fa = GetFileAttributes(path); |
642 DWORD fa = GetFileAttributesW(OTTD2FS(path)); |
643 |
643 |
644 if ((fa != INVALID_FILE_ATTRIBUTES) && (fa & FILE_ATTRIBUTE_DIRECTORY)) { |
644 if ((fa != INVALID_FILE_ATTRIBUTES) && (fa & FILE_ATTRIBUTE_DIRECTORY)) { |
645 d = dir_calloc(); |
645 d = dir_calloc(); |
646 if (d != NULL) { |
646 if (d != NULL) { |
647 char search_path[MAX_PATH]; |
647 char search_path[MAX_PATH]; |
648 /* build search path for FindFirstFile */ |
648 /* build search path for FindFirstFile */ |
649 snprintf(search_path, lengthof(search_path), "%s" PATHSEP "*", path); |
649 snprintf(search_path, lengthof(search_path), "%s" PATHSEP "*", path); |
650 d->hFind = FindFirstFile(search_path, &d->fd); |
650 d->hFind = FindFirstFileW(OTTD2FS(search_path), &d->fd); |
651 |
651 |
652 if (d->hFind != INVALID_HANDLE_VALUE || |
652 if (d->hFind != INVALID_HANDLE_VALUE || |
653 GetLastError() == ERROR_NO_MORE_FILES) { // the directory is empty |
653 GetLastError() == ERROR_NO_MORE_FILES) { // the directory is empty |
654 d->ent.dir = d; |
654 d->ent.dir = d; |
655 d->at_first_entry = true; |
655 d->at_first_entry = true; |
676 |
676 |
677 if (d->at_first_entry) { |
677 if (d->at_first_entry) { |
678 /* the directory was empty when opened */ |
678 /* the directory was empty when opened */ |
679 if (d->hFind == INVALID_HANDLE_VALUE) return NULL; |
679 if (d->hFind == INVALID_HANDLE_VALUE) return NULL; |
680 d->at_first_entry = false; |
680 d->at_first_entry = false; |
681 } else if (!FindNextFile(d->hFind, &d->fd)) { // determine cause and bail |
681 } else if (!FindNextFileW(d->hFind, &d->fd)) { // determine cause and bail |
682 if (GetLastError() == ERROR_NO_MORE_FILES) SetLastError(prev_err); |
682 if (GetLastError() == ERROR_NO_MORE_FILES) SetLastError(prev_err); |
683 return NULL; |
683 return NULL; |
684 } |
684 } |
685 |
685 |
686 /* This entry has passed all checks; return information about it. |
686 /* This entry has passed all checks; return information about it. |
719 |
719 |
720 bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb) |
720 bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb) |
721 { |
721 { |
722 // hectonanoseconds between Windows and POSIX epoch |
722 // hectonanoseconds between Windows and POSIX epoch |
723 static const int64 posix_epoch_hns = 0x019DB1DED53E8000LL; |
723 static const int64 posix_epoch_hns = 0x019DB1DED53E8000LL; |
724 const WIN32_FIND_DATA *fd = &ent->dir->fd; |
724 const WIN32_FIND_DATAW *fd = &ent->dir->fd; |
725 if (fd->dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) return false; |
725 if (fd->dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) return false; |
726 |
726 |
727 sb->st_size = ((uint64) fd->nFileSizeHigh << 32) + fd->nFileSizeLow; |
727 sb->st_size = ((uint64) fd->nFileSizeHigh << 32) + fd->nFileSizeLow; |
728 /* UTC FILETIME to seconds-since-1970 UTC |
728 /* UTC FILETIME to seconds-since-1970 UTC |
729 * we just have to subtract POSIX epoch and scale down to units of seconds. |
729 * we just have to subtract POSIX epoch and scale down to units of seconds. |
884 return 0; |
884 return 0; |
885 } |
885 } |
886 |
886 |
887 void DeterminePaths(void) |
887 void DeterminePaths(void) |
888 { |
888 { |
889 char *s; |
889 char *s, *cfg; |
890 char *cfg; |
890 wchar_t path[MAX_PATH]; |
891 |
891 |
892 _path.personal_dir = _path.game_data_dir = cfg = malloc(MAX_PATH); |
892 _path.personal_dir = _path.game_data_dir = cfg = malloc(MAX_PATH); |
893 GetCurrentDirectory(MAX_PATH - 1, cfg); |
893 GetCurrentDirectoryW(MAX_PATH - 1, path); |
|
894 WideCharToMultiByte(CP_UTF8, 0, path, -1, cfg, MAX_PATH, NULL, NULL); |
894 |
895 |
895 cfg[0] = toupper(cfg[0]); |
896 cfg[0] = toupper(cfg[0]); |
896 s = strchr(cfg, '\0'); |
897 s = strchr(cfg, '\0'); |
897 if (s[-1] != '\\') strcpy(s, "\\"); |
898 if (s[-1] != '\\') strcpy(s, "\\"); |
898 |
899 |
909 |
910 |
910 _highscore_file = str_fmt("%shs.dat", _path.personal_dir); |
911 _highscore_file = str_fmt("%shs.dat", _path.personal_dir); |
911 _log_file = str_fmt("%sopenttd.log", _path.personal_dir); |
912 _log_file = str_fmt("%sopenttd.log", _path.personal_dir); |
912 |
913 |
913 // make (auto)save and scenario folder |
914 // make (auto)save and scenario folder |
914 CreateDirectory(_path.save_dir, NULL); |
915 CreateDirectoryW(OTTD2FS(_path.save_dir), NULL); |
915 CreateDirectory(_path.autosave_dir, NULL); |
916 CreateDirectoryW(OTTD2FS(_path.autosave_dir), NULL); |
916 CreateDirectory(_path.scenario_dir, NULL); |
917 CreateDirectoryW(OTTD2FS(_path.scenario_dir), NULL); |
917 CreateDirectory(_path.heightmap_dir, NULL); |
918 CreateDirectoryW(OTTD2FS(_path.heightmap_dir), NULL); |
918 } |
919 } |
919 |
920 |
920 /** |
921 /** |
921 * Insert a chunk of text from the clipboard onto the textbuffer. Get TEXT clipboard |
922 * Insert a chunk of text from the clipboard onto the textbuffer. Get TEXT clipboard |
922 * and append this up to the maximum length (either absolute or screenlength). If maxlength |
923 * and append this up to the maximum length (either absolute or screenlength). If maxlength |
1007 freq = (double)1000000 / value; |
1008 freq = (double)1000000 / value; |
1008 } |
1009 } |
1009 QueryPerformanceCounter((LARGE_INTEGER*)&value); |
1010 QueryPerformanceCounter((LARGE_INTEGER*)&value); |
1010 return (__int64)(value * freq); |
1011 return (__int64)(value * freq); |
1011 } |
1012 } |
|
1013 |
|
1014 /** Convert from OpenTTD's encoding to that of the local environment |
|
1015 * First convert from UTF8 to wide-char, then to local |
|
1016 * @param name pointer to a valid string that will be converted |
|
1017 * @return pointer to a new stringbuffer that contains the converted string */ |
|
1018 const wchar_t *OTTD2FS(const char *name) |
|
1019 { |
|
1020 static wchar_t ucs2_buf[MAX_PATH]; |
|
1021 int len; |
|
1022 |
|
1023 len = MultiByteToWideChar(CP_UTF8, 0, name, -1, ucs2_buf, lengthof(ucs2_buf)); |
|
1024 if (len == 0) { |
|
1025 DEBUG(misc, 0) ("[utf8] Error converting '%s'. Errno %d", name, GetLastError()); |
|
1026 return L""; |
|
1027 } |
|
1028 |
|
1029 return (const wchar_t*)ucs2_buf; |
|
1030 } |
|
1031 |
|
1032 /** Convert to OpenTTD's encoding from that of the local environment |
|
1033 * @param name pointer to a valid string that will be converted |
|
1034 * @return pointer to a new stringbuffer that contains the converted string */ |
|
1035 const char *FS2OTTD(const wchar_t *name) |
|
1036 { |
|
1037 static char utf8_buf[512]; |
|
1038 int len; |
|
1039 |
|
1040 len = WideCharToMultiByte(CP_UTF8, 0, name, -1, utf8_buf, lengthof(utf8_buf), NULL, NULL); |
|
1041 if (len == 0) { |
|
1042 DEBUG(misc, 0) ("[utf8] Error converting string. Errno %d", GetLastError()); |
|
1043 return ""; |
|
1044 } |
|
1045 |
|
1046 return (const char*)utf8_buf; |
|
1047 } |