diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/analyzer.js | 10 | ||||
-rw-r--r-- | src/library.js | 13 | ||||
-rw-r--r-- | src/library_openal.js | 265 | ||||
-rw-r--r-- | src/library_sdl.js | 76 |
4 files changed, 199 insertions, 165 deletions
diff --git a/src/analyzer.js b/src/analyzer.js index 1a752305..931ce421 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -765,7 +765,15 @@ function analyzer(data, sidePass) { } break; } - case 'add': case 'sub': case 'sdiv': case 'udiv': case 'mul': case 'urem': case 'srem': + case 'add': case 'sub': case 'sdiv': case 'udiv': case 'mul': case 'urem': case 'srem': { + if (sourceBits < 32) { + // when we add illegal types like i24, we must work on the singleton chunks + item.assignTo += '$0'; + item.params[0].ident += '$0'; + item.params[1].ident += '$0'; + } + // fall through + } case 'uitofp': case 'sitofp': case 'fptosi': case 'fptoui': { // We cannot do these in parallel chunks of 32-bit operations. We will handle these in processMathop i++; diff --git a/src/library.js b/src/library.js index fedb8760..815badc1 100644 --- a/src/library.js +++ b/src/library.js @@ -1413,9 +1413,16 @@ LibraryManager.library = { // http://pubs.opengroup.org/onlinepubs/000095399/functions/usleep.html // We're single-threaded, so use a busy loop. Super-ugly. var msec = useconds / 1000; - var start = Date.now(); - while (Date.now() - start < msec) { - // Do nothing. + if (ENVIRONMENT_IS_WEB && window['performance'] && window['performance']['now']) { + var start = window['performance']['now'](); + while (window['performance']['now']() - start < msec) { + // Do nothing. + } + } else { + var start = Date.now(); + while (Date.now() - start < msec) { + // Do nothing. + } } return 0; }, diff --git a/src/library_openal.js b/src/library_openal.js index c55415b8..cbb5c0bb 100644 --- a/src/library_openal.js +++ b/src/library_openal.js @@ -6,7 +6,128 @@ var LibraryOpenAL = { contexts: [], currentContext: null, QUEUE_INTERVAL: 25, - QUEUE_LOOKAHEAD: 100 + QUEUE_LOOKAHEAD: 100, + + updateSources: function(context) { + for (var i = 0; i < context.src.length; i++) { + AL.updateSource(context.src[i]); + } + }, + + updateSource: function(src) { +#if OPENAL_DEBUG + var idx = AL.currentContext.src.indexOf(src); +#endif + if (src.state !== 0x1012 /* AL_PLAYING */) { + return; + } + + var currentTime = AL.currentContext.ctx.currentTime; + var startTime = src.bufferPosition; + + for (var i = src.buffersPlayed; i < src.queue.length; i++) { + var entry = src.queue[i]; + + var startOffset = startTime - currentTime; + var endTime = startTime + entry.buffer.duration; + + // Clean up old buffers. + if (currentTime >= endTime) { + // Update our location in the queue. + src.bufferPosition = endTime; + src.buffersPlayed = i + 1; + + // Stop / restart the source when we hit the end. + if (src.buffersPlayed >= src.queue.length) { + if (src.loop) { + AL.setSourceState(src, 0x1012 /* AL_PLAYING */); + } else { + AL.setSourceState(src, 0x1014 /* AL_STOPPED */); + } + } + } + // Process all buffers that'll be played before the next tick. + else if (startOffset < (AL.QUEUE_LOOKAHEAD / 1000) && !entry.src) { + // If the start offset is negative, we need to offset the actual buffer. + var offset = Math.abs(Math.min(startOffset, 0)); + + entry.src = AL.currentContext.ctx.createBufferSource(); + entry.src.buffer = entry.buffer; + entry.src.connect(src.gain); + entry.src.start(startTime, offset); + +#if OPENAL_DEBUG + console.log('updateSource queuing buffer ' + i + ' for source ' + idx + ' at ' + startTime + ' (offset by ' + offset + ')'); +#endif + } + + startTime = endTime; + } + }, + + setSourceState: function(src, state) { +#if OPENAL_DEBUG + var idx = AL.currentContext.src.indexOf(src); +#endif + if (state === 0x1012 /* AL_PLAYING */) { + if (src.state !== 0x1013 /* AL_PAUSED */) { + src.state = 0x1012 /* AL_PLAYING */; + // Reset our position. + src.bufferPosition = AL.currentContext.ctx.currentTime; + src.buffersPlayed = 0; +#if OPENAL_DEBUG + console.log('setSourceState resetting and playing source ' + idx); +#endif + } else { + src.state = 0x1012 /* AL_PLAYING */; + // Use the current offset from src.bufferPosition to resume at the correct point. + src.bufferPosition = AL.currentContext.ctx.currentTime - src.bufferPosition; +#if OPENAL_DEBUG + console.log('setSourceState resuming source ' + idx + ' at ' + src.bufferPosition.toFixed(4)); +#endif + } + AL.stopSourceQueue(src); + AL.updateSource(src); + } else if (state === 0x1013 /* AL_PAUSED */) { + if (src.state === 0x1012 /* AL_PLAYING */) { + src.state = 0x1013 /* AL_PAUSED */; + // Store off the current offset to restore with on resume. + src.bufferPosition = AL.currentContext.ctx.currentTime - src.bufferPosition; + AL.stopSourceQueue(src); +#if OPENAL_DEBUG + console.log('setSourceState pausing source ' + idx + ' at ' + src.bufferPosition.toFixed(4)); +#endif + } + } else if (state === 0x1014 /* AL_STOPPED */) { + if (src.state !== 0x1011 /* AL_INITIAL */) { + src.state = 0x1014 /* AL_STOPPED */; + src.buffersPlayed = src.queue.length; + AL.stopSourceQueue(src); +#if OPENAL_DEBUG + console.log('setSourceState stopping source ' + idx); +#endif + } + } else if (state == 0x1011 /* AL_INITIAL */) { + if (src.state !== 0x1011 /* AL_INITIAL */) { + src.state = 0x1011 /* AL_INITIAL */; + src.bufferPosition = 0; + src.buffersPlayed = 0; +#if OPENAL_DEBUG + console.log('setSourceState initializing source ' + idx); +#endif + } + } + }, + + stopSourceQueue: function(src) { + for (var i = 0; i < src.queue.length; i++) { + var entry = src.queue[i]; + if (entry.src) { + entry.src.stop(0); + entry.src = null; + } + } + } }, alcProcessContext: function(context) {}, @@ -41,7 +162,7 @@ var LibraryOpenAL = { alcDestroyContext: function(context) { // Stop playback, etc - clearInterval(context.interval); + clearInterval(AL.contexts[context - 1].interval); }, alcCloseDevice: function(device) { @@ -85,7 +206,7 @@ var LibraryOpenAL = { err: 0, src: [], buf: [], - interval: setInterval(function() { _updateSources(context); }, AL.QUEUE_INTERVAL) + interval: setInterval(function() { AL.updateSources(context); }, AL.QUEUE_INTERVAL) }; AL.contexts.push(context); return AL.contexts.length; @@ -94,130 +215,6 @@ var LibraryOpenAL = { } }, - updateSources__deps: ['updateSource'], - updateSources: function(context) { - for (var i = 0; i < context.src.length; i++) { - _updateSource(context.src[i]); - } - }, - - updateSource__deps: ['setSourceState'], - updateSource: function(src) { -#if OPENAL_DEBUG - var idx = AL.currentContext.src.indexOf(src); -#endif - if (src.state !== 0x1012 /* AL_PLAYING */) { - return; - } - - var currentTime = AL.currentContext.ctx.currentTime; - var startTime = src.bufferPosition; - - for (var i = src.buffersPlayed; i < src.queue.length; i++) { - var entry = src.queue[i]; - - var startOffset = startTime - currentTime; - var endTime = startTime + entry.buffer.duration; - - // Clean up old buffers. - if (currentTime >= endTime) { - // Update our location in the queue. - src.bufferPosition = endTime; - src.buffersPlayed = i + 1; - - // Stop / restart the source when we hit the end. - if (src.buffersPlayed >= src.queue.length) { - if (src.loop) { - _setSourceState(src, 0x1012 /* AL_PLAYING */); - } else { - _setSourceState(src, 0x1014 /* AL_STOPPED */); - } - } - } - // Process all buffers that'll be played before the next tick. - else if (startOffset < (AL.QUEUE_LOOKAHEAD / 1000) && !entry.src) { - // If the start offset is negative, we need to offset the actual buffer. - var offset = Math.abs(Math.min(startOffset, 0)); - - entry.src = AL.currentContext.ctx.createBufferSource(); - entry.src.buffer = entry.buffer; - entry.src.connect(src.gain); - entry.src.start(startTime, offset); - -#if OPENAL_DEBUG - console.log('updateSource queuing buffer ' + i + ' for source ' + idx + ' at ' + startTime + ' (offset by ' + offset + ')'); -#endif - } - - startTime = endTime; - } - }, - - setSourceState__deps: ['updateSource', 'stopSourceQueue'], - setSourceState: function(src, state) { -#if OPENAL_DEBUG - var idx = AL.currentContext.src.indexOf(src); -#endif - if (state === 0x1012 /* AL_PLAYING */) { - if (src.state !== 0x1013 /* AL_PAUSED */) { - src.state = 0x1012 /* AL_PLAYING */; - // Reset our position. - src.bufferPosition = AL.currentContext.ctx.currentTime; - src.buffersPlayed = 0; -#if OPENAL_DEBUG - console.log('setSourceState resetting and playing source ' + idx); -#endif - } else { - src.state = 0x1012 /* AL_PLAYING */; - // Use the current offset from src.bufferPosition to resume at the correct point. - src.bufferPosition = AL.currentContext.ctx.currentTime - src.bufferPosition; -#if OPENAL_DEBUG - console.log('setSourceState resuming source ' + idx + ' at ' + src.bufferPosition.toFixed(4)); -#endif - } - _stopSourceQueue(src); - _updateSource(src); - } else if (state === 0x1013 /* AL_PAUSED */) { - if (src.state === 0x1012 /* AL_PLAYING */) { - src.state = 0x1013 /* AL_PAUSED */; - // Store off the current offset to restore with on resume. - src.bufferPosition = AL.currentContext.ctx.currentTime - src.bufferPosition; - _stopSourceQueue(src); -#if OPENAL_DEBUG - console.log('setSourceState pausing source ' + idx + ' at ' + src.bufferPosition.toFixed(4)); -#endif - } - } else if (state === 0x1014 /* AL_STOPPED */) { - if (src.state !== 0x1011 /* AL_INITIAL */) { - src.state = 0x1014 /* AL_STOPPED */; - src.buffersPlayed = src.queue.length; - _stopSourceQueue(src); -#if OPENAL_DEBUG - console.log('setSourceState stopping source ' + idx); -#endif - } - } else if (state == 0x1011 /* AL_INITIAL */) { - if (src.state !== 0x1011 /* AL_INITIAL */) { - src.state = 0x1011 /* AL_INITIAL */; - src.bufferPosition = 0; - src.buffersPlayed = 0; -#if OPENAL_DEBUG - console.log('setSourceState initializing source ' + idx); -#endif - } - } - }, - - stopSourceQueue: function(src) { - for (var i = 0; i < src.queue.length; i++) { - var entry = src.queue[i]; - if (entry.src) { - entry.src.stop(0); - entry.src = null; - } - } - }, - alGetError: function() { if (!AL.currentContext) { return 0xA004 /* AL_INVALID_OPERATION */; @@ -336,7 +333,7 @@ var LibraryOpenAL = { } else { src.queue = [{ buffer: buffer }]; } - _updateSource(src); + AL.updateSource(src); break; case 0x202 /* AL_SOURCE_RELATIVE */: if (value === 1 /* AL_TRUE */) { @@ -505,7 +502,7 @@ var LibraryOpenAL = { src.queue.push({ buffer: buffer, src: null }); } - _updateSource(src); + AL.updateSource(src); }, alSourceUnqueueBuffers__deps: ["updateSource"], @@ -544,7 +541,7 @@ var LibraryOpenAL = { src.buffersPlayed--; } - _updateSource(src); + AL.updateSource(src); }, alDeleteBuffers: function(count, buffers) @@ -687,7 +684,7 @@ var LibraryOpenAL = { AL.currentContext.err = 0xA001 /* AL_INVALID_NAME */; return; } - _setSourceState(src, 0x1012 /* AL_PLAYING */); + AL.setSourceState(src, 0x1012 /* AL_PLAYING */); }, alSourceStop__deps: ['setSourceState'], @@ -707,7 +704,7 @@ var LibraryOpenAL = { AL.currentContext.err = 0xA001 /* AL_INVALID_NAME */; return; } - _setSourceState(src, 0x1014 /* AL_STOPPED */); + AL.setSourceState(src, 0x1014 /* AL_STOPPED */); }, alSourcePause__deps: ['setSourceState'], @@ -727,7 +724,7 @@ var LibraryOpenAL = { AL.currentContext.err = 0xA001 /* AL_INVALID_NAME */; return; } - _setSourceState(src, 0x1013 /* AL_PAUSED */); + AL.setSourceState(src, 0x1013 /* AL_PAUSED */); }, alGetSourcei__deps: ['updateSource'], @@ -754,7 +751,7 @@ var LibraryOpenAL = { // so we also forcefully update the source when alGetSourcei is queried // to aid in the common scenario of application calling alGetSourcei(AL_BUFFERS_PROCESSED) // to recycle buffers. - _updateSource(src); + AL.updateSource(src); switch (param) { case 0x202 /* AL_SOURCE_RELATIVE */: diff --git a/src/library_sdl.js b/src/library_sdl.js index 24f3de1b..92cfc7e5 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -519,6 +519,46 @@ var LibrarySDL = { return; }, + handleEvent: function(event) { + if (event.handled) return; + event.handled = true; + + switch (event.type) { + case 'keydown': case 'keyup': { + var down = event.type === 'keydown'; + var code = SDL.keyCodes[event.keyCode] || event.keyCode; + + {{{ makeSetValue('SDL.keyboardState', 'code', '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 + ({{{ makeGetValue('SDL.keyboardState', '1250', 'i8') }}} ? 0x0100 | 0x0200 : 0); // KMOD_LALT & KMOD_RALT + + if (down) { + SDL.keyboardMap[code] = event.keyCode; // save the DOM input, which we can use to unpress it during blur + } else { + delete SDL.keyboardMap[code]; + } + + break; + } + case 'mousedown': case 'mouseup': + if (event.type == 'mousedown') { + // SDL_BUTTON(x) is defined as (1 << ((x)-1)). SDL buttons are 1-3, + // and DOM buttons are 0-2, so this means that the below formula is + // correct. + SDL.buttonState |= 1 << event.button; + } else if (event.type == 'mouseup') { + SDL.buttonState &= ~(1 << event.button); + } + // fall through + case 'mousemove': { + Browser.calculateMouseEvent(event); + break; + } + } + }, + makeCEvent: function(event, ptr) { if (typeof event === 'number') { // This is a pointer to a native C event that was SDL_PushEvent'ed @@ -526,7 +566,9 @@ var LibrarySDL = { return; } - switch(event.type) { + SDL.handleEvent(event); + + switch (event.type) { case 'keydown': case 'keyup': { var down = event.type === 'keydown'; //Module.print('Received key event: ' + event.keyCode); @@ -543,19 +585,6 @@ var LibrarySDL = { scan = SDL.scanCodes[key] || key; } - var code = SDL.keyCodes[event.keyCode] || event.keyCode; - {{{ makeSetValue('SDL.keyboardState', 'code', 'down', 'i8') }}}; - if (down) { - SDL.keyboardMap[code] = event.keyCode; // save the DOM input, which we can use to unpress it during blur - } else { - delete SDL.keyboardMap[code]; - } - - // 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 - ({{{ makeGetValue('SDL.keyboardState', '1250', 'i8') }}} ? 0x0100 | 0x0200 : 0); // KMOD_LALT & KMOD_RALT - {{{ makeSetValue('ptr', 'SDL.structs.KeyboardEvent.type', 'SDL.DOMEventToSDLEvent[event.type]', 'i32') }}} {{{ makeSetValue('ptr', 'SDL.structs.KeyboardEvent.state', 'down ? 1 : 0', 'i8') }}} {{{ makeSetValue('ptr', 'SDL.structs.KeyboardEvent.repeat', '0', 'i8') }}} // TODO @@ -575,18 +604,7 @@ var LibrarySDL = { } break; } - case 'mousedown': case 'mouseup': - if (event.type == 'mousedown') { - // SDL_BUTTON(x) is defined as (1 << ((x)-1)). SDL buttons are 1-3, - // and DOM buttons are 0-2, so this means that the below formula is - // correct. - SDL.buttonState |= 1 << event.button; - } else if (event.type == 'mouseup') { - SDL.buttonState &= ~(1 << event.button); - } - // fall through - case 'mousemove': { - Browser.calculateMouseEvent(event); + case 'mousedown': case 'mouseup': case 'mousemove': { if (event.type != 'mousemove') { var down = event.type === 'mousedown'; {{{ makeSetValue('ptr', 'SDL.structs.MouseButtonEvent.type', 'SDL.DOMEventToSDLEvent[event.type]', 'i32') }}}; @@ -1174,7 +1192,11 @@ var LibrarySDL = { } }, - SDL_PumpEvents: function(){}, + SDL_PumpEvents: function(){ + SDL.events.forEach(function(event) { + SDL.handleEvent(event); + }); + }, SDL_SetColors: function(surf, colors, firstColor, nColors) { var surfData = SDL.surfaces[surf]; |