Skip to content

Commit 99dd8bb

Browse files
authored
Merge pull request #37 from speccytools/feature/win32-support
Windows support
2 parents 6aba54e + ef3d444 commit 99dd8bb

53 files changed

Lines changed: 2866 additions & 196 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
/roms/usource.rom
6767
/settings.c
6868
/settings.h
69+
/ui_menu_item_lookup_gen.c
6970
/stamp-h
7071
/stamp-h1
7172
/stamp-h.in
@@ -124,3 +125,8 @@ xcuserdata
124125
/fusepb/FuseX.xcodeproj/xcshareddata
125126
/FuseX.dmg
126127
/dist
128+
/3rdparty/dist
129+
*.dll
130+
*.exe
131+
/fusex-*
132+
.idea/

3rdparty/Makefile

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
# Makefile for building FuseX third-party libraries on Windows (MSYS2 MinGW-w64).
2+
# Run from MSYS2 "MinGW 64-bit" shell: cd 3rdparty && make
3+
4+
SCRIPT_DIR := $(CURDIR)
5+
DIST_PREFIX := $(SCRIPT_DIR)/dist
6+
7+
export PKG_CONFIG_PATH := $(DIST_PREFIX)/lib/pkgconfig:$(PKG_CONFIG_PATH)
8+
9+
RED := \033[0;31m
10+
GREEN := \033[0;32m
11+
YELLOW := \033[1;33m
12+
NC := \033[0m
13+
14+
# Optional audiofile: only the legacy `audiofile-patched/` tree (from zip), not the
15+
# submodule path, so default Windows deps stay minimal and build with current GCC.
16+
AUDIOFILE_SRC := $(shell if [ -d "audiofile-patched" ]; then echo "audiofile-patched"; else echo ""; fi)
17+
18+
.PHONY: all clean distclean libspectrum audiofile libxml2 mbedtls check-tools check-libspectrum extract-audiofile extract-libxml2 libspectrum-with-audiofile
19+
20+
# Default: libspectrum (+ optional libxml2 / mbedtls if present).
21+
all: check-tools check-libspectrum dist-dirs libspectrum
22+
@if [ -d "libxml2-2.9.12" ] || [ -f "libxml2-2.9.12.tar.gz" ]; then \
23+
$(MAKE) libxml2; \
24+
fi
25+
@if [ -d "mbedtls/src" ] && [ -f "mbedtls/src/Makefile" ]; then \
26+
$(MAKE) mbedtls; \
27+
fi
28+
@echo ""
29+
@echo "$(GREEN)=== Library build complete! ===$(NC)"
30+
@echo ""
31+
@echo "Libraries installed to: $(DIST_PREFIX)"
32+
@echo " - DLLs: $(DIST_PREFIX)/bin/"
33+
@echo " - Headers: $(DIST_PREFIX)/include/"
34+
@echo " - pkg-config: $(DIST_PREFIX)/lib/pkgconfig/"
35+
@echo ""
36+
@echo "Built libraries:"
37+
@echo " ✓ libspectrum"
38+
@if [ -n "$(AUDIOFILE_SRC)" ]; then echo " ✓ audiofile"; fi
39+
@if [ -d "libxml2-2.9.12" ]; then echo " ✓ libxml2"; fi
40+
@if [ -d "mbedtls/src" ] && [ -f "mbedtls/src/Makefile" ]; then echo " ✓ mbedtls"; fi
41+
@echo ""
42+
@echo "You can now run ./build_win32.sh from the repository root."
43+
44+
dist-dirs:
45+
@mkdir -p $(DIST_PREFIX)/bin
46+
@mkdir -p $(DIST_PREFIX)/lib/pkgconfig
47+
@mkdir -p $(DIST_PREFIX)/include
48+
@echo "$(GREEN)Using local dist prefix: $(DIST_PREFIX)$(NC)"
49+
50+
check-tools:
51+
@echo "$(GREEN)Checking for required tools...$(NC)"
52+
@for tool in gcc make pkg-config; do \
53+
if ! command -v $$tool >/dev/null 2>&1; then \
54+
echo "$(RED)Error: $$tool is not installed$(NC)"; \
55+
echo "Install with: pacman -S mingw-w64-x86_64-gcc mingw-w64-x86_64-make mingw-w64-x86_64-pkg-config"; \
56+
exit 1; \
57+
fi; \
58+
echo "$$tool found"; \
59+
done
60+
61+
check-libspectrum:
62+
@echo ""
63+
@echo "$(GREEN)Checking for libspectrum...$(NC)"
64+
@if [ ! -d "libspectrum" ]; then \
65+
echo "$(YELLOW)libspectrum submodule missing; initializing from repo root...$(NC)"; \
66+
cd .. && git submodule update --init --recursive 3rdparty/libspectrum && cd 3rdparty; \
67+
fi
68+
69+
extract-audiofile:
70+
@if [ -f "audiofile-patched.zip" ] && [ ! -d "audiofile-patched" ]; then \
71+
echo "$(GREEN)Extracting audiofile-patched.zip...$(NC)"; \
72+
unzip -q audiofile-patched.zip; \
73+
fi
74+
75+
extract-libxml2:
76+
@if [ -f "libxml2-2.9.12.tar.gz" ] && [ ! -d "libxml2-2.9.12" ]; then \
77+
echo "$(GREEN)Extracting libxml2...$(NC)"; \
78+
tar -xzf libxml2-2.9.12.tar.gz; \
79+
fi
80+
81+
libspectrum: dist-dirs check-libspectrum
82+
@echo ""
83+
@echo "$(GREEN)Building libspectrum (required)...$(NC)"
84+
@cd libspectrum && \
85+
if [ -f Makefile ]; then \
86+
$(MAKE) distclean || true; \
87+
fi && \
88+
if [ ! -f configure ]; then \
89+
./autogen.sh; \
90+
fi && \
91+
./configure --with-fake-glib --without-libaudiofile --without-libgcrypt \
92+
--without-zlib --without-bzip2 --prefix="$(DIST_PREFIX)" && \
93+
$(MAKE) && \
94+
$(MAKE) install
95+
96+
audiofile: extract-audiofile
97+
@afdir="$(AUDIOFILE_SRC)"; \
98+
if test -z "$$afdir" && test -d audiofile-patched; then afdir=audiofile-patched; fi; \
99+
if test -n "$$afdir"; then \
100+
echo ""; \
101+
echo "$(GREEN)Building audiofile (optional)...$(NC)"; \
102+
cd "$$afdir" && \
103+
if [ -f Makefile ]; then \
104+
$(MAKE) distclean || true; \
105+
fi && \
106+
if [ ! -f configure ]; then \
107+
./autogen.sh --disable-static --disable-flac --disable-docs --disable-examples; \
108+
fi && \
109+
./configure --disable-static --disable-flac --disable-docs --disable-examples --prefix="$(DIST_PREFIX)" && \
110+
$(MAKE) && \
111+
$(MAKE) install-strip; \
112+
fi
113+
114+
libspectrum-with-audiofile: audiofile
115+
@echo ""
116+
@echo "$(GREEN)Rebuilding libspectrum with audiofile...$(NC)"
117+
@cd libspectrum && \
118+
$(MAKE) distclean || true && \
119+
./autogen.sh && \
120+
./configure --with-fake-glib --with-libaudiofile --without-libgcrypt \
121+
--without-zlib --without-bzip2 --prefix="$(DIST_PREFIX)" && \
122+
$(MAKE) && \
123+
$(MAKE) install
124+
125+
libxml2: extract-libxml2
126+
@if [ -d "libxml2-2.9.12" ]; then \
127+
echo ""; \
128+
echo "$(GREEN)Building libxml2 (optional)...$(NC)"; \
129+
cd libxml2-2.9.12 && \
130+
if [ -f Makefile ]; then \
131+
$(MAKE) distclean || true; \
132+
fi && \
133+
./configure --disable-static --without-iconv --without-python --without-lzma --prefix="$(DIST_PREFIX)" && \
134+
$(MAKE) && \
135+
$(MAKE) install-strip; \
136+
fi
137+
138+
mbedtls:
139+
@if [ -d "mbedtls/src" ] && [ -f "mbedtls/src/Makefile" ]; then \
140+
echo ""; \
141+
echo "$(GREEN)Building mbedtls (optional)...$(NC)"; \
142+
cd mbedtls/src && \
143+
if [ -f library/Makefile ]; then \
144+
$(MAKE) clean || true; \
145+
fi && \
146+
$(MAKE) WINDOWS=1 SHARED=1 no_test && \
147+
mkdir -p "$(DIST_PREFIX)/include/mbedtls" && \
148+
cp -rp include/mbedtls/* "$(DIST_PREFIX)/include/mbedtls/" && \
149+
mkdir -p "$(DIST_PREFIX)/lib" && \
150+
mkdir -p "$(DIST_PREFIX)/bin" && \
151+
cd library && \
152+
for lib in libmbedtls libmbedx509 libmbedcrypto; do \
153+
if [ -f "$$lib.a" ]; then cp -f "$$lib.a" "$(DIST_PREFIX)/lib/" || true; fi; \
154+
if [ -f "$$lib.dll.a" ]; then cp -f "$$lib.dll.a" "$(DIST_PREFIX)/lib/" || true; fi; \
155+
if [ -f "$$lib.dll" ]; then cp -f "$$lib.dll" "$(DIST_PREFIX)/bin/" || true; fi; \
156+
done; \
157+
fi
158+
159+
clean:
160+
@echo "$(YELLOW)Cleaning build artifacts...$(NC)"
161+
@if [ -d "libspectrum" ] && [ -f "libspectrum/Makefile" ]; then \
162+
cd libspectrum && $(MAKE) distclean || true; \
163+
fi
164+
@if [ -n "$(AUDIOFILE_SRC)" ] && [ -f "$(AUDIOFILE_SRC)/Makefile" ]; then \
165+
cd "$(AUDIOFILE_SRC)" && $(MAKE) distclean || true; \
166+
fi
167+
@if [ -d "audiofile-patched" ] && [ -f "audiofile-patched/Makefile" ]; then \
168+
cd audiofile-patched && $(MAKE) distclean || true; \
169+
fi
170+
@if [ -d "libxml2-2.9.12" ] && [ -f "libxml2-2.9.12/Makefile" ]; then \
171+
cd libxml2-2.9.12 && $(MAKE) distclean || true; \
172+
fi
173+
@if [ -d "mbedtls/src" ] && [ -f "mbedtls/src/library/Makefile" ]; then \
174+
cd mbedtls/src && $(MAKE) clean || true; \
175+
fi
176+
177+
distclean: clean
178+
@echo "$(YELLOW)Removing dist directory...$(NC)"
179+
@rm -rf $(DIST_PREFIX)

Makefile.am

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ fuse_LDADD = \
6565
$(X_LIBS) \
6666
$(XML_LIBS)
6767

68+
if BUILD_SPECTRANET
69+
fuse_LDADD += $(MBEDTLS_LIBS)
70+
endif
71+
6872
if USE_SDL1
6973
fuse_LDADD += $(SDL1_LIBS)
7074
endif
@@ -77,10 +81,16 @@ fuse_DEPENDENCIES =
7781

7882
EXTRA_fuse_SOURCES =
7983

80-
BUILT_SOURCES = options.h settings.c settings.h
84+
BUILT_SOURCES = options.h settings.c settings.h \
85+
debugger/commandy.c debugger/commandy.h debugger/commandl.c
8186

87+
if COMPAT_WIN32
88+
settings.c: settings-win32.pl settings.dat
89+
$(AM_V_GEN)$(PERL) -I$(srcdir)/perl $(srcdir)/settings-win32.pl $(srcdir)/settings.dat > $@.tmp && mv $@.tmp $@
90+
else
8291
settings.c: settings.pl settings.dat
8392
$(AM_V_GEN)$(PERL) -I$(srcdir)/perl $(srcdir)/settings.pl $(srcdir)/settings.dat > $@.tmp && mv $@.tmp $@
93+
endif
8494

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

117+
if BUILD_SPECTRANET
118+
AM_CPPFLAGS += $(MBEDTLS_CFLAGS)
119+
endif
120+
107121
AM_CFLAGS = $(WARN_CFLAGS) $(PTHREAD_CFLAGS)
108122

109123
noinst_HEADERS = bitmap.h \
@@ -154,6 +168,7 @@ EXTRA_DIST = AUTHORS \
154168
menu_data.pl \
155169
settings.dat \
156170
settings.pl \
171+
settings-win32.pl \
157172
settings-header.pl
158173

159174
CLEANFILES = options.h \

build_win32.sh

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#!/bin/bash
2+
# FuseX — Windows distribution build (MSYS2 MinGW 64-bit).
3+
# Prerequisite: MSYS2 with mingw-w64-x86_64 toolchain, perl, zip, 7zip (optional), NSIS (optional).
4+
5+
set -e
6+
7+
echo "=== Building FuseX Windows distribution ==="
8+
9+
RED='\033[0;31m'
10+
GREEN='\033[0;32m'
11+
YELLOW='\033[1;33m'
12+
NC='\033[0m'
13+
14+
if [[ -z "${MSYSTEM:-}" ]]; then
15+
echo -e "${RED}Error: run this from MSYS2 (e.g. \"MSYS2 MinGW 64-bit\"), not plain PowerShell.${NC}"
16+
exit 1
17+
fi
18+
19+
if [[ "$MSYSTEM" != "MINGW64" && "$MSYSTEM" != "UCRT64" ]]; then
20+
echo -e "${YELLOW}Warning: MINGW64 or UCRT64 is recommended (current: $MSYSTEM).${NC}"
21+
fi
22+
23+
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
24+
cd "$SCRIPT_DIR"
25+
26+
# Windows NSIS installs makensis.exe here but does not add it to MSYS PATH — match typical fuse dev setups.
27+
for _nsis in "/c/Program Files/NSIS" "/c/Program Files (x86)/NSIS"; do
28+
if [[ -d "$_nsis" ]] && [[ -x "$_nsis/makensis.exe" || -x "$_nsis/makensis" ]]; then
29+
PATH="$_nsis:${PATH:-}"
30+
export PATH
31+
break
32+
fi
33+
done
34+
35+
# Code generators assume Unix line endings on option/menu data (avoid CRLF breakage under Windows).
36+
for f in ui/options.dat menu_data.dat settings.dat keysyms.dat \
37+
z80/opcodes_base.dat z80/opcodes_cb.dat z80/opcodes_ddfd.dat \
38+
z80/opcodes_ddfdcb.dat z80/opcodes_ed.dat; do
39+
if [[ -f "$f" ]]; then
40+
sed -i 's/\r$//' "$f" 2>/dev/null || true
41+
fi
42+
done
43+
44+
echo -e "${GREEN}Directory: $SCRIPT_DIR${NC}"
45+
46+
echo -e "\n${GREEN}Checking tools...${NC}"
47+
for tool in gcc make pkg-config perl; do
48+
if ! command -v "$tool" &> /dev/null; then
49+
echo -e "${RED}Missing: $tool${NC}"
50+
case "$tool" in
51+
perl) echo " pacman -S mingw-w64-x86_64-perl" ;;
52+
*) echo " pacman -S mingw-w64-x86_64-$tool" ;;
53+
esac
54+
exit 1
55+
fi
56+
echo " OK $tool"
57+
done
58+
59+
if [[ ! -d "$SCRIPT_DIR/3rdparty/dist/bin" ]] || [[ ! -f "$SCRIPT_DIR/3rdparty/dist/lib/libmbedtls.a" ]]; then
60+
echo -e "\n${GREEN}Building 3rdparty (libspectrum, mbedTLS for Spectranet, optional deps)...${NC}"
61+
( cd "$SCRIPT_DIR/3rdparty" && make -j"$(nproc 2>/dev/null || echo 4)" )
62+
else
63+
echo -e "\n${GREEN}Using existing 3rdparty/dist${NC}"
64+
fi
65+
66+
DIST_PREFIX="$SCRIPT_DIR/3rdparty/dist"
67+
export PKG_CONFIG_PATH="$DIST_PREFIX/lib/pkgconfig:${PKG_CONFIG_PATH:-}"
68+
69+
# Link the static archive explicitly (avoids picking /usr/local libspectrum.dll.a via libtool).
70+
PC="$DIST_PREFIX/lib/pkgconfig/libspectrum.pc"
71+
if [[ -f "$PC" ]]; then
72+
sed -i 's|^Libs:.*|Libs: ${libdir}/libspectrum.a|' "$PC" 2>/dev/null || true
73+
fi
74+
75+
# Static libspectrum from 3rdparty: strip dllimport so MinGW links the .a correctly.
76+
if [[ -f "$DIST_PREFIX/include/libspectrum.h" ]]; then
77+
sed -i 's/#define LIBSPECTRUM_API __declspec( dllimport )/#define LIBSPECTRUM_API/g' \
78+
"$DIST_PREFIX/include/libspectrum.h" 2>/dev/null || true
79+
fi
80+
# Prefer the static archive: libspectrum.dll.a can make -lspectrum import from a DLL.
81+
if [[ -f "$DIST_PREFIX/lib/libspectrum.a" && -f "$DIST_PREFIX/lib/libspectrum.dll.a" ]]; then
82+
rm -f "$DIST_PREFIX/lib/libspectrum.dll.a"
83+
echo " Removed libspectrum.dll.a (use static libspectrum.a)"
84+
fi
85+
86+
echo -e "\n${GREEN}Generating configure if needed...${NC}"
87+
if [[ ! -f configure ]]; then
88+
./autogen.sh
89+
else
90+
echo " configure present"
91+
fi
92+
93+
echo -e "\n${GREEN}Configuring FuseX...${NC}"
94+
95+
# Sockets enabled (default): Spectranet, gdbserver remote, etc. require Winsock on Windows.
96+
CONFIGURE_OPTS=( --with-win32 --without-zlib --without-png --prefix=/usr/local )
97+
if pkg-config --exists libxml-2.0 2>/dev/null; then
98+
echo " with libxml2 (pkg-config)"
99+
else
100+
echo " without libxml2"
101+
CONFIGURE_OPTS+=( --without-libxml2 )
102+
fi
103+
104+
./configure "${CONFIGURE_OPTS[@]}"
105+
106+
echo -e "\n${GREEN}Building and creating Windows distribution (zip, 7z, installer if NSIS is available)...${NC}"
107+
# Same as upstream fuse build_win32.sh: one target builds zip + 7z + setup.exe (see data/win32/distribution.mk).
108+
if command -v makensis &>/dev/null || command -v makensis.exe &>/dev/null; then
109+
make dist-win32 -j"$(nproc 2>/dev/null || echo 4)"
110+
else
111+
echo -e "${YELLOW}makensis not on PATH — building zip/7z only. Add NSIS to PATH or install to:${NC}"
112+
echo " C:\\Program Files\\NSIS or C:\\Program Files (x86)\\NSIS"
113+
make dist-win32-zip dist-win32-7z -j"$(nproc 2>/dev/null || echo 4)"
114+
fi
115+
116+
echo -e "\n${GREEN}=== Done ===${NC}"
117+
ls -la "$SCRIPT_DIR"/fusex-*-win32*.zip "$SCRIPT_DIR"/fusex-*-win32*.7z 2>/dev/null || true
118+
ls -la "$SCRIPT_DIR"/fusex-*-win32-setup.exe 2>/dev/null || true

compat.h

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,6 @@
3131
#include <stdlib.h>
3232
#include <sys/types.h>
3333

34-
#ifdef WIN32
35-
#include <winsock2.h>
36-
#else
37-
#include <netinet/in.h>
38-
#include <netinet/tcp.h>
39-
#endif
40-
4134
/* Remove the gcc-specific incantations if we're not using gcc */
4235
#ifdef __GNUC__
4336

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

180173
#ifdef WIN32
181174
#include <winsock2.h>
182-
#include <ws2tcpip.h>
183175
#define COMPAT_ENOTCONN WSAENOTCONN
184176
#define COMPAT_EWOULDBLOCK WSAEWOULDBLOCK
185177
#define COMPAT_EINPROGRESS WSAEINPROGRESS
@@ -192,6 +184,7 @@ typedef SOCKADDR compat_sockaddr;
192184
typedef int compat_socket_t;
193185
#else /* #ifndef WIN32 && GEKKO */
194186
#include <sys/socket.h>
187+
#include <netinet/tcp.h>
195188
#include <netdb.h>
196189
#include <errno.h>
197190
#define COMPAT_ENOTCONN ENOTCONN

0 commit comments

Comments
 (0)