aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/library_browser.js10
-rw-r--r--src/library_gl.js61
-rw-r--r--src/library_sdl.js73
-rw-r--r--src/runtime.js18
-rwxr-xr-x[-rw-r--r--]tools/dead_function_eliminator.py0
5 files changed, 138 insertions, 24 deletions
diff --git a/src/library_browser.js b/src/library_browser.js
index ccc13698..08d206ae 100644
--- a/src/library_browser.js
+++ b/src/library_browser.js
@@ -5,9 +5,13 @@ mergeInto(Library, {
syncLoad: function(url) {
var xhr = new XMLHttpRequest();
xhr.open("GET", url, false);
+ xhr.overrideMimeType('text/plain; charset=x-user-defined');
xhr.send(null);
- var buffer = xhr.mozResponseArrayBuffer;
- return new Uint8Array(buffer);
+ var ret = new Uint8Array(xhr.responseText.length);
+ for (var i = 0; i < xhr.responseText.length; i++) {
+ ret[i] = xhr.responseText.charCodeAt(i);
+ }
+ return ret;
},
// Given binary data for an image, in a format like PNG or JPG, we convert it
@@ -41,7 +45,7 @@ mergeInto(Library, {
var canvas = document.createElement('canvas');
img.src = 'data:image/' + format + ';base64,' + encodeBase64(pixels);
var ctx = canvas.getContext('2d');
- ctx.drawImage(Module.img, 0, 0);
+ ctx.drawImage(img, 0, 0);
var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
return imageData;
},
diff --git a/src/library_gl.js b/src/library_gl.js
index 3da67c80..8e4159af 100644
--- a/src/library_gl.js
+++ b/src/library_gl.js
@@ -1,34 +1,75 @@
+// XXX FIXME Hardcoded '4' in many places, here and in library_SDL, for RGBA
+
var LibraryGL = {
+ $GL: {
+ textures: {},
+ textureCounter: 0,
+ },
+
glGetString: function(name_) {
switch(name_) {
- case Module.contextGL.VENDOR:
- case Module.contextGL.RENDERER:
- case Module.contextGL.VERSION:
- return Pointer_make(intArrayFromString(Module.contextGL.getParameter(name_)), null, ALLOC_NORMAL);
+ case Module.ctxGL.VENDOR:
+ case Module.ctxGL.RENDERER:
+ case Module.ctxGL.VERSION:
+ return Pointer_make(intArrayFromString(Module.ctxGL.getParameter(name_)), null, ALLOC_NORMAL);
case 0x1F03: // Extensions
- return Pointer_make(intArrayFromString(Module.contextGL.getSupportedExtensions().join(' ')), null, ALLOC_NORMAL);
+ return Pointer_make(intArrayFromString(Module.ctxGL.getSupportedExtensions().join(' ')), null, ALLOC_NORMAL);
default:
throw 'Failure: Invalid glGetString value: ' + name_;
}
},
- glGetIntegerv: function(name_) {
+ glGetIntegerv: function(name_, p) {
switch(name_) {
- case Module.contextGL.MAX_TEXTURE_SIZE:
- return Module.contextGL.getParameter(name_);
+ case Module.ctxGL.MAX_TEXTURE_SIZE:
+ IHEAP[p] = Module.ctxGL.getParameter(name_);
+ break;
default:
throw 'Failure: Invalid glGetIntegerv value: ' + name_;
}
- }
+ },
+
+ glGenTextures__deps: ['$GL'],
+ glGenTextures: function(n, textures) {
+ for (var i = 0; i < n; i++) {
+ var id = GL.textureCounter++;
+ GL.textures[id] = Module.ctxGL.createTexture();
+ IHEAP[textures+QUANTUM_SIZE*i] = id;
+ }
+ },
+
+ glDeleteTextures: function(n, textures) {
+ for (var i = 0; i < n; i++) {
+ var id = IHEAP[textures+QUANTUM_SIZE*i];
+ Module.ctxGL.deleteTexture(GL.textures[id]);
+ delete GL.textures[id];
+ }
+ },
+
+ glTexImage2D: function(target, level, internalformat, width, height, border, format, type, pixels) {
+ if (pixels) {
+ pixels = new Uint8Array(IHEAP.slice(pixels, pixels + width*height*4)); // TODO: optimize
+ }
+ Module.ctxGL.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(IHEAP.slice(pixels, pixels + width*height*4)); // TODO: optimize
+ }
+ Module.ctxGL.texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+ },
};
+// Simple pass-through functions
[[0, 'shadeModel fogi fogfv'],
[1, 'clearDepth depthFunc enable disable frontFace cullFace'],
+ [2, 'pixelStorei'],
[4, 'viewport clearColor']].forEach(function(data) {
var num = data[0];
var names = data[1];
var args = range(num).map(function(i) { return 'x' + i }).join(', ');
- var stub = '(function(' + args + ') { ' + (num > 0 ? 'Module.contextGL.NAME(' + args + ')' : '') + ' })';
+ var stub = '(function(' + args + ') { ' + (num > 0 ? 'Module.ctxGL.NAME(' + args + ')' : '') + ' })';
names.split(' ').forEach(function(name_) {
var cName = 'gl' + name_[0].toUpperCase() + name_.substr(1);
LibraryGL[cName] = eval(stub.replace('NAME', name_));
diff --git a/src/library_sdl.js b/src/library_sdl.js
index 0dda52ef..648f0014 100644
--- a/src/library_sdl.js
+++ b/src/library_sdl.js
@@ -1,5 +1,5 @@
// To use emscripten's SDL library here, you need to define
-// Module.canvas and at least one of Module.context2D, Module.contextGL.
+// Module.canvas and at least one of Module.ctx2D, Module.ctxGL.
mergeInto(Library, {
$SDL__deps: ['$Browser'],
@@ -11,25 +11,45 @@ mergeInto(Library, {
surfaces: {},
+ structs: {
+ PixelFormat: Runtime.generateStructInfo([['void*', 'palette'], ['i8', 'BitsPerPixel'], ['i8', 'BytesPerPixel']])
+ },
+
makeSurface: function(width, height, flags) {
var surf = _malloc(14*QUANTUM_SIZE); // SDL_Surface has 14 fields of quantum size
var buffer = _malloc(width*height*4);
- IHEAP[surf+QUANTUM_SIZE*0] = flags; // SDL_Surface.flags
- IHEAP[surf+QUANTUM_SIZE*1] = 0; // SDL_Surface.format TODO
- IHEAP[surf+QUANTUM_SIZE*2] = width; // SDL_Surface.w
- IHEAP[surf+QUANTUM_SIZE*3] = height; // SDL_Surface.h
- IHEAP[surf+QUANTUM_SIZE*4] = width*4; // SDL_Surface.pitch, assuming RGBA for now, since that is what ImageData gives us in browsers
- IHEAP[surf+QUANTUM_SIZE*5] = buffer; // SDL_Surface.pixels
+ var pixelFormat = _malloc(18*QUANTUM_SIZE);
+
+ IHEAP[surf+QUANTUM_SIZE*0] = flags; // SDL_Surface.flags
+ IHEAP[surf+QUANTUM_SIZE*1] = pixelFormat; // SDL_Surface.format TODO
+ IHEAP[surf+QUANTUM_SIZE*2] = width; // SDL_Surface.w
+ IHEAP[surf+QUANTUM_SIZE*3] = height; // SDL_Surface.h
+ IHEAP[surf+QUANTUM_SIZE*4] = width*4; // SDL_Surface.pitch, assuming RGBA for now, since that is what ImageData gives us in browsers
+ IHEAP[surf+QUANTUM_SIZE*5] = buffer; // SDL_Surface.pixels
+
+ IHEAP[pixelFormat + SDL.structs.PixelFormat.palette] = 0; // TODO
+ IHEAP[pixelFormat + SDL.structs.PixelFormat.BitsPerPixel] = 32;
+ IHEAP[pixelFormat + SDL.structs.PixelFormat.BytesPerPixel] = 4;
+
SDL.surfaces[surf] = {
width: width,
height: height,
canvas: Module.canvas,
- context: Module.context2D,
+ ctx: Module.ctx2D,
surf: surf,
- buffer: buffer
+ buffer: buffer,
+ pixelFormat: pixelFormat,
+ alpha: 255
};
return surf;
},
+
+ freeSurface: function(surf) {
+ _free(SDL.surfaces[surf].buffer);
+ _free(SDL.surfaces[surf].pixelFormat);
+ _free(surf);
+ delete SDL.surfaces[surf];
+ }
},
SDL_Init__deps: ['$SDL'],
@@ -67,7 +87,7 @@ mergeInto(Library, {
SDL_LockSurface: function(surf) {
var surfData = SDL.surfaces[surf];
- surfData.image = surfData.context.getImageData(0, 0, surfData.width, surfData.height);
+ surfData.image = surfData.ctx.getImageData(0, 0, surfData.width, surfData.height);
// Copy pixel data to somewhere accessible to 'C/C++'
var num = surfData.image.data.length;
for (var i = 0; i < num; i++) {
@@ -93,7 +113,7 @@ mergeInto(Library, {
surfData.image.data[i*4+3] = 255; // opacity, as canvases blend alpha
}
// Copy to canvas
- surfData.context.putImageData(surfData.image, 0, 0);
+ surfData.ctx.putImageData(surfData.image, 0, 0);
// Cleanup
surfData.image = null;
},
@@ -123,7 +143,38 @@ mergeInto(Library, {
return Pointer_make(intArrayFromString("SDL is cool"), null);
},
+ SDL_CreateRGBSurface: function(flags, width, height, depth, rmask, gmask, bmask, amask) {
+ return SDL.makeSurface(width, height, flags);
+ },
+
+ SDL_FreeSurface: function(surf) {
+ SDL.freeSurface(surf);
+ },
+
+ SDL_UpperBlit: function(src, srcrect, dst, dstrect) {
+ assert(!srcrect && !dstrect); // TODO
+ var srcData = SDL.surfaces[src];
+ var dstData = SDL.surfaces[dst];
+ assert(srcData.width === dstData.width && srcData.height === dstData.height);
+ for (var i = 0; i < srcData.width*srcData.height*4; i++) {
+ IHEAP[dstData.buffer + i] = IHEAP[srcData.buffer + i];
+ }
+ return 0;
+ },
+
+ SDL_BlitSurface__deps: ['SDL_UpperBlit'],
+ SDL_BlitSurface: function(src, srcrect, dst, dstrect) {
+ return _SDL_Blit(src, srcrect, dst, dstrect);
+ },
+
+ SDL_SetAlpha: function(surf, flag, alpha) {
+ SDL.surfaces[surf].alpha = alpha;
+ },
+
+ // SDL_Image
+
IMG_Load: function(filename) {
+ filename = Pointer_stringify(filename);
var format = filename.split('.').slice(-1)[0];
var data = Browser.syncLoad(filename);
var raw = Browser.decodeImage(data, format);
diff --git a/src/runtime.js b/src/runtime.js
index 10aab3c9..0b809d6b 100644
--- a/src/runtime.js
+++ b/src/runtime.js
@@ -131,6 +131,24 @@ Runtime = {
}
type.needsFlattening = (type.flatFactor != 1);
return type.flatIndexes;
+ },
+
+ // Given details about a structure, returns its alignment. For example,
+ // generateStructInfo(
+ // [
+ // ['i32', 'field1'],
+ // ['i8', 'field2']
+ // ]
+ // ) will return
+ // { field1: 0, field2: 4 } (depending on QUANTUM_SIZE)
+ generateStructInfo: function(struct) {
+ var fields = struct.map(function(item) { return item[0] });
+ var alignment = Runtime.calculateStructAlignment({ fields: fields });
+ var ret = {};
+ struct.forEach(function(item, i) {
+ ret[item[1]] = alignment[i];
+ });
+ return ret;
}
};
diff --git a/tools/dead_function_eliminator.py b/tools/dead_function_eliminator.py
index a694ce05..a694ce05 100644..100755
--- a/tools/dead_function_eliminator.py
+++ b/tools/dead_function_eliminator.py