diff options
-rw-r--r-- | src/library_browser.js | 10 | ||||
-rw-r--r-- | src/library_gl.js | 61 | ||||
-rw-r--r-- | src/library_sdl.js | 73 | ||||
-rw-r--r-- | src/runtime.js | 18 | ||||
-rwxr-xr-x[-rw-r--r--] | tools/dead_function_eliminator.py | 0 |
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 |