Skip to content

Commit 15207f5

Browse files
authored
Fix MSVC 2005/2010 build: use boolean.h instead of stdbool.h (#116)
* Fix MSVC 2005/2010 build: replace stdbool.h with boolean.h MSVC versions prior to 2013 (VS12) don't ship <stdbool.h>. Use libretro-common's <boolean.h> which provides a compatible shim for old MSVC while delegating to <stdbool.h> elsewhere. Fixes GitLab CI: msvc05-i686, msvc10-i686, msvc10-x64. Made-with: Cursor * Expand CI to match libretro buildbot coverage Add targets missing from our GitHub Actions that the GitLab buildbot tests: - MSVC x64/x86 compilation check (cl.exe, catches stdbool.h/C89 issues) - macOS x86_64 (macos-13 Intel runner) - Android x86 and x86_64 - PS Vita (vitasdk Docker container) - Nintendo Switch (devkitPro Docker container) Add stdbool.h usage lint (must use boolean.h for MSVC 2005/2010 compat). Sync release.yml with new build targets so releases include all platforms. Made-with: Cursor * Fix C89 mid-block declarations in m68kinterface.c Move uint32_t pc_p_offset/pc_oldp_offset to function scope in M68KStateSave and M68KStateLoad. Expand C89 lint and MSVC compile check to include m68kinterface.c (hand-written, not machine-generated). Fixes MSVC 2005/2010 build failures on GitLab buildbot. Made-with: Cursor * Fix MSVC 2010 SSE2 build: replace _mm_set_epi64x _mm_set_epi64x is not available in MSVC 2010's emmintrin.h. Add SSE2_SET64 compat macro that uses _mm_set_epi32 with split 32-bit halves on MSVC < 2012, delegating to _mm_set_epi64x elsewhere. Also add blitter_simd_sse2.c to the GitHub Actions MSVC compile check so this class of intrinsic-availability issues is caught going forward. Made-with: Cursor
1 parent e5a74b5 commit 15207f5

6 files changed

Lines changed: 211 additions & 32 deletions

File tree

.github/workflows/c-cpp.yml

Lines changed: 114 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,13 @@ jobs:
4646
cc: 'clang'
4747
cxx: 'clang++'
4848

49-
# Windows
49+
- displayTargetName: 'macOS x86_64 (Clang)'
50+
artifact: 'virtualjaguar_libretro.dylib'
51+
os: macos-13
52+
cc: 'clang'
53+
cxx: 'clang++'
54+
55+
# Windows (MinGW)
5056
- displayTargetName: 'Windows x86_64 (MSYS2)'
5157
artifact: 'virtualjaguar_libretro.dll'
5258
os: windows-latest
@@ -71,28 +77,38 @@ jobs:
7177
os: ubuntu-latest
7278
emscripten: true
7379

74-
# Android NDK (arm64-v8a)
80+
# Android NDK
7581
- displayTargetName: 'Android arm64-v8a'
7682
artifact: 'libs/arm64-v8a/libretro.so'
7783
os: ubuntu-latest
7884
android: true
7985
android_abi: 'arm64-v8a'
8086

81-
# Android NDK (armeabi-v7a)
8287
- displayTargetName: 'Android armeabi-v7a'
8388
artifact: 'libs/armeabi-v7a/libretro.so'
8489
os: ubuntu-latest
8590
android: true
8691
android_abi: 'armeabi-v7a'
8792

88-
# iOS
93+
- displayTargetName: 'Android x86_64'
94+
artifact: 'libs/x86_64/libretro.so'
95+
os: ubuntu-latest
96+
android: true
97+
android_abi: 'x86_64'
98+
99+
- displayTargetName: 'Android x86'
100+
artifact: 'libs/x86/libretro.so'
101+
os: ubuntu-latest
102+
android: true
103+
android_abi: 'x86'
104+
105+
# iOS / tvOS
89106
- displayTargetName: 'iOS arm64'
90107
artifact: 'virtualjaguar_libretro_ios.dylib'
91108
os: macos-latest
92109
make_platform: 'ios-arm64'
93110
cross: true
94111

95-
# tvOS
96112
- displayTargetName: 'tvOS arm64'
97113
artifact: 'virtualjaguar_libretro_tvos.dylib'
98114
os: macos-latest
@@ -181,6 +197,79 @@ jobs:
181197
path: ${{ matrix.config.artifact }}
182198
if-no-files-found: error
183199

200+
msvc-check:
201+
name: MSVC ${{ matrix.arch }} compilation check
202+
runs-on: windows-latest
203+
strategy:
204+
fail-fast: false
205+
matrix:
206+
arch: [x64, x86]
207+
steps:
208+
- uses: actions/checkout@v4
209+
210+
- uses: ilammy/msvc-dev-cmd@v1
211+
with:
212+
arch: ${{ matrix.arch }}
213+
214+
- name: Compile all sources with cl.exe
215+
shell: cmd
216+
run: |
217+
cl.exe /c /W3 /O2 /DNDEBUG /D_CRT_SECURE_NO_DEPRECATE ^
218+
/I. /Isrc /Isrc\m68000 /Ilibretro-common\include ^
219+
/D__LIBRETRO__ /DINLINE="_inline" ^
220+
libretro.c ^
221+
src\blitter.c src\dac.c src\dsp.c src\file.c ^
222+
src\gpu.c src\jaguar.c src\jerry.c src\tom.c src\op.c ^
223+
src\cdintf.c src\cdrom.c src\crc32.c src\event.c ^
224+
src\eeprom.c src\filedb.c src\joystick.c src\settings.c ^
225+
src\memtrack.c src\mmu.c src\vjag_memory.c ^
226+
src\universalhdr.c src\wavetable.c ^
227+
src\jagbios.c src\jagbios2.c ^
228+
src\jagcdbios.c src\jagdevcdbios.c ^
229+
src\jagstub1bios.c src\jagstub2bios.c ^
230+
src\m68000\m68kinterface.c ^
231+
src\blitter_simd_scalar.c ^
232+
src\blitter_simd_sse2.c
233+
echo MSVC compilation check passed
234+
235+
vita-build:
236+
name: build-PS Vita
237+
runs-on: ubuntu-latest
238+
container:
239+
image: vitasdk/vitasdk:latest
240+
steps:
241+
- uses: actions/checkout@v4
242+
243+
- name: Build
244+
run: make -j4 platform=vita
245+
246+
- name: Upload artifact
247+
uses: actions/upload-artifact@v4
248+
with:
249+
name: PS Vita
250+
path: virtualjaguar_libretro_vita.a
251+
if-no-files-found: error
252+
253+
switch-build:
254+
name: build-Nintendo Switch
255+
runs-on: ubuntu-latest
256+
container:
257+
image: devkitpro/devkita64:latest
258+
steps:
259+
- uses: actions/checkout@v4
260+
261+
- name: Build
262+
run: make -j4 platform=libnx
263+
env:
264+
DEVKITPRO: /opt/devkitpro
265+
266+
- name: Upload artifact
267+
uses: actions/upload-artifact@v4
268+
with:
269+
name: Nintendo Switch
270+
path: virtualjaguar_libretro_libnx.a
271+
if-no-files-found: error
272+
184273
c89-lint:
185274
name: C89 compliance check
186275
runs-on: ubuntu-latest
@@ -191,10 +280,9 @@ jobs:
191280
run: |
192281
echo "==> Checking C89 compliance (catches MSVC C89 errors)..."
193282
FAILED=0
194-
for f in libretro.c src/*.c; do
195-
# Skip machine-generated files
283+
for f in libretro.c src/*.c src/m68000/m68kinterface.c; do
196284
case "$f" in
197-
src/m68000/*|src/jag*bios*.c|src/jagstub*bios.c|src/blitter_simd_neon.c|src/blitter_simd_sse2.c) continue ;;
285+
src/m68000/cpu*.c|src/m68000/read*.c|src/jag*bios*.c|src/jagstub*bios.c|src/blitter_simd_neon.c|src/blitter_simd_sse2.c) continue ;;
198286
esac
199287
if ! gcc -fsyntax-only -std=gnu89 \
200288
-Werror=declaration-after-statement \
@@ -209,3 +297,21 @@ jobs:
209297
exit 1
210298
fi
211299
echo "==> All files pass C89 declaration check"
300+
301+
- name: Check for stdbool.h usage (use boolean.h instead)
302+
run: |
303+
echo "==> Checking for direct stdbool.h includes..."
304+
FAILED=0
305+
for f in libretro.c src/*.c src/*.h; do
306+
case "$f" in
307+
src/boolean.h) continue ;;
308+
esac
309+
if grep -n '#include.*<stdbool\.h>' "$f" 2>/dev/null; then
310+
echo "::error file=$f::Use <boolean.h> instead of <stdbool.h> (MSVC 2005/2010 compat)"
311+
FAILED=1
312+
fi
313+
done
314+
if [ "$FAILED" = "1" ]; then
315+
exit 1
316+
fi
317+
echo "==> No direct stdbool.h includes found"

.github/workflows/release.yml

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ jobs:
4040
cc: clang
4141
cxx: clang++
4242

43+
- platform: macos-x86_64
44+
artifact: virtualjaguar_libretro.dylib
45+
os: macos-13
46+
cc: clang
47+
cxx: clang++
48+
4349
# Windows
4450
- platform: windows-x86_64
4551
artifact: virtualjaguar_libretro.dll
@@ -78,13 +84,24 @@ jobs:
7884
android: true
7985
android_abi: 'armeabi-v7a'
8086

81-
# iOS
87+
- platform: android-x86_64
88+
artifact: libs/x86_64/libretro.so
89+
os: ubuntu-latest
90+
android: true
91+
android_abi: 'x86_64'
92+
93+
- platform: android-x86
94+
artifact: libs/x86/libretro.so
95+
os: ubuntu-latest
96+
android: true
97+
android_abi: 'x86'
98+
99+
# iOS / tvOS
82100
- platform: ios-arm64
83101
artifact: virtualjaguar_libretro_ios.dylib
84102
os: macos-latest
85103
make_platform: 'ios-arm64'
86104

87-
# tvOS
88105
- platform: tvos-arm64
89106
artifact: virtualjaguar_libretro_tvos.dylib
90107
os: macos-latest
@@ -156,8 +173,56 @@ jobs:
156173
path: dist/
157174
if-no-files-found: error
158175

176+
vita-build:
177+
name: build-vita
178+
runs-on: ubuntu-latest
179+
container:
180+
image: vitasdk/vitasdk:latest
181+
steps:
182+
- uses: actions/checkout@v4
183+
184+
- name: Build
185+
run: make -j4 platform=vita
186+
187+
- name: Package
188+
run: |
189+
mkdir -p dist
190+
cp virtualjaguar_libretro_vita.a dist/virtualjaguar_libretro-vita.a
191+
192+
- name: Upload artifact
193+
uses: actions/upload-artifact@v4
194+
with:
195+
name: virtualjaguar_libretro-vita
196+
path: dist/
197+
if-no-files-found: error
198+
199+
switch-build:
200+
name: build-switch
201+
runs-on: ubuntu-latest
202+
container:
203+
image: devkitpro/devkita64:latest
204+
steps:
205+
- uses: actions/checkout@v4
206+
207+
- name: Build
208+
run: make -j4 platform=libnx
209+
env:
210+
DEVKITPRO: /opt/devkitpro
211+
212+
- name: Package
213+
run: |
214+
mkdir -p dist
215+
cp virtualjaguar_libretro_libnx.a dist/virtualjaguar_libretro-switch.a
216+
217+
- name: Upload artifact
218+
uses: actions/upload-artifact@v4
219+
with:
220+
name: virtualjaguar_libretro-switch
221+
path: dist/
222+
if-no-files-found: error
223+
159224
release:
160-
needs: build
225+
needs: [build, vita-build, switch-build]
161226
runs-on: ubuntu-latest
162227
steps:
163228
- uses: actions/checkout@v4

src/blitter_simd.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#define BLITTER_SIMD_H
1414

1515
#include <stdint.h>
16-
#include <stdbool.h>
16+
#include <boolean.h>
1717

1818
typedef struct
1919
{

src/blitter_simd_sse2.c

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,16 @@
1212
#include <emmintrin.h> /* SSE2 */
1313
#include <string.h> /* memcpy for type-punning extract */
1414

15-
/* _mm_cvtsi128_si64 only exists on x86_64 (needs 64-bit GP register).
16-
* memcpy from the __m128i is portable, alignment-safe, and compilers
17-
* optimize it to a single register move. */
15+
/* _mm_set_epi64x doesn't exist in MSVC 2010 and earlier.
16+
* Build from two 32-bit halves instead (pure SSE2). */
17+
#if defined(_MSC_VER) && _MSC_VER < 1700
18+
#define SSE2_SET64(hi, lo) \
19+
_mm_set_epi32((int)((uint64_t)(hi) >> 32), (int)(hi), \
20+
(int)((uint64_t)(lo) >> 32), (int)(lo))
21+
#else
22+
#define SSE2_SET64(hi, lo) _mm_set_epi64x((int64_t)(hi), (int64_t)(lo))
23+
#endif
24+
1825
static uint64_t sse2_extract_u64(__m128i v)
1926
{
2027
uint64_t r;
@@ -35,15 +42,15 @@ static uint64_t sse2_lfu(uint64_t srcd, uint64_t dstd, uint8_t lfu_func)
3542
uint64_t func2 = (lfu_func & 0x04) ? 0xFFFFFFFFFFFFFFFFULL : 0;
3643
uint64_t func3 = (lfu_func & 0x08) ? 0xFFFFFFFFFFFFFFFFULL : 0;
3744

38-
__m128i vs = _mm_set_epi64x(0, (int64_t)srcd);
39-
__m128i vd = _mm_set_epi64x(0, (int64_t)dstd);
45+
__m128i vs = SSE2_SET64(0, srcd);
46+
__m128i vd = SSE2_SET64(0, dstd);
4047
__m128i vns = _mm_andnot_si128(vs, _mm_set1_epi32(-1)); /* ~srcd */
4148
__m128i vnd = _mm_andnot_si128(vd, _mm_set1_epi32(-1)); /* ~dstd */
4249

43-
__m128i vf0 = _mm_set_epi64x(0, (int64_t)func0);
44-
__m128i vf1 = _mm_set_epi64x(0, (int64_t)func1);
45-
__m128i vf2 = _mm_set_epi64x(0, (int64_t)func2);
46-
__m128i vf3 = _mm_set_epi64x(0, (int64_t)func3);
50+
__m128i vf0 = SSE2_SET64(0, func0);
51+
__m128i vf1 = SSE2_SET64(0, func1);
52+
__m128i vf2 = SSE2_SET64(0, func2);
53+
__m128i vf3 = SSE2_SET64(0, func3);
4754

4855
/* (~s & ~d & f0) | (~s & d & f1) | (s & ~d & f2) | (s & d & f3) */
4956
__m128i t0 = _mm_and_si128(_mm_and_si128(vns, vnd), vf0);
@@ -64,8 +71,8 @@ static uint64_t sse2_lfu(uint64_t srcd, uint64_t dstd, uint8_t lfu_func)
6471
static uint8_t sse2_dcomp(uint64_t patd, uint64_t srcd, uint64_t dstd, bool cmpdst)
6572
{
6673
uint64_t other = cmpdst ? dstd : srcd;
67-
__m128i vp = _mm_set_epi64x(0, (int64_t)patd);
68-
__m128i vo = _mm_set_epi64x(0, (int64_t)other);
74+
__m128i vp = SSE2_SET64(0, patd);
75+
__m128i vo = SSE2_SET64(0, other);
6976
__m128i vxor = _mm_xor_si128(vp, vo);
7077

7178
/* Compare each byte against zero */
@@ -88,8 +95,8 @@ static uint8_t sse2_zcomp(uint64_t srcz, uint64_t dstz, uint8_t zmode)
8895
uint8_t result = 0;
8996
uint8_t packed = 0;
9097

91-
__m128i vs = _mm_set_epi64x(0, (int64_t)srcz);
92-
__m128i vd = _mm_set_epi64x(0, (int64_t)dstz);
98+
__m128i vs = SSE2_SET64(0, srcz);
99+
__m128i vd = SSE2_SET64(0, dstz);
93100

94101
/* Bias for unsigned comparison via signed instructions */
95102
__m128i bias = _mm_set1_epi16((short)0x8000);
@@ -150,9 +157,9 @@ static uint64_t sse2_byte_merge(uint64_t src, uint64_t dst, uint16_t mask)
150157
sel64 |= (uint64_t)((uint8_t)(-(int8_t)((mask >> 13) & 1))) << 48;
151158
sel64 |= (uint64_t)((uint8_t)(-(int8_t)((mask >> 14) & 1))) << 56;
152159

153-
vmask = _mm_set_epi64x(0, (int64_t)sel64);
154-
vsrc = _mm_set_epi64x(0, (int64_t)src);
155-
vdst = _mm_set_epi64x(0, (int64_t)dst);
160+
vmask = SSE2_SET64(0, sel64);
161+
vsrc = SSE2_SET64(0, src);
162+
vdst = SSE2_SET64(0, dst);
156163

157164
/* result = (src & mask) | (dst & ~mask) */
158165
r = _mm_or_si128(

src/eeprom.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#include "eeprom.h"
1717

1818
#include <stdlib.h>
19-
#include <stdbool.h>
19+
#include <boolean.h>
2020
#include <string.h> // For memset
2121

2222
uint16_t eeprom_ram[64];

0 commit comments

Comments
 (0)