diff --git a/src/audio_file.cc b/src/audio_file.cc index d4a507d..43d35d8 100644 --- a/src/audio_file.cc +++ b/src/audio_file.cc @@ -69,7 +69,7 @@ int audioFileOpen(const char* fname, int flags, ...) *pm++ = 'b'; } - FILE* stream = fopen(path, mode); + FILE* stream = compat_fopen(path, mode); if (stream == NULL) { return -1; } diff --git a/src/config.cc b/src/config.cc index 3dc7e15..e741417 100644 --- a/src/config.cc +++ b/src/config.cc @@ -277,7 +277,7 @@ bool configRead(Config* config, const char* filePath, bool isDb) fileClose(stream); } } else { - FILE* stream = fopen(filePath, "rt"); + FILE* stream = compat_fopen(filePath, "rt"); if (stream != NULL) { while (fgets(string, sizeof(string), stream) != NULL) { configParseLine(config, string); @@ -323,7 +323,7 @@ bool configWrite(Config* config, const char* filePath, bool isDb) fileClose(stream); } else { - FILE* stream = fopen(filePath, "wt"); + FILE* stream = compat_fopen(filePath, "wt"); if (stream == NULL) { return false; } diff --git a/src/core.cc b/src/core.cc index 3e2131d..144427f 100644 --- a/src/core.cc +++ b/src/core.cc @@ -721,7 +721,7 @@ int screenshotHandlerDefaultImpl(int width, int height, unsigned char* data, uns for (index = 0; index < 100000; index++) { sprintf(fileName, "scr%.5d.bmp", index); - stream = fopen(fileName, "rb"); + stream = compat_fopen(fileName, "rb"); if (stream == NULL) { break; } @@ -733,7 +733,7 @@ int screenshotHandlerDefaultImpl(int width, int height, unsigned char* data, uns return -1; } - stream = fopen(fileName, "wb"); + stream = compat_fopen(fileName, "wb"); if (stream == NULL) { return -1; } diff --git a/src/debug.cc b/src/debug.cc index 810a487..959e023 100644 --- a/src/debug.cc +++ b/src/debug.cc @@ -53,7 +53,7 @@ void _debug_register_log(const char* fileName, const char* mode) fclose(_fd); } - _fd = fopen(fileName, mode); + _fd = compat_fopen(fileName, mode); gDebugPrintProc = _debug_log; } } diff --git a/src/dfile.cc b/src/dfile.cc index 9d71446..cb1cb63 100644 --- a/src/dfile.cc +++ b/src/dfile.cc @@ -16,7 +16,7 @@ DBase* dbaseOpen(const char* filePath) { assert(filePath); // "filename", "dfile.c", 74 - FILE* stream = fopen(filePath, "rb"); + FILE* stream = compat_fopen(filePath, "rb"); if (stream == NULL) { return NULL; } @@ -635,7 +635,7 @@ DFile* dfileOpenInternal(DBase* dbase, const char* filePath, const char* mode, D dfile->entry = entry; // Open stream to .DAT file. - dfile->stream = fopen(dbase->path, "rb"); + dfile->stream = compat_fopen(dbase->path, "rb"); if (dfile->stream == NULL) { goto err; } diff --git a/src/file_utils.cc b/src/file_utils.cc index 7edba4b..86beed1 100644 --- a/src/file_utils.cc +++ b/src/file_utils.cc @@ -2,6 +2,7 @@ // of regular __usercall. #include "file_utils.h" +#include "platform_compat.h" #include <stdio.h> #include <zlib.h> @@ -11,7 +12,7 @@ // 0x452740 int fileCopyDecompressed(const char* existingFilePath, const char* newFilePath) { - FILE* stream = fopen(existingFilePath, "rb"); + FILE* stream = compat_fopen(existingFilePath, "rb"); if (stream == NULL) { return -1; } @@ -22,8 +23,8 @@ int fileCopyDecompressed(const char* existingFilePath, const char* newFilePath) fclose(stream); if (magic[0] == 0x1F && magic[1] == 0x8B) { - gzFile inStream = gzopen(existingFilePath, "rb"); - FILE* outStream = fopen(newFilePath, "wb"); + gzFile inStream = compat_gzopen(existingFilePath, "rb"); + FILE* outStream = compat_fopen(newFilePath, "wb"); if (inStream != NULL && outStream != NULL) { for (;;) { @@ -58,7 +59,7 @@ int fileCopyDecompressed(const char* existingFilePath, const char* newFilePath) // 0x452804 int fileCopyCompressed(const char* existingFilePath, const char* newFilePath) { - FILE* inStream = fopen(existingFilePath, "rb"); + FILE* inStream = compat_fopen(existingFilePath, "rb"); if (inStream == NULL) { return -1; } @@ -74,7 +75,7 @@ int fileCopyCompressed(const char* existingFilePath, const char* newFilePath) fclose(inStream); fileCopy(existingFilePath, newFilePath, true); } else { - gzFile outStream = gzopen(newFilePath, "wb"); + gzFile outStream = compat_gzopen(newFilePath, "wb"); if (outStream == NULL) { fclose(inStream); return -1; @@ -100,7 +101,7 @@ int fileCopyCompressed(const char* existingFilePath, const char* newFilePath) // TODO: Check, implementation looks odd. int _gzdecompress_file(const char* existingFilePath, const char* newFilePath) { - FILE* stream = fopen(existingFilePath, "rb"); + FILE* stream = compat_fopen(existingFilePath, "rb"); if (stream == NULL) { return -1; } @@ -112,12 +113,12 @@ int _gzdecompress_file(const char* existingFilePath, const char* newFilePath) // TODO: Is it broken? if (magic[0] != 0x1F || magic[1] != 0x8B) { - gzFile gzstream = gzopen(existingFilePath, "rb"); + gzFile gzstream = compat_gzopen(existingFilePath, "rb"); if (gzstream == NULL) { return -1; } - stream = fopen(newFilePath, "wb"); + stream = compat_fopen(newFilePath, "wb"); if (stream == NULL) { gzclose(gzstream); return -1; @@ -145,9 +146,17 @@ int _gzdecompress_file(const char* existingFilePath, const char* newFilePath) // `bFailIfExists` param. Update callers accordingly. void fileCopy(const char* existingFilePath, const char* newFilePath, bool overwrite) { + char nativeExistingFilePath[COMPAT_MAX_PATH]; + strcpy(nativeExistingFilePath, existingFilePath); + compat_windows_path_to_native(nativeExistingFilePath); + + char nativeNewFilePath[COMPAT_MAX_PATH]; + strcpy(nativeNewFilePath, newFilePath); + compat_windows_path_to_native(nativeNewFilePath); + std::error_code ec; std::filesystem::copy_options options = overwrite ? std::filesystem::copy_options::overwrite_existing : std::filesystem::copy_options::none; - std::filesystem::copy_file(std::filesystem::path(existingFilePath), std::filesystem::path(newFilePath), options, ec); + std::filesystem::copy_file(std::filesystem::path(nativeExistingFilePath), std::filesystem::path(nativeNewFilePath), options, ec); } diff --git a/src/game_sound.cc b/src/game_sound.cc index 47eab43..be2198d 100644 --- a/src/game_sound.cc +++ b/src/game_sound.cc @@ -1703,7 +1703,7 @@ int gameSoundFindBackgroundSoundPathWithCopy(char* dest, const char* src) char inPath[COMPAT_MAX_PATH]; sprintf(inPath, "%s%s%s", _sound_music_path2, src, ".ACM"); - FILE* inStream = fopen(inPath, "rb"); + FILE* inStream = compat_fopen(inPath, "rb"); if (inStream == NULL) { if (gGameSoundDebugEnabled) { debugPrint("Unable to find music file %s to copy down.\n", src); @@ -1712,7 +1712,7 @@ int gameSoundFindBackgroundSoundPathWithCopy(char* dest, const char* src) return -1; } - FILE* outStream = fopen(outPath, "wb"); + FILE* outStream = compat_fopen(outPath, "wb"); if (outStream == NULL) { if (gGameSoundDebugEnabled) { debugPrint("Unable to open music file %s for copying to.", src); @@ -2026,7 +2026,7 @@ Sound* _gsound_get_sound_ready_for_effect() // 0x4524E0 bool _gsound_file_exists_f(const char* fname) { - FILE* f = fopen(fname, "rb"); + FILE* f = compat_fopen(fname, "rb"); if (f == NULL) { return false; } diff --git a/src/platform_compat.cc b/src/platform_compat.cc index 69da2c5..185f7e3 100644 --- a/src/platform_compat.cc +++ b/src/platform_compat.cc @@ -132,6 +132,10 @@ long compat_filelength(int fd) int compat_mkdir(const char* path) { + char nativePath[COMPAT_MAX_PATH]; + strcpy(nativePath, path); + compat_windows_path_to_native(nativePath); + std::error_code ec; if (std::filesystem::create_directory(std::filesystem::path(path), ec)) { return 0; @@ -150,3 +154,32 @@ unsigned int compat_timeGetTime() return static_cast<unsigned int>(std::chrono::duration_cast<std::chrono::milliseconds>(now - start).count()); #endif } + +FILE* compat_fopen(const char* path, const char* mode) +{ + char nativePath[COMPAT_MAX_PATH]; + strcpy(nativePath, path); + compat_windows_path_to_native(nativePath); + return fopen(nativePath, mode); +} + +gzFile compat_gzopen(const char* path, const char* mode) +{ + char nativePath[COMPAT_MAX_PATH]; + strcpy(nativePath, path); + compat_windows_path_to_native(nativePath); + return gzopen(nativePath, mode); +} + +void compat_windows_path_to_native(char* path) +{ +#ifndef _WIN32 + char* pch = path; + while (*pch != '\0') { + if (*pch == '\\') { + *pch = '/'; + } + pch++; + } +#endif +} diff --git a/src/platform_compat.h b/src/platform_compat.h index 77b762d..a2f6fe6 100644 --- a/src/platform_compat.h +++ b/src/platform_compat.h @@ -2,6 +2,9 @@ #define PLATFORM_COMPAT_H #include <stddef.h> +#include <stdio.h> + +#include <zlib.h> // TODO: This is compatibility cross-platform layer. Designed to have minimal // impact on the codebase. Remove once it's no longer needed. @@ -31,5 +34,8 @@ long compat_tell(int fileHandle); long compat_filelength(int fd); int compat_mkdir(const char* path); unsigned int compat_timeGetTime(); +FILE* compat_fopen(const char* path, const char* mode); +gzFile compat_gzopen(const char* path, const char* mode); +void compat_windows_path_to_native(char* path); #endif /* PLATFORM_COMPAT_H */ diff --git a/src/xfile.cc b/src/xfile.cc index 27589db..0354d63 100644 --- a/src/xfile.cc +++ b/src/xfile.cc @@ -65,7 +65,7 @@ XFile* xfileOpen(const char* filePath, const char* mode) char path[COMPAT_MAX_PATH]; if (drive[0] != '\0' || dir[0] == '\\' || dir[0] == '/' || dir[0] == '.') { // [filePath] is an absolute path. Attempt to open as plain stream. - stream->file = fopen(filePath, mode); + stream->file = compat_fopen(filePath, mode); if (stream->file == NULL) { free(stream); return NULL; @@ -91,7 +91,7 @@ XFile* xfileOpen(const char* filePath, const char* mode) sprintf(path, "%s\\%s", curr->path, filePath); // Attempt to open plain stream. - stream->file = fopen(path, mode); + stream->file = compat_fopen(path, mode); if (stream->file != NULL) { stream->type = XFILE_TYPE_FILE; break; @@ -103,7 +103,7 @@ XFile* xfileOpen(const char* filePath, const char* mode) if (stream->file == NULL) { // File was not opened during the loop above. Attempt to open file // relative to the current working directory. - stream->file = fopen(filePath, mode); + stream->file = compat_fopen(filePath, mode); if (stream->file == NULL) { free(stream); return NULL; @@ -125,7 +125,7 @@ XFile* xfileOpen(const char* filePath, const char* mode) fclose(stream->file); stream->type = XFILE_TYPE_GZFILE; - stream->gzfile = gzopen(path, mode); + stream->gzfile = compat_gzopen(path, mode); } else { // File is not gzipped. rewind(stream->file);