diff options
52 files changed, 8263 insertions, 438 deletions
@@ -134,4 +134,7 @@ a license to everyone to use it as detailed in LICENSE.) * Daniele Di Proietto <daniele.di.proietto@gmail.com> * Dan Dascalescu <dNOSPAMdascalescu@gmail.com> * Thomas Borsos <thomasborsos@gmail.com> +* Ori Avtalion <ori@avtalion.name> +* Guillaume Blanc <guillaumeblanc.sc@gmail.com> +* Usagi Ito <usagi@WonderRabbitProject.net> @@ -10,7 +10,83 @@ Not all changes are documented here. In particular, new features, user-oriented Current trunk code ------------------ - To see a list of commits in the active development branch 'incoming', which have not yet been packaged in a release, see - https://github.com/kripken/emscripten/compare/1.13.1...incoming + - Emscripten: https://github.com/kripken/emscripten/compare/1.16.0...incoming + - Emscripten-LLVM: https://github.com/kripken/emscripten-fastcomp/compare/1.16.0...incoming + - Emscripten-Clang: https://github.com/kripken/emscripten-fastcomp-clang/compare/1.16.0...incoming + +v1.16.0: 4/16/2014 +------------------ + - Removed browser warnings message in VFS library about replacing __proto__ performance issue. + - Full list of changes: + - Emscripten: https://github.com/kripken/emscripten/compare/1.15.1...1.16.0 + - Emscripten-LLVM: no changes. + - Emscripten-Clang: https://github.com/kripken/emscripten-fastcomp-clang/compare/1.15.1...1.16.0 + +v1.15.1: 4/15/2014 +------------------ + - Added support for SDL2 touch api. + - Added new user-controllable emdind-related define #define EMSCRIPTEN_HAS_UNBOUND_TYPE_NAMES, which allows optimizing embind for minimal size when std::type_info is not needed. + - Fixed issues with CMake support where CMAKE_AR and CMAKE_RANLIB were not accessible from CMakeLists.txt files. + - Full list of changes: + - Emscripten: https://github.com/kripken/emscripten/compare/1.15.0...1.15.1 + - Emscripten-LLVM: no changes. + - Emscripten-Clang: no changes. + +v1.15.0: 4/11/2014 +------------------ + - Fix outlining feature for functions that return a double (#2278) + - Added support for C++11 atomic constructs (#2273) + - Adjusted stdout and stderr stream behavior in the default shell.html to always print out to both web page text log box, and the browser console. + - Fixed an issue with loop variable optimization. + - Full list of changes: + - Emscripten: https://github.com/kripken/emscripten/compare/1.14.1...1.15.0 + - Emscripten-LLVM: https://github.com/kripken/emscripten-fastcomp/compare/1.14.1...1.15.0 + - Emscripten-Clang: https://github.com/kripken/emscripten-fastcomp-clang/compare/1.14.1...1.15.0 + +v1.14.1: 4/8/2014 +------------------ + - Added new command line utility 'emcmake', which can be used to call emconfigure for cmake. + - Added a new emcc command line parameter '--valid-abspath', which allows selectively suppressing warning messages that occur when using absolute path names in include and link directories. + - Added a new emcc linker command line parameter '--emit-symbol-map', which will save a map file between minified global names and the original function names. + - Fixed an issue with --default-object-ext not always working properly. + - Added optimizations to eliminate redundant loop variables and redundant self-assignments. + - Migrated several libc functions to use compiled code from musl instead of handwritten JS implementations. + - Improved embind support. + - Renamed the EM_ASM_() macro to the form EM_ASM_ARGS(). + - Fixed mouse button ordering issue in glfw. + - Fixed an issue when creating a path name that ends in a slash (#2258, #2263) + - Full list of changes: + - Emscripten: https://github.com/kripken/emscripten/compare/1.14.0...1.14.1 + - Emscripten-LLVM: https://github.com/kripken/emscripten-fastcomp/compare/1.14.0...1.14.1 + - Emscripten-Clang: no changes. + +v1.14.0: 3/25/2014 +------------------ + - Added new emcc linker command line option '-profiling', which defaults JS code generation options suited for benchmarking and profiling purposes. + - Implemented the EGL function eglWaitGL(). + - Fixed an issue with the HTML5 API that caused the HTML5 event listener unregistration to fail. + - Fixed issues with numpad keys in SDL support library. + - Added a new JS optimizer pass 'simplifyIfs', which is run when -s SIMPLIFY_IFS=1 link flag is set and -g is not specified. This pass merges multiple nested if()s together into single comparisons, where possible. + - Removed false positive messages on missing internal "emscripten_xxx" symbols at link stage. + - Updated to latest relooper version. + - Full list of changes: + - Emscripten: https://github.com/kripken/emscripten/compare/1.13.2...1.14.0 + - Emscripten-LLVM: https://github.com/kripken/emscripten-fastcomp/compare/1.13.2...1.14.0 + - Emscripten-Clang: no changes. + +v1.13.2: 3/15/2014 +------------------ + - Fixed issues with SDL audio on Safari. + - Fixed issues with HTML5 API mouse scroll events on Safari. + - Fixed issues with HTML5 fullscreen requests in IE11. + - Enabled support for emscripten_get_callstack on IE10+. + - Fixed issues with Closure symbol minification. + - Further improved em_asm()-related error messages. + - Updated to latest relooper version. + - Full list of changes: + - Emscripten: https://github.com/kripken/emscripten/compare/1.13.1...1.13.2 + - Emscripten-LLVM: https://github.com/kripken/emscripten-fastcomp/compare/1.13.1...1.13.2 + - Emscripten-Clang: no changes. v1.13.1: 3/10/2014 ------------------ @@ -21,7 +97,16 @@ v1.13.1: 3/10/2014 - Fix an issue where extraneous system libraries would get included in the generated output (#2191). - Added a new function emscripten_async_wget2_data() that allows reading from an XMLHTTPRequest directly into memory while supporting advanced features. - Fixed esc key code in GLFW. - - Full list of changes: https://github.com/kripken/emscripten/compare/1.13.0...1.13.1 + - Added new emscripten_debugger() intrinsic function, which calls into JS "debugger;" statement to break into a JS debugger. + - Fixed varargs function call alignment of doubles to 8 bytes. + - Switched to using default function local stack alignment to 16 bytes to be SIMD-friendly. + - Improved error messages when user code has a syntax error in em_asm() statements. + - Switched to using a new custom LLVM datalayout format for Emscripten. See https://github.com/kripken/emscripten-fastcomp/commit/65405351ba0b32a8658c65940e0b65ceb2601ad4 + - Optimized function local stack space to use fewer temporary JS variables. + - Full list of changes: + - Emscripten: https://github.com/kripken/emscripten/compare/1.13.0...1.13.1 + - Emscripten-LLVM: https://github.com/kripken/emscripten-fastcomp/compare/1.13.0...1.13.1 + - Emscripten-Clang: https://github.com/kripken/emscripten-fastcomp-clang/compare/1.13.0...1.13.1 v1.13.0: 3/3/2014 ------------------ diff --git a/cmake/Platform/Emscripten.cmake b/cmake/Platform/Emscripten.cmake index 7d86c467..f9d8c773 100644 --- a/cmake/Platform/Emscripten.cmake +++ b/cmake/Platform/Emscripten.cmake @@ -66,11 +66,11 @@ if ("${CMAKE_CXX_COMPILER}" STREQUAL "") endif() if ("${CMAKE_AR}" STREQUAL "") - set(CMAKE_AR "${EMSCRIPTEN_ROOT_PATH}/emar${EMCC_SUFFIX}") + set(CMAKE_AR "${EMSCRIPTEN_ROOT_PATH}/emar${EMCC_SUFFIX}" CACHE FILEPATH "Emscripten ar") endif() if ("${CMAKE_RANLIB}" STREQUAL "") - set(CMAKE_RANLIB "${EMSCRIPTEN_ROOT_PATH}/emranlib${EMCC_SUFFIX}") + set(CMAKE_RANLIB "${EMSCRIPTEN_ROOT_PATH}/emranlib${EMCC_SUFFIX}" CACHE FILEPATH "Emscripten ranlib") endif() # Don't do compiler autodetection, since we are cross-compiling. @@ -113,8 +113,7 @@ set(CMAKE_CXX_ARCHIVE_APPEND "${CMAKE_AR} r <TARGET> ${CMAKE_START_TEMP_FILE} <L set(CMAKE_C_ARCHIVE_APPEND "${CMAKE_AR} r <TARGET> ${CMAKE_START_TEMP_FILE} <LINK_FLAGS> <OBJECTS>${CMAKE_END_TEMP_FILE}") # Set a global EMSCRIPTEN variable that can be used in client CMakeLists.txt to detect when building using Emscripten. -# There seems to be some kind of bug with CMake, so you might need to define this manually on the command line with "-DEMSCRIPTEN=1". -set(EMSCRIPTEN 1) +set(EMSCRIPTEN 1 CACHE BOOL "If true, we are targeting Emscripten output.") # We are cross-compiling, so unset the common CMake variables that represent the target platform. Leave UNIX define enabled, since Emscripten # mimics a Linux environment. diff --git a/emscripten-version.txt b/emscripten-version.txt index 226e95b7..f488f67e 100644 --- a/emscripten-version.txt +++ b/emscripten-version.txt @@ -1,2 +1,2 @@ -1.15.0 +1.16.0 diff --git a/emscripten.py b/emscripten.py index c8122cb9..c8fab3be 100755 --- a/emscripten.py +++ b/emscripten.py @@ -1003,7 +1003,7 @@ def emscript_fast(infile, settings, outfile, libraries=[], compiler_engine=None, basic_funcs = ['abort', 'assert', 'asmPrintInt', 'asmPrintFloat'] + [m.replace('.', '_') for m in math_envs] if settings['RESERVED_FUNCTION_POINTERS'] > 0: basic_funcs.append('jsCall') - if settings['SAFE_HEAP']: basic_funcs += ['SAFE_HEAP_LOAD', 'SAFE_HEAP_STORE'] + if settings['SAFE_HEAP']: basic_funcs += ['SAFE_HEAP_LOAD', 'SAFE_HEAP_STORE', 'SAFE_FT_MASK'] if settings['CHECK_HEAP_ALIGN']: basic_funcs += ['CHECK_ALIGN_2', 'CHECK_ALIGN_4', 'CHECK_ALIGN_8'] if settings['ASSERTIONS']: if settings['ASSERTIONS'] >= 2: import difflib diff --git a/src/library.js b/src/library.js index 1d5a9140..c2830397 100644 --- a/src/library.js +++ b/src/library.js @@ -3908,12 +3908,18 @@ LibraryManager.library = { {{{ makeCopyValues('(ppdest+'+Runtime.QUANTUM_SIZE+')', '(ppsrc+'+Runtime.QUANTUM_SIZE+')', Runtime.QUANTUM_SIZE, 'null', null, 1) }}}; }, + llvm_bswap_i16__asm: true, + llvm_bswap_i16__sig: 'ii', llvm_bswap_i16: function(x) { - return ((x&0xff)<<8) | ((x>>8)&0xff); + x = x|0; + return (((x&0xff)<<8) | ((x>>8)&0xff))|0; }, + llvm_bswap_i32__asm: true, + llvm_bswap_i32__sig: 'ii', llvm_bswap_i32: function(x) { - return ((x&0xff)<<24) | (((x>>8)&0xff)<<16) | (((x>>16)&0xff)<<8) | (x>>>24); + x = x|0; + return (((x&0xff)<<24) | (((x>>8)&0xff)<<16) | (((x>>16)&0xff)<<8) | (x>>>24))|0; }, llvm_bswap_i64__deps: ['llvm_bswap_i32'], diff --git a/src/library_browser.js b/src/library_browser.js index 0808b9f0..4cd8b392 100644 --- a/src/library_browser.js +++ b/src/library_browser.js @@ -196,41 +196,42 @@ mergeInto(LibraryManager.library, { // Canvas event setup var canvas = Module['canvas']; - - // forced aspect ratio can be enabled by defining 'forcedAspectRatio' on Module - // Module['forcedAspectRatio'] = 4 / 3; - - canvas.requestPointerLock = canvas['requestPointerLock'] || - canvas['mozRequestPointerLock'] || - canvas['webkitRequestPointerLock'] || - canvas['msRequestPointerLock'] || - function(){}; - canvas.exitPointerLock = document['exitPointerLock'] || - document['mozExitPointerLock'] || - document['webkitExitPointerLock'] || - document['msExitPointerLock'] || - function(){}; // no-op if function does not exist - canvas.exitPointerLock = canvas.exitPointerLock.bind(document); - - function pointerLockChange() { - Browser.pointerLock = document['pointerLockElement'] === canvas || - document['mozPointerLockElement'] === canvas || - document['webkitPointerLockElement'] === canvas || - document['msPointerLockElement'] === canvas; - } + if (canvas) { + // forced aspect ratio can be enabled by defining 'forcedAspectRatio' on Module + // Module['forcedAspectRatio'] = 4 / 3; + + canvas.requestPointerLock = canvas['requestPointerLock'] || + canvas['mozRequestPointerLock'] || + canvas['webkitRequestPointerLock'] || + canvas['msRequestPointerLock'] || + function(){}; + canvas.exitPointerLock = document['exitPointerLock'] || + document['mozExitPointerLock'] || + document['webkitExitPointerLock'] || + document['msExitPointerLock'] || + function(){}; // no-op if function does not exist + canvas.exitPointerLock = canvas.exitPointerLock.bind(document); + + function pointerLockChange() { + Browser.pointerLock = document['pointerLockElement'] === canvas || + document['mozPointerLockElement'] === canvas || + document['webkitPointerLockElement'] === canvas || + document['msPointerLockElement'] === canvas; + } - document.addEventListener('pointerlockchange', pointerLockChange, false); - document.addEventListener('mozpointerlockchange', pointerLockChange, false); - document.addEventListener('webkitpointerlockchange', pointerLockChange, false); - document.addEventListener('mspointerlockchange', pointerLockChange, false); + document.addEventListener('pointerlockchange', pointerLockChange, false); + document.addEventListener('mozpointerlockchange', pointerLockChange, false); + document.addEventListener('webkitpointerlockchange', pointerLockChange, false); + document.addEventListener('mspointerlockchange', pointerLockChange, false); - if (Module['elementPointerLock']) { - canvas.addEventListener("click", function(ev) { - if (!Browser.pointerLock && canvas.requestPointerLock) { - canvas.requestPointerLock(); - ev.preventDefault(); - } - }, false); + if (Module['elementPointerLock']) { + canvas.addEventListener("click", function(ev) { + if (!Browser.pointerLock && canvas.requestPointerLock) { + canvas.requestPointerLock(); + ev.preventDefault(); + } + }, false); + } } }, @@ -482,6 +483,8 @@ mergeInto(LibraryManager.library, { mouseY: 0, mouseMovementX: 0, mouseMovementY: 0, + touches: {}, + lastTouches: {}, calculateMouseEvent: function(event) { // event should be mousemove, mousedown or mouseup if (Browser.pointerLock) { @@ -510,8 +513,9 @@ mergeInto(LibraryManager.library, { // Otherwise, calculate the movement based on the changes // in the coordinates. var rect = Module["canvas"].getBoundingClientRect(); - var x, y; - + var cw = Module["canvas"].width; + var ch = Module["canvas"].height; + // Neither .scrollX or .pageXOffset are defined in a spec, but // we prefer .scrollX because it is currently in a spec draft. // (see: http://www.w3.org/TR/2013/WD-cssom-view-20131217/) @@ -522,26 +526,37 @@ mergeInto(LibraryManager.library, { // and we have no viable fallback. assert((typeof scrollX !== 'undefined') && (typeof scrollY !== 'undefined'), 'Unable to retrieve scroll position, mouse positions likely broken.'); #endif - if (event.type == 'touchstart' || - event.type == 'touchend' || - event.type == 'touchmove') { - var t = event.touches.item(0); - if (t) { - x = t.pageX - (scrollX + rect.left); - y = t.pageY - (scrollY + rect.top); - } else { - return; + + if (event.type === 'touchstart' || event.type === 'touchend' || event.type === 'touchmove') { + var touch = event.touch; + if (touch === undefined) { + return; // the "touch" property is only defined in SDL + } - } else { - x = event.pageX - (scrollX + rect.left); - y = event.pageY - (scrollY + rect.top); + var adjustedX = touch.pageX - (scrollX + rect.left); + var adjustedY = touch.pageY - (scrollY + rect.top); + + adjustedX = adjustedX * (cw / rect.width); + adjustedY = adjustedY * (ch / rect.height); + + var coords = { x: adjustedX, y: adjustedY }; + + if (event.type === 'touchstart') { + Browser.lastTouches[touch.identifier] = coords; + Browser.touches[touch.identifier] = coords; + } else if (event.type === 'touchend' || event.type === 'touchmove') { + Browser.lastTouches[touch.identifier] = Browser.touches[touch.identifier]; + Browser.touches[touch.identifier] = { x: adjustedX, y: adjustedY }; + } + return; } + var x = event.pageX - (scrollX + rect.left); + var y = event.pageY - (scrollY + rect.top); + // the canvas might be CSS-scaled compared to its backbuffer; // SDL-using content will want mouse coordinates in terms // of backbuffer units. - var cw = Module["canvas"].width; - var ch = Module["canvas"].height; x = x * (cw / rect.width); y = y * (ch / rect.height); diff --git a/src/library_fs.js b/src/library_fs.js index 3d0036ee..d53210f9 100644 --- a/src/library_fs.js +++ b/src/library_fs.js @@ -394,16 +394,12 @@ mergeInto(LibraryManager.library, { } }); } - if (stream.__proto__) { - // reuse the object - stream.__proto__ = FS.FSStream.prototype; - } else { - var newStream = new FS.FSStream(); - for (var p in stream) { - newStream[p] = stream[p]; - } - stream = newStream; + // clone it, so we can return an instance of FSStream + var newStream = new FS.FSStream(); + for (var p in stream) { + newStream[p] = stream[p]; } + stream = newStream; var fd = FS.nextfd(fd_start, fd_end); stream.fd = fd; FS.streams[fd] = stream; diff --git a/src/library_glfw.js b/src/library_glfw.js index f72aeb24..6d539326 100644 --- a/src/library_glfw.js +++ b/src/library_glfw.js @@ -130,9 +130,11 @@ var LibraryGLFW = { onKeyChanged: function(event, status) { var key = GLFW.DOMToGLFWKeyCode(event.keyCode); - if (key && GLFW.keyFunc) { + if (key) { GLFW.keys[key] = status; - Runtime.dynCall('vii', GLFW.keyFunc, [key, status]); + if (GLFW.keyFunc) { + Runtime.dynCall('vii', GLFW.keyFunc, [key, status]); + } } }, @@ -209,7 +211,7 @@ var LibraryGLFW = { }, onMouseWheel: function(event) { - GLFW.wheelPos += Browser.getMouseWheelDelta(event); + GLFW.wheelPos -= Browser.getMouseWheelDelta(event); if (GLFW.mouseWheelFunc && event.target == Module["canvas"]) { Runtime.dynCall('vi', GLFW.mouseWheelFunc, [GLFW.wheelPos]); diff --git a/src/library_sdl.js b/src/library_sdl.js index d90484ad..6e235e90 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -10,7 +10,7 @@ // or otherwise). var LibrarySDL = { - $SDL__deps: ['$FS', '$PATH', '$Browser'], + $SDL__deps: ['$FS', '$PATH', '$Browser', 'SDL_GetTicks'], $SDL: { defaults: { width: 320, @@ -82,6 +82,8 @@ var LibrarySDL = { DOMEventToSDLEvent: {}, + TOUCH_DEFAULT_ID: 0, // Our default deviceID for touch events (we get nothing from the browser) + keyCodes: { // DOM code ==> SDL code. See https://developer.mozilla.org/en/Document_Object_Model_%28DOM%29/KeyboardEvent and SDL_keycode.h // For keys that don't have unicode value, we map DOM codes with the corresponding scan codes + 1024 (using "| 1 << 10") 16: 225 | 1<<10, // shift @@ -417,50 +419,104 @@ var LibrarySDL = { } }, - touchX: 0, touchY: 0, + // the browser sends out touchstart events with the whole group of touches + // even if we received a previous touchstart for a specific touch identifier. + // You can test this by pressing one finger to the screen, then another. You'll + // receive two touchstart events, the first with a touches count of 1 the second + // with a touches count of two. + // SDL sends out a new touchstart event for only each newly started touch so to + // emulate this, we keep track of previously started touches. + downFingers: {}, savedKeydown: null, receiveEvent: function(event) { switch(event.type) { - case 'touchstart': + case 'touchstart': case 'touchmove': { event.preventDefault(); - var touch = event.touches[0]; - touchX = touch.pageX; - touchY = touch.pageY; - var event = { - type: 'mousedown', + + var touches = []; + + // Clear out any touchstart events that we've already processed + if (event.type === 'touchstart') { + for (var i = 0; i < event.touches.length; i++) { + var touch = event.touches[i]; + if (SDL.downFingers[touch.identifier] != true) { + SDL.downFingers[touch.identifier] = true; + touches.push(touch); + } + } + } else { + touches = event.touches; + } + + var firstTouch = touches[0]; + if (event.type == 'touchstart') { + SDL.DOMButtons[0] = 1; + } + var mouseEventType; + switch(event.type) { + case 'touchstart': mouseEventType = 'mousedown'; break; + case 'touchmove': mouseEventType = 'mousemove'; break; + } + var mouseEvent = { + type: mouseEventType, button: 0, - pageX: touchX, - pageY: touchY + pageX: firstTouch.clientX, + pageY: firstTouch.clientY }; - SDL.DOMButtons[0] = 1; - SDL.events.push(event); - break; - case 'touchmove': - event.preventDefault(); - var touch = event.touches[0]; - touchX = touch.pageX; - touchY = touch.pageY; - event = { - type: 'mousemove', - button: 0, - pageX: touchX, - pageY: touchY + SDL.events.push(mouseEvent); + + for (var i = 0; i < touches.length; i++) { + var touch = touches[i]; + SDL.events.push({ + type: event.type, + touch: touch + }); |