win32.c
changeset 5167 2b9d61386688
parent 5120 e12dfc67761f
child 5168 10a8dc9788d7
equal deleted inserted replaced
5166:c40f2b19eca9 5167:2b9d61386688
   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 }