diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/library.js | 20 | ||||
-rw-r--r-- | src/library_gl.js | 7 | ||||
-rw-r--r-- | src/library_sdl.js | 101 | ||||
-rw-r--r-- | src/parseTools.js | 3 | ||||
-rw-r--r-- | src/postamble.js | 4 | ||||
-rw-r--r-- | src/preamble.js | 4 | ||||
-rw-r--r-- | src/shell.html | 30 |
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, "&"); - text = text.replace(/</g, "<"); - text = text.replace(/>/g, ">"); - 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, "&"); + //text = text.replace(/</g, "<"); + //text = text.replace(/>/g, ">"); + //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.'); } }; |