aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/library.js20
-rw-r--r--src/library_gl.js7
-rw-r--r--src/library_sdl.js101
-rw-r--r--src/parseTools.js3
-rw-r--r--src/postamble.js4
-rw-r--r--src/preamble.js4
-rw-r--r--src/shell.html30
7 files changed, 100 insertions, 69 deletions
diff --git a/src/library.js b/src/library.js
index aa1fd242..78dd629b 100644
--- a/src/library.js
+++ b/src/library.js
@@ -445,6 +445,14 @@ LibraryManager.library = {
standardizePath: function(path) {
if (path.substr(0, 2) == './') path = path.substr(2);
return path;
+ },
+
+ deleteFile: function(path) {
+ var path = FS.analyzePath(path);
+ if (!path.parentExists || !path.exists) {
+ throw 'Invalid path ' + path;
+ }
+ delete path.parentObject.contents[path.name];
}
},
@@ -4642,16 +4650,20 @@ LibraryManager.library = {
_ZTIPv: [0],
llvm_uadd_with_overflow_i32: function(x, y) {
+ x = x>>>0;
+ y = y>>>0;
return {
- f0: x+y,
- f1: 0 // We never overflow... for now
+ f0: (x+y)>>>0,
+ f1: x+y > 4294967295
};
},
llvm_umul_with_overflow_i32: function(x, y) {
+ x = x>>>0;
+ y = y>>>0;
return {
- f0: x*y,
- f1: 0 // We never overflow... for now
+ f0: (x*y)>>>0,
+ f1: x*y > 4294967295
};
},
diff --git a/src/library_gl.js b/src/library_gl.js
index 6b0a270f..f6fb2e27 100644
--- a/src/library_gl.js
+++ b/src/library_gl.js
@@ -1,6 +1,11 @@
//"use strict";
-// XXX FIXME Hardcoded '4' in many places, here and in library_SDL, for RGBA
+// FIXME:
+// * glGetUniformLocation should return -1 when the value is not valid, not null
+// * glUniform1fi should be glUniform1iv
+// * glGetAttribLocation lacks return value (and should be -1 when not valid)
+// * single-underscore deps need double underscore (and, just auto-add them all)
+// * glGetProgramInfoLog and *shader* should be essentially identical
var LibraryGL = {
$GL: {
diff --git a/src/library_sdl.js b/src/library_sdl.js
index 06e10339..631de481 100644
--- a/src/library_sdl.js
+++ b/src/library_sdl.js
@@ -175,17 +175,21 @@ mergeInto(LibraryManager.library, {
},
// Load SDL color into a CSS-style color specification
- loadColorToCSS: function(color) {
+ loadColorToCSSRGB: function(color) {
var rgba = {{{ makeGetValue('color', '0', 'i32') }}};
- return 'rgba(' + (rgba&255) + ',' + ((rgba >> 8)&255) + ',' + ((rgba >> 16)&255) + ',' + (1-((rgba >> 24)&255)/255) + ')';
+ return 'rgb(' + (rgba&255) + ',' + ((rgba >> 8)&255) + ',' + ((rgba >> 16)&255) + ')';
+ },
+ loadColorToCSSRGBA: function(color) {
+ var rgba = {{{ makeGetValue('color', '0', 'i32') }}};
+ return 'rgba(' + (rgba&255) + ',' + ((rgba >> 8)&255) + ',' + ((rgba >> 16)&255) + ',' + (((rgba >> 24)&255)/255) + ')';
},
- translateColorToCSS: function(rgba) {
- return 'rgba(' + ((rgba >> 24)&255) + ',' + ((rgba >> 16)&255) + ',' + ((rgba >> 8)&255) + ',' + (1-(rgba&255)/255) + ')';
+ translateColorToCSSRGBA: function(rgba) {
+ return 'rgba(' + ((rgba >> 24)&255) + ',' + ((rgba >> 16)&255) + ',' + ((rgba >> 8)&255) + ',' + ((rgba&255)/255) + ')';
},
- translateRGBAToCSS: function(r, g, b, a) {
- return 'rgba(' + r + ',' + g + ',' + b + ',' + (1-a/255) + ')';
+ translateRGBAToCSSRGBA: function(r, g, b, a) {
+ return 'rgba(' + r + ',' + g + ',' + b + ',' + (a/255) + ')';
},
makeSurface: function(width, height, flags, usePageCanvas, source) {
@@ -273,6 +277,11 @@ mergeInto(LibraryManager.library, {
switch(event.type) {
case 'keydown': case 'keyup': case 'mousedown': case 'mouseup': case 'mousemove':
SDL.events.push(event);
+ if ((event.keyCode >= 37 && event.keyCode <= 40) || // arrow keys
+ event.keyCode == 32 || // space
+ event.keyCode == 33 || event.keyCode == 34) { // page up/down
+ event.preventDefault();
+ }
break;
}
//event.preventDefault();
@@ -342,7 +351,7 @@ mergeInto(LibraryManager.library, {
var tempCtx = SDL.surfaces[SDL.screen].ctx;
tempCtx.save();
tempCtx.font = fontString;
- var ret = tempCtx.measureText(text).width;
+ var ret = tempCtx.measureText(text).width | 0;
tempCtx.restore();
return ret;
},
@@ -408,6 +417,9 @@ mergeInto(LibraryManager.library, {
},
SDL_Quit: function() {
+ for (var i = 0; i < SDL.audios; i++) {
+ SDL.audios[i].pause();
+ }
Module.print('SDL_Quit called (and ignored)');
},
@@ -459,13 +471,14 @@ mergeInto(LibraryManager.library, {
assert(buffer % 4 == 0, 'Invalid buffer offset: ' + buffer);
var src = buffer >> 2;
var dst = 0;
+ var isScreen = surf == SDL.screen;
while (dst < num) {
// TODO: access underlying data buffer and write in 32-bit chunks or more
var val = HEAP32[src]; // This is optimized. Instead, we could do {{{ makeGetValue('buffer', 'dst', 'i32') }}};
- data[dst] = val & 0xff;
+ data[dst ] = val & 0xff;
data[dst+1] = (val >> 8) & 0xff;
data[dst+2] = (val >> 16) & 0xff;
- data[dst+3] = (val >> 24) & 0xff;
+ data[dst+3] = isScreen ? 0xff : ((val >> 24) & 0xff);
src++;
dst += 4;
}
@@ -582,14 +595,14 @@ mergeInto(LibraryManager.library, {
assert(!surfData.locked); // but we could unlock and re-lock if we must..
var r = SDL.loadRect(rect);
surfData.ctx.save();
- surfData.ctx.fillStyle = SDL.translateColorToCSS(color);
+ surfData.ctx.fillStyle = SDL.translateColorToCSSRGBA(color);
surfData.ctx.fillRect(r.x, r.y, r.w, r.h);
surfData.ctx.restore();
},
SDL_BlitSurface__deps: ['SDL_UpperBlit'],
SDL_BlitSurface: function(src, srcrect, dst, dstrect) {
- return _SDL_Blit(src, srcrect, dst, dstrect);
+ return _SDL_UpperBlit(src, srcrect, dst, dstrect);
},
SDL_SetAlpha: function(surf, flag, alpha) {
@@ -716,15 +729,14 @@ mergeInto(LibraryManager.library, {
SDL_CondWait: function() {},
SDL_DestroyCond: function() {},
-//SDL_CreateYUVOverlay
-//SDL_CreateThread, SDL_WaitThread etc
-
// SDL Mixer
- Mix_OpenAudio: function() { return 0 },
+ Mix_OpenAudio: function(frequency, format, channels, chunksize) {
+ return 0;
+ },
Mix_HookMusicFinished: function(func) {
- SDL.hookMusicFinished = func; // TODO: use this
+ SDL.hookMusicFinished = func;
},
Mix_VolumeMusic: function(func) {
@@ -733,46 +745,39 @@ mergeInto(LibraryManager.library, {
Mix_LoadWAV_RW: function(filename, freesrc) {
filename = FS.standardizePath(Pointer_stringify(filename));
+ var raw = preloadedAudios[filename];
+ assert(raw, 'Cannot find preloaded audio ' + filename);
var id = SDL.audios.length;
SDL.audios.push({
- audio: new Audio(filename)
+ source: filename,
+ audio: raw
});
return id;
},
- Mix_FreeChunk: function(audio) {
+ Mix_FreeChunk: function(id) {
SDL.audios[id].audio.pause();
SDL.audios[id] = null;
- return 0;
},
- Mix_PlayChannel: function(channel, audio, loops) {
+ Mix_PlayChannel: function(channel, id, loops) {
+ // TODO: handle loops
var audio = SDL.audios[id].audio;
+ if (audio.currentTime) audio.src = audio.src; // This hack prevents lags on replaying // TODO: parallel sounds through //cloneNode(true).play()
audio.play();
- return 0; // XXX should return channel
+ return 1; // XXX should return channel
},
Mix_PlayChannelTimed: 'Mix_PlayChannel', // XXX ignore Timing
- Mix_LoadMUS: function(filename) {
- filename = FS.standardizePath(Pointer_stringify(filename));
- var id = SDL.audios.length;
- SDL.audios.push({
- audio: new Audio(filename)
- });
- return id;
- },
-
- Mix_FreeMusic: function(id) {
- SDL.audios[id].audio.pause();
- SDL.audios[id] = null;
- return 0;
- },
+ Mix_LoadMUS: 'Mix_LoadWAV_RW',
+ Mix_FreeMusic: 'Mix_FreeChunk',
Mix_PlayMusic: function(id, loops) {
- if (loops == 0) return;
+ loops = Math.max(loops, 1);
var audio = SDL.audios[id].audio;
- audio.loop = loop != 1; // TODO: handle N loops for finite N
+ audio.loop = loops != 1; // TODO: handle N loops for finite N
audio.play();
+ SDL.music = audio;
return 0;
},
@@ -788,15 +793,21 @@ mergeInto(LibraryManager.library, {
return 0;
},
- Mix_HaltMusic: function(id) {
- var audio = SDL.audios[id].audio;
- audio.pause(); // TODO: actually rewind to the beginning
+ Mix_HaltMusic: function() {
+ var audio = SDL.music;
+ if (!audio) return 0;
+ audio.src = audio.src; // rewind
+ audio.pause();
+ SDL.music = null;
+ if (SDL.hookMusicFinished) {
+ FUNCTION_TABLE[SDL.hookMusicFinished]();
+ }
return 0;
},
Mix_FadeInMusicPos: 'Mix_PlayMusic', // XXX ignore fading in effect
- Mix_FadeOutMusic: function(id) {}, // TODO
+ Mix_FadeOutMusic: 'Mix_HaltMusic', // XXX ignore fading out effect
// SDL TTF
@@ -818,7 +829,7 @@ mergeInto(LibraryManager.library, {
var fontData = SDL.fonts[font];
var w = SDL.estimateTextWidth(fontData, text);
var h = fontData.size;
- var color = SDL.loadColorToCSS(color);
+ var color = SDL.loadColorToCSSRGB(color); // XXX alpha breaks fonts?
var fontString = h + 'px sans-serif';
var surf = SDL.makeSurface(w, h, 0, false, 'text:' + text); // bogus numbers..
var surfData = SDL.surfaces[surf];
@@ -861,7 +872,7 @@ mergeInto(LibraryManager.library, {
assert(!surfData.locked); // but we could unlock and re-lock if we must..
// TODO: if ctx does not change, leave as is, and also do not re-set xStyle etc.
surfData.ctx.save();
- surfData.ctx.fillStyle = SDL.translateRGBAToCSS(r, g, b, a);
+ surfData.ctx.fillStyle = SDL.translateRGBAToCSSRGBA(r, g, b, a);
surfData.ctx.fillRect(x1, y1, x2-x1, y2-y1);
surfData.ctx.restore();
},
@@ -870,7 +881,7 @@ mergeInto(LibraryManager.library, {
var surfData = SDL.surfaces[surf];
assert(!surfData.locked); // but we could unlock and re-lock if we must..
surfData.ctx.save();
- surfData.ctx.strokeStyle = SDL.translateRGBAToCSS(r, g, b, a);
+ surfData.ctx.strokeStyle = SDL.translateRGBAToCSSRGBA(r, g, b, a);
surfData.ctx.strokeRect(x1, y1, x2-x1, y2-y1);
surfData.ctx.restore();
},
@@ -879,7 +890,7 @@ mergeInto(LibraryManager.library, {
var surfData = SDL.surfaces[surf];
assert(!surfData.locked); // but we could unlock and re-lock if we must..
surfData.ctx.save();
- surfData.ctx.strokeStyle = SDL.translateRGBAToCSS(r, g, b, a);
+ surfData.ctx.strokeStyle = SDL.translateRGBAToCSSRGBA(r, g, b, a);
surfData.ctx.beginPath();
surfData.ctx.moveTo(x1, y1);
surfData.ctx.lineTo(x2, y2);
diff --git a/src/parseTools.js b/src/parseTools.js
index 520d278e..0e6ddee8 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -1537,7 +1537,8 @@ function makeRounding(value, bits, signed, floatConversion) {
// TODO: handle roundings of i64s
assert(bits);
// C rounds to 0 (-5.5 to -5, +5.5 to 5), while JS has no direct way to do that.
- if (bits <= 32 && signed) return '((' + value + ')|0)'; // This is fast and even correct, for all cases
+ if (bits <= 32 && signed) return '((' + value + ')&-1)'; // This is fast and even correct, for all cases. Note that it is the same
+ // as |0, but &-1 hints to the js optimizer that this is a rounding correction
// Do Math.floor, which is reasonably fast, if we either don't care, or if we can be sure
// the value is non-negative
if (!correctRoundings() || (!signed && !floatConversion)) return 'Math.floor(' + value + ')';
diff --git a/src/postamble.js b/src/postamble.js
index 62966d61..b14a31a1 100644
--- a/src/postamble.js
+++ b/src/postamble.js
@@ -32,6 +32,10 @@ Module.callMain = function callMain(args) {
function run(args) {
args = args || Module['arguments'];
+ if (Module['setStatus']) {
+ Module['setStatus'](''); // clear the status from "Downloading.." etc.
+ }
+
if (Module['preRun']) {
Module['preRun']();
}
diff --git a/src/preamble.js b/src/preamble.js
index 86a5ce80..c88a4671 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -850,9 +850,5 @@ function removeRunDependency() {
if (runDependencies == 0) run();
}
-// Preloading
-
-var preloadedImages = {}; // maps url to image data
-
// === Body ===
diff --git a/src/shell.html b/src/shell.html
index 79b7e9b9..436ba37e 100644
--- a/src/shell.html
+++ b/src/shell.html
@@ -4,34 +4,36 @@
<body>
<center>
<canvas id='canvas' width='256' height='256'></canvas>
+ <hr>
+ <textarea id="output" style="font-family: monospace; width: 80%" rows="8"></textarea>
+ <hr>
+ <div id='status'>Downloading...</div>
</center>
<hr>
- <div id='output'></div>
- <hr>
- <center><div id='status'></div></center>
- <hr>
<script type='text/javascript'>
// connect to canvas
var Module = {
print: (function() {
var element = document.getElementById('output');
- var printBuffer = [];
+ element.value = ''; // clear browser cache
return function(text) {
- text = text.replace(/&/g, "&amp;");
- text = text.replace(/</g, "&lt;");
- text = text.replace(/>/g, "&gt;");
- text = text.replace('\n', '<br>', 'g');
- if (printBuffer.length > 10) printBuffer.shift();
- printBuffer.push(text);
- element.innerHTML = printBuffer.join('<br>');
+ // These replacements are necessary if you render to raw HTML
+ //text = text.replace(/&/g, "&amp;");
+ //text = text.replace(/</g, "&lt;");
+ //text = text.replace(/>/g, "&gt;");
+ //text = text.replace('\n', '<br>', 'g');
+ element.value += text + "\n";
+ element.scrollTop = 99999; // focus on bottom
};
})(),
canvas: document.getElementById('canvas'),
+ setStatus: function(text) {
+ document.getElementById('status').innerHTML = text;
+ },
totalDependencies: 0,
monitorRunDependencies: function(left) {
this.totalDependencies = Math.max(this.totalDependencies, left);
- document.getElementById('status').innerHTML = left ? 'Downloading files: ' + (this.totalDependencies-left) + '/' + this.totalDependencies :
- 'All downloads complete.';
+ Module.setStatus(left ? 'Downloading: ' + (this.totalDependencies-left) + '/' + this.totalDependencies : 'All downloads complete.');
}
};