(svn r7274) -Codechange [utf8]: Add input/output unicode support. This actually only changes win32

since it uses UTF16 for file access. To keep os-specific code to a minimum, OpenTTD
 uses UTF8 internally everywhere, converting to OS-type when needed (save/load/screenshot/etc.)
This commit is contained in:
Darkvater
2006-11-28 14:42:31 +00:00
parent 9253387001
commit 4e71091137
10 changed files with 89 additions and 37 deletions

58
win32.c
View File

@@ -639,7 +639,7 @@ DIR *opendir(const char *path)
{
DIR *d;
UINT sem = SetErrorMode(SEM_FAILCRITICALERRORS); // disable 'no-disk' message box
DWORD fa = GetFileAttributes(path);
DWORD fa = GetFileAttributesW(OTTD2FS(path));
if ((fa != INVALID_FILE_ATTRIBUTES) && (fa & FILE_ATTRIBUTE_DIRECTORY)) {
d = dir_calloc();
@@ -647,7 +647,7 @@ DIR *opendir(const char *path)
char search_path[MAX_PATH];
/* build search path for FindFirstFile */
snprintf(search_path, lengthof(search_path), "%s" PATHSEP "*", path);
d->hFind = FindFirstFile(search_path, &d->fd);
d->hFind = FindFirstFileW(OTTD2FS(search_path), &d->fd);
if (d->hFind != INVALID_HANDLE_VALUE ||
GetLastError() == ERROR_NO_MORE_FILES) { // the directory is empty
@@ -678,7 +678,7 @@ struct dirent *readdir(DIR *d)
/* the directory was empty when opened */
if (d->hFind == INVALID_HANDLE_VALUE) return NULL;
d->at_first_entry = false;
} else if (!FindNextFile(d->hFind, &d->fd)) { // determine cause and bail
} else if (!FindNextFileW(d->hFind, &d->fd)) { // determine cause and bail
if (GetLastError() == ERROR_NO_MORE_FILES) SetLastError(prev_err);
return NULL;
}
@@ -721,7 +721,7 @@ bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb
{
// hectonanoseconds between Windows and POSIX epoch
static const int64 posix_epoch_hns = 0x019DB1DED53E8000LL;
const WIN32_FIND_DATA *fd = &ent->dir->fd;
const WIN32_FIND_DATAW *fd = &ent->dir->fd;
if (fd->dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) return false;
sb->st_size = ((uint64) fd->nFileSizeHigh << 32) + fd->nFileSizeLow;
@@ -886,11 +886,12 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
void DeterminePaths(void)
{
char *s;
char *cfg;
char *s, *cfg;
wchar_t path[MAX_PATH];
_path.personal_dir = _path.game_data_dir = cfg = malloc(MAX_PATH);
GetCurrentDirectory(MAX_PATH - 1, cfg);
GetCurrentDirectoryW(MAX_PATH - 1, path);
WideCharToMultiByte(CP_UTF8, 0, path, -1, cfg, MAX_PATH, NULL, NULL);
cfg[0] = toupper(cfg[0]);
s = strchr(cfg, '\0');
@@ -911,10 +912,10 @@ void DeterminePaths(void)
_log_file = str_fmt("%sopenttd.log", _path.personal_dir);
// make (auto)save and scenario folder
CreateDirectory(_path.save_dir, NULL);
CreateDirectory(_path.autosave_dir, NULL);
CreateDirectory(_path.scenario_dir, NULL);
CreateDirectory(_path.heightmap_dir, NULL);
CreateDirectoryW(OTTD2FS(_path.save_dir), NULL);
CreateDirectoryW(OTTD2FS(_path.autosave_dir), NULL);
CreateDirectoryW(OTTD2FS(_path.scenario_dir), NULL);
CreateDirectoryW(OTTD2FS(_path.heightmap_dir), NULL);
}
/**
@@ -1009,3 +1010,38 @@ int64 GetTS(void)
QueryPerformanceCounter((LARGE_INTEGER*)&value);
return (__int64)(value * freq);
}
/** Convert from OpenTTD's encoding to that of the local environment
* First convert from UTF8 to wide-char, then to local
* @param name pointer to a valid string that will be converted
* @return pointer to a new stringbuffer that contains the converted string */
const wchar_t *OTTD2FS(const char *name)
{
static wchar_t ucs2_buf[MAX_PATH];
int len;
len = MultiByteToWideChar(CP_UTF8, 0, name, -1, ucs2_buf, lengthof(ucs2_buf));
if (len == 0) {
DEBUG(misc, 0) ("[utf8] Error converting '%s'. Errno %d", name, GetLastError());
return L"";
}
return (const wchar_t*)ucs2_buf;
}
/** Convert to OpenTTD's encoding from that of the local environment
* @param name pointer to a valid string that will be converted
* @return pointer to a new stringbuffer that contains the converted string */
const char *FS2OTTD(const wchar_t *name)
{
static char utf8_buf[512];
int len;
len = WideCharToMultiByte(CP_UTF8, 0, name, -1, utf8_buf, lengthof(utf8_buf), NULL, NULL);
if (len == 0) {
DEBUG(misc, 0) ("[utf8] Error converting string. Errno %d", GetLastError());
return "";
}
return (const char*)utf8_buf;
}