Browse Source

Windows 9x MinGW build (#6619)

pull/6632/head
Gleb Mazovetskiy 3 years ago committed by GitHub
parent
commit
a95bcc10f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 66
      .github/workflows/Windows9x_MinGW.yml
  2. 20
      3rdParty/libfmt/CMakeLists.txt
  3. 8
      3rdParty/libmpq/CMakeLists.txt
  4. 4
      CMake/Platforms.cmake
  5. 25
      CMake/platforms/mingw9x.toolchain.cmake
  6. 22
      CMake/platforms/mingw9x/include/windef.h
  7. 38
      CMake/platforms/windows9x.cmake
  8. 2
      CMakeLists.txt
  9. 4
      Packaging/windows/mingw-prep.sh
  10. 48
      Packaging/windows/mingw9x-prep.sh
  11. 43
      Source/utils/file_util.cpp
  12. 49
      Source/utils/sdl2_to_1_2_backports.cpp
  13. 3
      Source/utils/stdcompat/filesystem.hpp

66
.github/workflows/Windows9x_MinGW.yml

@ -0,0 +1,66 @@
name: Windows 9x MinGW
on:
push:
branches:
- master
paths-ignore:
- '*.md'
- 'docs/**'
pull_request:
types: [ opened, synchronize ]
paths-ignore:
- '*.md'
- 'docs/**'
release:
types: [published]
paths-ignore:
- '*.md'
- 'docs/**'
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Create Build Environment
run: >
sudo apt-get update &&
sudo apt-get install -y cmake gcc-mingw-w64-i686 g++-mingw-w64-i686 mingw-w64-tools libz-mingw-w64-dev gettext dpkg-dev wget git sudo smpq &&
sudo rm /usr/i686-w64-mingw32/lib/libz.dll.a &&
sudo Packaging/windows/mingw9x-prep.sh
- name: Configure CMake
shell: bash
working-directory: ${{github.workspace}}
run: cmake -S. -Bbuild-windows9x -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF -DCPACK=ON -DCMAKE_TOOLCHAIN_FILE=../CMake/platforms/mingw9x.toolchain.cmake -DTARGET_PLATORM=windows9x
- name: Build
working-directory: ${{github.workspace}}
shell: bash
run: |
cmake --build build-windows9x -j $(nproc) --target package
mv build-windows9x/devilutionx.zip devilutionx-win9x.zip
- name: Upload-Package
if: ${{ !env.ACT }}
uses: actions/upload-artifact@v3
with:
path: devilutionx-win9x.zip
- name: Update Release
if: ${{ github.event_name == 'release' && !env.ACT }}
uses: svenstaro/upload-release-action@v2
with:
file: devilutionx-win9x.zip
overwrite: true

20
3rdParty/libfmt/CMakeLists.txt vendored

@ -15,16 +15,12 @@ else()
set(BUILD_SHARED_LIBS ON)
endif()
include(FetchContent)
if(NXDK)
# branch: nxdk-v10.0.0
FetchContent_Declare(libfmt
URL https://github.com/diasurgical/fmt/archive/e421e854efcb21ee641349bab604d91b34af26b8.tar.gz
URL_HASH MD5=ebaac86fca56d4ef4a162ef125433f6f
)
else()
FetchContent_Declare(libfmt
URL https://github.com/fmtlib/fmt/archive/refs/tags/10.1.1.tar.gz
URL_HASH MD5=0d41a16f1b3878d44e6fd7ff1f6cc45a
)
endif()
FetchContent_Declare(libfmt
URL https://github.com/fmtlib/fmt/archive/a8a73da7e44e26d7c18d752976522eff7a21e0bf.tar.gz
URL_HASH MD5=4ddd617a0921e919f1c2e6ab7c36c349
)
FetchContent_MakeAvailableExcludeFromAll(libfmt)
if(DEVILUTIONX_WINDOWS_NO_WCHAR)
target_compile_definitions(fmt PUBLIC FMT_WINDOWS_NO_WCHAR)
endif()

8
3rdParty/libmpq/CMakeLists.txt vendored

@ -10,8 +10,8 @@ include(functions/FetchContent_MakeAvailableExcludeFromAll)
include(FetchContent)
FetchContent_Declare(libmpq
URL https://github.com/diasurgical/libmpq/archive/2cf61ebd1ce78082e20dc1e23bd9d66aec7fc0d5.tar.gz
URL_HASH MD5=073d634575465e57d679a7498a666fe3
URL https://github.com/diasurgical/libmpq/archive/fc2ec5c0a83106f971602dec06dcdbc50a8bd5d4.tar.gz
URL_HASH MD5=1b3964264015792387f71f3f2325661d
)
FetchContent_MakeAvailableExcludeFromAll(libmpq)
@ -32,3 +32,7 @@ target_link_libraries(libmpq PRIVATE ZLIB::ZLIB BZip2::BZip2)
if(LIBMPQ_FILE_BUFFER_SIZE)
target_compile_definitions(libmpq PRIVATE "LIBMPQ_FILE_BUFFER_SIZE=${LIBMPQ_FILE_BUFFER_SIZE}")
endif()
if(DEVILUTIONX_WINDOWS_NO_WCHAR)
target_compile_definitions(libmpq PRIVATE LIBMPQ_WINDOWS_NO_WCHAR)
endif()

4
CMake/Platforms.cmake

@ -18,7 +18,7 @@ if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD|OpenBSD|DragonFly|NetBSD")
endif()
set(TARGET_PLATFORM host CACHE STRING "Target platform")
set_property(CACHE TARGET_PLATFORM PROPERTY STRINGS host retrofw rg99 rg350 gkd350h cpigamesh miyoo_mini)
set_property(CACHE TARGET_PLATFORM PROPERTY STRINGS host retrofw rg99 rg350 gkd350h cpigamesh miyoo_mini windows9x)
if(TARGET_PLATFORM STREQUAL "retrofw")
include(platforms/retrofw)
elseif(TARGET_PLATFORM STREQUAL "rg99")
@ -33,6 +33,8 @@ elseif(TARGET_PLATFORM STREQUAL "lepus")
include(platforms/lepus)
elseif(TARGET_PLATFORM STREQUAL "miyoo_mini")
include(platforms/miyoo_mini)
elseif(TARGET_PLATORM STREQUAL "windows9x")
include(platforms/windows9x)
endif()
if(NINTENDO_SWITCH)

25
CMake/platforms/mingw9x.toolchain.cmake

@ -0,0 +1,25 @@
SET(MINGW_CROSS TRUE)
SET(CROSS_PREFIX "/usr" CACHE STRING "crosstool-NG prefix")
SET(CMAKE_SYSTEM_NAME Windows)
# workaround
list(APPEND CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES "${CROSS_PREFIX}/i686-w64-mingw32/include")
list(PREPEND CMAKE_C_STANDARD_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_LIST_DIR}/mingw9x/include")
list(PREPEND CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_LIST_DIR}/mingw9x/include")
SET(CMAKE_C_COMPILER "i686-w64-mingw32-gcc")
SET(CMAKE_CXX_COMPILER "i686-w64-mingw32-g++")
set(CMAKE_RC_COMPILER "i686-w64-mingw32-windres")
set(PKG_CONFIG_EXECUTABLE "${CROSS_PREFIX}/bin/i686-w64-mingw32-pkg-config" CACHE STRING "Path to pkg-config")
SET(CMAKE_FIND_ROOT_PATH "${CROSS_PREFIX}/i686-w64-mingw32" "${CROSS_PREFIX}/i686-w64-mingw32/i686-w64-mingw32")
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(WIN32_INSTALL_DLLS "${CROSS_PREFIX}/i686-w64-mingw32/bin/SDL.dll")

22
CMake/platforms/mingw9x/include/windef.h

@ -0,0 +1,22 @@
#ifndef _WINDEF_OVERRIDE_
#define _WINDEF_OVERRIDE_
#include_next <windef.h>
// MinGW does not define these when _WIN32_WINNT < 0x0400
// but it declares functions that use it unconditionally.
typedef enum _FINDEX_INFO_LEVELS {
FindExInfoStandard,
FindExInfoBasic,
FindExInfoMaxInfoLevel
} FINDEX_INFO_LEVELS;
typedef enum _FINDEX_SEARCH_OPS {
FindExSearchNameMatch,
FindExSearchLimitToDirectories,
FindExSearchLimitToDevices,
FindExSearchMaxSearchOp
} FINDEX_SEARCH_OPS;
typedef void* SOLE_AUTHENTICATION_SERVICE;
#endif /* _WINDEF_ */

38
CMake/platforms/windows9x.cmake

@ -0,0 +1,38 @@
set(ASAN OFF)
set(UBSAN OFF)
set(DIST ON)
set(NONET ON)
set(DISABLE_ZERO_TIER ON)
set(USE_SDL1 ON)
set(DEVILUTIONX_SYSTEM_BZIP2 OFF)
set(DEVILUTIONX_SYSTEM_LIBFMT OFF)
set(DEVILUTIONX_STATIC_LIBSODIUM OFF)
# Compatibility with Windows 9x 8-bit mode and improved performance
set(SDL1_VIDEO_MODE_BPP 8)
set(SDL1_FORCE_DIRECT_RENDER ON)
set(DEVILUTIONX_WINDOWS_NO_WCHAR ON)
# `WINVER=0x0500` without `_WIN32_WINNT` is Windows 98.
# MinGW force-defines `_WIN32_WINNT=0xa00` if it isn't defined, so define it as 0.
add_definitions(-DWINVER=0x0500 -D_WIN32_WINDOWS=0x0500 -D_WIN32_WINNT=0)
list(APPEND DEVILUTIONX_PLATFORM_LINK_LIBRARIES
shlwapi
wsock32
ws2_32
wininet
)
if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
list(APPEND DEVILUTIONX_PLATFORM_COMPILE_OPTIONS "/W3" "/Zc:__cplusplus" "/utf-8")
list(APPEND DEVILUTIONX_PLATFORM_COMPILE_DEFINITIONS _CRT_SECURE_NO_WARNINGS)
else()
list(APPEND DEVILUTIONX_PLATFORM_COMPILE_OPTIONS $<$<CONFIG:Debug>:-gstabs>)
endif()
if(MINGW_CROSS)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/mingw")
endif()

2
CMakeLists.txt

@ -533,7 +533,7 @@ if(CPACK AND (APPLE OR BUILD_ASSETS_MPQ OR SRC_DIST))
DESTINATION "."
)
foreach(_SDL2_WIN32_DLL_PATH ${SDL2_WIN32_ALL_DLLS})
foreach(_SDL2_WIN32_DLL_PATH ${SDL2_WIN32_ALL_DLLS} ${WIN32_INSTALL_DLLS})
install(FILES "${_SDL2_WIN32_DLL_PATH}"
DESTINATION "."
)

4
Packaging/windows/mingw-prep.sh

@ -31,6 +31,10 @@ else
SUDO=""
fi
rm -rf "tmp-mingw-${MINGW_ARCH}-prep"
mkdir -p "tmp-mingw-${MINGW_ARCH}-prep"
cd "tmp-mingw-${MINGW_ARCH}-prep"
wget -q https://www.libsdl.org/release/SDL2-devel-${SDLDEV_VERS}-mingw.tar.gz -OSDL2-devel-${SDLDEV_VERS}-mingw.tar.gz
tar -xzf SDL2-devel-${SDLDEV_VERS}-mingw.tar.gz
$SUDO cp -r SDL2*/${MINGW_ARCH}/* ${MINGW_PREFIX}

48
Packaging/windows/mingw9x-prep.sh

@ -0,0 +1,48 @@
#!/usr/bin/env bash
SDLDEV_VERS=1.2.15
SODIUM_VERS=1.0.18
# exit when any command fails
set -euo pipefail
MINGW_ARCH=i686-w64-mingw32
SODIUM_ARCH=win32
# set MINGW_PREFIX
MINGW_PREFIX=/usr/${MINGW_ARCH}
if [ ! -d "${MINGW_PREFIX}" ]; then
echo "MinGW prefix not found (${MINGW_PREFIX})"
exit 1
else
echo "Installing to ${MINGW_PREFIX}"
fi
# only use sudo when necessary
if [ `id -u` -ne 0 ]; then
SUDO=sudo
else
SUDO=""
fi
rm -rf tmp-mingw9x-prep
mkdir -p tmp-mingw9x-prep
cd tmp-mingw9x-prep
curl --no-progress-meter -OL https://www.libsdl.org/release/SDL-devel-${SDLDEV_VERS}-mingw32.tar.gz
tar -xzf SDL-devel-${SDLDEV_VERS}-mingw32.tar.gz
$SUDO cp -r SDL-*/include/* ${MINGW_PREFIX}/include
$SUDO cp -r SDL-*/lib/* ${MINGW_PREFIX}/lib
$SUDO cp -r SDL-*/bin/* ${MINGW_PREFIX}/bin
wget -q https://github.com/jedisct1/libsodium/releases/download/${SODIUM_VERS}-RELEASE/libsodium-${SODIUM_VERS}-mingw.tar.gz -Olibsodium-${SODIUM_VERS}-mingw.tar.gz
tar -xzf libsodium-${SODIUM_VERS}-mingw.tar.gz --no-same-owner
$SUDO cp -r libsodium-${SODIUM_ARCH}/* ${MINGW_PREFIX}
# Fixup pkgconfig prefix:
find "${MINGW_PREFIX}/lib/pkgconfig/" -name '*.pc' -exec \
$SUDO sed -i "s|^prefix=.*|prefix=${MINGW_PREFIX}|" '{}' \;
# Fixup CMake prefix:
find "${MINGW_PREFIX}" -name '*.cmake' -exec \
$SUDO sed -i "s|/opt/local/${MINGW_ARCH}|${MINGW_PREFIX}|" '{}' \;

43
Source/utils/file_util.cpp

@ -4,6 +4,7 @@
#include <cerrno>
#include <cstdint>
#include <cstring>
#include <limits>
#include <string>
#include <string_view>
#include <vector>
@ -181,6 +182,24 @@ bool FileExistsAndIsWriteable(const char *path)
bool GetFileSize(const char *path, std::uintmax_t *size)
{
#ifdef _WIN32
#if defined(WINVER) && WINVER <= 0x0500 && (!defined(_WIN32_WINNT) || _WIN32_WINNT == 0)
HANDLE handle = ::CreateFileA(path, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
if (handle == INVALID_HANDLE_VALUE) {
LogError("File not found: {}", GetLastError());
return false;
}
DWORD fileSizeHigh;
const DWORD fileSizeLow = ::GetFileSize(handle, &fileSizeHigh);
if (fileSizeLow == INVALID_FILE_SIZE && GetLastError() != NO_ERROR) {
LogError("GetFileSize failed for {}: {}", path, GetLastError());
::CloseHandle(handle);
return false;
}
*size = (static_cast<uintmax_t>(fileSizeHigh) << 32) | fileSizeLow;
return true;
#else
WIN32_FILE_ATTRIBUTE_DATA attr;
#ifdef DEVILUTIONX_WINDOWS_NO_WCHAR
if (!GetFileAttributesExA(path, GetFileExInfoStandard, &attr)) {
@ -199,6 +218,7 @@ bool GetFileSize(const char *path, std::uintmax_t *size)
// C4293 in msvc when shifting a 32 bit type by 32 bits.
*size = static_cast<std::uintmax_t>(attr.nFileSizeHigh) << (sizeof(attr.nFileSizeHigh) * 8) | attr.nFileSizeLow;
return true;
#endif
#else
struct ::stat statResult;
if (::stat(path, &statResult) == -1)
@ -279,11 +299,18 @@ void RecursivelyCreateDir(const char *path)
bool ResizeFile(const char *path, std::uintmax_t size)
{
#ifdef _WIN32
#if defined(WINVER) && WINVER <= 0x0500 && (!defined(_WIN32_WINNT) || _WIN32_WINNT == 0)
if (size > std::numeric_limits<LONG>::max()) {
return false;
}
auto lisize = static_cast<LONG>(size);
#else
LARGE_INTEGER lisize;
lisize.QuadPart = static_cast<LONGLONG>(size);
if (lisize.QuadPart < 0) {
return false;
}
#endif
#ifdef DEVILUTIONX_WINDOWS_NO_WCHAR
HANDLE file = ::CreateFileA(path, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
#else
@ -296,7 +323,13 @@ bool ResizeFile(const char *path, std::uintmax_t size)
#endif
if (file == INVALID_HANDLE_VALUE) {
return false;
} else if (::SetFilePointerEx(file, lisize, NULL, FILE_BEGIN) == 0 || ::SetEndOfFile(file) == 0) {
} else if (
#if defined(WINVER) && WINVER <= 0x0500 && (!defined(_WIN32_WINNT) || _WIN32_WINNT == 0)
::SetFilePointer(file, lisize, NULL, FILE_BEGIN) == 0
#else
::SetFilePointerEx(file, lisize, NULL, FILE_BEGIN) == 0
#endif
|| ::SetEndOfFile(file) == 0) {
::CloseHandle(file);
return false;
}
@ -311,9 +344,10 @@ bool ResizeFile(const char *path, std::uintmax_t size)
void RenameFile(const char *from, const char *to)
{
#ifdef _WIN32
#ifdef DEVILUTIONX_WINDOWS_NO_WCHAR
::MoveFile(from, to);
#elif defined(_WIN32)
#else
const auto fromUtf16 = ToWideChar(from);
const auto toUtf16 = ToWideChar(to);
if (fromUtf16 == nullptr || toUtf16 == nullptr) {
@ -321,6 +355,7 @@ void RenameFile(const char *from, const char *to)
return;
}
::MoveFileW(&fromUtf16[0], &toUtf16[0]);
#endif // _WIN32
#elif defined(DVL_HAS_FILESYSTEM)
std::error_code ec;
std::filesystem::rename(std::filesystem::u8path(from), std::filesystem::u8path(to), ec);
@ -331,11 +366,12 @@ void RenameFile(const char *from, const char *to)
void CopyFileOverwrite(const char *from, const char *to)
{
#ifdef _WIN32
#ifdef DEVILUTIONX_WINDOWS_NO_WCHAR
if (!::CopyFile(from, to, /*bFailIfExists=*/false)) {
LogError("Failed to copy {} to {}", from, to);
}
#elif defined(_WIN32)
#else
const auto fromUtf16 = ToWideChar(from);
const auto toUtf16 = ToWideChar(to);
if (fromUtf16 == nullptr || toUtf16 == nullptr) {
@ -345,6 +381,7 @@ void CopyFileOverwrite(const char *from, const char *to)
if (!::CopyFileW(&fromUtf16[0], &toUtf16[0], /*bFailIfExists=*/false)) {
LogError("Failed to copy {} to {}", from, to);
}
#endif // _WIN32
#elif defined(__APPLE__)
::copyfile(from, to, nullptr, COPYFILE_ALL);
#elif defined(DVL_HAS_FILESYSTEM)

49
Source/utils/sdl2_to_1_2_backports.cpp

@ -1,18 +1,24 @@
#include "./sdl2_to_1_2_backports.h"
#include "utils/sdl2_to_1_2_backports.h"
#include <algorithm>
#include <cstddef>
#include <cstring>
#include <string_view>
#include "./console.h"
#if defined(_WIN32) && !defined(DEVILUTIONX_WINDOWS_NO_WCHAR)
#if defined(_WIN32)
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX 1
#ifndef DEVILUTIONX_WINDOWS_NO_WCHAR
#define UNICODE 1
#include <shlobj.h>
#endif
#include <windows.h>
#endif
#include <fmt/format.h>
#include "utils/console.h"
#define DEFAULT_PRIORITY SDL_LOG_PRIORITY_CRITICAL
#define DEFAULT_ASSERT_PRIORITY SDL_LOG_PRIORITY_WARN
#define DEFAULT_APPLICATION_PRIORITY SDL_LOG_PRIORITY_INFO
@ -696,7 +702,7 @@ char *SDL_GetPrefPath(const char *org, const char *app)
#else
namespace {
#if !defined(__QNXNTO__) && !defined(__amigaos__)
#if !defined(__QNXNTO__) && !defined(__amigaos__) && !(defined(WINVER) && WINVER <= 0x0500 && (!defined(_WIN32_WINNT) || _WIN32_WINNT == 0))
char *readSymLink(const char *path)
{
// From sdl2-2.0.9/src/filesystem/unix/SDL_sysfilesystem.c
@ -736,7 +742,17 @@ char *SDL_GetBasePath()
char *retval = NULL;
#if defined(__FREEBSD__)
#if defined(WINVER) && WINVER <= 0x0500 && (!defined(_WIN32_WINNT) || _WIN32_WINNT == 0)
TCHAR buffer[MAX_PATH] = { 0 };
GetModuleFileName(NULL, buffer, MAX_PATH);
const size_t len = std::string_view(buffer).size();
retval = static_cast<char *>(SDL_malloc(len + 1));
if (!retval) {
SDL_OutOfMemory();
return NULL;
}
SDL_memcpy(retval, buffer, len + 1);
#elif defined(__FREEBSD__)
char fullpath[PATH_MAX];
size_t buflen = sizeof(fullpath);
const int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
@ -747,8 +763,7 @@ char *SDL_GetBasePath()
return NULL;
}
}
#endif
#if defined(__OPENBSD__)
#elif defined(__OPENBSD__)
char **retvalargs;
size_t len;
const int mib[] = { CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ARGV };
@ -765,8 +780,7 @@ char *SDL_GetBasePath()
SDL_free(retvalargs);
}
#endif
#if defined(__SOLARIS__)
#elif defined(__SOLARIS__)
const char *path = getexecname();
if ((path != NULL) && (path[0] == '/')) { /* must be absolute path... */
retval = SDL_strdup(path);
@ -775,8 +789,7 @@ char *SDL_GetBasePath()
return NULL;
}
}
#endif
#if defined(__3DS__)
#elif defined(__3DS__)
retval = SDL_strdup("file:sdmc:/3ds/devilutionx/");
#elif defined(__amigaos__)
retval = SDL_strdup("PROGDIR:");
@ -892,20 +905,28 @@ char *SDL_GetPrefPath(const char *org, const char *app)
}
if (*org) {
SDL_snprintf(retval, len, "%s%s%s/%s", envr, append, org, app);
*fmt::format_to_n(retval, len - 1, "{}{}{}/{}", envr, append, org, app).out = '\0';
} else {
SDL_snprintf(retval, len, "%s%s%s", envr, append, app);
*fmt::format_to_n(retval, len - 1, "{}{}{}", envr, append, app).out = '\0';
}
for (ptr = retval + 1; *ptr; ptr++) {
if (*ptr == '/') {
*ptr = '\0';
#if defined(WINVER) && WINVER <= 0x0500 && (!defined(_WIN32_WINNT) || _WIN32_WINNT == 0)
if (mkdir(retval) != 0 && errno != EEXIST)
#else
if (mkdir(retval, 0700) != 0 && errno != EEXIST)
#endif
goto error;
*ptr = '/';
}
}
#if defined(WINVER) && WINVER <= 0x0500 && (!defined(_WIN32_WINNT) || _WIN32_WINNT == 0)
if (mkdir(retval) != 0 && errno != EEXIST) {
#else
if (mkdir(retval, 0700) != 0 && errno != EEXIST) {
#endif
error:
SDL_SetError("Couldn't create directory '%s': '%s'", retval, strerror(errno));
SDL_free(retval);

3
Source/utils/stdcompat/filesystem.hpp

@ -6,7 +6,8 @@
|| (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000)
#define DVL_NO_FILESYSTEM
#endif
#elif defined(NXDK) || (defined(_MSVC_LANG) && _MSVC_LANG < 201703L)
#elif defined(NXDK) || (defined(_MSVC_LANG) && _MSVC_LANG < 201703L) \
|| (defined(WINVER) && WINVER <= 0x0500 && (!defined(_WIN32_WINNT) || _WIN32_WINNT == 0))
#define DVL_NO_FILESYSTEM
#endif

Loading…
Cancel
Save