Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
/roms/usource.rom
/settings.c
/settings.h
/ui_menu_item_lookup_gen.c
/stamp-h
/stamp-h1
/stamp-h.in
Expand Down Expand Up @@ -124,3 +125,8 @@ xcuserdata
/fusepb/FuseX.xcodeproj/xcshareddata
/FuseX.dmg
/dist
/3rdparty/dist
*.dll
*.exe
/fusex-*
.idea/
179 changes: 179 additions & 0 deletions 3rdparty/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
# Makefile for building FuseX third-party libraries on Windows (MSYS2 MinGW-w64).
# Run from MSYS2 "MinGW 64-bit" shell: cd 3rdparty && make

SCRIPT_DIR := $(CURDIR)
DIST_PREFIX := $(SCRIPT_DIR)/dist

export PKG_CONFIG_PATH := $(DIST_PREFIX)/lib/pkgconfig:$(PKG_CONFIG_PATH)

RED := \033[0;31m
GREEN := \033[0;32m
YELLOW := \033[1;33m
NC := \033[0m

# Optional audiofile: only the legacy `audiofile-patched/` tree (from zip), not the
# submodule path, so default Windows deps stay minimal and build with current GCC.
AUDIOFILE_SRC := $(shell if [ -d "audiofile-patched" ]; then echo "audiofile-patched"; else echo ""; fi)

.PHONY: all clean distclean libspectrum audiofile libxml2 mbedtls check-tools check-libspectrum extract-audiofile extract-libxml2 libspectrum-with-audiofile

# Default: libspectrum (+ optional libxml2 / mbedtls if present).
all: check-tools check-libspectrum dist-dirs libspectrum
@if [ -d "libxml2-2.9.12" ] || [ -f "libxml2-2.9.12.tar.gz" ]; then \
$(MAKE) libxml2; \
fi
@if [ -d "mbedtls/src" ] && [ -f "mbedtls/src/Makefile" ]; then \
$(MAKE) mbedtls; \
fi
@echo ""
@echo "$(GREEN)=== Library build complete! ===$(NC)"
@echo ""
@echo "Libraries installed to: $(DIST_PREFIX)"
@echo " - DLLs: $(DIST_PREFIX)/bin/"
@echo " - Headers: $(DIST_PREFIX)/include/"
@echo " - pkg-config: $(DIST_PREFIX)/lib/pkgconfig/"
@echo ""
@echo "Built libraries:"
@echo " ✓ libspectrum"
@if [ -n "$(AUDIOFILE_SRC)" ]; then echo " ✓ audiofile"; fi
@if [ -d "libxml2-2.9.12" ]; then echo " ✓ libxml2"; fi
@if [ -d "mbedtls/src" ] && [ -f "mbedtls/src/Makefile" ]; then echo " ✓ mbedtls"; fi
@echo ""
@echo "You can now run ./build_win32.sh from the repository root."

dist-dirs:
@mkdir -p $(DIST_PREFIX)/bin
@mkdir -p $(DIST_PREFIX)/lib/pkgconfig
@mkdir -p $(DIST_PREFIX)/include
@echo "$(GREEN)Using local dist prefix: $(DIST_PREFIX)$(NC)"

check-tools:
@echo "$(GREEN)Checking for required tools...$(NC)"
@for tool in gcc make pkg-config; do \
if ! command -v $$tool >/dev/null 2>&1; then \
echo "$(RED)Error: $$tool is not installed$(NC)"; \
echo "Install with: pacman -S mingw-w64-x86_64-gcc mingw-w64-x86_64-make mingw-w64-x86_64-pkg-config"; \
exit 1; \
fi; \
echo " ✓ $$tool found"; \
done

check-libspectrum:
@echo ""
@echo "$(GREEN)Checking for libspectrum...$(NC)"
@if [ ! -d "libspectrum" ]; then \
echo "$(YELLOW)libspectrum submodule missing; initializing from repo root...$(NC)"; \
cd .. && git submodule update --init --recursive 3rdparty/libspectrum && cd 3rdparty; \
fi

extract-audiofile:
@if [ -f "audiofile-patched.zip" ] && [ ! -d "audiofile-patched" ]; then \
echo "$(GREEN)Extracting audiofile-patched.zip...$(NC)"; \
unzip -q audiofile-patched.zip; \
fi

extract-libxml2:
@if [ -f "libxml2-2.9.12.tar.gz" ] && [ ! -d "libxml2-2.9.12" ]; then \
echo "$(GREEN)Extracting libxml2...$(NC)"; \
tar -xzf libxml2-2.9.12.tar.gz; \
fi

libspectrum: dist-dirs check-libspectrum
@echo ""
@echo "$(GREEN)Building libspectrum (required)...$(NC)"
@cd libspectrum && \
if [ -f Makefile ]; then \
$(MAKE) distclean || true; \
fi && \
if [ ! -f configure ]; then \
./autogen.sh; \
fi && \
./configure --with-fake-glib --without-libaudiofile --without-libgcrypt \
--without-zlib --without-bzip2 --prefix="$(DIST_PREFIX)" && \
$(MAKE) && \
$(MAKE) install

audiofile: extract-audiofile
@afdir="$(AUDIOFILE_SRC)"; \
if test -z "$$afdir" && test -d audiofile-patched; then afdir=audiofile-patched; fi; \
if test -n "$$afdir"; then \
echo ""; \
echo "$(GREEN)Building audiofile (optional)...$(NC)"; \
cd "$$afdir" && \
if [ -f Makefile ]; then \
$(MAKE) distclean || true; \
fi && \
if [ ! -f configure ]; then \
./autogen.sh --disable-static --disable-flac --disable-docs --disable-examples; \
fi && \
./configure --disable-static --disable-flac --disable-docs --disable-examples --prefix="$(DIST_PREFIX)" && \
$(MAKE) && \
$(MAKE) install-strip; \
fi

libspectrum-with-audiofile: audiofile
@echo ""
@echo "$(GREEN)Rebuilding libspectrum with audiofile...$(NC)"
@cd libspectrum && \
$(MAKE) distclean || true && \
./autogen.sh && \
./configure --with-fake-glib --with-libaudiofile --without-libgcrypt \
--without-zlib --without-bzip2 --prefix="$(DIST_PREFIX)" && \
$(MAKE) && \
$(MAKE) install

libxml2: extract-libxml2
@if [ -d "libxml2-2.9.12" ]; then \
echo ""; \
echo "$(GREEN)Building libxml2 (optional)...$(NC)"; \
cd libxml2-2.9.12 && \
if [ -f Makefile ]; then \
$(MAKE) distclean || true; \
fi && \
./configure --disable-static --without-iconv --without-python --without-lzma --prefix="$(DIST_PREFIX)" && \
$(MAKE) && \
$(MAKE) install-strip; \
fi

mbedtls:
@if [ -d "mbedtls/src" ] && [ -f "mbedtls/src/Makefile" ]; then \
echo ""; \
echo "$(GREEN)Building mbedtls (optional)...$(NC)"; \
cd mbedtls/src && \
if [ -f library/Makefile ]; then \
$(MAKE) clean || true; \
fi && \
$(MAKE) WINDOWS=1 SHARED=1 no_test && \
mkdir -p "$(DIST_PREFIX)/include/mbedtls" && \
cp -rp include/mbedtls/* "$(DIST_PREFIX)/include/mbedtls/" && \
mkdir -p "$(DIST_PREFIX)/lib" && \
mkdir -p "$(DIST_PREFIX)/bin" && \
cd library && \
for lib in libmbedtls libmbedx509 libmbedcrypto; do \
if [ -f "$$lib.a" ]; then cp -f "$$lib.a" "$(DIST_PREFIX)/lib/" || true; fi; \
if [ -f "$$lib.dll.a" ]; then cp -f "$$lib.dll.a" "$(DIST_PREFIX)/lib/" || true; fi; \
if [ -f "$$lib.dll" ]; then cp -f "$$lib.dll" "$(DIST_PREFIX)/bin/" || true; fi; \
done; \
fi

clean:
@echo "$(YELLOW)Cleaning build artifacts...$(NC)"
@if [ -d "libspectrum" ] && [ -f "libspectrum/Makefile" ]; then \
cd libspectrum && $(MAKE) distclean || true; \
fi
@if [ -n "$(AUDIOFILE_SRC)" ] && [ -f "$(AUDIOFILE_SRC)/Makefile" ]; then \
cd "$(AUDIOFILE_SRC)" && $(MAKE) distclean || true; \
fi
@if [ -d "audiofile-patched" ] && [ -f "audiofile-patched/Makefile" ]; then \
cd audiofile-patched && $(MAKE) distclean || true; \
fi
@if [ -d "libxml2-2.9.12" ] && [ -f "libxml2-2.9.12/Makefile" ]; then \
cd libxml2-2.9.12 && $(MAKE) distclean || true; \
fi
@if [ -d "mbedtls/src" ] && [ -f "mbedtls/src/library/Makefile" ]; then \
cd mbedtls/src && $(MAKE) clean || true; \
fi

distclean: clean
@echo "$(YELLOW)Removing dist directory...$(NC)"
@rm -rf $(DIST_PREFIX)
17 changes: 16 additions & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ fuse_LDADD = \
$(X_LIBS) \
$(XML_LIBS)

if BUILD_SPECTRANET
fuse_LDADD += $(MBEDTLS_LIBS)
endif

if USE_SDL1
fuse_LDADD += $(SDL1_LIBS)
endif
Expand All @@ -77,10 +81,16 @@ fuse_DEPENDENCIES =

EXTRA_fuse_SOURCES =

BUILT_SOURCES = options.h settings.c settings.h
BUILT_SOURCES = options.h settings.c settings.h \
debugger/commandy.c debugger/commandy.h debugger/commandl.c

if COMPAT_WIN32
settings.c: settings-win32.pl settings.dat
$(AM_V_GEN)$(PERL) -I$(srcdir)/perl $(srcdir)/settings-win32.pl $(srcdir)/settings.dat > $@.tmp && mv $@.tmp $@
else
settings.c: settings.pl settings.dat
$(AM_V_GEN)$(PERL) -I$(srcdir)/perl $(srcdir)/settings.pl $(srcdir)/settings.dat > $@.tmp && mv $@.tmp $@
endif

settings.h: settings-header.pl settings.dat
$(AM_V_GEN)$(PERL) -I$(srcdir)/perl $(srcdir)/settings-header.pl $(srcdir)/settings.dat > $@.tmp && mv $@.tmp $@
Expand All @@ -104,6 +114,10 @@ if USE_SDL2
AM_CPPFLAGS += $(SDL2_CFLAGS)
endif

if BUILD_SPECTRANET
AM_CPPFLAGS += $(MBEDTLS_CFLAGS)
endif

AM_CFLAGS = $(WARN_CFLAGS) $(PTHREAD_CFLAGS)

noinst_HEADERS = bitmap.h \
Expand Down Expand Up @@ -154,6 +168,7 @@ EXTRA_DIST = AUTHORS \
menu_data.pl \
settings.dat \
settings.pl \
settings-win32.pl \
settings-header.pl

CLEANFILES = options.h \
Expand Down
118 changes: 118 additions & 0 deletions build_win32.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
#!/bin/bash
# FuseX — Windows distribution build (MSYS2 MinGW 64-bit).
# Prerequisite: MSYS2 with mingw-w64-x86_64 toolchain, perl, zip, 7zip (optional), NSIS (optional).

set -e

echo "=== Building FuseX Windows distribution ==="

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

if [[ -z "${MSYSTEM:-}" ]]; then
echo -e "${RED}Error: run this from MSYS2 (e.g. \"MSYS2 MinGW 64-bit\"), not plain PowerShell.${NC}"
exit 1
fi

if [[ "$MSYSTEM" != "MINGW64" && "$MSYSTEM" != "UCRT64" ]]; then
echo -e "${YELLOW}Warning: MINGW64 or UCRT64 is recommended (current: $MSYSTEM).${NC}"
fi

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd "$SCRIPT_DIR"

# Windows NSIS installs makensis.exe here but does not add it to MSYS PATH — match typical fuse dev setups.
for _nsis in "/c/Program Files/NSIS" "/c/Program Files (x86)/NSIS"; do
if [[ -d "$_nsis" ]] && [[ -x "$_nsis/makensis.exe" || -x "$_nsis/makensis" ]]; then
PATH="$_nsis:${PATH:-}"
export PATH
break
fi
done

# Code generators assume Unix line endings on option/menu data (avoid CRLF breakage under Windows).
for f in ui/options.dat menu_data.dat settings.dat keysyms.dat \
z80/opcodes_base.dat z80/opcodes_cb.dat z80/opcodes_ddfd.dat \
z80/opcodes_ddfdcb.dat z80/opcodes_ed.dat; do
if [[ -f "$f" ]]; then
sed -i 's/\r$//' "$f" 2>/dev/null || true
fi
done

echo -e "${GREEN}Directory: $SCRIPT_DIR${NC}"

echo -e "\n${GREEN}Checking tools...${NC}"
for tool in gcc make pkg-config perl; do
if ! command -v "$tool" &> /dev/null; then
echo -e "${RED}Missing: $tool${NC}"
case "$tool" in
perl) echo " pacman -S mingw-w64-x86_64-perl" ;;
*) echo " pacman -S mingw-w64-x86_64-$tool" ;;
esac
exit 1
fi
echo " OK $tool"
done

if [[ ! -d "$SCRIPT_DIR/3rdparty/dist/bin" ]] || [[ ! -f "$SCRIPT_DIR/3rdparty/dist/lib/libmbedtls.a" ]]; then
echo -e "\n${GREEN}Building 3rdparty (libspectrum, mbedTLS for Spectranet, optional deps)...${NC}"
( cd "$SCRIPT_DIR/3rdparty" && make -j"$(nproc 2>/dev/null || echo 4)" )
else
echo -e "\n${GREEN}Using existing 3rdparty/dist${NC}"
fi

DIST_PREFIX="$SCRIPT_DIR/3rdparty/dist"
export PKG_CONFIG_PATH="$DIST_PREFIX/lib/pkgconfig:${PKG_CONFIG_PATH:-}"

# Link the static archive explicitly (avoids picking /usr/local libspectrum.dll.a via libtool).
PC="$DIST_PREFIX/lib/pkgconfig/libspectrum.pc"
if [[ -f "$PC" ]]; then
sed -i 's|^Libs:.*|Libs: ${libdir}/libspectrum.a|' "$PC" 2>/dev/null || true
fi

# Static libspectrum from 3rdparty: strip dllimport so MinGW links the .a correctly.
if [[ -f "$DIST_PREFIX/include/libspectrum.h" ]]; then
sed -i 's/#define LIBSPECTRUM_API __declspec( dllimport )/#define LIBSPECTRUM_API/g' \
"$DIST_PREFIX/include/libspectrum.h" 2>/dev/null || true
fi
# Prefer the static archive: libspectrum.dll.a can make -lspectrum import from a DLL.
if [[ -f "$DIST_PREFIX/lib/libspectrum.a" && -f "$DIST_PREFIX/lib/libspectrum.dll.a" ]]; then
rm -f "$DIST_PREFIX/lib/libspectrum.dll.a"
echo " Removed libspectrum.dll.a (use static libspectrum.a)"
fi

echo -e "\n${GREEN}Generating configure if needed...${NC}"
if [[ ! -f configure ]]; then
./autogen.sh
else
echo " configure present"
fi

echo -e "\n${GREEN}Configuring FuseX...${NC}"

# Sockets enabled (default): Spectranet, gdbserver remote, etc. require Winsock on Windows.
CONFIGURE_OPTS=( --with-win32 --without-zlib --without-png --prefix=/usr/local )
if pkg-config --exists libxml-2.0 2>/dev/null; then
echo " with libxml2 (pkg-config)"
else
echo " without libxml2"
CONFIGURE_OPTS+=( --without-libxml2 )
fi

./configure "${CONFIGURE_OPTS[@]}"

echo -e "\n${GREEN}Building and creating Windows distribution (zip, 7z, installer if NSIS is available)...${NC}"
# Same as upstream fuse build_win32.sh: one target builds zip + 7z + setup.exe (see data/win32/distribution.mk).
if command -v makensis &>/dev/null || command -v makensis.exe &>/dev/null; then
make dist-win32 -j"$(nproc 2>/dev/null || echo 4)"
else
echo -e "${YELLOW}makensis not on PATH — building zip/7z only. Add NSIS to PATH or install to:${NC}"
echo " C:\\Program Files\\NSIS or C:\\Program Files (x86)\\NSIS"
make dist-win32-zip dist-win32-7z -j"$(nproc 2>/dev/null || echo 4)"
fi

echo -e "\n${GREEN}=== Done ===${NC}"
ls -la "$SCRIPT_DIR"/fusex-*-win32*.zip "$SCRIPT_DIR"/fusex-*-win32*.7z 2>/dev/null || true
ls -la "$SCRIPT_DIR"/fusex-*-win32-setup.exe 2>/dev/null || true
9 changes: 1 addition & 8 deletions compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,6 @@
#include <stdlib.h>
#include <sys/types.h>

#ifdef WIN32
#include <winsock2.h>
#else
#include <netinet/in.h>
#include <netinet/tcp.h>
#endif

/* Remove the gcc-specific incantations if we're not using gcc */
#ifdef __GNUC__

Expand Down Expand Up @@ -179,7 +172,6 @@ int compat_get_tap( const char *interface_name );

#ifdef WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#define COMPAT_ENOTCONN WSAENOTCONN
#define COMPAT_EWOULDBLOCK WSAEWOULDBLOCK
#define COMPAT_EINPROGRESS WSAEINPROGRESS
Expand All @@ -192,6 +184,7 @@ typedef SOCKADDR compat_sockaddr;
typedef int compat_socket_t;
#else /* #ifndef WIN32 && GEKKO */
#include <sys/socket.h>
#include <netinet/tcp.h>
#include <netdb.h>
#include <errno.h>
#define COMPAT_ENOTCONN ENOTCONN
Expand Down
Loading
Loading