diff options
-rwxr-xr-x | emcc | 10 | ||||
-rw-r--r-- | src/compiler.js | 3 | ||||
-rw-r--r-- | src/library_sdl.js | 40 | ||||
-rw-r--r-- | src/preamble.js | 6 | ||||
-rw-r--r-- | src/shell.html | 32 | ||||
-rw-r--r-- | src/shell.js | 3 | ||||
-rw-r--r-- | tests/hello_world.js | 3 | ||||
-rw-r--r-- | tests/hello_world_sdl.cpp | 29 | ||||
-rw-r--r-- | tests/runner.py | 14 |
9 files changed, 113 insertions, 27 deletions
@@ -290,8 +290,14 @@ elif use_compiler: shared.Building.emscripten(target_basename + '.bc', append_ext=False) shutil.move(target_basename + '.bc.o.js', target_basename + '.js') - ## TODO: If we were asked to also generate HTML, do that - #if final_suffix == 'html': + # If we were asked to also generate HTML, do that + if final_suffix == 'html': + shell = open(shared.path_from_root('src', 'shell.html')).read() + html = open(target_basename + '.html', 'w') + html.write(shell.replace('{{{ SCRIPT_CODE }}}', open(target_basename + '.js').read())) + html.close() + temp_files.note(target_basename + '.js') + finally: temp_files.clean() diff --git a/src/compiler.js b/src/compiler.js index 94085c3f..2015a09d 100644 --- a/src/compiler.js +++ b/src/compiler.js @@ -54,6 +54,9 @@ if (ENVIRONMENT_IS_NODE) { printErr = function(x) { console.log(x); }; + if (typeof print === 'undefined') { + print = printErr; + } read = function(url) { var xhr = new XMLHttpRequest(); diff --git a/src/library_sdl.js b/src/library_sdl.js index 45b0bb53..806ed0ec 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -22,8 +22,12 @@ // noInitialRun: true // }; // -// which is defined BEFORE you load the compiled code. Here -// is a full example: +// which is defined BEFORE you load the compiled code. + +// The test_emcc test in the tests/runner.py will test this +// in its last phase, where it generates HTML. You can see +// a concrete example there. The HTML source is in src/shell.html. +// Here is a more comprehensive example: /* <html> @@ -141,19 +145,19 @@ mergeInto(LibraryManager.library, { }, makeSurface: function(width, height, flags) { - var surf = _malloc(14*QUANTUM_SIZE); // SDL_Surface has 14 fields of quantum size + var surf = _malloc(14*Runtime.QUANTUM_SIZE); // SDL_Surface has 14 fields of quantum size var buffer = _malloc(width*height*4); - var pixelFormat = _malloc(18*QUANTUM_SIZE); + var pixelFormat = _malloc(18*Runtime.QUANTUM_SIZE); flags |= 1; // SDL_HWSURFACE - this tells SDL_MUSTLOCK that this needs to be locked - {{{ makeSetValue('surf+QUANTUM_SIZE*0', '0', 'flags', 'i32') }}} // SDL_Surface.flags - {{{ makeSetValue('surf+QUANTUM_SIZE*1', '0', 'pixelFormat', 'void*') }}} // SDL_Surface.format TODO - {{{ makeSetValue('surf+QUANTUM_SIZE*2', '0', 'width', 'i32') }}} // SDL_Surface.w - {{{ makeSetValue('surf+QUANTUM_SIZE*3', '0', 'height', 'i32') }}} // SDL_Surface.h - {{{ makeSetValue('surf+QUANTUM_SIZE*4', '0', 'width*4', 'i16') }}} // SDL_Surface.pitch, assuming RGBA for now, + {{{ makeSetValue('surf+Runtime.QUANTUM_SIZE*0', '0', 'flags', 'i32') }}} // SDL_Surface.flags + {{{ makeSetValue('surf+Runtime.QUANTUM_SIZE*1', '0', 'pixelFormat', 'void*') }}} // SDL_Surface.format TODO + {{{ makeSetValue('surf+Runtime.QUANTUM_SIZE*2', '0', 'width', 'i32') }}} // SDL_Surface.w + {{{ makeSetValue('surf+Runtime.QUANTUM_SIZE*3', '0', 'height', 'i32') }}} // SDL_Surface.h + {{{ makeSetValue('surf+Runtime.QUANTUM_SIZE*4', '0', 'width*4', 'i16') }}} // SDL_Surface.pitch, assuming RGBA for now, // since that is what ImageData gives us in browsers - {{{ makeSetValue('surf+QUANTUM_SIZE*5', '0', 'buffer', 'void*') }}} // SDL_Surface.pixels - {{{ makeSetValue('surf+QUANTUM_SIZE*6', '0', '0', 'i32*') }}} // SDL_Surface.offset + {{{ makeSetValue('surf+Runtime.QUANTUM_SIZE*5', '0', 'buffer', 'void*') }}} // SDL_Surface.pixels + {{{ makeSetValue('surf+Runtime.QUANTUM_SIZE*6', '0', '0', 'i32*') }}} // SDL_Surface.offset {{{ makeSetValue('pixelFormat + SDL.structs.PixelFormat.palette', '0', '0', 'i32') }}} // TODO {{{ makeSetValue('pixelFormat + SDL.structs.PixelFormat.BitsPerPixel', '0', '32', 'i8') }}} // TODO @@ -239,12 +243,12 @@ mergeInto(LibraryManager.library, { SDL_GetVideoInfo: function() { // %struct.SDL_VideoInfo = type { i32, i32, %struct.SDL_PixelFormat*, i32, i32 } - 5 fields of quantum size - var ret = _malloc(5*QUANTUM_SIZE); - {{{ makeSetValue('ret+QUANTUM_SIZE*0', '0', '0', 'i32') }}} // TODO - {{{ makeSetValue('ret+QUANTUM_SIZE*1', '0', '0', 'i32') }}} // TODO - {{{ makeSetValue('ret+QUANTUM_SIZE*2', '0', '0', 'void*') }}} - {{{ makeSetValue('ret+QUANTUM_SIZE*3', '0', 'SDL.defaults.width', 'i32') }}} - {{{ makeSetValue('ret+QUANTUM_SIZE*4', '0', 'SDL.defaults.height', 'i32') }}} + var ret = _malloc(5*Runtime.QUANTUM_SIZE); + {{{ makeSetValue('ret+Runtime.QUANTUM_SIZE*0', '0', '0', 'i32') }}} // TODO + {{{ makeSetValue('ret+Runtime.QUANTUM_SIZE*1', '0', '0', 'i32') }}} // TODO + {{{ makeSetValue('ret+Runtime.QUANTUM_SIZE*2', '0', '0', 'void*') }}} + {{{ makeSetValue('ret+Runtime.QUANTUM_SIZE*3', '0', 'SDL.defaults.width', 'i32') }}} + {{{ makeSetValue('ret+Runtime.QUANTUM_SIZE*4', '0', 'SDL.defaults.height', 'i32') }}} return ret; }, @@ -298,7 +302,7 @@ mergeInto(LibraryManager.library, { // SDL_Surface has the following fields: Uint32 flags, SDL_PixelFormat *format; int w, h; Uint16 pitch; void *pixels; ... // So we have fields all of the same size, and 5 of them before us. // TODO: Use macros like in library.js - {{{ makeSetValue('surf', '5*QUANTUM_SIZE', 'surfData.buffer', 'void*') }}}; + {{{ makeSetValue('surf', '5*Runtime.QUANTUM_SIZE', 'surfData.buffer', 'void*') }}}; }, SDL_UnlockSurface: function(surf) { diff --git a/src/preamble.js b/src/preamble.js index 1e9e1f11..cd9138d4 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -690,12 +690,6 @@ Module['String_copy'] = String_copy; // Tools -if (typeof console === 'object' && typeof console.log === 'function') { - this['print'] = function(x) { console.log(x) }; // web console -} else if (typeof print === 'undefined') { - this['print'] = function(){}; // harmless no-op -} - // This processes a JS string into a C-line array of numbers, 0-terminated. // For LLVM-originating strings, see parser.js:parseLLVMString function function intArrayFromString(stringy, dontAddNull) { diff --git a/src/shell.html b/src/shell.html new file mode 100644 index 00000000..284bc8d6 --- /dev/null +++ b/src/shell.html @@ -0,0 +1,32 @@ +<html> + <head> + <title>Emscripten-Generated Code</title> + <body> + <center> + <canvas id='canvas' width='256' height='256'></canvas> + </center> + <hr> + <div id='output'></div> + <hr> + <script type='text/javascript'> + // implement print + var print = (function() { + var element = document.getElementById('output'); + return function(text) { + element.innerHTML += text.replace('\n', '<br>', 'g') + '<br>'; + }; + })(); + + // connect to canvas + var Module = { + canvas: document.getElementById('canvas'), + ctx2D: document.getElementById('canvas').getContext('2d') + }; + if (!Module.ctx2D) alert('Canvas not available :('); + + // The compiled code + {{{ SCRIPT_CODE }}} + </script> + </body> +</html> + diff --git a/src/shell.js b/src/shell.js index d52cd77d..038fde02 100644 --- a/src/shell.js +++ b/src/shell.js @@ -46,6 +46,9 @@ if (ENVIRONMENT_IS_NODE) { printErr = function(x) { console.log(x); }; + if (typeof print === 'undefined') { + print = printErr; + } read = function(url) { var xhr = new XMLHttpRequest(); diff --git a/tests/hello_world.js b/tests/hello_world.js index 3fd19d53..530f5d4c 100644 --- a/tests/hello_world.js +++ b/tests/hello_world.js @@ -43,6 +43,9 @@ if (ENVIRONMENT_IS_NODE) { printErr = function(x) { console.log(x); }; + if (typeof print === 'undefined') { + print = printErr; + } read = function(url) { var xhr = new XMLHttpRequest(); diff --git a/tests/hello_world_sdl.cpp b/tests/hello_world_sdl.cpp new file mode 100644 index 00000000..a317c0c5 --- /dev/null +++ b/tests/hello_world_sdl.cpp @@ -0,0 +1,29 @@ +#include <stdio.h> +#include <SDL/SDL.h> + + +int main() { + printf("hello, world!\n"); + + SDL_Init(SDL_INIT_VIDEO); + SDL_Surface *screen = SDL_SetVideoMode(256, 256, 32, SDL_SWSURFACE); + + SDL_LockSurface(screen); + for (int i = 0; i < 256; i++) { + for (int j = 0; j < 256; j++) { + *((char*)screen->pixels + i*256*4 + j*4 + 0) = i; + *((char*)screen->pixels + i*256*4 + j*4 + 1) = j; + *((char*)screen->pixels + i*256*4 + j*4 + 2) = 255-i; + *((char*)screen->pixels + i*256*4 + j*4 + 3) = 255; + } + } + SDL_UnlockSurface(screen); + SDL_Flip(screen); + + printf("you should see a colored cube."); + + // SDL_Quit(); // Don't call SDL_Quit so that the canvas is not cleared + + return 0; +} + diff --git a/tests/runner.py b/tests/runner.py index e8564585..ef99a7b1 100644 --- a/tests/runner.py +++ b/tests/runner.py @@ -12,7 +12,7 @@ will use 4 processes. To install nose do something like ''' from subprocess import Popen, PIPE, STDOUT -import os, unittest, tempfile, shutil, time, inspect, sys, math, glob, tempfile, re, difflib +import os, unittest, tempfile, shutil, time, inspect, sys, math, glob, tempfile, re, difflib, webbrowser # Setup @@ -4963,6 +4963,18 @@ JavaScript in the final linking stage of building. # TODO: when ready, switch tools/shared building to use emcc over emmaken # TODO: add shebang to generated .js files, using JS_ENGINES[0]? #!/usr/bin/python etc + # Finally, test HTML generation. (Coincidentally we also test that compiling a .cpp works in EMCC here.) + clear() + output = Popen([EMCC, path_from_root('tests', 'hello_world_sdl.cpp'), '-o', 'something.html'], stdout=PIPE, stderr=PIPE).communicate(input) + assert len(output[0]) == 0, output[0] + assert os.path.exists('something.html'), output + webbrowser.open_new(os.path.join(self.get_dir(), 'something.html')) + print 'A web browser window should have opened a page containing the results of a part of this test.' + print 'You need to manually look at the page to see that it works ok: You should see "hello, world!" and a colored cube.' + print '(sleeping for a bit to keep the directory alive for the web browser..)' + time.sleep(5) + print '(moving on..)' + def test_eliminator(self): input = open(path_from_root('tools', 'eliminator', 'eliminator-test.js')).read() expected = open(path_from_root('tools', 'eliminator', 'eliminator-test-output.js')).read() |