aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler.js2
-rw-r--r--src/jsifier.js17
-rw-r--r--src/library_browser.js50
-rw-r--r--src/library_sdl.js54
-rw-r--r--tests/runner.py2
5 files changed, 96 insertions, 29 deletions
diff --git a/src/compiler.js b/src/compiler.js
index fc9ae7fc..699b0393 100644
--- a/src/compiler.js
+++ b/src/compiler.js
@@ -71,7 +71,7 @@ do {
var inter = intertyper(lines);
// Load library, with preprocessing and macros. Must be done after intertyper, so we know if we have debug info or not
-for (suffix in set('', '_sdl', '_gl')) {
+for (suffix in set('', '_sdl', '_gl', '_browser')) {
eval(processMacros(preprocess(read('library' + suffix + '.js'), CONSTANTS)));
}
diff --git a/src/jsifier.js b/src/jsifier.js
index 7c5c5f4f..0a590163 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -215,14 +215,17 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) {
} else if (typeof snippet === 'object') {
// JSON.stringify removes functions, so we need to make sure they are added
var funcs = [];
+ var hasNonFunc = false;
for (var x in snippet) {
if (typeof snippet[x] === 'function') {
funcs.push(x + ': ' + snippet[x].toString());
+ } else {
+ hasNonFunc = true;
}
}
snippet = JSON.stringify(snippet);
if (funcs.length > 0) {
- snippet = snippet.replace(/}$/, ', ' + funcs.join(', ') + ' }');
+ snippet = snippet.replace(/}$/, (hasNonFunc ? ', ' : '') + funcs.join(', ') + ' }');
}
} else if (typeof snippet === 'function') {
snippet = snippet.toString();
@@ -241,11 +244,17 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) {
});
}
- var deps = Library[ident + '__deps'];
+ var deps = Library[ident + '__deps'] || [];
if (redirectedIdent) {
- deps = (deps || []).concat(Library[redirectedIdent + '__deps']);
+ deps = deps.concat(Library[redirectedIdent + '__deps'] || []);
}
- return 'var _' + ident + '=' + snippet + (deps ? '\n' + deps.map(addFromLibrary).join('\n') : '');
+ // $ident's are special, we do not prefix them with a '_'.
+ if (ident[0] === '$') {
+ ident = ident.substr(1);
+ } else {
+ ident = '_' + ident;
+ }
+ return 'var ' + ident + '=' + snippet + (deps ? '\n' + deps.map(addFromLibrary).join('\n') : '');
}
item.JS = addFromLibrary(shortident);
} else {
diff --git a/src/library_browser.js b/src/library_browser.js
new file mode 100644
index 00000000..ccc13698
--- /dev/null
+++ b/src/library_browser.js
@@ -0,0 +1,50 @@
+// Utilities for browser environments
+
+mergeInto(Library, {
+ $Browser: {
+ syncLoad: function(url) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", url, false);
+ xhr.send(null);
+ var buffer = xhr.mozResponseArrayBuffer;
+ return new Uint8Array(buffer);
+ },
+
+ // Given binary data for an image, in a format like PNG or JPG, we convert it
+ // to flat pixel data. We do so using the browser's native code.
+ decodeImage: function(pixels, format) {
+ function encodeBase64(data) {
+ var BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+ var PAD = '=';
+ var ret = '';
+ var leftchar = 0;
+ var leftbits = 0;
+ for (var i = 0; i < data.length; i++) {
+ leftchar = (leftchar << 8) | data[i];
+ leftbits += 8;
+ while (leftbits >= 6) {
+ var curr = (leftchar >> (leftbits-6)) & 0x3f;
+ leftbits -= 6;
+ ret += BASE[curr];
+ }
+ }
+ if (leftbits == 2) {
+ ret += BASE[(leftchar&3) << 4];
+ ret += PAD + PAD;
+ } else if (leftbits == 4) {
+ ret += BASE[(leftchar&0xf) << 2];
+ ret += PAD;
+ }
+ return ret;
+ }
+ var img = new Image();
+ var canvas = document.createElement('canvas');
+ img.src = 'data:image/' + format + ';base64,' + encodeBase64(pixels);
+ var ctx = canvas.getContext('2d');
+ ctx.drawImage(Module.img, 0, 0);
+ var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
+ return imageData;
+ },
+ }
+});
+
diff --git a/src/library_sdl.js b/src/library_sdl.js
index 629df786..0dda52ef 100644
--- a/src/library_sdl.js
+++ b/src/library_sdl.js
@@ -2,19 +2,8 @@
// Module.canvas and at least one of Module.context2D, Module.contextGL.
mergeInto(Library, {
- _SDL: {
- // Given binary data for an image, in a format like PNG or JPG, we convert it
- // to flat pixel data.
- _decodeImage: function(image) {
- var img = new Image();
- var canvas = document.createElement('canvas');
- img.src = imageToBase64(image);
- var ctx = canvas.getContext('2d');
- ctx.drawImage(Module.img,0,0);
- var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
- return imageData;
- },
-
+ $SDL__deps: ['$Browser'],
+ $SDL: {
defaults: {
width: 320,
height: 240
@@ -22,21 +11,28 @@ mergeInto(Library, {
surfaces: {},
- makeSurface: function(width, height, depth, flags) {
- var surf = _malloc(14*QUANTUM_SIZE); // SDL_Surface has 14 fields of quantum size
- __SDL.surfaces[surf] = {
+ 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
+ SDL.surfaces[surf] = {
width: width,
height: height,
canvas: Module.canvas,
context: Module.context2D,
surf: surf,
- buffer: _malloc(width*height*4)
+ buffer: buffer
};
return surf;
},
},
- SDL_Init__deps: ['_SDL'],
+ SDL_Init__deps: ['$SDL'],
SDL_Init: function(what) {
return 0; // success
},
@@ -48,8 +44,8 @@ mergeInto(Library, {
IHEAP[ret] = 0; // TODO
IHEAP[ret+QUANTUM_SIZE] = 0; // TODO
IHEAP[ret+QUANTUM_SIZE*2] = 0; // TODO
- IHEAP[ret+QUANTUM_SIZE*3] = __SDL.defaults.width;
- IHEAP[ret+QUANTUM_SIZE*4] = __SDL.defaults.height;
+ IHEAP[ret+QUANTUM_SIZE*3] = SDL.defaults.width;
+ IHEAP[ret+QUANTUM_SIZE*4] = SDL.defaults.height;
return ret;
},
@@ -62,7 +58,7 @@ mergeInto(Library, {
},
SDL_SetVideoMode: function(width, height, depth, flags) {
- return __SDL.makeSurface(width, height, depth, flags);
+ return SDL.makeSurface(width, height, flags);
},
SDL_Quit: function() {
@@ -70,7 +66,7 @@ mergeInto(Library, {
},
SDL_LockSurface: function(surf) {
- var surfData = __SDL.surfaces[surf];
+ var surfData = SDL.surfaces[surf];
surfData.image = surfData.context.getImageData(0, 0, surfData.width, surfData.height);
// Copy pixel data to somewhere accessible to 'C/C++'
var num = surfData.image.data.length;
@@ -86,7 +82,7 @@ mergeInto(Library, {
},
SDL_UnlockSurface: function(surf) {
- var surfData = __SDL.surfaces[surf];
+ var surfData = SDL.surfaces[surf];
// Copy pixel data to image
var num = surfData.image.data.length;
for (var i = 0; i < num; i++) {
@@ -125,6 +121,18 @@ mergeInto(Library, {
SDL_GetError: function() {
return Pointer_make(intArrayFromString("SDL is cool"), null);
+ },
+
+ IMG_Load: function(filename) {
+ var format = filename.split('.').slice(-1)[0];
+ var data = Browser.syncLoad(filename);
+ var raw = Browser.decodeImage(data, format);
+ var surf = SDL.makeSurface(raw.width, raw.height, 0);
+ // XXX Extremely inefficient!
+ for (var i = 0; i < raw.width*raw.height*4; i++) {
+ IHEAP[SDL.surfaces[surf].buffer+i] = raw.data[i];
+ }
+ return surf;
}
});
diff --git a/tests/runner.py b/tests/runner.py
index ea9b2f94..4ce0746d 100644
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -1901,7 +1901,7 @@ if 'benchmark' not in sys.argv:
src.write(
'''
_STDIO.prepare('paper.pdf', eval(read('paper.pdf.js')));
- run(args);
+ run();
print("Data: " + JSON.stringify(_STDIO.streams[_STDIO.filenames['*s-0*d.']].data)); // work around __formatString__ fail
'''
)