mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-22 14:24:33 +01:00
convert more platform functions over to utf8 and close #1713
This commit is contained in:
10
src/game.c
10
src/game.c
@@ -890,10 +890,18 @@ int save_game()
|
||||
|
||||
void game_autosave()
|
||||
{
|
||||
char path[MAX_PATH];
|
||||
utf8 path[MAX_PATH];
|
||||
utf8 backupPath[MAX_PATH];
|
||||
|
||||
platform_get_user_directory(path, "save");
|
||||
strcpy(backupPath, path);
|
||||
|
||||
strcat(path, "autosave.sv6");
|
||||
strcat(backupPath, "autosave.sv6.bak");
|
||||
|
||||
if (platform_file_exists(path)) {
|
||||
platform_file_copy(path, backupPath, true);
|
||||
}
|
||||
|
||||
SDL_RWops* rw = platform_sdl_rwfromfile(path, "wb+");
|
||||
if (rw != NULL) {
|
||||
|
||||
@@ -158,7 +158,7 @@ void title_sequence_duplicate_preset(int duplicate, const char *name)
|
||||
strncat(path, &separator, 1);
|
||||
strcat(path, gConfigTitleSequences.presets[preset].saves[i]);
|
||||
|
||||
platform_file_copy(srcPath, path);
|
||||
platform_file_copy(srcPath, path, false);
|
||||
}
|
||||
|
||||
if (loadmm) {
|
||||
@@ -237,7 +237,7 @@ void title_sequence_add_save(int preset, const char *path, const char *newName)
|
||||
// Add the appropriate extension if needed
|
||||
if (_stricmp(extension, ".sv6") != 0 && _stricmp(extension, ".sc6") != 0)
|
||||
strcat(newPath, ".sv6");
|
||||
platform_file_copy(path, newPath);
|
||||
platform_file_copy(path, newPath, false);
|
||||
|
||||
gConfigTitleSequences.presets[preset].num_saves++;
|
||||
gConfigTitleSequences.presets[preset].saves = realloc(gConfigTitleSequences.presets[preset].saves, sizeof(char[TITLE_SEQUENCE_MAX_SAVE_LENGTH]) * (size_t)gConfigTitleSequences.presets[preset].num_saves);
|
||||
|
||||
@@ -76,5 +76,8 @@ int utf8_insert_codepoint(utf8 *dst, uint32 codepoint);
|
||||
bool utf8_is_codepoint_start(utf8 *text);
|
||||
void utf8_remove_format_codes(utf8 *text);
|
||||
int utf8_get_codepoint_length(int codepoint);
|
||||
int utf8_length(const utf8 *text);
|
||||
wchar_t *utf8_to_widechar(const utf8 *src);
|
||||
utf8 *widechar_to_utf8(const wchar_t *src);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -83,3 +83,52 @@ int utf8_get_codepoint_length(int codepoint)
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of characters / codepoints in a UTF-8 string (not necessarily 1:1 with bytes and not including null
|
||||
* terminator).
|
||||
*/
|
||||
int utf8_length(const utf8 *text)
|
||||
{
|
||||
int codepoint;
|
||||
const utf8 *ch = text;
|
||||
|
||||
int count = 0;
|
||||
while ((codepoint = utf8_get_next(ch, &ch)) != 0) {
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
wchar_t *utf8_to_widechar(const utf8 *src)
|
||||
{
|
||||
wchar_t *result = malloc((utf8_length(src) + 1) * sizeof(wchar_t));
|
||||
wchar_t *dst = result;
|
||||
|
||||
const utf8 *ch = src;
|
||||
int codepoint;
|
||||
while ((codepoint = utf8_get_next(ch, &ch)) != 0) {
|
||||
if ((uint32)codepoint > 0xFFFF) {
|
||||
*dst++ = '?';
|
||||
} else {
|
||||
*dst++ = codepoint;
|
||||
}
|
||||
}
|
||||
*dst = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
utf8 *widechar_to_utf8(const wchar_t *src)
|
||||
{
|
||||
utf8 *result = malloc((wcslen(src) * 4) + 1);
|
||||
utf8 *dst = result;
|
||||
|
||||
for (; *src != 0; src++) {
|
||||
dst = utf8_write_codepoint(dst, *src);
|
||||
}
|
||||
*dst++ = 0;
|
||||
|
||||
int size = dst - result;
|
||||
return realloc(result, size);
|
||||
}
|
||||
|
||||
@@ -55,9 +55,9 @@ static struct { sint16 x, y, z; } _spritelocations1[MAX_SPRITES], _spritelocatio
|
||||
|
||||
static void openrct2_loop();
|
||||
|
||||
static void openrct2_copy_files_over(const char *originalDirectory, const char *newDirectory, const char *extension)
|
||||
static void openrct2_copy_files_over(const utf8 *originalDirectory, const utf8 *newDirectory, const utf8 *extension)
|
||||
{
|
||||
char *ch, filter[MAX_PATH], oldPath[MAX_PATH], newPath[MAX_PATH];
|
||||
utf8 *ch, filter[MAX_PATH], oldPath[MAX_PATH], newPath[MAX_PATH];
|
||||
int fileEnumHandle;
|
||||
file_info fileInfo;
|
||||
|
||||
@@ -86,7 +86,7 @@ static void openrct2_copy_files_over(const char *originalDirectory, const char *
|
||||
strcat(oldPath, fileInfo.path);
|
||||
|
||||
if (!platform_file_exists(newPath))
|
||||
platform_file_copy(oldPath, newPath);
|
||||
platform_file_copy(oldPath, newPath, false);
|
||||
}
|
||||
platform_enumerate_files_end(fileEnumHandle);
|
||||
|
||||
@@ -110,6 +110,7 @@ static void openrct2_copy_files_over(const char *originalDirectory, const char *
|
||||
platform_enumerate_directories_end(fileEnumHandle);
|
||||
}
|
||||
|
||||
// TODO move to platform
|
||||
static void openrct2_set_exe_path()
|
||||
{
|
||||
wchar_t exePath[MAX_PATH];
|
||||
@@ -131,18 +132,18 @@ static void openrct2_set_exe_path()
|
||||
*/
|
||||
static void openrct2_copy_original_user_files_over()
|
||||
{
|
||||
char path[MAX_PATH];
|
||||
utf8 path[MAX_PATH];
|
||||
|
||||
platform_get_user_directory(path, "save");
|
||||
openrct2_copy_files_over((char*)RCT2_ADDRESS_SAVED_GAMES_PATH, path, ".sv6");
|
||||
openrct2_copy_files_over((utf8*)RCT2_ADDRESS_SAVED_GAMES_PATH, path, ".sv6");
|
||||
|
||||
platform_get_user_directory(path, "landscape");
|
||||
openrct2_copy_files_over((char*)RCT2_ADDRESS_LANDSCAPES_PATH, path, ".sc6");
|
||||
openrct2_copy_files_over((utf8*)RCT2_ADDRESS_LANDSCAPES_PATH, path, ".sc6");
|
||||
}
|
||||
|
||||
bool openrct2_initialise()
|
||||
{
|
||||
char userPath[MAX_PATH];
|
||||
utf8 userPath[MAX_PATH];
|
||||
|
||||
platform_get_user_directory(userPath, NULL);
|
||||
if (!platform_ensure_directory_exists(userPath)) {
|
||||
|
||||
@@ -81,46 +81,46 @@ void platform_get_closest_resolution(int inWidth, int inHeight, int *outWidth, i
|
||||
void platform_init();
|
||||
void platform_draw();
|
||||
void platform_free();
|
||||
void platform_update_palette(char* colours, int start_index, int num_colours);
|
||||
void platform_update_palette(char *colours, int start_index, int num_colours);
|
||||
void platform_set_fullscreen_mode(int mode);
|
||||
void platform_set_cursor(char cursor);
|
||||
void platform_refresh_video();
|
||||
void platform_process_messages();
|
||||
int platform_scancode_to_rct_keycode(int sdl_key);
|
||||
void platform_start_text_input(char* buffer, int max_length);
|
||||
void platform_start_text_input(utf8 *buffer, int max_length);
|
||||
void platform_stop_text_input();
|
||||
SDL_RWops* platform_sdl_rwfromfile(const char* filename, const char* mode);
|
||||
SDL_RWops* platform_sdl_rwfromfile(const utf8* filename, const char* mode);
|
||||
|
||||
// Platform specific definitions
|
||||
char platform_get_path_separator();
|
||||
int platform_file_exists(const char *path);
|
||||
int platform_directory_exists(const char *path);
|
||||
int platform_original_game_data_exists(const char *path);
|
||||
time_t platform_file_get_modified_time(char* path);
|
||||
int platform_ensure_directory_exists(const char *path);
|
||||
int platform_directory_delete(const char *path);
|
||||
int platform_lock_single_instance();
|
||||
int platform_enumerate_files_begin(const char *pattern);
|
||||
int platform_enumerate_files_next(int handle, file_info *outFileInfo);
|
||||
bool platform_file_exists(const utf8 *path);
|
||||
bool platform_directory_exists(const utf8 *path);
|
||||
bool platform_original_game_data_exists(const utf8 *path);
|
||||
time_t platform_file_get_modified_time(const utf8* path);
|
||||
bool platform_ensure_directory_exists(const utf8 *path);
|
||||
bool platform_directory_delete(const utf8 *path);
|
||||
bool platform_lock_single_instance();
|
||||
int platform_enumerate_files_begin(const utf8 *pattern);
|
||||
bool platform_enumerate_files_next(int handle, file_info *outFileInfo);
|
||||
void platform_enumerate_files_end(int handle);
|
||||
int platform_enumerate_directories_begin(const char *directory);
|
||||
int platform_enumerate_directories_next(int handle, char *path);
|
||||
int platform_enumerate_directories_begin(const utf8 *directory);
|
||||
bool platform_enumerate_directories_next(int handle, utf8 *path);
|
||||
void platform_enumerate_directories_end(int handle);
|
||||
|
||||
// Returns the bitmask of the GetLogicalDrives function for windows, 0 for other systems
|
||||
int platform_get_drives();
|
||||
|
||||
int platform_file_copy(const char *srcPath, const char *dstPath);
|
||||
int platform_file_move(const char *srcPath, const char *dstPath);
|
||||
int platform_file_delete(const char *path);
|
||||
bool platform_file_copy(const utf8 *srcPath, const utf8 *dstPath, bool overwrite);
|
||||
bool platform_file_move(const utf8 *srcPath, const utf8 *dstPath);
|
||||
bool platform_file_delete(const utf8 *path);
|
||||
void platform_hide_cursor();
|
||||
void platform_show_cursor();
|
||||
void platform_get_cursor_position(int *x, int *y);
|
||||
void platform_set_cursor_position(int x, int y);
|
||||
unsigned int platform_get_ticks();
|
||||
void platform_get_user_directory(char *outPath, const char *subDirectory);
|
||||
void platform_show_messagebox(char *message);
|
||||
int platform_open_common_file_dialog(int type, char *title, char *filename, char *filterPattern, char *filterName);
|
||||
void platform_get_user_directory(utf8 *outPath, const utf8 *subDirectory);
|
||||
void platform_show_messagebox(utf8 *message);
|
||||
int platform_open_common_file_dialog(int type, utf8 *title, utf8 *filename, utf8 *filterPattern, utf8 *filterName);
|
||||
utf8 *platform_open_directory_browser(utf8 *title);
|
||||
uint8 platform_get_locale_currency();
|
||||
uint16 platform_get_locale_language();
|
||||
|
||||
@@ -90,55 +90,68 @@ char platform_get_path_separator()
|
||||
return '\\';
|
||||
}
|
||||
|
||||
int platform_file_exists(const char *path)
|
||||
bool platform_file_exists(const utf8 *path)
|
||||
{
|
||||
return !(GetFileAttributes(path) == INVALID_FILE_ATTRIBUTES && (GetLastError() == ERROR_FILE_NOT_FOUND || GetLastError() == ERROR_PATH_NOT_FOUND));
|
||||
wchar_t *wPath = utf8_to_widechar(path);
|
||||
DWORD result = GetFileAttributesW(wPath);
|
||||
DWORD error = GetLastError();
|
||||
free(wPath);
|
||||
return !(result == INVALID_FILE_ATTRIBUTES && (error == ERROR_FILE_NOT_FOUND || error == ERROR_PATH_NOT_FOUND));
|
||||
}
|
||||
|
||||
int platform_directory_exists(const char *path)
|
||||
bool platform_directory_exists(const utf8 *path)
|
||||
{
|
||||
DWORD dwAttrib = GetFileAttributes(path);
|
||||
wchar_t *wPath = utf8_to_widechar(path);
|
||||
DWORD dwAttrib = GetFileAttributesW(wPath);
|
||||
free(wPath);
|
||||
return dwAttrib != INVALID_FILE_ATTRIBUTES && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
|
||||
}
|
||||
|
||||
int platform_original_game_data_exists(const char *path)
|
||||
bool platform_original_game_data_exists(const utf8 *path)
|
||||
{
|
||||
char checkPath[MAX_PATH];
|
||||
utf8 checkPath[MAX_PATH];
|
||||
sprintf(checkPath, "%s%c%s%c%s", path, platform_get_path_separator(), "data", platform_get_path_separator(), "g1.dat");
|
||||
return platform_file_exists(checkPath);
|
||||
}
|
||||
|
||||
int platform_ensure_directory_exists(const char *path)
|
||||
bool platform_ensure_directory_exists(const utf8 *path)
|
||||
{
|
||||
if (platform_directory_exists(path))
|
||||
return 1;
|
||||
|
||||
return CreateDirectory(path, NULL);
|
||||
wchar_t *wPath = utf8_to_widechar(path);
|
||||
BOOL success = CreateDirectoryW(wPath, NULL);
|
||||
free(wPath);
|
||||
return success == TRUE;
|
||||
}
|
||||
|
||||
int platform_directory_delete(const char *path)
|
||||
bool platform_directory_delete(const utf8 *path)
|
||||
{
|
||||
char pszFrom[MAX_PATH];
|
||||
strcpy(pszFrom, path);
|
||||
wchar_t pszFrom[MAX_PATH];
|
||||
|
||||
wchar_t *wPath = utf8_to_widechar(path);
|
||||
wcsncpy(pszFrom, wPath, MAX_PATH);
|
||||
free(wPath);
|
||||
|
||||
// Needs to be double-null terminated for some weird reason
|
||||
pszFrom[strlen(path) + 1] = 0;
|
||||
|
||||
SHFILEOPSTRUCTA fileop;
|
||||
pszFrom[wcslen(wPath) + 1] = 0;
|
||||
|
||||
SHFILEOPSTRUCTW fileop;
|
||||
fileop.hwnd = NULL; // no status display
|
||||
fileop.wFunc = FO_DELETE; // delete operation
|
||||
fileop.pFrom = pszFrom; // source file name as double null terminated string
|
||||
fileop.pTo = NULL; // no destination needed
|
||||
fileop.fFlags = FOF_NOCONFIRMATION|FOF_SILENT; // do not prompt the user
|
||||
fileop.fFlags = FOF_NOCONFIRMATION | FOF_SILENT; // do not prompt the user
|
||||
|
||||
fileop.fAnyOperationsAborted = FALSE;
|
||||
fileop.lpszProgressTitle = NULL;
|
||||
fileop.hNameMappings = NULL;
|
||||
|
||||
int ret = SHFileOperationA(&fileop);
|
||||
int ret = SHFileOperationW(&fileop);
|
||||
return (ret == 0);
|
||||
}
|
||||
|
||||
int platform_lock_single_instance()
|
||||
bool platform_lock_single_instance()
|
||||
{
|
||||
HANDLE mutex, status;
|
||||
|
||||
@@ -150,67 +163,74 @@ int platform_lock_single_instance()
|
||||
if (status == NULL)
|
||||
log_error("unable to create mutex\n");
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
} else {
|
||||
// Already running
|
||||
CloseHandle(mutex);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
char active;
|
||||
char pattern[MAX_PATH];
|
||||
bool active;
|
||||
wchar_t pattern[MAX_PATH];
|
||||
HANDLE handle;
|
||||
WIN32_FIND_DATAA data;
|
||||
WIN32_FIND_DATAW data;
|
||||
utf8 *outFilename;
|
||||
} enumerate_file_info;
|
||||
static enumerate_file_info _enumerateFileInfoList[8] = { 0 };
|
||||
|
||||
int platform_enumerate_files_begin(const char *pattern)
|
||||
int platform_enumerate_files_begin(const utf8 *pattern)
|
||||
{
|
||||
int i;
|
||||
enumerate_file_info *enumFileInfo;
|
||||
|
||||
wchar_t *wPattern = utf8_to_widechar(pattern);
|
||||
|
||||
for (i = 0; i < countof(_enumerateFileInfoList); i++) {
|
||||
enumFileInfo = &_enumerateFileInfoList[i];
|
||||
if (!enumFileInfo->active) {
|
||||
strncpy(enumFileInfo->pattern, pattern, MAX_PATH);
|
||||
wcsncpy(enumFileInfo->pattern, wPattern, MAX_PATH);
|
||||
enumFileInfo->handle = NULL;
|
||||
enumFileInfo->active = 1;
|
||||
enumFileInfo->active = true;
|
||||
enumFileInfo->outFilename = NULL;
|
||||
|
||||
free(wPattern);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
free(wPattern);
|
||||
return INVALID_HANDLE;
|
||||
}
|
||||
|
||||
int platform_enumerate_files_next(int handle, file_info *outFileInfo)
|
||||
bool platform_enumerate_files_next(int handle, file_info *outFileInfo)
|
||||
{
|
||||
int result;
|
||||
bool result;
|
||||
enumerate_file_info *enumFileInfo;
|
||||
HANDLE findFileHandle;
|
||||
|
||||
enumFileInfo = &_enumerateFileInfoList[handle];
|
||||
|
||||
if (enumFileInfo->handle == NULL) {
|
||||
findFileHandle = FindFirstFile(enumFileInfo->pattern, &enumFileInfo->data);
|
||||
findFileHandle = FindFirstFileW(enumFileInfo->pattern, &enumFileInfo->data);
|
||||
if (findFileHandle != INVALID_HANDLE_VALUE) {
|
||||
enumFileInfo->handle = findFileHandle;
|
||||
result = 1;
|
||||
result = true;
|
||||
} else {
|
||||
result = 0;
|
||||
result = false;
|
||||
}
|
||||
} else {
|
||||
result = FindNextFile(enumFileInfo->handle, &enumFileInfo->data);
|
||||
result = FindNextFileW(enumFileInfo->handle, &enumFileInfo->data);
|
||||
}
|
||||
|
||||
if (result) {
|
||||
outFileInfo->path = enumFileInfo->data.cFileName;
|
||||
outFileInfo->path = enumFileInfo->outFilename = widechar_to_utf8(enumFileInfo->data.cFileName);
|
||||
outFileInfo->size = ((uint64)enumFileInfo->data.nFileSizeHigh << 32ULL) | (uint64)enumFileInfo->data.nFileSizeLow;
|
||||
outFileInfo->last_modified = ((uint64)enumFileInfo->data.ftLastWriteTime.dwHighDateTime << 32ULL) | (uint64)enumFileInfo->data.ftLastWriteTime.dwLowDateTime;
|
||||
return 1;
|
||||
return true;
|
||||
} else {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,32 +243,39 @@ void platform_enumerate_files_end(int handle)
|
||||
FindClose(enumFileInfo->handle);
|
||||
enumFileInfo->handle = NULL;
|
||||
}
|
||||
enumFileInfo->active = 0;
|
||||
enumFileInfo->active = false;
|
||||
SafeFree(enumFileInfo->outFilename);
|
||||
}
|
||||
|
||||
int platform_enumerate_directories_begin(const char *directory)
|
||||
int platform_enumerate_directories_begin(const utf8 *directory)
|
||||
{
|
||||
int i;
|
||||
enumerate_file_info *enumFileInfo;
|
||||
|
||||
if (strlen(directory) + 3 >= MAX_PATH)
|
||||
wchar_t *wDirectory = utf8_to_widechar(directory);
|
||||
|
||||
if (wcslen(wDirectory) + 3 >= MAX_PATH)
|
||||
return INVALID_HANDLE;
|
||||
|
||||
for (i = 0; i < countof(_enumerateFileInfoList); i++) {
|
||||
enumFileInfo = &_enumerateFileInfoList[i];
|
||||
if (!enumFileInfo->active) {
|
||||
strncpy(enumFileInfo->pattern, directory, MAX_PATH);
|
||||
strncat(enumFileInfo->pattern, "*", MAX_PATH);
|
||||
wcsncpy(enumFileInfo->pattern, wDirectory, MAX_PATH);
|
||||
wcsncat(enumFileInfo->pattern, L"*", MAX_PATH);
|
||||
enumFileInfo->handle = NULL;
|
||||
enumFileInfo->active = 1;
|
||||
enumFileInfo->active = true;
|
||||
enumFileInfo->outFilename = NULL;
|
||||
|
||||
free(wDirectory);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
free(wDirectory);
|
||||
return INVALID_HANDLE;
|
||||
}
|
||||
|
||||
int platform_enumerate_directories_next(int handle, char *path)
|
||||
bool platform_enumerate_directories_next(int handle, utf8 *path)
|
||||
{
|
||||
enumerate_file_info *enumFileInfo;
|
||||
HANDLE fileHandle;
|
||||
@@ -256,31 +283,32 @@ int platform_enumerate_directories_next(int handle, char *path)
|
||||
enumFileInfo = &_enumerateFileInfoList[handle];
|
||||
|
||||
if (enumFileInfo->handle == NULL) {
|
||||
fileHandle = FindFirstFile(enumFileInfo->pattern, &enumFileInfo->data);
|
||||
fileHandle = FindFirstFileW(enumFileInfo->pattern, &enumFileInfo->data);
|
||||
if (fileHandle != 0) {
|
||||
enumFileInfo->handle = fileHandle;
|
||||
} else {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!FindNextFile(enumFileInfo->handle, &enumFileInfo->data)) {
|
||||
return 0;
|
||||
if (!FindNextFileW(enumFileInfo->handle, &enumFileInfo->data)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
while (
|
||||
(enumFileInfo->data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0
|
||||
|| strchr(enumFileInfo->data.cFileName, '.') != NULL
|
||||
(enumFileInfo->data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0 ||
|
||||
wcschr(enumFileInfo->data.cFileName, '.') != NULL
|
||||
) {
|
||||
if (!FindNextFile(enumFileInfo->handle, &enumFileInfo->data)) {
|
||||
return 0;
|
||||
if (!FindNextFileW(enumFileInfo->handle, &enumFileInfo->data)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
memset(path, '\0', MAX_PATH);
|
||||
strncpy(path, enumFileInfo->data.cFileName, MAX_PATH);
|
||||
|
||||
utf8 *filename = widechar_to_utf8(enumFileInfo->data.cFileName);
|
||||
strncpy(path, filename, MAX_PATH);
|
||||
strncat(path, "\\", MAX_PATH);
|
||||
return 1;
|
||||
free(filename);
|
||||
return true;
|
||||
}
|
||||
|
||||
void platform_enumerate_directories_end(int handle)
|
||||
@@ -292,26 +320,40 @@ void platform_enumerate_directories_end(int handle)
|
||||
FindClose(enumFileInfo->handle);
|
||||
enumFileInfo->handle = NULL;
|
||||
}
|
||||
enumFileInfo->active = 0;
|
||||
enumFileInfo->active = false;
|
||||
}
|
||||
|
||||
int platform_get_drives(){
|
||||
int platform_get_drives()
|
||||
{
|
||||
return GetLogicalDrives();
|
||||
}
|
||||
|
||||
int platform_file_copy(const char *srcPath, const char *dstPath)
|
||||
bool platform_file_copy(const utf8 *srcPath, const utf8 *dstPath, bool overwrite)
|
||||
{
|
||||
return CopyFileA(srcPath, dstPath, TRUE);
|
||||
wchar_t *wSrcPath = utf8_to_widechar(srcPath);
|
||||
wchar_t *wDstPath = utf8_to_widechar(dstPath);
|
||||
BOOL success = CopyFileW(wSrcPath, wDstPath, overwrite ? FALSE : TRUE);
|
||||
free(wSrcPath);
|
||||
free(wDstPath);
|
||||
return success == TRUE;
|
||||
}
|
||||
|
||||
int platform_file_move(const char *srcPath, const char *dstPath)
|
||||
bool platform_file_move(const utf8 *srcPath, const utf8 *dstPath)
|
||||
{
|
||||
return MoveFileA(srcPath, dstPath);
|
||||
wchar_t *wSrcPath = utf8_to_widechar(srcPath);
|
||||
wchar_t *wDstPath = utf8_to_widechar(dstPath);
|
||||
BOOL success = MoveFileW(wSrcPath, wDstPath);
|
||||
free(wSrcPath);
|
||||
free(wDstPath);
|
||||
return success == TRUE;
|
||||
}
|
||||
|
||||
int platform_file_delete(const char *path)
|
||||
bool platform_file_delete(const utf8 *path)
|
||||
{
|
||||
return DeleteFileA(path);
|
||||
wchar_t *wPath = utf8_to_widechar(path);
|
||||
BOOL success = DeleteFileW(wPath);
|
||||
free(wPath);
|
||||
return success == TRUE;
|
||||
}
|
||||
|
||||
void platform_hide_cursor()
|
||||
@@ -347,11 +389,16 @@ unsigned int platform_get_ticks()
|
||||
return GetTickCount();
|
||||
}
|
||||
|
||||
void platform_get_user_directory(char *outPath, const char *subDirectory)
|
||||
void platform_get_user_directory(utf8 *outPath, const utf8 *subDirectory)
|
||||
{
|
||||
wchar_t wOutPath[MAX_PATH];
|
||||
char separator[2] = { platform_get_path_separator(), 0 };
|
||||
|
||||
if (SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_PERSONAL | CSIDL_FLAG_CREATE, NULL, 0, outPath))) {
|
||||
if (SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_PERSONAL | CSIDL_FLAG_CREATE, NULL, 0, wOutPath))) {
|
||||
utf8 *outPathTemp = widechar_to_utf8(wOutPath);
|
||||
strcpy(outPath, outPathTemp);
|
||||
free(outPathTemp);
|
||||
|
||||
strcat(outPath, separator);
|
||||
strcat(outPath, "OpenRCT2");
|
||||
strcat(outPath, separator);
|
||||
@@ -362,6 +409,8 @@ void platform_get_user_directory(char *outPath, const char *subDirectory)
|
||||
} else {
|
||||
outPath[0] = 0;
|
||||
}
|
||||
|
||||
free(wOutPath);
|
||||
}
|
||||
|
||||
void platform_show_messagebox(char *message)
|
||||
@@ -643,7 +692,8 @@ PCHAR *CommandLineToArgvA(PCHAR CmdLine, int *_argc)
|
||||
return argv;
|
||||
}
|
||||
|
||||
uint16 platform_get_locale_language(){
|
||||
uint16 platform_get_locale_language()
|
||||
{
|
||||
CHAR langCode[4];
|
||||
|
||||
if (GetLocaleInfo(LOCALE_USER_DEFAULT,
|
||||
@@ -689,23 +739,33 @@ uint16 platform_get_locale_language(){
|
||||
return LANGUAGE_UNDEFINED;
|
||||
}
|
||||
|
||||
time_t platform_file_get_modified_time(char* path){
|
||||
time_t platform_file_get_modified_time(const utf8* path)
|
||||
{
|
||||
WIN32_FILE_ATTRIBUTE_DATA data;
|
||||
if (!GetFileAttributesEx(path, GetFileExInfoStandard, &data))
|
||||
|
||||
wchar_t *wPath = utf8_to_widechar(path);
|
||||
BOOL result = GetFileAttributesExW(wPath, GetFileExInfoStandard, &data);
|
||||
free(wPath);
|
||||
|
||||
if (result) {
|
||||
ULARGE_INTEGER ull;
|
||||
ull.LowPart = data.ftLastWriteTime.dwLowDateTime;
|
||||
ull.HighPart = data.ftLastWriteTime.dwHighDateTime;
|
||||
return ull.QuadPart / 10000000ULL - 11644473600ULL;
|
||||
} else {
|
||||
return 0;
|
||||
ULARGE_INTEGER ull;
|
||||
ull.LowPart = data.ftLastWriteTime.dwLowDateTime;
|
||||
ull.HighPart = data.ftLastWriteTime.dwHighDateTime;
|
||||
return ull.QuadPart / 10000000ULL - 11644473600ULL;
|
||||
}
|
||||
}
|
||||
|
||||
uint8 platform_get_locale_currency(){
|
||||
uint8 platform_get_locale_currency()
|
||||
{
|
||||
CHAR currCode[4];
|
||||
|
||||
if (GetLocaleInfo(LOCALE_USER_DEFAULT,
|
||||
LOCALE_SINTLSYMBOL,
|
||||
(LPSTR)&currCode,
|
||||
sizeof(currCode)) == 0){
|
||||
sizeof(currCode)) == 0
|
||||
) {
|
||||
return CURRENCY_POUNDS;
|
||||
}
|
||||
if (strcmp(currCode, "GBP") == 0){
|
||||
@@ -741,15 +801,18 @@ uint8 platform_get_locale_currency(){
|
||||
return CURRENCY_POUNDS;
|
||||
}
|
||||
|
||||
uint8 platform_get_locale_measurement_format(){
|
||||
uint8 platform_get_locale_measurement_format()
|
||||
{
|
||||
UINT measurement_system;
|
||||
if (GetLocaleInfo(LOCALE_USER_DEFAULT,
|
||||
LOCALE_IMEASURE | LOCALE_RETURN_NUMBER,
|
||||
(LPSTR)&measurement_system,
|
||||
sizeof(measurement_system)) == 0){
|
||||
sizeof(measurement_system)) == 0
|
||||
) {
|
||||
return MEASUREMENT_FORMAT_IMPERIAL;
|
||||
}
|
||||
switch (measurement_system){
|
||||
|
||||
switch (measurement_system) {
|
||||
case 0:
|
||||
return MEASUREMENT_FORMAT_METRIC;
|
||||
case 1:
|
||||
@@ -758,16 +821,19 @@ uint8 platform_get_locale_measurement_format(){
|
||||
}
|
||||
}
|
||||
|
||||
uint8 platform_get_locale_temperature_format(){
|
||||
uint8 platform_get_locale_temperature_format()
|
||||
{
|
||||
// There does not seem to be a function to obtain this, just check the countries
|
||||
UINT country;
|
||||
if (GetLocaleInfo(LOCALE_USER_DEFAULT,
|
||||
LOCALE_IMEASURE | LOCALE_RETURN_NUMBER,
|
||||
(LPSTR)&country,
|
||||
sizeof(country)) == 0){
|
||||
sizeof(country)) == 0
|
||||
) {
|
||||
return TEMPERATURE_FORMAT_C;
|
||||
}
|
||||
switch (country){
|
||||
|
||||
switch (country) {
|
||||
case CTRY_UNITED_STATES:
|
||||
case CTRY_BELIZE:
|
||||
return TEMPERATURE_FORMAT_F;
|
||||
|
||||
@@ -3171,7 +3171,7 @@ int install_track(char* source_path, char* dest_name){
|
||||
// Set path for actual copy
|
||||
subsitute_path(dest_path, RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char), dest_name);
|
||||
|
||||
return platform_file_copy(source_path, dest_path);
|
||||
return platform_file_copy(source_path, dest_path, false);
|
||||
}
|
||||
|
||||
/* rct2: 0x006D13FE */
|
||||
|
||||
Reference in New Issue
Block a user