aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/library.js44
-rw-r--r--src/library_gl.js372
-rw-r--r--src/library_sdl.js10
-rw-r--r--src/preamble.js18
-rw-r--r--src/settings.js3
5 files changed, 419 insertions, 28 deletions
diff --git a/src/library.js b/src/library.js
index cdcd275a..78dd629b 100644
--- a/src/library.js
+++ b/src/library.js
@@ -86,6 +86,23 @@ LibraryManager.library = {
parentPath: null,
parentObject: null
};
+#if FS_LOG
+ var inputPath = path;
+ function log() {
+ print('FS.analyzePath("' + inputPath + '", ' +
+ dontResolveLastLink + ', ' +
+ linksVisited + ') => {' +
+ 'isRoot: ' + ret.isRoot + ', ' +
+ 'exists: ' + ret.exists + ', ' +
+ 'error: ' + ret.error + ', ' +
+ 'name: "' + ret.name + '", ' +
+ 'path: "' + ret.path + '", ' +
+ 'object: ' + ret.object + ', ' +
+ 'parentExists: ' + ret.parentExists + ', ' +
+ 'parentPath: "' + ret.parentPath + '", ' +
+ 'parentObject: ' + ret.parentObject + '}');
+ }
+#endif
path = FS.absolutePath(path);
if (path == '/') {
ret.isRoot = true;
@@ -123,8 +140,12 @@ LibraryManager.library = {
break;
}
var link = FS.absolutePath(current.link, traversed.join('/'));
- return FS.analyzePath([link].concat(path).join('/'),
- dontResolveLastLink, linksVisited + 1);
+ ret = FS.analyzePath([link].concat(path).join('/'),
+ dontResolveLastLink, linksVisited + 1);
+#if FS_LOG
+ log();
+#endif
+ return ret;
}
traversed.push(target);
if (path.length == 0) {
@@ -133,8 +154,10 @@ LibraryManager.library = {
ret.object = current;
}
}
- return ret;
}
+#if FS_LOG
+ log();
+#endif
return ret;
},
// Finds the file system object at a given path. If dontResolveLastLink is
@@ -152,6 +175,13 @@ LibraryManager.library = {
},
// Creates a file system record: file, link, device or folder.
createObject: function(parent, name, properties, canRead, canWrite) {
+#if FS_LOG
+ print('FS.createObject("' + parent + '", ' +
+ '"' + name + '", ' +
+ JSON.stringify(properties) + ', ' +
+ canRead + ', ' +
+ canWrite + ')');
+#endif
if (!parent) parent = '/';
if (typeof parent === 'string') parent = FS.findObject(parent);
@@ -4217,11 +4247,19 @@ LibraryManager.library = {
isdigit: function(chr) {
return chr >= '0'.charCodeAt(0) && chr <= '9'.charCodeAt(0);
},
+ isdigit_l__deps: ['isdigit'],
+ isdigit_l: function(chr, loc) {
+ return _isdigit(chr);
+ },
isxdigit: function(chr) {
return (chr >= '0'.charCodeAt(0) && chr <= '9'.charCodeAt(0)) ||
(chr >= 'a'.charCodeAt(0) && chr <= 'f'.charCodeAt(0)) ||
(chr >= 'A'.charCodeAt(0) && chr <= 'F'.charCodeAt(0));
},
+ isxdigit_l__deps: ['isxdigit'],
+ isxdigit_l: function(chr, loc) {
+ return _isxdigit(chr);
+ },
isalnum: function(chr) {
return (chr >= '0'.charCodeAt(0) && chr <= '9'.charCodeAt(0)) ||
(chr >= 'a'.charCodeAt(0) && chr <= 'z'.charCodeAt(0)) ||
diff --git a/src/library_gl.js b/src/library_gl.js
index 9a63f5c0..f6fb2e27 100644
--- a/src/library_gl.js
+++ b/src/library_gl.js
@@ -29,6 +29,14 @@ var LibraryGL = {
#endif
return this.table[id];
},
+ id: function(obj) {
+ for (var i = 1; i < this.counter; ++i) {
+ if (obj == this.table[i]) {
+ return i;
+ }
+ }
+ return null;
+ },
remove: function(id) {
if( id == 0 ) return;
#if ASSERTIONS
@@ -44,11 +52,11 @@ var LibraryGL = {
glGetString: function(name_) {
switch(name_) {
- case Module.ctx.VENDOR:
- case Module.ctx.RENDERER:
- case Module.ctx.VERSION:
+ case 0x1F00 /* GL_VENDOR */:
+ case 0x1F01 /* GL_RENDERER */:
+ case 0x1F02 /* GL_VERSION */:
return allocate(intArrayFromString(Module.ctx.getParameter(name_)), 'i8', ALLOC_NORMAL);
- case 0x1F03: // Extensions
+ case 0x1F03 /* GL_EXTENSIONS */:
return allocate(intArrayFromString(Module.ctx.getSupportedExtensions().join(' ')), 'i8', ALLOC_NORMAL);
default:
throw 'Failure: Invalid glGetString value: ' + name_;
@@ -56,7 +64,125 @@ var LibraryGL = {
},
glGetIntegerv: function(name_, p) {
- {{{ makeSetValue('p', '0', 'Module.ctx.getParameter(name_)', 'i32') }}};
+ var result = Module.ctx.getParameter(name_);
+ switch (typeof(result)) {
+ case "number":
+ {{{ makeSetValue('p', '0', 'result', 'i32') }}};
+ break;
+ case "boolean":
+ {{{ makeSetValue('p', '0', 'result ? 1 : 0', 'i32') }}};
+ break;
+ case "string":
+ throw 'Native code calling glGetIntegerv(' + name_ + ') on a name which returns a string!';
+ case "object":
+ if (result === null) {
+ {{{ makeSetValue('p', '0', '0', 'i32') }}};
+ } else if (result instanceof Float32Array ||
+ result instanceof Uint32Array ||
+ result instanceof Int32Array ||
+ result instanceof Array) {
+ for (var i = 0; i < result.length; ++i) {
+ {{{ makeSetValue('p', 'i', 'result[i]', 'i32') }}};
+ }
+ } else if (result instanceof WebGLBuffer) {
+ {{{ makeSetValue('p', '0', 'GL.hashtable("buffer").id(result)', 'i32') }}};
+ } else if (result instanceof WebGLProgram) {
+ {{{ makeSetValue('p', '0', 'GL.hashtable("program").id(result)', 'i32') }}};
+ } else if (result instanceof WebGLFramebuffer) {
+ {{{ makeSetValue('p', '0', 'GL.hashtable("framebuffer").id(result)', 'i32') }}};
+ } else if (result instanceof WebGLRenderbuffer) {
+ {{{ makeSetValue('p', '0', 'gl.hashtable("renderbuffer").id(result)', 'i32') }}};
+ } else if (result instanceof WebGLTexture) {
+ {{{ makeSetValue('p', '0', 'gl.hashtable("texture").id(result)', 'i32') }}};
+ } else {
+ throw 'Unknown object returned from WebGL getParameter';
+ }
+ break;
+ case "undefined":
+ throw 'Native code calling glGetIntegerv(' + name_ + ') and it returns undefined';
+ default:
+ throw 'Why did we hit the default case?';
+ }
+ },
+
+ glGetFloatv: function(name_, p) {
+ var result = Module.ctx.getParameter(name_);
+ switch (typeof(result)) {
+ case "number":
+ {{{ makeSetValue('p', '0', 'result', 'float') }}};
+ break;
+ case "boolean":
+ {{{ makeSetValue('p', '0', 'result ? 1.0 : 0.0', 'float') }}};
+ break;
+ case "string":
+ {{{ makeSetValue('p', '0', '0', 'float') }}};
+ case "object":
+ if (result === null) {
+ throw 'Native code calling glGetFloatv(' + name_ + ') and it returns null';
+ } else if (result instanceof Float32Array ||
+ result instanceof Uint32Array ||
+ result instanceof Int32Array ||
+ result instanceof Array) {
+ for (var i = 0; i < result.length; ++i) {
+ {{{ makeSetValue('p', 'i', 'result[i]', 'float') }}};
+ }
+ } else if (result instanceof WebGLBuffer) {
+ {{{ makeSetValue('p', '0', 'GL.hashtable("buffer").id(result)', 'float') }}};
+ } else if (result instanceof WebGLProgram) {
+ {{{ makeSetValue('p', '0', 'GL.hashtable("program").id(result)', 'float') }}};
+ } else if (result instanceof WebGLFramebuffer) {
+ {{{ makeSetValue('p', '0', 'GL.hashtable("framebuffer").id(result)', 'float') }}};
+ } else if (result instanceof WebGLRenderbuffer) {
+ {{{ makeSetValue('p', '0', 'gl.hashtable("renderbuffer").id(result)', 'float') }}};
+ } else if (result instanceof WebGLTexture) {
+ {{{ makeSetValue('p', '0', 'gl.hashtable("texture").id(result)', 'float') }}};
+ } else {
+ throw 'Unknown object returned from WebGL getParameter';
+ }
+ break;
+ case "undefined":
+ throw 'Native code calling glGetFloatv(' + name_ + ') and it returns undefined';
+ default:
+ throw 'Why did we hit the default case?';
+ }
+ },
+
+ glGetBooleanv: function(name_, p) {
+ var result = Module.ctx.getParameter(name_);
+ switch (typeof(result)) {
+ case "number":
+ {{{ makeSetValue('p', '0', 'result != 0', 'i8') }}};
+ break;
+ case "boolean":
+ {{{ makeSetValue('p', '0', 'result != 0', 'i8') }}};
+ break;
+ case "string":
+ throw 'Native code calling glGetBooleanv(' + name_ + ') on a name which returns a string!';
+ case "object":
+ if (result === null) {
+ {{{ makeSetValue('p', '0', '0', 'i8') }}};
+ } else if (result instanceof Float32Array ||
+ result instanceof Uint32Array ||
+ result instanceof Int32Array ||
+ result instanceof Array) {
+ for (var i = 0; i < result.length; ++i) {
+ {{{ makeSetValue('p', 'i', 'result[i] != 0', 'i8') }}};
+ }
+ } else if (result instanceof WebGLBuffer ||
+ result instanceof WebGLProgram ||
+ result instanceof WebGLFramebuffer ||
+ result instanceof WebGLRenderbuffer ||
+ result instanceof WebGLTexture) {
+ {{{ makeSetValue('p', '0', '1', 'i8') }}}; // non-zero ID is always 1!
+ } else {
+ throw 'Unknown object returned from WebGL getParameter';
+ }
+ break;
+ case "undefined":
+ throw 'Unknown object returned from WebGL getParameter';
+ default:
+ throw 'Why did we hit the default case?';
+ }
},
glGenTextures__deps: ['$GL'],
@@ -75,16 +201,98 @@ var LibraryGL = {
}
},
+ glCompressedTexImage2D: function(target, level, internalformat, width, height, border, imageSize, data) {
+ if (data) {
+ data = new Uint8Array(Array_copy(data, imageSize));
+ } else {
+ data = null;
+ }
+ Module.ctx.compressedTexImage2D(target, level, internalformat, width, height, border, data);
+ },
+
+ glCompressedTexSubImage2D: function(target, level, xoffset, yoffset, width, height, format, imageSize, data) {
+ if (data) {
+ data = new Uint8Array(Array_copy(data, imageSize));
+ } else {
+ data = null;
+ }
+ Module.ctx.compressedTexSubImage2D(target, level, xoffset, yoffset, width, height, data);
+ },
+
glTexImage2D: function(target, level, internalformat, width, height, border, format, type, pixels) {
if (pixels) {
- pixels = new Uint8Array(Array_copy(pixels, pixels + width*height*4)); // TODO: optimize
+ var sizePerPixel;
+ switch (type) {
+ case 0x1401 /* GL_UNSIGNED_BYTE */:
+ switch (format) {
+ case 0x1906 /* GL_ALPHA */:
+ case 0x1909 /* GL_LUMINANCE */:
+ sizePerPixel = 1;
+ break;
+ case 0x1907 /* GL_RGB */:
+ sizePerPixel = 3;
+ break;
+ case 0x1908 /* GL_RGBA */:
+ sizePerPixel = 4;
+ break;
+ case 0x190A /* GL_LUMINANCE_ALPHA */:
+ sizePerPixel = 2;
+ break;
+ default:
+ throw 'Invalid format (' + format + ') passed to glTexImage2D';
+ }
+ pixels = new Uint8Array(Array_copy(pixels, width*height*sizePerPixel));
+ break;
+ case 0x8363 /* GL_UNSIGNED_SHORT_5_6_5 */:
+ case 0x8033 /* GL_UNSIGNED_SHORT_4_4_4_4 */:
+ case 0x8034 /* GL_UNSIGNED_SHORT_5_5_5_1 */:
+ sizePerPixel = 2;
+ pixels = new Uint16Array(new ArrayBuffer(Array_copy(pixels, width*height*sizePerPixel*2)));
+ break;
+ default:
+ throw 'Invalid type (' + type + ') passed to glTexImage2D';
+ }
+ } else {
+ pixels = null;
}
Module.ctx.texImage2D(target, level, internalformat, width, height, border, format, type, pixels);
},
glTexSubImage2D: function(target, level, xoffset, yoffset, width, height, format, type, pixels) {
if (pixels) {
- pixels = new Uint8Array(Array_copy(pixels, pixels + width*height*4)); // TODO: optimize
+ var sizePerPixel;
+ switch (type) {
+ case 0x1401 /* GL_UNSIGNED_BYTE */:
+ switch (format) {
+ case 0x1906 /* GL_ALPHA */:
+ case 0x1909 /* GL_LUMINANCE */:
+ sizePerPixel = 1;
+ break;
+ case 0x1907 /* GL_RGB */:
+ sizePerPixel = 3;
+ break;
+ case 0x1908 /* GL_RGBA */:
+ sizePerPixel = 4;
+ break;
+ case 0x190A /* GL_LUMINANCE_ALPHA */:
+ sizePerPixel = 2;
+ break;
+ default:
+ throw 'Invalid format (' + format + ') passed to glTexSubImage2D';
+ }
+ pixels = new Uint8Array(Array_copy(pixels, (width-xoffset+1)*(height-yoffset+1)*sizePerPixel));
+ break;
+ case 0x8363 /* GL_UNSIGNED_SHORT_5_6_5 */:
+ case 0x8033 /* GL_UNSIGNED_SHORT_4_4_4_4 */:
+ case 0x8034 /* GL_UNSIGNED_SHORT_5_5_5_1 */:
+ sizePerPixel = 2;
+ pixels = new Uint16Array(new ArrayBuffer(Array_copy(pixels, (width-xoffset+1)*(height-yoffset+1)*sizePerPixel*2)));
+ break;
+ default:
+ throw 'Invalid type (' + type + ') passed to glTexSubImage2D';
+ }
+ } else {
+ pixels = null;
}
Module.ctx.texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
},
@@ -93,6 +301,23 @@ var LibraryGL = {
Module.ctx.bindTexture(target, GL.hashtable("texture").get(texture));
},
+ glGetTexParameterfv: function(target, pname, params) {
+ {{{ makeSetValue('params', '0', 'Module.getTexParameter(target, pname)', 'float') }}};
+ },
+
+ glGetTexParameteriv: function(target, pname, params) {
+ {{{ makeSetValue('params', '0', 'Module.getTexParameter(target, pname)', 'i32') }}};
+ },
+
+ glIsTexture_deps: ['$GL'],
+ glIsTexture: function(texture) {
+ var fb = GL.hashtable("texture").get(texture);
+ if (typeof(fb) == 'undefined') {
+ return false;
+ }
+ return Module.ctx.isTexture(fb);
+ },
+
glGenBuffers__deps: ['$GL'],
glGenBuffers: function(n, buffers) {
for (var i = 0; i < n; i++) {
@@ -114,6 +339,53 @@ var LibraryGL = {
Module.ctx.bufferData(target, floatArray, usage);
},
+ glBufferSubData: function(target, offset, size, data) {
+ var floatArray = new Float32Array(TypedArray_copy(data, size, offset));
+ Module.ctx.bufferSubData(target, offset, floatArray);
+ },
+
+ glIsBuffer_deps: ['$GL'],
+ glIsBuffer: function(buffer) {
+ var fb = GL.hashtable("buffer").get(buffer);
+ if (typeof(fb) == 'undefined') {
+ return false;
+ }
+ return Module.ctx.isBuffer(fb);
+ },
+
+ glGenRenderbuffers__deps: ['$GL'],
+ glGenRenderbuffers: function(n, renderbuffers) {
+ for (var i = 0; i < n; i++) {
+ var id = GL.hashtable("renderbuffer").add(Module.ctx.createRenderbuffer());
+ {{{ makeSetValue('renderbuffers', 'i', 'id', 'i32') }}};
+ }
+ },
+
+ glDeleteRenderbuffers: function(n, renderbuffers) {
+ for (var i = 0; i < n; i++) {
+ var id = {{{ makeGetValue('renderbuffers', 'i', 'i32') }}};
+ Module.ctx.deleteRenderbuffer(GL.hashtable("renderbuffer").get(id));
+ GL.hashtable("renderbuffer").remove(id);
+ }
+ },
+
+ glBindRenderbuffer: function(target, renderbuffer) {
+ Module.ctx.bindRenderbuffer(target, GL.hashtable("renderbuffer").get(renderbuffer));
+ },
+
+ glGetRenderbufferParameteriv: function(target, pname, params) {
+ {{{ makeSetValue('params', '0', 'Module.ctx.getRenderbufferParameter(target, pname)', 'i32') }}};
+ },
+
+ glIsRenderbuffer_deps: ['$GL'],
+ glIsRenderbuffer: function(renderbuffer) {
+ var fb = GL.hashtable("renderbuffer").get(renderbuffer);
+ if (typeof(fb) == 'undefined') {
+ return false;
+ }
+ return Module.ctx.isRenderbuffer(fb);
+ },
+
glBindAttribLocation_deps: ['$GL'],
glGetUniformLocation: function(program, name) {
name = Pointer_stringify(name);
@@ -272,6 +544,27 @@ var LibraryGL = {
return GL.hashtable("shader").add(shader);
},
+ glDeleteShader: function(shader) {
+ Module.ctx.deleteShader(GL.hashtable("shader").get(shader));
+ },
+
+ glDetachShader: function(program, shader) {
+ Module.ctx.detachShader(GL.hashtable("program").get(program),
+ GL.hashtable("shader").get(shader));
+ },
+
+ glGetAttachedShaders: function(program, maxCount, count, shaders) {
+ var result = Module.ctx.getAttachedShaders(GL.hashtable("program").get(program));
+ var len = result.length;
+ if (len > maxCount) {
+ len = maxCount;
+ }
+ {{{ makeSetValue('count', '0', 'len', 'i32') }}};
+ for (var i = 0; i < len; ++i) {
+ {{{ makeSetValue('shaders', 'i', 'GL.hashtable("shader").get(result[i])', 'i32') }}};
+ }
+ },
+
glShaderSource_deps: ['$GL'],
glShaderSource: function(shader, count, string, length) {
var source = "";
@@ -295,6 +588,15 @@ var LibraryGL = {
Module.ctx.shaderSource(GL.hashtable("shader").get(shader), source);
},
+ glGetShaderSource: function(shader, bufsize, length, source) {
+ var result = Module.ctx.getShaderSource(GL.hashtable("shader").get(shader));
+ result.slice(0, bufsize - 1);
+ writeStringToMemory(result, source);
+ if (length) {
+ {{{ makeSetValue('length', '0', 'result.length', 'i32') }}};
+ }
+ },
+
glCompileShader_deps: ['$GL'],
glCompileShader: function(shader) {
Module.ctx.compileShader(GL.hashtable("shader").get(shader));
@@ -306,18 +608,27 @@ var LibraryGL = {
log.slice(0, maxLength - 1);
writeStringToMemory(log, infoLog);
if (length) {
- {{{ makeSetValue('length', 'i', 'log.length', 'i32') }}}
+ {{{ makeSetValue('length', '0', 'log.length', 'i32') }}}
}
},
-
+
glGetShaderiv_deps: ['$GL'],
- glGetShaderiv : function(shader, pname, p) {
- {{{ makeSetValue('p', '0', 'Module.ctx.getShaderParameter(GL.hashtable("shader").get(shader),pname)', 'i32') }}};
+ glGetShaderiv : function(shader, pname, p) {
+ {{{ makeSetValue('p', '0', 'Module.ctx.getShaderParameter(GL.hashtable("shader").get(shader), pname)', 'i32') }}};
},
glGetProgramiv_deps: ['$GL'],
- glGetProgramiv : function(program, pname, p) {
- {{{ makeSetValue('p', '0', 'Module.ctx.getProgramParameter(GL.hashtable("program").get(program),pname)', 'i32') }}};
+ glGetProgramiv : function(program, pname, p) {
+ {{{ makeSetValue('p', '0', 'Module.ctx.getProgramParameter(GL.hashtable("program").get(program), pname)', 'i32') }}};
+ },
+
+ glIsShader_deps: ['$GL'],
+ glIsShader: function(shader) {
+ var fb = GL.hashtable("shader").get(shader);
+ if (typeof(fb) == 'undefined') {
+ return false;
+ }
+ return Module.ctx.isShader(fb);
},
glCreateProgram_deps: ['$GL'],
@@ -325,12 +636,23 @@ var LibraryGL = {
return GL.hashtable("program").add(Module.ctx.createProgram());
},
+ glDeleteProgram: function(program) {
+ Module.ctx.deleteProgram(GL.hashtable("program").get(program));
+ },
+
glAttachShader_deps: ['$GL'],
glAttachShader: function(program, shader) {
Module.ctx.attachShader(GL.hashtable("program").get(program),
GL.hashtable("shader").get(shader));
},
+ glGetShaderPrecisionFormat: function(shaderType, precisionType, range, precision) {
+ var result = Module.ctx.getShaderPrecisionFormat(shaderType, precisionType);
+ {{{ makeSetValue('range', '0', 'result.rangeMin', 'i32') }}};
+ {{{ makeSetValue('range', '1', 'result.rangeMax', 'i32') }}};
+ {{{ makeSetValue('precision', '0', 'result.precision', 'i32') }}};
+ },
+
glLinkProgram_deps: ['$GL'],
glLinkProgram: function(program) {
Module.ctx.linkProgram(GL.hashtable("program").get(program));
@@ -346,7 +668,7 @@ var LibraryGL = {
log = log.substr(0, maxLength - 1);
writeStringToMemory(log, infoLog);
if (length) {
- {{{ makeSetValue('length', 'i', 'log.length', 'i32') }}}
+ {{{ makeSetValue('length', '0', 'log.length', 'i32') }}}
}
},
@@ -355,6 +677,20 @@ var LibraryGL = {
Module.ctx.useProgram(GL.hashtable("program").get(program));
},
+ glValidateProgram_deps: ['$Gl'],
+ glValidateProgram: function(program) {
+ Module.ctx.validateProgram(GL.hashtable("program").get(program));
+ },
+
+ glIsProgram_deps: ['$GL'],
+ glIsProgram: function(program) {
+ var fb = GL.hashtable("program").get(program);
+ if (typeof(fb) == 'undefined') {
+ return false;
+ }
+ return Module.ctx.isProgram(fb);
+ },
+
glBindAttribLocation_deps: ['$GL'],
glBindAttribLocation: function(program, index, name) {
name = Pointer_stringify(name);
@@ -414,12 +750,12 @@ var LibraryGL = {
// Simple pass-through functions
[[0, 'shadeModel fogi fogfv getError finish flush'],
- [1, 'clearDepth depthFunc enable disable frontFace cullFace clear enableVertexAttribArray disableVertexAttribArray lineWidth clearStencil depthMask stencilMask stencilMaskSeparate checkFramebufferStatus activeTexture'],
- [2, 'pixelStorei vertexAttrib1f depthRange polygonOffset blendFunc'],
+ [1, 'clearDepth depthFunc enable disable frontFace cullFace clear enableVertexAttribArray disableVertexAttribArray lineWidth clearStencil depthMask stencilMask stencilMaskSeparate checkFramebufferStatus generateMipmap activeTexture'],
[3, 'texParameteri texParameterf drawArrays vertexAttrib2f'],
- [4, 'viewport clearColor scissor vertexAttrib3f colorMask drawElements'],
+ [4, 'viewport clearColor scissor vertexAttrib3f colorMask drawElements renderbufferStorage'],
[5, 'vertexAttrib4f'],
- [6, 'vertexAttribPointer']].forEach(function(data) {
+ [6, 'vertexAttribPointer'],
+ [8, 'copyTexImage2D copyTexSubImage2D']].forEach(function(data) {
var num = data[0];
var names = data[1];
var args = range(num).map(function(i) { return 'x' + i }).join(', ');
diff --git a/src/library_sdl.js b/src/library_sdl.js
index 4c28eefd..631de481 100644
--- a/src/library_sdl.js
+++ b/src/library_sdl.js
@@ -90,6 +90,7 @@ mergeInto(LibraryManager.library, {
fonts: [null],
keyboardState: null,
+ startTime: null,
mouseX: 0,
mouseY: 0,
@@ -98,6 +99,7 @@ mergeInto(LibraryManager.library, {
40: 1105, // down arrow
37: 1104, // left arrow
39: 1103, // right arrow
+
17: 305, // control (right, or left)
18: 308, // alt
109: 45, // minus
@@ -378,7 +380,13 @@ mergeInto(LibraryManager.library, {
return 0; // success
},
- SDL_WasInit: function() { return 0 }, // TODO
+ SDL_WasInit__deps: ['SDL_Init'],
+ SDL_WasInit: function() {
+ if (SDL.startTime === null) {
+ _SDL_Init();
+ }
+ return 1;
+ },
SDL_GetVideoInfo: function() {
// %struct.SDL_VideoInfo = type { i32, i32, %struct.SDL_PixelFormat*, i32, i32 } - 5 fields of quantum size
diff --git a/src/preamble.js b/src/preamble.js
index 33da1159..c88a4671 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -729,11 +729,14 @@ Module['Array_copy'] = Array_copy;
#if USE_TYPED_ARRAYS
// Copies a list of num items on the HEAP into a
// JavaScript typed array.
-function TypedArray_copy(ptr, num) {
+function TypedArray_copy(ptr, num, offset /*optional*/) {
// TODO: optimize this!
- var arr = new Uint8Array(num);
- for (var i = 0; i < num; ++i) {
- arr[i] = {{{ makeGetValue('ptr', 'i', 'i8') }}};
+ if (offset === undefined) {
+ offset = 0;
+ }
+ var arr = new Uint8Array(num - offset);
+ for (var i = offset; i < num; ++i) {
+ arr[i - offset] = {{{ makeGetValue('ptr', 'i', 'i8') }}};
}
return arr.buffer;
}
@@ -762,11 +765,14 @@ Module['String_copy'] = String_copy;
// This processes a JS string into a C-line array of numbers, 0-terminated.
// For LLVM-originating strings, see parser.js:parseLLVMString function
-function intArrayFromString(stringy, dontAddNull) {
+function intArrayFromString(stringy, dontAddNull, length /* optional */) {
var ret = [];
var t;
var i = 0;
- while (i < stringy.length) {
+ if (length === undefined) {
+ length = stringy.length;
+ }
+ while (i < length) {
var chr = stringy.charCodeAt(i);
if (chr > 0xFF) {
#if ASSERTIONS
diff --git a/src/settings.js b/src/settings.js
index b8dbe06e..66b53218 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -136,6 +136,9 @@ var CORRECT_OVERFLOWS = 1; // Experimental code that tries to prevent unexpected
var CORRECT_ROUNDINGS = 1; // C rounds to 0 (-5.5 to -5, +5.5 to 5), while JS has no direct way to do that:
// Math.floor is to negative, ceil to positive. With CORRECT_ROUNDINGS,
// we will do slow but correct C rounding operations.
+var FS_LOG = 0; // Log all FS operations. This is especially helpful when you're porting
+ // a new project and want to see a list of file system operations happening
+ // so that you can create a virtual file system with all of the required files.
var PGO = 0; // Profile-guided optimization.
// When run with the CHECK_* options, will not fail on errors. Instead, will