Skip to content
Permalink
Browse files
Initial merge of Emscripten port!
With this commit, you can compile SDL2 with Emscripten
( http://emscripten.org/ ), and make your SDL-based C/C++ program
into a web app.

This port was due to the efforts of several people, including: Charlie Birks,
Sathyanarayanan Gunasekaran, Jukka Jyl?nki, Alon Zakai, Edward Rudd,
Bruce Mitchener, and Martin Gerhardy. (Thanks, everyone!)
  • Loading branch information
icculus committed Dec 18, 2014
1 parent a228b67 commit fe40a1722481c2f04c742445e7a8fb2eee7a481d
Showing with 4,044 additions and 597 deletions.
  1. +91 −14 CMakeLists.txt
  2. +2 −0 build-scripts/config.sub
  3. +133 −0 configure
  4. +83 −0 configure.in
  5. +26 −0 docs/README-emscripten.txt
  6. +1 −1 include/SDL_atomic.h
  7. +5 −0 include/SDL_config.h.cmake
  8. +5 −0 include/SDL_config.h.in
  9. +14 −0 include/SDL_hints.h
  10. +4 −0 src/audio/SDL_audio.c
  11. +271 −0 src/audio/emscripten/SDL_emscriptenaudio.c
  12. +42 −0 src/audio/emscripten/SDL_emscriptenaudio.h
  13. +8 −0 src/cpuinfo/SDL_cpuinfo.c
  14. +1 −1 src/dynapi/SDL_dynapi.h
  15. +68 −0 src/filesystem/emscripten/SDL_sysfilesystem.c
  16. +15 −1 src/joystick/SDL_gamecontroller.c
  17. +2 −0 src/joystick/SDL_gamecontrollerdb.h
  18. +426 −0 src/joystick/emscripten/SDL_sysjoystick.c
  19. +76 −0 src/joystick/emscripten/SDL_sysjoystick_c.h
  20. +4 −0 src/power/SDL_power.c
  21. +62 −0 src/power/emscripten/SDL_syspower.c
  22. +4 −0 src/render/opengles2/SDL_gles2funcs.h
  23. +47 −8 src/render/opengles2/SDL_render_gles2.c
  24. +3 −0 src/video/SDL_sysvideo.h
  25. +3 −0 src/video/SDL_video.c
  26. +638 −0 src/video/emscripten/SDL_emscriptenevents.c
  27. +36 −0 src/video/emscripten/SDL_emscriptenevents.h
  28. +136 −0 src/video/emscripten/SDL_emscriptenframebuffer.c
  29. +32 −0 src/video/emscripten/SDL_emscriptenframebuffer.h
  30. +218 −0 src/video/emscripten/SDL_emscriptenmouse.c
  31. +39 −0 src/video/emscripten/SDL_emscriptenmouse.h
  32. +117 −0 src/video/emscripten/SDL_emscriptenopengles.c
  33. +49 −0 src/video/emscripten/SDL_emscriptenopengles.h
  34. +320 −0 src/video/emscripten/SDL_emscriptenvideo.c
  35. +52 −0 src/video/emscripten/SDL_emscriptenvideo.h
  36. +13 −0 test/Makefile.in
  37. +39 −20 test/checkkeys.c
  38. +5 −0 test/configure
  39. +6 −0 test/configure.in
  40. +25 −0 test/emscripten/joystick-pre.js
  41. +16 −0 test/loopwave.c
  42. +1 −0 test/testautomation_surface.c
  43. +39 −19 test/testdraw2.c
  44. +41 −19 test/testdrawchessboard.c
  45. +19 −0 test/testfilesystem.c
  46. +100 −84 test/testgamecontroller.c
  47. +41 −27 test/testgesture.c
  48. +72 −45 test/testgles2.c
  49. +75 −56 test/testintersections.c
  50. +56 −39 test/testjoystick.c
  51. +29 −15 test/testmultiaudio.c
  52. +74 −51 test/testoverlay2.c
  53. +38 −27 test/testrelative.c
  54. +31 −13 test/testrendercopyex.c
  55. +36 −17 test/testrendertarget.c
  56. +31 −12 test/testscale.c
  57. +30 −11 test/testsprite2.c
  58. +28 −11 test/testspriteminimal.c
  59. +41 −23 test/teststreaming.c
  60. +62 −35 test/testviewport.c
  61. +63 −48 test/testwm2.c
@@ -117,6 +117,12 @@ else()
set(UNIX_OR_MAC_SYS OFF)
endif()

if (UNIX_OR_MAC_SYS AND NOT EMSCRIPTEN) # JavaScript does not yet have threading support, so disable pthreads when building for Emscripten.
set(PTHREADS_ENABLED_BY_DEFAULT ON)
else()
set(PTHREADS_ENABLED_BY_DEFAULT OFF)
endif()

# Default option knobs
if(APPLE OR ARCH_64)
set(OPT_DEF_SSEMATH ON)
@@ -170,13 +176,19 @@ endif()
set(SDL_LIBS "-lSDL2")
set(SDL_CFLAGS "")

# Emscripten toolchain has a nonempty default value for this, and the checks
# in this file need to change that, so remember the original value, and
# restore back to that afterwards. For check_function_exists() to work in
# Emscripten, this value must be at its default value.
set(ORIG_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})

if(CYGWIN)
# We build SDL on cygwin without the UNIX emulation layer
include_directories("-I/usr/include/mingw")
set(CMAKE_REQUIRED_FLAGS "-mno-cygwin")
check_c_source_compiles("int main(int argc, char **argv) {}"
HAVE_GCC_NO_CYGWIN)
set(CMAKE_REQUIRED_FLAGS)
set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
if(HAVE_GCC_NO_CYGWIN)
list(APPEND EXTRA_LDFLAGS "-mno-cygwin")
list(APPEND SDL_LIBS "-mno-cygwin")
@@ -188,12 +200,35 @@ add_definitions(-DUSING_GENERATED_CONFIG_H)
# General includes
include_directories(${SDL2_BINARY_DIR}/include ${SDL2_SOURCE_DIR}/include)

if(EMSCRIPTEN)
# Set up default values for the currently supported set of subsystems:
# Emscripten/Javascript does not have assembly support, a dynamic library
# loading architecture, low-level CPU inspection or multithreading.
set(OPT_DEF_ASM FALSE)
set(SDL_SHARED_ENABLED_BY_DEFAULT OFF)
set(SDL_ATOMIC_ENABLED_BY_DEFAULT OFF)
set(SDL_THREADS_ENABLED_BY_DEFAULT OFF)
set(SDL_LOADSO_ENABLED_BY_DEFAULT OFF)
set(SDL_CPUINFO_ENABLED_BY_DEFAULT OFF)
set(DLOPEN_ENABLED_BY_DEFAULT OFF)
else()
set(SDL_SHARED_ENABLED_BY_DEFAULT ON)
set(SDL_ATOMIC_ENABLED_BY_DEFAULT ON)
set(SDL_THREADS_ENABLED_BY_DEFAULT ON)
set(SDL_LOADSO_ENABLED_BY_DEFAULT ON)
set(SDL_CPUINFO_ENABLED_BY_DEFAULT ON)
set(DLOPEN_ENABLED_BY_DEFAULT ON)
endif()

set(SDL_SUBSYSTEMS
Atomic Audio Video Render Events Joystick Haptic Power Threads Timers
File Loadso CPUinfo Filesystem)
foreach(_SUB ${SDL_SUBSYSTEMS})
string(TOUPPER ${_SUB} _OPT)
option(SDL_${_OPT} "Enable the ${_SUB} subsystem" ON)
if (NOT DEFINED SDL_${_OPT}_ENABLED_BY_DEFAULT)
set(SDL_${_OPT}_ENABLED_BY_DEFAULT ON)
endif()
option(SDL_${_OPT} "Enable the ${_SUB} subsystem" ${SDL_${_OPT}_ENABLED_BY_DEFAULT})
endforeach()

option_string(ASSERTIONS "Enable internal sanity checks (auto/disabled/release/enabled/paranoid)" "auto")
@@ -216,9 +251,9 @@ dep_option(FUSIONSOUND_SHARED "Dynamically load fusionsound audio support" ON "
set_option(VIDEO_DUMMY "Use dummy video driver" ON)
set_option(VIDEO_OPENGL "Include OpenGL support" ON)
set_option(VIDEO_OPENGLES "Include OpenGL ES support" ON)
set_option(PTHREADS "Use POSIX threads for multi-threading" ${UNIX_OR_MAC_SYS})
set_option(PTHREADS "Use POSIX threads for multi-threading" ${PTHREADS_ENABLED_BY_DEFAULT})
dep_option(PTHREADS_SEM "Use pthread semaphores" ON "PTHREADS" OFF)
set_option(SDL_DLOPEN "Use dlopen for shared object loading" ON)
set_option(SDL_DLOPEN "Use dlopen for shared object loading" ${DLOPEN_ENABLED_BY_DEFAULT})
set_option(OSS "Support the OSS audio API" ${UNIX_SYS})
set_option(ALSA "Support the ALSA audio API" ${UNIX_SYS})
dep_option(ALSA_SHARED "Dynamically load ALSA audio support" ON "ALSA" OFF)
@@ -251,7 +286,7 @@ set_option(VIDEO_VIVANTE "Use Vivante EGL video driver" ${UNIX_SYS})

# TODO: We should (should we?) respect cmake's ${BUILD_SHARED_LIBS} flag here
# The options below are for compatibility to configure's default behaviour.
set(SDL_SHARED ON CACHE BOOL "Build a shared version of the library")
set(SDL_SHARED ${SDL_SHARED_ENABLED_BY_DEFAULT} CACHE BOOL "Build a shared version of the library")
set(SDL_STATIC ON CACHE BOOL "Build a static version of the library")

# General source files
@@ -317,7 +352,7 @@ if(USE_GCC OR USE_CLANG)
set(CMAKE_REQUIRED_FLAGS "-mpreferred-stack-boundary=2")
check_c_source_compiles("int x = 0; int main(int argc, char **argv) {}"
HAVE_GCC_PREFERRED_STACK_BOUNDARY)
set(CMAKE_REQUIRED_FLAGS)
set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})

set(CMAKE_REQUIRED_FLAGS "-fvisibility=hidden -Werror")
check_c_source_compiles("
@@ -328,7 +363,7 @@ if(USE_GCC OR USE_CLANG)
if(HAVE_GCC_FVISIBILITY)
list(APPEND EXTRA_CFLAGS "-fvisibility=hidden")
endif()
set(CMAKE_REQUIRED_FLAGS)
set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})

check_c_compiler_flag(-Wall HAVE_GCC_WALL)
if(HAVE_GCC_WALL)
@@ -376,7 +411,7 @@ if(ASSEMBLY)
if(HAVE_MMX)
list(APPEND EXTRA_CFLAGS "-mmmx")
endif()
set(CMAKE_REQUIRED_FLAGS)
set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
endif()

if(3DNOW)
@@ -393,7 +428,7 @@ if(ASSEMBLY)
if(HAVE_3DNOW)
list(APPEND EXTRA_CFLAGS "-m3dnow")
endif()
set(CMAKE_REQUIRED_FLAGS)
set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
endif()

if(SSE)
@@ -416,7 +451,7 @@ if(ASSEMBLY)
if(HAVE_SSE)
list(APPEND EXTRA_CFLAGS "-msse")
endif()
set(CMAKE_REQUIRED_FLAGS)
set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
endif()

if(SSE2)
@@ -439,7 +474,7 @@ if(ASSEMBLY)
if(HAVE_SSE2)
list(APPEND EXTRA_CFLAGS "-msse2")
endif()
set(CMAKE_REQUIRED_FLAGS)
set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
endif()

if(SSEMATH)
@@ -464,7 +499,7 @@ if(ASSEMBLY)
return vec_splat_u32(0);
}
int main(int argc, char **argv) { }" HAVE_ALTIVEC)
set(CMAKE_REQUIRED_FLAGS)
set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
if(HAVE_ALTIVEC OR HAVE_ALTIVEC_H_HDR)
set(HAVE_ALTIVEC TRUE) # if only HAVE_ALTIVEC_H_HDR is set
list(APPEND EXTRA_CFLAGS "-maltivec")
@@ -642,7 +677,49 @@ if(SDL_VIDEO)
endif()

# Platform-specific options and settings
if(UNIX AND NOT APPLE)
if(EMSCRIPTEN)
# Hide noisy warnings that intend to aid mostly during initial stages of porting a new
# project. Uncomment at will for verbose cross-compiling -I/../ path info.
add_definitions(-Wno-warn-absolute-paths)
if(SDL_AUDIO)
set(SDL_AUDIO_DRIVER_EMSCRIPTEN 1)
file(GLOB EM_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/emscripten/*.c)
set(SOURCE_FILES ${SOURCE_FILES} ${EM_AUDIO_SOURCES})
set(HAVE_SDL_AUDIO TRUE)
endif()
if(SDL_FILESYSTEM)
set(SDL_FILESYSTEM_EMSCRIPTEN 1)
file(GLOB EM_FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/emscripten/*.c)
set(SOURCE_FILES ${SOURCE_FILES} ${EM_FILESYSTEM_SOURCES})
set(HAVE_SDL_FILESYSTEM TRUE)
endif()
if(SDL_JOYSTICK)
set(SDL_JOYSTICK_EMSCRIPTEN 1)
file(GLOB EM_JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/emscripten/*.c)
set(SOURCE_FILES ${SOURCE_FILES} ${EM_JOYSTICK_SOURCES})
set(HAVE_SDL_JOYSTICK TRUE)
endif()
if(SDL_POWER)
set(SDL_POWER_EMSCRIPTEN 1)
file(GLOB EM_POWER_SOURCES ${SDL2_SOURCE_DIR}/src/power/emscripten/*.c)
set(SOURCE_FILES ${SOURCE_FILES} ${EM_POWER_SOURCES})
set(HAVE_SDL_POWER TRUE)
endif()
if(SDL_VIDEO)
set(SDL_VIDEO_DRIVER_EMSCRIPTEN 1)
file(GLOB EM_VIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/emscripten/*.c)
set(SOURCE_FILES ${SOURCE_FILES} ${EM_VIDEO_SOURCES})
set(HAVE_SDL_VIDEO TRUE)

#enable gles
if(VIDEO_OPENGLES)
set(SDL_VIDEO_OPENGL_EGL 1)
set(HAVE_VIDEO_OPENGLES TRUE)
set(SDL_VIDEO_OPENGL_ES2 1)
set(SDL_VIDEO_RENDER_OGL_ES2 1)
endif()
endif()
elseif(UNIX AND NOT APPLE)
if(SDL_AUDIO)
if(SYSV5 OR SOLARIS OR HPUX)
set(SDL_AUDIO_DRIVER_SUNAUDIO 1)
@@ -829,7 +906,7 @@ elseif(WINDOWS)
link_directories($ENV{DXSDK_DIR}\\lib\\${PROCESSOR_ARCH})
include_directories($ENV{DXSDK_DIR}\\Include)
endif()
set(CMAKE_REQUIRED_FLAGS)
set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
endif()

if(SDL_AUDIO)
@@ -1534,6 +1534,8 @@ case $os in
-pnacl*)
os=-pnacl
;;
-emscripten*)
;;
-none)
;;
*)
133 configure
@@ -21385,6 +21385,78 @@ $as_echo "#define SDL_VIDEO_RENDER_OGL 1" >>confdefs.h
fi
}

CheckEmscriptenGLES()
{
if test x$enable_video = xyes -a x$enable_video_opengles = xyes; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for EGL support" >&5
$as_echo_n "checking for EGL support... " >&6; }
video_opengl_egl=no
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */

#include <EGL/egl.h>

int
main ()
{


;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

video_opengl_egl=yes

fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $video_opengl_egl" >&5
$as_echo "$video_opengl_egl" >&6; }
if test x$video_opengl_egl = xyes; then

$as_echo "#define SDL_VIDEO_OPENGL_EGL 1" >>confdefs.h

fi

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenGL ES v2 headers" >&5
$as_echo_n "checking for OpenGL ES v2 headers... " >&6; }
video_opengles_v2=no
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */

#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>

int
main ()
{


;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

video_opengles_v2=yes

fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $video_opengles_v2" >&5
$as_echo "$video_opengles_v2" >&6; }
if test x$video_opengles_v2 = xyes; then

$as_echo "#define SDL_VIDEO_OPENGL_ES2 1" >>confdefs.h


$as_echo "#define SDL_VIDEO_RENDER_OGL_ES2 1" >>confdefs.h

SUMMARY_video="${SUMMARY_video} opengl_es2"
fi
fi
}

CheckInputEvents()
{
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Linux 2.4 unified input interface" >&5
@@ -23483,7 +23555,68 @@ $as_echo "#define SDL_FILESYSTEM_NACL 1" >>confdefs.h
SOURCES="$SOURCES $srcdir/src/filesystem/nacl/*.c"
have_filesystem=yes
fi
;;
*-*-emscripten* )
if test x$enable_video = xyes; then

$as_echo "#define SDL_VIDEO_DRIVER_EMSCRIPTEN 1" >>confdefs.h

SOURCES="$SOURCES $srcdir/src/video/emscripten/*.c"
have_video=yes
SUMMARY_video="${SUMMARY_video} emscripten"
fi

if test x$enable_audio = xyes; then

$as_echo "#define SDL_AUDIO_DRIVER_EMSCRIPTEN 1" >>confdefs.h

SOURCES="$SOURCES $srcdir/src/audio/emscripten/*.c"
have_audio=yes
SUMMARY_audio="${SUMMARY_audio} emscripten"
fi

CheckVisibilityHidden
CheckDummyVideo
CheckDiskAudio
CheckDummyAudio
CheckDLOPEN
CheckClockGettime
CheckEmscriptenGLES

# Set up files for the power library
if test x$enable_power = xyes; then

$as_echo "#define SDL_POWER_EMSCRIPTEN 1" >>confdefs.h

SOURCES="$SOURCES $srcdir/src/power/emscripten/*.c"
have_power=yes
fi

# Set up files for the power library
if test x$enable_joystick = xyes; then

$as_echo "#define SDL_JOYSTICK_EMSCRIPTEN 1" >>confdefs.h

SOURCES="$SOURCES $srcdir/src/joystick/emscripten/*.c"
have_joystick=yes
fi

# Set up files for the filesystem library
if test x$enable_filesystem = xyes; then

$as_echo "#define SDL_FILESYSTEM_EMSCRIPTEN 1" >>confdefs.h

SOURCES="$SOURCES $srcdir/src/filesystem/emscripten/*.c"
have_filesystem=yes
fi
# Set up files for the timer library
if test x$enable_timers = xyes; then

$as_echo "#define SDL_TIMER_UNIX 1" >>confdefs.h

SOURCES="$SOURCES $srcdir/src/timer/unix/*.c"
have_timers=yes
fi
;;
*)
as_fn_error $? "

0 comments on commit fe40a17

Please sign in to comment.