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);