Skip to content

Commit

Permalink
Windows 9x MinGW build (diasurgical#6619)
Browse files Browse the repository at this point in the history
  • Loading branch information
glebm authored and pionere committed Sep 22, 2023
1 parent 9e5caf7 commit 48297e4
Show file tree
Hide file tree
Showing 11 changed files with 348 additions and 14 deletions.
47 changes: 47 additions & 0 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,53 @@ jobs:
with:
path: build/devilutionx.zip
name: ${{ matrix.artifact }}
# MingW Win9x
build_w98:
needs: build_check
if: ${{ needs.build_check.outputs.should_run != 'false' }}
name: Nightly-MingW-Win9x
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
#name: [diablo-x86, hellfire-x86]
include:
# x86 builds
- name: diablo-w9x
cmakeargs: '-D DEVILUTIONX_SYSTEM_LIBSODIUM=OFF -D USE_PATCH=ON -D NONET=ON'
artifact: 'diablo-nightly-mingw-w9x.zip'
- name: hellfire-w9x
cmakeargs: '-D DEVILUTIONX_SYSTEM_LIBSODIUM=OFF -D USE_PATCH=ON -D NONET=ON -D HELLFIRE=ON'
artifact: 'hellfire-nightly-mingw-w9x.zip'
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 &&
sudo rm /usr/i686-w64-mingw32/lib/libz.dll.a &&
sudo Packaging/windows/mingw9x-prep.sh
- name: Configure CMake
shell: bash
working-directory: ${{ env.buildDir }}
run: cmake .. ${{ matrix.cmakeargs }} -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=../CMake/mingw9x.toolchain.cmake -DTARGET_PLATFORM=windows9x

- name: Build
working-directory: ${{ env.buildDir }}
shell: bash
run: cmake --build . -j $(nproc) --target package

# Upload the created artifact
- name: Upload
uses: actions/upload-artifact@v3
with:
path: ${{ env.buildDir }}/devilutionx.zip
name: ${{ matrix.artifact }}
# Linux-builds
# 64bit
build_linux64:
Expand Down
26 changes: 26 additions & 0 deletions CMake/mingw9x.toolchain.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#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")
#set(SDL1_EXEC_PREFIX "${CROSS_PREFIX}/i686-w64-mingw32")
22 changes: 22 additions & 0 deletions CMake/mingw9x/include/windef.h
Original file line number Diff line number Diff line change
@@ -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_ */
20 changes: 20 additions & 0 deletions CMake/windows9x_defs.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
set(ASAN OFF)
set(UBSAN OFF)

#set(NONET 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)
set(WINVER 0x0500)
set(_WIN32_WINNT 0)
59 changes: 51 additions & 8 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ if(VITA)
endif()

set(TARGET_PLATFORM host CACHE STRING "Target platform")
set_property(CACHE TARGET_PLATFORM PROPERTY STRINGS host lepus retrofw rg350 gkd350h cpigamesh)
set_property(CACHE TARGET_PLATFORM PROPERTY STRINGS host lepus retrofw rg350 gkd350h cpigamesh windows9x)
if(TARGET_PLATFORM STREQUAL "lepus")
include(lepus_defs)
elseif(TARGET_PLATFORM STREQUAL "retrofw")
Expand All @@ -67,6 +67,8 @@ elseif(TARGET_PLATFORM STREQUAL "gkd350h")
include(gkd350h_defs)
elseif(TARGET_PLATFORM STREQUAL "cpigamesh")
include(cpigamesh_defs)
elseif(TARGET_PLATFORM STREQUAL "windows9x")
include(windows9x_defs)
endif()

if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD|OpenBSD|DragonFly|NetBSD")
Expand All @@ -82,8 +84,13 @@ endif()
if(WIN32)
set(ASAN OFF)
set(UBSAN OFF)
if(_WIN32_WINNT)
if(DEFINED _WIN32_WINNT)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_WIN32_WINNT=${_WIN32_WINNT}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_WIN32_WINNT=${_WIN32_WINNT}")
endif()
if(DEFINED WINVER)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWINVER=${WINVER}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWINVER=${WINVER}")
endif()
set(USE_PATCH ON)
endif()
Expand Down Expand Up @@ -856,6 +863,8 @@ foreach(
SCREEN_HEIGHT
#TTF_FONT_DIR
#TTF_FONT_NAME
#WINVER
#_WIN32_WINNT
SDL1_VIDEO_MODE_BPP
SDL1_VIDEO_MODE_FLAGS
SDL1_VIDEO_MODE_SVID_FLAGS
Expand Down Expand Up @@ -1242,12 +1251,42 @@ if(CPACK)
set(CPACK_GENERATOR "ZIP")
set(CPACK_STRIP_FILES TRUE)
install(TARGETS ${BIN_TARGET} DESTINATION .)
#install(DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}/"
# DESTINATION "."
# PATTERN "*.lib" EXCLUDE
# PATTERN "*.exp" EXCLUDE
# PATTERN "*.h" EXCLUDE
#)
if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
file(GLOB _WIN32_ALL_DLLS
LIST_DIRECTORIES false
"${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}/*.dll")
else()
# find sdl.dll
if(USE_SDL1)
set(SDL_EXEC_PREFIX "${SDL_INCLUDE_DIRS}/../..")
elseif(NOT DEVILUTIONX_STATIC_SDL2)
set(SDL_EXEC_PREFIX ${SDL2_EXEC_PREFIX})
endif()
if(SDL_EXEC_PREFIX)
file(GLOB _SDL_WIN32_ALL_DLLS
LIST_DIRECTORIES false
"${SDL_EXEC_PREFIX}/bin/sdl*.dll" "${SDL_EXEC_PREFIX}/bin/SDL*.dll")
list(APPEND _WIN32_ALL_DLLS ${_SDL_WIN32_ALL_DLLS})
endif()
# find libsodium.dll
if(NOT NONET AND NOT DEVILUTIONX_STATIC_LIBSODIUM)
if(DEVILUTIONX_SYSTEM_LIBSODIUM)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(SODIUM_DLL_PATH ${sodium_DLL_DEBUG})
else()
set(SODIUM_DLL_PATH ${sodium_DLL_RELEASE})
endif()
else()
set(SODIUM_DLL_PATH "${CMAKE_BINARY_DIR}/libsodium.dll")
endif()
list(APPEND _WIN32_ALL_DLLS ${SODIUM_DLL_PATH})
endif()
endif()
foreach(_WIN32_DLL_PATH ${_WIN32_ALL_DLLS})
install(FILES "${_WIN32_DLL_PATH}"
DESTINATION "."
)
endforeach()
install(FILES "${PROJECT_SOURCE_DIR}/Packaging/windows/README.txt"
DESTINATION "."
)
Expand Down Expand Up @@ -1416,7 +1455,11 @@ message(STATUS "")
message(STATUS "Devilx was configured with the following options:")
message(STATUS "")
message(STATUS "Platform: ${CMAKE_SYSTEM}")
if(WIN32)
message(STATUS "Target platform: ${TARGET_PLATFORM} WinVer: ${WINVER} WinNT: ${_WIN32_WINNT}")
else()
message(STATUS "Target platform: ${TARGET_PLATFORM}")
endif()
message(STATUS "Compiler: ${CMAKE_C_COMPILER} .. (${CMAKE_CXX_COMPILER_ID})")
message(STATUS "Revision: ${PROJECT_VERSION} .. ${VERSION_NUM}")
message(STATUS "")
Expand Down
4 changes: 4 additions & 0 deletions Packaging/windows/mingw-prep.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,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
#wget -q https://www.libsdl.org/projects/SDL_ttf/release/SDL2_ttf-devel-${SDLTTF_VERS}-mingw.tar.gz -OSDL2_ttf-devel-${SDLTTF_VERS}-mingw.tar.gz
Expand Down
48 changes: 48 additions & 0 deletions Packaging/windows/mingw9x-prep.sh
Original file line number Diff line number Diff line change
@@ -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}|" '{}' \;
29 changes: 27 additions & 2 deletions Source/utils/file_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,22 @@ inline bool FileExists(const char* path)

inline bool GetFileSize(const char* path, std::uintmax_t* size)
{
#if defined(_WIN32)
#if defined(_WIN32) && (!defined(_WIN32_WINNT) || _WIN32_WINNT <= 0x0500)
HANDLE handle = ::CreateFileA(path, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
if (handle == INVALID_HANDLE_VALUE) {
return false;
}
::DWORD fileSizeHigh;
const DWORD fileSizeLow = ::GetFileSize(handle, &fileSizeHigh);
::CloseHandle(handle);
if (fileSizeLow == INVALID_FILE_SIZE) {
return false;
}
*size = (static_cast<uintmax_t>(fileSizeHigh) << 32) | fileSizeLow;
return true;
#elif defined(_WIN32)
WIN32_FILE_ATTRIBUTE_DATA attr;
/*int path_utf16_size = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0);
wchar_t *path_utf16 = new wchar_t[path_utf16_size];
Expand Down Expand Up @@ -95,7 +110,17 @@ inline bool WriteFile(const void* data, size_t size, FILE* f)

inline bool ResizeFile(const char* path, std::uintmax_t size)
{
#if defined(_WIN32)
#if defined(_WIN32) && (!defined(_WIN32_WINNT) || _WIN32_WINNT <= 0x0500)
HANDLE file = ::CreateFileA(path, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (file == INVALID_HANDLE_VALUE) {
return false;
}
::LONG fileSizeHigh = size >> 32;
::LONG fileSizeLow = size;
bool result = ::SetFilePointer(file, fileSizeLow, &fileSizeHigh, FILE_BEGIN) != 0 && ::SetEndOfFile(file) != 0;
::CloseHandle(file);
return result;
#elif defined(_WIN32)
LARGE_INTEGER lisize;
lisize.QuadPart = static_cast<LONGLONG>(size);
if (lisize.QuadPart < 0) {
Expand Down
39 changes: 38 additions & 1 deletion Source/utils/sdl2_to_1_2_backports.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
#include "sdl2_to_1_2_backports.h"

#ifdef USE_SDL1

#if defined(_WIN32)
// Suppress definitions of `min` and `max` macros by <windows.h>:
#define NOMINMAX 1
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif

#define DEFAULT_PRIORITY SDL_LOG_PRIORITY_CRITICAL
#define DEFAULT_ASSERT_PRIORITY SDL_LOG_PRIORITY_WARN
#define DEFAULT_APPLICATION_PRIORITY SDL_LOG_PRIORITY_INFO
Expand Down Expand Up @@ -485,7 +493,7 @@ int SDL_BlitScaled(SDL_Surface* src, SDL_Rect* srcrect,

// = Filesystem

#if !defined(__QNXNTO__) && !defined(__amigaos__)
#if !defined(__3DS__) && !defined(__QNXNTO__) && !defined(__amigaos__) && !defined(_WIN32)
static char* readSymLink(const char* path)
{
// From sdl2-2.0.9/src/filesystem/unix/SDL_sysfilesystem.c
Expand Down Expand Up @@ -524,6 +532,28 @@ char* SDL_GetBasePath()
return SDL_strdup("file:sdmc:/3ds/devilutionx/");
#elif defined(__amigaos__)
return SDL_strdup("PROGDIR:");
#elif defined(_WIN32)
char buffer[MAX_PATH];
::DWORD len = GetModuleFileNameA(NULL, buffer, MAX_PATH);
if (len == 0) {
SDL_SetError("SDL_GetBasePath failed.");
return NULL;
}
/* chop off filename. */
for ( ; len > 0; len--) {
if (buffer[len] == '\\') {
break;
}
}
len++;
char* retval = static_cast<char *>(SDL_malloc(len + 1));
if (retval == NULL) {
SDL_OutOfMemory();
return NULL;
}
SDL_memcpy(retval, buffer, len);
retval[len] = '\0';
return retval;
#else
// From sdl2-2.0.9/src/filesystem/unix/SDL_sysfilesystem.c

Expand Down Expand Up @@ -624,6 +654,13 @@ char* SDL_GetPrefPath(const char* org, const char* app)
return SDL_strdup("sdmc:/3ds/devilutionx/");
#elif defined(__amigaos__)
return SDL_strdup("PROGDIR:");
#elif defined(_WIN32)
//#if (!defined(_WIN32_WINNT) || _WIN32_WINNT <= 0x0500)
// On Windows9x there is no such thing as PrefPath. Simply use the current directory.
char *result = (char *)SDL_malloc(1);
*result = '\0';
return result;
//#endif
#else
// From sdl2-2.0.9/src/filesystem/unix/SDL_sysfilesystem.c
/*
Expand Down
Loading

0 comments on commit 48297e4

Please sign in to comment.