diff options
Diffstat (limited to 'src/library_sdl.js')
-rw-r--r-- | src/library_sdl.js | 445 |
1 files changed, 322 insertions, 123 deletions
diff --git a/src/library_sdl.js b/src/library_sdl.js index cadc3aee..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,22 +82,31 @@ 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 + 17: 224 | 1<<10, // control (right, or left) + 18: 226 | 1<<10, // alt + 20: 57 | 1<<10, // caps lock + + 33: 75 | 1<<10, // pagedup + 34: 78 | 1<<10, // pagedown + 35: 77 | 1<<10, // end + 36: 74 | 1<<10, // home + 37: 80 | 1<<10, // left arrow + 38: 82 | 1<<10, // up arrow + 39: 79 | 1<<10, // right arrow + 40: 81 | 1<<10, // down arrow + 44: 316, // print screen + 45: 73 | 1<<10, // insert 46: 127, // SDLK_DEL == '\177' - 38: 1106, // up arrow - 40: 1105, // down arrow - 37: 1104, // left arrow - 39: 1103, // right arrow - - 33: 1099, // pagedup - 34: 1102, // pagedown - - 17: 1248, // control (right, or left) - 18: 1250, // alt - 173: 45, // minus - 16: 1249, // shift - 96: 88 | 1<<10, // keypad 0 + 91: 227 | 1<<10, // windows key or super key on linux (doesn't work on Mac) + 93: 101 | 1<<10, // application + + 96: 98 | 1<<10, // keypad 0 97: 89 | 1<<10, // keypad 1 98: 90 | 1<<10, // keypad 2 99: 91 | 1<<10, // keypad 3 @@ -107,7 +116,11 @@ var LibrarySDL = { 103: 95 | 1<<10, // keypad 7 104: 96 | 1<<10, // keypad 8 105: 97 | 1<<10, // keypad 9 - + 106: 85 | 1<<10, // keypad multiply + 107: 87 | 1<<10, // keypad plus + 109: 86 | 1<<10, // keypad minus + 110: 99 | 1<<10, // keypad decimal point + 111: 84 | 1<<10, // keypad divide 112: 58 | 1<<10, // F1 113: 59 | 1<<10, // F2 114: 60 | 1<<10, // F3 @@ -119,67 +132,121 @@ var LibrarySDL = { 120: 66 | 1<<10, // F9 121: 67 | 1<<10, // F10 122: 68 | 1<<10, // F11 - 123: 69 | 1<<10, // F12 - + 123: 69 | 1<<10, // F12 + 124: 104 | 1<<10, // F13 + 125: 105 | 1<<10, // F14 + 126: 106 | 1<<10, // F15 + 127: 107 | 1<<10, // F16 + 128: 108 | 1<<10, // F17 + 129: 109 | 1<<10, // F18 + 130: 110 | 1<<10, // F19 + 131: 111 | 1<<10, // F20 + 132: 112 | 1<<10, // F21 + 133: 113 | 1<<10, // F22 + 134: 114 | 1<<10, // F23 + 135: 115 | 1<<10, // F24 + + 144: 83 | 1<<10, // keypad num lock + + 160: 94, // caret + 161: 33, // exclaim + 162: 34, // double quote + 163: 35, // hash + 164: 36, // dollar + 165: 37, // percent + 166: 38, // ampersand + 167: 95, // underscore + 168: 40, // open parenthesis + 169: 41, // close parenthesis + 170: 42, // asterix + 171: 43, // plus + 172: 124, // pipe + 173: 45, // minus + 174: 123, // open curly bracket + 175: 125, // close curly bracket + 176: 126, // tilde + + 181: 127, // audio mute + 182: 129, // audio volume down + 183: 128, // audio volume up + 188: 44, // comma 190: 46, // period 191: 47, // slash (/) 192: 96, // backtick/backquote (`) + 219: 91, // open square bracket + 220: 92, // back slash + 221: 93, // close square bracket + 222: 39, // quote }, scanCodes: { // SDL keycode ==> SDL scancode. See SDL_scancode.h + 8: 42, // backspace + 9: 43, // tab + 13: 40, // return + 27: 41, // escape + 32: 44, // space + 35: 204, // hash + + 39: 53, // grave + + 44: 54, // comma + 46: 55, // period + 47: 56, // slash + 48: 39, // 0 + 49: 30, // 1 + 50: 31, // 2 + 51: 32, // 3 + 52: 33, // 4 + 53: 34, // 5 + 54: 35, // 6 + 55: 36, // 7 + 56: 37, // 8 + 57: 38, // 9 + 58: 203, // colon + 59: 51, // semicolon + + 61: 46, // equals + + 91: 47, // left bracket + 92: 49, // backslash + 93: 48, // right bracket + + 96: 52, // apostrophe 97: 4, // A - 98: 5, - 99: 6, - 100: 7, - 101: 8, - 102: 9, - 103: 10, - 104: 11, - 105: 12, - 106: 13, - 107: 14, - 108: 15, - 109: 16, - 110: 17, - 111: 18, - 112: 19, - 113: 20, - 114: 21, - 115: 22, - 116: 23, - 117: 24, - 118: 25, - 119: 26, - 120: 27, - 121: 28, + 98: 5, // B + 99: 6, // C + 100: 7, // D + 101: 8, // E + 102: 9, // F + 103: 10, // G + 104: 11, // H + 105: 12, // I + 106: 13, // J + 107: 14, // K + 108: 15, // L + 109: 16, // M + 110: 17, // N + 111: 18, // O + 112: 19, // P + 113: 20, // Q + 114: 21, // R + 115: 22, // S + 116: 23, // T + 117: 24, // U + 118: 25, // V + 119: 26, // W + 120: 27, // X + 121: 28, // Y 122: 29, // Z - 49: 30, // 1 - 50: 31, - 51: 32, - 52: 33, - 53: 34, - 54: 35, - 55: 36, - 56: 37, - 57: 38, // 9 - 48: 39, // 0 - 13: 40, // return - 27: 41, // escape - 8: 42, // backspace - 9: 43, // tab - 32: 44, // space - 61: 46, // equals - 91: 47, // left bracket - 93: 48, // right bracket - 92: 49, // backslash - 59: 51, // ; - 96: 52, // apostrophe - 44: 54, // comma - 46: 55, // period - 47: 56, // slash + + 127: 76, // delete + 305: 224, // ctrl + 308: 226, // alt + + 316: 70, // print screen }, loadRect: function(rect) { return { @@ -346,52 +413,110 @@ var LibrarySDL = { _free(info.pixelFormat); _free(surf); SDL.surfaces[surf] = null; + + if (surf === SDL.screen) { + SDL.screen = null; + } }, - 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 + }); }; - SDL.events.push(event); break; - case 'touchend': + } + case 'touchend': { event.preventDefault(); - event = { + + // Remove the entry in the SDL.downFingers hash + // because the finger is no longer down. + for(var i = 0; i < event.changedTouches.length; i++) { + var touch = event.changedTouches[i]; + if (SDL.downFingers[touch.identifier] === true) { + delete SDL.downFingers[touch.identifier]; + } + } + + var mouseEvent = { type: 'mouseup', button: 0, - pageX: touchX, - pageY: touchY + pageX: event.changedTouches[0].clientX, + pageY: event.changedTouches[0].clientY }; SDL.DOMButtons[0] = 0; - SDL.events.push(event); + SDL.events.push(mouseEvent); + + for (var i = 0; i < event.changedTouches.length; i++) { + var touch = event.changedTouches[i]; + SDL.events.push({ + type: 'touchend', + touch: touch + }); + }; break; + } case 'mousemove': + if (SDL.DOMButtons[0] === 1) { + SDL.events.push({ + type: 'touchmove', + touch: { + identifier: 0, + deviceID: {{{ cDefine('SDL_TOUCH_MOUSEID') }}}, + pageX: event.pageX, + pageY: event.pageY + } + }); + } if (Browser.pointerLock) { // workaround for firefox bug 750111 if ('mozMovementX' in event) { @@ -433,6 +558,15 @@ var LibrarySDL = { }; } else if (event.type == 'mousedown') { SDL.DOMButtons[event.button] = 1; + SDL.events.push({ + type: 'touchstart', + touch: { + identifier: 0, + deviceID: {{{ cDefine('SDL_TOUCH_MOUSEID') }}}, + pageX: event.pageX, + pageY: event.pageY + } + }); } else if (event.type == 'mouseup') { // ignore extra ups, can happen if we leave the canvas while pressing down, then return, // since we add a mouseup in that case @@ -440,6 +574,15 @@ var LibrarySDL = { return; } + SDL.events.push({ + type: 'touchend', + touch: { + identifier: 0, + deviceID: {{{ cDefine('SDL_TOUCH_MOUSEID') }}}, + pageX: event.pageX, + pageY: event.pageY + } + }); SDL.DOMButtons[event.button] = 0; } @@ -450,9 +593,9 @@ var LibrarySDL = { // keyup. This isn't perfect, but it enables SDL_WM_ToggleFullScreen // to work as the result of a keypress (which is an extremely // common use case). - if (event.type === 'keydown') { + if (event.type === 'keydown' || event.type === 'mousedown') { SDL.canRequestFullscreen = true; - } else if (event.type === 'keyup') { + } else if (event.type === 'keyup' || event.type === 'mouseup') { if (SDL.isRequestingFullscreen) { Module['requestFullScreen'](true, true); SDL.isRequestingFullscreen = false; @@ -531,6 +674,10 @@ var LibrarySDL = { event.handled = true; switch (event.type) { + case 'touchstart': case 'touchend': case 'touchmove': { + Browser.calculateMouseEvent(event); + break; + } case 'keydown': case 'keyup': { var down = event.type === 'keydown'; var code = event.keyCode; @@ -539,8 +686,11 @@ var LibrarySDL = { } else { code = SDL.keyCodes[event.keyCode] || event.keyCode; } + + var scan = code & ~(1 << 10); + scan = SDL.scanCodes[scan] || scan; - {{{ makeSetValue('SDL.keyboardState', 'code', 'down', 'i8') }}}; + {{{ makeSetValue('SDL.keyboardState', 'scan', 'down', 'i8') }}}; // TODO: lmeta, rmeta, numlock, capslock, KMOD_MODE, KMOD_RESERVED SDL.modState = ({{{ makeGetValue('SDL.keyboardState', '1248', 'i8') }}} ? 0x0040 | 0x0080 : 0) | // KMOD_LCTRL & KMOD_RCTRL ({{{ makeGetValue('SDL.keyboardState', '1249', 'i8') }}} ? 0x0001 | 0x0002 : 0) | // KMOD_LSHIFT & KMOD_RSHIFT @@ -621,13 +771,19 @@ var LibrarySDL = { if (event.type != 'mousemove') { var down = event.type === 'mousedown'; {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseButtonEvent.type, 'SDL.DOMEventToSDLEvent[event.type]', 'i32') }}}; + {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseButtonEvent.timestamp, '0', 'i32') }}}; + {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseButtonEvent.windowID, '0', 'i32') }}}; + {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseButtonEvent.which, '0', 'i32') }}}; {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseButtonEvent.button, 'event.button+1', 'i8') }}}; // DOM buttons are 0-2, SDL 1-3 {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseButtonEvent.state, 'down ? 1 : 0', 'i8') }}}; {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseButtonEvent.x, 'Browser.mouseX', 'i32') }}}; {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseButtonEvent.y, 'Browser.mouseY', 'i32') }}}; } else { {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseMotionEvent.type, 'SDL.DOMEventToSDLEvent[event.type]', 'i32') }}}; - {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseMotionEvent.state, 'SDL.buttonState', 'i8') }}}; + {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseMotionEvent.timestamp, '0', 'i32') }}}; + {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseMotionEvent.windowID, '0', 'i32') }}}; + {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseMotionEvent.which, '0', 'i32') }}}; + {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseMotionEvent.state, 'SDL.buttonState', 'i32') }}}; {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseMotionEvent.x, 'Browser.mouseX', 'i32') }}}; {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseMotionEvent.y, 'Browser.mouseY', 'i32') }}}; {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseMotionEvent.xrel, 'Browser.mouseMovementX', 'i32') }}}; @@ -635,6 +791,33 @@ var LibrarySDL = { } break; } + case 'touchstart': case 'touchend': case 'touchmove': { + var touch = event.touch; + var w = Module['canvas'].width; + var h = Module['canvas'].height; + var x = Browser.touches[touch.identifier].x / w; + var y = Browser.touches[touch.identifier].y / h; + var lx = Browser.lastTouches[touch.identifier].x / w; + var ly = Browser.lastTouches[touch.identifier].y / h; + var dx = x - lx; + var dy = y - ly; + if (touch['deviceID'] === undefined) touch.deviceID = SDL.TOUCH_DEFAULT_ID; + if (dx === 0 && dy === 0 && event.type === 'touchmove') return; // don't send these if nothing happened + {{{ makeSetValue('ptr', C_STRUCTS.SDL_TouchFingerEvent.type, 'SDL.DOMEventToSDLEvent[event.type]', 'i32') }}}; + {{{ makeSetValue('ptr', C_STRUCTS.SDL_TouchFingerEvent.timestamp, '_SDL_GetTicks()', 'i32') }}}; + {{{ makeSetValue('ptr', C_STRUCTS.SDL_TouchFingerEvent.touchId, 'touch.deviceID', 'i64') }}}; + {{{ makeSetValue('ptr', C_STRUCTS.SDL_TouchFingerEvent.fingerId, 'touch.identifier', 'i64') }}}; + {{{ makeSetValue('ptr', C_STRUCTS.SDL_TouchFingerEvent.x, 'x', 'float') }}}; + {{{ makeSetValue('ptr', C_STRUCTS.SDL_TouchFingerEvent.y, 'y', 'float') }}}; + {{{ makeSetValue('ptr', C_STRUCTS.SDL_TouchFingerEvent.dx, 'dx', 'float') }}}; + {{{ makeSetValue('ptr', C_STRUCTS.SDL_TouchFingerEvent.dy, 'dy', 'float') }}}; + if (touch.force !== undefined) { + {{{ makeSetValue('ptr', C_STRUCTS.SDL_TouchFingerEvent.pressure, 'touch.force', 'float') }}}; + } else { // No pressure data, send a digital 0/1 pressure. + {{{ makeSetValue('ptr', C_STRUCTS.SDL_TouchFingerEvent.pressure, 'event.type == "touchend" ? 0 : 1', 'float') }}}; + } + break; + } case 'unload': { {{{ makeSetValue('ptr', C_STRUCTS.SDL_KeyboardEvent.type, 'SDL.DOMEventToSDLEvent[event.type]', 'i32') }}}; break; @@ -879,14 +1062,17 @@ var LibrarySDL = { SDL.keyboardState = _malloc(0x10000); // Our SDL needs 512, but 64K is safe for older SDLs _memset(SDL.keyboardState, 0, 0x10000); // Initialize this structure carefully for closure - SDL.DOMEventToSDLEvent['keydown'] = 0x300 /* SDL_KEYDOWN */; - SDL.DOMEventToSDLEvent['keyup'] = 0x301 /* SDL_KEYUP */; - SDL.DOMEventToSDLEvent['keypress'] = 0x303 /* SDL_TEXTINPUT */; - SDL.DOMEventToSDLEvent['mousedown'] = 0x401 /* SDL_MOUSEBUTTONDOWN */; - SDL.DOMEventToSDLEvent['mouseup'] = 0x402 /* SDL_MOUSEBUTTONUP */; - SDL.DOMEventToSDLEvent['mousemove'] = 0x400 /* SDL_MOUSEMOTION */; - SDL.DOMEventToSDLEvent['unload'] = 0x100 /* SDL_QUIT */; - SDL.DOMEventToSDLEvent['resize'] = 0x7001 /* SDL_VIDEORESIZE/SDL_EVENT_COMPAT2 */; + SDL.DOMEventToSDLEvent['keydown'] = 0x300 /* SDL_KEYDOWN */; + SDL.DOMEventToSDLEvent['keyup'] = 0x301 /* SDL_KEYUP */; + SDL.DOMEventToSDLEvent['keypress'] = 0x303 /* SDL_TEXTINPUT */; + SDL.DOMEventToSDLEvent['mousedown'] = 0x401 /* SDL_MOUSEBUTTONDOWN */; + SDL.DOMEventToSDLEvent['mouseup'] = 0x402 /* SDL_MOUSEBUTTONUP */; + SDL.DOMEventToSDLEvent['mousemove'] = 0x400 /* SDL_MOUSEMOTION */; + SDL.DOMEventToSDLEvent['touchstart'] = 0x700 /* SDL_FINGERDOWN */; + SDL.DOMEventToSDLEvent['touchend'] = 0x701 /* SDL_FINGERUP */; + SDL.DOMEventToSDLEvent['touchmove'] = 0x702 /* SDL_FINGERMOTION */; + SDL.DOMEventToSDLEvent['unload'] = 0x100 /* SDL_QUIT */; + SDL.DOMEventToSDLEvent['resize'] = 0x7001 /* SDL_VIDEORESIZE/SDL_EVENT_COMPAT2 */; // These are not technically DOM events; the HTML gamepad API is poll-based. // However, we define them here, as the rest of the SDL code assumes that // all SDL events originate as DOM events. @@ -956,7 +1142,7 @@ var LibrarySDL = { }, SDL_SetVideoMode: function(width, height, depth, flags) { - ['mousedown', 'mouseup', 'mousemove', 'DOMMouseScroll', 'mousewheel', 'mouseout'].forEach(function(event) { + ['touchstart', 'touchend', 'touchmove', 'mousedown', 'mouseup', 'mousemove', 'DOMMouseScroll', 'mousewheel', 'mouseout'].forEach(function(event) { Module['canvas'].addEventListener(event, SDL.receiveEvent, true); }); @@ -971,7 +1157,7 @@ var LibrarySDL = { // Free the old surface first. if (SDL.screen) { SDL.freeSurface(SDL.screen); - SDL.screen = null; + assert(!SDL.screen); } SDL.screen = SDL.makeSurface(width, height, flags, true, 'screen'); if (!SDL.addedResizeListener) { @@ -1304,7 +1490,7 @@ var LibrarySDL = { dstData.ctx.globalAlpha = oldAlpha; if (dst != SDL.screen) { // XXX As in IMG_Load, for compatibility we write out |pixels| - console.log('WARNING: copying canvas data to memory for compatibility'); + Runtime.warnOnce('WARNING: copying canvas data to memory for compatibility'); _SDL_LockSurface(dst); dstData.locked--; // The surface is not actually locked in this hack } @@ -1407,20 +1593,28 @@ var LibrarySDL = { return 0; }, - SDL_PeepEvents: function(events, numEvents, action, from, to) { + SDL_PeepEvents: function(events, requestedEventCount, action, from, to) { switch(action) { case 2: { // SDL_GETEVENT - assert(numEvents == 1); - var got = 0; - while (SDL.events.length > 0 && numEvents > 0) { - var type = SDL.DOMEventToSDLEvent[SDL.events[0].type]; - if (type < from || type > to) break; - SDL.makeCEvent(SDL.events.shift(), events); - got++; - numEvents--; - // events += sizeof(..) + // We only handle 1 event right now + assert(requestedEventCount == 1); + + var index = 0; + var retrievedEventCount = 0; + // this should look through the entire queue until it has filled up the events + // array + while (index < SDL.events.length && retrievedEventCount < requestedEventCount) { + var event = SDL.events[index]; + var type = SDL.DOMEventToSDLEvent[event.type]; + if (from <= type && type <= to) { + SDL.makeCEvent(event, events); + SDL.events.splice(index, 1); + retrievedEventCount++; + } else { + index++; + } } - return got; + return retrievedEventCount; } default: throw 'SDL_PeepEvents does not yet support that action: ' + action; } @@ -1746,9 +1940,9 @@ var LibrarySDL = { // Initialize Web Audio API if we haven't done so yet. Note: Only initialize Web Audio context ever once on the web page, // since initializing multiple times fails on Chrome saying 'audio resources have been exhausted'. if (!SDL.audioContext) { - if (typeof(AudioContext) === 'function') { + if (typeof(AudioContext) !== 'undefined') { SDL.audioContext = new AudioContext(); - } else if (typeof(webkitAudioContext) === 'function') { + } else if (typeof(webkitAudioContext) !== 'undefined') { SDL.audioContext = new webkitAudioContext(); } else { throw 'Web Audio API is not available!'; @@ -1791,7 +1985,12 @@ var LibrarySDL = { } #endif var playtime = Math.max(curtime, SDL.audio.nextPlayTime); - SDL.audio.soundSource[SDL.audio.nextSoundSource]['start'](playtime); + var ss = SDL.audio.soundSource[SDL.audio.nextSoundSource]; + if (typeof ss['start'] !== 'undefined') { + ss['start'](playtime); + } else if (typeof ss['noteOn'] !== 'undefined') { + ss['noteOn'](playtime); + } var buffer_duration = sizeSamplesPerChannel / SDL.audio.freq; SDL.audio.nextPlayTime = playtime + buffer_duration; // Timer will be scheduled before the buffer completed playing. @@ -1864,7 +2063,7 @@ var LibrarySDL = { } else if (!SDL.audio.timer && !SDL.audio.scriptProcessorNode) { // If we are using the same sampling frequency as the native sampling rate of the Web Audio graph is using, we can feed our buffers via // Web Audio ScriptProcessorNode, which is a pull-mode API that calls back to our code to get audio data. - if (SDL.audioContext !== undefined && SDL.audio.freq == SDL.audioContext['sampleRate']) { + if (SDL.audioContext !== undefined && SDL.audio.freq == SDL.audioContext['sampleRate'] && typeof SDL.audioContext['createScriptProcessor'] !== 'undefined') { var sizeSamplesPerChannel = SDL.audio.bufferSize / SDL.audio.bytesPerSample / SDL.audio.channels; // How many samples per a single channel fit in the cb buffer? SDL.audio.scriptProcessorNode = SDL.audioContext['createScriptProcessor'](sizeSamplesPerChannel, 0, SDL.audio.channels); SDL.audio.scriptProcessorNode['onaudioprocess'] = function (e) { |