aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/analyzer.js10
-rw-r--r--src/library.js13
-rw-r--r--src/library_openal.js265
-rw-r--r--src/library_sdl.js76
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];