diff options
188 files changed, 25753 insertions, 1451 deletions
@@ -20,4 +20,10 @@ under the licensing terms detailed in LICENSE. * David Benjamin <davidben@mit.edu> * Pierre Renaux <pierre@talansoft.com> * Brian Anderson <banderson@mozilla.com> +* Jon Bardin <diclophis@gmail.com> +* Jukka Jylänki <jujjyl@gmail.com> +* Aleksander Guryanov <caiiiycuk@gmail.com> +* Chad Austin <chad@chadaustin.me> +* nandhp <nandhp@gmail.com> * YeZhongWen <linghuye2.0@gmail.com> + diff --git a/em-config b/em-config new file mode 100755 index 00000000..dee399ed --- /dev/null +++ b/em-config @@ -0,0 +1,24 @@ +#!/usr/bin/env python + +''' +This is a helper tool which is designed to make it possible +for other apps to read emscripten's configuration variables +in a unified way. Usage: + + em-config VAR_NAME + +This tool prints the value of the variable to stdout if one +is found, or exits with 1 if the variable does not exist. +''' + +import os, sys, re +from tools import shared + +if len(sys.argv) != 2 or \ + not re.match(r"^[\w\W_][\w\W_\d]*$", sys.argv[1]) or \ + not (sys.argv[1] in dir(shared)): + print 'Usage: em-config VAR_NAME' + exit(1) + +print eval('shared.' + sys.argv[1]) + @@ -77,15 +77,7 @@ emcc can be influenced by a few environment variables: import os, sys, shutil, tempfile, subprocess, shlex from subprocess import PIPE, STDOUT from tools import shared - -def execute(cmd, *args, **kw): - try: - return subprocess.Popen(cmd, *args, **kw).communicate() # let compiler frontend print directly, so colors are saved (PIPE kills that) - except: - if not isinstance(cmd, str): - cmd = ' '.join(cmd) - print >> sys.stderr, 'Invoking Process failed: <<< ' + cmd + ' >>>' - raise +from tools.shared import Compression, execute, suffix, unsuffixed, unsuffixed_basename # Mapping of emcc opt levels to llvm opt levels. We use llvm opt level 3 in emcc opt # levels 2 and 3 (emcc 3 is unsafe opts, so unsuitable for the only level to get @@ -128,7 +120,7 @@ if len(sys.argv) == 1: if sys.argv[1] == '--version': print '''emcc (Emscripten GCC-like replacement) 2.0 -Copyright (C) 2011 the Emscripten authors. +Copyright (C) 2012 the Emscripten authors. This is free and open source software under the MIT license. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ''' @@ -220,9 +212,14 @@ Options that are modified or new in %s include: compiled code asynchronously. Otherwise similar to --embed-file, except that this option is only relevant when generating - HTML (it uses asynchronous binary XHRs). + HTML (it uses asynchronous binary XHRs), + or JS that will be used in a web page. If a directory is passed here, its entire contents will be preloaded. + Preloaded files are stored in filename.data, + where filename.html is the main file you + are compiling to. To run your code, you + will need both the .html and the .data. --compression <codec> Compress both the compiled code and embedded/ preloaded files. <codec> should be a triple, @@ -269,6 +266,18 @@ Options that are modified or new in %s include: target other than HTML is specified using the -o option. + --js-library <lib> A JavaScript library to use in addition to + those in Emscripten's src/library_* + + -v Turns on verbose output. This will pass + -v to Clang, and also enable EMCC_DEBUG + to details emcc's operations + + --remove-duplicates If set, will remove duplicate symbols when + linking. This can be useful because + llvm-link's behavior is not as permissive + as ld is. + The target file, if specified (-o <target>), defines what will be generated: @@ -290,6 +299,9 @@ the source of emcc (search for 'os.environ'). ''' % (this, this, this) exit(0) +elif len(sys.argv) == 2 and sys.argv[1] == '-v': # -v with no inputs + print 'emcc (Emscripten GCC-like replacement) 2.0' + exit(subprocess.call([shared.CLANG, '-v'])) # If this is a configure-type thing, do not compile to JavaScript, instead use clang # to compile to a native binary (using our headers, so things make sense later) @@ -322,31 +334,17 @@ if EMMAKEN_CFLAGS: CC_ADDITIONAL_ARGS += shlex.split(EMMAKEN_CFLAGS) # ---------------- Utilities --------------- SOURCE_SUFFIXES = ('.c', '.cpp', '.cxx', '.cc') -BITCODE_SUFFIXES = ('.bc', '.o') +BITCODE_SUFFIXES = ('.bc', '.o', '.obj') DYNAMICLIB_SUFFIXES = ('.dylib', '.so', '.dll') STATICLIB_SUFFIXES = ('.a',) ASSEMBLY_SUFFIXES = ('.ll',) LIB_PREFIXES = ('', 'lib') -IMAGE_SUFFIXES = ('.jpg', '.png', '.bmp') -AUDIO_SUFFIXES = ('.ogg', '.wav', '.mp3') -AUDIO_MIMETYPES = { 'ogg': 'audio/ogg', 'wav': 'audio/wav', 'mp3': 'audio/mpeg' } - -def suffix(name): - return name.split('.')[-1] - -def unsuffixed(name): - return '.'.join(name.split('.')[:-1]) - -def unsuffixed_basename(name): - return os.path.basename(unsuffixed(name)) - seen_names = {} -def unsuffixed_uniquename(name): - ret = unsuffixed_basename(name) +def uniquename(name): if name not in seen_names: seen_names[name] = str(len(seen_names)) - return ret + '_' + seen_names[name] + return unsuffixed(name) + '_' + seen_names[name] + (('.' + suffix(name)) if suffix(name) else '') # ---------------- End configs ------------- @@ -401,22 +399,7 @@ else: temp_dir = tempfile.mkdtemp() def in_temp(name): - return os.path.join(temp_dir, name) - -class Compression: - on = False - - @staticmethod - def compressed_name(filename): - return filename + '.compress' - - @staticmethod - def compress(filename): - execute(Compression.encoder, stdin=open(filename, 'rb'), stdout=open(Compression.compressed_name(filename), 'wb')) - - @staticmethod - def worth_it(original, compressed): - return compressed < original - 1500 # save at least one TCP packet or so + return os.path.join(temp_dir, os.path.basename(name)) try: call = CXX if use_cxx else CC @@ -430,13 +413,16 @@ try: llvm_lto = None closure = None js_transform = None - pre_js = None - post_js = None + pre_js = '' + post_js = '' minify_whitespace = None - data_files = [] + preload_files = [] + embed_files = [] compression = None ignore_dynamic_linking = False shell_path = shared.path_from_root('src', 'shell.html') + js_libraries = [] + remove_duplicates = False def check_bad_eq(arg): assert '=' not in arg, 'Invalid parameter (do not use "=" with "--" options)' @@ -471,12 +457,12 @@ try: newargs[i+1] = '' elif newargs[i].startswith('--pre-js'): check_bad_eq(newargs[i]) - pre_js = open(newargs[i+1]).read() + pre_js += open(newargs[i+1]).read() + '\n' newargs[i] = '' newargs[i+1] = '' elif newargs[i].startswith('--post-js'): check_bad_eq(newargs[i]) - post_js = open(newargs[i+1]).read() + post_js += open(newargs[i+1]).read() + '\n' newargs[i] = '' newargs[i+1] = '' elif newargs[i].startswith('--minify'): @@ -486,12 +472,12 @@ try: newargs[i+1] = '' elif newargs[i].startswith('--embed-file'): check_bad_eq(newargs[i]) - data_files.append({ 'name': newargs[i+1], 'mode': 'embed' }) + embed_files.append(newargs[i+1]) newargs[i] = '' newargs[i+1] = '' elif newargs[i].startswith('--preload-file'): check_bad_eq(newargs[i]) - data_files.append({ 'name': newargs[i+1], 'mode': 'preload' }) + preload_files.append(newargs[i+1]) newargs[i] = '' newargs[i+1] = '' elif newargs[i].startswith('--compression'): @@ -509,11 +495,23 @@ try: elif newargs[i] == '--ignore-dynamic-linking': ignore_dynamic_linking = True newargs[i] = '' + elif newargs[i] == '-v': + shared.COMPILER_OPTS += ['-v'] + DEBUG = 1 + newargs[i] = '' elif newargs[i].startswith('--shell-file'): check_bad_eq(newargs[i]) shell_path = newargs[i+1] newargs[i] = '' newargs[i+1] = '' + elif newargs[i].startswith('--js-library'): + check_bad_eq(newargs[i]) + js_libraries.append(newargs[i+1]) + newargs[i] = '' + newargs[i+1] = '' + elif newargs[i] == '--remove-duplicates': + remove_duplicates = True + newargs[i] = '' newargs = [ arg for arg in newargs if arg is not '' ] if llvm_opts is None: llvm_opts = LLVM_OPT_LEVEL[opt_level] @@ -528,9 +526,11 @@ try: settings_changes = [] for i in range(len(newargs)): if newargs[i] == '-s': - assert '=' in newargs[i+1], 'Incorrect syntax for -s (use -s OPT=VAL): ' + newargs[i+1] - settings_changes.append(newargs[i+1]) - newargs[i] = newargs[i+1] = '' + if i+1 < len(newargs) and '=' in newargs[i+1]: # -s OPT=VALUE is for us, -s by itself is a linker option + settings_changes.append(newargs[i+1]) + newargs[i] = newargs[i+1] = '' + else: + print >> sys.stderr, 'emcc: warning: treating -s as linker option and not as -s OPT=VALUE for js compilation' elif newargs[i].startswith('--typed-arrays'): assert '=' not in newargs[i], 'Invalid typed arrays parameter (do not use "=")' settings_changes.append('USE_TYPED_ARRAYS=' + newargs[i+1]) @@ -583,6 +583,8 @@ try: libs.append(arg[2:]) newargs[i] = '' + original_input_files = input_files[:] + newargs = [ arg for arg in newargs if arg is not '' ] # Find library files @@ -648,7 +650,7 @@ try: for input_file in input_files: if input_file.endswith(SOURCE_SUFFIXES): if DEBUG: print >> sys.stderr, 'emcc: compiling source file: ', input_file - output_file = in_temp(unsuffixed_uniquename(input_file) + '.o') + output_file = in_temp(unsuffixed(uniquename(input_file)) + '.o') temp_files.append(output_file) args = newargs + ['-emit-llvm', '-c', input_file, '-o', output_file] if DEBUG: print >> sys.stderr, "emcc running:", call, ' '.join(args) @@ -659,12 +661,12 @@ try: else: # bitcode if input_file.endswith(BITCODE_SUFFIXES): if DEBUG: print >> sys.stderr, 'emcc: copying bitcode file: ', input_file - temp_file = in_temp(unsuffixed_uniquename(input_file) + '.o') + temp_file = in_temp(unsuffixed(uniquename(input_file)) + '.o') shutil.copyfile(input_file, temp_file) temp_files.append(temp_file) elif input_file.endswith(DYNAMICLIB_SUFFIXES) or shared.Building.is_ar(input_file): if DEBUG: print >> sys.stderr, 'emcc: copying library file: ', input_file - temp_file = in_temp(os.path.basename(input_file)) + temp_file = in_temp(uniquename(input_file)) shutil.copyfile(input_file, temp_file) temp_files.append(temp_file) else: #.ll @@ -672,7 +674,7 @@ try: # Note that by assembling the .ll file, then disassembling it later, we will # remove annotations which is a good thing for compilation time if DEBUG: print >> sys.stderr, 'emcc: assembling assembly file: ', input_file - temp_file = in_temp(unsuffixed_uniquename(input_file) + '.o') + temp_file = in_temp(unsuffixed(uniquename(input_file)) + '.o') shared.Building.llvm_as(input_file, temp_file) temp_files.append(temp_file) @@ -684,18 +686,16 @@ try: print >> sys.stderr, 'emcc: warning: -Ox flags ignored, since not generating JavaScript' if not specified_target: for input_file in input_files: - shutil.move(in_temp(unsuffixed_uniquename(input_file) + '.o'), unsuffixed_basename(input_file) + '.' + final_suffix) + shutil.move(in_temp(unsuffixed(uniquename(input_file)) + '.o'), unsuffixed_basename(input_file) + '.' + final_suffix) else: if len(input_files) == 1: - shutil.move(in_temp(unsuffixed_uniquename(input_files[0]) + '.o'), specified_target) + shutil.move(in_temp(unsuffixed(uniquename(input_files[0])) + '.o'), specified_target) else: - assert not has_dash_c, 'fatal error: cannot specify -o with -c with multiple files' + str(sys.argv) + assert len(original_input_files) == 1 or not has_dash_c, 'fatal error: cannot specify -o with -c with multiple files' + str(sys.argv) + ':' + str(original_input_files) # We have a specified target (-o <target>), which is not JavaScript or HTML, and - # we have multiple files: Link them TODO: llvm link-time opts? - ld_args = temp_files + ['-b', specified_target] - #[arg.split('-Wl,')[1] for arg in filter(lambda arg: arg.startswith('-Wl,'), sys.argv)] - if DEBUG: print >> sys.stderr, 'emcc: link: ' + str(ld_args) - execute([shared.LLVM_LD, '-disable-opt'] + ld_args) + # we have multiple files: Link them + if DEBUG: print >> sys.stderr, 'emcc: link: ' + str(temp_files) + shared.Building.link(temp_files, specified_target, remove_duplicates=remove_duplicates) exit(0) ## Continue on to create JavaScript @@ -713,9 +713,9 @@ try: # dlmalloc def create_dlmalloc(): if DEBUG: print >> sys.stderr, 'emcc: building dlmalloc for cache' - execute(['python', shared.EMCC, shared.path_from_root('system', 'lib', 'dlmalloc.c'), '-g', '-o', in_temp('dlmalloc.o')], stdout=stdout, stderr=stderr) + execute(shared.ENV_PREFIX + ['python', shared.EMCC, shared.path_from_root('system', 'lib', 'dlmalloc.c'), '-g', '-o', in_temp('dlmalloc.o')], stdout=stdout, stderr=stderr) # we include the libc++ new stuff here, so that the common case of using just new/delete is quick to link - execute(['python', shared.EMXX, shared.path_from_root('system', 'lib', 'libcxx', 'new.cpp'), '-g', '-o', in_temp('new.o')], stdout=stdout, stderr=stderr) + execute(shared.ENV_PREFIX + ['python', shared.EMXX, shared.path_from_root('system', 'lib', 'libcxx', 'new.cpp'), '-g', '-o', in_temp('new.o')], stdout=stdout, stderr=stderr) shared.Building.link([in_temp('dlmalloc.o'), in_temp('new.o')], in_temp('dlmalloc_full.o')) return in_temp('dlmalloc_full.o') def fix_dlmalloc(): @@ -741,7 +741,7 @@ try: assert shared.Settings.QUANTUM_SIZE == 4, 'We do not support libc++ with QUANTUM_SIZE == 1' # libcxx might need corrections, so turn them all on. TODO: check which are actually needed shared.Settings.CORRECT_SIGNS = shared.Settings.CORRECT_OVERFLOWS = shared.Settings.CORRECT_ROUNDINGS = 1 - print >> sys.stderr, 'emcc: warning: using libcxx turns on CORRECT_* options' + #print >> sys.stderr, 'emcc: info: using libcxx turns on CORRECT_* options' libcxx_symbols = map(lambda line: line.strip().split(' ')[1], open(shared.path_from_root('system', 'lib', 'libcxx', 'symbols')).readlines()) libcxx_symbols = filter(lambda symbol: symbol not in dlmalloc_symbols, libcxx_symbols) libcxx_symbols = set(libcxx_symbols) @@ -753,7 +753,7 @@ try: return os.path.join(shared.EMSCRIPTEN_TEMP_DIR, 'libcxxabi', 'libcxxabi.bc') def fix_libcxxabi(): assert shared.Settings.QUANTUM_SIZE == 4, 'We do not support libc++abi with QUANTUM_SIZE == 1' - print >> sys.stderr, 'emcc: warning: using libcxxabi, this may need CORRECT_* options' + #print >> sys.stderr, 'emcc: info: using libcxxabi, this may need CORRECT_* options' #shared.Settings.CORRECT_SIGNS = shared.Settings.CORRECT_OVERFLOWS = shared.Settings.CORRECT_ROUNDINGS = 1 libcxxabi_symbols = map(lambda line: line.strip().split(' ')[1], open(shared.path_from_root('system', 'lib', 'libcxxabi', 'symbols')).readlines()) libcxxabi_symbols = filter(lambda symbol: symbol not in dlmalloc_symbols, libcxxabi_symbols) @@ -787,8 +787,7 @@ try: (not LEAVE_INPUTS_RAW and not (suffix(temp_files[0]) in BITCODE_SUFFIXES or suffix(temp_files[0]) in DYNAMICLIB_SUFFIXES) and shared.Building.is_ar(temp_files[0])): linker_inputs = temp_files + extra_files_to_link if DEBUG: print >> sys.stderr, 'emcc: linking: ', linker_inputs - shared.Building.link(linker_inputs, - in_temp(target_basename + '.bc')) + shared.Building.link(linker_inputs, in_temp(target_basename + '.bc'), remove_duplicates=remove_duplicates) final = in_temp(target_basename + '.bc') else: if not LEAVE_INPUTS_RAW: @@ -837,215 +836,29 @@ try: if AUTODEBUG: if DEBUG: print >> sys.stderr, 'emcc: autodebug' - execute(['python', shared.AUTODEBUGGER, final, final + '.ad.ll']) + execute(shared.ENV_PREFIX + ['python', shared.AUTODEBUGGER, final, final + '.ad.ll']) final += '.ad.ll' if DEBUG: save_intermediate('autodebug', 'll') # Emscripten if DEBUG: print >> sys.stderr, 'emcc: LLVM => JS' - final = shared.Building.emscripten(final, append_ext=False) + extra_args = [] if not js_libraries else ['--libraries', ','.join(map(os.path.abspath, js_libraries))] + final = shared.Building.emscripten(final, append_ext=False, extra_args=extra_args) if DEBUG: save_intermediate('original') # Embed and preload files - if len(data_files) > 0: + if len(preload_files) + len(embed_files) > 0: if DEBUG: print >> sys.stderr, 'emcc: setting up files' - code = '' - - if final_suffix == 'html': - code += ''' - var BlobBuilder = typeof MozBlobBuilder != "undefined" ? MozBlobBuilder : (typeof WebKitBlobBuilder != "undefined" ? WebKitBlobBuilder : console.log("warning: cannot build blobs")); - var URLObject = typeof window != "undefined" ? (window.URL ? window.URL : window.webkitURL) : console.log("warning: cannot create object URLs"); - var hasBlobConstructor; - try { - new Blob(); - hasBlobConstructor = true; - } catch(e) { - hasBlobConstructor = false; - console.log("warning: no blob constructor, cannot create blobs with mimetypes"); - } -''' - - code += 'var preloadedImages = {}; // maps url to image data\n' - code += 'var preloadedAudios = {}; // maps url to audio data\n' - - # Expand directories into individual files - def add(mode, dirname, names): - for name in names: - fullname = os.path.join(dirname, name) - if not os.path.isdir(fullname): - data_files.append({ 'name': fullname, 'mode': mode }) - - for file_ in data_files: - if os.path.isdir(file_['name']): - os.path.walk(file_['name'], add, file_['mode']) - data_files = filter(lambda file_: not os.path.isdir(file_['name']), data_files) - - for file_ in data_files: - file_['net_name'] = file_['name'] - - data_target = unsuffixed(target) + '.data' - - # Set up folders - partial_dirs = [] - for file_ in data_files: - dirname = os.path.dirname(file_['name']) - if dirname != '' and dirname != os.path.sep: - parts = dirname.split(os.path.sep) - for i in range(len(parts)): - partial = os.path.sep.join(parts[:i+1]) - if partial not in partial_dirs: - code += '''FS.createFolder('/%s', '%s', true, false);\n''' % (os.path.sep.join(parts[:i]), parts[i]) - partial_dirs.append(partial) - - if final_suffix == 'html': - # Bundle all datafiles into one archive. Avoids doing lots of simultaneous XHRs which has overhead. - data = open(data_target, 'wb') - start = 0 - for file_ in data_files: - file_['data_start'] = start - curr = open(file_['name']).read() - file_['data_end'] = start + len(curr) - start += len(curr) - data.write(curr) - data.close() - if Compression.on: - Compression.compress(data_target) - - # Data requests - for getting a block of data out of the big archive - have a similar API to XHRs - code += ''' - function DataRequest() {} - DataRequest.prototype = { - requests: {}, - open: function(mode, name) { - this.requests[name] = this; - }, - send: function() {} - }; - ''' - - counter = 0 - for file_ in data_files: - filename = file_['name'] - if file_['mode'] == 'embed': - # Embed - code += '''FS.createDataFile('/', '%s', %s, true, true);\n''' % (os.path.basename(filename), str(map(ord, open(filename, 'rb').read()))) - elif file_['mode'] == 'preload': - # Preload - assert final_suffix == 'html', 'Can only preload files when generating HTML' - - varname = 'filePreload%d' % counter - counter += 1 - image = filename.endswith(IMAGE_SUFFIXES) - audio = filename.endswith(AUDIO_SUFFIXES) - - if image: - finish = ''' - var bb = new BlobBuilder(); - bb.append(byteArray.buffer); - var b = bb.getBlob(); - var url = URLObject.createObjectURL(b); - var img = new Image(); - img.onload = function() { - assert(img.complete, 'Image %(filename)s could not be decoded'); - var canvas = document.createElement('canvas'); - canvas.width = img.width; - canvas.height = img.height; - var ctx = canvas.getContext('2d'); - ctx.drawImage(img, 0, 0); - preloadedImages['%(filename)s'] = canvas; - URLObject.revokeObjectURL(url); - removeRunDependency(); - }; - img.onerror = function(event) { - console.log('Image %(filename)s could not be decoded'); - }; - img.src = url; -''' % { 'filename': filename } - elif audio: - # Need actual blob constructor here, to set the mimetype or else audios fail to decode - finish = ''' - if (hasBlobConstructor) { - var b = new Blob([byteArray.buffer], { type: '%(mimetype)s' }); - var url = URLObject.createObjectURL(b); // XXX we never revoke this! - var audio = new Audio(); - audio['oncanplaythrough'] = function() { // XXX string for closure - audio['oncanplaythrough'] = null; - preloadedAudios['%(filename)s'] = audio; - removeRunDependency(); - }; - audio.onerror = function(event) { - console.log('Audio %(filename)s could not be decoded'); - }; - audio.src = url; - } else { - preloadedAudios['%(filename)s'] = new Audio(); // empty shim - removeRunDependency(); - } -''' % { 'filename': filename, 'mimetype': AUDIO_MIMETYPES[suffix(filename)] } - else: - finish = 'removeRunDependency();\n' - - code += ''' - var %(varname)s = new %(request)s(); - %(varname)s.open('GET', '%(netname)s', true); - %(varname)s.responseType = 'arraybuffer'; - %(varname)s.onload = function() { - var arrayBuffer = %(varname)s.response; - assert(arrayBuffer, 'Loading file %(filename)s failed.'); - var byteArray = arrayBuffer.byteLength ? new Uint8Array(arrayBuffer) : arrayBuffer; - FS.createDataFile('/%(dirname)s', '%(basename)s', byteArray, true, true); - %(finish)s - }; - addRunDependency(); - %(varname)s.send(null); -''' % { - 'request': 'DataRequest', # In the past we also supported XHRs here - 'varname': varname, - 'filename': filename, - 'netname': file_['net_name'], - 'dirname': os.path.dirname(filename), - 'basename': os.path.basename(filename), - 'finish': finish - } - else: - assert 0 - - if final_suffix == 'html': - # Get the big archive and split it up - use_data = '' - for file_ in data_files: - if file_['mode'] == 'preload': - use_data += ''' - curr = DataRequest.prototype.requests['%s']; - curr.response = byteArray.subarray(%d,%d); - curr.onload(); - ''' % (file_['name'], file_['data_start'], file_['data_end']) - use_data += ' removeRunDependency();\n' - - if Compression.on: - use_data = ''' - Module["decompress"](byteArray, function(decompressed) { - byteArray = new Uint8Array(decompressed); - %s - }); - ''' % use_data - - code += ''' - var dataFile = new XMLHttpRequest(); - dataFile.open('GET', '%s', true); - dataFile.responseType = 'arraybuffer'; - dataFile.onload = function() { - var arrayBuffer = dataFile.response; - assert(arrayBuffer, 'Loading data file failed.'); - var byteArray = new Uint8Array(arrayBuffer); - var curr; - %s - }; - addRunDependency(); - dataFile.send(null); - if (Module['setStatus']) Module['setStatus']('Downloading...'); - ''' % (Compression.compressed_name(data_target) if Compression.on else data_target, use_data) - + file_args = [] + if len(preload_files) > 0: + file_args.append('--preload') + file_args += preload_files + if len(embed_files) > 0: + file_args.append('--embed') + file_args += embed_files + if Compression.on: + file_args += ['--compress', Compression.encoder, Compression.decoder, Compression.js_name] + code = execute(shared.ENV_PREFIX + ['python', shared.FILE_PACKAGER, unsuffixed(target) + '.data'] + file_args, stdout=PIPE)[0] src = open(final).read().replace('// {{PRE_RUN_ADDITIONS}}', code) final += '.files.js' open(final, 'w').write(src) @@ -1056,7 +869,7 @@ try: if DEBUG: print >> sys.stderr, 'emcc: applying pre/postjses' src = open(final).read() final += '.pp.js' - open(final, 'w').write((pre_js or '') + src + (post_js or '')) + open(final, 'w').write(pre_js + src + post_js) if DEBUG: save_intermediate('pre-post') # Apply a source code transformation, if requested @@ -1095,18 +908,16 @@ try: flush_js_optimizer_queue() - # eliminator if DEBUG: print >> sys.stderr, 'emcc: running variable eliminator' final = shared.Building.eliminator(final) if DEBUG: save_intermediate('eliminator') - # js optimizer pre-pass js_optimizer_queue += ['simplifyExpressionsPre'] if shared.Settings.RELOOP: js_optimizer_queue += ['optimizeShiftsAggressive'] # aggressive shifts optimization requires loops, it breaks on switches - flush_js_optimizer_queue() - final = shared.Building.eliminator(final) # aggressive shifts optimization introduces some new variables, remove ones that we can - if DEBUG: save_intermediate('eliminator') + flush_js_optimizer_queue() + final = shared.Building.eliminator(final) # aggressive shifts optimization introduces some new variables, remove ones that we can + if DEBUG: save_intermediate('eliminator') if closure: flush_js_optimizer_queue() @@ -1116,7 +927,6 @@ try: if DEBUG: save_intermediate('closure') if opt_level >= 1: - # js optimizer post-pass if DEBUG: print >> sys.stderr, 'emcc: running post-closure post-opts' js_optimizer_queue += ['simplifyExpressionsPost'] @@ -1,60 +0,0 @@ -#!/usr/bin/env python - -''' -emld - linker helper script -=========================== - -This script acts as a frontend replacement for the ld linker. See emcc. - -We could use the compiler code for this, but here we want to be careful to use all the linker flags we have been passed, sending them to ld. -''' - -import os, subprocess, sys -from tools import shared - -DEBUG = os.environ.get('EMCC_DEBUG') - -if DEBUG: - print >> sys.stderr, 'emld:', sys.argv - -ALLOWED_LINK_ARGS = ['-f', '-help', '-o', '-print-after', '-print-after-all', '-print-before', - '-print-before-all', '-time-passes', '-v', '-verify-dom-info', '-version' ] -TWO_PART_DISALLOWED_LINK_ARGS = ['-L'] # Ignore thingsl like |-L .| - -# Check for specified target -target = None -for i in range(len(sys.argv)-1): - if sys.argv[i].startswith('-o='): - raise Exception('Invalid syntax: do not use -o=X, use -o X') - - if sys.argv[i] == '-o': - target = sys.argv[i+1] - sys.argv = sys.argv[:i] + sys.argv[i+2:] - break - -call = shared.LLVM_LD -newargs = ['-disable-opt'] -i = 0 -while i < len(sys.argv)-1: - i += 1 - arg = sys.argv[i] - if arg.startswith('-'): - prefix = arg.split('=')[0] - if prefix in ALLOWED_LINK_ARGS: - newargs.append(arg) - if arg in TWO_PART_DISALLOWED_LINK_ARGS: - i += 1 - elif arg.endswith('.so'): - continue # .so's do not exist yet, in many cases - else: - # not option, so just append - newargs.append(arg) -if target: - actual_target = target - if target.endswith('.js'): - actual_target = unsuffixed(target) + '.bc' - newargs.append('-o=' + actual_target) - -if DEBUG: print >> sys.stderr, "emld running:", call, ' '.join(newargs) -subprocess.call([call] + newargs) - diff --git a/emscripten.py b/emscripten.py index 5674c33a..800ca8d7 100755 --- a/emscripten.py +++ b/emscripten.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python ''' You should normally never use this! Use emcc instead. @@ -35,7 +35,7 @@ def path_from_root(*pathelems): temp_files = shared.TempFiles() -def emscript(infile, settings, outfile): +def emscript(infile, settings, outfile, libraries=[]): """Runs the emscripten LLVM-to-JS compiler. Args: @@ -49,7 +49,7 @@ def emscript(infile, settings, outfile): s.write(settings) s.close() compiler = path_from_root('src', 'compiler.js') - shared.run_js(compiler, shared.COMPILER_ENGINE, [settings_file, infile], stdout=outfile, cwd=path_from_root('src')) + shared.run_js(compiler, shared.COMPILER_ENGINE, [settings_file, infile] + libraries, stdout=outfile, cwd=path_from_root('src')) outfile.close() @@ -123,12 +123,15 @@ def main(args): #print >> sys.stderr, 'new defs:', str(defines).replace(',', ',\n '), '\n\n' settings.setdefault('C_DEFINES', {}).update(defines) + # libraries + libraries = args.libraries[0].split(',') if len(args.libraries) > 0 else [] + # Compile the assembly to Javascript. - emscript(args.infile, json.dumps(settings), args.outfile) + emscript(args.infile, json.dumps(settings), args.outfile, libraries) if __name__ == '__main__': parser = optparse.OptionParser( - usage='usage: %prog [-h] [-O] [-m] [-H HEADERS] [-o OUTFILE] [-s FOO=BAR]* infile', + usage='usage: %prog [-h] [-H HEADERS] [-o OUTFILE] [-s FOO=BAR]* infile', description=('You should normally never use this! Use emcc instead. ' 'This is a wrapper around the JS compiler, converting .ll to .js.'), epilog='') @@ -136,6 +139,10 @@ if __name__ == '__main__': default=[], action='append', help='System headers (comma separated) whose #defines should be exposed to the compiled code.') + parser.add_option('-L', '--libraries', + default=[], + action='append', + help='Library files (comma separated) to use in addition to those in emscripten src/library_*.') parser.add_option('-o', '--outfile', default=sys.stdout, help='Where to write the output; defaults to stdout.') diff --git a/settings.py b/settings.py index 48eaa9ab..1133a656 100644 --- a/settings.py +++ b/settings.py @@ -1,17 +1,21 @@ # This file will be copied to ~/.emscripten if that file doesn't exist. Or, this is that copy. # IMPORTANT: Edit the *copy* with the right paths! +# Note: If you put paths relative to the home directory, do not forget os.path.expanduser EMSCRIPTEN_ROOT = os.path.expanduser('~/Dev/emscripten') # this helps projects using emscripten find it -LLVM_ROOT = os.path.expanduser('~/Dev/llvm-3.0/cbuild/bin') +LLVM_ROOT = os.path.expanduser('~/Dev/llvm/cbuild/bin') # See below for notes on which JS engine(s) you need NODE_JS = 'node' SPIDERMONKEY_ENGINE = [os.path.expanduser('~/Dev/mozilla-central/js/src/js'), '-m', '-n'] V8_ENGINE = os.path.expanduser('~/Dev/v8/d8') -TEMP_DIR = '/tmp' +JAVA = 'java' +TEMP_DIR = '/tmp' # You will need to modify this on Windows + +#CLOSURE_COMPILER = '..' # define this to not use the bundled version ######################################################################################################## diff --git a/src/analyzer.js b/src/analyzer.js index 8ded86f1..4bf2255e 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -9,7 +9,7 @@ var VAR_NATIVIZED = 'nativized'; var VAR_EMULATED = 'emulated'; var ENTRY_IDENT = toNiceIdent('%0'); -var ENTRY_IDENTS = set(toNiceIdent('%0'), toNiceIdent('%1')); +var ENTRY_IDENT_IDS = set(0, 1); // XXX function recomputeLines(func) { func.lines = func.labels.map(function(label) { return label.lines }).reduce(concatenator, []); @@ -544,6 +544,10 @@ function analyzer(data, sidePass) { params: [(signed && j + whole > sourceElements.length) ? signedKeepAlive : null], type: 'i32', }; + if (j == 0 && isUnsignedOp(value.op) && sourceBits < 32) { + // zext sign correction + result.ident = makeSignOp(result.ident, 'i' + sourceBits, 'un', 1, 1); + } if (fraction != 0) { var other = { intertype: 'value', @@ -1176,7 +1180,9 @@ function analyzer(data, sidePass) { func.labelIdsInverse = {}; func.labelIds[toNiceIdent('%0')] = 0; func.labelIdsInverse[0] = toNiceIdent('%0'); - func.labelIdCounter = 1; + func.labelIds[toNiceIdent('%1')] = 1; + func.labelIdsInverse[1] = toNiceIdent('%1'); + func.labelIdCounter = 2; func.labels.forEach(function(label) { func.labelIds[label.ident] = func.labelIdCounter++; func.labelIdsInverse[func.labelIdCounter-1] = label.ident; @@ -1202,6 +1208,7 @@ function analyzer(data, sidePass) { if (phi.intertype == 'phi') { for (var i = 0; i < phi.params.length; i++) { phi.params[i].label = func.labelIds[phi.params[i].label]; + if (!phi.params[i].label) warn('phi refers to nonexistent label on line ' + phi.lineNum); } } }); @@ -1217,9 +1224,10 @@ function analyzer(data, sidePass) { // So we need to handle that in a special way here. function getActualLabelId(labelId) { if (func.labelsDict[labelId]) return labelId; - if (labelId in ENTRY_IDENTS) { - assert(func.labelsDict[ENTRY_IDENT]); - return ENTRY_IDENT; + if (labelId in ENTRY_IDENT_IDS) { + labelId = func.labelIds[ENTRY_IDENT]; + assert(func.labelsDict[labelId]); + return labelId; } return null; } @@ -1270,88 +1278,44 @@ function analyzer(data, sidePass) { recomputeLines(func); } - if (!MICRO_OPTS) { - // 'Emulate' phis, by doing an if where the phi appears in the .ll. For this - // we need __lastLabel__. - func.needsLastLabel = false; - func.labels.forEach(function(label) { - var phis = []; - label.lines.forEach(function(phi) { - if (phi.intertype == 'phi') { - for (var i = 0; i < phi.params.length; i++) { - var sourceLabelId = getActualLabelId(phi.params[i].label); - if (sourceLabelId) { - var sourceLabel = func.labelsDict[sourceLabelId]; - var lastLine = sourceLabel.lines.slice(-1)[0]; - assert(lastLine.intertype in LLVM.PHI_REACHERS, 'Only some can lead to labels with phis:' + [func.ident, label.ident, lastLine.intertype]); - lastLine.currLabelId = sourceLabelId; - } - } - phis.push(phi); - func.needsLastLabel = true; - } - }); + // Properly implement phis, by pushing them back into the branch + // that leads to here. We will only have the |var| definition in this location. - if (phis.length >= 2) { - // Multiple phis have the semantics that they all occur 'in parallel', i.e., changes to - // a variable that is the result of a phi should *not* affect the other results. We must - // therefore be careful! - phis[phis.length-1].postSet = '; /* post-phi: */'; - for (var i = 0; i < phis.length-1; i++) { - var ident = phis[i].assignTo; - var phid = ident+'$phi' - phis[phis.length-1].postSet += ident + '=' + phid + ';'; - phis[i].assignTo = phid; - func.variables[phid] = { - ident: phid, - type: func.variables[ident].type, - origin: func.variables[ident].origin, - lineNum: func.variables[ident].lineNum, - uses: 1, - impl: VAR_EMULATED - }; - } - } - }); - } else { - // MICRO_OPTS == 1: Properly implement phis, by pushing them back into the branch - // that leads to here. We will only have the |var| definition in this location. - - // First, push phis back - func.labels.forEach(function(label) { - label.lines.forEach(function(phi) { - if (phi.intertype == 'phi') { - for (var i = 0; i < phi.params.length; i++) { - var param = phi.params[i]; - var sourceLabelId = getActualLabelId(param.label); - if (sourceLabelId) { - var sourceLabel = func.labelsDict[sourceLabelId]; - var lastLine = sourceLabel.lines.slice(-1)[0]; - assert(lastLine.intertype in LLVM.PHI_REACHERS, 'Only some can lead to labels with phis:' + [func.ident, label.ident, lastLine.intertype]); - if (!lastLine.phi) { - lastLine.phi = true; - assert(!lastLine.dependent); - lastLine.dependent = { - intertype: 'phiassigns', - params: [] - }; + // First, push phis back + func.labels.forEach(function(label) { + label.lines.forEach(function(phi) { + if (phi.intertype == 'phi') { + for (var i = 0; i < phi.params.length; i++) { + var param = phi.params[i]; + if (!param.label) warn('phi refers to nonexistent label on line ' + phi.lineNum); + var sourceLabelId = getActualLabelId(param.label); + if (sourceLabelId) { + var sourceLabel = func.labelsDict[sourceLabelId]; + var lastLine = sourceLabel.lines.slice(-1)[0]; + assert(lastLine.intertype in LLVM.PHI_REACHERS, 'Only some can lead to labels with phis:' + [func.ident, label.ident, lastLine.intertype]); + if (!lastLine.phi) { + lastLine.phi = true; + assert(!lastLine.dependent); + lastLine.dependent = { + intertype: 'phiassigns', + params: [] }; - lastLine.dependent.params.push({ - intertype: 'phiassign', - ident: phi.assignTo, - value: param.value, - targetLabel: label.ident - }); - } + }; + lastLine.dependent.params.push({ + intertype: 'phiassign', + ident: phi.assignTo, + value: param.value, + targetLabel: label.ident + }); } - // The assign to phi is now just a var - phi.intertype = 'var'; - phi.ident = phi.assignTo; - phi.assignTo = null; } - }); + // The assign to phi is now just a var + phi.intertype = 'var'; + phi.ident = phi.assignTo; + phi.assignTo = null; + } }); - } + }); }); this.forwardItem(item, 'StackAnalyzer'); } diff --git a/src/compiler.js b/src/compiler.js index 29ae47dd..89da32d5 100644 --- a/src/compiler.js +++ b/src/compiler.js @@ -114,6 +114,7 @@ load('settings.js'); var settings_file = arguments_[0]; var ll_file = arguments_[1]; +additionalLibraries = Array.prototype.slice.call(arguments_, 2); if (settings_file) { var settings = JSON.parse(read(settings_file)); @@ -122,6 +123,7 @@ if (settings_file) { } } + if (CORRECT_SIGNS >= 2) { CORRECT_SIGNS_LINES = set(CORRECT_SIGNS_LINES); // for fast checking } @@ -144,6 +146,8 @@ if (PGO) { // by default, correct everything during PGO EXPORTED_FUNCTIONS = set(EXPORTED_FUNCTIONS); EXPORTED_GLOBALS = set(EXPORTED_GLOBALS); +RUNTIME_DEBUG = LIBRARY_DEBUG || GL_DEBUG; + // Settings sanity checks assert(!(USE_TYPED_ARRAYS === 2 && QUANTUM_SIZE !== 4), 'For USE_TYPED_ARRAYS == 2, must have normal QUANTUM_SIZE of 4'); diff --git a/src/experimental/stringCache.diff b/src/experimental/stringCache.diff new file mode 100644 index 00000000..26cbc68c --- /dev/null +++ b/src/experimental/stringCache.diff @@ -0,0 +1,147 @@ +diff --git a/src/library_gl.js b/src/library_gl.js +index 7471578..9228964 100644 +--- a/src/library_gl.js ++++ b/src/library_gl.js +@@ -1256,28 +1256,28 @@ var LibraryGL = { + + setClientAttribute: function(name, size, type, stride, pointer) { + var attrib = this.clientAttributes[GL.immediate.ATTRIBUTE_BY_NAME[name]]; + attrib.size = size; + attrib.type = type; + attrib.stride = stride; + attrib.pointer = pointer; +- attrib.name = name + size; ++ attrib.name = Runtime.getStringConcat(name, size); + }, + + // Renderers + addRendererComponent: function(component) { + if (this.rendererComponents[component]) return; + this.rendererComponents[component] = 1; +- this.renderer += component; ++ this.renderer = Runtime.getStringConcat(this.renderer, component); + }, + + setRenderer: function(renderer) { + var name = renderer; + if (GL.currProgram && renderer[0] != 'U') { +- name = 'UD' + GL.currProgram + '|' + renderer; // user-defined program renderer ++ name = Runtime.getStringConcat(Runtime.getStringConcat('UD', GL.currProgram), Runtime.getStringConcat('|', renderer)); // user-defined program renderer + } + this.renderer = name; + if (this.renderers[name]) return this.renderers[name]; + this.renderers[name] = this.createRenderer(renderer); + return this.renderers[name]; + }, + +@@ -1300,15 +1300,18 @@ var LibraryGL = { + } + vertexSize += size * 4; // XXX assuming float + } else if (which == 'N') { + vertexSize += 4; // 1 char, + alignment + } else if (which == 'C') { + vertexSize += 4; // Up to 4 chars, + alignment + } else { +- console.log('Warning: Ignoring renderer attribute ' + which); ++#if ASSERTIONS ++ console.log('Warning: Ignoring renderer attribute'); ++ console.log(which); ++#endif + size = parseInt(renderer[i+1]); + vertexSize += size * 4; // XXX assuming float + } + } + assert(positionSize > 0); + // TODO: verify vertexSize is equal to the stride in enabled client arrays + var useCurrProgram = !!GL.currProgram; +@@ -1465,30 +1468,30 @@ var LibraryGL = { + var renderer = '', bytes = 0; + for (var i = 0; i < attributes.length; i++) { + var attribute = attributes[i]; + if (!attribute) break; + attribute.offset = attribute.pointer - start; + if (attribute.offset > bytes) { // ensure we start where we should + assert((attribute.offset - bytes)%4 == 0); // XXX assuming 4-alignment +- renderer += '?' + ((attribute.offset - bytes)/4); ++ renderer = Runtime.getStringConcat(renderer, Runtime.getStringConcat('?', ((attribute.offset - bytes)/4))); + bytes += attribute.offset - bytes; + } +- renderer += attribute.name; ++ renderer = Runtime.getStringConcat(renderer, attribute.name); + bytes += attribute.size * GL.immediate.byteSizeByType[attribute.type]; + if (bytes % 4 != 0) bytes += 4 - (bytes % 4); // XXX assuming 4-alignment + #if ASSERTIONS + assert(0 <= attribute.offset && attribute.offset < stride); // must all be in the same buffer + #endif + } + + assert(stride == 0 || bytes <= stride); + + if (bytes < stride) { // ensure the size is that of the stride + assert((stride - bytes)%4 == 0); // assuming float +- renderer += '?' + ((stride-bytes)/4); ++ renderer = Runtime.getStringConcat(renderer, Runtime.getStringConcat('?', ((stride-bytes)/4))); + bytes = stride; + } + + bytes *= count; + if (!GL.currArrayBuffer) { + GL.immediate.vertexData = {{{ makeHEAPView('F32', 'start', 'start + bytes') }}}; // XXX assuming float + } +@@ -1671,15 +1674,15 @@ var LibraryGL = { + }, + + glVertexPointer__deps: ['$GLEmulation'], // if any pointers are used, glVertexPointer must be, and if it is, then we need emulation + glVertexPointer: function(size, type, stride, pointer) { + GL.immediate.setClientAttribute('V', size, type, stride, pointer); + }, + glTexCoordPointer: function(size, type, stride, pointer) { +- GL.immediate.setClientAttribute('T' + GL.immediate.clientActiveTexture, size, type, stride, pointer); ++ GL.immediate.setClientAttribute(Runtime.getStringConcat('T', GL.immediate.clientActiveTexture), size, type, stride, pointer); + }, + glNormalPointer: function(type, stride, pointer) { + GL.immediate.setClientAttribute('N', 1, type, stride, pointer); + }, + glColorPointer: function(size, type, stride, pointer) { + GL.immediate.setClientAttribute('C', size, type, stride, pointer); + }, +diff --git a/src/runtime.js b/src/runtime.js +index 6a251c4..012a66d 100644 +--- a/src/runtime.js ++++ b/src/runtime.js +@@ -319,25 +319,34 @@ var Runtime = { + if (!Runtime.warnOnce.shown) Runtime.warnOnce.shown = {}; + if (!Runtime.warnOnce.shown[text]) { + Runtime.warnOnce.shown[text] = 1; + Module.printErr(text); + } + }, + ++ // Cache for JS function wrappers for C functions in FUNCTION_TABLE + funcWrappers: {}, +- + getFuncWrapper: function(func) { + if (!Runtime.funcWrappers[func]) { + Runtime.funcWrappers[func] = function() { + FUNCTION_TABLE[func].apply(null, arguments); + }; + } + return Runtime.funcWrappers[func]; + }, + ++ // Cache for small recurring strings generated by concatenating other ++ // strings, use this to avoid needless allocation and collection ++ stringCache: {}, ++ getStringConcat: function(a, b) { ++ var cacheItem = Runtime.stringCache[a]; ++ if (!cacheItem) cacheItem = Runtime.stringCache[a] = {}; ++ return cacheItem[b] || (cacheItem[b] = a + b); ++ }, ++ + #if RUNTIME_DEBUG + debug: true, // Switch to false at runtime to disable logging at the right times + + printObjectList: [], + + prettyPrint: function(arg) { + if (typeof arg == 'undefined') return '!UNDEFINED!'; diff --git a/src/intertyper.js b/src/intertyper.js index 0f9ce659..fbad353a 100644 --- a/src/intertyper.js +++ b/src/intertyper.js @@ -69,12 +69,12 @@ function intertyper(data, sidePass, baseLineNums) { if (mainPass && (line[0] == '%' || line[0] == '@')) { // If this isn't a type, it's a global variable, make a note of the information now, we will need it later - var testType = /[@%\w\d\.\" $]+ = type .*/.exec(line); + var testType = /[@%\w\d\.\" $-]+ = type .*/.exec(line); if (!testType) { - var global = /([@%\w\d\.\" $]+) = .*/.exec(line); + var global = /([@%\w\d\.\" $-]+) = .*/.exec(line); var globalIdent = toNiceIdent(global[1]); - var testAlias = /[@%\w\d\.\" $]+ = alias .*/.exec(line); - var testString = /^[^"]+c\"[^"]+"/.exec(line); + var testAlias = /[@%\w\d\.\" $-]+ = alias .*/.exec(line); + var testString = /[@%\w\d\.\" $-]+ = [\w ]+ \[\d+ x i8] c".*/.exec(line); Variables.globals[globalIdent] = { name: globalIdent, alias: !!testAlias, @@ -350,6 +350,10 @@ function intertyper(data, sidePass, baseLineNums) { return 'FuncHeader'; if (tokensLength >= 1 && token0Text == '}') return 'FuncEnd'; + if (token0Text == 'module' && token1Text == 'asm') { + warn('Ignoring module asm: ' + item.tokens[2].text); + return '/dev/null'; + } } if (tokensLength >= 3 && (token0Text == 'call' || token1Text == 'call')) return 'Call'; @@ -790,7 +794,7 @@ function intertyper(data, sidePass, baseLineNums) { value: parseLLVMSegment(typeToken.concat(subSegments[0])) }; return ret; - }); + }).filter(function(param) { return param.value && param.value.ident != 'undef' }); this.forwardItem(item, 'Reintegrator'); } }); diff --git a/src/jsifier.js b/src/jsifier.js index 904517e1..01ecd7d3 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -71,7 +71,7 @@ function JSify(data, functionsOnly, givenFunctions) { } } } else { - libFuncsToInclude = ['memcpy', 'memset', 'malloc', 'free']; + libFuncsToInclude = ['memcpy', 'memset', 'malloc', 'free', '$Browser']; } libFuncsToInclude.forEach(function(ident) { data.functionStubs.push({ @@ -283,7 +283,7 @@ function JSify(data, functionsOnly, givenFunctions) { var val = LibraryManager.library[shortident]; var padding; if (Runtime.isNumberType(item.type) || isPointerType(item.type)) { - padding = [item.type].concat(zeros(Runtime.getNativeFieldSize(item.type))); + padding = [item.type].concat(zeros(Runtime.getNativeFieldSize(item.type)-1)); } else { padding = makeEmptyStruct(item.type); } @@ -408,8 +408,8 @@ function JSify(data, functionsOnly, givenFunctions) { // name the function; overwrite if it's already named snippet = snippet.replace(/function(?:\s+([^(]+))?\s*\(/, 'function _' + ident + '('); if (LIBRARY_DEBUG) { - snippet = snippet.replace('{', '{ var ret = (function() {Module.printErr("[library call:' + ident + ': " + Array.prototype.slice.call(arguments) + "]"); '); - snippet = snippet.substr(0, snippet.length-1) + '}).apply(this, arguments); Module.printErr(" [ return:" + ret); return ret; }'; + snippet = snippet.replace('{', '{ var ret = (function() { if (Runtime.debug) Module.printErr("[library call:' + ident + ': " + Array.prototype.slice.call(arguments).map(Runtime.prettyPrint) + "]"); '); + snippet = snippet.substr(0, snippet.length-1) + '}).apply(this, arguments); if (Runtime.debug && typeof ret !== "undefined") Module.printErr(" [ return:" + Runtime.prettyPrint(ret)); return ret; }'; } } @@ -432,7 +432,7 @@ function JSify(data, functionsOnly, givenFunctions) { } else { ident = '_' + ident; } - var text = (deps ? '\n' + deps.map(addFromLibrary).join('\n') : ''); + var text = (deps ? '\n' + deps.map(addFromLibrary).filter(function(x) { return x != '' }).join('\n') : ''); text += isFunction ? snippet : 'var ' + ident + '=' + snippet + ';'; if (ident in EXPORTED_FUNCTIONS) { text += '\nModule["' + ident + '"] = ' + ident + ';'; @@ -450,6 +450,9 @@ function JSify(data, functionsOnly, givenFunctions) { item.JS = addFromLibrary(shortident); } else { item.JS = 'var ' + item.ident + '; // stub for ' + item.ident; + if (WARN_ON_UNDEFINED_SYMBOLS) { + warn('Unresolved symbol: ' + item.ident); + } } return ret; } @@ -555,9 +558,6 @@ function JSify(data, functionsOnly, givenFunctions) { if (CLOSURE_ANNOTATIONS) func.JS += '/** @type {number} */'; func.JS += ' var __label__;\n'; } - if (func.needsLastLabel) { - func.JS += ' var __lastLabel__ = null;\n'; - } // Walk function blocks and generate JS function walkBlock(block, indent) { @@ -748,7 +748,7 @@ function JSify(data, functionsOnly, givenFunctions) { makeFuncLineActor('noop', function(item) { return ';'; }); - makeFuncLineActor('var', function(item) { // assigns into phis become simple vars when MICRO_OPTS + makeFuncLineActor('var', function(item) { // assigns into phis become simple vars return 'var ' + item.ident + ';'; }); makeFuncLineActor('store', function(item) { @@ -762,6 +762,10 @@ function JSify(data, functionsOnly, givenFunctions) { } switch (impl) { case VAR_NATIVIZED: + if (isNumber(item.ident)) { + // Direct write to a memory address; this may be an intentional segfault, if not, it is a bug in the source + return 'throw "fault on write to ' + item.ident + '";'; + } return item.ident + '=' + value + ';'; // We have the actual value here break; case VAR_EMULATED: @@ -789,11 +793,8 @@ function JSify(data, functionsOnly, givenFunctions) { return label; } - function makeBranch(label, lastLabel, labelIsVariable) { + function makeBranch(label, lastLabel, labelIsVariable) { // lastLabel is deprecated var pre = ''; - if (!MICRO_OPTS && lastLabel) { - pre = '__lastLabel__ = ' + getLabelId(lastLabel) + '; '; - } if (label[0] == 'B') { assert(!labelIsVariable, 'Cannot handle branches to variables with special branching options'); var parts = label.split('|'); @@ -1030,7 +1031,16 @@ function JSify(data, functionsOnly, givenFunctions) { makeFuncLineActor('extractvalue', function(item) { assert(item.indexes.length == 1); // TODO: use getelementptr parsing stuff, for depth. For now, we assume that LLVM aggregates are flat, // and we emulate them using simple JS objects { f1: , f2: , } etc., for speed - return item.ident + '.f' + item.indexes[0][0].text; + var index = item.indexes[0][0].text; + var valueType = Types.types[item.type].fields[index]; + if (USE_TYPED_ARRAYS != 2 || valueType != 'i64') { + return item.ident + '.f' + index; + } else { + var assignTo = item.assignTo; + item.assignTo = null; + return 'var ' + assignTo + '$0 = ' + item.ident + '.f' + index + '[0];' + + 'var ' + assignTo + '$1 = ' + item.ident + '.f' + index + '[1];'; + } }); makeFuncLineActor('insertvalue', function(item) { assert(item.indexes.length == 1); // TODO: see extractvalue @@ -1052,20 +1062,6 @@ function JSify(data, functionsOnly, givenFunctions) { return RuntimeGenerator.stackAlloc(getFastValue(calcAllocatedSize(item.allocatedType), '*', item.allocatedNum)); } }); - makeFuncLineActor('phi', function(item) { - var params = item.params; - assert(!MICRO_OPTS); - function makeOne(i) { - if (i === params.length-1) { - return finalizeLLVMParameter(params[i].value); - } - return '__lastLabel__ == ' + getLabelId(params[i].label) + ' ? ' + - finalizeLLVMParameter(params[i].value) + ' : (' + makeOne(i+1) + ')'; - } - var ret = makeOne(0); - if (item.postSet) ret += item.postSet; - return ret; - }); makeFuncLineActor('mathop', processMathop); diff --git a/src/library.js b/src/library.js index 5b85c56f..bb73c48a 100644 --- a/src/library.js +++ b/src/library.js @@ -28,7 +28,14 @@ LibraryManager.library = { $FS__deps: ['$ERRNO_CODES', '__setErrNo', 'stdin', 'stdout', 'stderr', '_impure_ptr'], $FS__postset: '__ATINIT__.unshift({ func: function() { if (!Module["noFSInit"] && !FS.init.initialized) FS.init() } });' + '__ATMAIN__.push({ func: function() { FS.ignorePermissions = false } });' + - '__ATEXIT__.push({ func: function() { FS.quit() } });', + '__ATEXIT__.push({ func: function() { FS.quit() } });' + + // export some names through closure + 'Module["FS_createFolder"] = FS.createFolder;' + + 'Module["FS_createPath"] = FS.createPath;' + + 'Module["FS_createDataFile"] = FS.createDataFile;' + + 'Module["FS_createLazyFile"] = FS.createLazyFile;' + + 'Module["FS_createLink"] = FS.createLink;' + + 'Module["FS_createDevice"] = FS.createDevice;', $FS: { // The path to the current folder. currentPath: '/', @@ -90,18 +97,18 @@ LibraryManager.library = { #if FS_LOG var inputPath = path; function log() { - print('FS.analyzePath("' + inputPath + '", ' + - dontResolveLastLink + ', ' + - linksVisited + ') => {' + - 'isRoot: ' + ret.isRoot + ', ' + - 'exists: ' + ret.exists + ', ' + - 'error: ' + ret.error + ', ' + - 'name: "' + ret.name + '", ' + - 'path: "' + ret.path + '", ' + - 'object: ' + ret.object + ', ' + - 'parentExists: ' + ret.parentExists + ', ' + - 'parentPath: "' + ret.parentPath + '", ' + - 'parentObject: ' + ret.parentObject + '}'); + Module['print']('FS.analyzePath("' + inputPath + '", ' + + dontResolveLastLink + ', ' + + linksVisited + ') => {' + + 'isRoot: ' + ret.isRoot + ', ' + + 'exists: ' + ret.exists + ', ' + + 'error: ' + ret.error + ', ' + + 'name: "' + ret.name + '", ' + + 'path: "' + ret.path + '", ' + + 'object: ' + ret.object + ', ' + + 'parentExists: ' + ret.parentExists + ', ' + + 'parentPath: "' + ret.parentPath + '", ' + + 'parentObject: ' + ret.parentObject + '}'); } #endif path = FS.absolutePath(path); @@ -177,11 +184,11 @@ LibraryManager.library = { // Creates a file system record: file, link, device or folder. createObject: function(parent, name, properties, canRead, canWrite) { #if FS_LOG - print('FS.createObject("' + parent + '", ' + - '"' + name + '", ' + - JSON.stringify(properties) + ', ' + - canRead + ', ' + - canWrite + ')'); + Module['print']('FS.createObject("' + parent + '", ' + + '"' + name + '", ' + + JSON.stringify(properties) + ', ' + + canRead + ', ' + + canWrite + ')'); #endif if (!parent) parent = '/'; if (typeof parent === 'string') parent = FS.findObject(parent); @@ -257,11 +264,20 @@ LibraryManager.library = { var properties = {isDevice: false, contents: data}; return FS.createFile(parent, name, properties, canRead, canWrite); }, - // Creates a file record for lazy-loading from a URL. + // Creates a file record for lazy-loading from a URL. XXX This requires a synchronous + // XHR, which is not possible in browsers except in a web worker! Use preloading, + // either --preload-file in emcc or FS.createPreloadedFile createLazyFile: function(parent, name, url, canRead, canWrite) { var properties = {isDevice: false, url: url}; return FS.createFile(parent, name, properties, canRead, canWrite); }, + // Preloads a file asynchronously. You can call this before run, for example in + // preRun. run will be delayed until this file arrives and is set up. + createPreloadedFile: function(parent, name, url, canRead, canWrite) { + Browser.asyncLoad(url, function(data) { + FS.createDataFile(parent, name, data, canRead, canWrite); + }); + }, // Creates a link to a sepcific local path. createLink: function(parent, name, target, canRead, canWrite) { var properties = {isDevice: false, link: target}; @@ -340,6 +356,7 @@ LibraryManager.library = { typeof window.prompt == 'function') { // Browser. result = window.prompt('Input: '); + if (result === null) result = String.fromCharCode(0); // cancel ==> EOF } else if (typeof readline == 'function') { // Command line. result = readline(); @@ -371,8 +388,10 @@ LibraryManager.library = { if (!error.printer) error.printer = Module['print']; if (!error.buffer) error.buffer = []; - // Create the temporary folder. - FS.createFolder('/', 'tmp', true, true); + // Create the temporary folder, if not already created + try { + FS.createFolder('/', 'tmp', true, true); + } catch(e) {} // Create the I/O devices. var devFolder = FS.createFolder('/', 'dev', true, true); @@ -1476,7 +1495,7 @@ LibraryManager.library = { lseek: function(fildes, offset, whence) { // off_t lseek(int fildes, off_t offset, int whence); // http://pubs.opengroup.org/onlinepubs/000095399/functions/lseek.html - if (FS.streams[fildes] && !FS.streams[fildes].isDevice) { + if (FS.streams[fildes] && !FS.streams[fildes].object.isDevice) { var stream = FS.streams[fildes]; var position = offset; if (whence === 1) { // SEEK_CUR. @@ -1867,7 +1886,7 @@ LibraryManager.library = { #if CATCH_EXIT_CODE throw new ExitStatus(); -#else +#else throw 'exit(' + status + ') called, at ' + new Error().stack; #endif }, @@ -2217,6 +2236,9 @@ LibraryManager.library = { if (!self.called) { STATICTOP = alignMemoryPage(STATICTOP); // make sure we start out aligned self.called = true; +#if GC_SUPPORT + _sbrk.DYNAMIC_START = STATICTOP; +#endif } var ret = STATICTOP; if (bytes != 0) Runtime.staticAlloc(bytes); @@ -2242,6 +2264,15 @@ LibraryManager.library = { // TODO: Document. _scanString__deps: ['_isFloat'], _scanString: function(format, get, unget, varargs) { + if (!__scanString.whiteSpace) { + __scanString.whiteSpace = {}; + __scanString.whiteSpace[' '.charCodeAt(0)] = 1; + __scanString.whiteSpace['\t'.charCodeAt(0)] = 1; + __scanString.whiteSpace['\n'.charCodeAt(0)] = 1; + __scanString.whiteSpace[' '] = 1; + __scanString.whiteSpace['\t'] = 1; + __scanString.whiteSpace['\n'] = 1; + } // Supports %x, %4x, %d.%d, %s, %f, %lf. // TODO: Support all format specifiers. format = Pointer_stringify(format); @@ -2249,6 +2280,7 @@ LibraryManager.library = { var argsi = 0; var fields = 0; var argIndex = 0; + var next; for (var formatIndex = 0; formatIndex < format.length; formatIndex++) { if (next <= 0) return fields; var next = get(); @@ -2264,11 +2296,14 @@ LibraryManager.library = { if (formatIndex != maxSpecifierStart) { max_ = parseInt(format.slice(maxSpecifierStart, formatIndex), 10); } - // TODO: Handle type size modifier. var long_ = false; + var half = false; if (format[formatIndex] == 'l') { long_ = true; formatIndex++; + } else if (format[formatIndex] == 'h') { + half = true; + formatIndex++; } var type = format[formatIndex]; formatIndex++; @@ -2288,13 +2323,18 @@ LibraryManager.library = { buffer.pop(); unget(); } + unget(); + next = get(); } else { + var first = true; while ((curr < max_ || isNaN(max_)) && next > 0) { - if ((type === 'd' && next >= '0'.charCodeAt(0) && next <= '9'.charCodeAt(0)) || - (type === 'x' && (next >= '0'.charCodeAt(0) && next <= '9'.charCodeAt(0) || - next >= 'a'.charCodeAt(0) && next <= 'f'.charCodeAt(0) || - next >= 'A'.charCodeAt(0) && next <= 'F'.charCodeAt(0))) || - (type === 's') && + if (!(next in __scanString.whiteSpace) && // stop on whitespace + (type == 's' || + ((type === 'd' || type == 'u') && ((next >= '0'.charCodeAt(0) && next <= '9'.charCodeAt(0)) || + (first && next == '-'.charCodeAt(0)))) || + (type === 'x' && (next >= '0'.charCodeAt(0) && next <= '9'.charCodeAt(0) || + next >= 'a'.charCodeAt(0) && next <= 'f'.charCodeAt(0) || + next >= 'A'.charCodeAt(0) && next <= 'F'.charCodeAt(0)))) && (formatIndex >= format.length || next !== format[formatIndex].charCodeAt(0))) { // Stop when we read something that is coming up buffer.push(String.fromCharCode(next)); next = get(); @@ -2302,6 +2342,7 @@ LibraryManager.library = { } else { break; } + first = false; } } if (buffer.length === 0) return 0; // Failure. @@ -2309,8 +2350,12 @@ LibraryManager.library = { var argPtr = {{{ makeGetValue('varargs', 'argIndex', 'void*') }}}; argIndex += Runtime.getNativeFieldSize('void*'); switch (type) { - case 'd': - {{{ makeSetValue('argPtr', 0, 'parseInt(text, 10)', 'i32') }}} + case 'd': case 'u': + if (half) { + {{{ makeSetValue('argPtr', 0, 'parseInt(text, 10)', 'i16') }}}; + } else { + {{{ makeSetValue('argPtr', 0, 'parseInt(text, 10)', 'i32') }}}; + } break; case 'x': {{{ makeSetValue('argPtr', 0, 'parseInt(text, 16)', 'i32') }}} @@ -2330,6 +2375,12 @@ LibraryManager.library = { break; } fields++; + } else if (format[formatIndex] in __scanString.whiteSpace) { + while (next in __scanString.whiteSpace) { + next = get(); + if (next <= 0) return fields; // End of input. + } + unget(); } else { // Not a specifier. if (format[formatIndex].charCodeAt(0) !== next) { @@ -2666,24 +2717,19 @@ LibraryManager.library = { }); } else if (next == 's'.charCodeAt(0)) { // String. - var arg = getNextArg('i8*'); - var copiedString; - if (arg) { - copiedString = String_copy(arg); - if (precisionSet && copiedString.length > precision) { - copiedString = copiedString.slice(0, precision); - } - } else { - copiedString = intArrayFromString('(null)', true); - } + var arg = getNextArg('i8*') || 0; // 0 holds '(null)' + var argLength = String_len(arg); + if (precisionSet) argLength = Math.min(String_len(arg), precision); if (!flagLeftAlign) { - while (copiedString.length < width--) { + while (argLength < width--) { ret.push(' '.charCodeAt(0)); } } - ret = ret.concat(copiedString); + for (var i = 0; i < argLength; i++) { + ret.push({{{ makeGetValue('arg++', 0, 'i8', null, true) }}}); + } if (flagLeftAlign) { - while (copiedString.length < width--) { + while (argLength < width--) { ret.push(' '.charCodeAt(0)); } } @@ -2808,7 +2854,7 @@ LibraryManager.library = { streamObj.error = true; return -1; } else { - return {{{ makeGetValue('_fgetc.ret', '0', 'i8') }}}; + return {{{ makeGetValue('_fgetc.ret', '0', 'i8', null, 1) }}}; } }, getc: 'fgetc', @@ -3413,6 +3459,8 @@ LibraryManager.library = { strtod__deps: ['isspace', 'isdigit'], strtod: function(str, endptr) { + var origin = str; + // Skip space. while (_isspace({{{ makeGetValue('str', 0, 'i8') }}})) str++; @@ -3429,26 +3477,35 @@ LibraryManager.library = { var ret = 0; // Get whole part. + var whole = false; while(1) { chr = {{{ makeGetValue('str', 0, 'i8') }}}; if (!_isdigit(chr)) break; + whole = true; ret = ret*10 + chr - '0'.charCodeAt(0); str++; } // Get fractional part. + var fraction = false; if ({{{ makeGetValue('str', 0, 'i8') }}} == '.'.charCodeAt(0)) { str++; var mul = 1/10; while(1) { chr = {{{ makeGetValue('str', 0, 'i8') }}}; if (!_isdigit(chr)) break; + fraction = true; ret += mul*(chr - '0'.charCodeAt(0)); mul /= 10; str++; } } + if (!whole && !fraction) { + {{{ makeSetValue('endptr', 0, 'origin', '*') }}} + return 0; + } + // Get exponent part. chr = {{{ makeGetValue('str', 0, 'i8') }}}; if (chr == 'e'.charCodeAt(0) || chr == 'E'.charCodeAt(0)) { @@ -3480,6 +3537,9 @@ LibraryManager.library = { return ret * multiplier; }, + strtod_l: 'strtod', // no locale support yet + strtold: 'strtod', // XXX add real support for long double + strtold_l: 'strtold', // no locale support yet _parseInt__deps: ['isspace', '__setErrNo', '$ERRNO_CODES'], _parseInt: function(str, endptr, base, min, max, bits, unsign) { @@ -3956,19 +4016,35 @@ LibraryManager.library = { }, strspn: function(pstr, pset) { - var str = String_copy(pstr, true); - var set = String_copy(pset); - var i = 0; - while (set.indexOf(str[i]) != -1) i++; // Must halt, as 0 is in str but not set - return i; + var str = pstr, set, strcurr, setcurr; + while (1) { + strcurr = {{{ makeGetValue('str', '0', 'i8') }}}; + if (!strcurr) return str - pstr; + set = pset; + while (1) { + setcurr = {{{ makeGetValue('set', '0', 'i8') }}}; + if (!setcurr || setcurr == strcurr) break; + set++; + } + if (!setcurr) return str - pstr; + str++; + } }, strcspn: function(pstr, pset) { - var str = String_copy(pstr, true); - var set = String_copy(pset, true); - var i = 0; - while (set.indexOf(str[i]) == -1) i++; // Must halt, as 0 is in both - return i; + var str = pstr, set, strcurr, setcurr; + while (1) { + strcurr = {{{ makeGetValue('str', '0', 'i8') }}}; + if (!strcurr) return str - pstr; + set = pset; + while (1) { + setcurr = {{{ makeGetValue('set', '0', 'i8') }}}; + if (!setcurr || setcurr == strcurr) break; + set++; + } + if (setcurr) return str - pstr; + str++; + } }, strcpy: function(pdest, psrc) { @@ -4149,10 +4225,36 @@ LibraryManager.library = { return newStr; }, + strndup__deps: ['strdup'], + strndup: function(ptr, size) { + var len = String_len(ptr); + + if (size >= len) { + return _strdup(ptr); + } + + if (size < 0) { + size = 0; + } + + var newStr = _malloc(size + 1); + {{{ makeCopyValues('newStr', 'ptr', 'size', 'null', null, 1) }}}; + {{{ makeSetValue('newStr', 'size', '0', 'i8') }}}; + return newStr; + }, + strpbrk: function(ptr1, ptr2) { - var searchSet = Runtime.set.apply(null, String_copy(ptr2)); - while ({{{ makeGetValue('ptr1', 0, 'i8') }}}) { - if ({{{ makeGetValue('ptr1', 0, 'i8') }}} in searchSet) return ptr1; + var curr; + var searchSet = {}; + while (1) { + var curr = {{{ makeGetValue('ptr2++', 0, 'i8') }}}; + if (!curr) break; + searchSet[curr] = 1; + } + while (1) { + curr = {{{ makeGetValue('ptr1', 0, 'i8') }}}; + if (!curr) break; + if (curr in searchSet) return ptr1; ptr1++; } return 0; @@ -4280,19 +4382,13 @@ LibraryManager.library = { isdigit: function(chr) { return chr >= '0'.charCodeAt(0) && chr <= '9'.charCodeAt(0); }, - isdigit_l__deps: ['isdigit'], - isdigit_l: function(chr, loc) { - return _isdigit(chr); - }, + isdigit_l: 'isdigit', // no locale support yet isxdigit: function(chr) { return (chr >= '0'.charCodeAt(0) && chr <= '9'.charCodeAt(0)) || (chr >= 'a'.charCodeAt(0) && chr <= 'f'.charCodeAt(0)) || (chr >= 'A'.charCodeAt(0) && chr <= 'F'.charCodeAt(0)); }, - isxdigit_l__deps: ['isxdigit'], - isxdigit_l: function(chr, loc) { - return _isxdigit(chr); - }, + isxdigit_l: 'isxdigit', // no locale support yet isalnum: function(chr) { return (chr >= '0'.charCodeAt(0) && chr <= '9'.charCodeAt(0)) || (chr >= 'a'.charCodeAt(0) && chr <= 'z'.charCodeAt(0)) || @@ -4422,6 +4518,21 @@ LibraryManager.library = { */ }, + llvm_bswap_i16: function(x) { + x = unSign(x, 32); + var bytes = []; + bytes[0] = x & 255; + x >>= 8; + bytes[1] = x & 255; + x >>= 8; + var ret = 0; + ret <<= 8; + ret += bytes[0]; + ret <<= 8; + ret += bytes[1]; + return ret; + }, + llvm_bswap_i32: function(x) { x = unSign(x, 32); var bytes = []; @@ -4436,7 +4547,7 @@ LibraryManager.library = { } return ret; }, - + llvm_ctlz_i32: function(x) { for (var i=0; i<32; i++) { if ( (x & (1 << (31-i))) != 0 ) { @@ -4615,12 +4726,12 @@ LibraryManager.library = { // return the type of the catch block which should be called. for (var i = 0; i < typeArray.length; i++) { if (___cxa_does_inherit(typeArray[i], throwntype, thrown)) - return { 'f0':thrown, 'f1':typeArray[i]}; + return { f0:thrown, f1:typeArray[i] }; } // Shouldn't happen unless we have bogus data in typeArray // or encounter a type for which emscripten doesn't have suitable // typeinfo defined. Best-efforts match just in case. - return {'f0':thrown,'f1':throwntype}; + return { f0:thrown, f1 :throwntype }; }, // Recursively walks up the base types of 'possibilityType' @@ -4682,6 +4793,42 @@ LibraryManager.library = { // type_info for void*. _ZTIPv: [0], + llvm_uadd_with_overflow_i8: function(x, y) { + x = x & 0xff; + y = y & 0xff; + return { + f0: (x+y) & 0xff, + f1: x+y > 255 + }; + }, + + llvm_umul_with_overflow_i8: function(x, y) { + x = x & 0xff; + y = y & 0xff; + return { + f0: (x*y) & 0xff, + f1: x*y > 255 + }; + }, + + llvm_uadd_with_overflow_i16: function(x, y) { + x = x & 0xffff; + y = y & 0xffff; + return { + f0: (x+y) & 0xffff, + f1: x+y > 65535 + }; + }, + + llvm_umul_with_overflow_i16: function(x, y) { + x = x & 0xffff; + y = y & 0xffff; + return { + f0: (x*y) & 0xffff, + f1: x*y > 65535 + }; + }, + llvm_uadd_with_overflow_i32: function(x, y) { x = x>>>0; y = y>>>0; @@ -4700,6 +4847,24 @@ LibraryManager.library = { }; }, + llvm_uadd_with_overflow_i64__deps: [function() { preciseI64MathUsed = 1 }], + llvm_uadd_with_overflow_i64: function(xl, xh, yl, yh) { + i64Math.add(xl, xh, yl, yh); + return { + f0: i64Math.result, + f1: 0 // XXX Need to hack support for this in long.js + }; + }, + + llvm_umul_with_overflow_i64__deps: [function() { preciseI64MathUsed = 1 }], + llvm_umul_with_overflow_i64: function(xl, xh, yl, yh) { + i64Math.mul(xl, xh, yl, yh); + return { + f0: i64Math.result, + f1: 0 // XXX Need to hack support for this in long.js + }; + }, + llvm_stacksave: function() { var self = _llvm_stacksave; if (!self.LLVM_SAVEDSTACKS) { @@ -4739,6 +4904,11 @@ LibraryManager.library = { llvm_lifetime_start: function() {}, llvm_lifetime_end: function() {}, + llvm_invariant_start: function() {}, + llvm_invariant_end: function() {}, + + llvm_objectsize_i32: function() { return -1 }, // TODO: support this + // ========================================================================== // math.h // ========================================================================== @@ -4963,7 +5133,7 @@ LibraryManager.library = { if (isNaN(x)) return {{{ cDefine('FP_NAN') }}}; if (!isFinite(x)) return {{{ cDefine('FP_INFINITE') }}}; if (x == 0) return {{{ cDefine('FP_ZERO') }}}; - // FP_SUBNORMAL..? + // FP_SUBNORMAL..? return {{{ cDefine('FP_NORMAL') }}}; }, __fpclassifyd: '__fpclassifyf', @@ -5367,6 +5537,7 @@ LibraryManager.library = { // TODO: Implement. return 0; }, + strftime_l: 'strftime', // no locale support yet strptime: function(buf, format, tm) { // char *strptime(const char *restrict buf, const char *restrict format, struct tm *restrict tm); @@ -5374,6 +5545,7 @@ LibraryManager.library = { // TODO: Implement. return 0; }, + strptime_l: 'strptime', // no locale support yet getdate: function(string) { // struct tm *getdate(const char *string); @@ -6080,6 +6252,10 @@ LibraryManager.library = { return eval(Pointer_stringify(ptr)); }, + emscripten_random: function() { + return Math.random(); + }, + $Profiling: { max_: 0, times: null, diff --git a/src/library_browser.js b/src/library_browser.js index 17dff2eb..075bd8bf 100644 --- a/src/library_browser.js +++ b/src/library_browser.js @@ -3,24 +3,30 @@ // Utilities for browser environments mergeInto(LibraryManager.library, { - emscripten_set_main_loop: function(func, fps) { - fps = fps || 60; // TODO: use requestAnimationFrame - _emscripten_set_main_loop.cancel = false; - var jsFunc = FUNCTION_TABLE[func]; - function doOne() { - if (_emscripten_set_main_loop.cancel) return; - jsFunc(); - setTimeout(doOne, 1000/fps); // doing this each time means that on exception, we stop - } - setTimeout(doOne, 1000/fps); - }, - - emscripten_cancel_main_loop: function(func) { - _emscripten_set_main_loop.cancel = true; - }, - + $Browser__postset: 'Module["requestFullScreen"] = function() { Browser.requestFullScreen() };\n' + // exports + 'Module["requestAnimationFrame"] = function(func) { Browser.requestAnimationFrame(func) };\n' + + 'Module["pauseMainLoop"] = function() { Browser.mainLoop.pause() };\n' + + 'Module["resumeMainLoop"] = function() { Browser.mainLoop.resume() };\n', $Browser: { - createContext: function(canvas, useWebGL) { + mainLoop: { + scheduler: null, + shouldPause: false, + paused: false, + pause: function() { + Browser.mainLoop.shouldPause = true; + }, + resume: function() { + if (Browser.mainLoop.paused) { + Browser.mainLoop.paused = false; + Browser.mainLoop.scheduler(); + } + Browser.mainLoop.shouldPause = false; + }, + }, + pointerLock: false, + moduleContextCreatedCallbacks: [], + + createContext: function(canvas, useWebGL, setInModule) { #if !USE_TYPED_ARRAYS if (useWebGL) { Module.print('(USE_TYPED_ARRAYS needs to be enabled for WebGL)'); @@ -39,50 +45,19 @@ mergeInto(LibraryManager.library, { // Useful to debug native webgl apps: var Module = { printErr: function(x) { console.log(x) } }; var tempCtx = ctx; var wrapper = {}; - wrapper.objectMap = new WeakMap(); - wrapper.objectCounter = 1; for (var prop in tempCtx) { (function(prop) { switch (typeof tempCtx[prop]) { case 'function': { wrapper[prop] = function() { - var printArgs = Array.prototype.slice.call(arguments).map(function(arg) { - if (wrapper.objectMap[arg]) return '<' + arg + '|' + wrapper.objectMap[arg] + '>'; - if (arg.toString() == '[object HTMLImageElement]') { - return arg + '\n\n'; - } - if (arg.byteLength) { - var buf = new ArrayBuffer(32); - var i8buf = new Int8Array(buf); - var f32buf = new Float32Array(buf); - switch(arg.toString()) { - case '[object Uint8Array]': - i8buf.set(arg.subarray(0, 32)); - break; - case '[object Float32Array]': - f32buf.set(arg.subarray(0, 5)); - break; - default: - alert('unknown array for debugging: ' + arg); - throw 'see alert'; - } - var ret = '{' + arg.byteLength + ':\n'; - var arr = Array.prototype.slice.call(i8buf); - ret += 'i8:' + arr.toString().replace(/,/g, ',') + '\n'; - arr = Array.prototype.slice.call(f32buf, 0, 8); - ret += 'f32:' + arr.toString().replace(/,/g, ',') + '}'; - return ret; - } - return arg; - }); - Module.printErr('[gl_f:' + prop + ':' + printArgs + ']'); + if (GL.debug) { + var printArgs = Array.prototype.slice.call(arguments).map(Runtime.prettyPrint); + Module.printErr('[gl_f:' + prop + ':' + printArgs + ']'); + } var ret = tempCtx[prop].apply(tempCtx, arguments); - var printRet = ret; - if (typeof ret == 'object') { - wrapper.objectMap[ret] = wrapper.objectCounter++; - printRet = '<' + ret + '|' + wrapper.objectMap[ret] + '>'; + if (GL.debug && typeof ret != 'undefined') { + Module.printErr('[ gl:' + prop + ':return:' + Runtime.prettyPrint(ret) + ']'); } - Module.printErr('[ gl:' + prop + ':return:' + printRet + ']'); return ret; } break; @@ -93,7 +68,9 @@ mergeInto(LibraryManager.library, { return tempCtx[prop]; }); wrapper.__defineSetter__(prop, function(value) { - Module.printErr('[gl_s:' + prop + ':' + value + ']'); + if (GL.debug) { + Module.printErr('[gl_s:' + prop + ':' + value + ']'); + } tempCtx[prop] = value; }); break; @@ -105,50 +82,232 @@ mergeInto(LibraryManager.library, { #endif // Set the background of the WebGL canvas to black canvas.style.backgroundColor = "black"; + + // Warn on context loss + canvas.addEventListener('webglcontextlost', function(event) { + alert('WebGL context lost. You will need to reload the page.'); + }, false); + } + if (setInModule) { + Module.ctx = ctx; + Module.useWebGL = useWebGL; + Browser.moduleContextCreatedCallbacks.forEach(function(callback) { callback() }); } return ctx; }, - // 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. - // This is deprecated, it is preferred to load binary files, createObjectURL, etc., - // see the sdl_* tests. - /*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]; - } + requestFullScreen: function() { + var canvas = Module.canvas; + function fullScreenChange() { + if (Module['onFullScreen']) Module['onFullScreen'](); + if (document['webkitFullScreenElement'] === canvas || + document['mozFullScreenElement'] === canvas || + document['fullScreenElement'] === canvas) { + canvas.requestPointerLock = canvas['requestPointerLock'] || + canvas['mozRequestPointerLock'] || + canvas['webkitRequestPointerLock']; + canvas.requestPointerLock(); } - if (leftbits == 2) { - ret += BASE[(leftchar&3) << 4]; - ret += PAD + PAD; - } else if (leftbits == 4) { - ret += BASE[(leftchar&0xf) << 2]; - ret += PAD; + } + + document.addEventListener('fullscreenchange', fullScreenChange, false); + document.addEventListener('mozfullscreenchange', fullScreenChange, false); + document.addEventListener('webkitfullscreenchange', fullScreenChange, false); + + function pointerLockChange() { + Browser.pointerLock = document['pointerLockElement'] === canvas || + document['mozPointerLockElement'] === canvas || + document['webkitPointerLockElement'] === canvas; + } + + document.addEventListener('pointerlockchange', pointerLockChange, false); + document.addEventListener('mozpointerlockchange', pointerLockChange, false); + document.addEventListener('webkitpointerlockchange', pointerLockChange, false); + + canvas.requestFullScreen = canvas['requestFullScreen'] || + canvas['mozRequestFullScreen'] || + (canvas['webkitRequestFullScreen'] ? function() { canvas['webkitRequestFullScreen'](Element['ALLOW_KEYBOARD_INPUT']) } : null); + canvas.requestFullScreen(); + }, + + requestAnimationFrame: function(func) { + if (!window.requestAnimationFrame) { + window.requestAnimationFrame = window['requestAnimationFrame'] || + window['mozRequestAnimationFrame'] || + window['webkitRequestAnimationFrame'] || + window['msRequestAnimationFrame'] || + window['oRequestAnimationFrame'] || + window['setTimeout']; + } + window.requestAnimationFrame(func); + }, + + getMovementX: function(event) { + return event['movementX'] || + event['mozMovementX'] || + event['webkitMovementX'] || + 0; + }, + + getMovementY: function(event) { + return event['movementY'] || + event['mozMovementY'] || + event['webkitMovementY'] || + 0; + }, + + xhrLoad: function(url, onload, onerror) { + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, true); + xhr.responseType = 'arraybuffer'; + xhr.onload = function() { + if (xhr.status == 200) { + onload(xhr.response); + } else { + onerror(); } - return ret; + }; + xhr.onerror = onerror; + xhr.send(null); + }, + + asyncLoad: function(url, callback) { + Browser.xhrLoad(url, function(arrayBuffer) { + assert(arrayBuffer, 'Loading data file "' + url + '" failed (no arrayBuffer).'); + callback(new Uint8Array(arrayBuffer)); + removeRunDependency(); + }, function(event) { + throw 'Loading data file "' + url + '" failed.'; + }); + addRunDependency(); + } + }, + + emscripten_async_wget: function(url, file, onload, onerror) { + url = Pointer_stringify(url); + + Browser.xhrLoad(url, function(response) { + var absolute = Pointer_stringify(file); + var index = absolute.lastIndexOf('/'); + FS.createDataFile( + absolute.substr(0, index), + absolute.substr(index +1), + new Uint8Array(response), + true, true); + + if (onload) { + FUNCTION_TABLE[onload](file); + } + }, function(event) { + if (onerror) { + FUNCTION_TABLE[onerror](file); } - var image = new Image(); - image.src = 'data:image/' + format + ';base64,' + encodeBase64(pixels); - assert(image.complete, 'Image could not be decoded'); // page reload might fix it, decoding is async... need .onload handler... - var canvas = document.createElement('canvas'); - canvas.width = image.width; - canvas.height = image.height; - var ctx = canvas.getContext('2d'); - ctx.drawImage(image, 0, 0); - var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); - return imageData; - },*/ + }); + }, + + emscripten_async_run_script__deps: ['emscripten_run_script'], + emscripten_async_run_script: function(script, millis) { + Module['noExitRuntime'] = true; + + // TODO: cache these to avoid generating garbage + setTimeout(function() { + _emscripten_run_script(script); + }, millis); + }, + + emscripten_set_main_loop: function(func, fps) { + Module['noExitRuntime'] = true; + + var jsFunc = FUNCTION_TABLE[func]; + var wrapper = function() { + if (Browser.mainLoop.shouldPause) { + // catch pauses from non-main loop sources + Browser.mainLoop.paused = true; + Browser.mainLoop.shouldPause = false; + return; + } + jsFunc(); + if (Browser.mainLoop.shouldPause) { + // catch pauses from the main loop itself + Browser.mainLoop.paused = true; + Browser.mainLoop.shouldPause = false; + return; + } + Browser.mainLoop.scheduler(); + } + if (fps && fps > 0) { + Browser.mainLoop.scheduler = function() { + setTimeout(wrapper, 1000/fps); // doing this each time means that on exception, we stop + } + } else { + Browser.mainLoop.scheduler = function() { + Browser.requestAnimationFrame(wrapper); + } + } + Browser.mainLoop.scheduler(); + }, + + emscripten_cancel_main_loop: function(func) { + Browser.mainLoop.scheduler = null; + Browser.mainLoop.shouldPause = true; + }, + + emscripten_pause_main_loop: function(func) { + Browser.mainLoop.pause(); + }, + + emscripten_resume_main_loop: function(func) { + Browser.mainLoop.resume(); + }, + + emscripten_async_call: function(func, millis) { + Module['noExitRuntime'] = true; + + var asyncCall = Runtime.getFuncWrapper(func); + if (millis >= 0) { + setTimeout(asyncCall, millis); + } else { + Browser.requestAnimationFrame(asyncCall); + } + }, + + emscripten_hide_mouse: function() { + var styleSheet = document.styleSheets[0]; + var rules = styleSheet.cssRules; + for (var i = 0; i < rules.length; i++) { + if (rules[i].cssText.substr(0, 5) == 'canvas') { + styleSheet.deleteRule(i); + i--; + } + } + styleSheet.insertRule('canvas.emscripten { border: 1px solid black; cursor: none; }', 0); + }, + + emscripten_set_canvas_size: function(width, height) { + Module['canvas'].width = width; + Module['canvas'].height = height; + }, + + emscripten_get_now: function() { + if (window['performance'] && window['performance']['now']) { + return window['performance']['now'](); + } else { + return Date.now(); + } } }); +/* Useful stuff for browser debugging + +function slowLog(label, text) { + if (!slowLog.labels) slowLog.labels = {}; + if (!slowLog.labels[label]) slowLog.labels[label] = 0; + var now = Date.now(); + if (now - slowLog.labels[label] > 1000) { + Module.print(label + ': ' + text); + slowLog.labels[label] = now; + } +} + +*/ + diff --git a/src/library_egl.js b/src/library_egl.js index f1558f80..635e00a7 100644 --- a/src/library_egl.js +++ b/src/library_egl.js @@ -12,6 +12,12 @@ var LibraryEGL = { return 1; }, + // EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value); + eglQuerySurface: function(display, surface, attribute, value) { return 0 }, + + // EGLAPI EGLint EGLAPIENTRY eglGetError(void); + eglGetError: function() { return 0x3000 /* EGL_SUCCESS */ }, + eglMakeCurrent: function(display, surface, surface_, context) { return 1 }, eglSwapBuffers: function() {}, }; diff --git a/src/library_gc.js b/src/library_gc.js new file mode 100644 index 00000000..bf0a6aff --- /dev/null +++ b/src/library_gc.js @@ -0,0 +1,167 @@ + +if (GC_SUPPORT) { + var LibraryGC = { + $GC__deps: ['sbrk'], + $GC: { + ALLOCATIONS_TO_GC: 1*1024*1024, + + sizes: {}, // if in this map, then a live allocated object. this is iterable + scannables: {}, + finalizers: {}, + finalizerArgs: {}, + + totalAllocations: 0, // bytes of all currently active objects + recentAllocations: 0, // bytes allocated since last gc. ignores free()s + + init: function() { + assert(!GC.initted); + GC.initted = true; + if (ENVIRONMENT_IS_WEB) { + setInterval(function() { + GC.maybeCollect(); + }, 1000); + } else { +#if ASSERTIONS + Module.print('No HTML intervals, so you need to call GC.maybeCollect() or GC.collect() manually'); +#endif + } + }, + + malloc: function(bytes, clear, scannable) { + if (!bytes) return 0; + var ptr; + if (clear) { + ptr = _calloc(1, bytes); + } else { + ptr = _malloc(bytes); + } + GC.scannables[ptr] = scannable; + GC.sizes[ptr] = bytes; + GC.totalAllocations += bytes; + GC.recentAllocations += bytes; + return ptr; + }, + + free: function(ptr) { // does not check if anything refers to it, this is a forced free + var finalizer = GC.finalizers[ptr]; + if (finalizer) { + Runtime.getFuncWrapper(finalizer)(ptr, GC.finalizerArgs[ptr]); + GC.finalizers[ptr] = 0; + } + _free(ptr); + delete GC.sizes[ptr]; + GC.totalAllocations -= GC.sizes[ptr]; + }, + + registerFinalizer: function(ptr, func, arg, oldFunc, oldArg) { + var finalizer = GC.finalizers[ptr]; + if (finalizer) { + if (oldFunc) { + {{{ makeSetValue('oldFunc', '0', 'finalizer', 'i32') }}}; + } + if (oldArg) { + {{{ makeSetValue('oldArg', '0', 'GC.finalizerArgs[ptr]', 'i32') }}}; + } + } + GC.finalizers[ptr] = func; + GC.finalizerArgs[ptr] = arg; + }, + + maybeCollect: function() { + if (GC.needCollect()) GC.collect(); + }, + + needCollect: function() { + return GC.recentAllocations >= GC.ALLOCATIONS_TO_GC; // TODO: time, etc. + }, + + collect: function() { + GC.prep(); + GC.mark(); + GC.sweep(); + GC.recentAllocations = 0; + }, + + scan: function(start, end) { // scans a memory region and adds new reachable objects + for (var i = start; i < end; i += {{{ Runtime.getNativeTypeSize('void*') }}}) { + var ptr = {{{ makeGetValue('i', '0', 'void*') }}}; + if (GC.sizes[ptr] && !GC.reachable[ptr]) { + GC.reachable[ptr] = 1; + if (GC.scannables[ptr]) { + GC.reachableList.push(ptr); + } + } + } + }, + + prep: function() { // Clear reachables and scan for roots + GC.reachable = {}; // 1 if reachable. XXX + GC.reachableList = []; // each reachable is added once to this. XXX + // static data areas + var staticStart = STACK_MAX; + var staticEnd = _sbrk.DYNAMIC_START || STATICTOP; // after DYNAMIC_START, sbrk manages it (but it might not exist yet) + GC.scan(staticStart, staticEnd); + // TODO: scan stack and registers. Currently we assume we run from a timeout or such, so no stack/regs + // stack: STACK_ROOT to STACKTOP + // registers: call scanners + }, + + mark: function() { // mark all reachable from roots + for (var i = 0; i < GC.reachableList.length; i++) { // note that the list length changes as we push more + var ptr = GC.reachableList[i]; + GC.scan(ptr, ptr + GC.sizes[ptr]); + } + }, + + sweep: function() { // traverse all objects and free all unreachable + var freeList = []; + for (var ptr in GC.sizes) { + if (!GC.reachable[ptr]) { + freeList.push(parseInt(ptr)); + } + } + for (var i = 0; i < freeList.length; i++) { + GC.free(freeList[i]); + } + } + }, + + GC_INIT__deps: ['$GC'], + GC_INIT: function() { + GC.init(); + }, + + GC_MALLOC__deps: ['$GC'], + GC_MALLOC: function(bytes) { + return GC.malloc(bytes, true, true); + }, + + GC_MALLOC_ATOMIC__deps: ['$GC'], + GC_MALLOC_ATOMIC: function(bytes) { + return GC.malloc(bytes, false, false); + }, + + GC_FREE__deps: ['$GC'], + GC_FREE: function(ptr) { + GC.free(ptr); + }, + + GC_REGISTER_FINALIZER_NO_ORDER__deps: ['$GC'], + GC_REGISTER_FINALIZER_NO_ORDER: function(ptr, func, arg, old_func, old_arg) { + GC.registerFinalizer(ptr, func, arg, old_func, old_arg); + }, + + GC_MAYBE_COLLECT__deps: ['$GC'], + GC_MAYBE_COLLECT: function() { + GC.maybeCollect(); + }, + + GC_FORCE_COLLECT__deps: ['$GC'], + GC_FORCE_COLLECT: function() { + GC.collect(); + } + }; + + mergeInto(LibraryManager.library, LibraryGC); +} + diff --git a/src/library_gl.js b/src/library_gl.js index 3c33ec2c..f3cea384 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -4,17 +4,27 @@ */ var LibraryGL = { + $GL__postset: 'GL.init()', $GL: { +#if GL_DEBUG + debug: true, +#endif + counter: 1, buffers: {}, programs: {}, framebuffers: {}, - renderbuffer: {}, + renderbuffers: {}, textures: {}, uniforms: {}, shaders: {}, - matrix: {}, + packAlignment: 4, // default alignment is 4 bytes + unpackAlignment: 4, // default alignment is 4 bytes + + init: function() { + Browser.moduleContextCreatedCallbacks.push(GL.initExtensions); + }, // Linear lookup in one of the tables (buffers, programs, etc.). TODO: consider using a weakmap to make this faster, if it matters scan: function(table, object) { @@ -51,9 +61,135 @@ var LibraryGL = { return true; } while (true); return false; + }, + + getSource: function(shader, count, string, length) { + var source = ''; + for (var i = 0; i < count; ++i) { + var frag; + if (length) { + var len = {{{ makeGetValue('length', 'i*4', 'i32') }}}; + if (len < 0) { + frag = Pointer_stringify({{{ makeGetValue('string', 'i*4', 'i32') }}}); + } else { + frag = Pointer_stringify({{{ makeGetValue('string', 'i*4', 'i32') }}}, len); + } + } else { + frag = Pointer_stringify({{{ makeGetValue('string', 'i*4', 'i32') }}}); + } + source += frag; + } + // Let's see if we need to enable the standard derivatives extension + type = Module.ctx.getShaderParameter(GL.shaders[shader], 0x8B4F /* GL_SHADER_TYPE */); + if (type == 0x8B30 /* GL_FRAGMENT_SHADER */) { + if (GL.findToken(source, "dFdx") || + GL.findToken(source, "dFdy") || + GL.findToken(source, "fwidth")) { + source = "#extension GL_OES_standard_derivatives : enable\n" + source; + var extension = Module.ctx.getExtension("OES_standard_derivatives"); +#if GL_DEBUG + if (!extension) { + Module.printErr("Shader attempts to use the standard derivatives extension which is not available."); + } +#endif + } + } + return source; + }, + + computeImageSize: function(width, height, sizePerPixel, alignment) { + function roundedToNextMultipleOf(x, y) { + return Math.floor((x + y - 1) / y) * y + } + var plainRowSize = width * sizePerPixel; + var alignedRowSize = roundedToNextMultipleOf(plainRowSize, alignment); + return (height <= 0) ? 0 : + ((height - 1) * alignedRowSize + plainRowSize); + }, + + getTexPixelData: function(type, format, width, height, pixels, internalFormat) { + var sizePerPixel; + switch (type) { + case 0x1401 /* GL_UNSIGNED_BYTE */: + switch (format) { + case 0x1906 /* GL_ALPHA */: + case 0x1909 /* GL_LUMINANCE */: + sizePerPixel = 1; + break; + case 0x1907 /* GL_RGB */: + sizePerPixel = 3; + break; + case 0x1908 /* GL_RGBA */: + sizePerPixel = 4; + break; + case 0x190A /* GL_LUMINANCE_ALPHA */: + sizePerPixel = 2; + break; + default: + throw 'Invalid format (' + format + ')'; + } + break; + case 0x8363 /* GL_UNSIGNED_SHORT_5_6_5 */: + case 0x8033 /* GL_UNSIGNED_SHORT_4_4_4_4 */: + case 0x8034 /* GL_UNSIGNED_SHORT_5_5_5_1 */: + sizePerPixel = 2; + break; + case 0x1406 /* GL_FLOAT */: + assert(GL.floatExt, 'Must have OES_texture_float to use float textures'); + switch (format) { + case 0x1907 /* GL_RGB */: + sizePerPixel = 3*4; + break; + case 0x1908 /* GL_RGBA */: + sizePerPixel = 4*4; + break; + default: + throw 'Invalid format (' + format + ')'; + } + internalFormat = Module.ctx.RGBA; + break; + default: + throw 'Invalid type (' + type + ')'; + } + var bytes = GL.computeImageSize(width, height, sizePerPixel, GL.unpackAlignment); + if (type == 0x1401 /* GL_UNSIGNED_BYTE */) { + pixels = {{{ makeHEAPView('U8', 'pixels', 'pixels+bytes') }}}; + } else if (type == 0x1406 /* GL_FLOAT */) { + pixels = {{{ makeHEAPView('F32', 'pixels', 'pixels+bytes') }}}; + } else { + pixels = {{{ makeHEAPView('U16', 'pixels', 'pixels+bytes') }}}; + } + return { + pixels: pixels, + internalFormat: internalFormat + } + }, + + initExtensions: function() { + if (GL.initExtensions.done) return; + GL.initExtensions.done = true; + + GL.compressionExt = Module.ctx.getExtension('WEBGL_compressed_texture_s3tc') || + Module.ctx.getExtension('MOZ_WEBGL_compressed_texture_s3tc') || + Module.ctx.getExtension('WEBKIT_WEBGL_compressed_texture_s3tc'); + + GL.anisotropicExt = Module.ctx.getExtension('EXT_texture_filter_anisotropic') || + Module.ctx.getExtension('MOZ_EXT_texture_filter_anisotropic') || + Module.ctx.getExtension('WEBKIT_EXT_texture_filter_anisotropic'); + + GL.floatExt = Module.ctx.getExtension('OES_texture_float'); } }, + glPixelStorei: function(pname, param) { + if (pname == 0x0D05 /* GL_PACK_ALIGNMENT */) { + GL.packAlignment = param; + } else if (pname == 0x0cf5 /* GL_UNPACK_ALIGNMENT */) { + GL.unpackAlignment = param; + } + Module.ctx.pixelStorei(pname, param); + }, + glGetString: function(name_) { switch(name_) { case 0x1F00 /* GL_VENDOR */: @@ -62,12 +198,22 @@ var LibraryGL = { return allocate(intArrayFromString(Module.ctx.getParameter(name_)), 'i8', ALLOC_NORMAL); case 0x1F03 /* GL_EXTENSIONS */: return allocate(intArrayFromString(Module.ctx.getSupportedExtensions().join(' ')), 'i8', ALLOC_NORMAL); + case 0x8B8C /* GL_SHADING_LANGUAGE_VERSION */: + return allocate(intArrayFromString('OpenGL ES GLSL 1.00 (WebGL)'), 'i8', ALLOC_NORMAL); default: throw 'Failure: Invalid glGetString value: ' + name_; } }, glGetIntegerv: function(name_, p) { + switch(name_) { // Handle a few trivial GLES values + case 0x8DFA: // GL_SHADER_COMPILER + {{{ makeSetValue('p', '0', '1', 'i32') }}}; + return; + case 0x8DF9: // GL_NUM_SHADER_BINARY_FORMATS + {{{ makeSetValue('p', '0', '0', 'i32') }}}; + return; + } var result = Module.ctx.getParameter(name_); switch (typeof(result)) { case "number": @@ -205,104 +351,53 @@ var LibraryGL = { } }, - glCompressedTexImage2D: function(target, level, internalformat, width, height, border, imageSize, data) { + glCompressedTexImage2D: function(target, level, internalFormat, width, height, border, imageSize, data) { + assert(GL.compressionExt); if (data) { data = {{{ makeHEAPView('U8', 'data', 'data+imageSize') }}}; } else { data = null; } - Module.ctx.compressedTexImage2D(target, level, internalformat, width, height, border, data); + Module.ctx['compressedTexImage2D'](target, level, internalFormat, width, height, border, data); }, glCompressedTexSubImage2D: function(target, level, xoffset, yoffset, width, height, format, imageSize, data) { + assert(GL.compressionExt); if (data) { data = {{{ makeHEAPView('U8', 'data', 'data+imageSize') }}}; } else { data = null; } - Module.ctx.compressedTexSubImage2D(target, level, xoffset, yoffset, width, height, data); + Module.ctx['compressedTexSubImage2D'](target, level, xoffset, yoffset, width, height, data); }, - glTexImage2D: function(target, level, internalformat, width, height, border, format, type, pixels) { + glTexImage2D: function(target, level, internalFormat, width, height, border, format, type, pixels) { if (pixels) { - var sizePerPixel; - switch (type) { - case 0x1401 /* GL_UNSIGNED_BYTE */: - switch (format) { - case 0x1906 /* GL_ALPHA */: - case 0x1909 /* GL_LUMINANCE */: - sizePerPixel = 1; - break; - case 0x1907 /* GL_RGB */: - sizePerPixel = 3; - break; - case 0x1908 /* GL_RGBA */: - sizePerPixel = 4; - break; - case 0x190A /* GL_LUMINANCE_ALPHA */: - sizePerPixel = 2; - break; - default: - throw 'Invalid format (' + format + ') passed to glTexImage2D'; - } - pixels = {{{ makeHEAPView('U8', 'pixels', 'pixels+width*height*sizePerPixel') }}}; - break; - case 0x8363 /* GL_UNSIGNED_SHORT_5_6_5 */: - case 0x8033 /* GL_UNSIGNED_SHORT_4_4_4_4 */: - case 0x8034 /* GL_UNSIGNED_SHORT_5_5_5_1 */: - sizePerPixel = 2; - pixels = {{{ makeHEAPView('U16', 'pixels', 'pixels+width*height*sizePerPixel') }}}; - break; - default: - throw 'Invalid type (' + type + ') passed to glTexImage2D'; - } + var data = GL.getTexPixelData(type, format, width, height, pixels, internalFormat); + pixels = data.pixels; + internalFormat = data.internalFormat; } else { pixels = null; } - Module.ctx.texImage2D(target, level, internalformat, width, height, border, format, type, pixels); + Module.ctx.texImage2D(target, level, internalFormat, width, height, border, format, type, pixels); }, glTexSubImage2D: function(target, level, xoffset, yoffset, width, height, format, type, pixels) { if (pixels) { - var sizePerPixel; - switch (type) { - case 0x1401 /* GL_UNSIGNED_BYTE */: - switch (format) { - case 0x1906 /* GL_ALPHA */: - case 0x1909 /* GL_LUMINANCE */: - sizePerPixel = 1; - break; - case 0x1907 /* GL_RGB */: - sizePerPixel = 3; - break; - case 0x1908 /* GL_RGBA */: - sizePerPixel = 4; - break; - case 0x190A /* GL_LUMINANCE_ALPHA */: - sizePerPixel = 2; - break; - default: - throw 'Invalid format (' + format + ') passed to glTexSubImage2D'; - } - pixels = {{{ makeHEAPView('U8', 'pixels', 'pixels+width*height*sizePerPixel') }}}; - break; - case 0x8363 /* GL_UNSIGNED_SHORT_5_6_5 */: - case 0x8033 /* GL_UNSIGNED_SHORT_4_4_4_4 */: - case 0x8034 /* GL_UNSIGNED_SHORT_5_5_5_1 */: - sizePerPixel = 2; - pixels = {{{ makeHEAPView('U16', 'pixels', 'pixels+width*height*sizePerPixel') }}}; - break; - default: - throw 'Invalid type (' + type + ') passed to glTexSubImage2D'; - } + var data = GL.getTexPixelData(type, format, width, height, pixels, -1); + pixels = data.pixels; } else { pixels = null; } Module.ctx.texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); }, + glReadPixels: function(x, y, width, height, format, type, pixels) { + Module.ctx.readPixels(x, y, width, height, format, type, HEAPU8.subarray(pixels)); + }, + glBindTexture: function(target, texture) { - Module.ctx.bindTexture(target, GL.textures[texture]); + Module.ctx.bindTexture(target, texture ? GL.textures[texture] : null); }, glGetTexParameterfv: function(target, pname, params) { @@ -316,7 +411,7 @@ var LibraryGL = { glIsTexture: function(texture) { var fb = GL.textures[texture]; if (typeof(fb) == 'undefined') { - return false; + return 0; } return Module.ctx.isTexture(fb); }, @@ -337,6 +432,10 @@ var LibraryGL = { } }, + glGetBufferParameteriv: function(target, value, data) { + {{{ makeSetValue('data', '0', 'Module.ctx.getBufferParameter(target, value)', 'i32') }}}; + }, + glBufferData: function(target, size, data, usage) { Module.ctx.bufferData(target, HEAPU8.subarray(data, data+size), usage); }, @@ -349,7 +448,7 @@ var LibraryGL = { glIsBuffer: function(buffer) { var fb = GL.buffers[buffer]; if (typeof(fb) == 'undefined') { - return false; + return 0; } return Module.ctx.isBuffer(fb); }, @@ -371,7 +470,7 @@ var LibraryGL = { }, glBindRenderbuffer: function(target, renderbuffer) { - Module.ctx.bindRenderbuffer(target, GL.renderbuffers[renderbuffer]); + Module.ctx.bindRenderbuffer(target, renderbuffer ? GL.renderbuffers[renderbuffer] : null); }, glGetRenderbufferParameteriv: function(target, pname, params) { @@ -381,11 +480,33 @@ var LibraryGL = { glIsRenderbuffer: function(renderbuffer) { var fb = GL.renderbuffers[renderbuffer]; if (typeof(fb) == 'undefined') { - return false; + return 0; } return Module.ctx.isRenderbuffer(fb); }, + glGetUniformfv: function(program, location, params) { + var data = Module.ctx.getUniform(GL.programs[program], GL.uniforms[location]); + if (typeof data == 'number') { + {{{ makeSetValue('params', '0', 'data', 'float') }}}; + } else { + for (var i = 0; i < data.length; i++) { + {{{ makeSetValue('params', 'i', 'data[i]', 'float') }}}; + } + } + }, + + glGetUniformiv: function(program, location, params) { + var data = Module.ctx.getUniform(GL.programs[program], GL.uniforms[location]); + if (typeof data == 'number' || typeof data == 'boolean') { + {{{ makeSetValue('params', '0', 'data', 'i32') }}}; + } else { + for (var i = 0; i < data.length; i++) { + {{{ makeSetValue('params', 'i', 'data[i]', 'i32') }}}; + } + } + }, + glGetUniformLocation: function(program, name) { name = Pointer_stringify(name); var loc = Module.ctx.getUniformLocation(GL.programs[program], name); @@ -395,11 +516,37 @@ var LibraryGL = { return id; }, + glGetVertexAttribfv: function(index, pname, params) { + var data = Module.ctx.getVertexAttrib(index, pname); + if (typeof data == 'number') { + {{{ makeSetValue('params', '0', 'data', 'float') }}}; + } else { + for (var i = 0; i < data.length; i++) { + {{{ makeSetValue('params', 'i', 'data[i]', 'float') }}}; + } + } + }, + + glGetVertexAttribiv: function(index, pname, params) { + var data = Module.ctx.getVertexAttrib(index, pname); + if (typeof data == 'number' || typeof data == 'boolean') { + {{{ makeSetValue('params', '0', 'data', 'i32') }}}; + } else { + for (var i = 0; i < data.length; i++) { + {{{ makeSetValue('params', 'i', 'data[i]', 'i32') }}}; + } + } + }, + + glGetVertexAttribPointerv: function(index, pname, pointer) { + {{{ makeSetValue('pointer', '0', 'Module.ctx.getVertexAttribOffset(index, pname)', 'i32') }}}; + }, + glGetActiveUniform: function(program, index, bufSize, length, size, type, name) { program = GL.programs[program]; var info = Module.ctx.getActiveUniform(program, index); - var infoname = info.name.slice(0, bufsize - 1); + var infoname = info.name.slice(0, bufSize - 1); writeStringToMemory(infoname, name); if (length) { @@ -529,7 +676,7 @@ var LibraryGL = { }, glBindBuffer: function(target, buffer) { - Module.ctx.bindBuffer(target, GL.buffers[buffer]); + Module.ctx.bindBuffer(target, buffer ? GL.buffers[buffer] : null); }, glVertexAttrib1fv: function(index, v) { @@ -562,7 +709,7 @@ var LibraryGL = { program = GL.programs[program]; var info = Module.ctx.getActiveAttrib(program, index); - var infoname = info.name.slice(0, bufsize - 1); + var infoname = info.name.slice(0, bufSize - 1); writeStringToMemory(infoname, name); if (length) { @@ -605,42 +752,13 @@ var LibraryGL = { }, glShaderSource: function(shader, count, string, length) { - var source = ""; - for (var i = 0; i < count; ++i) { - var frag; - if (length) { - var len = {{{ makeGetValue('length', 'i*4', 'i32') }}}; - if (len < 0) { - frag = Pointer_stringify({{{ makeGetValue('string', 'i*4', 'i32') }}}); - } else { - frag = Pointer_stringify({{{ makeGetValue('string', 'i*4', 'i32') }}}, len); - } - } else { - frag = Pointer_stringify({{{ makeGetValue('string', 'i*4', 'i32') }}}); - } - source += frag; - } - // Let's see if we need to enable the standard derivatives extension - type = Module.ctx.getShaderParameter(GL.shaders[shader], 0x8B4F /* GL_SHADER_TYPE */); - if (type == 0x8B30 /* GL_FRAGMENT_SHADER */) { - if (GL.findToken(source, "dFdx") || - GL.findToken(source, "dFdy") || - GL.findToken(source, "fwidth")) { - source = "#extension GL_OES_standard_derivatives : enable\n" + source; - var extension = Module.ctx.getExtension("OES_standard_derivatives"); -#if GL_DEBUG - if (!extension) { - Module.printErr("Shader attempts to use the standard derivatives extension which is not available."); - } -#endif - } - } + var source = GL.getSource(shader, count, string, length); Module.ctx.shaderSource(GL.shaders[shader], source); }, - glGetShaderSource: function(shader, bufsize, length, source) { + glGetShaderSource: function(shader, bufSize, length, source) { var result = Module.ctx.getShaderSource(GL.shaders[shader]); - result.slice(0, bufsize - 1); + result.slice(0, bufSize - 1); writeStringToMemory(result, source); if (length) { {{{ makeSetValue('length', '0', 'result.length', 'i32') }}}; @@ -665,17 +783,25 @@ var LibraryGL = { }, glGetShaderiv : function(shader, pname, p) { - {{{ makeSetValue('p', '0', 'Module.ctx.getShaderParameter(GL.shaders[shader], pname)', 'i32') }}}; + if (pname == 0x8B84) { // GL_INFO_LOG_LENGTH + {{{ makeSetValue('p', '0', 'Module.ctx.getShaderInfoLog(GL.shaders[shader]).length + 1', 'i32') }}}; + } else { + {{{ makeSetValue('p', '0', 'Module.ctx.getShaderParameter(GL.shaders[shader], pname)', 'i32') }}}; + } }, glGetProgramiv : function(program, pname, p) { - {{{ makeSetValue('p', '0', 'Module.ctx.getProgramParameter(GL.programs[program], pname)', 'i32') }}}; + if (pname == 0x8B84) { // GL_INFO_LOG_LENGTH + {{{ makeSetValue('p', '0', 'Module.ctx.getProgramInfoLog(GL.programs[program]).length + 1', 'i32') }}}; + } else { + {{{ makeSetValue('p', '0', 'Module.ctx.getProgramParameter(GL.programs[program], pname)', 'i32') }}}; + } }, glIsShader: function(shader) { var fb = GL.shaders[shader]; if (typeof(fb) == 'undefined') { - return false; + return 0; } return Module.ctx.isShader(fb); }, @@ -721,7 +847,7 @@ var LibraryGL = { }, glUseProgram: function(program) { - Module.ctx.useProgram(GL.programs[program]); + Module.ctx.useProgram(program ? GL.programs[program] : null); }, glValidateProgram: function(program) { @@ -731,7 +857,7 @@ var LibraryGL = { glIsProgram: function(program) { var fb = GL.programs[program]; if (typeof(fb) == 'undefined') { - return false; + return 0; } return Module.ctx.isProgram(fb); }, @@ -742,7 +868,7 @@ var LibraryGL = { }, glBindFramebuffer: function(target, framebuffer) { - Module.ctx.bindFramebuffer(target, GL.framebuffers[framebuffer]); + Module.ctx.bindFramebuffer(target, framebuffer ? GL.framebuffers[framebuffer] : null); }, glGenFramebuffers: function(n, ids) { @@ -779,57 +905,452 @@ var LibraryGL = { glIsFramebuffer: function(framebuffer) { var fb = GL.framebuffers[framebuffer]; if (typeof(fb) == 'undefined') { - return false; + return 0; } return Module.ctx.isFramebuffer(fb); }, // GL emulation: provides misc. functionality not present in OpenGL ES 2.0 or WebGL - $GLEmulation__deps: ['glCreateShader', 'glShaderSource', 'glCompileShader', 'glCreateProgram', 'glDeleteShader', 'glDeleteProgram', 'glAttachShader', 'glActiveTexture', 'glGetShaderiv', 'glGetProgramiv', 'glLinkProgram'], + $GLEmulation__postset: 'GLEmulation.init();', $GLEmulation: { - procReplacements: { - 'glCreateShaderObjectARB': 'glCreateShader', - 'glShaderSourceARB': 'glShaderSource', - 'glCompileShaderARB': 'glCompileShader', - 'glCreateProgramObjectARB': 'glCreateProgram', - 'glAttachObjectARB': 'glAttachShader', - 'glLinkProgramARB': 'glLinkProgram', - 'glActiveTextureARB': 'glActiveTexture' - }, + // Fog support. Partial, we assume shaders are used that implement fog. We just pass them uniforms + fogStart: 0, + fogEnd: 1, + fogDensity: 1.0, + fogColor: null, + fogMode: 0x0800, // GL_EXP + fogEnabled: false, + + init: function() { + GLEmulation.fogColor = new Float32Array(4); + + // Add some emulation workarounds + Module.printErr('WARNING: using emscripten GL emulation. This is a collection of limited workarounds, do not expect it to work'); + + // XXX some of the capabilities we don't support may lead to incorrect rendering, if we do not emulate them in shaders + var validCapabilities = { + 0x0B44: 1, // GL_CULL_FACE + 0x0BE2: 1, // GL_BLEND + 0x0BD0: 1, // GL_DITHER, + 0x0B90: 1, // GL_STENCIL_TEST + 0x0B71: 1, // GL_DEPTH_TEST + 0x0C11: 1, // GL_SCISSOR_TEST + 0x8037: 1, // GL_POLYGON_OFFSET_FILL + 0x809E: 1, // GL_SAMPLE_ALPHA_TO_COVERAGE + 0x80A0: 1 // GL_SAMPLE_COVERAGE + }; + _glEnable = function(cap) { + // Clean up the renderer on any change to the rendering state. The optimization of + // skipping renderer setup is aimed at the case of multiple glDraw* right after each other + if (GL.immediate.lastRenderer) GL.immediate.lastRenderer.cleanup(); + if (cap == 0x0B60 /* GL_FOG */) { + GLEmulation.fogEnabled = true; + return; + } else if (!(cap in validCapabilities)) { + return; + } + Module.ctx.enable(cap); + }; + _glDisable = function(cap) { + if (GL.immediate.lastRenderer) GL.immediate.lastRenderer.cleanup(); + if (cap == 0x0B60 /* GL_FOG */) { + GLEmulation.fogEnabled = false; + return; + } else if (!(cap in validCapabilities)) { + return; + } + Module.ctx.disable(cap); + }; + _glIsEnabled = function(cap) { + if (cap == 0x0B60 /* GL_FOG */) { + return GLEmulation.fogEnabled ? 1 : 0; + } else if (!(cap in validCapabilities)) { + return 0; + } + return Module.ctx.isEnabled(cap); + }; + + var glGetIntegerv = _glGetIntegerv; + _glGetIntegerv = function(pname, params) { + switch (pname) { + case 0x84E2: pname = Module.ctx.MAX_TEXTURE_IMAGE_UNITS /* fake it */; break; // GL_MAX_TEXTURE_UNITS + case 0x8B4A: { // GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB + var result = Module.ctx.getParameter(Module.ctx.MAX_VERTEX_UNIFORM_VECTORS); + {{{ makeSetValue('params', '0', 'result*4', 'i32') }}}; // GLES gives num of 4-element vectors, GL wants individual components, so multiply + return; + } + case 0x8B49: { // GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB + var result = Module.ctx.getParameter(Module.ctx.MAX_FRAGMENT_UNIFORM_VECTORS); + {{{ makeSetValue('params', '0', 'result*4', 'i32') }}}; // GLES gives num of 4-element vectors, GL wants individual components, so multiply + return; + } + case 0x8B4B: { // GL_MAX_VARYING_FLOATS_ARB + var result = Module.ctx.getParameter(Module.ctx.MAX_VARYING_VECTORS); + {{{ makeSetValue('params', '0', 'result*4', 'i32') }}}; // GLES gives num of 4-element vectors, GL wants individual components, so multiply + return; + } + case 0x8871: pname = Module.ctx.MAX_COMBINED_TEXTURE_IMAGE_UNITS /* close enough */; break; // GL_MAX_TEXTURE_COORDS + } + glGetIntegerv(pname, params); + }; + + var glGetString = _glGetString; + _glGetString = function(name_) { + switch(name_) { + case 0x1F03 /* GL_EXTENSIONS */: // Add various extensions that we can support + return allocate(intArrayFromString(Module.ctx.getSupportedExtensions().join(' ') + + ' GL_EXT_texture_env_combine GL_ARB_texture_env_crossbar GL_ATI_texture_env_combine3 GL_NV_texture_env_combine4 GL_EXT_texture_env_dot3 GL_ARB_multitexture GL_ARB_vertex_buffer_object GL_EXT_framebuffer_object GL_ARB_vertex_program GL_ARB_fragment_program GL_ARB_shading_language_100 GL_ARB_shader_objects GL_ARB_vertex_shader GL_ARB_fragment_shader GL_ARB_texture_cube_map GL_EXT_draw_range_elements' + + (GL.compressionExt ? ' GL_ARB_texture_compression GL_EXT_texture_compression_s3tc' : '') + + (GL.anisotropicExt ? ' GL_EXT_texture_filter_anisotropic' : '') + ), 'i8', ALLOC_NORMAL); + } + return glGetString(name_); + }; - procs: { - glDeleteObjectARB: function(id) { - if (GL.programs[id]) { - _glDeleteProgram(id); - } else if (GL.shaders[id]) { - _glDeleteShader(id); - } else { - console.log('WARNING: deleteObjectARB received invalid id: ' + id); + // Do some automatic rewriting to work around GLSL differences. Note that this must be done in + // tandem with the rest of the program, by itself it cannot suffice. + // Note that we need to remember shader types for this rewriting, saving sources makes it easier to debug. + GL.shaderInfos = {}; +#if GL_DEBUG + GL.shaderSources = {}; + GL.shaderOriginalSources = {}; +#endif + var glCreateShader = _glCreateShader; + _glCreateShader = function(shaderType) { + var id = glCreateShader(shaderType); + GL.shaderInfos[id] = { + type: shaderType, + ftransform: false + }; + return id; + }; + + var glShaderSource = _glShaderSource; + _glShaderSource = function(shader, count, string, length) { + var source = GL.getSource(shader, count, string, length); +#if GL_DEBUG + GL.shaderOriginalSources[shader] = source; +#endif + // XXX We add attributes and uniforms to shaders. The program can ask for the # of them, and see the + // ones we generated, potentially confusing it? Perhaps we should hide them. + if (GL.shaderInfos[shader].type == Module.ctx.VERTEX_SHADER) { + // Replace ftransform() with explicit project/modelview transforms, and add position and matrix info. + var has_pm = source.search(/u_projection/) >= 0; + var has_mm = source.search(/u_modelView/) >= 0; + var has_pv = source.search(/a_position/) >= 0; + var need_pm = 0, need_mm = 0, need_pv = 0; + var old = source; + source = source.replace(/ftransform\(\)/g, '(u_projection * u_modelView * a_position)'); + if (old != source) need_pm = need_mm = need_pv = 1; + old = source; + source = source.replace(/gl_ProjectionMatrix/g, 'u_projection'); + if (old != source) need_pm = 1; + old = source; + source = source.replace(/gl_ModelViewMatrixTranspose\[2\]/g, 'vec4(u_modelView[0][2], u_modelView[1][2], u_modelView[2][2], u_modelView[3][2])'); // XXX extremely inefficient + if (old != source) need_mm = 1; + old = source; + source = source.replace(/gl_ModelViewMatrix/g, 'u_modelView'); + if (old != source) need_mm = 1; + old = source; + source = source.replace(/gl_Vertex/g, 'a_position'); + if (old != source) need_pv = 1; + old = source; + source = source.replace(/gl_ModelViewProjectionMatrix/g, '(u_projection * u_modelView)'); + if (old != source) need_pm = need_mm = 1; + if (need_pv && !has_pv) source = 'attribute vec4 a_position; \n' + source; + if (need_mm && !has_mm) source = 'uniform mat4 u_modelView; \n' + source; + if (need_pm && !has_pm) source = 'uniform mat4 u_projection; \n' + source; + GL.shaderInfos[shader].ftransform = need_pm || need_mm || need_pv; // we will need to provide the fixed function stuff as attributes and uniforms + for (var i = 0; i < GL.immediate.MAX_TEXTURES; i++) { + // XXX To handle both regular texture mapping and cube mapping, we use vec4 for tex coordinates. + var old = source; + var need_vtc = source.search('v_texCoord' + i) == -1; + source = source.replace(new RegExp('gl_TexCoord\\[' + i + '\\]', 'g'), 'v_texCoord' + i) + .replace(new RegExp('gl_MultiTexCoord' + i, 'g'), 'a_texCoord' + i); + if (source != old) { + source = 'attribute vec4 a_texCoord' + i + '; \n' + source; + if (need_vtc) { + source = 'varying vec4 v_texCoord' + i + '; \n' + source; + } + } + + old = source; + source = source.replace(new RegExp('gl_TextureMatrix\\[' + i + '\\]', 'g'), 'u_textureMatrix' + i); + if (source != old) { + source = 'uniform mat4 u_textureMatrix' + i + '; \n' + source; + } + } + if (source.indexOf('gl_FrontColor') >= 0) { + source = 'varying vec4 v_color; \n' + + source.replace(/gl_FrontColor/g, 'v_color'); + } + if (source.indexOf('gl_Color') >= 0) { + source = 'attribute vec4 a_color; \n' + + 'uniform vec4 u_color; \n' + + 'uniform int u_hasColorAttrib; \n' + + source.replace(/gl_Color/g, '(u_hasColorAttrib > 0 ? a_color : u_color)'); + } + if (source.indexOf('gl_Normal') >= 0) { + source = 'attribute vec3 a_normal; \n' + + source.replace(/gl_Normal/g, 'a_normal'); + } + // fog + if (source.indexOf('gl_FogFragCoord') >= 0) { + source = 'varying float v_fogFragCoord; \n' + + source.replace(/gl_FogFragCoord/g, 'v_fogFragCoord'); + } + } else { // Fragment shader + for (var i = 0; i < GL.immediate.MAX_TEXTURES; i++) { + var old = source; + source = source.replace(new RegExp('gl_TexCoord\\[' + i + '\\]', 'g'), 'v_texCoord' + i); + if (source != old) { + source = 'varying vec4 v_texCoord' + i + '; \n' + source; + } + } + if (source.indexOf('gl_Color') >= 0) { + source = 'varying vec4 v_color; \n' + source.replace(/gl_Color/g, 'v_color'); + } + if (source.indexOf('gl_Fog.color') >= 0) { + source = 'uniform vec4 u_fogColor; \n' + + source.replace(/gl_Fog.color/g, 'u_fogColor'); + } + if (source.indexOf('gl_Fog.end') >= 0) { + source = 'uniform float u_fogEnd; \n' + + source.replace(/gl_Fog.end/g, 'u_fogEnd'); + } + if (source.indexOf('gl_Fog.scale') >= 0) { + source = 'uniform float u_fogScale; \n' + + source.replace(/gl_Fog.scale/g, 'u_fogScale'); + } + if (source.indexOf('gl_Fog.density') >= 0) { + source = 'uniform float u_fogDensity; \n' + + source.replace(/gl_Fog.density/g, 'u_fogDensity'); + } + if (source.indexOf('gl_FogFragCoord') >= 0) { + source = 'varying float v_fogFragCoord; \n' + + source.replace(/gl_FogFragCoord/g, 'v_fogFragCoord'); + } + source = 'precision mediump float;\n' + source; } - }, +#if GL_DEBUG + GL.shaderSources[shader] = source; +#endif + Module.ctx.shaderSource(GL.shaders[shader], source); + }; + + var glCompileShader = _glCompileShader; + _glCompileShader = function(shader) { + Module.ctx.compileShader(GL.shaders[shader]); + if (!Module.ctx.getShaderParameter(GL.shaders[shader], Module.ctx.COMPILE_STATUS)) { + Module.printErr('Failed to compile shader: ' + Module.ctx.getShaderInfoLog(GL.shaders[shader])); + Module.printErr('Info: ' + JSON.stringify(GL.shaderInfos[shader])); +#if GL_DEBUG + Module.printErr('Original source: ' + GL.shaderOriginalSources[shader]); + Module.printErr('Source: ' + GL.shaderSources[shader]); + throw 'Shader compilation halt'; +#else + Module.printErr('Enable GL_DEBUG to see shader source'); +#endif + } + }; + + GL.programShaders = {}; + var glAttachShader = _glAttachShader; + _glAttachShader = function(program, shader) { + if (!GL.programShaders[program]) GL.programShaders[program] = []; + GL.programShaders[program].push(shader); + glAttachShader(program, shader); + }; + + var glUseProgram = _glUseProgram; + _glUseProgram = function(program) { +#if GL_DEBUG + if (GL.debug) { + Module.printErr('[using program with shaders]'); + if (program) { + GL.programShaders[program].forEach(function(shader) { + Module.printErr(' shader ' + shader + ', original source: ' + GL.shaderOriginalSources[shader]); + Module.printErr(' Source: ' + GL.shaderSources[shader]); + }); + } + } +#endif + GL.currProgram = program; + glUseProgram(program); + } - glGetObjectParameterivARB: function(id, type, result) { - if (GL.programs[id]) { - _glGetProgramiv(id, type, result); - } else if (GL.shaders[id]) { - _glGetShaderiv(id, type, result); + var glDeleteProgram = _glDeleteProgram; + _glDeleteProgram = function(program) { + glDeleteProgram(program); + if (program == GL.currProgram) GL.currProgram = 0; + }; + + // If attribute 0 was not bound, bind it to 0 for WebGL performance reasons. Track if 0 is free for that. + var zeroUsedPrograms = {}; + var glBindAttribLocation = _glBindAttribLocation; + _glBindAttribLocation = function(program, index, name) { + if (index == 0) zeroUsedPrograms[program] = true; + glBindAttribLocation(program, index, name); + }; + var glLinkProgram = _glLinkProgram; + _glLinkProgram = function(program) { + if (!(program in zeroUsedPrograms)) { + Module.ctx.bindAttribLocation(GL.programs[program], 0, 'a_position'); + } + glLinkProgram(program); + }; + + var glBindBuffer = _glBindBuffer; + _glBindBuffer = function(target, buffer) { + glBindBuffer(target, buffer); + if (target == Module.ctx.ARRAY_BUFFER) { + GL.currArrayBuffer = buffer; + } else if (target == Module.ctx.ELEMENT_ARRAY_BUFFER) { + GL.currElementArrayBuffer = buffer; + } + }; + + var glDeleteBuffers = _glDeleteBuffers; + _glDeleteBuffers = function(n, buffers) { + glDeleteBuffers(n, buffers); + for (var i = 0; i < n; i++) { + var buffer = {{{ makeGetValue('buffers', 'i*4', 'i32') }}}; + if (buffer == GL.currArrayBuffer) GL.currArrayBuffer = 0; + if (buffer == GL.currElementArrayBuffer) GL.currElementArrayBuffer = 0; + } + }; + + var glGetFloatv = _glGetFloatv; + _glGetFloatv = function(pname, params) { + if (pname == 0x0BA6) { // GL_MODELVIEW_MATRIX + HEAPF32.set(GL.immediate.matrix['m'], params >> 2); + } else if (pname == 0x0BA7) { // GL_PROJECTION_MATRIX + HEAPF32.set(GL.immediate.matrix['p'], params >> 2); + } else if (pname == 0x0BA8) { // GL_TEXTURE_MATRIX + HEAPF32.set(GL.immediate.matrix['t' + GL.immediate.clientActiveTexture], params >> 2); + } else if (pname == 0x0B66) { // GL_FOG_COLOR + HEAPF32.set(GLEmulation.fogColor, params >> 2); + } else if (pname == 0x0B63) { // GL_FOG_START + {{{ makeSetValue('params', '0', 'GLEmulation.fogStart', 'float') }}}; + } else if (pname == 0x0B64) { // GL_FOG_END + {{{ makeSetValue('params', '0', 'GLEmulation.fogEnd', 'float') }}}; + } else if (pname == 0x0B62) { // GL_FOG_DENSITY + {{{ makeSetValue('params', '0', 'GLEmulation.fogDensity', 'float') }}}; + } else if (pname == 0x0B65) { // GL_FOG_MODE + {{{ makeSetValue('params', '0', 'GLEmulation.fogMode', 'float') }}}; } else { - console.log('WARNING: getObjectParameterivARB received invalid id: ' + id); + glGetFloatv(pname, params); + } + }; + + var glHint = _glHint; + _glHint = function(target, mode) { + if (target == 0x84EF) { // GL_TEXTURE_COMPRESSION_HINT + return; } - }, + glHint(target, mode); + }; }, - getProcAddress: function(name_) { - name_ = GLEmulation.procReplacements[name_] || name_; - var func = GLEmulation.procs[name_]; - if (!func) { - try { - func = eval('_' + name_); - } catch(e) { - console.log('WARNING: getProcAddress failed for ' + name_); + getProcAddress: function(name) { + name = name.replace('EXT', '').replace('ARB', ''); + // Do the translation carefully because of closure + switch (name) { + case 'glCreateShaderObject': case 'glCreateShader': func = _glCreateShader; break; + case 'glCreateProgramObject': case 'glCreateProgram': func = _glCreateProgram; break; + case 'glAttachObject': case 'glAttachShader': func = _glAttachShader; break; + case 'glUseProgramObject': case 'glUseProgram': func = _glUseProgram; break; + case 'glDeleteObject': func = function(id) { + if (GL.programs[id]) { + _glDeleteProgram(id); + } else if (GL.shaders[id]) { + _glDeleteShader(id); + } else { + Module.printErr('WARNING: deleteObject received invalid id: ' + id); + } + }; break; + case 'glGetObjectParameteriv': func = function(id, type, result) { + if (GL.programs[id]) { + if (type == 0x8B84) { // GL_OBJECT_INFO_LOG_LENGTH_ARB + {{{ makeSetValue('result', '0', 'Module.ctx.getProgramInfoLog(GL.programs[id]).length', 'i32') }}}; + return; + } + _glGetProgramiv(id, type, result); + } else if (GL.shaders[id]) { + if (type == 0x8B84) { // GL_OBJECT_INFO_LOG_LENGTH_ARB + {{{ makeSetValue('result', '0', 'Module.ctx.getShaderInfoLog(GL.shaders[id]).length', 'i32') }}}; + return; + } + _glGetShaderiv(id, type, result); + } else { + Module.printErr('WARNING: getObjectParameteriv received invalid id: ' + id); + } + }; break; + case 'glGetInfoLog': func = function(id, maxLength, length, infoLog) { + if (GL.programs[id]) { + _glGetProgramInfoLog(id, maxLength, length, infoLog); + } else if (GL.shaders[id]) { + _glGetShaderInfoLog(id, maxLength, length, infoLog); + } else { + Module.printErr('WARNING: getObjectParameteriv received invalid id: ' + id); + } + }; break; + case 'glBindProgram': func = function(type, id) { + assert(id == 0); + }; break; + case 'glDrawRangeElements': func = _glDrawRangeElements; break; + case 'glShaderSource': func = _glShaderSource; break; + case 'glCompileShader': func = _glCompileShader; break; + case 'glLinkProgram': func = _glLinkProgram; break; + case 'glGetUniformLocation': func = _glGetUniformLocation; break; + case 'glUniform1f': func = _glUniform1f; break; + case 'glUniform2f': func = _glUniform2f; break; + case 'glUniform3f': func = _glUniform3f; break; + case 'glUniform4f': func = _glUniform4f; break; + case 'glUniform1fv': func = _glUniform1fv; break; + case 'glUniform2fv': func = _glUniform2fv; break; + case 'glUniform3fv': func = _glUniform3fv; break; + case 'glUniform4fv': func = _glUniform4fv; break; + case 'glUniform1i': func = _glUniform1i; break; + case 'glUniform2i': func = _glUniform2i; break; + case 'glUniform3i': func = _glUniform3i; break; + case 'glUniform4i': func = _glUniform4i; break; + case 'glUniform1iv': func = _glUniform1iv; break; + case 'glUniform2iv': func = _glUniform2iv; break; + case 'glUniform3iv': func = _glUniform3iv; break; + case 'glUniform4iv': func = _glUniform4iv; break; + case 'glBindAttribLocation': func = _glBindAttribLocation; break; + case 'glGetActiveUniform': func = _glGetActiveUniform; break; + case 'glGenBuffers': func = _glGenBuffers; break; + case 'glBindBuffer': func = _glBindBuffer; break; + case 'glBufferData': func = _glBufferData; break; + case 'glBufferSubData': func = _glBufferSubData; break; + case 'glDeleteBuffers': func = _glDeleteBuffers; break; + case 'glActiveTexture': func = _glActiveTexture; break; + case 'glClientActiveTexture': func = _glClientActiveTexture; break; + case 'glGetProgramiv': func = _glGetProgramiv; break; + case 'glEnableVertexAttribArray': func = _glEnableVertexAttribArray; break; + case 'glDisableVertexAttribArray': func = _glDisableVertexAttribArray; break; + case 'glVertexAttribPointer': func = _glVertexAttribPointer; break; + case 'glBindRenderbuffer': func = _glBindRenderbuffer; break; + case 'glDeleteRenderbuffers': func = _glDeleteRenderbuffers; break; + case 'glGenRenderbuffers': func = _glGenRenderbuffers; break; + case 'glCompressedTexImage2D': func = _glCompressedTexImage2D; break; + case 'glCompressedTexSubImage2D': func = _glCompressedTexSubImage2D; break; + case 'glBindFramebuffer': func = _glBindFramebuffer; break; + case 'glGenFramebuffers': func = _glGenFramebuffers; break; + case 'glDeleteFramebuffers': func = _glDeleteFramebuffers; break; + case 'glFramebufferRenderbuffer': func = _glFramebufferRenderbuffer; break; + case 'glFramebufferTexture2D': func = _glFramebufferTexture2D; break; + case 'glGetFramebufferAttachmentParameteriv': func = _glGetFramebufferAttachmentParameteriv; break; + case 'glIsFramebuffer': func = _glIsFramebuffer; break; + case 'glCheckFramebufferStatus': func = _glCheckFramebufferStatus; break; + case 'glRenderbufferStorage': func = _glRenderbufferStorage; break; + default: { + Module.printErr('WARNING: getProcAddress failed for ' + name); func = function() { - console.log('WARNING: empty replacement for ' + name_ + ' called, no-op'); + Module.printErr('WARNING: empty replacement for ' + name + ' called, no-op'); return 0; }; } @@ -838,32 +1359,1122 @@ var LibraryGL = { } }, - glBegin__deps: ['$GL', function() { return 'GL.matrix.lib = ' + read('gl-matrix.js') }], - glBegin: function() { - Module.print('TODO'); + // GL Immediate mode + + $GLImmediate__postset: 'Browser.moduleContextCreatedCallbacks.push(function() { GL.immediate.init() });', + $GLImmediate__deps: ['$Browser'], + $GLImmediate: { + MAX_TEXTURES: 7, + + // Vertex and index data + vertexData: null, // current vertex data. either tempData (glBegin etc.) or a view into the heap (gl*Pointer). Default view is F32 + vertexDataU8: null, // U8 view + tempData: null, + indexData: null, + vertexCounter: 0, + mode: 0, + + rendererCache: {}, + rendererComponents: {}, // small cache for calls inside glBegin/end. counts how many times the element was seen + rendererComponentPointer: 0, // next place to start a glBegin/end component + lastRenderer: null, // used to avoid cleaning up and re-preparing the same renderer + lastArrayBuffer: null, // used in conjunction with lastRenderer + lastProgram: null, // "" + + // The following data structures are used for OpenGL Immediate Mode matrix routines. + matrix: {}, + matrixStack: {}, + currentMatrix: 'm', // default is modelview + tempMatrix: null, + matricesModified: false, + + // Clientside attributes + VERTEX: 0, + NORMAL: 1, + COLOR: 2, + TEXTURE0: 3, + TEXTURE1: 4, + TEXTURE2: 5, + TEXTURE3: 6, + TEXTURE4: 7, + TEXTURE5: 8, + TEXTURE6: 9, + NUM_ATTRIBUTES: 10, + NUM_TEXTURES: 7, + ATTRIBUTE_BY_NAME: {}, + + totalEnabledClientAttributes: 0, + enabledClientAttributes: [0, 0], + clientAttributes: [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}], // raw data, including possible unneeded ones + liveClientAttributes: [], // the ones actually alive in the current computation, sorted + modifiedClientAttributes: false, + clientActiveTexture: 0, + clientColor: null, + + byteSizeByType: { + 0x1400: 1, // GL_BYTE + 0x1401: 1, // GL_UNSIGNED_BYTE + 0x1402: 2, // GL_SHORT + 0x1403: 2, // GL_UNSIGNED_SHORT + 0x1404: 4, // GL_INT + 0x1405: 4, // GL_UNSIGNED_INT + 0x1406: 4 // GL_FLOAT + }, + + setClientAttribute: function(name, size, type, stride, pointer) { + var attrib = this.clientAttributes[GL.immediate.ATTRIBUTE_BY_NAME[name]]; + attrib.name = name; + attrib.size = size; + attrib.type = type; + attrib.stride = stride; + attrib.pointer = pointer; + this.modifiedClientAttributes = true; + }, + + // Temporary buffers + MAX_TEMP_BUFFER_SIZE: 2*1024*1024, + tempBufferIndexLookup: null, + tempVertexBuffers: null, + tempIndexBuffers: null, + tempQuadIndexBuffer: null, + + generateTempBuffers: function() { + function ceilPower2(x) { + return Math.pow(2, Math.ceil(Math.log(i || 1)/Math.log(2))); + } + this.tempBufferIndexLookup = new Uint8Array(this.MAX_TEMP_BUFFER_SIZE+1); + var last = -1, curr = -1; + for (var i = 0; i <= this.MAX_TEMP_BUFFER_SIZE; i++) { + var size = ceilPower2(i); + if (size != last) { + curr++; + last = size; + } + this.tempBufferIndexLookup[i] = curr; + } + this.tempVertexBuffers = []; + this.tempIndexBuffers = []; + last = -1; + for (var i = 0; i <= this.MAX_TEMP_BUFFER_SIZE; i++) { + var size = ceilPower2(i); + curr = this.tempBufferIndexLookup[i]; + if (size != last) { + this.tempVertexBuffers[curr] = Module.ctx.createBuffer(); + Module.ctx.bindBuffer(Module.ctx.ARRAY_BUFFER, this.tempVertexBuffers[curr]); + Module.ctx.bufferData(Module.ctx.ARRAY_BUFFER, size, Module.ctx.DYNAMIC_DRAW); + Module.ctx.bindBuffer(Module.ctx.ARRAY_BUFFER, null); + this.tempIndexBuffers[curr] = Module.ctx.createBuffer(); + Module.ctx.bindBuffer(Module.ctx.ELEMENT_ARRAY_BUFFER, this.tempIndexBuffers[curr]); + Module.ctx.bufferData(Module.ctx.ELEMENT_ARRAY_BUFFER, size, Module.ctx.DYNAMIC_DRAW); + Module.ctx.bindBuffer(Module.ctx.ELEMENT_ARRAY_BUFFER, null); + last = size; + } + } + + // GL_QUAD indexes can be precalculated + this.tempQuadIndexBuffer = Module.ctx.createBuffer(); + Module.ctx.bindBuffer(Module.ctx.ELEMENT_ARRAY_BUFFER, this.tempQuadIndexBuffer); + var numIndexes = this.MAX_TEMP_BUFFER_SIZE >> 1; + var quadIndexes = new Uint16Array(numIndexes); + var i = 0, v = 0; + while (1) { + quadIndexes[i++] = v; + if (i >= numIndexes) break; + quadIndexes[i++] = v+1; + if (i >= numIndexes) break; + quadIndexes[i++] = v+2; + if (i >= numIndexes) break; + quadIndexes[i++] = v; + if (i >= numIndexes) break; + quadIndexes[i++] = v+2; + if (i >= numIndexes) break; + quadIndexes[i++] = v+3; + if (i >= numIndexes) break; + v += 4; + } + Module.ctx.bufferData(Module.ctx.ELEMENT_ARRAY_BUFFER, quadIndexes, Module.ctx.STATIC_DRAW); + Module.ctx.bindBuffer(Module.ctx.ELEMENT_ARRAY_BUFFER, null); + }, + + // Renderers + addRendererComponent: function(name, size, type) { + if (!this.rendererComponents[name]) { + this.rendererComponents[name] = 1; +#if ASSERTIONS + assert(!this.enabledClientAttributes[this.ATTRIBUTE_BY_NAME[name]]); // cannot get mixed up with this, for example we will disable this later +#endif + this.enabledClientAttributes[this.ATTRIBUTE_BY_NAME[name]] = true; + this.setClientAttribute(name, size, type, 0, this.rendererComponentPointer); + this.rendererComponentPointer += size * this.byteSizeByType[type]; + } else { + this.rendererComponents[name]++; + } + }, + + disableBeginEndClientAttributes: function() { + for (var name in this.rendererComponents) { + this.enabledClientAttributes[this.ATTRIBUTE_BY_NAME[name]] = false; + } + }, + + getRenderer: function() { + // return a renderer object given the liveClientAttributes + // we maintain a cache of renderers, optimized to not generate garbage + var attributes = GL.immediate.liveClientAttributes; + var cacheItem = GL.immediate.rendererCache; + for (var i = 0; i < attributes.length; i++) { + var attribute = attributes[i]; + if (!cacheItem[attribute.name]) cacheItem[attribute.name] = {}; + cacheItem = cacheItem[attribute.name]; + if (!cacheItem[attribute.size]) cacheItem[attribute.size] = {}; + cacheItem = cacheItem[attribute.size]; + if (!cacheItem[attribute.type]) cacheItem[attribute.type] = {}; + cacheItem = cacheItem[attribute.type]; + } + if (GLEmulation.fogEnabled) { + var fogParam = GLEmulation.fogMode; + } else { + var fogParam = 0; // all valid modes are non-zero + } + if (!cacheItem[fogParam]) cacheItem[fogParam] = {}; + cacheItem = cacheItem[fogParam]; + if (GL.currProgram) { // Note the order here; this one is last, and optional + if (!cacheItem[GL.currProgram]) cacheItem[GL.currProgram] = {}; + cacheItem = cacheItem[GL.currProgram]; + } + if (!cacheItem.renderer) { +#if GL_DEBUG + Module.printErr('generating renderer for ' + JSON.stringify(attributes)); +#endif + cacheItem.renderer = this.createRenderer(); + } + return cacheItem.renderer; + }, + + createRenderer: function(renderer) { + var useCurrProgram = !!GL.currProgram; + var hasTextures = false, textureSizes = [], textureTypes = [], textureOffsets = []; + for (var i = 0; i < GL.immediate.NUM_TEXTURES; i++) { + if (GL.immediate.enabledClientAttributes[GL.immediate.TEXTURE0 + i]) { + textureSizes[i] = GL.immediate.clientAttributes[GL.immediate.TEXTURE0 + i].size; + textureTypes[i] = GL.immediate.clientAttributes[GL.immediate.TEXTURE0 + i].type; + textureOffsets[i] = GL.immediate.clientAttributes[GL.immediate.TEXTURE0 + i].offset; + hasTextures = true; + } + } + var stride = GL.immediate.stride; + var positionSize = GL.immediate.clientAttributes[GL.immediate.VERTEX].size; + var positionType = GL.immediate.clientAttributes[GL.immediate.VERTEX].type; + var positionOffset = GL.immediate.clientAttributes[GL.immediate.VERTEX].offset; + var colorSize = 0, colorType, colorOffset; + if (GL.immediate.enabledClientAttributes[GL.immediate.COLOR]) { + colorSize = GL.immediate.clientAttributes[GL.immediate.COLOR].size; + colorType = GL.immediate.clientAttributes[GL.immediate.COLOR].type; + colorOffset = GL.immediate.clientAttributes[GL.immediate.COLOR].offset; + } + var normalSize = 0, normalType, normalOffset; + if (GL.immediate.enabledClientAttributes[GL.immediate.NORMAL]) { + normalSize = GL.immediate.clientAttributes[GL.immediate.NORMAL].size; + normalType = GL.immediate.clientAttributes[GL.immediate.NORMAL].type; + normalOffset = GL.immediate.clientAttributes[GL.immediate.NORMAL].offset; + } + var ret = { + init: function() { + if (useCurrProgram) { + if (GL.shaderInfos[GL.programShaders[GL.currProgram][0]].type == Module.ctx.VERTEX_SHADER) { + this.vertexShader = GL.shaders[GL.programShaders[GL.currProgram][0]]; + this.fragmentShader = GL.shaders[GL.programShaders[GL.currProgram][1]]; + } else { + this.vertexShader = GL.shaders[GL.programShaders[GL.currProgram][1]]; + this.fragmentShader = GL.shaders[GL.programShaders[GL.currProgram][0]]; + } + this.program = GL.programs[GL.currProgram]; + } else { + // IMPORTANT NOTE: If you parameterize the shader source based on any runtime values + // in order to create the least expensive shader possible based on the features being + // used, you should also update the code in the beginning of getRenderer to make sure + // that you cache the renderer based on the said parameters. + this.vertexShader = Module.ctx.createShader(Module.ctx.VERTEX_SHADER); + var zero = positionSize == 2 ? '0, ' : ''; + if (GLEmulation.fogEnabled) { + switch (GLEmulation.fogMode) { + case 0x0801: // GL_EXP2 + // fog = exp(-(gl_Fog.density * gl_FogFragCoord)^2) + var fogFormula = ' float fog = exp(-u_fogDensity * u_fogDensity * ecDistance * ecDistance); \n'; + break; + case 0x2601: // GL_LINEAR + // fog = (gl_Fog.end - gl_FogFragCoord) * gl_fog.scale + var fogFormula = ' float fog = (u_fogEnd - ecDistance) * u_fogScale; \n'; + break; + default: // default to GL_EXP + // fog = exp(-gl_Fog.density * gl_FogFragCoord) + var fogFormula = ' float fog = exp(-u_fogDensity * ecDistance); \n'; + break; + } + } + Module.ctx.shaderSource(this.vertexShader, 'attribute vec' + positionSize + ' a_position; \n' + + 'attribute vec2 a_texCoord0; \n' + + (hasTextures ? 'varying vec2 v_texCoord; \n' : '') + + 'varying vec4 v_color; \n' + + (colorSize ? 'attribute vec4 a_color; \n': 'uniform vec4 u_color; \n') + + (GLEmulation.fogEnabled ? 'varying float v_fogFragCoord; \n' : '') + + 'uniform mat4 u_modelView; \n' + + 'uniform mat4 u_projection; \n' + + 'void main() \n' + + '{ \n' + + ' vec4 ecPosition = (u_modelView * vec4(a_position, ' + zero + '1.0)); \n' + // eye-coordinate position + ' gl_Position = u_projection * ecPosition; \n' + + (hasTextures ? 'v_texCoord = a_texCoord0; \n' : '') + + (colorSize ? 'v_color = a_color; \n' : 'v_color = u_color; \n') + + (GLEmulation.fogEnabled ? 'v_fogFragCoord = abs(ecPosition.z);\n' : '') + + '} \n'); + Module.ctx.compileShader(this.vertexShader); + + this.fragmentShader = Module.ctx.createShader(Module.ctx.FRAGMENT_SHADER); + Module.ctx.shaderSource(this.fragmentShader, 'precision mediump float; \n' + + 'varying vec2 v_texCoord; \n' + + 'uniform sampler2D u_texture; \n' + + 'varying vec4 v_color; \n' + + (GLEmulation.fogEnabled ? ( + 'varying float v_fogFragCoord; \n' + + 'uniform vec4 u_fogColor; \n' + + 'uniform float u_fogEnd; \n' + + 'uniform float u_fogScale; \n' + + 'uniform float u_fogDensity; \n' + + 'float ffog(in float ecDistance) { \n' + + fogFormula + + ' fog = clamp(fog, 0.0, 1.0); \n' + + ' return fog; \n' + + '} \n' + ) : '') + + 'void main() \n' + + '{ \n' + + (hasTextures ? 'gl_FragColor = v_color * texture2D( u_texture, v_texCoord );\n' : + 'gl_FragColor = v_color;\n') + + (GLEmulation.fogEnabled ? 'gl_FragColor = vec4(mix(u_fogColor.rgb, gl_FragColor.rgb, ffog(v_fogFragCoord)), gl_FragColor.a); \n' : '') + + '} \n'); + Module.ctx.compileShader(this.fragmentShader); + + this.program = Module.ctx.createProgram(); + Module.ctx.attachShader(this.program, this.vertexShader); + Module.ctx.attachShader(this.program, this.fragmentShader); + Module.ctx.bindAttribLocation(this.program, 0, 'a_position'); + Module.ctx.linkProgram(this.program); + } + + this.positionLocation = Module.ctx.getAttribLocation(this.program, 'a_position'); + this.texCoordLocations = []; + for (var i = 0; i < textureSizes.length; i++) { + if (textureSizes[i]) { + this.texCoordLocations[i] = Module.ctx.getAttribLocation(this.program, 'a_texCoord' + i); + } + } + this.textureMatrixLocations = []; + for (var i = 0; i < GL.immediate.MAX_TEXTURES; i++) { + this.textureMatrixLocations[i] = Module.ctx.getUniformLocation(this.program, 'u_textureMatrix' + i); + } + this.colorLocation = Module.ctx.getAttribLocation(this.program, 'a_color'); + this.normalLocation = Module.ctx.getAttribLocation(this.program, 'a_normal'); + + this.textureLocation = Module.ctx.getUniformLocation(this.program, 'u_texture'); // only for immediate mode with no shaders, so only one is enough + this.modelViewLocation = Module.ctx.getUniformLocation(this.program, 'u_modelView'); + this.projectionLocation = Module.ctx.getUniformLocation(this.program, 'u_projection'); + this.hasColorAttribLocation = Module.ctx.getUniformLocation(this.program, 'u_hasColorAttrib'); + this.colorUniformLocation = Module.ctx.getUniformLocation(this.program, 'u_color'); + + this.hasTextures = hasTextures; + this.hasColorAttrib = colorSize > 0 && this.colorLocation >= 0; + this.hasColorUniform = !!this.colorUniformLocation; + this.hasNormal = normalSize > 0 && this.normalLocation >= 0; + + this.floatType = Module.ctx.FLOAT; // minor optimization + + this.fogColorLocation = Module.ctx.getUniformLocation(this.program, 'u_fogColor'); + this.fogEndLocation = Module.ctx.getUniformLocation(this.program, 'u_fogEnd'); + this.fogScaleLocation = Module.ctx.getUniformLocation(this.program, 'u_fogScale'); + this.fogDensityLocation = Module.ctx.getUniformLocation(this.program, 'u_fogDensity'); + this.hasFog = !!(this.fogColorLocation || this.fogEndLocation || + this.fogScaleLocation || this.fogDensityLocation); + }, + + prepare: function() { + // Calculate the array buffer + var arrayBuffer; + if (!GL.currArrayBuffer) { + var start = GL.immediate.firstVertex*GL.immediate.stride; + var end = GL.immediate.lastVertex*GL.immediate.stride; + assert(end <= GL.immediate.MAX_TEMP_BUFFER_SIZE, 'too much vertex data'); + arrayBuffer = GL.immediate.tempVertexBuffers[GL.immediate.tempBufferIndexLookup[end]]; + // TODO: consider using the last buffer we bound, if it was larger. downside is larger buffer, but we might avoid rebinding and preparing + } else { + arrayBuffer = GL.currArrayBuffer; + } + + // If the array buffer is unchanged and the renderer as well, then we can avoid all the work here + // XXX We use some heuristics here, and this may not work in all cases. Try disabling this if you + // have odd glitches (by setting canSkip always to 0, or even cleaning up the renderer right + // after rendering) + var lastRenderer = GL.immediate.lastRenderer; + var canSkip = this == lastRenderer && + arrayBuffer == GL.immediate.lastArrayBuffer && + (GL.currProgram || this.program) == GL.immediate.lastProgram && + !GL.immediate.matricesModified; + if (!canSkip && lastRenderer) lastRenderer.cleanup(); + if (!GL.currArrayBuffer) { + // Bind the array buffer and upload data after cleaning up the previous renderer + if (arrayBuffer != GL.immediate.lastArrayBuffer) { + Module.ctx.bindBuffer(Module.ctx.ARRAY_BUFFER, arrayBuffer); + } + Module.ctx.bufferSubData(Module.ctx.ARRAY_BUFFER, start, GL.immediate.vertexData.subarray(start >> 2, end >> 2)); + } + if (canSkip) return; + GL.immediate.lastRenderer = this; + GL.immediate.lastArrayBuffer = arrayBuffer; + GL.immediate.lastProgram = GL.currProgram || this.program; + GL.immediate.matricesModified = false; + + if (!GL.currProgram) { + Module.ctx.useProgram(this.program); + } + + if (this.modelViewLocation) Module.ctx.uniformMatrix4fv(this.modelViewLocation, false, GL.immediate.matrix['m']); + if (this.projectionLocation) Module.ctx.uniformMatrix4fv(this.projectionLocation, false, GL.immediate.matrix['p']); + + Module.ctx.vertexAttribPointer(this.positionLocation, positionSize, positionType, false, + stride, positionOffset); + Module.ctx.enableVertexAttribArray(this.positionLocation); + if (this.hasTextures) { + for (var i = 0; i < textureSizes.length; i++) { + if (textureSizes[i] && this.texCoordLocations[i] >= 0) { + Module.ctx.vertexAttribPointer(this.texCoordLocations[i], textureSizes[i], textureTypes[i], false, + stride, textureOffsets[i]); + Module.ctx.enableVertexAttribArray(this.texCoordLocations[i]); + } + } + for (var i = 0; i < GL.immediate.MAX_TEXTURES; i++) { + if (this.textureMatrixLocations[i]) { // XXX might we need this even without the condition we are currently in? + Module.ctx.uniformMatrix4fv(this.textureMatrixLocations[i], false, GL.immediate.matrix['t' + i]); + } + } + } + if (this.hasColorAttrib) { + Module.ctx.vertexAttribPointer(this.colorLocation, colorSize, colorType, true, + stride, colorOffset); + Module.ctx.enableVertexAttribArray(this.colorLocation); + Module.ctx.uniform1i(this.hasColorAttribLocation, 1); + } else if (this.hasColorUniform) { + Module.ctx.uniform1i(this.hasColorAttribLocation, 0); + Module.ctx.uniform4fv(this.colorUniformLocation, GL.immediate.clientColor); + } + if (this.hasNormal) { + Module.ctx.vertexAttribPointer(this.normalLocation, normalSize, normalType, true, + stride, normalOffset); + Module.ctx.enableVertexAttribArray(this.normalLocation); + } + if (!useCurrProgram) { // otherwise, the user program will set the sampler2D binding and uniform itself + var texture = Module.ctx.getParameter(Module.ctx.TEXTURE_BINDING_2D); + Module.ctx.activeTexture(Module.ctx.TEXTURE0); + Module.ctx.bindTexture(Module.ctx.TEXTURE_2D, texture); + Module.ctx.uniform1i(this.textureLocation, 0); + } + if (this.hasFog) { + if (this.fogColorLocation) Module.ctx.uniform4fv(this.fogColorLocation, GLEmulation.fogColor); + if (this.fogEndLocation) Module.ctx.uniform1f(this.fogEndLocation, GLEmulation.fogEnd); + if (this.fogScaleLocation) Module.ctx.uniform1f(this.fogScaleLocation, 1/(GLEmulation.fogEnd - GLEmulation.fogStart)); + if (this.fogDensityLocation) Module.ctx.uniform1f(this.fogDensityLocation, GLEmulation.fogDensity); + } + }, + + cleanup: function() { + Module.ctx.disableVertexAttribArray(this.positionLocation); + if (this.hasTextures) { + for (var i = 0; i < textureSizes.length; i++) { + if (textureSizes[i] && this.texCoordLocations[i] >= 0) { + Module.ctx.disableVertexAttribArray(this.texCoordLocations[i]); + } + } + } + if (this.hasColorAttrib) { + Module.ctx.disableVertexAttribArray(this.colorLocation); + } + if (this.hasNormal) { + Module.ctx.disableVertexAttribArray(this.normalLocation); + } + if (!GL.currProgram) { + Module.ctx.useProgram(null); + } + if (!GL.currArrayBuffer) { + Module.ctx.bindBuffer(Module.ctx.ARRAY_BUFFER, null); + } + + GL.immediate.lastRenderer = null; + GL.immediate.lastArrayBuffer = null; + GL.immediate.lastProgram = null; + GL.immediate.matricesModified = true; + } + }; + ret.init(); + return ret; + }, + + // Main functions + initted: false, + init: function() { + Module.printErr('WARNING: using emscripten GL immediate mode emulation. This is very limited in what it supports'); + GL.immediate.initted = true; + + if (!Module.useWebGL) return; // a 2D canvas may be currently used TODO: make sure we are actually called in that case + + this.matrixStack['m'] = []; + this.matrixStack['p'] = []; + for (var i = 0; i < GL.immediate.MAX_TEXTURES; i++) { + this.matrixStack['t' + i] = []; + } + + this.ATTRIBUTE_BY_NAME['V'] = 0; + this.ATTRIBUTE_BY_NAME['N'] = 1; + this.ATTRIBUTE_BY_NAME['C'] = 2; + this.ATTRIBUTE_BY_NAME['T0'] = 3; + this.ATTRIBUTE_BY_NAME['T1'] = 4; + this.ATTRIBUTE_BY_NAME['T2'] = 5; + this.ATTRIBUTE_BY_NAME['T3'] = 6; + this.ATTRIBUTE_BY_NAME['T4'] = 7; + this.ATTRIBUTE_BY_NAME['T5'] = 8; + this.ATTRIBUTE_BY_NAME['T6'] = 9; + + // Initialize matrix library + + GL.immediate.matrix['m'] = GL.immediate.matrix.lib.mat4.create(); + GL.immediate.matrix.lib.mat4.identity(GL.immediate.matrix['m']); + GL.immediate.matrix['p'] = GL.immediate.matrix.lib.mat4.create(); + GL.immediate.matrix.lib.mat4.identity(GL.immediate.matrix['p']); + for (var i = 0; i < GL.immediate.MAX_TEXTURES; i++) { + GL.immediate.matrix['t' + i] = GL.immediate.matrix.lib.mat4.create(); + } + + // Buffers for data + this.tempData = new Float32Array(this.MAX_TEMP_BUFFER_SIZE >> 2); + this.indexData = new Uint16Array(this.MAX_TEMP_BUFFER_SIZE >> 1); + + this.vertexDataU8 = new Uint8Array(this.tempData.buffer); + + this.generateTempBuffers(); + + this.clientColor = new Float32Array([1, 1, 1, 1]); + + // Replace some functions with immediate-mode aware versions. If there are no client + // attributes enabled, and we use webgl-friendly modes (no GL_QUADS), then no need + // for emulation + _glDrawArrays = function(mode, first, count) { + if (GL.immediate.totalEnabledClientAttributes == 0 && mode <= 6) { + Module.ctx.drawArrays(mode, first, count); + return; + } + GL.immediate.prepareClientAttributes(count, false); + GL.immediate.mode = mode; + if (!GL.currArrayBuffer) { + GL.immediate.vertexData = {{{ makeHEAPView('F32', 'GL.immediate.vertexPointer', 'GL.immediate.vertexPointer + (first+count)*GL.immediate.stride') }}}; // XXX assuming float + GL.immediate.firstVertex = first; + GL.immediate.lastVertex = first + count; + } + GL.immediate.flush(null, first); + GL.immediate.mode = 0; + }; + + _glDrawElements = function(mode, count, type, indices, start, end) { // start, end are given if we come from glDrawRangeElements + if (GL.immediate.totalEnabledClientAttributes == 0 && mode <= 6 && GL.currElementArrayBuffer) { + Module.ctx.drawElements(mode, count, type, indices); + return; + } + if (!GL.currElementArrayBuffer) { + assert(type == Module.ctx.UNSIGNED_SHORT); // We can only emulate buffers of this kind, for now + } + GL.immediate.prepareClientAttributes(count, false); + GL.immediate.mode = mode; + if (!GL.currArrayBuffer) { + GL.immediate.firstVertex = end ? start : TOTAL_MEMORY; // if we don't know the start, set an invalid value and we will calculate it later from the indices + GL.immediate.lastVertex = end ? end+1 : 0; + GL.immediate.vertexData = {{{ makeHEAPView('F32', 'GL.immediate.vertexPointer', '(end ? GL.immediate.vertexPointer + (end+1)*GL.immediate.stride : TOTAL_MEMORY)') }}}; // XXX assuming float + } + GL.immediate.flush(count, 0, indices); + GL.immediate.mode = 0; + }; + }, + + // Prepares and analyzes client attributes. + // Modifies liveClientAttributes, stride, vertexPointer, vertexCounter + // count: number of elements we will draw + // beginEnd: whether we are drawing the results of a begin/end block + prepareClientAttributes: function(count, beginEnd) { + // If no client attributes were modified since we were last called, do nothing. Note that this + // does not work for glBegin/End, where we generate renderer components dynamically and then + // disable them ourselves, but it does help with glDrawElements/Arrays. + if (!this.modifiedClientAttributes) { + return; + } + this.modifiedClientAttributes = false; + + var stride = 0, start; + var attributes = GL.immediate.liveClientAttributes; + attributes.length = 0; + for (var i = 0; i < GL.immediate.NUM_ATTRIBUTES; i++) { + if (GL.immediate.enabledClientAttributes[i]) attributes.push(GL.immediate.clientAttributes[i]); + } + attributes.sort(function(x, y) { return !x ? (!y ? 0 : 1) : (!y ? -1 : (x.pointer - y.pointer)) }); + start = attributes[0].pointer; + for (var i = 0; i < attributes.length; i++) { + var attribute = attributes[i]; + if (!attribute) break; +#if ASSERTIONS + assert(stride == 0 || stride == attribute.stride); // must all be in the same buffer +#endif + if (attribute.stride) stride = attribute.stride; + } + + var bytes = 0; + for (var i = 0; i < attributes.length; i++) { + var attribute = attributes[i]; + if (!attribute) break; + attribute.offset = attribute.pointer - start; + if (attribute.offset > bytes) { // ensure we start where we should + assert((attribute.offset - bytes)%4 == 0); // XXX assuming 4-alignment + bytes += attribute.offset - bytes; + } + bytes += attribute.size * GL.immediate.byteSizeByType[attribute.type]; + if (bytes % 4 != 0) bytes += 4 - (bytes % 4); // XXX assuming 4-alignment + } + assert(stride == 0 || bytes <= stride); + if (bytes < stride) { // ensure the size is that of the stride + bytes = stride; + } + GL.immediate.stride = bytes; + + if (!beginEnd) { + bytes *= count; + if (!GL.currArrayBuffer) { + GL.immediate.vertexPointer = start; + } + GL.immediate.vertexCounter = bytes / 4; // XXX assuming float + } + }, + + flush: function(numProvidedIndexes, startIndex, ptr) { + startIndex = startIndex || 0; + ptr = ptr || 0; + + var renderer = this.getRenderer(); + + // Generate index data in a format suitable for GLES 2.0/WebGL + var numVertexes = 4 * this.vertexCounter / GL.immediate.stride; // XXX assuming float + assert(numVertexes % 1 == 0); + + var emulatedElementArrayBuffer = false; + var numIndexes = 0; + if (numProvidedIndexes) { + numIndexes = numProvidedIndexes; + if (!GL.currArrayBuffer && GL.immediate.firstVertex > GL.immediate.lastVertex) { + // Figure out the first and last vertex from the index data + assert(!GL.currElementArrayBuffer); // If we are going to upload array buffer data, we need to find which range to + // upload based on the indices. If they are in a buffer on the GPU, that is very + // inconvenient! So if you do not have an array buffer, you should also not have + // an element array buffer. But best is to use both buffers! + for (var i = 0; i < numProvidedIndexes; i++) { + var currIndex = {{{ makeGetValue('ptr', 'i*2', 'i16', null, 1) }}}; + GL.immediate.firstVertex = Math.min(GL.immediate.firstVertex, currIndex); + GL.immediate.lastVertex = Math.max(GL.immediate.lastVertex, currIndex+1); + } + } + if (!GL.currElementArrayBuffer) { + // If no element array buffer is bound, then indices is a literal pointer to clientside data + assert(numProvidedIndexes << 1 <= GL.immediate.MAX_TEMP_BUFFER_SIZE, 'too many immediate mode indexes (a)'); + var indexBuffer = GL.immediate.tempIndexBuffers[GL.immediate.tempBufferIndexLookup[numProvidedIndexes << 1]]; + Module.ctx.bindBuffer(Module.ctx.ELEMENT_ARRAY_BUFFER, indexBuffer); + Module.ctx.bufferSubData(Module.ctx.ELEMENT_ARRAY_BUFFER, 0, {{{ makeHEAPView('U16', 'ptr', 'ptr + (numProvidedIndexes << 1)') }}}); + ptr = 0; + emulatedElementArrayBuffer = true; + } + } else if (GL.immediate.mode > 6) { // above GL_TRIANGLE_FAN are the non-GL ES modes + if (GL.immediate.mode != 7) throw 'unsupported immediate mode ' + GL.immediate.mode; // GL_QUADS + // GL.immediate.firstVertex is the first vertex we want. Quad indexes are in the pattern + // 0 1 2, 0 2 3, 4 5 6, 4 6 7, so we need to look at index firstVertex * 1.5 to see it. + // Then since indexes are 2 bytes each, that means 3 + assert(GL.immediate.firstVertex % 4 == 0); + ptr = GL.immediate.firstVertex*3; + var numQuads = numVertexes / 4; + numIndexes = numQuads * 6; // 0 1 2, 0 2 3 pattern + assert(ptr + (numIndexes << 1) <= GL.immediate.MAX_TEMP_BUFFER_SIZE, 'too many immediate mode indexes (b)'); + Module.ctx.bindBuffer(Module.ctx.ELEMENT_ARRAY_BUFFER, this.tempQuadIndexBuffer); + emulatedElementArrayBuffer = true; + } + + renderer.prepare(); + + if (numIndexes) { + Module.ctx.drawElements(Module.ctx.TRIANGLES, numIndexes, Module.ctx.UNSIGNED_SHORT, ptr); + } else { + Module.ctx.drawArrays(GL.immediate.mode, startIndex, numVertexes); + } + + if (emulatedElementArrayBuffer) { + Module.ctx.bindBuffer(Module.ctx.ELEMENT_ARRAY_BUFFER, GL.buffers[GL.currElementArrayBuffer] || null); + } + } + }, + + $GLImmediateSetup__deps: ['$GLImmediate', function() { return 'GL.immediate = GLImmediate; GL.immediate.matrix.lib = ' + read('gl-matrix.js') + ';\n' }], + $GLImmediateSetup: {}, + + glBegin__deps: ['$GLImmediateSetup'], + glBegin: function(mode) { + GL.immediate.mode = mode; + GL.immediate.vertexCounter = 0; + GL.immediate.rendererComponents = {}; // XXX + GL.immediate.rendererComponentPointer = 0; + GL.immediate.vertexData = GL.immediate.tempData; + }, + + glEnd: function() { + GL.immediate.prepareClientAttributes(GL.immediate.rendererComponents['V'], true); + GL.immediate.firstVertex = 0; + GL.immediate.lastVertex = GL.immediate.vertexCounter / (GL.immediate.stride >> 2); + GL.immediate.flush(); + GL.immediate.disableBeginEndClientAttributes(); + GL.immediate.mode = 0; + }, + + glVertex3f: function(x, y, z) { +#if ASSERTIONS + assert(GL.immediate.mode); // must be in begin/end +#endif + GL.immediate.vertexData[GL.immediate.vertexCounter++] = x; + GL.immediate.vertexData[GL.immediate.vertexCounter++] = y; + GL.immediate.vertexData[GL.immediate.vertexCounter++] = z || 0; +#if ASSERTIONS + assert(GL.immediate.vertexCounter << 2 < GL.immediate.MAX_TEMP_BUFFER_SIZE); +#endif + GL.immediate.addRendererComponent('V', 3, Module.ctx.FLOAT); + }, + glVertex2f: 'glVertex3f', + + glVertex3fv__deps: ['glVertex3f'], + glVertex3fv: function(p) { + _glVertex3f({{{ makeGetValue('p', '0', 'float') }}}, {{{ makeGetValue('p', '4', 'float') }}}, {{{ makeGetValue('p', '8', 'float') }}}); + }, + + glTexCoord2i: function(u, v) { +#if ASSERTIONS + assert(GL.immediate.mode); // must be in begin/end +#endif + GL.immediate.vertexData[GL.immediate.vertexCounter++] = u; + GL.immediate.vertexData[GL.immediate.vertexCounter++] = v; + GL.immediate.addRendererComponent('T0', 2, Module.ctx.FLOAT); + }, + glTexCoord2f: 'glTexCoord2i', + + glTexCoord2fv__deps: ['glTexCoord2f'], + glTexCoord2fv: function(v) { + _glTexCoord2f({{{ makeGetValue('v', '0', 'float') }}}, {{{ makeGetValue('v', '4', 'float') }}}); + }, + + glColor4f: function(r, g, b, a) { + // TODO: make ub the default, not f, save a few mathops + if (GL.immediate.mode) { + var start = GL.immediate.vertexCounter << 2; + GL.immediate.vertexDataU8[start + 0] = r * 255; + GL.immediate.vertexDataU8[start + 1] = g * 255; + GL.immediate.vertexDataU8[start + 2] = b * 255; + GL.immediate.vertexDataU8[start + 3] = a * 255; + GL.immediate.vertexCounter++; + GL.immediate.addRendererComponent('C', 4, Module.ctx.UNSIGNED_BYTE); + } else { + GL.immediate.clientColor[0] = r; + GL.immediate.clientColor[1] = g; + GL.immediate.clientColor[2] = b; + GL.immediate.clientColor[3] = a; + } + }, + glColor4d: 'glColor4f', + glColor4ub__deps: ['glColor4f'], + glColor4ub: function(r, g, b, a) { + _glColor4f((r&255)/255, (g&255)/255, (b&255)/255, (a&255)/255); + }, + glColor4us__deps: ['glColor4f'], + glColor4us: function(r, g, b, a) { + _glColor4f((r&65535)/65535, (g&65535)/65535, (b&65535)/65535, (a&65535)/65535); + }, + glColor4ui__deps: ['glColor4f'], + glColor4ui: function(r, g, b, a) { + _glColor4f((r>>>0)/4294967295, (g>>>0)/4294967295, (b>>>0)/4294967295, (a>>>0)/4294967295); + }, + glColor3f__deps: ['glColor4f'], + glColor3f: function(r, g, b) { + _glColor4f(r, g, b, 1); + }, + glColor3d: 'glColor3f', + glColor3ub__deps: ['glColor4ub'], + glColor3ub: function(r, g, b) { + _glColor4ub(r, g, b, 255); + }, + glColor3us__deps: ['glColor4us'], + glColor3us: function(r, g, b) { + _glColor4us(r, g, b, 65535); + }, + glColor3ui__deps: ['glColor4ui'], + glColor3ui: function(r, g, b) { + _glColor4ui(r, g, b, 4294967295); + }, + + glColor3ubv__deps: ['glColor3ub'], + glColor3ubv: function(p) { + _glColor3ub({{{ makeGetValue('p', '0', 'i8') }}}, {{{ makeGetValue('p', '1', 'i8') }}}, {{{ makeGetValue('p', '2', 'i8') }}}); + }, + glColor3usv__deps: ['glColor3us'], + glColor3usv: function(p) { + _glColor3us({{{ makeGetValue('p', '0', 'i16') }}}, {{{ makeGetValue('p', '2', 'i16') }}}, {{{ makeGetValue('p', '4', 'i16') }}}); + }, + glColor3uiv__deps: ['glColor3ui'], + glColor3uiv: function(p) { + _glColor3ui({{{ makeGetValue('p', '0', 'i32') }}}, {{{ makeGetValue('p', '4', 'i32') }}}, {{{ makeGetValue('p', '8', 'i32') }}}); + }, + glColor3fv__deps: ['glColor3f'], + glColor3fv: function(p) { + _glColor3f({{{ makeGetValue('p', '0', 'float') }}}, {{{ makeGetValue('p', '4', 'float') }}}, {{{ makeGetValue('p', '8', 'float') }}}); + }, + glColor4fv__deps: ['glColor4f'], + glColor4fv: function(p) { + _glColor4f({{{ makeGetValue('p', '0', 'float') }}}, {{{ makeGetValue('p', '4', 'float') }}}, {{{ makeGetValue('p', '8', 'float') }}}, {{{ makeGetValue('p', '12', 'float') }}}); + }, + + glFogf: function(pname, param) { // partial support, TODO + switch(pname) { + case 0x0B63: // GL_FOG_START + GLEmulation.fogStart = param; break; + case 0x0B64: // GL_FOG_END + GLEmulation.fogEnd = param; break; + case 0x0B62: // GL_FOG_DENSITY + GLEmulation.fogDensity = param; break; + case 0x0B65: // GL_FOG_MODE + switch (param) { + case 0x0801: // GL_EXP2 + case 0x2601: // GL_LINEAR + GLEmulation.fogMode = param; break; + default: // default to GL_EXP + GLEmulation.fogMode = 0x0800 /* GL_EXP */; break; + } + break; + } + }, + glFogi__deps: ['glFogf'], + glFogi: function(pname, param) { + return _glFogf(pname, param); + }, + glFogfv__deps: ['glFogf'], + glFogfv: function(pname, param) { // partial support, TODO + switch(pname) { + case 0x0B66: // GL_FOG_COLOR + GLEmulation.fogColor[0] = {{{ makeGetValue('param', '0', 'float') }}}; + GLEmulation.fogColor[1] = {{{ makeGetValue('param', '4', 'float') }}}; + GLEmulation.fogColor[2] = {{{ makeGetValue('param', '8', 'float') }}}; + GLEmulation.fogColor[3] = {{{ makeGetValue('param', '12', 'float') }}}; + break; + case 0x0B63: // GL_FOG_START + case 0x0B64: // GL_FOG_END + _glFogf(pname, {{{ makeGetValue('param', '0', 'float') }}}); break; + } + }, + glFogiv__deps: ['glFogf'], + glFogiv: function(pname, param) { + switch(pname) { + case 0x0B66: // GL_FOG_COLOR + GLEmulation.fogColor[0] = ({{{ makeGetValue('param', '0', 'i32') }}}/2147483647)/2.0+0.5; + GLEmulation.fogColor[1] = ({{{ makeGetValue('param', '4', 'i32') }}}/2147483647)/2.0+0.5; + GLEmulation.fogColor[2] = ({{{ makeGetValue('param', '8', 'i32') }}}/2147483647)/2.0+0.5; + GLEmulation.fogColor[3] = ({{{ makeGetValue('param', '12', 'i32') }}}/2147483647)/2.0+0.5; + break; + default: + _glFogf(pname, {{{ makeGetValue('param', '0', 'i32') }}}); break; + } + }, + glFogx: 'glFogi', + glFogxv: 'glFogiv', + + glPolygonMode: function(){}, // TODO + + glAlphaFunc: function(){}, // TODO + + glNormal3f: function(){}, // TODO + + // Additional non-GLES rendering calls + + glDrawRangeElements: function(mode, start, end, count, type, indices) { + _glDrawElements(mode, count, type, indices, start, end); + }, + + // ClientState/gl*Pointer + + glEnableClientState: function(cap, disable) { + var attrib; + switch(cap) { + case 0x8078: // GL_TEXTURE_COORD_ARRAY + attrib = GL.immediate.TEXTURE0 + GL.immediate.clientActiveTexture; break; + case 0x8074: // GL_VERTEX_ARRAY + attrib = GL.immediate.VERTEX; break; + case 0x8075: // GL_NORMAL_ARRAY + attrib = GL.immediate.NORMAL; break; + case 0x8076: // GL_COLOR_ARRAY + attrib = GL.immediate.COLOR; break; + default: + throw 'unhandled clientstate: ' + cap; + } + if (disable && GL.immediate.enabledClientAttributes[attrib]) { + GL.immediate.enabledClientAttributes[attrib] = false; + GL.immediate.totalEnabledClientAttributes--; + } else if (!disable && !GL.immediate.enabledClientAttributes[attrib]) { + GL.immediate.enabledClientAttributes[attrib] = true; + GL.immediate.totalEnabledClientAttributes++; + } + GL.immediate.modifiedClientAttributes = true; + }, + glDisableClientState: function(cap) { + _glEnableClientState(cap, 1); + }, + + glVertexPointer__deps: ['$GLEmulation'], // if any pointers are used, glVertexPointer must be, and if it is, then we need emulation + glVertexPointer: function(size, type, stride, pointer) { + GL.immediate.setClientAttribute('V', size, type, stride, pointer); + }, + glTexCoordPointer: function(size, type, stride, pointer) { + GL.immediate.setClientAttribute('T' + GL.immediate.clientActiveTexture, size, type, stride, pointer); + }, + glNormalPointer: function(type, stride, pointer) { + GL.immediate.setClientAttribute('N', 3, type, stride, pointer); + }, + glColorPointer: function(size, type, stride, pointer) { + GL.immediate.setClientAttribute('C', size, type, stride, pointer); + }, + + glClientActiveTexture: function(texture) { + GL.immediate.clientActiveTexture = texture - 0x84C0; // GL_TEXTURE0 + }, + + // OpenGL Immediate Mode matrix routines. + // Note that in the future we might make these available only in certain modes. + glMatrixMode__deps: ['$GL', '$GLImmediateSetup', '$GLEmulation'], // emulation is not strictly needed, this is a workaround + glMatrixMode: function(mode) { + if (mode == 0x1700 /* GL_MODELVIEW */) { + GL.immediate.currentMatrix = 'm'; + } else if (mode == 0x1701 /* GL_PROJECTION */) { + GL.immediate.currentMatrix = 'p'; + } else if (mode == 0x1702) { // GL_TEXTURE + GL.immediate.currentMatrix = 't' + GL.immediate.clientActiveTexture; + } else { + throw "Wrong mode " + mode + " passed to glMatrixMode"; + } + }, + + glPushMatrix: function() { + GL.immediate.matricesModified = true; + GL.immediate.matrixStack[GL.immediate.currentMatrix].push( + Array.prototype.slice.call(GL.immediate.matrix[GL.immediate.currentMatrix])); + }, + + glPopMatrix: function() { + GL.immediate.matricesModified = true; + GL.immediate.matrix[GL.immediate.currentMatrix] = GL.immediate.matrixStack[GL.immediate.currentMatrix].pop(); + }, + + glLoadIdentity__deps: ['$GL', '$GLImmediateSetup'], + glLoadIdentity: function() { + GL.immediate.matricesModified = true; + GL.immediate.matrix.lib.mat4.identity(GL.immediate.matrix[GL.immediate.currentMatrix]); + }, + + glLoadMatrixd: function(matrix) { + GL.immediate.matricesModified = true; + GL.immediate.matrix.lib.mat4.set({{{ makeHEAPView('F64', 'matrix', 'matrix+16*8') }}}, GL.immediate.matrix[GL.immediate.currentMatrix]); + }, + + glLoadMatrixf: function(matrix) { +#if GL_DEBUG + if (GL.debug) Module.printErr('glLoadMatrixf receiving: ' + Array.prototype.slice.call(HEAPF32.subarray(matrix >> 2, (matrix >> 2) + 16))); +#endif + GL.immediate.matricesModified = true; + GL.immediate.matrix.lib.mat4.set({{{ makeHEAPView('F32', 'matrix', 'matrix+16*4') }}}, GL.immediate.matrix[GL.immediate.currentMatrix]); + }, + + glLoadTransposeMatrixd: function(matrix) { + GL.immediate.matricesModified = true; + GL.immediate.matrix.lib.mat4.set({{{ makeHEAPView('F64', 'matrix', 'matrix+16*8') }}}, GL.immediate.matrix[GL.immediate.currentMatrix]); + GL.immediate.matrix.lib.mat4.transpose(GL.immediate.matrix[GL.immediate.currentMatrix]); + }, + + glLoadTransposeMatrixf: function(matrix) { + GL.immediate.matricesModified = true; + GL.immediate.matrix.lib.mat4.set({{{ makeHEAPView('F32', 'matrix', 'matrix+16*4') }}}, GL.immediate.matrix[GL.immediate.currentMatrix]); + GL.immediate.matrix.lib.mat4.transpose(GL.immediate.matrix[GL.immediate.currentMatrix]); + }, + + glMultMatrixd: function(matrix) { + GL.immediate.matricesModified = true; + GL.immediate.matrix.lib.mat4.multiply(GL.immediate.matrix[GL.immediate.currentMatrix], + {{{ makeHEAPView('F64', 'matrix', 'matrix+16*8') }}}); + }, + + glMultMatrixf: function(matrix) { + GL.immediate.matricesModified = true; + GL.immediate.matrix.lib.mat4.multiply(GL.immediate.matrix[GL.immediate.currentMatrix], + {{{ makeHEAPView('F32', 'matrix', 'matrix+16*4') }}}); + }, + + glMultTransposeMatrixd: function(matrix) { + GL.immediate.matricesModified = true; + var colMajor = GL.immediate.matrix.lib.mat4.create(); + GL.immediate.matrix.lib.mat4.set({{{ makeHEAPView('F64', 'matrix', 'matrix+16*8') }}}, colMajor); + GL.immediate.matrix.lib.mat4.transpose(colMajor); + GL.immediate.matrix.lib.mat4.multiply(GL.immediate.matrix[GL.immediate.currentMatrix], colMajor); + }, + + glMultTransposeMatrixf: function(matrix) { + GL.immediate.matricesModified = true; + var colMajor = GL.immediate.matrix.lib.mat4.create(); + GL.immediate.matrix.lib.mat4.set({{{ makeHEAPView('F32', 'matrix', 'matrix+16*4') }}}, colMajor); + GL.immediate.matrix.lib.mat4.transpose(colMajor); + GL.immediate.matrix.lib.mat4.multiply(GL.immediate.matrix[GL.immediate.currentMatrix], colMajor); + }, + + glFrustum: function(left, right, bottom, top_, nearVal, farVal) { + GL.immediate.matricesModified = true; + GL.immediate.matrix.lib.mat4.multiply(GL.immediate.matrix[GL.immediate.currentMatrix], + GL.immediate.matrix.lib.mat4.frustum(left, right, bottom, top_, nearVal, farVal)); + }, + + glOrtho: function(left, right, bottom, top_, nearVal, farVal) { + GL.immediate.matricesModified = true; + GL.immediate.matrix.lib.mat4.multiply(GL.immediate.matrix[GL.immediate.currentMatrix], + GL.immediate.matrix.lib.mat4.ortho(left, right, bottom, top_, nearVal, farVal)); + }, + glOrthof: 'glOrtho', + + glScaled: function(x, y, z) { + GL.immediate.matricesModified = true; + GL.immediate.matrix.lib.mat4.scale(GL.immediate.matrix[GL.immediate.currentMatrix], [x, y, z]); + }, + glScalef: 'glScaled', + + glTranslated: function(x, y, z) { + GL.immediate.matricesModified = true; + GL.immediate.matrix.lib.mat4.translate(GL.immediate.matrix[GL.immediate.currentMatrix], [x, y, z]); + }, + glTranslatef: 'glTranslated', + + glRotated: function(angle, x, y, z) { + GL.immediate.matricesModified = true; + GL.immediate.matrix.lib.mat4.rotate(GL.immediate.matrix[GL.immediate.currentMatrix], angle*Math.PI/180, [x, y, z]); + }, + glRotatef: 'glRotated', + + // GLU + + gluPerspective: function(fov, aspect, near, far) { + GL.immediate.matricesModified = true; + GL.immediate.matrix.lib.mat4.multiply(GL.immediate.matrix[GL.immediate.currentMatrix], + GL.immediate.matrix.lib.mat4.perspective(fov, aspect, near, far, GL.immediate.currentMatrix)); + }, + + gluLookAt: function(ex, ey, ez, cx, cy, cz, ux, uy, uz) { + GL.immediate.matricesModified = true; + GL.immediate.matrix.lib.mat4.lookAt(GL.immediate.matrix[GL.immediate.currentMatrix], [ex, ey, ez], + [cx, cy, cz], [ux, uy, uz]); + }, + + gluProject: function(objX, objY, objZ, model, proj, view, winX, winY, winZ) { + // The algorithm for this functions comes from Mesa + + var inVec = new Float32Array(4); + var outVec = new Float32Array(4); + GL.immediate.matrix.lib.mat4.multiplyVec4({{{ makeHEAPView('F64', 'model', 'model+16*8') }}}, + [objX, objY, objZ, 1.0], outVec); + GL.immediate.matrix.lib.mat4.multiplyVec4({{{ makeHEAPView('F64', 'proj', 'proj+16*8') }}}, + outVec, inVec); + if (inVec[3] == 0.0) { + return 0 /* GL_FALSE */; + } + inVec[0] /= inVec[3]; + inVec[1] /= inVec[3]; + inVec[2] /= inVec[3]; + // Map x, y and z to range 0-1 */ + inVec[0] = inVec[0] * 0.5 + 0.5; + inVec[1] = inVec[1] * 0.5 + 0.5; + inVec[2] = inVec[2] * 0.5 + 0.5; + // Map x, y to viewport + inVec[0] = inVec[0] * {{{ makeGetValue('view', '2*4', 'i32') }}} + {{{ makeGetValue('view', '0*4', 'i32') }}}; + inVec[1] = inVec[1] * {{{ makeGetValue('view', '3*4', 'i32') }}} + {{{ makeGetValue('view', '1*4', 'i32') }}}; + + {{{ makeSetValue('winX', '0', 'inVec[0]', 'double') }}}; + {{{ makeSetValue('winY', '0', 'inVec[1]', 'double') }}}; + {{{ makeSetValue('winZ', '0', 'inVec[2]', 'double') }}}; + + return 1 /* GL_TRUE */; + }, + + gluUnProject: function(winX, winY, winZ, model, proj, view, objX, objY, objZ) { + var result = GL.immediate.matrix.lib.mat4.unproject([winX, winY, winZ], + {{{ makeHEAPView('F64', 'model', 'model+16*8') }}}, + {{{ makeHEAPView('F64', 'proj', 'proj+16*8') }}}, + {{{ makeHEAPView('32', 'view', 'view+4*4') }}}); + + if (result === null) { + return 0 /* GL_FALSE */; + } + + {{{ makeSetValue('objX', '0', 'result[0]', 'double') }}}; + {{{ makeSetValue('objY', '0', 'result[1]', 'double') }}}; + {{{ makeSetValue('objZ', '0', 'result[2]', 'double') }}}; + + return 1 /* GL_TRUE */; } }; -// Simple pass-through functions -[[0, 'shadeModel fogi fogfv getError finish flush'], - [1, 'clearDepth depthFunc enable disable frontFace cullFace clear enableVertexAttribArray disableVertexAttribArray lineWidth clearStencil depthMask stencilMask stencilMaskSeparate checkFramebufferStatus generateMipmap activeTexture blendEquation'], - [2, 'pixelStorei blendFunc blendEquationSeparate'], - [3, 'texParameteri texParameterf drawArrays vertexAttrib2f'], - [4, 'viewport clearColor scissor vertexAttrib3f colorMask drawElements renderbufferStorage blendFuncSeparate'], +// Simple pass-through functions. Starred ones have return values. [X] ones have X in the C name but not in the JS name +[[0, 'shadeModel getError* finish flush'], + [1, 'clearDepth clearDepth[f] depthFunc enable disable frontFace cullFace clear enableVertexAttribArray disableVertexAttribArray lineWidth clearStencil depthMask stencilMask checkFramebufferStatus* generateMipmap activeTexture blendEquation sampleCoverage isEnabled*'], + [2, 'blendFunc blendEquationSeparate depthRange depthRange[f] stencilMaskSeparate hint polygonOffset'], + [3, 'texParameteri texParameterf drawArrays vertexAttrib2f stencilFunc stencilOp'], + [4, 'viewport clearColor scissor vertexAttrib3f colorMask drawElements renderbufferStorage blendFuncSeparate blendColor stencilFuncSeparate stencilOpSeparate'], [5, 'vertexAttrib4f'], [6, 'vertexAttribPointer'], [8, 'copyTexImage2D copyTexSubImage2D']].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.ctx.NAME(' + args + ')' : '') + ' })'; - names.split(' ').forEach(function(name_) { - var cName = 'gl' + name_[0].toUpperCase() + name_.substr(1); + var plainStub = '(function(' + args + ') { ' + (num > 0 ? 'Module.ctx.NAME(' + args + ')' : '') + ' })'; + var returnStub = '(function(' + args + ') { ' + (num > 0 ? 'return Module.ctx.NAME(' + args + ')' : '') + ' })'; + names.split(' ').forEach(function(name) { + var stub = plainStub; + if (name[name.length-1] == '*') { + name = name.substr(0, name.length-1); + stub = returnStub; + } + var cName = name; + if (name.indexOf('[') >= 0) { + cName = name.replace('[', '').replace(']', ''); + name = cName.substr(0, cName.length-1); + } + var cName = 'gl' + cName[0].toUpperCase() + cName.substr(1); assert(!(cName in LibraryGL), "Cannot reimplement the existing function " + cName); - LibraryGL[cName] = eval(stub.replace('NAME', name_)); + LibraryGL[cName] = eval(stub.replace('NAME', name)); }); }); autoAddDeps(LibraryGL, '$GL'); + +// Emulation requires everything else, potentially +LibraryGL.$GLEmulation__deps = LibraryGL.$GLEmulation__deps.slice(0); +for (var item in LibraryGL) { + if (item != '$GLEmulation' && item.substr(-6) != '__deps' && item.substr(-9) != '__postset' && item.substr(0, 2) == 'gl') { + LibraryGL.$GLEmulation__deps.push(item); + } +} + mergeInto(LibraryManager.library, LibraryGL); diff --git a/src/library_glut.js b/src/library_glut.js index 0de0ce6a..d33f8436 100644 --- a/src/library_glut.js +++ b/src/library_glut.js @@ -226,13 +226,13 @@ var LibraryGLUT = { onFullScreenEventChange: function(event){ var width; var height; - if (document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen) { + if (document["fullScreen"] || document["mozFullScreen"] || document["webkitIsFullScreen"]) { width = screen["width"]; height = screen["height"]; } else { width = GLUT.windowWidth; height = GLUT.windowHeight; - // TODO set position + // TODO set position document.removeEventListener('fullscreenchange', GLUT.onFullScreenEventChange, true); document.removeEventListener('mozfullscreenchange', GLUT.onFullScreenEventChange, true); document.removeEventListener('webkitfullscreenchange', GLUT.onFullScreenEventChange, true); @@ -241,6 +241,7 @@ var LibraryGLUT = { Module['canvas'].height = height; /* Can't call _glutReshapeWindow as that requests cancelling fullscreen. */ if (GLUT.reshapeFunc) { + // console.log("GLUT.reshapeFunc (from FS): " + width + ", " + height); FUNCTION_TABLE[GLUT.reshapeFunc](width, height); } _glutPostRedisplay(); @@ -262,16 +263,7 @@ var LibraryGLUT = { document['webkitCancelFullScreen'] || (function() {}); CFS.apply(document, []); - }, - - requestAnimationFrame: function(func) { - var RAF = window['requestAnimationFrame'] || - window['mozRequestAnimationFrame'] || - window['webkitRequestAnimationFrame'] || - window['msRequestAnimationFrame'] || - window['setTimeout']; - RAF.apply(window, [func]); - }, + } }, glutGetModifiers: function() { return GLUT.modifiers; }, @@ -286,6 +278,10 @@ var LibraryGLUT = { Module['canvas'].height = GLUT.initWindowHeight = height; }, + glutInitWindowPosition: function(x, y) { + // Ignore for now + }, + glutGet: function(type) { switch (type) { case 100: /* GLUT_WINDOW_X */ @@ -367,16 +363,18 @@ var LibraryGLUT = { glutCreateWindow__deps: ['$Browser'], glutCreateWindow: function(name) { - Module.ctx = Browser.createContext(Module['canvas'], true); + Module.ctx = Browser.createContext(Module['canvas'], true, true); return 1; }, glutReshapeWindow__deps: ['$GLUT', 'glutPostRedisplay'], glutReshapeWindow: function(width, height) { GLUT.cancelFullScreen(); + // console.log("glutReshapeWindow: " + width + ", " + height); Module['canvas'].width = width; Module['canvas'].height = height; if (GLUT.reshapeFunc) { + // console.log("GLUT.reshapeFunc: " + width + ", " + height); FUNCTION_TABLE[GLUT.reshapeFunc](width, height); } _glutPostRedisplay(); @@ -406,7 +404,7 @@ var LibraryGLUT = { glutPostRedisplay: function() { if (GLUT.displayFunc) { - GLUT.requestAnimationFrame(FUNCTION_TABLE[GLUT.displayFunc]); + Browser.requestAnimationFrame(FUNCTION_TABLE[GLUT.displayFunc]); } }, diff --git a/src/library_sdl.js b/src/library_sdl.js index b607bdb3..73848502 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -1,81 +1,9 @@ //"use strict"; -// To use emscripten's SDL library here, you need to define -// Module.canvas. -// -// More specifically, our SDL implementation will look for -// Module.canvas. You should fill it using something like -// -// function onLoad() { -// // Pass canvas and context to the generated code -// Module.canvas = document.getElementById('canvas'); -// } -// -// Note that this must be called during onload, since you will -// only be able to access the canvas element in the page after -// it loads. You will likely also want to disable running by -// default, with something like -// -// var Module = { -// noInitialRun: true -// }; -// -// 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> - <head> - <title>Demo</title> - <script type='text/javascript'> - var Module = { - noInitialRun: true - }; +// See browser tests for examples (tests/runner.py, search for sdl_). Run with +// python tests/runner.py browser - // implement print - var print = function(text) { - var element = document.getElementById('output') - element.innerHTML = text.replace('\n', '<br>', 'g') + element.innerHTML; - } - </script> - <script src='doom.ccsimple.js' type='text/javascript'></script> - <script type='text/javascript'> - function onLoad() { - // Pass canvas and context to the generated code, and do the actual run() here - Module.canvas = document.getElementById('canvas'); - Module.run(); - } - </script> - <body onload='onLoad()' style='background-color: black; color: white'> - <center> - <canvas id='canvas' width='320' height='200'></canvas> - </center> - <div id='output'></div> - </body> -</html> -*/ - -// Other stuff to take into account: -// -// * Make sure alpha values are proper in your input. If they are all 0, everything will be transparent! -// -// * Your code should not write a 32-bit value and expect that to set an RGBA pixel. -// The reason is that that data will be read as 8-bit values, and according to the -// load-store consistency assumption, it should be written that way (see docs/paper.pdf). -// Instead, do something like *ptr++ = R; *ptr++ = G; *ptr++ = B; -// -// * A normal C++ main loop with SDL_Delay will not work in JavaScript - there is no way -// to wait for a short time without locking up the web page entirely. The simplest -// solution here is to have a singleIteration() function which is a single loop -// iteration, and from JS to do something like setInterval(_singleIteration, 1/30) -// -// * SDL_Quit does nothing. - -mergeInto(LibraryManager.library, { +var LibrarySDL = { $SDL__deps: ['$FS', '$Browser'], $SDL: { defaults: { @@ -88,27 +16,76 @@ mergeInto(LibraryManager.library, { surfaces: {}, events: [], - audios: [null], fonts: [null], + audios: [null], + music: { + audio: null, + volume: 1.0 + }, + mixerFrequency: 22050, + mixerFormat: 0x8010, // AUDIO_S16LSB + mixerNumChannels: 2, + mixerChunkSize: 1024, + keyboardState: null, + shiftKey: false, + ctrlKey: false, + altKey: false, + startTime: null, mouseX: 0, mouseY: 0, + buttonState: 0, + DOMButtons: [0, 0, 0], + + DOMEventToSDLEvent: {}, - keyCodes: { // DOM code ==> SDL code + keyCodes: { // DOM code ==> SDL code. See https://developer.mozilla.org/en/Document_Object_Model_%28DOM%29/KeyboardEvent and SDL_keycode.h 38: 1106, // up arrow 40: 1105, // down arrow 37: 1104, // left arrow 39: 1103, // right arrow + 33: 1099, // pagedup + 34: 1102, // pagedown + 17: 305, // control (right, or left) 18: 308, // alt - 109: 45, // minus - 16: 304 // shift + 173: 45, // minus + 16: 304, // shift + + 96: 88 | 1<<10, // keypad 0 + 97: 89 | 1<<10, // keypad 1 + 98: 90 | 1<<10, // keypad 2 + 99: 91 | 1<<10, // keypad 3 + 100: 92 | 1<<10, // keypad 4 + 101: 93 | 1<<10, // keypad 5 + 102: 94 | 1<<10, // keypad 6 + 103: 95 | 1<<10, // keypad 7 + 104: 96 | 1<<10, // keypad 8 + 105: 97 | 1<<10, // keypad 9 + + 112: 58 | 1<<10, // F1 + 113: 59 | 1<<10, // F2 + 114: 60 | 1<<10, // F3 + 115: 61 | 1<<10, // F4 + 116: 62 | 1<<10, // F5 + 117: 63 | 1<<10, // F6 + 118: 64 | 1<<10, // F7 + 119: 65 | 1<<10, // F8 + 120: 66 | 1<<10, // F9 + 121: 67 | 1<<10, // F10 + 122: 68 | 1<<10, // F11 + 123: 69 | 1<<10, // F12 + + 188: 44, // comma + 190: 46, // period + 191: 47, // slash (/) + 192: 96, // backtick/backquote (`) }, - scanCodes: { // SDL keycode ==> SDL scancode + scanCodes: { // SDL keycode ==> SDL scancode. See SDL_scancode.h 97: 4, // A 98: 5, 99: 6, @@ -135,25 +112,26 @@ mergeInto(LibraryManager.library, { 120: 27, 121: 28, 122: 29, // Z - 48: 30, // 0 - 49: 31, - 50: 32, - 51: 33, - 52: 34, - 53: 35, - 54: 36, - 55: 37, - 56: 38, - 57: 39, // 9 + 44: 54, // comma + 46: 55, // period + 47: 56, // slash + 49: 30, // 1 + 50: 31, + 51: 32, + 52: 33, + 53: 34, + 54: 35, + 55: 36, + 56: 37, + 57: 38, // 9 + 48: 39, // 0 13: 40, // return 9: 43, // tab + 27: 41, // escape 32: 44, // space 92: 49, // backslash - 47: 56, // slash - 1106: 82, // up arrow - 1105: 81, // down arrow - 1104: 80, // left arrow - 1103: 79 // right arrow + 305: 224, // ctrl + 308: 226, // alt }, structs: { @@ -249,31 +227,39 @@ mergeInto(LibraryManager.library, { return 'rgba(' + r + ',' + g + ',' + b + ',' + (a/255) + ')'; }, - makeSurface: function(width, height, flags, usePageCanvas, source) { + translateRGBAToColor: function(r, g, b, a) { + return (r << 24) + (g << 16) + (b << 8) + a; + }, + + makeSurface: function(width, height, flags, usePageCanvas, source, rmask, gmask, bmask, amask) { flags = flags || 0; var surf = _malloc(14*Runtime.QUANTUM_SIZE); // SDL_Surface has 14 fields of quantum size var buffer = _malloc(width*height*4); // TODO: only allocate when locked the first time var pixelFormat = _malloc(18*Runtime.QUANTUM_SIZE); flags |= 1; // SDL_HWSURFACE - this tells SDL_MUSTLOCK that this needs to be locked + //surface with SDL_HWPALETTE flag is 8bpp surface (1 byte) + var is_SDL_HWPALETTE = flags & 0x00200000; + var bpp = is_SDL_HWPALETTE ? 1 : 4; + {{{ 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', 'i32') }}} // SDL_Surface.pitch, assuming RGBA for now, + {{{ makeSetValue('surf+Runtime.QUANTUM_SIZE*4', '0', 'width * bpp', 'i32') }}} // SDL_Surface.pitch, assuming RGBA or indexed for now, // since that is what ImageData gives us in browsers {{{ 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.format', '0', '-2042224636', 'i32') }}} // SDL_PIXELFORMAT_RGBA8888 {{{ makeSetValue('pixelFormat + SDL.structs.PixelFormat.palette', '0', '0', 'i32') }}} // TODO - {{{ makeSetValue('pixelFormat + SDL.structs.PixelFormat.BitsPerPixel', '0', '32', 'i8') }}} // TODO - {{{ makeSetValue('pixelFormat + SDL.structs.PixelFormat.BytesPerPixel', '0', '4', 'i8') }}} // TODO + {{{ makeSetValue('pixelFormat + SDL.structs.PixelFormat.BitsPerPixel', '0', 'bpp * 8', 'i8') }}} + {{{ makeSetValue('pixelFormat + SDL.structs.PixelFormat.BytesPerPixel', '0', 'bpp', 'i8') }}} - {{{ makeSetValue('pixelFormat + SDL.structs.PixelFormat.Rmask', '0', '0xff', 'i32') }}} - {{{ makeSetValue('pixelFormat + SDL.structs.PixelFormat.Gmask', '0', '0xff', 'i32') }}} - {{{ makeSetValue('pixelFormat + SDL.structs.PixelFormat.Bmask', '0', '0xff', 'i32') }}} - {{{ makeSetValue('pixelFormat + SDL.structs.PixelFormat.Amask', '0', '0xff', 'i32') }}} + {{{ makeSetValue('pixelFormat + SDL.structs.PixelFormat.Rmask', '0', 'rmask || 0x000000ff', 'i32') }}} + {{{ makeSetValue('pixelFormat + SDL.structs.PixelFormat.Gmask', '0', 'gmask || 0x0000ff00', 'i32') }}} + {{{ makeSetValue('pixelFormat + SDL.structs.PixelFormat.Bmask', '0', 'bmask || 0x00ff0000', 'i32') }}} + {{{ makeSetValue('pixelFormat + SDL.structs.PixelFormat.Amask', '0', 'amask || 0xff000000', 'i32') }}} // Decide if we want to use WebGL or not var useWebGL = (flags & 0x04000000) != 0; // SDL_OPENGL @@ -285,10 +271,7 @@ mergeInto(LibraryManager.library, { } else { canvas = Module['canvas']; } - var ctx = Browser.createContext(canvas, useWebGL); - if (usePageCanvas) { - Module.ctx = ctx; - } + var ctx = Browser.createContext(canvas, useWebGL, usePageCanvas); SDL.surfaces[surf] = { width: width, height: height, @@ -301,11 +284,54 @@ mergeInto(LibraryManager.library, { flags: flags, locked: 0, usePageCanvas: usePageCanvas, - source: source + source: source, + + isFlagSet: function (flag) { + return flags & flag; + } }; + return surf; }, + // Copy data from the C++-accessible storage to the canvas backing + // for surface with HWPALETTE flag(8bpp depth) + copyIndexedColorData: function(surfData, rX, rY, rW, rH) { + // HWPALETTE works with palette + // setted by SDL_SetColors + if (!surfData.colors) { + return; + } + + var fullWidth = Module['canvas'].width; + var fullHeight = Module['canvas'].height; + + var startX = rX || 0; + var startY = rY || 0; + var endX = (rW || (fullWidth - startX)) + startX; + var endY = (rH || (fullHeight - startY)) + startY; + + var buffer = surfData.buffer; + var data = surfData.image.data; + var colors = surfData.colors; + + for (var y = startY; y < endY; ++y) { + var indexBase = y * fullWidth; + var colorBase = indexBase * 4; + for (var x = startX; x < endX; ++x) { + // HWPALETTE have only 256 colors (not rgba) + var index = {{{ makeGetValue('buffer + indexBase + x', '0', 'i8', null, true) }}}; + var color = colors[index] || [Math.floor(Math.random()*255),Math.floor(Math.random()*255),Math.floor(Math.random()*255)]; // XXX + var colorOffset = colorBase + x * 4; + + data[colorOffset ] = color[0]; + data[colorOffset +1] = color[1]; + data[colorOffset +2] = color[2]; + //unused: data[colorOffset +3] = color[3]; + } + } + }, + freeSurface: function(surf) { _free(SDL.surfaces[surf].buffer); _free(SDL.surfaces[surf].pixelFormat); @@ -315,73 +341,143 @@ mergeInto(LibraryManager.library, { receiveEvent: function(event) { switch(event.type) { - case 'keydown': case 'keyup': case 'mousedown': case 'mouseup': case 'mousemove': + case 'mousemove': + // workaround for firefox bug 750111 + event['movementX'] = event['mozMovementX']; + event['movementY'] = event['mozMovementY']; + // fall through + case 'keydown': case 'keyup': case 'mousedown': case 'mouseup': case 'DOMMouseScroll': + if (event.type == 'DOMMouseScroll') { + event = { + type: 'mousedown', + button: event.detail > 0 ? 4 : 3, + pageX: event.pageX, + pageY: event.pageY + }; + } else if (event.type == 'mousedown') { + SDL.DOMButtons[event.button] = 1; + } else if (event.type == 'mouseup') { + if (!SDL.DOMButtons[event.button]) return false; // ignore extra ups, can happen if we leave the canvas while pressing down, then return, + // since we add a mouseup in that case + SDL.DOMButtons[event.button] = 0; + } + SDL.events.push(event); + if (SDL.events.length >= 10000) { + Module.printErr('SDL event queue full, dropping earliest event'); + SDL.events.shift(); + } 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; + case 'mouseout': + // Un-press all pressed mouse buttons, because we might miss the release outside of the canvas + for (var i = 0; i < 3; i++) { + if (SDL.DOMButtons[i]) { + SDL.events.push({ + type: 'mouseup', + button: i, + pageX: event.pageX, + pageY: event.pageY + }); + SDL.DOMButtons[i] = 0; + } + } + break; } - //event.preventDefault(); return false; }, - + makeCEvent: function(event, ptr) { if (typeof event === 'number') { // This is a pointer to a native C event that was SDL_PushEvent'ed - _memcpy(ptr, event, SDL.structs.KeyboardEvent.__size__); + _memcpy(ptr, event, SDL.structs.KeyboardEvent.__size__); // XXX return; } switch(event.type) { case 'keydown': case 'keyup': { var down = event.type === 'keydown'; - var key = SDL.keyCodes[event.keyCode] || event.keyCode; + //Module.print('Received key event: ' + event.keyCode); + var key = event.keyCode; if (key >= 65 && key <= 90) { - key = String.fromCharCode(key).toLowerCase().charCodeAt(0); + key += 32; // make lowercase for SDL + } else { + key = SDL.keyCodes[event.keyCode] || event.keyCode; + } + var scan; + if (key >= 1024) { + scan = key - 1024; + } else { + scan = SDL.scanCodes[key] || key; } - var scan = SDL.scanCodes[key] || key; - {{{ makeSetValue('ptr', 'SDL.structs.KeyboardEvent.type', 'down ? 0x300 : 0x301', 'i32') }}} + {{{ makeSetValue('ptr', 'SDL.structs.KeyboardEvent.type', 'SDL.DOMEventToSDLEvent[event.type]', 'i32') }}} //{{{ makeSetValue('ptr', 'SDL.structs.KeyboardEvent.which', '1', 'i32') }}} {{{ makeSetValue('ptr', 'SDL.structs.KeyboardEvent.state', 'down ? 1 : 0', 'i8') }}} {{{ makeSetValue('ptr', 'SDL.structs.KeyboardEvent.repeat', '0', 'i8') }}} // TODO - {{{ makeSetValue('ptr', 'SDL.structs.KeyboardEvent.keysym + SDL.structs.keysym.scancode', 'scan', 'i8') }}} + {{{ makeSetValue('ptr', 'SDL.structs.KeyboardEvent.keysym + SDL.structs.keysym.scancode', 'scan', 'i32') }}} {{{ makeSetValue('ptr', 'SDL.structs.KeyboardEvent.keysym + SDL.structs.keysym.sym', 'key', 'i32') }}} {{{ makeSetValue('ptr', 'SDL.structs.KeyboardEvent.keysym + SDL.structs.keysym.mod', '0', 'i32') }}} - //{{{ makeSetValue('ptr', 'SDL.structs.KeyboardEvent.keysym + SDL.structs.keysym.unicode', 'key', 'i32') }}} + {{{ makeSetValue('ptr', 'SDL.structs.KeyboardEvent.keysym + SDL.structs.keysym.unicode', 'key', 'i32') }}} {{{ makeSetValue('SDL.keyboardState', 'SDL.keyCodes[event.keyCode] || event.keyCode', 'event.type == "keydown"', 'i8') }}}; + SDL.shiftKey = event.shiftKey; + SDL.ctrlKey = event.ctrlKey; + SDL.altKey = event.altKey; + break; } - case 'mousedown': case 'mouseup': case 'mousemove': { - var x = event.pageX - Module['canvas'].offsetLeft; - var y = event.pageY - Module['canvas'].offsetTop; + case 'mousedown': case 'mouseup': + if (event.type == 'mousedown') { + // SDL_BUTTON(x) is defined as (1 << ((x)-1)). SDL buttons are 1-3, + // and DOM buttons are 0-2, so this means that the below formula is + // correct. + SDL.buttonState |= 1 << event.button; + } else if (event.type == 'mouseup') { + SDL.buttonState = 0; + } + // fall through + case 'mousemove': { + if (Browser.pointerLock) { + // When the pointer is locked, calculate the coordinates + // based on the movement of the mouse. + var movementX = Browser.getMovementX(event); + var movementY = Browser.getMovementY(event); + var x = SDL.mouseX + movementX; + var y = SDL.mouseY + movementY; + } else { + // Otherwise, calculate the movement based on the changes + // in the coordinates. + var x = event.pageX - Module["canvas"].offsetLeft; + var y = event.pageY - Module["canvas"].offsetTop; + var movementX = x - SDL.mouseX; + var movementY = y - SDL.mouseY; + } if (event.type != 'mousemove') { var down = event.type === 'mousedown'; - {{{ makeSetValue('ptr', 'SDL.structs.MouseButtonEvent.type', 'down ? 0x401 : 0x402', 'i32') }}}; + {{{ makeSetValue('ptr', 'SDL.structs.MouseButtonEvent.type', 'SDL.DOMEventToSDLEvent[event.type]', 'i32') }}}; {{{ makeSetValue('ptr', 'SDL.structs.MouseButtonEvent.button', 'event.button+1', 'i8') }}}; // DOM buttons are 0-2, SDL 1-3 {{{ makeSetValue('ptr', 'SDL.structs.MouseButtonEvent.state', 'down ? 1 : 0', 'i8') }}}; {{{ makeSetValue('ptr', 'SDL.structs.MouseButtonEvent.x', 'x', 'i32') }}}; {{{ makeSetValue('ptr', 'SDL.structs.MouseButtonEvent.y', 'y', 'i32') }}}; } else { - {{{ makeSetValue('ptr', 'SDL.structs.MouseMotionEvent.type', '0x400', 'i32') }}}; - {{{ makeSetValue('ptr', 'SDL.structs.MouseMotionEvent.button', 'event.button', 'i8') }}}; - {{{ makeSetValue('ptr', 'SDL.structs.MouseMotionEvent.state', 'down ? 1 : 0', 'i8') }}}; + {{{ makeSetValue('ptr', 'SDL.structs.MouseMotionEvent.type', 'SDL.DOMEventToSDLEvent[event.type]', 'i32') }}}; + {{{ makeSetValue('ptr', 'SDL.structs.MouseMotionEvent.state', 'SDL.buttonState', 'i8') }}}; {{{ makeSetValue('ptr', 'SDL.structs.MouseMotionEvent.x', 'x', 'i32') }}}; {{{ makeSetValue('ptr', 'SDL.structs.MouseMotionEvent.y', 'y', 'i32') }}}; - {{{ makeSetValue('ptr', 'SDL.structs.MouseMotionEvent.xrel', 'x - SDL.mouseX', 'i32') }}}; - {{{ makeSetValue('ptr', 'SDL.structs.MouseMotionEvent.yrel', 'y - SDL.mouseY', 'i32') }}}; + {{{ makeSetValue('ptr', 'SDL.structs.MouseMotionEvent.xrel', 'movementX', 'i32') }}}; + {{{ makeSetValue('ptr', 'SDL.structs.MouseMotionEvent.yrel', 'movementY', 'i32') }}}; } SDL.mouseX = x; SDL.mouseY = y; break; } - default: - throw 'Unhandled SDL event: ' + event.type; + default: throw 'Unhandled SDL event: ' + event.type; } }, @@ -397,6 +493,30 @@ mergeInto(LibraryManager.library, { return ret; }, + // Sound + + allocateChannels: function(num) { // called from Mix_AllocateChannels and init + if (SDL.numChannels && SDL.numChannels >= num) return; + SDL.numChannels = num; + SDL.channels = []; + for (var i = 0; i < num; i++) { + SDL.channels[i] = { + audio: null, + volume: 1.0 + }; + } + }, + + setGetVolume: function(info, volume) { + if (!info) return 0; + var ret = info.volume * 128; // MIX_MAX_VOLUME + if (volume != -1) { + info.volume = volume / 128; + if (info.audio) info.audio.volume = info.volume; + } + return ret; + }, + // Debugging debugSurface: function(surfData) { @@ -420,7 +540,6 @@ mergeInto(LibraryManager.library, { return SDL.version; }, - SDL_Init__deps: ['$SDL'], SDL_Init: function(what) { SDL.startTime = Date.now(); ['keydown', 'keyup'].forEach(function(event) { @@ -428,6 +547,12 @@ mergeInto(LibraryManager.library, { }); SDL.keyboardState = _malloc(0x10000); _memset(SDL.keyboardState, 0, 0x10000); + // Initialize this structure carefully for closure + SDL.DOMEventToSDLEvent['keydown'] = 0x300 /* SDL_KEYDOWN */; + SDL.DOMEventToSDLEvent['keyup'] = 0x301 /* SDL_KEYUP */; + SDL.DOMEventToSDLEvent['mousedown'] = 0x401 /* SDL_MOUSEBUTTONDOWN */; + SDL.DOMEventToSDLEvent['mouseup'] = 0x402 /* SDL_MOUSEBUTTONUP */; + SDL.DOMEventToSDLEvent['mousemove'] = 0x400 /* SDL_MOUSEMOTION */; return 0; // success }, @@ -454,8 +579,39 @@ mergeInto(LibraryManager.library, { return -1; // -1 == all modes are ok. TODO }, + SDL_VideoModeOK: function(width, height, depth, flags) { + // SDL_VideoModeOK returns 0 if the requested mode is not supported under any bit depth, or returns the + // bits-per-pixel of the closest available mode with the given width, height and requested surface flags + return depth; // all modes are ok. + }, + + SDL_VideoDriverName: function(buf, max_size) { + if (SDL.startTime === null) { + return 0; //return NULL + } + //driverName - emscripten_sdl_driver + var driverName = [101, 109, 115, 99, 114, 105, 112, 116, 101, + 110, 95, 115, 100, 108, 95, 100, 114, 105, 118, 101, 114]; + + var index = 0; + var size = driverName.length; + + if (max_size <= size) { + size = max_size - 1; //-1 cause null-terminator + } + + while (index < size) { + var value = driverName[index]; + {{{ makeSetValue('buf', 'index', 'value', 'i8') }}}; + index++; + } + + {{{ makeSetValue('buf', 'index', '0', 'i8') }}}; + return buf; + }, + SDL_SetVideoMode: function(width, height, depth, flags) { - ['mousedown', 'mouseup', 'mousemove'].forEach(function(event) { + ['mousedown', 'mouseup', 'mousemove', 'DOMMouseScroll', 'mouseout'].forEach(function(event) { Module['canvas'].addEventListener(event, SDL.receiveEvent, true); }); Module['canvas'].width = width; @@ -463,6 +619,14 @@ mergeInto(LibraryManager.library, { return SDL.screen = SDL.makeSurface(width, height, flags, true, 'screen'); }, + SDL_GetVideoSurface: function() { + return SDL.screen; + }, + + SDL_QuitSubSystem: function(flags) { + Module.print('SDL_QuitSubSystem called (and ignored)'); + }, + SDL_Quit: function() { for (var i = 0; i < SDL.audios; i++) { SDL.audios[i].pause(); @@ -475,7 +639,7 @@ mergeInto(LibraryManager.library, { var surfData = SDL.surfaces[surf]; surfData.locked++; - if (surfData.locked > 1) return; + if (surfData.locked > 1) return 0; if (!surfData.image) { surfData.image = surfData.ctx.getImageData(0, 0, surfData.width, surfData.height); @@ -489,17 +653,44 @@ mergeInto(LibraryManager.library, { } if (SDL.defaults.copyOnLock) { // Copy pixel data to somewhere accessible to 'C/C++' + if (surfData.isFlagSet(0x00200000 /* SDL_HWPALETTE */)) { + // If this is neaded then + // we should compact the data from 32bpp to 8bpp index. + // I think best way to implement this is use + // additional colorMap hash (color->index). + // Something like this: + // + // var size = surfData.width * surfData.height; + // var data = ''; + // for (var i = 0; i<size; i++) { + // var color = SDL.translateRGBAToColor( + // surfData.image.data[i*4 ], + // surfData.image.data[i*4 +1], + // surfData.image.data[i*4 +2], + // 255); + // var index = surfData.colorMap[color]; + // {{{ makeSetValue('surfData.buffer', 'i', 'index', 'i8') }}}; + // } + throw 'CopyOnLock is not supported for SDL_LockSurface with SDL_HWPALETTE flag set' + new Error().stack; + } else { +#if USE_TYPED_ARRAYS == 2 + HEAPU8.set(surfData.image.data, surfData.buffer); +#else var num2 = surfData.image.data.length; - // TODO: use typed array Set() for (var i = 0; i < num2; i++) { {{{ makeSetValue('surfData.buffer', 'i', 'surfData.image.data[i]', 'i8') }}}; } +#endif + } } + // Mark in C/C++-accessible SDL structure // 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*Runtime.QUANTUM_SIZE', 'surfData.buffer', 'void*') }}}; + + return 0; }, // Copy data from the C++-accessible storage to the canvas backing @@ -510,8 +701,10 @@ mergeInto(LibraryManager.library, { if (surfData.locked > 0) return; // Copy pixel data to image - var num = surfData.image.data.length; - if (!surfData.colors) { + if (surfData.isFlagSet(0x00200000 /* SDL_HWPALETTE */)) { + SDL.copyIndexedColorData(surfData); + } else if (!surfData.colors) { + var num = surfData.image.data.length; var data = surfData.image.data; var buffer = surfData.buffer; #if USE_TYPED_ARRAYS == 2 @@ -533,7 +726,7 @@ mergeInto(LibraryManager.library, { for (var i = 0; i < num; i++) { // We may need to correct signs here. Potentially you can hardcode a write of 255 to alpha, say, and // the compiler may decide to write -1 in the llvm bitcode... - data[i] = {{{ makeGetValue('buffer', 'i', 'i8') + (CORRECT_SIGNS ? '&0xff' : '') }}}; + data[i] = {{{ makeGetValue('buffer', 'i', 'i8', null, true) }}}; if (i % 4 == 3) data[i] = 0xff; } #endif @@ -547,7 +740,7 @@ mergeInto(LibraryManager.library, { var base = y*width*4; for (var x = 0; x < width; x++) { // See comment above about signs - var val = {{{ makeGetValue('s++', '0', 'i8') + (CORRECT_SIGNS ? '&0xff' : '') }}}; + var val = {{{ makeGetValue('s++', '0', 'i8', null, true) }}}; var color = colors[val] || [Math.floor(Math.random()*255),Math.floor(Math.random()*255),Math.floor(Math.random()*255)]; // XXX var start = base + x*4; data[start] = color[0]; @@ -571,6 +764,10 @@ mergeInto(LibraryManager.library, { // We actually do the whole screen in Unlock... }, + SDL_UpdateRects: function(surf, numrects, rects) { + // We actually do the whole screen in Unlock... + }, + SDL_Delay: function(delay) { throw 'SDL_Delay called! Potential infinite loop, quitting. ' + new Error().stack; }, @@ -588,12 +785,33 @@ mergeInto(LibraryManager.library, { return SDL.keyboardState; }, + SDL_GetKeyState__deps: ['SDL_GetKeyboardState'], + SDL_GetKeyState: function() { + return _SDL_GetKeyboardState(); + }, + + SDL_GetModState: function() { + // TODO: numlock, capslock, etc. + return (SDL.shiftKey ? 0x0001 & 0x0002 : 0) | // KMOD_LSHIFT & KMOD_RSHIFT + (SDL.ctrlKey ? 0x0040 & 0x0080 : 0) | // KMOD_LCTRL & KMOD_RCTRL + (SDL.altKey ? 0x0100 & 0x0200 : 0); // KMOD_LALT & KMOD_RALT + }, + SDL_GetMouseState: function(x, y) { if (x) {{{ makeSetValue('x', '0', 'SDL.mouseX', 'i32') }}}; if (y) {{{ makeSetValue('y', '0', 'SDL.mouseY', 'i32') }}}; return 0; }, + SDL_WarpMouse: function(x, y) { + return; // TODO: implement this in a non-buggy way. Need to keep relative mouse movements correct after calling this + SDL.events.push({ + type: 'mousemove', + pageX: x + Module['canvas'].offsetLeft, + pageY: y + Module['canvas'].offsetTop + }); + }, + SDL_ShowCursor: function(toggle) { // TODO }, @@ -603,7 +821,7 @@ mergeInto(LibraryManager.library, { }, SDL_CreateRGBSurface: function(flags, width, height, depth, rmask, gmask, bmask, amask) { - return SDL.makeSurface(width, height, flags, false, 'CreateRGBSurface'); + return SDL.makeSurface(width, height, flags, false, 'CreateRGBSurface', rmask, gmask, bmask, amask); }, SDL_DisplayFormatAlpha: function(surf) { @@ -634,13 +852,28 @@ mergeInto(LibraryManager.library, { dr = { x: 0, y: 0, w: -1, h: -1 }; } dstData.ctx.drawImage(srcData.canvas, sr.x, sr.y, sr.w, sr.h, dr.x, dr.y, sr.w, sr.h); + if (dst != SDL.screen) { + // XXX As in IMG_Load, for compatibility we write out |pixels| + console.log('WARNING: copying canvas data to memory for compatibility'); + _SDL_LockSurface(dst); + dstData.locked--; // The surface is not actually locked in this hack + } return 0; }, SDL_FillRect: function(surf, rect, color) { var surfData = SDL.surfaces[surf]; assert(!surfData.locked); // but we could unlock and re-lock if we must.. - var r = SDL.loadRect(rect); + + if (surfData.isFlagSet(0x00200000 /* SDL_HWPALETTE */)) { + //in SDL_HWPALETTE color is index (0..255) + //so we should translate 1 byte value to + //32 bit canvas + color = surfData.colors[color] || [0, 0, 0, 255]; + color = SDL.translateRGBAToColor(color[0], color[1], color[2], 255); + } + + var r = rect ? SDL.loadRect(rect) : { x: 0, y: 0, w: surfData.width, h: surfData.height }; surfData.ctx.save(); surfData.ctx.fillStyle = SDL.translateColorToCSSRGBA(color); surfData.ctx.fillRect(r.x, r.y, r.w, r.h); @@ -670,42 +903,102 @@ mergeInto(LibraryManager.library, { SDL_PushEvent: function(ptr) { SDL.events.push(ptr); // XXX Should we copy it? Not clear from API - return 0; }, + SDL_PeepEvents: function(events, numEvents, action, from, to) { + switch(action) { + case 2: { // SDL_GETEVENT + assert(numEvents == 1); + var got = 0; + while (SDL.events.length > 0 && numEvents > 0) { + var type = SDL.DOMEventToSDLEvent[SDL.events[0].type]; + if (type < from || type > to) break; + SDL.makeCEvent(SDL.events.shift(), events); + got++; + numEvents--; + // events += sizeof(..) + } + return got; + } + default: throw 'SDL_PeepEvents does not yet support that action: ' + action; + } + }, + + SDL_PumpEvents: function(){}, + SDL_SetColors: function(surf, colors, firstColor, nColors) { var surfData = SDL.surfaces[surf]; - surfData.colors = []; - for (var i = firstColor; i < nColors; i++) { - surfData.colors[i] = Array_copy(colors + i*4, colors + i*4 + 4); + + // we should create colors array + // only once cause client code + // often wants to change portion + // of palette not all palette. + if (!surfData.colors) { + surfData.colors = []; + } + + for (var i = firstColor; i < firstColor + nColors; i++) { + surfData.colors[i] = [ + {{{ makeGetValue('colors', 'i*4', 'i8', null, true) }}}, + {{{ makeGetValue('colors', 'i*4 + 1', 'i8', null, true) }}}, + {{{ makeGetValue('colors', 'i*4 + 2', 'i8', null, true) }}}, + {{{ makeGetValue('colors', 'i*4 + 3', 'i8', null, true) }}} + ]; } + return 1; }, SDL_MapRGB: function(fmt, r, g, b) { // Canvas screens are always RGBA - return r + (g << 8) + (b << 16); + return 0xff+((b&0xff)<<8)+((g&0xff)<<16)+((r&0xff)<<24) + }, + + SDL_MapRGBA: function(fmt, r, g, b, a) { + // Canvas screens are always RGBA + return (a&0xff)+((b&0xff)<<8)+((g&0xff)<<16)+((r&0xff)<<24) }, SDL_WM_GrabInput: function() {}, - SDL_ShowCursor: function() {}, // SDL_Image + IMG_Init: function(flags) { + return flags; // We support JPG, PNG, TIF because browsers do + }, + + IMG_Load__deps: ['SDL_LockSurface'], IMG_Load: function(filename) { filename = FS.standardizePath(Pointer_stringify(filename)); - var raw = preloadedImages[filename]; - assert(raw, 'Cannot find preloaded image ' + filename); + if (filename[0] == '/') { + // Convert the path to relative + filename = filename.substr(1); + } + var raw = Module["preloadedImages"][filename]; + if (!raw) { + Runtime.warnOnce('Cannot find preloaded image ' + filename); + return 0; + } var surf = SDL.makeSurface(raw.width, raw.height, 0, false, 'load:' + filename); var surfData = SDL.surfaces[surf]; surfData.ctx.drawImage(raw, 0, 0, raw.width, raw.height, 0, 0, raw.width, raw.height); + // XXX SDL does not specify that loaded images must have available pixel data, in fact + // there are cases where you just want to blit them, so you just need the hardware + // accelerated version. However, code everywhere seems to assume that the pixels + // are in fact available, so we retrieve it here. This does add overhead though. + _SDL_LockSurface(surf); + surfData.locked--; // The surface is not actually locked in this hack return surf; }, + SDL_LoadBMP: 'IMG_Load', + SDL_LoadBMP_RW: 'IMG_Load', // SDL_Audio SDL_OpenAudio: function(desired, obtained) { + SDL.allocateChannels(32); + // FIXME: Assumes 16-bit audio assert(obtained === 0, 'Cannot return obtained SDL audio params'); @@ -774,24 +1067,52 @@ mergeInto(LibraryManager.library, { SDL_CondWait: function() {}, SDL_DestroyCond: function() {}, + SDL_StartTextInput: function() {}, // TODO + SDL_StopTextInput: function() {}, // TODO + // SDL Mixer Mix_OpenAudio: function(frequency, format, channels, chunksize) { + SDL.allocateChannels(32); + SDL.mixerFrequency = frequency; + SDL.mixerFormat = format; + SDL.mixerNumChannels = channels; + SDL.mixerChunkSize = chunksize; return 0; }, - Mix_HookMusicFinished: function(func) { - SDL.hookMusicFinished = func; + Mix_CloseAudio: 'SDL_CloseAudio', + + Mix_AllocateChannels: function(num) { + SDL.allocateChannels(num); + return num; + }, + + Mix_ChannelFinished: function(func) { + SDL.channelFinished = func; + }, + + Mix_Volume: function(channel, volume) { + if (channel == -1) { + for (var i = 0; i < SDL.numChannels-1; i++) { + _Mix_Volume(i, volume); + } + return _Mix_Volume(SDL.numChannels-1, volume); + } + return SDL.setGetVolume(SDL.channels[channel], volume); }, - Mix_VolumeMusic: function(func) { - return 0; // TODO + Mix_SetPanning: function() { + return 0; // error }, Mix_LoadWAV_RW: function(filename, freesrc) { filename = FS.standardizePath(Pointer_stringify(filename)); - var raw = preloadedAudios[filename]; - assert(raw, 'Cannot find preloaded audio ' + filename); + var raw = Module["preloadedAudios"][filename]; + if (!raw) { + Runtime.warnOnce('Cannot find preloaded audio ' + filename); + return 0; + } var id = SDL.audios.length; SDL.audios.push({ source: filename, @@ -800,50 +1121,129 @@ mergeInto(LibraryManager.library, { return id; }, + Mix_QuickLoad_RAW: function(mem, len) { + var audio = new Audio(); + audio['mozSetup'](SDL.mixerNumChannels, SDL.mixerFrequency); + var numSamples = (len / (SDL.mixerNumChannels * 2)) | 0; + var buffer = new Float32Array(numSamples); + for (var i = 0; i < numSamples; ++i) { + buffer[i] = ({{{ makeGetValue('mem', 'i*2', 'i16', 0, 0) }}}) / 0x8000; // hardcoded 16-bit audio, signed (TODO: reSign if not ta2?) + } + var id = SDL.audios.length; + SDL.audios.push({ + source: '', + audio: audio, + buffer: buffer + }); + return id; + }, + Mix_FreeChunk: function(id) { - SDL.audios[id].audio.pause(); SDL.audios[id] = null; }, 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 1; // XXX should return channel + var info = SDL.audios[id]; + if (!info) return 0; + var audio = info.audio; + if (!audio) return 0; + if (channel == -1) { + channel = 0; + for (var i = 0; i < SDL.numChannels; i++) { + if (!SDL.channels[i].audio) { + channel = i; + break; + } + } + } + var channelInfo = SDL.channels[channel]; + channelInfo.audio = audio = audio.cloneNode(true); + if (SDL.channelFinished) { + audio['onended'] = function() { // TODO: cache these + Runtime.getFuncWrapper(SDL.channelFinished)(channel); + } + } + if (info.buffer) { + audio['mozSetup'](SDL.mixerNumChannels, SDL.mixerFrequency); + audio["mozWriteAudio"](info.buffer); + } else { + audio.play(); + } + audio.volume = channelInfo.volume; + return channel; }, Mix_PlayChannelTimed: 'Mix_PlayChannel', // XXX ignore Timing + Mix_FadingChannel: function(channel) { + return 0; // MIX_NO_FADING, TODO + }, + + Mix_HaltChannel: function(channel) { + var info = SDL.channels[channel]; + if (info.audio) { + info.audio.pause(); + info.audio = null; + } + if (SDL.channelFinished) { + Runtime.getFuncWrapper(SDL.channelFinished)(channel); + } + return 0; + }, + + Mix_HookMusicFinished__deps: ['Mix_HaltMusic'], + Mix_HookMusicFinished: function(func) { + SDL.hookMusicFinished = func; + if (SDL.music.audio) { // ensure the callback will be called, if a music is already playing + SDL.music.audio['onended'] = _Mix_HaltMusic; + } + }, + + Mix_VolumeMusic: function(volume) { + return SDL.setGetVolume(SDL.music, volume); + }, + Mix_LoadMUS: 'Mix_LoadWAV_RW', + Mix_FreeMusic: 'Mix_FreeChunk', + Mix_PlayMusic__deps: ['Mix_HaltMusic'], Mix_PlayMusic: function(id, loops) { loops = Math.max(loops, 1); var audio = SDL.audios[id].audio; + if (!audio) return 0; audio.loop = loops != 1; // TODO: handle N loops for finite N - audio.play(); - SDL.music = audio; + if (SDL.audios[id].buffer) { + audio["mozWriteAudio"](SDL.audios[id].buffer); + } else { + audio.play(); + } + audio.volume = SDL.music.volume; + audio['onended'] = _Mix_HaltMusic; // will send callback + SDL.music.audio = audio; return 0; }, - Mix_PauseMusic: function(id) { - var audio = SDL.audios[id].audio; + Mix_PauseMusic: function() { + var audio = SDL.music.audio; + if (!audio) return 0; audio.pause(); return 0; }, - Mix_ResumeMusic: function(id) { - var audio = SDL.audios[id].audio; + Mix_ResumeMusic: function() { + var audio = SDL.music.audio; + if (!audio) return 0; audio.play(); return 0; }, Mix_HaltMusic: function() { - var audio = SDL.music; + var audio = SDL.music.audio; if (!audio) return 0; audio.src = audio.src; // rewind audio.pause(); - SDL.music = null; + SDL.music.audio = null; if (SDL.hookMusicFinished) { FUNCTION_TABLE[SDL.hookMusicFinished](); } @@ -854,6 +1254,14 @@ mergeInto(LibraryManager.library, { Mix_FadeOutMusic: 'Mix_HaltMusic', // XXX ignore fading out effect + Mix_PlayingMusic: function() { + return (SDL.music.audio && !SDL.music.audio.paused) ? 1 : 0; + }, + + Mix_PausedMusic: function() { + return (SDL.music.audio && SDL.music.audio.paused) ? 1 : 0; + }, + // SDL TTF TTF_Init: function() { return 0 }, @@ -987,5 +1395,8 @@ mergeInto(LibraryManager.library, { window.clearTimeout(id); return true; } -}); +}; + +autoAddDeps(LibrarySDL, '$SDL'); +mergeInto(LibraryManager.library, LibrarySDL); diff --git a/src/modules.js b/src/modules.js index 2bed1756..0f3b483b 100644 --- a/src/modules.js +++ b/src/modules.js @@ -259,8 +259,9 @@ var LibraryManager = { load: function() { assert(!this.library); - for (var suffix in set('', '_sdl', '_browser', '_gl', '_glut', '_xlib', '_egl')) { - eval(processMacros(preprocess(read('library' + suffix + '.js')))); + var libraries = ['library.js', 'library_browser.js', 'library_sdl.js', 'library_gl.js', 'library_glut.js', 'library_xlib.js', 'library_egl.js', 'library_gc.js'].concat(additionalLibraries); + for (var i = 0; i < libraries.length; i++) { + eval(processMacros(preprocess(read(libraries[i])))); } }, diff --git a/src/parseTools.js b/src/parseTools.js index 8ccf1f9f..86e3c643 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -169,7 +169,15 @@ function isFunctionDef(token, out) { function isFunctionType(type, out) { type = type.replace(/"[^"]+"/g, '".."'); - var parts = type.split(' '); + var parts; + // hackish, but quick splitting of function def parts. this must be fast as it happens a lot + if (type[0] != '[') { + parts = type.split(' '); + } else { + var index = type.search(']'); + index += type.substr(index).search(' '); + parts = [type.substr(0, index), type.substr(index+1)]; + } if (pointingLevels(type) !== 1) return false; var text = removeAllPointing(parts.slice(1).join(' ')); if (!text) return false; @@ -767,7 +775,7 @@ function generateStructTypes(type) { if (USE_TYPED_ARRAYS == 2 && type == 'i64') { return ['i64', 0, 0, 0, 'i32', 0, 0, 0]; } - return [type].concat(zeros(Runtime.getNativeFieldSize(type))); + return [type].concat(zeros(Runtime.getNativeFieldSize(type)-1)); } // Avoid multiple concats by finding the size first. This is much faster @@ -986,7 +994,7 @@ function makeSetValue(ptr, pos, value, type, noNeedFirst, ignore, align, noSafe, value = range(typeData.fields.length).map(function(i) { return value + '.f' + i }); } for (var i = 0; i < typeData.fields.length; i++) { - ret.push(makeSetValue(ptr, pos + typeData.flatIndexes[i], value[i], typeData.fields[i], noNeedFirst)); + ret.push(makeSetValue(ptr, getFastValue(pos, '+', typeData.flatIndexes[i]), value[i], typeData.fields[i], noNeedFirst)); } return ret.join('; '); } @@ -1147,7 +1155,7 @@ function makeHEAPView(which, start, end) { // Assumes USE_TYPED_ARRAYS == 2 var size = parseInt(which.replace('U', '').replace('F', ''))/8; var mod = size == 1 ? '' : ('>>' + log2(size)); - return 'HEAP' + which + '.subarray(' + start + mod + ',' + end + mod + ')'; + return 'HEAP' + which + '.subarray((' + start + ')' + mod + ',(' + end + ')' + mod + ')'; } var PLUS_MUL = set('+', '*'); @@ -1163,7 +1171,7 @@ function getFastValue(a, op, b, type) { if (op == 'pow') { return Math.pow(a, b).toString(); } else { - return eval(a + op + b).toString(); + return eval(a + op + '(' + b + ')').toString(); // parens protect us from "5 - -12" being seen as "5--12" which is "(5--)12" } } if (op == 'pow') { @@ -1209,7 +1217,7 @@ function getFastValue(a, op, b, type) { return a; } } - return a + op + b; + return '(' + a + ')' + op + '(' + b + ')'; } function getFastValues(list, op, type) { @@ -1256,7 +1264,7 @@ function makePointer(slab, pos, allocator, type) { var evaled = typeof slab === 'string' ? eval(slab) : slab; de = dedup(evaled); if (de.length === 1 && de[0] === 0) { - slab = evaled.length; + slab = types.length; } // TODO: if not all zeros, at least filter out items with type === 0. requires cleverness to know how to skip at runtime though. also // be careful of structure padding @@ -1314,27 +1322,35 @@ function finalizeLLVMFunctionCall(item, noIndexizeFunctions) { // Warn about some types of casts, then fall through to the handling code below var oldType = item.params[0].type; var newType = item.type; - if (isPossiblyFunctionType(oldType) && isPossiblyFunctionType(newType) && - countNormalArgs(oldType) != countNormalArgs(newType)) { - warnOnce('Casting a function pointer type to another with a different number of arguments. See more info in the source'); - // This may be dangerous as clang generates different code for C and C++ calling conventions. The only problem - // case appears to be passing a structure by value, C will have (field1, field2) as function args, and the - // function will internally create a structure with that data, while C++ will have (struct* byVal) and it - // will create a copy before calling the function, then call it with a pointer to the copy. Mixing the two - // first of all leads to two copies being made, so this is a bad idea even regardless of Emscripten. But, - // what is a problem for Emscr ipten is that mixing these two calling conventions (say, calling a C one from - // C++) will then assume that (struct* byVal) is actually the same as (field1, field2). In native code, this - // is easily possible, you place the two fields on the stack and call the function (you know to place the - // values since there is 'byVal'). In Emscripten, though, this means we would need to always do one or the - // other of the two possibilities, for example, always passing by-value structs as (field1, field2). This - // would slow down everything, just to handle this corner case. (Which, just to point out how much of a - // corner case it is, does not appear to happen with nested structures!) - // - // The recommended solution for this problem is not to mix C and C++ calling conventions when passing structs - // by value. Either always pass structs by value within C code or C++ code, but not mixing the two by - // defining a function in one and calling it from the other (so, just changing .c to .cpp, or moving code - // from one file to another, would be enough to fix this), or, do not pass structs by value (which in general - // is inefficient, and worth avoiding if you can). + if (isPossiblyFunctionType(oldType) && isPossiblyFunctionType(newType)) { + var oldCount = countNormalArgs(oldType); + var newCount = countNormalArgs(newType); + if (oldCount != newCount && oldCount && newCount) { + warnOnce('Casting a function pointer type to another with a different number of arguments. See more info in the compiler source'); + if (VERBOSE) { + warnOnce('Casting a function pointer type to another with a different number of arguments: ' + oldType + ' vs. ' + newType + ', on ' + item.params[0].ident); + } + // This may be dangerous as clang generates different code for C and C++ calling conventions. The only problem + // case appears to be passing a structure by value, C will have (field1, field2) as function args, and the + // function will internally create a structure with that data, while C++ will have (struct* byVal) and it + // will create a copy before calling the function, then call it with a pointer to the copy. Mixing the two + // first of all leads to two copies being made, so this is a bad idea even regardless of Emscripten. But, + // what is a problem for Emscr ipten is that mixing these two calling conventions (say, calling a C one from + // C++) will then assume that (struct* byVal) is actually the same as (field1, field2). In native code, this + // is easily possible, you place the two fields on the stack and call the function (you know to place the + // values since there is 'byVal'). In Emscripten, though, this means we would need to always do one or the + // other of the two possibilities, for example, always passing by-value structs as (field1, field2). This + // would slow down everything, just to handle this corner case. (Which, just to point out how much of a + // corner case it is, does not appear to happen with nested structures!) + // + // The recommended solution for this problem is not to mix C and C++ calling conventions when passing structs + // by value. Either always pass structs by value within C code or C++ code, but not mixing the two by + // defining a function in one and calling it from the other (so, just changing .c to .cpp, or moving code + // from one file to another, would be enough to fix this), or, do not pass structs by value (which in general + // is inefficient, and worth avoiding if you can). + // + // Note that removing all arguments is acceptable, as a vast to void ()*. + } } } var temp = { diff --git a/src/postamble.js b/src/postamble.js index cf863669..10ac1888 100644 --- a/src/postamble.js +++ b/src/postamble.js @@ -32,28 +32,47 @@ 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'](); + if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']]; + while (Module['preRun'].length > 0) { + Module['preRun'].pop()(); + if (runDependencies > 0) { + // preRun added a dependency, run will be called later + return 0; + } + } } - var ret = null; - if (Module['_main']) { - preMain(); - ret = Module.callMain(args); - if (!Module['noExitRuntime']) { - exitRuntime(); + function doRun() { + var ret = 0; + if (Module['_main']) { + preMain(); + ret = Module.callMain(args); + if (!Module['noExitRuntime']) { + exitRuntime(); + } } + if (Module['postRun']) { + if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']]; + while (Module['postRun'].length > 0) { + Module['postRun'].pop()(); + } + } + return ret; } - if (Module['postRun']) { - Module['postRun'](); + if (Module['setStatus']) { + Module['setStatus']('Running...'); + setTimeout(function() { + setTimeout(function() { + Module['setStatus'](''); + }, 1); + doRun(); + }, 1); + return 0; + } else { + return doRun(); } - - return ret; } Module['run'] = run; diff --git a/src/preamble.js b/src/preamble.js index 7c2b1a50..ae00b796 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -76,7 +76,7 @@ function SAFE_HEAP_STORE(dest, value, type, ignore) { Module.print('SAFE_HEAP store: ' + [dest, type, value, ignore]); #endif - if (!ignore && !value && value !== 0 && value !== false && !isNaN(value)) { // false can be the result of a mathop comparator; NaN can be the result of a math function + if (!ignore && !value && (value === null || value === undefined)) { throw('Warning: Writing an invalid value of ' + JSON.stringify(value) + ' at ' + dest + ' :: ' + new Error().stack + '\n'); } SAFE_HEAP_ACCESS(dest, type, true, ignore); @@ -315,8 +315,10 @@ var globalScope = this; // -s EXPORTED_FUNCTIONS='["_func1","_func2"]' // // @param ident The name of the C function (note that C++ functions will be name-mangled - use extern "C") -// @param returnType The return type of the function, one of the JS types 'number' or 'string' (use 'number' for any C pointer). -// @param argTypes An array of the types of arguments for the function (if there are no arguments, this can be ommitted). Types are as in returnType. +// @param returnType The return type of the function, one of the JS types 'number', 'string' or 'array' (use 'number' for any C pointer, and +// 'array' for JavaScript arrays and typed arrays). +// @param argTypes An array of the types of arguments for the function (if there are no arguments, this can be ommitted). Types are as in returnType, +// except that 'array' is not possible (there is no way for us to know the length of the array) // @param args An array of the arguments to the function, as native JS values (as in returnType) // Note that string arguments will be stored on the stack (the JS string will become a C string on the stack). // @return The return value, as a native JS value (as in returnType) @@ -324,10 +326,16 @@ function ccall(ident, returnType, argTypes, args) { var stack = 0; function toC(value, type) { if (type == 'string') { + if (value === null || value === undefined || value === 0) return 0; // null string if (!stack) stack = Runtime.stackSave(); var ret = Runtime.stackAlloc(value.length+1); writeStringToMemory(value, ret); return ret; + } else if (type == 'array') { + if (!stack) stack = Runtime.stackSave(); + var ret = Runtime.stackAlloc(value.length); + writeArrayToMemory(value, ret); + return ret; } return value; } @@ -335,6 +343,7 @@ function ccall(ident, returnType, argTypes, args) { if (type == 'string') { return Pointer_stringify(value); } + assert(type != 'array'); return value; } try { @@ -713,40 +722,6 @@ function exitRuntime() { CorrectionsMonitor.print(); } - -// Copies a list of num items on the HEAP into a -// a normal JavaScript array of numbers -function Array_copy(ptr, num) { -#if USE_TYPED_ARRAYS == 1 - // TODO: In the SAFE_HEAP case, do some reading here, for debugging purposes - currently this is an 'unnoticed read'. - return Array.prototype.slice.call(IHEAP.subarray(ptr, ptr+num)); // Make a normal array out of the typed 'view' - // Consider making a typed array here, for speed? -#endif -#if USE_TYPED_ARRAYS == 2 - return Array.prototype.slice.call(HEAP8.subarray(ptr, ptr+num)); // Make a normal array out of the typed 'view' - // Consider making a typed array here, for speed? -#endif - return HEAP.slice(ptr, ptr+num); -} -Module['Array_copy'] = Array_copy; - -#if USE_TYPED_ARRAYS -// Copies a list of num items on the HEAP into a -// JavaScript typed array. -function TypedArray_copy(ptr, num, offset /*optional*/) { - // TODO: optimize this! - if (offset === undefined) { - offset = 0; - } - var arr = new Uint8Array(num - offset); - for (var i = offset; i < num; ++i) { - arr[i - offset] = {{{ makeGetValue('ptr', 'i', 'i8') }}}; - } - return arr.buffer; -} -Module['TypedArray_copy'] = TypedArray_copy; -#endif - function String_len(ptr) { var i = 0; while ({{{ makeGetValue('ptr', 'i', 'i8') }}}) i++; // Note: should be |!= 0|, technically. But this helps catch bugs with undefineds @@ -754,17 +729,6 @@ function String_len(ptr) { } Module['String_len'] = String_len; -// Copies a C-style string, terminated by a zero, from the HEAP into -// a normal JavaScript array of numbers -function String_copy(ptr, addZero) { - var len = String_len(ptr); - if (addZero) len++; - var ret = Array_copy(ptr, len); - if (addZero) ret[len-1] = 0; - return ret; -} -Module['String_copy'] = String_copy; - // Tools // This processes a JS string into a C-line array of numbers, 0-terminated. @@ -830,6 +794,13 @@ function writeStringToMemory(string, buffer, dontAddNull) { } Module['writeStringToMemory'] = writeStringToMemory; +function writeArrayToMemory(array, buffer) { + for (var i = 0; i < array.length; i++) { + {{{ makeSetValue('buffer', 'i', 'array[i]', 'i8') }}}; + } +} +Module['writeArrayToMemory'] = writeArrayToMemory; + var STRING_TABLE = []; {{{ unSign }}} @@ -837,8 +808,11 @@ var STRING_TABLE = []; // A counter of dependencies for calling run(). If we need to // do asynchronous work before running, increment this and -// decrement it. Incrementing must happen in Module.preRun -// or PRE_RUN_ADDITIONS (used by emcc to add file preloading). +// decrement it. Incrementing must happen in a place like +// PRE_RUN_ADDITIONS (used by emcc to add file preloading). +// Note that you can add dependencies in preRun, even though +// it happens right before run - run will be postponed until +// the dependencies are met. var runDependencies = 0; function addRunDependency() { runDependencies++; @@ -846,6 +820,7 @@ function addRunDependency() { Module['monitorRunDependencies'](runDependencies); } } +Module['addRunDependency'] = addRunDependency; function removeRunDependency() { runDependencies--; if (Module['monitorRunDependencies']) { @@ -853,6 +828,7 @@ function removeRunDependency() { } if (runDependencies == 0) run(); } +Module['removeRunDependency'] = removeRunDependency; // === Body === diff --git a/src/runtime.js b/src/runtime.js index 0e4b7b2d..1f8a618f 100644 --- a/src/runtime.js +++ b/src/runtime.js @@ -313,7 +313,78 @@ var Runtime = { FUNCTION_TABLE.push(func); FUNCTION_TABLE.push(0); return ret; + }, + + warnOnce: function(text) { + if (!Runtime.warnOnce.shown) Runtime.warnOnce.shown = {}; + if (!Runtime.warnOnce.shown[text]) { + Runtime.warnOnce.shown[text] = 1; + Module.printErr(text); + } + }, + + funcWrappers: {}, + + getFuncWrapper: function(func) { + if (!Runtime.funcWrappers[func]) { + Runtime.funcWrappers[func] = function() { + FUNCTION_TABLE[func].apply(null, arguments); + }; + } + return Runtime.funcWrappers[func]; + }, + +#if RUNTIME_DEBUG + debug: true, // Switch to false at runtime to disable logging at the right times + + printObjectList: [], + + prettyPrint: function(arg) { + if (typeof arg == 'undefined') return '!UNDEFINED!'; + if (typeof arg == 'boolean') arg = arg + 0; + if (!arg) return arg; + var index = Runtime.printObjectList.indexOf(arg); + if (index >= 0) return '<' + arg + '|' + index + '>'; + if (arg.toString() == '[object HTMLImageElement]') { + return arg + '\n\n'; + } + if (arg.byteLength) { + return '{' + Array.prototype.slice.call(arg, 0, Math.min(arg.length, 400)) + '}'; // Useful for correct arrays, less so for compiled arrays, see the code below for that + var buf = new ArrayBuffer(32); + var i8buf = new Int8Array(buf); + var i16buf = new Int16Array(buf); + var f32buf = new Float32Array(buf); + switch(arg.toString()) { + case '[object Uint8Array]': + i8buf.set(arg.subarray(0, 32)); + break; + case '[object Float32Array]': + f32buf.set(arg.subarray(0, 5)); + break; + case '[object Uint16Array]': + i16buf.set(arg.subarray(0, 16)); + break; + default: + alert('unknown array for debugging: ' + arg); + throw 'see alert'; + } + var ret = '{' + arg.byteLength + ':\n'; + var arr = Array.prototype.slice.call(i8buf); + ret += 'i8:' + arr.toString().replace(/,/g, ',') + '\n'; + arr = Array.prototype.slice.call(f32buf, 0, 8); + ret += 'f32:' + arr.toString().replace(/,/g, ',') + '}'; + return ret; + } + if (typeof arg == 'object') { + Runtime.printObjectList.push(arg); + return '<' + arg + '|' + (Runtime.printObjectList.length-1) + '>'; + } + if (typeof arg == 'number') { + if (arg > 0) return '0x' + arg.toString(16) + ' (' + arg + ')'; + } + return arg; } +#endif }; Runtime.stackAlloc = unInline('stackAlloc', ['size']); diff --git a/src/settings.js b/src/settings.js index 7df86c90..2526081b 100644 --- a/src/settings.js +++ b/src/settings.js @@ -26,6 +26,7 @@ var ASSERTIONS = 1; // Whether we should add runtime assertions, for example to // exceed it's size, whether all allocations (stack and static) are // of positive size, etc., whether we should throw if we encounter a bad __label__, i.e., // if code flow runs into a fault +var VERBOSE = 0; // When set to 1, will generate more verbose output during compilation. var INVOKE_RUN = 1; // Whether we will call run(). Disable if you embed the generated // code in your own, and will call run() yourself at the right time @@ -100,9 +101,13 @@ var SAFE_HEAP_LOG = 0; // Log out all SAFE_HEAP operations var LABEL_DEBUG = 0; // Print out labels and functions as we enter them var EXCEPTION_DEBUG = 1; // Print out exceptions in emscriptened code -var LIBRARY_DEBUG = 0; // Print out when we enter a library call (library*.js) -var GL_DEBUG = 0; // Print out all calls into WebGL +var LIBRARY_DEBUG = 0; // Print out when we enter a library call (library*.js). You can also unset + // Runtime.debug at runtime for logging to cease, and can set it when you + // want it back. A simple way to set it in C++ is + // emscripten_run_script("Runtime.debug = ...;"); +var GL_DEBUG = 0; // Print out all calls into WebGL. As with LIBRARY_DEBUG, you can set a runtime + // option, in this case GL.debug. var DISABLE_EXCEPTION_CATCHING = 0; // Disables generating code to actually catch exceptions. If the code you // are compiling does not actually rely on catching exceptions (but the @@ -209,6 +214,16 @@ var FAKE_X86_FP80 = 1; // Replaces x86_fp80 with double. This loses precision. I // if you can, to get the original source code to build without x86_fp80 // (which is nonportable anyhow). +var GC_SUPPORT = 1; // Enables GC, see gc.h (this does not add overhead, so it is on by default) + +var WARN_ON_UNDEFINED_SYMBOLS = 0; // If set to 1, we will warn on any undefined symbols that + // are not resolved by the library_*.js files. We by default + // do not warn because (1) it is normal in large projects to + // not implement everything, when you know what is not + // going to actually be called (and don't want to mess with + // the existing buildsystem), and (2) functions might be + // implemented later on, say in --pre-js + // Compiler debugging options var DEBUG_TAGS_SHOWING = []; // Some useful items: diff --git a/src/shell.html b/src/shell.html index 37509889..c04ae84b 100644 --- a/src/shell.html +++ b/src/shell.html @@ -1,20 +1,30 @@ -<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> -<html> +<!doctype html> +<html lang="en-us"> <head> + <meta charset="utf-8"> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Emscripten-Generated Code</title> + <style> + .emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; } + canvas.emscripten { border: 1px solid black; } + textarea.emscripten { font-family: monospace; width: 80%; } + div.emscripten { text-align: center; } + </style> + </head> <body> - <center> - <canvas id='canvas' width='256' height='256' style="border: 1px solid black" - oncontextmenu="event.preventDefault()"></canvas> - <hr> - <textarea id="output" style="font-family: monospace; width: 80%" rows="8"></textarea> - <hr> - <div id='status'>Downloading...</div> - </center> + <hr/> + <div class="emscripten" id="status">Downloading...</div> + <canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()"></canvas> + <hr/> + <div class="emscripten"><input type="button" value="fullscreen" onclick="Module.requestFullScreen()"></div> + <hr/> + <textarea class="emscripten" id="output" rows="8"></textarea> <hr> <script type='text/javascript'> // connect to canvas var Module = { + preRun: [], + postRun: [], print: (function() { var element = document.getElementById('output'); element.value = ''; // clear browser cache @@ -28,19 +38,42 @@ element.scrollTop = 99999; // focus on bottom }; })(), + printErr: function(text) { + if (0) { // XXX disabled for safety typeof dump == 'function') { + dump(text + '\n'); // fast, straight to the real console + } else { + console.log(text); + } + }, canvas: document.getElementById('canvas'), setStatus: function(text) { + if (Module.setStatus.interval) clearInterval(Module.setStatus.interval); document.getElementById('status').innerHTML = text; + if (text) { + var counter = 0; + Module.setStatus.interval = setInterval(function() { + counter++; + counter %= 3; + var dots = ' '; + for (var i = 0; i < counter; i++) dots += '.'; + dots += '*'; + for (var i = counter; i < 2; i++) dots += '.'; + document.getElementById('status').innerHTML = text.replace('...', dots); + }, 300); + } }, totalDependencies: 0, monitorRunDependencies: function(left) { this.totalDependencies = Math.max(this.totalDependencies, left); - Module.setStatus(left ? 'Downloading: ' + (this.totalDependencies-left) + '/' + this.totalDependencies : 'All downloads complete.'); + Module.setStatus(left ? 'Preparing: ' + (this.totalDependencies-left) + '/' + this.totalDependencies + '...' : 'All downloads complete.'); } }; + Module.setStatus('Downloading...'); + </script> + <script type='text/javascript'> {{{ SCRIPT_CODE }}} + </script> </body> </html> - diff --git a/src/shell.js b/src/shell.js index ab54c284..891a6328 100644 --- a/src/shell.js +++ b/src/shell.js @@ -46,7 +46,7 @@ if (ENVIRONMENT_IS_NODE) { } } else if (ENVIRONMENT_IS_SHELL) { Module['print'] = print; - Module['printErr'] = printErr; + if (typeof printErr != 'undefined') Module['printErr'] = printErr; // not present in v8 or older sm // Polyfill over SpiderMonkey/V8 differences if (typeof read != 'undefined') { @@ -104,17 +104,25 @@ if (!Module['load'] == 'undefined' && Module['read']) { globalEval(Module['read'](f)); }; } -if (!Module['printErr']) { - Module['printErr'] = function(){}; -} if (!Module['print']) { - Module['print'] = Module['printErr']; + Module['print'] = function(){}; +} +if (!Module['printErr']) { + Module['printErr'] = Module['print']; } if (!Module['arguments']) { Module['arguments'] = []; } // *** Environment setup code *** +// Closure helpers +Module.print = Module['print']; +Module.printErr = Module['printErr']; + +// Callbacks +if (!Module['preRun']) Module['preRun'] = []; +if (!Module['postRun']) Module['postRun'] = []; + {{BODY}} // {{MODULE_ADDITIONS}} diff --git a/src/utility.js b/src/utility.js index 7d5e0970..42e8ede4 100644 --- a/src/utility.js +++ b/src/utility.js @@ -40,7 +40,7 @@ function dumpKeys(item) { function assertEq(a, b) { if (a !== b) { - print('Stack: ' + new Error().stack); + printErr('Stack: ' + new Error().stack); throw 'Should have been equal: ' + a + ' : ' + b; } return false; @@ -50,7 +50,7 @@ function assertTrue(a, msg) { if (!a) { msg = 'Assertion failed: ' + msg; print(msg); - print('Stack: ' + new Error().stack); + printErr('Stack: ' + new Error().stack); throw msg; } } diff --git a/system/include/emscripten.h b/system/include/emscripten.h deleted file mode 100644 index ea078e8c..00000000 --- a/system/include/emscripten.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - * This file contains a few useful things for compiling C/C++ code - * with Emscripten, an LLVM-to-JavaScript compiler. - * - * The code can be used permissively under the MIT license. - * - * http://emscripten.org - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Interface to the underlying JS engine. This function will - * eval() the given script. - */ -extern void emscripten_run_script(const char *script); -extern int emscripten_run_script_int(const char *script); - -/* - * Set a C function as the main event loop. The JS environment - * will call that function at a specified number of frames per - * second. Setting 0 as the fps will use the default browser - * frame rate. - */ -extern void emscripten_set_main_loop(void (*func)(), int fps); -extern void emscripten_cancel_main_loop(); - -/* - * This macro-looking function will cause Emscripten to - * generate a comment in the generated code. - * XXX This is deprecated for now, because it requires us to - * hold all global vars in memory. We need a better solution. - */ -//extern void EMSCRIPTEN_COMMENT(const char *text); - -/* - * Profiling tools. - * INIT must be called first, with the maximum identifier that - * will be used. BEGIN will add some code that marks - * the beginning of a section of code whose run time you - * want to measure. END will finish such a section. Note: If you - * call begin but not end, you will get invalid data! - * The profiling data will be written out if you call Profile.dump(). - */ -extern void EMSCRIPTEN_PROFILE_INIT(int max); -extern void EMSCRIPTEN_PROFILE_BEGIN(int id); -extern void EMSCRIPTEN_PROFILE_END(int id); - -#ifdef __cplusplus -} -#endif - diff --git a/system/include/emscripten/emscripten.h b/system/include/emscripten/emscripten.h new file mode 100644 index 00000000..5b71ce6a --- /dev/null +++ b/system/include/emscripten/emscripten.h @@ -0,0 +1,133 @@ +/** + * This file contains a few useful things for compiling C/C++ code + * with Emscripten, an LLVM-to-JavaScript compiler. + * + * The code can be used permissively under the MIT license. + * + * http://emscripten.org + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Forces LLVM to not dead-code-eliminate a function. Note that + * closure may still eliminate it at the JS level, for which you + * should use EXPORTED_FUNCTIONS (see settings.js). + * + * Example usage: + * void EMSCRIPTEN_KEEPALIVE my_function() { .. } + */ +#define EMSCRIPTEN_KEEPALIVE __attribute__((used)) + +/* + * Interface to the underlying JS engine. This function will + * eval() the given script. + */ +extern void emscripten_run_script(const char *script); +extern int emscripten_run_script_int(const char *script); +extern void emscripten_async_run_script(const char *script, int millis); + +/* + * Set a C function as the main event loop. The JS environment + * will call that function at a specified number of frames per + * second. Setting 0 or a negative value as the fps will use + * the browser's requestAnimationFrame mechanism. + * + * Pausing and resuming the main loop is useful if your app + * needs to perform some synchronous operation, for example + * to load a file from the network. It might be wrong to + * run the main loop before that finishes (the original + * code assumes that), so you can break the code up into + * asynchronous callbacks, but you must pause the main + * loop until they complete. + */ +extern void emscripten_set_main_loop(void (*func)(), int fps); +extern void emscripten_pause_main_loop(); +extern void emscripten_resume_main_loop(); +extern void emscripten_cancel_main_loop(); + +/* + * Call a C function asynchronously, that is, after returning + * control to the JS event loop. This is done by a setTimeout. + * When building natively this becomes a simple direct call, + * after SDL_Delay (you must include SDL.h for that). + * + * If millis is negative, the browser's requestAnimationFrame + * mechanism is used. + */ +#if EMSCRIPTEN +extern void emscripten_async_call(void (*func)(), int millis); +#else +inline void emscripten_async_call(void (*func)(), int millis) { + SDL_Delay(millis); + func(); +} +#endif + +/* + * Hide the OS mouse cursor over the canvas. Note that SDL's + * SDL_ShowCursor command shows and hides the SDL cursor, not + * the OS one. This command is useful to hide the OS cursor + * if your app draws its own cursor. + */ +void emscripten_hide_mouse(); + +/* + * Resizes the pixel width and height of the <canvas> element + * on the Emscripten web page. + */ +void emscripten_set_canvas_size(int width, int height); + +/* + * Returns the highest-precision representation of the + * current time that the browser provides. This uses either + * Date.now or performance.now. The result is *not* an + * absolute time, and is only meaningful in comparison to + * other calls to this function. The unit is ms. + */ +float emscripten_get_now(); + +/* + * Simple random number generation in [0, 1), maps to Math.random(). + */ +float emscripten_random(); + +/* + * This macro-looking function will cause Emscripten to + * generate a comment in the generated code. + * XXX This is deprecated for now, because it requires us to + * hold all global vars in memory. We need a better solution. + */ +//extern void EMSCRIPTEN_COMMENT(const char *text); + +/* + * Emscripten file system api + */ + +/* + * Load file from url in asynchronous way. + * When file is loaded then 'onload' callback will called. + * If any error occurred 'onerror' will called. + * The callbacks are called with the file as their argument. + */ +void emscripten_async_wget(const char* url, const char* file, void (*onload)(const char*), void (*onerror)(const char*)); + +/* + * Profiling tools. + * INIT must be called first, with the maximum identifier that + * will be used. BEGIN will add some code that marks + * the beginning of a section of code whose run time you + * want to measure. END will finish such a section. Note: If you + * call begin but not end, you will get invalid data! + * The profiling data will be written out if you call Profile.dump(). + */ +extern void EMSCRIPTEN_PROFILE_INIT(int max); +extern void EMSCRIPTEN_PROFILE_BEGIN(int id); +extern void EMSCRIPTEN_PROFILE_END(int id); + +#ifdef __cplusplus +} +#endif + diff --git a/system/include/features.h b/system/include/features.h new file mode 100644 index 00000000..1dd6ea6d --- /dev/null +++ b/system/include/features.h @@ -0,0 +1,3 @@ + +#include <sys/features.h> + diff --git a/system/include/gc.h b/system/include/gc.h new file mode 100644 index 00000000..996bc9ec --- /dev/null +++ b/system/include/gc.h @@ -0,0 +1,50 @@ +/* + * Boehm-compatible GC API + */ + +#include <stdlib.h> + +#ifdef __cplusplus +extern "C" { +#endif + +void __attribute__((used)) __GC_KEEPALIVE__() { + // Force inclusion of necessary dlmalloc functions + static int times = 1; + void *x = malloc(times); + free(x); + x = calloc(1, times); + free(x); + x = calloc(times, 1); + free(x); + times++; +} + +/* Initialize. */ +void GC_INIT(); + +/* Allocate memory. Cleared to 0 to erase all pointers. */ +void *GC_MALLOC(int bytes); + +/* Allocate memory for an object that the user promises will not contain pointers. */ +void *GC_MALLOC_ATOMIC(int bytes); + +/* Explicitly deallocate an object. Dangerous as it forces a free and does not check if the object is reffed. */ +void GC_FREE(void *ptr); + +/* Register a finalizer. func(ptr, arg) will be called. The old values are saved in old_func, old_arg */ +void GC_REGISTER_FINALIZER_NO_ORDER(void *ptr, void (*func)(void *, void *), void *arg, + void *(*old_func)(void *, void *), void *old_arg); + +/* Non-Boehm additions */ + +/* Call this once per frame or such, it will collect if necessary */ +void GC_MAYBE_COLLECT(); + +/* Forces a GC. Mainly useful for testing, but call it if you know a good time to GC in your app. */ +void GC_FORCE_COLLECT(); + +#ifdef __cplusplus +} +#endif + diff --git a/system/include/libc/sys/_default_fcntl.h b/system/include/libc/sys/_default_fcntl.h index 0f2ffb07..188e25c4 100644 --- a/system/include/libc/sys/_default_fcntl.h +++ b/system/include/libc/sys/_default_fcntl.h @@ -209,6 +209,11 @@ extern int _open64 _PARAMS ((const char *, int, ...)); #define POSIX_FADV_DONTNEED 135 int posix_fadvise(int fd, off_t offset, off_t len, int advice); int posix_fallocate(int fd, off_t offset, off_t len); +#define LOCK_SH 1 +#define LOCK_EX 2 +#define LOCK_UN 4 +#define LOCK_NB 8 +int flock(int fd, int operation); #ifdef __cplusplus } diff --git a/system/include/libc/sys/dirent.h b/system/include/libc/sys/dirent.h index 1fbe2b21..9dcf34d1 100644 --- a/system/include/libc/sys/dirent.h +++ b/system/include/libc/sys/dirent.h @@ -26,6 +26,10 @@ long telldir(DIR *); DIR *readdir(DIR *); int closedir(DIR *dirp); void rewinddir(DIR *dirp); +int scandir(const char *dirp, + struct dirent ***namelist, + int (*filter)(const struct dirent *), + int (*compar)(const struct dirent **, const struct dirent **)); enum { DT_UNKNOWN = 0, diff --git a/system/include/libc/sys/types.h b/system/include/libc/sys/types.h index 77acc92e..2f887537 100644 --- a/system/include/libc/sys/types.h +++ b/system/include/libc/sys/types.h @@ -140,12 +140,8 @@ typedef unsigned long vm_size_t; #define __BIT_TYPES_DEFINED__ -// XXX Emscripten: removed unsigned types which are already defined -typedef signed char int8_t; -typedef short int16_t; -typedef int int32_t; -typedef long long int64_t; -typedef int32_t register_t; +// XXX Emscripten: removed types which are already defined, get them from stdint +#include <stdint.h> #endif /* __MS_types__ */ /* diff --git a/system/include/net/if.h b/system/include/net/if.h index 9a4badf3..dd7884aa 100644 --- a/system/include/net/if.h +++ b/system/include/net/if.h @@ -2,6 +2,10 @@ #ifndef _NET_IF_H #define _NET_IF_H +#include <sys/socket.h> +#include <sys/types.h> +#include <sys/ioctl.h> + #ifdef __cplusplus extern "C" { #endif @@ -11,6 +15,61 @@ struct if_nameindex { char *if_name; }; +#define IFHWADDRLEN 6 +#define IFNAMSIZ 16 + +struct ifmap { + unsigned long int mem_start; + unsigned long int mem_end; + unsigned short int base_addr; + unsigned char irq; + unsigned char dma; + unsigned char port; +}; + +struct ifreq { + union { + char ifrn_name[IFNAMSIZ]; + } ifr_ifrn; + union { + struct sockaddr ifru_addr; + struct sockaddr ifru_destaddr; + struct sockaddr ifru_broadaddr; + struct sockaddr ifru_netmask; + struct sockaddr ifru_hwaddr; + short int ifru_flags; + int ifru_ivalue; + int ifru_mtu; + struct ifmap ifru_map; + char ifru_slave[IFNAMSIZ]; + char ifru_newname[IFNAMSIZ]; + caddr_t ifru_data; + } ifr_ifru; +}; +#define ifr_name ifr_ifrn.ifrn_name +#define ifr_addr ifr_ifru.ifru_addr +#define ifr_destaddr ifr_ifru.ifru_destaddr +#define ifr_broadaddr ifr_ifru.ifru_broadaddr +#define ifr_netmask ifr_ifru.ifru_netmask +#define ifr_hwaddr ifr_ifru.ifru_hwaddr +#define ifr_flags ifr_ifru.ifru_flags +#define ifr_ivalue ifr_ifru.ifru_ivalue +#define ifr_mtu ifr_ifru.ifru_mtu +#define ifr_map ifr_ifru.ifru_map +#define ifr_slave ifr_ifru.ifru_slave +#define ifr_newname ifr_ifru.ifru_newname +#define ifr_data ifr_ifru.ifru_data + +struct ifconf { + int ifc_len; + union { + caddr_t ifcu_buf; + struct ifreq* ifcu_req; + } ifc_ifcu; +}; +#define ifc_buf ifc_ifcu.ifcu_buf +#define ifc_req ifc_ifcu.ifcu_req + #define IF_NAMESIZE abort(0); unsigned if_nametoindex(const char *a); @@ -18,6 +77,8 @@ char *if_indextoname(unsigned int a, char *b); struct if_nameindex *if_nameindex(); void if_freenameindex(struct if_nameindex *a); + + #ifdef __cplusplus } #endif diff --git a/system/include/net/netinet/in.h b/system/include/net/netinet/in.h index 4547696b..9229ca84 100644 --- a/system/include/net/netinet/in.h +++ b/system/include/net/netinet/in.h @@ -39,6 +39,11 @@ struct sockaddr_in6 { int sin6_scope_id; }; +struct ip_mreq { + struct in_addr imr_multiaddr; + struct in_addr imr_interface; +}; + #ifdef __cplusplus } #endif diff --git a/system/include/net/netinet/tcp.h b/system/include/net/netinet/tcp.h new file mode 100644 index 00000000..06e8414b --- /dev/null +++ b/system/include/net/netinet/tcp.h @@ -0,0 +1,246 @@ +/* + * Copyright (c) 1982, 1986, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)tcp.h 8.1 (Berkeley) 6/10/93 + */ + +#ifndef _NETINET_TCP_H +#define _NETINET_TCP_H 1 + +#include <features.h> + +/* + * User-settable options (used with setsockopt). + */ +#define TCP_NODELAY 1 /* Don't delay send to coalesce packets */ +#define TCP_MAXSEG 2 /* Set maximum segment size */ +#define TCP_CORK 3 /* Control sending of partial frames */ +#define TCP_KEEPIDLE 4 /* Start keeplives after this period */ +#define TCP_KEEPINTVL 5 /* Interval between keepalives */ +#define TCP_KEEPCNT 6 /* Number of keepalives before death */ +#define TCP_SYNCNT 7 /* Number of SYN retransmits */ +#define TCP_LINGER2 8 /* Life time of orphaned FIN-WAIT-2 state */ +#define TCP_DEFER_ACCEPT 9 /* Wake up listener only when data arrive */ +#define TCP_WINDOW_CLAMP 10 /* Bound advertised window */ +#define TCP_INFO 11 /* Information about this connection. */ +#define TCP_QUICKACK 12 /* Bock/reenable quick ACKs. */ +#define TCP_CONGESTION 13 /* Congestion control algorithm. */ +#define TCP_MD5SIG 14 /* TCP MD5 Signature (RFC2385) */ + +#ifdef __USE_MISC +# include <sys/types.h> +# include <sys/socket.h> + +# ifdef __FAVOR_BSD +typedef u_int32_t tcp_seq; +/* + * TCP header. + * Per RFC 793, September, 1981. + */ +struct tcphdr + { + u_int16_t th_sport; /* source port */ + u_int16_t th_dport; /* destination port */ + tcp_seq th_seq; /* sequence number */ + tcp_seq th_ack; /* acknowledgement number */ +# if __BYTE_ORDER == __LITTLE_ENDIAN + u_int8_t th_x2:4; /* (unused) */ + u_int8_t th_off:4; /* data offset */ +# endif +# if __BYTE_ORDER == __BIG_ENDIAN + u_int8_t th_off:4; /* data offset */ + u_int8_t th_x2:4; /* (unused) */ +# endif + u_int8_t th_flags; +# define TH_FIN 0x01 +# define TH_SYN 0x02 +# define TH_RST 0x04 +# define TH_PUSH 0x08 +# define TH_ACK 0x10 +# define TH_URG 0x20 + u_int16_t th_win; /* window */ + u_int16_t th_sum; /* checksum */ + u_int16_t th_urp; /* urgent pointer */ +}; + +# else /* !__FAVOR_BSD */ +struct tcphdr + { + u_int16_t source; + u_int16_t dest; + u_int32_t seq; + u_int32_t ack_seq; +# if __BYTE_ORDER == __LITTLE_ENDIAN + u_int16_t res1:4; + u_int16_t doff:4; + u_int16_t fin:1; + u_int16_t syn:1; + u_int16_t rst:1; + u_int16_t psh:1; + u_int16_t ack:1; + u_int16_t urg:1; + u_int16_t res2:2; +# elif __BYTE_ORDER == __BIG_ENDIAN + u_int16_t doff:4; + u_int16_t res1:4; + u_int16_t res2:2; + u_int16_t urg:1; + u_int16_t ack:1; + u_int16_t psh:1; + u_int16_t rst:1; + u_int16_t syn:1; + u_int16_t fin:1; +# else +# error "Adjust your <bits/endian.h> defines" +# endif + u_int16_t window; + u_int16_t check; + u_int16_t urg_ptr; +}; +# endif /* __FAVOR_BSD */ + +enum +{ + TCP_ESTABLISHED = 1, + TCP_SYN_SENT, + TCP_SYN_RECV, + TCP_FIN_WAIT1, + TCP_FIN_WAIT2, + TCP_TIME_WAIT, + TCP_CLOSE, + TCP_CLOSE_WAIT, + TCP_LAST_ACK, + TCP_LISTEN, + TCP_CLOSING /* now a valid state */ +}; + +# define TCPOPT_EOL 0 +# define TCPOPT_NOP 1 +# define TCPOPT_MAXSEG 2 +# define TCPOLEN_MAXSEG 4 +# define TCPOPT_WINDOW 3 +# define TCPOLEN_WINDOW 3 +# define TCPOPT_SACK_PERMITTED 4 /* Experimental */ +# define TCPOLEN_SACK_PERMITTED 2 +# define TCPOPT_SACK 5 /* Experimental */ +# define TCPOPT_TIMESTAMP 8 +# define TCPOLEN_TIMESTAMP 10 +# define TCPOLEN_TSTAMP_APPA (TCPOLEN_TIMESTAMP+2) /* appendix A */ + +# define TCPOPT_TSTAMP_HDR \ + (TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP) + +/* + * Default maximum segment size for TCP. + * With an IP MSS of 576, this is 536, + * but 512 is probably more convenient. + * This should be defined as MIN(512, IP_MSS - sizeof (struct tcpiphdr)). + */ +# define TCP_MSS 512 + +# define TCP_MAXWIN 65535 /* largest value for (unscaled) window */ + +# define TCP_MAX_WINSHIFT 14 /* maximum window shift */ + +# define SOL_TCP 6 /* TCP level */ + + +# define TCPI_OPT_TIMESTAMPS 1 +# define TCPI_OPT_SACK 2 +# define TCPI_OPT_WSCALE 4 +# define TCPI_OPT_ECN 8 + +/* Values for tcpi_state. */ +enum tcp_ca_state +{ + TCP_CA_Open = 0, + TCP_CA_Disorder = 1, + TCP_CA_CWR = 2, + TCP_CA_Recovery = 3, + TCP_CA_Loss = 4 +}; + +struct tcp_info +{ + u_int8_t tcpi_state; + u_int8_t tcpi_ca_state; + u_int8_t tcpi_retransmits; + u_int8_t tcpi_probes; + u_int8_t tcpi_backoff; + u_int8_t tcpi_options; + u_int8_t tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4; + + u_int32_t tcpi_rto; + u_int32_t tcpi_ato; + u_int32_t tcpi_snd_mss; + u_int32_t tcpi_rcv_mss; + + u_int32_t tcpi_unacked; + u_int32_t tcpi_sacked; + u_int32_t tcpi_lost; + u_int32_t tcpi_retrans; + u_int32_t tcpi_fackets; + + /* Times. */ + u_int32_t tcpi_last_data_sent; + u_int32_t tcpi_last_ack_sent; /* Not remembered, sorry. */ + u_int32_t tcpi_last_data_recv; + u_int32_t tcpi_last_ack_recv; + + /* Metrics. */ + u_int32_t tcpi_pmtu; + u_int32_t tcpi_rcv_ssthresh; + u_int32_t tcpi_rtt; + u_int32_t tcpi_rttvar; + u_int32_t tcpi_snd_ssthresh; + u_int32_t tcpi_snd_cwnd; + u_int32_t tcpi_advmss; + u_int32_t tcpi_reordering; + + u_int32_t tcpi_rcv_rtt; + u_int32_t tcpi_rcv_space; + + u_int32_t tcpi_total_retrans; +}; + + +/* For TCP_MD5SIG socket option. */ +#define TCP_MD5SIG_MAXKEYLEN 80 + +struct tcp_md5sig +{ + struct sockaddr_storage tcpm_addr; /* Address associated. */ + u_int16_t __tcpm_pad1; /* Zero. */ + u_int16_t tcpm_keylen; /* Key length. */ + u_int32_t __tcpm_pad2; /* Zero. */ + u_int8_t tcpm_key[TCP_MD5SIG_MAXKEYLEN]; /* Key (binary). */ +}; + +#endif /* Misc. */ + +#endif /* netinet/tcp.h */ diff --git a/system/include/netdb.h b/system/include/netdb.h new file mode 100644 index 00000000..20f876df --- /dev/null +++ b/system/include/netdb.h @@ -0,0 +1,55 @@ +#ifndef _NETDB_H +#define _NETDB_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define HOST_NOT_FOUND 1 +#define TRY_AGAIN 2 +#define NO_RECOVERY 3 +#define NO_DATA 4 + +#define IP_TOS 1 +#define IP_TTL 2 +#define IP_HDRINCL 3 +#define IP_OPTIONS 4 +#define IP_ROUTER_ALERT 5 +#define IP_RECVOPTS 6 +#define IP_RETOPTS 7 +#define IP_PKTINFO 8 +#define IP_PKTOPTIONS 9 +#define IP_MTU_DISCOVER 10 +#define IP_RECVERR 11 +#define IP_RECVTTL 12 +#define IP_RECVTOS 13 +#define IP_MTU 14 +#define IP_FREEBIND 15 +#define IP_IPSEC_POLICY 16 +#define IP_XFRM_POLICY 17 +#define IP_PASSSEC 18 +#define IP_TRANSPARENT 19 + +typedef int socklen_t; + +struct hostent { + char* h_name; + char** h_aliases; + int h_addrtype; + int h_length; + char** h_addr_list; +}; +#define h_addr h_addr_list[0] + +struct hostent* gethostbyaddr(const void* addr, socklen_t len, int type); +struct hostent* gethostbyname(const char* name); +void sethostent(int stayopen); +void endhostent(void); +void herror(const char* s); +const char* hstrerror(int err); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/system/include/sys/ioctl.h b/system/include/sys/ioctl.h index 061ba925..b7ade699 100644 --- a/system/include/sys/ioctl.h +++ b/system/include/sys/ioctl.h @@ -1,7 +1,20 @@ +#ifndef _IOCTL_H +#define _IOCTL_H -/* ioctl.h */ +#ifdef __cplusplus +extern "C" { +#endif + +#define SIOCGIFCONF 1 // bogus value +#define SIOCGIFNETMASK 2 // bogus value + +int ioctl(int d, int request, ...); #define SO_RCVTIMEO 1000 #define SO_SNDTIMEO 2000 +#ifdef __cplusplus +} +#endif +#endif diff --git a/system/include/sys/socket.h b/system/include/sys/socket.h index 2c23ddb7..69bbdcaa 100644 --- a/system/include/sys/socket.h +++ b/system/include/sys/socket.h @@ -1,10 +1,14 @@ #ifndef _SYS_SOCKET_H #define _SYS_SOCKET_H +#include <netdb.h> +#include <sys/select.h> + #ifdef __cplusplus extern "C" { #endif +// Note that the values of these constants are mostly arbitrary numbers. #define SOMAXCONN 128 #define PF_INET 2 #define SO_BROADCAST 6 @@ -17,8 +21,10 @@ extern "C" { #define SO_REUSEADDR 30 #define SO_SNDBUF 40 #define SO_RCVBUF 60 +#define SO_LINGER 70 +#define SO_NOSIGPIPE 80 -typedef int socklen_t; +#define SHUT_RDWR 1 typedef unsigned int sa_family_t; #define AF_INET 1 @@ -41,6 +47,7 @@ int bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen); int listen(int sockfd, int backlog); int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen); +int shutdown(int sockfd, int how); int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen); ssize_t recv(int s, void *buf, size_t len, int flags); ssize_t send(int s, const void *buf, size_t len, int flags); @@ -58,6 +65,11 @@ struct msghdr int msg_flags; }; +struct linger { + int l_onoff; + int l_linger; +}; + #ifdef __cplusplus } #endif diff --git a/system/include/sys/socketvar.h b/system/include/sys/socketvar.h new file mode 100644 index 00000000..58fe99cf --- /dev/null +++ b/system/include/sys/socketvar.h @@ -0,0 +1,3 @@ + +#include <sys/socket.h> + diff --git a/system/include/sys/statvfs.h b/system/include/sys/statvfs.h index cf0a8c96..192be153 100644 --- a/system/include/sys/statvfs.h +++ b/system/include/sys/statvfs.h @@ -20,7 +20,7 @@ struct statvfs { int f_namemax; }; -int statvfs(char *path, struct statvfs *s); +int statvfs(const char *path, struct statvfs *s); #ifdef __cplusplus } diff --git a/system/lib/libcxx/Makefile b/system/lib/libcxx/Makefile index 98a5974d..814921ea 100644 --- a/system/lib/libcxx/Makefile +++ b/system/lib/libcxx/Makefile @@ -12,7 +12,6 @@ OBJECTS = \ debug.bc \ hash.bc \ mutex.bc \ - readme.txt \ string.bc \ thread.bc \ valarray.bc \ diff --git a/tests/aniso.c b/tests/aniso.c new file mode 100644 index 00000000..e673e228 --- /dev/null +++ b/tests/aniso.c @@ -0,0 +1,210 @@ +/******************************************************************* + * * + * Using SDL With OpenGL * + * * + * Tutorial by Kyle Foley (sdw) * + * * + * http://gpwiki.org/index.php/SDL:Tutorials:Using_SDL_with_OpenGL * + * * + *******************************************************************/ + +/* +THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION +AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN. + +THE ORIGINAL AUTHOR IS KYLE FOLEY. + +THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY +OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF +MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, +ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE +RESULTING FROM THE USE, MODIFICATION, OR +REDISTRIBUTION OF THIS SOFTWARE. +*/ + +#include "SDL/SDL.h" +#include "SDL/SDL_image.h" +#include "SDL/SDL_opengl.h" + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#define MAX(x, y) ((x) > (y) ? (x) : (y)) + +int hasext(const char *exts, const char *ext) // from cube2, zlib licensed +{ + int len = strlen(ext); + if(len) for(const char *cur = exts; (cur = strstr(cur, ext)); cur += len) + { + if((cur == exts || cur[-1] == ' ') && (cur[len] == ' ' || !cur[len])) return 1; + } + return 0; +} + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + + // Slightly different SDL initialization + if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { + printf("Unable to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // *new* + + screen = SDL_SetVideoMode( 600, 600, 16, SDL_OPENGL ); // *changed* + if ( !screen ) { + printf("Unable to set video mode: %s\n", SDL_GetError()); + return 1; + } + + // Check extensions + + const char *exts = (const char *)glGetString(GL_EXTENSIONS); + assert(hasext(exts, "GL_EXT_texture_filter_anisotropic")); + + GLint aniso; + glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &aniso); + printf("Max anisotropy: %d (using that)\n", aniso); + assert(aniso >= 4); + + // Set the OpenGL state after creating the context with SDL_SetVideoMode + + glClearColor( 0, 0, 0, 0 ); + +#if !EMSCRIPTEN + glEnable( GL_TEXTURE_2D ); // Need this to display a texture XXX unnecessary in OpenGL ES 2.0/WebGL +#endif + + glViewport( 0, 0, 600, 600 ); + + glMatrixMode( GL_PROJECTION ); + GLfloat matrixData[] = { 2.0/600, 0, 0, 0, + 0, -2.0/600, 0, 0, + 0, 0, -2.0/600, 0, + -1, 1, 0, 1 }; + glLoadMatrixf(matrixData); // test loadmatrix + + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + + + // Load the OpenGL texture + + GLuint texture, texture2; + + const int DDS_SIZE = 43920; + FILE *dds = fopen("water.dds", "rb"); + assert(dds); + char *ddsdata = (char*)malloc(DDS_SIZE); + assert(fread(ddsdata, 1, DDS_SIZE, dds) == DDS_SIZE); + fclose(dds); + + { + glGenTextures( 1, &texture ); + glBindTexture( GL_TEXTURE_2D, texture ); + + char *curr = ddsdata + 128; + int level = 0; + int w = 512; + int h = 64; + while (level < 5) { + printf("uploading level %d: %d, %d\n", level, w, h); + assert(!glGetError()); + glCompressedTexImage2D(GL_TEXTURE_2D, level, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, w, h, 0, w*h, curr); + assert(!glGetError()); + curr += MAX(w, 4)*MAX(h, 4); + w /= 2; + h /= 2; + level++; + } + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + } + { + glGenTextures( 1, &texture2 ); + glBindTexture( GL_TEXTURE_2D, texture2 ); + + char *curr = ddsdata + 128; + int level = 0; + int w = 512; + int h = 64; + while (level < 5) { + printf("uploading level %d: %d, %d\n", level, w, h); + assert(!glGetError()); + glCompressedTexImage2D(GL_TEXTURE_2D, level, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, w, h, 0, w*h, curr); + assert(!glGetError()); + curr += MAX(w, 4)*MAX(h, 4); + w /= 2; + h /= 2; + level++; + } + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso); + } + + // Prepare and Render + + // Clear the screen before drawing + glClear( GL_COLOR_BUFFER_BIT ); + + // Bind the texture to which subsequent calls refer to + int w = 10; + int n = 15; + glBindTexture( GL_TEXTURE_2D, texture ); + for (int x = 0; x < n; x++) { + int start = x*w*2; + glBegin( GL_TRIANGLES ); + glTexCoord2i( 1, 0 ); glVertex3f( start , 0, 0 ); + glTexCoord2i( 0, 0 ); glVertex3f( start+w, 300, 0 ); + glTexCoord2i( 1, 1 ); glVertex3f( start-w, 300, 0 ); + glEnd(); + } + glBindTexture( GL_TEXTURE_2D, texture2 ); + for (int x = 0; x < n; x++) { + int start = n*w*2 + x*w*2; + glBegin( GL_TRIANGLES ); + glTexCoord2i( 1, 0 ); glVertex3f( start , 0, 0 ); + glTexCoord2i( 0, 0 ); glVertex3f( start+w, 300, 0 ); + glTexCoord2i( 1, 1 ); glVertex3f( start-w, 300, 0 ); + glEnd(); + } +/* + int w = 8; + int n = 20; + for (int x = 0; x < n; x++) { + for (int y = 0; y < n*2; y++) { + glBindTexture( GL_TEXTURE_2D, texture ); + glBegin( GL_TRIANGLE_STRIP ); + glTexCoord2i( 0, 0 ); glVertex3f( x*w, y*(w), 0 ); + glTexCoord2i( 1, 0 ); glVertex3f( (x+1)*(w-2*y/n), y*(w), 0 ); + glTexCoord2i( 1, 1 ); glVertex3f( (x+1)*(w-2*y/n), (y+1)*(w), 0 ); + glTexCoord2i( 0, 1 ); glVertex3f( x*w, (y+1)*(w), 0 ); + glEnd(); + glBindTexture( GL_TEXTURE_2D, texture2 ); + glBegin( GL_TRIANGLE_STRIP ); + glTexCoord2i( 0, 0 ); glVertex3f( n*w + x*w, y*(w), 0 ); + glTexCoord2i( 1, 0 ); glVertex3f( n*w + (x+1)*(w-2*y/n), y*(w), 0 ); + glTexCoord2i( 1, 1 ); glVertex3f( n*w + (x+1)*(w-2*y/n), (y+1)*(w), 0 ); + glTexCoord2i( 0, 1 ); glVertex3f( n*w + x*w, (y+1)*(w), 0 ); + glEnd(); + } + } +*/ + SDL_GL_SwapBuffers(); + +#if !EMSCRIPTEN + // Wait for 3 seconds to give us a chance to see the image + SDL_Delay(2000); +#endif + + // Now we can delete the OpenGL texture and close down SDL + glDeleteTextures( 1, &texture ); + + SDL_Quit(); + + return 0; +} diff --git a/tests/aniso.png b/tests/aniso.png Binary files differnew file mode 100644 index 00000000..5f5812d2 --- /dev/null +++ b/tests/aniso.png diff --git a/tests/bloom.dds b/tests/bloom.dds Binary files differnew file mode 100644 index 00000000..ed51ab51 --- /dev/null +++ b/tests/bloom.dds diff --git a/tests/browser_gc.cpp b/tests/browser_gc.cpp new file mode 100644 index 00000000..75dea10a --- /dev/null +++ b/tests/browser_gc.cpp @@ -0,0 +1,96 @@ +#include <stdio.h> +#include <gc.h> +#include <assert.h> +#include <emscripten.h> + +void *global; + +int freed = 0; + +void finalizer(void *ptr, void *arg) { + printf("finalizing %d (global == %d)\n", (int)arg, ptr == global); + freed++; + if (ptr == global) global = 0; +} + +int stage = 0; +float start = 0; + +void waiter() { + if (stage == 0) { // wait for a while, see no GCing + assert(global); + if (emscripten_get_now() - start > 2100) { + GC_MALLOC(1024*1024*2); // allocate enough to trigger a GC + start = emscripten_get_now(); + stage = 1; + printf("stage 1\n"); + } + } else if (stage == 1) { + assert(global); + if (freed > 0) { + GC_FREE(global); + stage = 2; + start = emscripten_get_now(); + printf("stage 2\n"); + } + if (emscripten_get_now() - start > 2100) { + printf("fail, too much time passed (a)\n"); + return; + } + } else if (stage == 2) { + if (emscripten_get_now() - start > 2100) { // wait and see that no gc'ing happens yet + GC_MALLOC(1024*1024*2); // allocate enough to trigger a GC + stage = 3; + start = emscripten_get_now(); + printf("stage 3\n"); + } + } else if (stage == 3) { + assert(!global); + if (freed == 5) { + printf("Ok.\n"); + int result = 1; + REPORT_RESULT(); + return; + } + if (emscripten_get_now() - start > 2100) { + printf("fail, too much time passed (b)\n"); + return; + } + } + + emscripten_async_call(waiter, 100); +} + +int main() { + start = emscripten_get_now(); + + GC_INIT(); + + void *local, *local2, *local3, *local4; + + global = GC_MALLOC(12); + GC_REGISTER_FINALIZER_NO_ORDER(global, finalizer, 0, 0, 0); + local = GC_MALLOC(12); + GC_REGISTER_FINALIZER_NO_ORDER(local, finalizer, (void*)1, 0, 0); + local2 = GC_MALLOC_ATOMIC(12); + GC_REGISTER_FINALIZER_NO_ORDER(local2, finalizer, (void*)2, 0, 0); + local3 = GC_MALLOC(12); + GC_REGISTER_FINALIZER_NO_ORDER(local3, finalizer, (void*)3, 0, 0); + local4 = GC_MALLOC(12); + GC_REGISTER_FINALIZER_NO_ORDER(local4, finalizer, (void*)4, 0, 0); + + void **globalData = (void**)global; + globalData[0] = local; + globalData[1] = local2; + + void **localData = (void**)local; + localData[0] = local3; + + void **local2Data = (void**)local2; + local2Data[0] = local4; // actually ignored, because local2 is atomic, so 4 is freeable + + emscripten_async_call(waiter, 100); + + return 0; +} + diff --git a/tests/browser_harness.html b/tests/browser_harness.html index 3fbe8646..86f3749f 100644 --- a/tests/browser_harness.html +++ b/tests/browser_harness.html @@ -1,5 +1,9 @@ <html> +<head> + <title>Emscripten Browser Test Harness</title> +</head> <body> +<h2><b>Running tests...</b></h2> <div id="output"></div> <script> var counter = 0; @@ -9,8 +13,8 @@ try { request.send(null); if (request.responseText != 'False') { - document.getElementById('output').innerHTML += 'opening test window ' + (counter++) + '..<br>'; window.open(request.responseText); + document.getElementById('output').innerHTML += 'opened test window ' + (counter++) + '..<br>'; } setTimeout(check, 333); } catch(e) { diff --git a/tests/cases/complexphi.ll b/tests/cases/complexphi.ll index 6f64af06..fcb7185f 100644 --- a/tests/cases/complexphi.ll +++ b/tests/cases/complexphi.ll @@ -3,6 +3,7 @@ target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f3 target triple = "i386-pc-linux-gnu" @.str = private unnamed_addr constant [15 x i8] c"hello, world!\0A\00", align 1 ; [#uses=1 type=[15 x i8]*] +@_dispatchTable = internal global i64 0 ; [#uses=0] define i32 @main() { @@ -19,6 +20,9 @@ cond.null: cond.end: ; preds = %cond.false, %cond.true %cond = phi { i32, i32 } [ { i32 5, i32 6 }, %entry ], [ zeroinitializer, %cond.null ] ; [#uses=1] store { i32, i32 } %cond, { i32, i32 }* %comp + + store { i32, i32 } { i32 ptrtoint (i64* @_dispatchTable to i32), i32 0 }, { i32, i32 }* getelementptr inbounds ([1 x i64]* @_dispatchTable, i32 0, i32 0, i32 1), align 4 + ret i32 0 ; [debug line = 6:13] } diff --git a/tests/cases/dash.ll b/tests/cases/dash.ll new file mode 100644 index 00000000..ed5b01ae --- /dev/null +++ b/tests/cases/dash.ll @@ -0,0 +1,18 @@ +; ModuleID = '/tmp/tmpqfApGD/a.out.bc' +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128" +target triple = "i386-pc-linux-gnu" + +@other-name = alias i32 ()* @main + +@.st-r = private unnamed_addr constant [15 x i8] c"hello, world!\0A\00", align 1 + +define i32 @main() { +entry: + %ret-val = alloca i32, align 4 + store i32 0, i32* %ret-val + %aaa = bitcast i32 ()* @other-name to i32 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.st-r, i32 0, i32 0), i32 %aaa) + ret i32 %ret-val +} + +declare i32 @printf(i8*, ...) diff --git a/tests/cases/funcptr.ll b/tests/cases/funcptr.ll new file mode 100644 index 00000000..07e2bf91 --- /dev/null +++ b/tests/cases/funcptr.ll @@ -0,0 +1,27 @@ +; ModuleID = 'tests/hello_world.bc' +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128" +target triple = "i386-pc-linux-gnu" + +@.str = private unnamed_addr constant [17 x i8] c"hello %d world!\0A\00", align 1 ; [#uses=1 type=[17 x i8]*] + +; [#uses=0] +define i32 @main() { +entry: + %retval = alloca i32, align 4 ; [#uses=1 type=i32*] + store i32 0, i32* %retval + %access_virt_barray = bitcast i32 0 to [64 x i16]* (i32*, i32)** + store [64 x i16]* (i32*, i32)* @access_virt_barray, [64 x i16]* (i32*, i32)** %access_virt_barray, align 4 + %wakaptr = bitcast [64 x i16]* (i32*, i32)** %access_virt_barray to i32* + %waka = load i32* %wakaptr + %waka2 = icmp eq i32 %waka, 0 + %waka3 = zext i1 %waka2 to i32 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([17 x i8]* @.str, i32 0, i32 0), i32 %waka3) ; [#uses=0 type=i32] + ret i32 1 +} + +define [64 x i16]* @access_virt_barray(i32*, i32) { + ret void +} + +; [#uses=1] +declare i32 @printf(i8*, ...) diff --git a/tests/cases/funcptr.txt b/tests/cases/funcptr.txt new file mode 100644 index 00000000..1030830d --- /dev/null +++ b/tests/cases/funcptr.txt @@ -0,0 +1 @@ +hello 0 world! diff --git a/tests/cases/phientryimplicitmoar.ll b/tests/cases/phientryimplicitmoar.ll new file mode 100644 index 00000000..c83458e6 --- /dev/null +++ b/tests/cases/phientryimplicitmoar.ll @@ -0,0 +1,28 @@ +; ModuleID = 'tests/hello_world.bc' +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128" +target triple = "i386-pc-linux-gnu" + +@.str = private unnamed_addr constant [15 x i8] c"hello, world!\0A\00", align 1 ; [#uses=1 type=[15 x i8]*] +@.str2 = private unnamed_addr constant [15 x i8] c"hello!!world!\0A\00", align 1 ; [#uses=1 type=[15 x i8]*] + +define i32 @main() { + %retval = alloca i32, align 4 + %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str2, i32 0, i32 0)) + %a12 = zext i1 1 to i32 + br label %13 + +; <label>:13 ; preds = %13, %1 + %a14 = phi i32 [ %a12, %1 ], [ %a15, %13 ] + %call0 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str, i32 0, i32 0)) + %a15 = add nsw i32 %a14, 2 + %a16 = icmp eq i32 %a15, 9 + br i1 %a16, label %17, label %13 + +; <label>:17 ; preds = %1 + %call1 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str2, i32 0, i32 0)) + ret i32 1 +} + +; [#uses=1] +declare i32 @printf(i8*, ...) + diff --git a/tests/cases/phientryimplicitmoar.txt b/tests/cases/phientryimplicitmoar.txt new file mode 100644 index 00000000..50e5e9ae --- /dev/null +++ b/tests/cases/phientryimplicitmoar.txt @@ -0,0 +1,6 @@ +hello!!world! +hello, world! +hello, world! +hello, world! +hello, world! +hello!!world! diff --git a/tests/cases/phinonexist.ll b/tests/cases/phinonexist.ll new file mode 100644 index 00000000..145d2221 --- /dev/null +++ b/tests/cases/phinonexist.ll @@ -0,0 +1,25 @@ +; ModuleID = 'tests/hello_world.bc' +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128" +target triple = "i386-pc-linux-gnu" + +@.str = private unnamed_addr constant [15 x i8] c"hello, world!\0A\00", align 1 ; [#uses=1 type=[15 x i8]*] + +define i32 @main() { + %retval = alloca i32, align 4 + %a12 = zext i1 1 to i32 + br label %13 + +; <label>:13 ; preds = %13, %1 + %a14 = phi i32 [ %a12, %1 ], [ %a15, %135 ] + %call0 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str, i32 0, i32 0)) + %a15 = add nsw i32 %a14, 2 + %a16 = icmp eq i32 %a15, 9 + br label %17 + +; <label>:17 ; preds = %1 + ret i32 1 +} + +; [#uses=1] +declare i32 @printf(i8*, ...) + diff --git a/tests/cases/subnums.ll b/tests/cases/subnums.ll new file mode 100644 index 00000000..981a1592 --- /dev/null +++ b/tests/cases/subnums.ll @@ -0,0 +1,18 @@ +; ModuleID = 'tests/hello_world.bc' +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128" +target triple = "i386-pc-linux-gnu" + +@.str = private unnamed_addr constant [15 x i8] c"hello, world! %d\0A\00", align 1 ; [#uses=1 type=[18 x i8]*] + +; [#uses=0] +define i32 @main() { +entry: + %retval = alloca i32, align 4 ; [#uses=1 type=i32*] + %sub = sub nsw i32 0, -2147483648 + store i32 %sub, i32* %retval + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([18 x i8]* @.str, i32 0, i32 0), i32 %sub) ; [#uses=0 type=i32] + ret i32 1 +} + +; [#uses=1] +declare i32 @printf(i8*, ...) diff --git a/tests/cases/subnums.txt b/tests/cases/subnums.txt new file mode 100644 index 00000000..e8831e0b --- /dev/null +++ b/tests/cases/subnums.txt @@ -0,0 +1 @@ +hello, world! -2147483648 diff --git a/tests/cube2md5.cpp b/tests/cube2md5.cpp new file mode 100644 index 00000000..d2a638d1 --- /dev/null +++ b/tests/cube2md5.cpp @@ -0,0 +1,28 @@ +#include <stdio.h> +#include <stdlib.h> + +FILE *file; +bool getline(char *str, int len) { return fgets(str, len, file)!=NULL; } + +int main() { + file = fopen("cube2md5.txt", "r"); + char buf[1024]; + int tmp; + getline(buf, sizeof(buf)); + if(sscanf(buf, " frame %d", &tmp)==1) + { + printf("frame %d\n", tmp); + for(int numdata = 0; getline(buf, sizeof(buf)) && buf[0]!='}';) + { + printf("frameline\n"); + for(char *src = buf, *next = src; numdata < 198; numdata++, src = next) + { + double x = strtod(src, &next); + printf("animdata[%d] = %.8f\n", numdata, x); + if(next <= src) break; + } + } + } + return 1; +} + diff --git a/tests/cube2md5.ok b/tests/cube2md5.ok new file mode 100644 index 00000000..13505e73 --- /dev/null +++ b/tests/cube2md5.ok @@ -0,0 +1,264 @@ +frame 0 +frameline +animdata[0] = 0.00000000 +animdata[1] = -0.02213600 +animdata[2] = 0.21368000 +animdata[3] = 0.00000000 +animdata[4] = 0.94635600 +animdata[5] = 0.32312500 +animdata[6] = 0.00000000 +frameline +animdata[6] = 0.00000000 +animdata[7] = 0.10150600 +animdata[8] = 0.00000000 +animdata[9] = -0.10292100 +animdata[10] = 0.00000000 +animdata[11] = 0.00000000 +animdata[12] = 0.00000000 +frameline +animdata[12] = 0.00000000 +animdata[13] = 0.11562300 +animdata[14] = 0.00000000 +animdata[15] = -0.13181200 +animdata[16] = 0.00000000 +animdata[17] = 0.00000000 +animdata[18] = 0.00000000 +frameline +animdata[18] = 0.00000000 +animdata[19] = 0.14716600 +animdata[20] = 0.05224800 +animdata[21] = 0.00000000 +animdata[22] = 0.99503400 +animdata[23] = 0.09954000 +animdata[24] = 0.00000000 +frameline +animdata[24] = -0.08901200 +animdata[25] = 0.03495200 +animdata[26] = 0.10200100 +animdata[27] = -0.90449900 +animdata[28] = 0.31986300 +animdata[29] = -0.16450100 +animdata[30] = 0.00000000 +frameline +animdata[30] = 0.00000000 +animdata[31] = 0.03460000 +animdata[32] = 0.00000000 +animdata[33] = -0.33932300 +animdata[34] = -0.17058500 +animdata[35] = -0.05674000 +animdata[36] = 0.00000000 +frameline +animdata[36] = 0.08901300 +animdata[37] = 0.03495300 +animdata[38] = 0.10200300 +animdata[39] = -0.90678000 +animdata[40] = -0.30414400 +animdata[41] = 0.13180800 +animdata[42] = 0.00000000 +frameline +animdata[42] = 0.00000000 +animdata[43] = 0.03459800 +animdata[44] = 0.00000000 +animdata[45] = -0.38465600 +animdata[46] = 0.20853500 +animdata[47] = 0.04355200 +animdata[48] = 0.00000000 +frameline +animdata[48] = 0.05478300 +animdata[49] = 0.08776100 +animdata[50] = 0.00658100 +animdata[51] = -0.04975400 +animdata[52] = -0.00020500 +animdata[53] = -0.00542700 +animdata[54] = 0.00000000 +frameline +animdata[54] = -0.05362600 +animdata[55] = 0.08775300 +animdata[56] = 0.00662200 +animdata[57] = -0.03224000 +animdata[58] = 0.70633700 +animdata[59] = 0.03805700 +animdata[60] = 0.00000000 +frameline +animdata[60] = 0.08767800 +animdata[61] = 0.09910000 +animdata[62] = 0.04200400 +animdata[63] = -0.48658300 +animdata[64] = -0.75782800 +animdata[65] = -0.39224400 +animdata[66] = 0.00000000 +frameline +animdata[66] = 0.00000000 +animdata[67] = 0.08621700 +animdata[68] = 0.00000000 +animdata[69] = -0.13275100 +animdata[70] = -0.25403200 +animdata[71] = 0.42206600 +animdata[72] = 0.00000000 +frameline +animdata[72] = 0.00010900 +animdata[73] = 0.11343800 +animdata[74] = -0.00046000 +animdata[75] = 0.00424900 +animdata[76] = 0.43245700 +animdata[77] = 0.08065100 +animdata[78] = 0.00000000 +frameline +animdata[78] = -0.08767700 +animdata[79] = 0.09909800 +animdata[80] = 0.04200500 +animdata[81] = -0.48460700 +animdata[82] = 0.76187500 +animdata[83] = 0.38432000 +animdata[84] = 0.00000000 +frameline +animdata[84] = 0.00000000 +animdata[85] = 0.08621700 +animdata[86] = 0.00000000 +animdata[87] = -0.09719100 +animdata[88] = 0.28995100 +animdata[89] = -0.44564500 +animdata[90] = 0.00000000 +frameline +animdata[90] = 0.00021600 +animdata[91] = 0.11610300 +animdata[92] = 0.00060100 +animdata[93] = -0.02305500 +animdata[94] = -0.41085000 +animdata[95] = -0.08651400 +animdata[96] = 0.00000000 +frameline +animdata[96] = 0.00000000 +animdata[97] = -0.02463200 +animdata[98] = 0.22803300 +animdata[99] = 0.00000000 +animdata[100] = 0.81624500 +animdata[101] = -0.57770600 +animdata[102] = 0.00000000 +frameline +animdata[102] = 0.06124500 +animdata[103] = 0.07378500 +animdata[104] = 0.01947500 +animdata[105] = -0.49098300 +animdata[106] = -0.18594000 +animdata[107] = 0.01243400 +animdata[108] = 0.00000000 +frameline +animdata[108] = 0.00000000 +animdata[109] = 0.10644500 +animdata[110] = 0.00000000 +animdata[111] = -0.54092700 +animdata[112] = 0.23666500 +animdata[113] = -0.28196200 +animdata[114] = 0.00000000 +frameline +animdata[114] = 0.00000000 +animdata[115] = 0.08007200 +animdata[116] = 0.00000000 +animdata[117] = -0.31038200 +animdata[118] = -0.77741400 +animdata[119] = 0.54682500 +animdata[120] = 0.00000000 +frameline +animdata[120] = 0.00000000 +animdata[121] = 0.05055300 +animdata[122] = 0.00000000 +animdata[123] = 0.09166800 +animdata[124] = -0.20672100 +animdata[125] = -0.07288900 +animdata[126] = 0.00000000 +frameline +animdata[126] = -0.06124500 +animdata[127] = 0.07378400 +animdata[128] = 0.01947500 +animdata[129] = -0.58758300 +animdata[130] = 0.18610800 +animdata[131] = 0.00950000 +animdata[132] = 0.00000000 +frameline +animdata[132] = 0.00000000 +animdata[133] = 0.10644600 +animdata[134] = 0.00000000 +animdata[135] = -0.54092800 +animdata[136] = -0.23666300 +animdata[137] = 0.28196400 +animdata[138] = 0.00000000 +frameline +animdata[138] = 0.00000000 +animdata[139] = 0.08007200 +animdata[140] = 0.00000000 +animdata[141] = -0.28906600 +animdata[142] = 0.74845100 +animdata[143] = -0.59650400 +animdata[144] = 0.00000000 +frameline +animdata[144] = 0.00000000 +animdata[145] = 0.05055300 +animdata[146] = 0.00000000 +animdata[147] = 0.12786100 +animdata[148] = 0.23079600 +animdata[149] = 0.07114100 +animdata[150] = 0.00000000 +frameline +animdata[150] = 0.00000000 +animdata[151] = -0.04418300 +animdata[152] = 0.02565600 +animdata[153] = -0.87689900 +animdata[154] = 0.00000000 +animdata[155] = 0.00000000 +animdata[156] = 0.00000000 +frameline +animdata[156] = 0.00000000 +animdata[157] = 0.04597000 +animdata[158] = 0.00000000 +animdata[159] = 0.14528300 +animdata[160] = 0.00000000 +animdata[161] = 0.00000000 +animdata[162] = 0.00000000 +frameline +animdata[162] = 0.00000000 +animdata[163] = 0.05919300 +animdata[164] = 0.00000000 +animdata[165] = 0.06151300 +animdata[166] = 0.00000000 +animdata[167] = 0.00000000 +animdata[168] = 0.00000000 +frameline +animdata[168] = 0.00000000 +animdata[169] = 0.06477600 +animdata[170] = 0.00000000 +animdata[171] = 0.01219600 +animdata[172] = 0.00000000 +animdata[173] = 0.00000000 +animdata[174] = 0.00000000 +frameline +animdata[174] = 0.00000000 +animdata[175] = 0.06418900 +animdata[176] = 0.00000000 +animdata[177] = -0.01392400 +animdata[178] = 0.00000000 +animdata[179] = 0.00000000 +animdata[180] = 0.00000000 +frameline +animdata[180] = 0.00000000 +animdata[181] = 0.06595100 +animdata[182] = 0.00000000 +animdata[183] = -0.04015600 +animdata[184] = 0.00000000 +animdata[185] = 0.00000000 +animdata[186] = 0.00000000 +frameline +animdata[186] = 0.00000000 +animdata[187] = 0.06742100 +animdata[188] = 0.00000000 +animdata[189] = -0.02690900 +animdata[190] = 0.00000000 +animdata[191] = 0.00000000 +animdata[192] = 0.00000000 +frameline +animdata[192] = 0.00000000 +animdata[193] = 0.06124900 +animdata[194] = 0.00000000 +animdata[195] = -0.01467800 +animdata[196] = 0.00000000 +animdata[197] = 0.00000000 diff --git a/tests/cube2md5.txt b/tests/cube2md5.txt new file mode 100644 index 00000000..5226b5bf --- /dev/null +++ b/tests/cube2md5.txt @@ -0,0 +1,37 @@ +frame 0 { + 0.000000 -0.022136 0.213680 0.000000 0.946356 0.323125 + 0.000000 0.101506 0.000000 -0.102921 0.000000 0.000000 + 0.000000 0.115623 0.000000 -0.131812 0.000000 0.000000 + 0.000000 0.147166 0.052248 0.000000 0.995034 0.099540 + -0.089012 0.034952 0.102001 -0.904499 0.319863 -0.164501 + 0.000000 0.034600 0.000000 -0.339323 -0.170585 -0.056740 + 0.089013 0.034953 0.102003 -0.906780 -0.304144 0.131808 + 0.000000 0.034598 0.000000 -0.384656 0.208535 0.043552 + 0.054783 0.087761 0.006581 -0.049754 -0.000205 -0.005427 + -0.053626 0.087753 0.006622 -0.032240 0.706337 0.038057 + 0.087678 0.099100 0.042004 -0.486583 -0.757828 -0.392244 + 0.000000 0.086217 0.000000 -0.132751 -0.254032 0.422066 + 0.000109 0.113438 -0.000460 0.004249 0.432457 0.080651 + -0.087677 0.099098 0.042005 -0.484607 0.761875 0.384320 + 0.000000 0.086217 0.000000 -0.097191 0.289951 -0.445645 + 0.000216 0.116103 0.000601 -0.023055 -0.410850 -0.086514 + 0.000000 -0.024632 0.228033 0.000000 0.816245 -0.577706 + 0.061245 0.073785 0.019475 -0.490983 -0.185940 0.012434 + 0.000000 0.106445 0.000000 -0.540927 0.236665 -0.281962 + 0.000000 0.080072 0.000000 -0.310382 -0.777414 0.546825 + 0.000000 0.050553 0.000000 0.091668 -0.206721 -0.072889 + -0.061245 0.073784 0.019475 -0.587583 0.186108 0.009500 + 0.000000 0.106446 0.000000 -0.540928 -0.236663 0.281964 + 0.000000 0.080072 0.000000 -0.289066 0.748451 -0.596504 + 0.000000 0.050553 0.000000 0.127861 0.230796 0.071141 + 0.000000 -0.044183 0.025656 -0.876899 0.000000 0.000000 + 0.000000 0.045970 0.000000 0.145283 0.000000 0.000000 + 0.000000 0.059193 0.000000 0.061513 0.000000 0.000000 + 0.000000 0.064776 0.000000 0.012196 0.000000 0.000000 + 0.000000 0.064189 0.000000 -0.013924 0.000000 0.000000 + 0.000000 0.065951 0.000000 -0.040156 0.000000 0.000000 + 0.000000 0.067421 0.000000 -0.026909 0.000000 0.000000 + 0.000000 0.061249 0.000000 -0.014678 0.000000 0.000000 +} + + diff --git a/tests/cube_explosion.c b/tests/cube_explosion.c new file mode 100644 index 00000000..ee990a57 --- /dev/null +++ b/tests/cube_explosion.c @@ -0,0 +1,235 @@ +/* +THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION +AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN. + +THE ORIGINAL AUTHOR IS KYLE FOLEY. + +THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY +OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF +MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, +ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE +RESULTING FROM THE USE, MODIFICATION, OR +REDISTRIBUTION OF THIS SOFTWARE. +*/ + +#if !EMSCRIPTEN +#define USE_GLEW 1 +#endif + +#if USE_GLEW +#include "GL/glew.h" +#endif + +#include "SDL/SDL.h" +#if !USE_GLEW +#include "SDL/SDL_opengl.h" +#endif + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +void verify() { + int width = 640, height = 480; + unsigned char *data = (unsigned char*)malloc(width*height*4); + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); + int sum = 0; + for (int x = 0; x < width*height*4; x++) { + if (x % 4 != 3) sum += x * data[x]; + } +#if EMSCRIPTEN + int result = sum; + REPORT_RESULT(); +#endif +} + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { + printf("Unable to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); + screen = SDL_SetVideoMode( 640, 480, 24, SDL_OPENGL ); + if ( !screen ) { + printf("Unable to set video mode: %s\n", SDL_GetError()); + return 1; + } + + glClearColor( 0, 0, 0, 0 ); + glClear( GL_COLOR_BUFFER_BIT ); + + // Create a texture + + GLuint texture; + glGenTextures( 1, &texture ); + glBindTexture( GL_TEXTURE_2D, texture ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + GLubyte textureData[16*16*4]; + for (int x = 0; x < 16; x++) { + for (int y = 0; y < 16; y++) { + *((int*)&textureData[(x*16 + y) * 4]) = x*16 + ((y*16) << 8) + ((y*16) << 16) + 0xff331177; + } + } + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, + GL_RGBA, GL_UNSIGNED_BYTE, textureData ); + + // BEGIN + +#if USE_GLEW + glewInit(); +#endif + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + // original: glFrustum(-0.6435469817188064, 0.6435469817188064 ,-0.48266022190470925, 0.48266022190470925 ,0.5400000214576721, 2048); + // cubegeom: glFrustum(-0.6435469817188064, 0.1435469817188064, -0.48266022190470925, 0.88266022190470925 ,0.5400000214576721, 2048); + glFrustum(-0.6435469817188064, 0.6435469817188064, -0.48266022190470925, 0.48266022190470925, 0.5400000214576721, 2048); + + glMatrixMode(GL_MODELVIEW); + GLfloat matrixData[] = { -1, 0, 0, 0, + 0, 0,-1, 0, + 0, 1, 0, 0, + 0, 0, 0, 1 }; + glLoadMatrixf(matrixData); + // cubegeom glTranslated(-512,-512,-527); // XXX this should be uncommented, but if it is then nothing is shown + glRotated(0, 0, 1, 0); + glRotated(0, -1, 0, 0); + glRotated(0, 0, 0, -1); + glTranslated(-512,-512,-527); + + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + + glClear(GL_DEPTH_BUFFER_BIT); + + GLint ok; + + const char *vertexShader = + "uniform vec4 center, animstate;\n" + "uniform vec4 texgenS, texgenT;\n" + "void main(void)\n" + "{\n" + " vec4 wobble = vec4(gl_Vertex.xyz*(1.0 + 0.5*abs(fract(dot(gl_Vertex.xyz, center.xyz) + animstate.w*0.002) - 0.5)), gl_Vertex.w);\n" + " gl_Position = gl_ModelViewProjectionMatrix * wobble;\n" + " gl_FrontColor = gl_Color;\n" + " gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;\n" + " vec2 texgen = vec2(dot(texgenS, gl_Vertex), dot(texgenT, gl_Vertex)); \n" + " gl_TexCoord[1].xy = texgen;\n" + " gl_TexCoord[2].xy = texgen - animstate.w*0.0005;\n" + "}\n"; + const char *fragmentShader = + "uniform sampler2D tex2;\n" + "uniform sampler2D tex0, tex1;\n" + "void main(void)\n" + "{\n" + " vec2 dtc = gl_TexCoord[0].xy + texture2D(tex0, gl_TexCoord[2].xy).xy*0.1; \n" + " vec4 diffuse = texture2D(tex0, dtc);\n" + " vec4 blend = texture2D(tex1, gl_TexCoord[1].xy); \n" + " diffuse *= blend.a*4.0; \n" + " diffuse.b += 0.5 - blend.a*0.5; \n" + " gl_FragColor = diffuse * gl_Color;\n" + "}\n"; + + GLuint vs = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vs, 1, &vertexShader, NULL); + glCompileShader(vs); + glGetShaderiv(vs, GL_COMPILE_STATUS, &ok); + assert(ok); + + GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fs, 1, &fragmentShader, NULL); + glCompileShader(fs); + glGetShaderiv(fs, GL_COMPILE_STATUS, &ok); + assert(ok); + + GLuint program = glCreateProgram(); + + glAttachShader(program, vs); + glAttachShader(program, fs); + glLinkProgram(program); + glGetProgramiv(program, GL_LINK_STATUS, &ok); + assert(ok); + + glUseProgram(program); + + // get active uniform data for 10 uniforms. XXX they include our additions from shader rewriting! XXX + + // gen texture, we already has one + + GLuint arrayBuffer; + glGenBuffers(1, &arrayBuffer); + glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer); + GLubyte arrayBufferData[] = +{0,0,0,128,0,0,0,0,0,0,128,63,0,0,0,0,0,0,128,63,0,0,0,128,0,0,0,0,0,0,128,63,171,170,170,61,0,0,128,63,0,0,0,128,0,0,0,0,0,0,128,63,171,170,42,62,0,0,128,63,0,0,0,128,0,0,0,0,0,0,128,63,0,0,128,62,0,0,128,63,0,0,0,128,0,0,0,128,0,0,128,63,171,170,170,62,0,0,128,63,0,0,0,128,0,0,0,128,0,0,128,63,85,85,213,62,0,0,128,63,0,0,0,128,0,0,0,128,0,0,128,63,0,0,0,63,0,0,128,63,0,0,0,0,0,0,0,128,0,0,128,63,85,85,21,63,0,0,128,63,0,0,0,0,0,0,0,128,0,0,128,63,171,170,42,63,0,0,128,63,0,0,0,0,0,0,0,128,0,0,128,63,0,0,64,63,0,0,128,63,0,0,0,0,0,0,0,0,0,0,128,63,85,85,85,63,0,0,128,63,0,0,0,0,0,0,0,0,0,0,128,63,171,170,106,63,0,0,128,63,0,0,0,128,0,0,0,0,0,0,128,63,0,0,128,63,0,0,128,63,0,0,0,128,0,0,0,63,215,179,93,63,0,0,0,0,85,85,85,63,0,0,128,190,215,179,221,62,215,179,93,63,171,170,170,61,85,85,85,63,215,179,221,190,0,0,128,62,215,179,93,63,171,170,42,62,85,85,85,63,0,0,0,191,0,48,13,36,215,179,93,63,0,0,128,62,85,85,85,63,215,179,221,190,0,0,128,190,215,179,93,63,171,170,170,62,85,85,85,63,0,0,128,190,215,179,221,190,215,179,93,63,85,85,213,62,85,85,85,63,0,76,163,165,0,0,0,191,215,179,93,63,0,0,0,63,85,85,85,63,0,0,128,62,215,179,221,190,215,179,93,63,85,85,21,63,85,85,85,63,215,179,221,62,0,0,128,190,215,179,93,63,171,170,42,63,85,85,85,63,0,0,0,63,0,200,211,164,215,179,93,63,0,0,64,63,85,85,85,63,215,179,221,62,0,0,128,62,215,179,93,63,85,85,85,63,85,85,85,63,0,0,128,62,215,179,221,62,215,179,93,63,171,170,106,63,85,85,85,63,0,0,0,128,0,0,0,63,215,179,93,63,0,0,128,63,85,85,85,63,0,0,0,128,215,179,93,63,0,0,0,63,0,0,0,0,171,170,42,63,215,179,221,190,0,0,64,63,0,0,0,63,171,170,170,61,171,170,42,63,0,0,64,191,215,179,221,62,0,0,0,63,171,170,42,62,171,170,42,63,215,179,93,191,63,139,116,36,0,0,0,63,0,0,128,62,171,170,42,63,0,0,64,191,215,179,221,190,0,0,0,63,171,170,170,62,171,170,42,63,215,179,221,190,0,0,64,191,0,0,0,63,85,85,213,62,171,170,42,63,83,107,13,166,215,179,93,191,0,0,0,63,0,0,0,63,171,170,42,63,215,179,221,62,0,0,64,191,0,0,0,63,85,85,21,63,171,170,42,63,0,0,64,63,215,179,221,190,0,0,0,63,171,170,42,63,171,170,42,63,215,179,93,63,111,104,55,165,0,0,0,63,0,0,64,63,171,170,42,63,0,0,64,63,215,179,221,62,0,0,0,63,85,85,85,63,171,170,42,63,215,179,221,62,0,0,64,63,0,0,0,63,171,170,106,63,171,170,42,63,0,0,0,128,215,179,93,63,0,0,0,63,0,0,128,63,171,170,42,63,0,0,0,128,0,0,128,63,0,166,17,38,0,0,0,0,0,0,0,63,0,0,0,191,215,179,93,63,0,166,17,38,171,170,170,61,0,0,0,63,215,179,93,191,0,0,0,63,0,166,17,38,171,170,42,62,0,0,0,63,0,0,128,191,0,48,141,36,0,166,17,38,0,0,128,62,0,0,0,63,215,179,93,191,0,0,0,191,0,166,17,38,171,170,170,62,0,0,0,63,0,0,0,191,215,179,93,191,0,166,17,38,85,85,213,62,0,0,0,63,0,76,35,166,0,0,128,191,0,166,17,38,0,0,0,63,0,0,0,63,0,0,0,63,215,179,93,191,0,166,17,38,85,85,21,63,0,0,0,63,215,179,93,63,0,0,0,191,0,166,17,38,171,170,42,63,0,0,0,63,0,0,128,63,0,200,83,165,0,166,17,38,0,0,64,63,0,0,0,63,215,179,93,63,0,0,0,63,0,166,17,38,85,85,85,63,0,0,0,63,0,0,0,63,215,179,93,63,0,166,17,38,171,170,106,63,0,0,0,63,0,0,0,128,0,0,128,63,0,166,17,38,0,0,128,63,0,0,0,63,0,0,0,128,215,179,93,63,0,0,0,191,0,0,0,0,171,170,170,62,215,179,221,190,0,0,64,63,0,0,0,191,171,170,170,61,171,170,170,62,0,0,64,191,215,179,221,62,0,0,0,191,171,170,42,62,171,170,170,62,215,179,93,191,63,139,116,36,0,0,0,191,0,0,128,62,171,170,170,62,0,0,64,191,215,179,221,190,0,0,0,191,171,170,170,62,171,170,170,62,215,179,221,190,0,0,64,191,0,0,0,191,85,85,213,62,171,170,170,62,83,107,13,166,215,179,93,191,0,0,0,191,0,0,0,63,171,170,170,62,215,179,221,62,0,0,64,191,0,0,0,191,85,85,21,63,171,170,170,62,0,0,64,63,215,179,221,190,0,0,0,191,171,170,42,63,171,170,170,62,215,179,93,63,111,104,55,165,0,0,0,191,0,0,64,63,171,170,170,62,0,0,64,63,215,179,221,62,0,0,0,191,85,85,85,63,171,170,170,62,215,179,221,62,0,0,64,63,0,0,0,191,171,170,106,63,171,170,170,62,0,0,0,128,215,179,93,63,0,0,0,191,0,0,128,63,171,170,170,62,0,0,0,128,0,0,0,63,215,179,93,191,0,0,0,0,171,170,42,62,0,0,128,190,215,179,221,62,215,179,93,191,171,170,170,61,171,170,42,62,215,179,221,190,0,0,128,62,215,179,93,191,171,170,42,62,171,170,42,62,0,0,0,191,0,48,13,36,215,179,93,191,0,0,128,62,171,170,42,62,215,179,221,190,0,0,128,190,215,179,93,191,171,170,170,62,171,170,42,62,0,0,128,190,215,179,221,190,215,179,93,191,85,85,213,62,171,170,42,62,0,76,163,165,0,0,0,191,215,179,93,191,0,0,0,63,171,170,42,62,0,0,128,62,215,179,221,190,215,179,93,191,85,85,21,63,171,170,42,62,215,179,221,62,0,0,128,190,215,179,93,191,171,170,42,63,171,170,42,62,0,0,0,63,0,200,211,164,215,179,93,191,0,0,64,63,171,170,42,62,215,179,221,62,0,0,128,62,215,179,93,191,85,85,85,63,171,170,42,62,0,0,128,62,215,179,221,62,215,179,93,191,171,170,106,63,171,170,42,62,0,0,0,128,0,0,0,63,215,179,93,191,0,0,128,63,171,170,42,62,0,0,0,128,0,166,145,38,0,0,128,191,0,0,0,0,0,0,64,37,0,166,17,166,63,69,124,38,0,0,128,191,171,170,170,61,0,0,64,37,63,69,124,166,0,166,17,38,0,0,128,191,171,170,42,62,0,0,64,37,0,166,145,166,122,167,160,11,0,0,128,191,0,0,128,62,0,0,64,37,63,69,124,166,0,166,17,166,0,0,128,191,171,170,170,62,0,0,64,37,0,166,17,166,63,69,124,166,0,0,128,191,85,85,213,62,0,0,64,37,223,207,57,141,0,166,145,166,0,0,128,191,0,0,0,63,0,0,64,37,0,166,17,38,63,69,124,166,0,0,128,191,85,85,21,63,0,0,64,37,63,69,124,38,0,166,17,166,0,0,128,191,171,170,42,63,0,0,64,37,0,166,145,38,55,251,112,140,0,0,128,191,0,0,64,63,0,0,64,37,63,69,124,38,0,166,17,38,0,0,128,191,85,85,85,63,0,0,64,37,0,166,17,38,63,69,124,38,0,0,128,191,171,170,106,63,0,0,64,37,0,0,0,128,0,166,145,38,0,0,128,191,0,0,128,63,0,0,64,37}; + glBufferData(GL_ARRAY_BUFFER, 1820, arrayBufferData, GL_STATIC_DRAW); + + GLuint elementBuffer; + glGenBuffers(1, &elementBuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer); + GLubyte elementBufferData[] = +{0,0,13,0,1,0,1,0,13,0,14,0,1,0,14,0,2,0,2,0,14,0,15,0,2,0,15,0,3,0,3,0,15,0,16,0,3,0,16,0,4,0,4,0,16,0,17,0,4,0,17,0,5,0,5,0,17,0,18,0,5,0,18,0,6,0,6,0,18,0,19,0,6,0,19,0,7,0,7,0,19,0,20,0,7,0,20,0,8,0,8,0,20,0,21,0,8,0,21,0,9,0,9,0,21,0,22,0,9,0,22,0,10,0,10,0,22,0,23,0,10,0,23,0,11,0,11,0,23,0,24,0,11,0,24,0,12,0,12,0,24,0,25,0,24,0,37,0,25,0,25,0,37,0,38,0,23,0,36,0,24,0,24,0,36,0,37,0,22,0,35,0,23,0,23,0,35,0,36,0,21,0,34,0,22,0,22,0,34,0,35,0,20,0,33,0,21,0,21,0,33,0,34,0,19,0,32,0,20,0,20,0,32,0,33,0,18,0,31,0,19,0,19,0,31,0,32,0,17,0,30,0,18,0,18,0,30,0,31,0,16,0,29,0,17,0,17,0,29,0,30,0,15,0,28,0,16,0,16,0,28,0,29,0,14,0,27,0,15,0,15,0,27,0,28,0,13,0,26,0,14,0,14,0,26,0,27,0,26,0,39,0,27,0,27,0,39,0,40,0,27,0,40,0,28,0,28,0,40,0,41,0,28,0,41,0,29,0,29,0,41,0,42,0,29,0,42,0,30,0,30,0,42,0,43,0,30,0,43,0,31,0,31,0,43,0,44,0,31,0,44,0,32,0,32,0,44,0,45,0,32,0,45,0,33,0,33,0,45,0,46,0,33,0,46,0,34,0,34,0,46,0,47,0,34,0,47,0,35,0,35,0,47,0,48,0,35,0,48,0,36,0,36,0,48,0,49,0,36,0,49,0,37,0,37,0,49,0,50,0,37,0,50,0,38,0,38,0,50,0,51,0,50,0,63,0,51,0,51,0,63,0,64,0,49,0,62,0,50,0,50,0,62,0,63,0,48,0,61,0,49,0,49,0,61,0,62,0,47,0,60,0,48,0,48,0,60,0,61,0,46,0,59,0,47,0,47,0,59,0,60,0,45,0,58,0,46,0,46,0,58,0,59,0,44,0,57,0,45,0,45,0,57,0,58,0,43,0,56,0,44,0,44,0,56,0,57,0,42,0,55,0,43,0,43,0,55,0,56,0,41,0,54,0,42,0,42,0,54,0,55,0,40,0,53,0,41,0,41,0,53,0,54,0,39,0,52,0,40,0,40,0,52,0,53,0,52,0,65,0,53,0,53,0,65,0,66,0,53,0,66,0,54,0,54,0,66,0,67,0,54,0,67,0,55,0,55,0,67,0,68,0,55,0,68,0,56,0,56,0,68,0,69,0,56,0,69,0,57,0,57,0,69,0,70,0,57,0,70,0,58,0,58,0,70,0,71,0,58,0,71,0,59,0,59,0,71,0,72,0,59,0,72,0,60,0,60,0,72,0,73,0,60,0,73,0,61,0,61,0,73,0,74,0,61,0,74,0,62,0,62,0,74,0,75,0,62,0,75,0,63,0,63,0,75,0,76,0,63,0,76,0,64,0,64,0,76,0,77,0,76,0,89,0,77,0,77,0,89,0,90,0,75,0,88,0,76,0,76,0,88,0,89,0,74,0,87,0,75,0,75,0,87,0,88,0,73,0,86,0,74,0,74,0,86,0,87,0,72,0,85,0,73,0,73,0,85,0,86,0,71,0,84,0,72,0,72,0,84,0,85,0,70,0,83,0,71,0,71,0,83,0,84,0,69,0,82,0,70,0,70,0,82,0,83,0,68,0,81,0,69,0,69,0,81,0,82,0,67,0,80,0,68,0,68,0,80,0,81,0,66,0,79,0,67,0,67,0,79,0,80,0,65,0,78,0,66,0,66,0,78,0,79,0}; + glBufferData(GL_ELEMENT_ARRAY_BUFFER, 864, elementBufferData, GL_STATIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer); + + // try to confuse the client state tracker + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glVertexPointer(3, GL_FLOAT, 20, 0); + glTexCoordPointer(2, GL_FLOAT, 20, (void*)12); + + glPushMatrix(); + glTranslated(484.50579833984375, 589.3919067382812, 528.0055541992188); + + GLint texgenSLocation = glGetUniformLocation(program, "texgenS"); + assert(texgenSLocation >= 0); + GLfloat texgenSData[4] = { 0.31012535095214844, 0.05928778275847435, 0.38769474625587463, 0.5 }; + glUniform4fv(texgenSLocation, 1, texgenSData); + + GLint texgenTLocation = glGetUniformLocation(program, "texgenT"); + assert(texgenTLocation >= 0 && texgenTLocation != texgenSLocation); + GLfloat texgenTData[4] = { -0.12697559595108032, -0.4524572193622589, 0.17076200246810913, 0.5 }; + glUniform4fv(texgenTLocation, 1, texgenTData); + + GLint centerLocation = glGetUniformLocation(program, "center"); + if (centerLocation >= 0) { + GLfloat centerData[4] = { 484.50579833984375, 589.3919067382812, 528.0055541992188, 0 }; + glUniform4fv(centerLocation, 1, centerData); + } + + GLint animstateLocation = glGetUniformLocation(program, "animstate"); + assert(animstateLocation >= 0); + GLfloat animstateData[4] = { 1, 55, 51, 10709 }; + glUniform4fv(animstateLocation, 1, animstateData); + + glRotated(1529.857142857143, 0.5773502588272095, 0.5773502588272095, 0.5773502588272095); + glScaled(-55, 55, -55); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture); // XXX this is after setting Pointers, do we miss it? Also, does it not need clientActiveTexture - should we have updated that? + glActiveTexture(GL_TEXTURE0); + glColor4f(1, 0.158823529411764705, 0.058823529411764705, 1); + + glDrawElements(GL_TRIANGLES, 432, GL_UNSIGNED_SHORT, 0); + + // END + + SDL_GL_SwapBuffers(); + + verify(); + +#if !EMSCRIPTEN + SDL_Delay(1500); +#endif + + SDL_Quit(); + + return 0; +} diff --git a/tests/cubegeom.c b/tests/cubegeom.c new file mode 100644 index 00000000..ecefb24a --- /dev/null +++ b/tests/cubegeom.c @@ -0,0 +1,295 @@ +/* +THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION +AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN. + +THE ORIGINAL AUTHOR IS KYLE FOLEY. + +THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY +OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF +MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, +ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE +RESULTING FROM THE USE, MODIFICATION, OR +REDISTRIBUTION OF THIS SOFTWARE. +*/ + +#if !EMSCRIPTEN +#define USE_GLEW 1 +#endif + +#if USE_GLEW +#include "GL/glew.h" +#endif + +#include "SDL/SDL.h" +#if !USE_GLEW +#include "SDL/SDL_opengl.h" +#endif + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +void verify() { + int width = 640, height = 480; + unsigned char *data = (unsigned char*)malloc(width*height*4); + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); + int sum = 0; + for (int x = 0; x < width*height*4; x++) { + if (x % 4 != 3) sum += x * data[x]; + } +#if EMSCRIPTEN + int result = sum; + REPORT_RESULT(); +#endif +} + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { + printf("Unable to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); + screen = SDL_SetVideoMode( 640, 480, 24, SDL_OPENGL ); + if ( !screen ) { + printf("Unable to set video mode: %s\n", SDL_GetError()); + return 1; + } + + glClearColor( 0, 0, 0, 0 ); + glClear( GL_COLOR_BUFFER_BIT ); + + // Create a texture + + GLuint texture; + glGenTextures( 1, &texture ); + glBindTexture( GL_TEXTURE_2D, texture ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + GLubyte textureData[16*16*4]; + for (int x = 0; x < 16; x++) { + for (int y = 0; y < 16; y++) { + *((int*)&textureData[(x*16 + y) * 4]) = x*16 + ((y*16) << 8); + } + } + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, + GL_RGBA, GL_UNSIGNED_BYTE, textureData ); + + // Create a second texture + + GLuint texture2; + glGenTextures( 1, &texture2 ); + glBindTexture( GL_TEXTURE_2D, texture2 ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + GLubyte texture2Data[] = { 0xff, 0, 0, 0xff, + 0, 0xff, 0, 0xaa, + 0, 0, 0xff, 0x55, + 0x80, 0x90, 0x70, 0 }; + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, + GL_RGBA, GL_UNSIGNED_BYTE, texture2Data ); + + // BEGIN + +#if USE_GLEW + glewInit(); +#endif + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + // original: glFrustum(-0.6435469817188064, 0.6435469817188064 ,-0.48266022190470925, 0.48266022190470925 ,0.5400000214576721, 2048); + glFrustum(-0.6435469817188064, 0.1435469817188064 ,-0.48266022190470925, 0.88266022190470925 ,0.5400000214576721, 2048); + glRotatef(-30, 1, 1, 1); + //GLfloat pm[] = { 1.372136116027832, 0, 0, 0, 0, 0.7910231351852417, 0, 0, -0.6352481842041016, 0.29297152161598206, -1.0005275011062622, -1, 0, 0, -1.080284833908081, 0 }; + //glLoadMatrixf(pm); + + glMatrixMode(GL_MODELVIEW); + GLfloat matrixData[] = { -1, 0, 0, 0, + 0, 0,-1, 0, + 0, 1, 0, 0, + 0, 0, 0, 1 }; + glLoadMatrixf(matrixData); + //glTranslated(-512,-512,-527); // XXX this should be uncommented, but if it is then nothing is shown + + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + + glClear(GL_DEPTH_BUFFER_BIT); + + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glActiveTexture(GL_TEXTURE0); + + glEnableClientState(GL_VERTEX_ARRAY); + + GLuint arrayBuffer, elementBuffer; + glGenBuffers(1, &arrayBuffer); + glGenBuffers(1, &elementBuffer); + + GLubyte arrayData[] = { +/* +[0, 0, 0, 67] ==> 128 float +[0, 0, 128, 67] ==> 256 float +[0, 0, 0, 68] ==> 512 float +[0, 0, 128, 68] ==> 1024 float + +[vertex x ] [vertex y ] [vertex z ] [nr] [texture u ] [texture v ] [lm u ] [lm v ] [color r,g,b,a ] */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 0 + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 1 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 2 + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 3 + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 4 + 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 5 + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 6 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 7 + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 8 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 9 + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 10 + 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 11 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 12 + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 13 + 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 14 + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 15 + + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128 + }; + assert(sizeof(arrayData) == 1408); + glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(arrayData), arrayData, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + GLushort elementData[] = { 1, 2, 0, 2, 3, 0, 5, 6, 4, 6, 7, 4, 9, 10, 8, 10, 11, 8, 13, 14, 12, 14, 15, 12 }; + assert(sizeof(elementData) == 48); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elementData), elementData, GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer); + + // sauer vertex data is apparently 0-12: V3F, 12: N1B, 16-24: T2F, 24-28: T2S, 28-32: C4B + glVertexPointer(3, GL_FLOAT, 32, (void*)0); // all these apply to the ARRAY_BUFFER that is bound + glTexCoordPointer(2, GL_FLOAT, 32, (void*)16); + glClientActiveTexture(GL_TEXTURE1); // XXX seems to be ignored in native build + glTexCoordPointer(2, GL_SHORT, 32, (void*)24); + glClientActiveTexture(GL_TEXTURE0); // likely not needed, it is a cleanup + glNormalPointer(GL_BYTE, 32, (void*)12); + glColorPointer(4, GL_UNSIGNED_BYTE, 32, (void*)28); + + glBindTexture(GL_TEXTURE_2D, texture); // diffuse? + glActiveTexture(GL_TEXTURE0); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, texture2); // lightmap? + glActiveTexture(GL_TEXTURE0); + + GLint ok; + + const char *vertexShader = "uniform vec4 texgenscroll;\n" + "void main(void)\n" + "{\n" + " gl_Position = ftransform();\n" + " gl_TexCoord[0].xy = gl_MultiTexCoord0.xy/100.0 + texgenscroll.xy;\n" // added /100 here + " gl_TexCoord[1].xy = gl_MultiTexCoord1.xy/100.0 * 3.051851e-05;\n" + "}\n"; + const char *fragmentShader = "uniform vec4 colorparams;\n" + "uniform sampler2D diffusemap, lightmap;\n" + "void main(void)\n" + "{\n" + " vec4 diffuse = texture2D(diffusemap, gl_TexCoord[0].xy);\n" + " vec4 lm = texture2D(lightmap, gl_TexCoord[1].xy);\n" + " diffuse *= colorparams;\n" + " gl_FragColor = diffuse * lm;\n" + "}\n"; + + GLuint vs = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vs, 1, &vertexShader, NULL); + glCompileShader(vs); + glGetShaderiv(vs, GL_COMPILE_STATUS, &ok); + assert(ok); + + GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fs, 1, &fragmentShader, NULL); + glCompileShader(fs); + glGetShaderiv(fs, GL_COMPILE_STATUS, &ok); + assert(ok); + + GLuint program = glCreateProgram(); + + glAttachShader(program, vs); + glAttachShader(program, fs); + glLinkProgram(program); + glGetProgramiv(program, GL_LINK_STATUS, &ok); + assert(ok); + + glUseProgram(program); + + GLint lightmapLocation = glGetUniformLocation(program, "lightmap"); + assert(lightmapLocation >= 0); + glUniform1i(lightmapLocation, 1); // sampler2D? Is it the texture unit? + + GLint diffusemapLocation = glGetUniformLocation(program, "diffusemap"); + assert(diffusemapLocation >= 0); + glUniform1i(diffusemapLocation, 0); + + GLint texgenscrollLocation = glGetUniformLocation(program, "texgenscroll"); + assert(texgenscrollLocation >= 0); + + GLint colorparamsLocation = glGetUniformLocation(program, "colorparams"); + assert(colorparamsLocation >= 0); + + GLfloat texgenscrollData[] = { 0, 0, 0, 0 }; + glUniform4fv(texgenscrollLocation, 1, texgenscrollData); + + GLfloat colorparamsData[] = { 2, 2, 2, 1 }; + glUniform4fv(colorparamsLocation, 1, colorparamsData); + + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)12); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*) 0); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)24); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)36); + + // END + + SDL_GL_SwapBuffers(); + + verify(); + +#if !EMSCRIPTEN + SDL_Delay(1500); +#endif + + SDL_Quit(); + + return 0; +} diff --git a/tests/cubegeom_color.c b/tests/cubegeom_color.c new file mode 100644 index 00000000..7d384324 --- /dev/null +++ b/tests/cubegeom_color.c @@ -0,0 +1,295 @@ +/* +THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION +AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN. + +THE ORIGINAL AUTHOR IS KYLE FOLEY. + +THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY +OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF +MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, +ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE +RESULTING FROM THE USE, MODIFICATION, OR +REDISTRIBUTION OF THIS SOFTWARE. +*/ + +#if !EMSCRIPTEN +#define USE_GLEW 1 +#endif + +#if USE_GLEW +#include "GL/glew.h" +#endif + +#include "SDL/SDL.h" +#if !USE_GLEW +#include "SDL/SDL_opengl.h" +#endif + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +void verify() { + int width = 640, height = 480; + unsigned char *data = (unsigned char*)malloc(width*height*4); + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); + int sum = 0; + for (int x = 0; x < width*height*4; x++) { + if (x % 4 != 3) sum += x * data[x]; + } +#if EMSCRIPTEN + int result = sum; + REPORT_RESULT(); +#endif +} + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { + printf("Unable to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); + screen = SDL_SetVideoMode( 640, 480, 24, SDL_OPENGL ); + if ( !screen ) { + printf("Unable to set video mode: %s\n", SDL_GetError()); + return 1; + } + + glClearColor( 0, 0, 0, 0 ); + glClear( GL_COLOR_BUFFER_BIT ); + + // Create a texture + + GLuint texture; + glGenTextures( 1, &texture ); + glBindTexture( GL_TEXTURE_2D, texture ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + GLubyte textureData[16*16*4]; + for (int x = 0; x < 16; x++) { + for (int y = 0; y < 16; y++) { + *((int*)&textureData[(x*16 + y) * 4]) = x*16 + ((y*16) << 8); + } + } + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, + GL_RGBA, GL_UNSIGNED_BYTE, textureData ); + + // Create a second texture + + GLuint texture2; + glGenTextures( 1, &texture2 ); + glBindTexture( GL_TEXTURE_2D, texture2 ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + GLubyte texture2Data[] = { 0xff, 0, 0, 0xff, + 0, 0xff, 0, 0xaa, + 0, 0, 0xff, 0x55, + 0x80, 0x90, 0x70, 0 }; + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, + GL_RGBA, GL_UNSIGNED_BYTE, texture2Data ); + + // BEGIN + +#if USE_GLEW + glewInit(); +#endif + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + // original: glFrustum(-0.6435469817188064, 0.6435469817188064 ,-0.48266022190470925, 0.48266022190470925 ,0.5400000214576721, 2048); + glFrustum(-0.6435469817188064, 0.1435469817188064 ,-0.48266022190470925, 0.88266022190470925 ,0.5400000214576721, 2048); + glRotatef(-30, 1, 1, 1); + //GLfloat pm[] = { 1.372136116027832, 0, 0, 0, 0, 0.7910231351852417, 0, 0, -0.6352481842041016, 0.29297152161598206, -1.0005275011062622, -1, 0, 0, -1.080284833908081, 0 }; + //glLoadMatrixf(pm); + + glMatrixMode(GL_MODELVIEW); + GLfloat matrixData[] = { -1, 0, 0, 0, + 0, 0,-1, 0, + 0, 1, 0, 0, + 0, 0, 0, 1 }; + glLoadMatrixf(matrixData); + //glTranslated(-512,-512,-527); // XXX this should be uncommented, but if it is then nothing is shown + + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + + glClear(GL_DEPTH_BUFFER_BIT); + + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glActiveTexture(GL_TEXTURE0); + + glEnableClientState(GL_VERTEX_ARRAY); + + GLuint arrayBuffer, elementBuffer; + glGenBuffers(1, &arrayBuffer); + glGenBuffers(1, &elementBuffer); + + GLubyte arrayData[] = { +/* +[0, 0, 0, 67] ==> 128 float +[0, 0, 128, 67] ==> 256 float +[0, 0, 0, 68] ==> 512 float +[0, 0, 128, 68] ==> 1024 float + +[vertex x ] [vertex y ] [vertex z ] [nr] [texture u ] [texture v ] [lm u ] [lm v ] [color r,g,b,a ] */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 128, 255, 128, // 0 + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 255, 128, // 1 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 64, 255, 128, // 2 + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 255, 255, // 3 + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 196, 128, 255, 128, // 4 + 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 255, 128, // 5 + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 255, 128, // 6 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 64, 255, 0, // 7 + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 64, 128, 255, 128, // 8 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 0, 255, 128, // 9 + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 255, 128, // 10 + 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 255, 0, // 11 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 100, 128, 255, 128, // 12 + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 0, 255, 128, // 13 + 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 255, 128, // 14 + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 255, 0, // 15 + + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128 + }; + assert(sizeof(arrayData) == 1408); + glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(arrayData), arrayData, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + GLushort elementData[] = { 1, 2, 0, 2, 3, 0, 5, 6, 4, 6, 7, 4, 9, 10, 8, 10, 11, 8, 13, 14, 12, 14, 15, 12 }; + assert(sizeof(elementData) == 48); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elementData), elementData, GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer); + + // sauer vertex data is apparently 0-12: V3F, 12: N1B, 16-24: T2F, 24-28: T2S, 28-32: C4B + glVertexPointer(3, GL_FLOAT, 32, (void*)0); // all these apply to the ARRAY_BUFFER that is bound + glTexCoordPointer(2, GL_FLOAT, 32, (void*)16); + glClientActiveTexture(GL_TEXTURE1); // XXX seems to be ignored in native build + glTexCoordPointer(2, GL_SHORT, 32, (void*)24); + glClientActiveTexture(GL_TEXTURE0); // likely not needed, it is a cleanup + glNormalPointer(GL_BYTE, 32, (void*)12); + glColorPointer(4, GL_UNSIGNED_BYTE, 32, (void*)28); + + glBindTexture(GL_TEXTURE_2D, texture); // diffuse? + glActiveTexture(GL_TEXTURE0); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, texture2); // lightmap? + glActiveTexture(GL_TEXTURE0); + + GLint ok; + + const char *vertexShader = "uniform vec4 texgenscroll;\n" + "void main(void)\n" + "{\n" + " gl_Position = ftransform();\n" + " gl_TexCoord[0].xy = gl_MultiTexCoord0.xy/100.0 + texgenscroll.xy;\n" // added /100 here + " gl_TexCoord[1] = gl_Color;\n" + "}\n"; + const char *fragmentShader = "uniform vec4 colorparams;\n" + "uniform sampler2D diffusemap, lightmap;\n" + "void main(void)\n" + "{\n" + " vec4 diffuse = texture2D(diffusemap, gl_TexCoord[0].xy);\n" + " vec4 lm = texture2D(lightmap, gl_TexCoord[1].xy);\n" + " diffuse *= colorparams;\n" + " gl_FragColor = (diffuse * lm * 0.2) + gl_TexCoord[1];\n" + "}\n"; + + GLuint vs = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vs, 1, &vertexShader, NULL); + glCompileShader(vs); + glGetShaderiv(vs, GL_COMPILE_STATUS, &ok); + assert(ok); + + GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fs, 1, &fragmentShader, NULL); + glCompileShader(fs); + glGetShaderiv(fs, GL_COMPILE_STATUS, &ok); + assert(ok); + + GLuint program = glCreateProgram(); + + glAttachShader(program, vs); + glAttachShader(program, fs); + glLinkProgram(program); + glGetProgramiv(program, GL_LINK_STATUS, &ok); + assert(ok); + + glUseProgram(program); + + GLint lightmapLocation = glGetUniformLocation(program, "lightmap"); + assert(lightmapLocation >= 0); + glUniform1i(lightmapLocation, 1); // sampler2D? Is it the texture unit? + + GLint diffusemapLocation = glGetUniformLocation(program, "diffusemap"); + assert(diffusemapLocation >= 0); + glUniform1i(diffusemapLocation, 0); + + GLint texgenscrollLocation = glGetUniformLocation(program, "texgenscroll"); + assert(texgenscrollLocation >= 0); + + GLint colorparamsLocation = glGetUniformLocation(program, "colorparams"); + assert(colorparamsLocation >= 0); + + GLfloat texgenscrollData[] = { 0, 0, 0, 0 }; + glUniform4fv(texgenscrollLocation, 1, texgenscrollData); + + GLfloat colorparamsData[] = { 2, 2, 2, 1 }; + glUniform4fv(colorparamsLocation, 1, colorparamsData); + + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)12); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*) 0); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)24); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)36); + + // END + + SDL_GL_SwapBuffers(); + + verify(); + +#if !EMSCRIPTEN + SDL_Delay(1500); +#endif + + SDL_Quit(); + + return 0; +} diff --git a/tests/cubegeom_color2.c b/tests/cubegeom_color2.c new file mode 100644 index 00000000..5294329d --- /dev/null +++ b/tests/cubegeom_color2.c @@ -0,0 +1,299 @@ +/* +THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION +AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN. + +THE ORIGINAL AUTHOR IS KYLE FOLEY. + +THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY +OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF +MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, +ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE +RESULTING FROM THE USE, MODIFICATION, OR +REDISTRIBUTION OF THIS SOFTWARE. +*/ + +#if !EMSCRIPTEN +#define USE_GLEW 1 +#endif + +#if USE_GLEW +#include "GL/glew.h" +#endif + +#include "SDL/SDL.h" +#if !USE_GLEW +#include "SDL/SDL_opengl.h" +#endif + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +void verify() { + int width = 640, height = 480; + unsigned char *data = (unsigned char*)malloc(width*height*4); + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); + int sum = 0; + for (int x = 0; x < width*height*4; x++) { + if (x % 4 != 3) sum += x * data[x]; + } +#if EMSCRIPTEN + int result = sum; + REPORT_RESULT(); +#endif +} + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { + printf("Unable to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); + screen = SDL_SetVideoMode( 640, 480, 24, SDL_OPENGL ); + if ( !screen ) { + printf("Unable to set video mode: %s\n", SDL_GetError()); + return 1; + } + + glClearColor( 0, 0, 0, 0 ); + glClear( GL_COLOR_BUFFER_BIT ); + + // Create a texture + + GLuint texture; + glGenTextures( 1, &texture ); + glBindTexture( GL_TEXTURE_2D, texture ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + GLubyte textureData[16*16*4]; + for (int x = 0; x < 16; x++) { + for (int y = 0; y < 16; y++) { + *((int*)&textureData[(x*16 + y) * 4]) = x*16 + ((y*16) << 8); + } + } + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, + GL_RGBA, GL_UNSIGNED_BYTE, textureData ); + + // Create a second texture + + GLuint texture2; + glGenTextures( 1, &texture2 ); + glBindTexture( GL_TEXTURE_2D, texture2 ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + GLubyte texture2Data[] = { 0xff, 0, 0, 0xff, + 0, 0xff, 0, 0xaa, + 0, 0, 0xff, 0x55, + 0x80, 0x90, 0x70, 0 }; + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, + GL_RGBA, GL_UNSIGNED_BYTE, texture2Data ); + + // BEGIN + +#if USE_GLEW + glewInit(); +#endif + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + // original: glFrustum(-0.6435469817188064, 0.6435469817188064 ,-0.48266022190470925, 0.48266022190470925 ,0.5400000214576721, 2048); + glFrustum(-0.6435469817188064, 0.1435469817188064 ,-0.48266022190470925, 0.88266022190470925 ,0.5400000214576721, 2048); + glRotatef(-30, 1, 1, 1); + //GLfloat pm[] = { 1.372136116027832, 0, 0, 0, 0, 0.7910231351852417, 0, 0, -0.6352481842041016, 0.29297152161598206, -1.0005275011062622, -1, 0, 0, -1.080284833908081, 0 }; + //glLoadMatrixf(pm); + + glMatrixMode(GL_MODELVIEW); + GLfloat matrixData[] = { -1, 0, 0, 0, + 0, 0,-1, 0, + 0, 1, 0, 0, + 0, 0, 0, 1 }; + glLoadMatrixf(matrixData); + //glTranslated(-512,-512,-527); // XXX this should be uncommented, but if it is then nothing is shown + + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + + glClear(GL_DEPTH_BUFFER_BIT); + + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glActiveTexture(GL_TEXTURE0); + + glEnableClientState(GL_VERTEX_ARRAY); + + GLuint arrayBuffer, elementBuffer; + glGenBuffers(1, &arrayBuffer); + glGenBuffers(1, &elementBuffer); + + GLubyte arrayData[] = { +/* +[0, 0, 0, 67] ==> 128 float +[0, 0, 128, 67] ==> 256 float +[0, 0, 0, 68] ==> 512 float +[0, 0, 128, 68] ==> 1024 float + +[vertex x ] [vertex y ] [vertex z ] [nr] [texture u ] [texture v ] [lm u ] [lm v ] [color r,g,b,a ] */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 128, 255, 128, // 0 + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 255, 128, // 1 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 64, 255, 128, // 2 + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 255, 255, // 3 + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 196, 128, 255, 128, // 4 + 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 255, 128, // 5 + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 255, 128, // 6 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 64, 255, 0, // 7 + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 64, 128, 255, 128, // 8 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 0, 255, 128, // 9 + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 255, 128, // 10 + 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 255, 0, // 11 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 100, 128, 255, 128, // 12 + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 0, 255, 128, // 13 + 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 255, 128, // 14 + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 255, 0, // 15 + + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128 + }; + assert(sizeof(arrayData) == 1408); + glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(arrayData), arrayData, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + GLushort elementData[] = { 1, 2, 0, 2, 3, 0, 5, 6, 4, 6, 7, 4, 9, 10, 8, 10, 11, 8, 13, 14, 12, 14, 15, 12 }; + assert(sizeof(elementData) == 48); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elementData), elementData, GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer); + + // sauer vertex data is apparently 0-12: V3F, 12: N1B, 16-24: T2F, 24-28: T2S, 28-32: C4B + glVertexPointer(3, GL_FLOAT, 32, (void*)0); // all these apply to the ARRAY_BUFFER that is bound + glTexCoordPointer(2, GL_FLOAT, 32, (void*)16); + glClientActiveTexture(GL_TEXTURE1); // XXX seems to be ignored in native build + glTexCoordPointer(2, GL_SHORT, 32, (void*)24); + glClientActiveTexture(GL_TEXTURE0); // likely not needed, it is a cleanup + glNormalPointer(GL_BYTE, 32, (void*)12); + glColorPointer(4, GL_UNSIGNED_BYTE, 32, (void*)28); + + glBindTexture(GL_TEXTURE_2D, texture); // diffuse? + glActiveTexture(GL_TEXTURE0); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, texture2); // lightmap? + glActiveTexture(GL_TEXTURE0); + + GLint ok; + + const char *vertexShader = "uniform vec4 texgenscroll;\n" + "void main(void)\n" + "{\n" + " gl_Position = ftransform();\n" + " gl_TexCoord[0].xy = gl_MultiTexCoord0.xy/100.0 + texgenscroll.xy;\n" // added /100 here + " gl_TexCoord[1] = gl_Color;\n" + "}\n"; + const char *fragmentShader = "uniform vec4 colorparams;\n" + "uniform sampler2D diffusemap, lightmap;\n" + "void main(void)\n" + "{\n" + " vec4 diffuse = texture2D(diffusemap, gl_TexCoord[0].xy);\n" + " vec4 lm = texture2D(lightmap, gl_TexCoord[1].xy);\n" + " diffuse *= colorparams;\n" + " gl_FragColor = (diffuse * lm * 0.2) + gl_TexCoord[1];\n" + "}\n"; + + GLuint vs = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vs, 1, &vertexShader, NULL); + glCompileShader(vs); + glGetShaderiv(vs, GL_COMPILE_STATUS, &ok); + assert(ok); + + GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fs, 1, &fragmentShader, NULL); + glCompileShader(fs); + glGetShaderiv(fs, GL_COMPILE_STATUS, &ok); + assert(ok); + + GLuint program = glCreateProgram(); + + glAttachShader(program, vs); + glAttachShader(program, fs); + glLinkProgram(program); + glGetProgramiv(program, GL_LINK_STATUS, &ok); + assert(ok); + + glUseProgram(program); + + GLint lightmapLocation = glGetUniformLocation(program, "lightmap"); + assert(lightmapLocation >= 0); + glUniform1i(lightmapLocation, 1); // sampler2D? Is it the texture unit? + + GLint diffusemapLocation = glGetUniformLocation(program, "diffusemap"); + assert(diffusemapLocation >= 0); + glUniform1i(diffusemapLocation, 0); + + GLint texgenscrollLocation = glGetUniformLocation(program, "texgenscroll"); + assert(texgenscrollLocation >= 0); + + GLint colorparamsLocation = glGetUniformLocation(program, "colorparams"); + assert(colorparamsLocation >= 0); + + GLfloat texgenscrollData[] = { 0, 0, 0, 0 }; + glUniform4fv(texgenscrollLocation, 1, texgenscrollData); + + GLfloat colorparamsData[] = { 2, 2, 2, 1 }; + glUniform4fv(colorparamsLocation, 1, colorparamsData); + + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)12); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*) 0); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)24); + + // Disable the color attrib, and use a fixed color + glDisableClientState(GL_COLOR_ARRAY); + glColor3f(1.0, 0.25, 0.33); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)36); + + // END + + SDL_GL_SwapBuffers(); + + verify(); + +#if !EMSCRIPTEN + SDL_Delay(1500); +#endif + + SDL_Quit(); + + return 0; +} diff --git a/tests/cubegeom_fog.c b/tests/cubegeom_fog.c new file mode 100644 index 00000000..9c04a55d --- /dev/null +++ b/tests/cubegeom_fog.c @@ -0,0 +1,307 @@ +/* +THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION +AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN. + +THE ORIGINAL AUTHOR IS KYLE FOLEY. + +THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY +OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF +MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, +ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE +RESULTING FROM THE USE, MODIFICATION, OR +REDISTRIBUTION OF THIS SOFTWARE. +*/ + +#if !EMSCRIPTEN +#define USE_GLEW 1 +#endif + +#if USE_GLEW +#include "GL/glew.h" +#endif + +#include "SDL/SDL.h" +#if !USE_GLEW +#include "SDL/SDL_opengl.h" +#endif + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +void verify() { + int width = 640, height = 480; + unsigned char *data = (unsigned char*)malloc(width*height*4); + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); + int sum = 0; + for (int x = 0; x < width*height*4; x++) { + if (x % 4 != 3) sum += x * data[x]; + } +#if EMSCRIPTEN + int result = sum; + REPORT_RESULT(); +#endif +} + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { + printf("Unable to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); + screen = SDL_SetVideoMode( 640, 480, 24, SDL_OPENGL ); + if ( !screen ) { + printf("Unable to set video mode: %s\n", SDL_GetError()); + return 1; + } + + glClearColor( 0, 0, 0, 0 ); + glClear( GL_COLOR_BUFFER_BIT ); + + // Fog + + glEnable(GL_FOG); + glFogf(GL_FOG_START, 100); + glFogf(GL_FOG_END, 2000); + glFogi(GL_FOG_MODE, GL_LINEAR); + GLfloat fogcolor[4] = { 0.9, 0.1, 0.35, 0 }; + glFogfv(GL_FOG_COLOR, fogcolor); + + // Create a texture + + GLuint texture; + glGenTextures( 1, &texture ); + glBindTexture( GL_TEXTURE_2D, texture ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + GLubyte textureData[16*16*4]; + for (int x = 0; x < 16; x++) { + for (int y = 0; y < 16; y++) { + *((int*)&textureData[(x*16 + y) * 4]) = x*16 + ((y*16) << 8); + } + } + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, + GL_RGBA, GL_UNSIGNED_BYTE, textureData ); + + // Create a second texture + + GLuint texture2; + glGenTextures( 1, &texture2 ); + glBindTexture( GL_TEXTURE_2D, texture2 ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + GLubyte texture2Data[] = { 0xff, 0, 0, 0xff, + 0, 0xff, 0, 0xaa, + 0, 0, 0xff, 0x55, + 0x80, 0x90, 0x70, 0 }; + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, + GL_RGBA, GL_UNSIGNED_BYTE, texture2Data ); + + // BEGIN + +#if USE_GLEW + glewInit(); +#endif + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + // original: glFrustum(-0.6435469817188064, 0.6435469817188064 ,-0.48266022190470925, 0.48266022190470925 ,0.5400000214576721, 2048); + glFrustum(-0.6435469817188064, 0.1435469817188064 ,-0.48266022190470925, 0.88266022190470925 ,0.5400000214576721, 2048); + glRotatef(-30, 1, 1, 1); + //GLfloat pm[] = { 1.372136116027832, 0, 0, 0, 0, 0.7910231351852417, 0, 0, -0.6352481842041016, 0.29297152161598206, -1.0005275011062622, -1, 0, 0, -1.080284833908081, 0 }; + //glLoadMatrixf(pm); + + glMatrixMode(GL_MODELVIEW); + GLfloat matrixData[] = { -1, 0, 0, 0, + 0, 0,-1, 0, + 0, 1, 0, 0, + 0, 0, 0, 1 }; + glLoadMatrixf(matrixData); + //glTranslated(-512,-512,-527); // XXX this should be uncommented, but if it is then nothing is shown + + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + + glClear(GL_DEPTH_BUFFER_BIT); + + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glActiveTexture(GL_TEXTURE0); + + glEnableClientState(GL_VERTEX_ARRAY); + + GLuint arrayBuffer, elementBuffer; + glGenBuffers(1, &arrayBuffer); + glGenBuffers(1, &elementBuffer); + + GLubyte arrayData[] = { +/* +[0, 0, 0, 67] ==> 128 float +[0, 0, 128, 67] ==> 256 float +[0, 0, 0, 68] ==> 512 float +[0, 0, 128, 68] ==> 1024 float + +[vertex x ] [vertex y ] [vertex z ] [nr] [texture u ] [texture v ] [lm u ] [lm v ] [color r,g,b,a ] */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 11, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 0 + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 23, 20, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 1 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 35, 30, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 2 + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 47, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 3 + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 51, 50, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 4 + 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 68, 64, 60, 0, 0, 0, 0, 128, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 5 + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 70, 70, 0, 0, 0, 0, 128, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 6 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 89, 80, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 7 + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 94, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 8 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 20, 10, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 9 + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 31, 20, 0, 0, 0, 0, 0, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 10 + 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 68, 42, 30, 0, 0, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 11 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 53, 40, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 12 + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 64, 50, 0, 0, 0, 0, 128, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 13 + 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 68, 75, 60, 0, 0, 0, 0, 128, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 14 + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 86, 70, 0, 0, 0, 0, 0, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 15 + + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128 + }; + assert(sizeof(arrayData) == 1408); + glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(arrayData), arrayData, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + GLushort elementData[] = { 1, 2, 0, 2, 3, 0, 5, 6, 4, 6, 7, 4, 9, 10, 8, 10, 11, 8, 13, 14, 12, 14, 15, 12 }; + assert(sizeof(elementData) == 48); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elementData), elementData, GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer); + + // sauer vertex data is apparently 0-12: V3F, 12: N1B, 16-24: T2F, 24-28: T2S, 28-32: C4B + glVertexPointer(3, GL_FLOAT, 32, (void*)0); // all these apply to the ARRAY_BUFFER that is bound + glTexCoordPointer(2, GL_FLOAT, 32, (void*)16); + glClientActiveTexture(GL_TEXTURE1); // XXX seems to be ignored in native build + glTexCoordPointer(2, GL_SHORT, 32, (void*)24); + glClientActiveTexture(GL_TEXTURE0); // likely not needed, it is a cleanup + glNormalPointer(GL_BYTE, 32, (void*)12); + glColorPointer(4, GL_UNSIGNED_BYTE, 32, (void*)28); + + glBindTexture(GL_TEXTURE_2D, texture); // diffuse? + glActiveTexture(GL_TEXTURE0); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, texture2); // lightmap? + glActiveTexture(GL_TEXTURE0); + + GLint ok; + + const char *vertexShader = "uniform vec4 texgenscroll;\n" + "void main(void)\n" + "{\n" + " gl_Position = ftransform();\n" + " gl_TexCoord[0].xy = gl_MultiTexCoord0.xy/10000.0 + (0.001*texgenscroll.xy) + gl_Normal.xy;\n" // added /100 here + " gl_TexCoord[1].xy = gl_MultiTexCoord1.xy/100.0 * 3.051851e-05;\n" + " gl_FogFragCoord = gl_Position.z;\n" + "}\n"; + const char *fragmentShader = "uniform vec4 colorparams;\n" + "uniform sampler2D diffusemap, lightmap;\n" + "void main(void)\n" + "{\n" + " vec4 diffuse = texture2D(diffusemap, gl_TexCoord[0].xy);\n" + " vec4 lm = texture2D(lightmap, gl_TexCoord[1].xy);\n" + " diffuse *= colorparams;\n" + " vec4 color = diffuse * lm;\n" + " gl_FragColor.rgb = mix((gl_Fog.color).rgb, color.rgb, clamp((gl_Fog.end - gl_FogFragCoord) * gl_Fog.scale, 0.0, 1.0));\n" + //" gl_FragColor.rgb = 0.0001 * color.rgb + ((gl_Fog.color).rgb * (1.0-clamp((gl_FogFragCoord)* 1.0/1000.0, 0.0, 1.0)));\n" + "}\n"; + + GLuint vs = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vs, 1, &vertexShader, NULL); + glCompileShader(vs); + glGetShaderiv(vs, GL_COMPILE_STATUS, &ok); + assert(ok); + + GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fs, 1, &fragmentShader, NULL); + glCompileShader(fs); + glGetShaderiv(fs, GL_COMPILE_STATUS, &ok); + assert(ok); + + GLuint program = glCreateProgram(); + + glAttachShader(program, vs); + glAttachShader(program, fs); + glLinkProgram(program); + glGetProgramiv(program, GL_LINK_STATUS, &ok); + assert(ok); + + glUseProgram(program); + + GLint lightmapLocation = glGetUniformLocation(program, "lightmap"); + assert(lightmapLocation >= 0); + glUniform1i(lightmapLocation, 1); // sampler2D? Is it the texture unit? + + GLint diffusemapLocation = glGetUniformLocation(program, "diffusemap"); + assert(diffusemapLocation >= 0); + glUniform1i(diffusemapLocation, 0); + + GLint texgenscrollLocation = glGetUniformLocation(program, "texgenscroll"); + assert(texgenscrollLocation >= 0); + + GLint colorparamsLocation = glGetUniformLocation(program, "colorparams"); + assert(colorparamsLocation >= 0); + + GLfloat texgenscrollData[] = { 0, 0, 0, 0 }; + glUniform4fv(texgenscrollLocation, 1, texgenscrollData); + + GLfloat colorparamsData[] = { 2, 2, 2, 1 }; + glUniform4fv(colorparamsLocation, 1, colorparamsData); + + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)12); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*) 0); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)24); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)36); + + // END + + SDL_GL_SwapBuffers(); + + verify(); + +#if !EMSCRIPTEN + SDL_Delay(1500); +#endif + + SDL_Quit(); + + return 0; +} diff --git a/tests/cubegeom_mt.c b/tests/cubegeom_mt.c new file mode 100644 index 00000000..464de7cc --- /dev/null +++ b/tests/cubegeom_mt.c @@ -0,0 +1,300 @@ +/* +THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION +AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN. + +THE ORIGINAL AUTHOR IS KYLE FOLEY. + +THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY +OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF +MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, +ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE +RESULTING FROM THE USE, MODIFICATION, OR +REDISTRIBUTION OF THIS SOFTWARE. +*/ + +#if !EMSCRIPTEN +#define USE_GLEW 1 +#endif + +#if USE_GLEW +#include "GL/glew.h" +#endif + +#include "SDL/SDL.h" +#if !USE_GLEW +#include "SDL/SDL_opengl.h" +#endif + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +void verify() { + int width = 640, height = 480; + unsigned char *data = (unsigned char*)malloc(width*height*4); + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); + int sum = 0; + for (int x = 0; x < width*height*4; x++) { + if (x % 4 != 3) sum += x * data[x]; + } +#if EMSCRIPTEN + int result = sum; + REPORT_RESULT(); +#endif +} + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { + printf("Unable to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); + screen = SDL_SetVideoMode( 640, 480, 24, SDL_OPENGL ); + if ( !screen ) { + printf("Unable to set video mode: %s\n", SDL_GetError()); + return 1; + } + + glClearColor( 0, 0, 0, 0 ); + glClear( GL_COLOR_BUFFER_BIT ); + + // Create a texture + + GLuint texture; + glGenTextures( 1, &texture ); + glBindTexture( GL_TEXTURE_2D, texture ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + GLubyte textureData[16*16*4]; + for (int x = 0; x < 16; x++) { + for (int y = 0; y < 16; y++) { + *((int*)&textureData[(x*16 + y) * 4]) = x*16 + ((y*16) << 8) + ((x*y) << 16); + } + } + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, + GL_RGBA, GL_UNSIGNED_BYTE, textureData ); + + // Create a second texture + + GLuint texture2; + glGenTextures( 1, &texture2 ); + glBindTexture( GL_TEXTURE_2D, texture2 ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + GLubyte texture2Data[] = { 0x00, 0x00, 0xff, 0x77, + 0x00, 0x44, 0xaa, 0x77, + 0x44, 0x00, 0xcc, 0x77, + 0x00, 0x44, 0x77, 0x77 }; + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, + GL_RGBA, GL_UNSIGNED_BYTE, texture2Data ); + + // BEGIN + +#if USE_GLEW + glewInit(); +#endif + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + // original: glFrustum(-0.6435469817188064, 0.6435469817188064 ,-0.48266022190470925, 0.48266022190470925 ,0.5400000214576721, 2048); + glFrustum(-0.6435469817188064, 0.1435469817188064 ,-0.48266022190470925, 0.88266022190470925 ,0.5400000214576721, 2048); + glRotatef(-30, 1, 1, 1); + //GLfloat pm[] = { 1.372136116027832, 0, 0, 0, 0, 0.7910231351852417, 0, 0, -0.6352481842041016, 0.29297152161598206, -1.0005275011062622, -1, 0, 0, -1.080284833908081, 0 }; + //glLoadMatrixf(pm); + + glMatrixMode(GL_MODELVIEW); + GLfloat matrixData[] = { -1, 0, 0, 0, + 0, 0,-1, 0, + 0, 1, 0, 0, + 0, 0, 0, 1 }; + glLoadMatrixf(matrixData); + //glTranslated(-512,-512,-527); // XXX this should be uncommented, but if it is then nothing is shown + + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + + glClear(GL_DEPTH_BUFFER_BIT); + + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glActiveTexture(GL_TEXTURE0); + + glEnableClientState(GL_VERTEX_ARRAY); + + GLuint arrayBuffer, elementBuffer; + glGenBuffers(1, &arrayBuffer); + glGenBuffers(1, &elementBuffer); + + GLubyte arrayData[] = { +/* +[0, 0, 0, 67] ==> 128 float +[0, 0, 128, 67] ==> 256 float +[0, 0, 0, 68] ==> 512 float +[0, 0, 128, 68] ==> 1024 float + +[vertex x ] [vertex y ] [vertex z ] [nr] [texture u ] [texture v ] [lm u ] [lm v ] [color r,g,b,a ] */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 128, 128, 128, 128, // 0 + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 1, 0, 1, 128, 128, 128, 128, // 1 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 1, 128, 128, 128, 128, // 2 + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 3 + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 1, 0, 0, 128, 128, 128, 128, // 4 + 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 0, 0, 1, 0, 1, 128, 128, 128, 128, // 5 + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 67, 0, 0, 0, 1, 128, 128, 128, 128, // 6 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 7 + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 1, 0, 0, 128, 128, 128, 128, // 8 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 1, 0, 1, 128, 128, 128, 128, // 9 + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 128, 67, 0, 0, 0, 1, 128, 128, 128, 128, // 10 + 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 11 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 1, 0, 0, 128, 128, 128, 128, // 12 + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 67, 0, 1, 0, 1, 128, 128, 128, 128, // 13 + 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 128, 67, 0, 0, 0, 1, 128, 128, 128, 128, // 14 + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 15 + + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128 + }; + assert(sizeof(arrayData) == 1408); + glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(arrayData), arrayData, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + GLushort elementData[] = { 1, 2, 0, 2, 3, 0, 5, 6, 4, 6, 7, 4, 9, 10, 8, 10, 11, 8, 13, 14, 12, 14, 15, 12 }; + assert(sizeof(elementData) == 48); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elementData), elementData, GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer); + + // sauer vertex data is apparently 0-12: V3F, 12: N1B, 16-24: T2F, 24-28: T2S, 28-32: C4B + glVertexPointer(3, GL_FLOAT, 32, (void*)0); // all these apply to the ARRAY_BUFFER that is bound + + glClientActiveTexture(GL_TEXTURE1); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, 32, (void*)16); + + glClientActiveTexture(GL_TEXTURE0); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_SHORT, 32, (void*)24); + + glNormalPointer(GL_BYTE, 32, (void*)12); + glColorPointer(4, GL_UNSIGNED_BYTE, 32, (void*)28); + + glBindTexture(GL_TEXTURE_2D, texture); // diffuse? + glActiveTexture(GL_TEXTURE0); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, texture2); // lightmap? + glActiveTexture(GL_TEXTURE0); + + GLint ok; + + const char *vertexShader = "uniform vec4 texgenscroll;\n" + "void main(void)\n" + "{\n" + " gl_Position = ftransform();\n" + " gl_TexCoord[0].xy = gl_MultiTexCoord0.xy/100.0 + texgenscroll.xy;\n" // added /100 here + " gl_TexCoord[1].xy = gl_MultiTexCoord1.xy/100.0 * 3.051851e-05;\n" + "}\n"; + const char *fragmentShader = "uniform vec4 colorparams;\n" + "uniform sampler2D diffusemap, lightmap;\n" + "void main(void)\n" + "{\n" + " vec4 diffuse = texture2D(diffusemap, gl_TexCoord[0].xy);\n" + " vec4 lm = texture2D(lightmap, gl_TexCoord[1].xy);\n" + " diffuse *= colorparams;\n" + " gl_FragColor = diffuse * lm;\n" + "}\n"; + + GLuint vs = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vs, 1, &vertexShader, NULL); + glCompileShader(vs); + glGetShaderiv(vs, GL_COMPILE_STATUS, &ok); + assert(ok); + + GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fs, 1, &fragmentShader, NULL); + glCompileShader(fs); + glGetShaderiv(fs, GL_COMPILE_STATUS, &ok); + assert(ok); + + GLuint program = glCreateProgram(); + + glAttachShader(program, vs); + glAttachShader(program, fs); + glLinkProgram(program); + glGetProgramiv(program, GL_LINK_STATUS, &ok); + assert(ok); + + glUseProgram(program); + + GLint lightmapLocation = glGetUniformLocation(program, "lightmap"); + assert(lightmapLocation >= 0); + glUniform1i(lightmapLocation, 1); // sampler2D? Is it the texture unit? + + GLint diffusemapLocation = glGetUniformLocation(program, "diffusemap"); + assert(diffusemapLocation >= 0); + glUniform1i(diffusemapLocation, 0); + + GLint texgenscrollLocation = glGetUniformLocation(program, "texgenscroll"); + assert(texgenscrollLocation >= 0); + + GLint colorparamsLocation = glGetUniformLocation(program, "colorparams"); + assert(colorparamsLocation >= 0); + + GLfloat texgenscrollData[] = { 0, 0, 0, 0 }; + glUniform4fv(texgenscrollLocation, 1, texgenscrollData); + + GLfloat colorparamsData[] = { 2, 2, 2, 1 }; + glUniform4fv(colorparamsLocation, 1, colorparamsData); + + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)12); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*) 0); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)24); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)36); + + // END + + SDL_GL_SwapBuffers(); + + verify(); + +#if !EMSCRIPTEN + SDL_Delay(1500); +#endif + + SDL_Quit(); + + return 0; +} diff --git a/tests/cubegeom_normal.c b/tests/cubegeom_normal.c new file mode 100644 index 00000000..d128fef2 --- /dev/null +++ b/tests/cubegeom_normal.c @@ -0,0 +1,295 @@ +/* +THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION +AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN. + +THE ORIGINAL AUTHOR IS KYLE FOLEY. + +THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY +OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF +MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, +ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE +RESULTING FROM THE USE, MODIFICATION, OR +REDISTRIBUTION OF THIS SOFTWARE. +*/ + +#if !EMSCRIPTEN +#define USE_GLEW 1 +#endif + +#if USE_GLEW +#include "GL/glew.h" +#endif + +#include "SDL/SDL.h" +#if !USE_GLEW +#include "SDL/SDL_opengl.h" +#endif + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +void verify() { + int width = 640, height = 480; + unsigned char *data = (unsigned char*)malloc(width*height*4); + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); + int sum = 0; + for (int x = 0; x < width*height*4; x++) { + if (x % 4 != 3) sum += x * data[x]; + } +#if EMSCRIPTEN + int result = sum; + REPORT_RESULT(); +#endif +} + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { + printf("Unable to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); + screen = SDL_SetVideoMode( 640, 480, 24, SDL_OPENGL ); + if ( !screen ) { + printf("Unable to set video mode: %s\n", SDL_GetError()); + return 1; + } + + glClearColor( 0, 0, 0, 0 ); + glClear( GL_COLOR_BUFFER_BIT ); + + // Create a texture + + GLuint texture; + glGenTextures( 1, &texture ); + glBindTexture( GL_TEXTURE_2D, texture ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + GLubyte textureData[16*16*4]; + for (int x = 0; x < 16; x++) { + for (int y = 0; y < 16; y++) { + *((int*)&textureData[(x*16 + y) * 4]) = x*16 + ((y*16) << 8); + } + } + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, + GL_RGBA, GL_UNSIGNED_BYTE, textureData ); + + // Create a second texture + + GLuint texture2; + glGenTextures( 1, &texture2 ); + glBindTexture( GL_TEXTURE_2D, texture2 ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + GLubyte texture2Data[] = { 0xff, 0, 0, 0xff, + 0, 0xff, 0, 0xaa, + 0, 0, 0xff, 0x55, + 0x80, 0x90, 0x70, 0 }; + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, + GL_RGBA, GL_UNSIGNED_BYTE, texture2Data ); + + // BEGIN + +#if USE_GLEW + glewInit(); +#endif + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + // original: glFrustum(-0.6435469817188064, 0.6435469817188064 ,-0.48266022190470925, 0.48266022190470925 ,0.5400000214576721, 2048); + glFrustum(-0.6435469817188064, 0.1435469817188064 ,-0.48266022190470925, 0.88266022190470925 ,0.5400000214576721, 2048); + glRotatef(-30, 1, 1, 1); + //GLfloat pm[] = { 1.372136116027832, 0, 0, 0, 0, 0.7910231351852417, 0, 0, -0.6352481842041016, 0.29297152161598206, -1.0005275011062622, -1, 0, 0, -1.080284833908081, 0 }; + //glLoadMatrixf(pm); + + glMatrixMode(GL_MODELVIEW); + GLfloat matrixData[] = { -1, 0, 0, 0, + 0, 0,-1, 0, + 0, 1, 0, 0, + 0, 0, 0, 1 }; + glLoadMatrixf(matrixData); + //glTranslated(-512,-512,-527); // XXX this should be uncommented, but if it is then nothing is shown + + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + + glClear(GL_DEPTH_BUFFER_BIT); + + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glActiveTexture(GL_TEXTURE0); + + glEnableClientState(GL_VERTEX_ARRAY); + + GLuint arrayBuffer, elementBuffer; + glGenBuffers(1, &arrayBuffer); + glGenBuffers(1, &elementBuffer); + + GLubyte arrayData[] = { +/* +[0, 0, 0, 67] ==> 128 float +[0, 0, 128, 67] ==> 256 float +[0, 0, 0, 68] ==> 512 float +[0, 0, 128, 68] ==> 1024 float + +[vertex x ] [vertex y ] [vertex z ] [nr] [texture u ] [texture v ] [lm u ] [lm v ] [color r,g,b,a ] */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 11, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 0 + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 23, 20, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 1 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 35, 30, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 2 + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 47, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 3 + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 51, 50, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 4 + 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 68, 64, 60, 0, 0, 0, 0, 128, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 5 + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 70, 70, 0, 0, 0, 0, 128, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 6 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 89, 80, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 7 + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 94, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 8 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 20, 10, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 9 + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 31, 20, 0, 0, 0, 0, 0, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 10 + 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 68, 42, 30, 0, 0, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 11 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 53, 40, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 12 + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 64, 50, 0, 0, 0, 0, 128, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 13 + 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 68, 75, 60, 0, 0, 0, 0, 128, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 14 + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 86, 70, 0, 0, 0, 0, 0, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 15 + + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128 + }; + assert(sizeof(arrayData) == 1408); + glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(arrayData), arrayData, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + GLushort elementData[] = { 1, 2, 0, 2, 3, 0, 5, 6, 4, 6, 7, 4, 9, 10, 8, 10, 11, 8, 13, 14, 12, 14, 15, 12 }; + assert(sizeof(elementData) == 48); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elementData), elementData, GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer); + + // sauer vertex data is apparently 0-12: V3F, 12: N1B, 16-24: T2F, 24-28: T2S, 28-32: C4B + glVertexPointer(3, GL_FLOAT, 32, (void*)0); // all these apply to the ARRAY_BUFFER that is bound + glTexCoordPointer(2, GL_FLOAT, 32, (void*)16); + glClientActiveTexture(GL_TEXTURE1); // XXX seems to be ignored in native build + glTexCoordPointer(2, GL_SHORT, 32, (void*)24); + glClientActiveTexture(GL_TEXTURE0); // likely not needed, it is a cleanup + glNormalPointer(GL_BYTE, 32, (void*)12); + glColorPointer(4, GL_UNSIGNED_BYTE, 32, (void*)28); + + glBindTexture(GL_TEXTURE_2D, texture); // diffuse? + glActiveTexture(GL_TEXTURE0); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, texture2); // lightmap? + glActiveTexture(GL_TEXTURE0); + + GLint ok; + + const char *vertexShader = "uniform vec4 texgenscroll;\n" + "void main(void)\n" + "{\n" + " gl_Position = ftransform();\n" + " gl_TexCoord[0].xy = gl_MultiTexCoord0.xy/10000.0 + (0.001*texgenscroll.xy) + gl_Normal.xy;\n" // added /100 here + " gl_TexCoord[1].xy = gl_MultiTexCoord1.xy/100.0 * 3.051851e-05;\n" + "}\n"; + const char *fragmentShader = "uniform vec4 colorparams;\n" + "uniform sampler2D diffusemap, lightmap;\n" + "void main(void)\n" + "{\n" + " vec4 diffuse = texture2D(diffusemap, gl_TexCoord[0].xy);\n" + " vec4 lm = texture2D(lightmap, gl_TexCoord[1].xy);\n" + " diffuse *= colorparams;\n" + " gl_FragColor = diffuse * lm;\n" + "}\n"; + + GLuint vs = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vs, 1, &vertexShader, NULL); + glCompileShader(vs); + glGetShaderiv(vs, GL_COMPILE_STATUS, &ok); + assert(ok); + + GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fs, 1, &fragmentShader, NULL); + glCompileShader(fs); + glGetShaderiv(fs, GL_COMPILE_STATUS, &ok); + assert(ok); + + GLuint program = glCreateProgram(); + + glAttachShader(program, vs); + glAttachShader(program, fs); + glLinkProgram(program); + glGetProgramiv(program, GL_LINK_STATUS, &ok); + assert(ok); + + glUseProgram(program); + + GLint lightmapLocation = glGetUniformLocation(program, "lightmap"); + assert(lightmapLocation >= 0); + glUniform1i(lightmapLocation, 1); // sampler2D? Is it the texture unit? + + GLint diffusemapLocation = glGetUniformLocation(program, "diffusemap"); + assert(diffusemapLocation >= 0); + glUniform1i(diffusemapLocation, 0); + + GLint texgenscrollLocation = glGetUniformLocation(program, "texgenscroll"); + assert(texgenscrollLocation >= 0); + + GLint colorparamsLocation = glGetUniformLocation(program, "colorparams"); + assert(colorparamsLocation >= 0); + + GLfloat texgenscrollData[] = { 0, 0, 0, 0 }; + glUniform4fv(texgenscrollLocation, 1, texgenscrollData); + + GLfloat colorparamsData[] = { 2, 2, 2, 1 }; + glUniform4fv(colorparamsLocation, 1, colorparamsData); + + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)12); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*) 0); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)24); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)36); + + // END + + SDL_GL_SwapBuffers(); + + verify(); + +#if !EMSCRIPTEN + SDL_Delay(1500); +#endif + + SDL_Quit(); + + return 0; +} diff --git a/tests/cubegeom_normal_dap.c b/tests/cubegeom_normal_dap.c new file mode 100644 index 00000000..f811c586 --- /dev/null +++ b/tests/cubegeom_normal_dap.c @@ -0,0 +1,291 @@ +/* +THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION +AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN. + +THE ORIGINAL AUTHOR IS KYLE FOLEY. + +THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY +OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF +MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, +ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE +RESULTING FROM THE USE, MODIFICATION, OR +REDISTRIBUTION OF THIS SOFTWARE. +*/ + +#if !EMSCRIPTEN +#define USE_GLEW 1 +#endif + +#if USE_GLEW +#include "GL/glew.h" +#endif + +#include "SDL/SDL.h" +#if !USE_GLEW +#include "SDL/SDL_opengl.h" +#endif + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +void verify() { + int width = 640, height = 480; + unsigned char *data = (unsigned char*)malloc(width*height*4); + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); + int sum = 0; + for (int x = 0; x < width*height*4; x++) { + if (x % 4 != 3) sum += x * data[x]; + } +#if EMSCRIPTEN + int result = sum; + REPORT_RESULT(); +#endif +} + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { + printf("Unable to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); + screen = SDL_SetVideoMode( 640, 480, 24, SDL_OPENGL ); + if ( !screen ) { + printf("Unable to set video mode: %s\n", SDL_GetError()); + return 1; + } + + glClearColor( 0, 0, 0, 0 ); + glClear( GL_COLOR_BUFFER_BIT ); + + // Create a texture + + GLuint texture; + glGenTextures( 1, &texture ); + glBindTexture( GL_TEXTURE_2D, texture ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + GLubyte textureData[16*16*4]; + for (int x = 0; x < 16; x++) { + for (int y = 0; y < 16; y++) { + *((int*)&textureData[(x*16 + y) * 4]) = x*16 + ((y*16) << 8); + } + } + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, + GL_RGBA, GL_UNSIGNED_BYTE, textureData ); + + // Create a second texture + + GLuint texture2; + glGenTextures( 1, &texture2 ); + glBindTexture( GL_TEXTURE_2D, texture2 ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + GLubyte texture2Data[] = { 0xff, 0, 0, 0xff, + 0, 0xff, 0, 0xaa, + 0, 0, 0xff, 0x55, + 0x80, 0x90, 0x70, 0 }; + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, + GL_RGBA, GL_UNSIGNED_BYTE, texture2Data ); + + // BEGIN + +#if USE_GLEW + glewInit(); +#endif + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + // original: glFrustum(-0.6435469817188064, 0.6435469817188064 ,-0.48266022190470925, 0.48266022190470925 ,0.5400000214576721, 2048); + glFrustum(-0.6435469817188064, 0.1435469817188064 ,-0.48266022190470925, 0.88266022190470925 ,0.5400000214576721, 2048); + glRotatef(-30, 1, 1, 1); + //GLfloat pm[] = { 1.372136116027832, 0, 0, 0, 0, 0.7910231351852417, 0, 0, -0.6352481842041016, 0.29297152161598206, -1.0005275011062622, -1, 0, 0, -1.080284833908081, 0 }; + //glLoadMatrixf(pm); + + glMatrixMode(GL_MODELVIEW); + GLfloat matrixData[] = { -1, 0, 0, 0, + 0, 0,-1, 0, + 0, 1, 0, 0, + 0, 0, 0, 1 }; + glLoadMatrixf(matrixData); + //glTranslated(-512,-512,-527); // XXX this should be uncommented, but if it is then nothing is shown + + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + + glClear(GL_DEPTH_BUFFER_BIT); + + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glActiveTexture(GL_TEXTURE0); + + glEnableClientState(GL_VERTEX_ARRAY); + + GLuint arrayBuffer, elementBuffer; + glGenBuffers(1, &arrayBuffer); + glGenBuffers(1, &elementBuffer); + + GLubyte arrayData[] = { +/* +[0, 0, 0, 67] ==> 128 float +[0, 0, 128, 67] ==> 256 float +[0, 0, 0, 68] ==> 512 float +[0, 0, 128, 68] ==> 1024 float + +[vertex x ] [vertex y ] [vertex z ] [nr] [texture u ] [texture v ] [lm u ] [lm v ] [color r,g,b,a ] */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 11, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 0 + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 23, 20, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 1 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 35, 30, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 2 + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 47, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 3 + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 51, 50, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 4 + 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 68, 64, 60, 0, 0, 0, 0, 128, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 5 + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 70, 70, 0, 0, 0, 0, 128, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 6 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 89, 80, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 7 + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 94, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 8 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 20, 10, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 9 + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 31, 20, 0, 0, 0, 0, 0, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 10 + 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 68, 42, 30, 0, 0, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 11 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 53, 40, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 12 + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 64, 50, 0, 0, 0, 0, 128, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 13 + 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 68, 75, 60, 0, 0, 0, 0, 128, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 14 + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 86, 70, 0, 0, 0, 0, 0, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 15 + + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128 + }; + assert(sizeof(arrayData) == 1408); + glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(arrayData), arrayData, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + GLushort elementData[] = { 1, 2, 0, 2, 3, 0, 5, 6, 4, 6, 7, 4, 9, 10, 8, 10, 11, 8, 13, 14, 12, 14, 15, 12 }; + assert(sizeof(elementData) == 48); + + glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer); + + // sauer vertex data is apparently 0-12: V3F, 12: N1B, 16-24: T2F, 24-28: T2S, 28-32: C4B + glVertexPointer(3, GL_FLOAT, 32, (void*)0); // all these apply to the ARRAY_BUFFER that is bound + glTexCoordPointer(2, GL_FLOAT, 32, (void*)16); + glClientActiveTexture(GL_TEXTURE1); // XXX seems to be ignored in native build + glTexCoordPointer(2, GL_SHORT, 32, (void*)24); + glClientActiveTexture(GL_TEXTURE0); // likely not needed, it is a cleanup + glNormalPointer(GL_BYTE, 32, (void*)12); + glColorPointer(4, GL_UNSIGNED_BYTE, 32, (void*)28); + + glBindTexture(GL_TEXTURE_2D, texture); // diffuse? + glActiveTexture(GL_TEXTURE0); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, texture2); // lightmap? + glActiveTexture(GL_TEXTURE0); + + GLint ok; + + const char *vertexShader = "uniform vec4 texgenscroll;\n" + "void main(void)\n" + "{\n" + " gl_Position = ftransform();\n" + " gl_TexCoord[0].xy = gl_MultiTexCoord0.xy/10000.0 + (0.001*texgenscroll.xy) + gl_Normal.xy;\n" // added /100 here + " gl_TexCoord[1].xy = gl_MultiTexCoord1.xy/100.0 * 3.051851e-05;\n" + "}\n"; + const char *fragmentShader = "uniform vec4 colorparams;\n" + "uniform sampler2D diffusemap, lightmap;\n" + "void main(void)\n" + "{\n" + " vec4 diffuse = texture2D(diffusemap, gl_TexCoord[0].xy);\n" + " vec4 lm = texture2D(lightmap, gl_TexCoord[1].xy);\n" + " diffuse *= colorparams;\n" + " gl_FragColor = diffuse * lm;\n" + "}\n"; + + GLuint vs = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vs, 1, &vertexShader, NULL); + glCompileShader(vs); + glGetShaderiv(vs, GL_COMPILE_STATUS, &ok); + assert(ok); + + GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fs, 1, &fragmentShader, NULL); + glCompileShader(fs); + glGetShaderiv(fs, GL_COMPILE_STATUS, &ok); + assert(ok); + + GLuint program = glCreateProgram(); + + glAttachShader(program, vs); + glAttachShader(program, fs); + glLinkProgram(program); + glGetProgramiv(program, GL_LINK_STATUS, &ok); + assert(ok); + + glUseProgram(program); + + GLint lightmapLocation = glGetUniformLocation(program, "lightmap"); + assert(lightmapLocation >= 0); + glUniform1i(lightmapLocation, 1); // sampler2D? Is it the texture unit? + + GLint diffusemapLocation = glGetUniformLocation(program, "diffusemap"); + assert(diffusemapLocation >= 0); + glUniform1i(diffusemapLocation, 0); + + GLint texgenscrollLocation = glGetUniformLocation(program, "texgenscroll"); + assert(texgenscrollLocation >= 0); + + GLint colorparamsLocation = glGetUniformLocation(program, "colorparams"); + assert(colorparamsLocation >= 0); + + GLfloat texgenscrollData[] = { 0, 0, 0, 0 }; + glUniform4fv(texgenscrollLocation, 1, texgenscrollData); + + GLfloat colorparamsData[] = { 2, 2, 2, 1 }; + glUniform4fv(colorparamsLocation, 1, colorparamsData); + + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)&elementData[12/sizeof(GLushort)]); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)&elementData[ 0/sizeof(GLushort)]); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)&elementData[24/sizeof(GLushort)]); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)&elementData[36/sizeof(GLushort)]); + + // END + + SDL_GL_SwapBuffers(); + + verify(); + +#if !EMSCRIPTEN + SDL_Delay(1500); +#endif + + SDL_Quit(); + + return 0; +} diff --git a/tests/cubegeom_normal_dap_far.c b/tests/cubegeom_normal_dap_far.c new file mode 100644 index 00000000..f954b3c7 --- /dev/null +++ b/tests/cubegeom_normal_dap_far.c @@ -0,0 +1,289 @@ +/* +THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION +AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN. + +THE ORIGINAL AUTHOR IS KYLE FOLEY. + +THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY +OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF +MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, +ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE +RESULTING FROM THE USE, MODIFICATION, OR +REDISTRIBUTION OF THIS SOFTWARE. +*/ + +#if !EMSCRIPTEN +#define USE_GLEW 1 +#endif + +#if USE_GLEW +#include "GL/glew.h" +#endif + +#include "SDL/SDL.h" +#if !USE_GLEW +#include "SDL/SDL_opengl.h" +#endif + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +void verify() { + int width = 640, height = 480; + unsigned char *data = (unsigned char*)malloc(width*height*4); + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); + int sum = 0; + for (int x = 0; x < width*height*4; x++) { + if (x % 4 != 3) sum += x * data[x]; + } +#if EMSCRIPTEN + int result = sum; + REPORT_RESULT(); +#endif +} + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { + printf("Unable to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); + screen = SDL_SetVideoMode( 640, 480, 24, SDL_OPENGL ); + if ( !screen ) { + printf("Unable to set video mode: %s\n", SDL_GetError()); + return 1; + } + + glClearColor( 0, 0, 0, 0 ); + glClear( GL_COLOR_BUFFER_BIT ); + + // Create a texture + + GLuint texture; + glGenTextures( 1, &texture ); + glBindTexture( GL_TEXTURE_2D, texture ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + GLubyte textureData[16*16*4]; + for (int x = 0; x < 16; x++) { + for (int y = 0; y < 16; y++) { + *((int*)&textureData[(x*16 + y) * 4]) = x*16 + ((y*16) << 8); + } + } + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, + GL_RGBA, GL_UNSIGNED_BYTE, textureData ); + + // Create a second texture + + GLuint texture2; + glGenTextures( 1, &texture2 ); + glBindTexture( GL_TEXTURE_2D, texture2 ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + GLubyte texture2Data[] = { 0xff, 0, 0, 0xff, + 0, 0xff, 0, 0xaa, + 0, 0, 0xff, 0x55, + 0x80, 0x90, 0x70, 0 }; + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, + GL_RGBA, GL_UNSIGNED_BYTE, texture2Data ); + + // BEGIN + +#if USE_GLEW + glewInit(); +#endif + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + // original: glFrustum(-0.6435469817188064, 0.6435469817188064 ,-0.48266022190470925, 0.48266022190470925 ,0.5400000214576721, 2048); + glFrustum(-0.6435469817188064, 0.1435469817188064 ,-0.48266022190470925, 0.88266022190470925 ,0.5400000214576721, 2048); + glRotatef(-30, 1, 1, 1); + //GLfloat pm[] = { 1.372136116027832, 0, 0, 0, 0, 0.7910231351852417, 0, 0, -0.6352481842041016, 0.29297152161598206, -1.0005275011062622, -1, 0, 0, -1.080284833908081, 0 }; + //glLoadMatrixf(pm); + + glMatrixMode(GL_MODELVIEW); + GLfloat matrixData[] = { -1, 0, 0, 0, + 0, 0,-1, 0, + 0, 1, 0, 0, + 0, 0, 0, 1 }; + glLoadMatrixf(matrixData); + //glTranslated(-512,-512,-527); // XXX this should be uncommented, but if it is then nothing is shown + + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + + glClear(GL_DEPTH_BUFFER_BIT); + + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glActiveTexture(GL_TEXTURE0); + + glEnableClientState(GL_VERTEX_ARRAY); + + GLubyte arrayData[] = { +/* +[0, 0, 0, 67] ==> 128 float +[0, 0, 128, 67] ==> 256 float +[0, 0, 0, 68] ==> 512 float +[0, 0, 128, 68] ==> 1024 float + +[vertex x ] [vertex y ] [vertex z ] [nr] [texture u ] [texture v ] [lm u ] [lm v ] [color r,g,b,a ] */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // ignorable ones + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 11, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 0 + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 23, 20, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 1 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 35, 30, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 2 + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 47, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 3 + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 51, 50, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 4 + 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 68, 64, 60, 0, 0, 0, 0, 128, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 5 + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 70, 70, 0, 0, 0, 0, 128, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 6 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 89, 80, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 7 + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 94, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 8 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 20, 10, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 9 + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 31, 20, 0, 0, 0, 0, 0, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 10 + 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 68, 42, 30, 0, 0, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 11 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 53, 40, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 12 + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 64, 50, 0, 0, 0, 0, 128, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 13 + 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 68, 75, 60, 0, 0, 0, 0, 128, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 14 + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 86, 70, 0, 0, 0, 0, 0, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 15 + + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + }; + + GLushort elementData[] = { 1, 2, 0, 2, 3, 0, 5, 6, 4, 6, 7, 4, 9, 10, 8, 10, 11, 8, 13, 14, 12, 14, 15, 12 }; + assert(sizeof(elementData) == 48); + for (int i = 0; i < 24; i++) { + elementData[i] += 16; + } + + // sauer vertex data is apparently 0-12: V3F, 12: N1B, 16-24: T2F, 24-28: T2S, 28-32: C4B + glVertexPointer(3, GL_FLOAT, 32, (void*)&arrayData[0]); + glTexCoordPointer(2, GL_FLOAT, 32, (void*)&arrayData[16]); + glClientActiveTexture(GL_TEXTURE1); // XXX seems to be ignored in native build + glTexCoordPointer(2, GL_SHORT, 32, (void*)&arrayData[24]); + glClientActiveTexture(GL_TEXTURE0); // likely not needed, it is a cleanup + glNormalPointer(GL_BYTE, 32, (void*)&arrayData[12]); + glColorPointer(4, GL_UNSIGNED_BYTE, 32, (void*)&arrayData[28]); + + glBindTexture(GL_TEXTURE_2D, texture); // diffuse? + glActiveTexture(GL_TEXTURE0); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, texture2); // lightmap? + glActiveTexture(GL_TEXTURE0); + + GLint ok; + + const char *vertexShader = "uniform vec4 texgenscroll;\n" + "void main(void)\n" + "{\n" + " gl_Position = ftransform();\n" + " gl_TexCoord[0].xy = gl_MultiTexCoord0.xy/10000.0 + (0.001*texgenscroll.xy) + gl_Normal.xy;\n" // added /100 here + " gl_TexCoord[1].xy = gl_MultiTexCoord1.xy/100.0 * 3.051851e-05;\n" + "}\n"; + const char *fragmentShader = "uniform vec4 colorparams;\n" + "uniform sampler2D diffusemap, lightmap;\n" + "void main(void)\n" + "{\n" + " vec4 diffuse = texture2D(diffusemap, gl_TexCoord[0].xy);\n" + " vec4 lm = texture2D(lightmap, gl_TexCoord[1].xy);\n" + " diffuse *= colorparams;\n" + " gl_FragColor = diffuse * lm;\n" + "}\n"; + + GLuint vs = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vs, 1, &vertexShader, NULL); + glCompileShader(vs); + glGetShaderiv(vs, GL_COMPILE_STATUS, &ok); + assert(ok); + + GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fs, 1, &fragmentShader, NULL); + glCompileShader(fs); + glGetShaderiv(fs, GL_COMPILE_STATUS, &ok); + assert(ok); + + GLuint program = glCreateProgram(); + + glAttachShader(program, vs); + glAttachShader(program, fs); + glLinkProgram(program); + glGetProgramiv(program, GL_LINK_STATUS, &ok); + assert(ok); + + glUseProgram(program); + + GLint lightmapLocation = glGetUniformLocation(program, "lightmap"); + assert(lightmapLocation >= 0); + glUniform1i(lightmapLocation, 1); // sampler2D? Is it the texture unit? + + GLint diffusemapLocation = glGetUniformLocation(program, "diffusemap"); + assert(diffusemapLocation >= 0); + glUniform1i(diffusemapLocation, 0); + + GLint texgenscrollLocation = glGetUniformLocation(program, "texgenscroll"); + assert(texgenscrollLocation >= 0); + + GLint colorparamsLocation = glGetUniformLocation(program, "colorparams"); + assert(colorparamsLocation >= 0); + + GLfloat texgenscrollData[] = { 0, 0, 0, 0 }; + glUniform4fv(texgenscrollLocation, 1, texgenscrollData); + + GLfloat colorparamsData[] = { 2, 2, 2, 1 }; + glUniform4fv(colorparamsLocation, 1, colorparamsData); + + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)&elementData[12/sizeof(GLushort)]); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)&elementData[ 0/sizeof(GLushort)]); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)&elementData[24/sizeof(GLushort)]); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)&elementData[36/sizeof(GLushort)]); + + // END + + SDL_GL_SwapBuffers(); + + verify(); + +#if !EMSCRIPTEN + SDL_Delay(1500); +#endif + + SDL_Quit(); + + return 0; +} diff --git a/tests/cubegeom_normal_dap_far_glda.c b/tests/cubegeom_normal_dap_far_glda.c new file mode 100644 index 00000000..a4b4975b --- /dev/null +++ b/tests/cubegeom_normal_dap_far_glda.c @@ -0,0 +1,280 @@ +/* +THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION +AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN. + +THE ORIGINAL AUTHOR IS KYLE FOLEY. + +THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY +OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF +MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, +ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE +RESULTING FROM THE USE, MODIFICATION, OR +REDISTRIBUTION OF THIS SOFTWARE. +*/ + +#if !EMSCRIPTEN +#define USE_GLEW 1 +#endif + +#if USE_GLEW +#include "GL/glew.h" +#endif + +#include "SDL/SDL.h" +#if !USE_GLEW +#include "SDL/SDL_opengl.h" +#endif + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +void verify() { + int width = 640, height = 480; + unsigned char *data = (unsigned char*)malloc(width*height*4); + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); + int sum = 0; + for (int x = 0; x < width*height*4; x++) { + if (x % 4 != 3) sum += x * data[x]; + } +#if EMSCRIPTEN + int result = sum; + REPORT_RESULT(); +#endif +} + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { + printf("Unable to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); + screen = SDL_SetVideoMode( 640, 480, 24, SDL_OPENGL ); + if ( !screen ) { + printf("Unable to set video mode: %s\n", SDL_GetError()); + return 1; + } + + glClearColor( 0, 0, 0, 0 ); + glClear( GL_COLOR_BUFFER_BIT ); + + // Create a texture + + GLuint texture; + glGenTextures( 1, &texture ); + glBindTexture( GL_TEXTURE_2D, texture ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + GLubyte textureData[16*16*4]; + for (int x = 0; x < 16; x++) { + for (int y = 0; y < 16; y++) { + *((int*)&textureData[(x*16 + y) * 4]) = x*16 + ((y*16) << 8); + } + } + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, + GL_RGBA, GL_UNSIGNED_BYTE, textureData ); + + // Create a second texture + + GLuint texture2; + glGenTextures( 1, &texture2 ); + glBindTexture( GL_TEXTURE_2D, texture2 ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + GLubyte texture2Data[] = { 0xff, 0, 0, 0xff, + 0, 0xff, 0, 0xaa, + 0, 0, 0xff, 0x55, + 0x80, 0x90, 0x70, 0 }; + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, + GL_RGBA, GL_UNSIGNED_BYTE, texture2Data ); + + // BEGIN + +#if USE_GLEW + glewInit(); +#endif + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + // original: glFrustum(-0.6435469817188064, 0.6435469817188064 ,-0.48266022190470925, 0.48266022190470925 ,0.5400000214576721, 2048); + glFrustum(-0.6435469817188064, 0.1435469817188064 ,-0.48266022190470925, 0.88266022190470925 ,0.5400000214576721, 2048); + glRotatef(-30, 1, 1, 1); + //GLfloat pm[] = { 1.372136116027832, 0, 0, 0, 0, 0.7910231351852417, 0, 0, -0.6352481842041016, 0.29297152161598206, -1.0005275011062622, -1, 0, 0, -1.080284833908081, 0 }; + //glLoadMatrixf(pm); + + glMatrixMode(GL_MODELVIEW); + GLfloat matrixData[] = { -1, 0, 0, 0, + 0, 0,-1, 0, + 0, 1, 0, 0, + 0, 0, 0, 1 }; + glLoadMatrixf(matrixData); + //glTranslated(-512,-512,-527); // XXX this should be uncommented, but if it is then nothing is shown + + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + + glClear(GL_DEPTH_BUFFER_BIT); + + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glActiveTexture(GL_TEXTURE0); + + glEnableClientState(GL_VERTEX_ARRAY); + + GLubyte arrayData[] = { +/* +[0, 0, 0, 67] ==> 128 float +[0, 0, 128, 67] ==> 256 float +[0, 0, 0, 68] ==> 512 float +[0, 0, 128, 68] ==> 1024 float + +[vertex x ] [vertex y ] [vertex z ] [nr] [texture u ] [texture v ] [lm u ] [lm v ] [color r,g,b,a ] */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // ignorable ones + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + + 0, 0, 10, 0, 0, 0, 40, 0, 0, 0, 10, 68, 11, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 0 + 0, 0, 20, 68, 0, 0, 50, 0, 0, 0, 20, 68, 23, 20, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 1 + 0, 0, 30, 68, 0, 0, 60, 68, 0, 0, 30, 68, 35, 30, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 2 + 0, 0, 40, 0, 0, 0, 70, 68, 0, 0, 40, 68, 47, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 3 + 0, 0, 50, 68, 0, 0, 80, 0, 0, 0, 50, 68, 51, 50, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 4 + 0, 0, 128, 68, 0, 0, 90, 0, 0, 0, 60, 68, 64, 60, 0, 0, 0, 0, 128, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 5 + 0, 0, 128, 68, 0, 0, 100, 68, 0, 0, 70, 68, 70, 70, 0, 0, 0, 0, 128, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 6 + 0, 0, 60, 68, 0, 0, 110, 68, 0, 0, 80, 68, 89, 80, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 7 + 0, 0, 70, 0, 0, 0, 10, 68, 0, 0, 90, 68, 94, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 8 + 0, 0, 80, 68, 0, 0, 20, 68, 0, 0, 100, 68, 20, 10, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 9 + 0, 0, 90, 68, 0, 0, 128, 68, 0, 0, 110, 68, 31, 20, 0, 0, 0, 0, 0, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 10 + 0, 0, 100, 0, 0, 0, 128, 68, 0, 0, 120, 68, 42, 30, 0, 0, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 11 + 0, 0, 110, 68, 0, 0, 55, 68, 0, 0, 5, 68, 53, 40, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 12 + 0, 0, 128, 68, 0, 0, 75, 68, 0, 0, 15, 68, 64, 50, 0, 0, 0, 0, 128, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 13 + 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 25, 68, 75, 60, 0, 0, 0, 0, 128, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 14 + 0, 0, 55, 68, 0, 0, 128, 68, 0, 0, 55, 68, 86, 70, 0, 0, 0, 0, 0, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 15 + + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + }; + + // sauer vertex data is apparently 0-12: V3F, 12: N1B, 16-24: T2F, 24-28: T2S, 28-32: C4B + glVertexPointer(3, GL_FLOAT, 32, (void*)&arrayData[0]); + glTexCoordPointer(2, GL_FLOAT, 32, (void*)&arrayData[16]); + glClientActiveTexture(GL_TEXTURE1); // XXX seems to be ignored in native build + glTexCoordPointer(2, GL_SHORT, 32, (void*)&arrayData[24]); + glClientActiveTexture(GL_TEXTURE0); // likely not needed, it is a cleanup + glNormalPointer(GL_BYTE, 32, (void*)&arrayData[12]); + glColorPointer(4, GL_UNSIGNED_BYTE, 32, (void*)&arrayData[28]); + + glBindTexture(GL_TEXTURE_2D, texture); // diffuse? + glActiveTexture(GL_TEXTURE0); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, texture2); // lightmap? + glActiveTexture(GL_TEXTURE0); + + GLint ok; + + const char *vertexShader = "uniform vec4 texgenscroll;\n" + "void main(void)\n" + "{\n" + " gl_Position = ftransform();\n" + " gl_TexCoord[0].xy = gl_MultiTexCoord0.xy/10000.0 + (0.001*texgenscroll.xy) + gl_Normal.xy;\n" // added /100 here + " gl_TexCoord[1].xy = gl_MultiTexCoord1.xy/100.0 * 3.051851e-05;\n" + "}\n"; + const char *fragmentShader = "uniform vec4 colorparams;\n" + "uniform sampler2D diffusemap, lightmap;\n" + "void main(void)\n" + "{\n" + " vec4 diffuse = texture2D(diffusemap, gl_TexCoord[0].xy);\n" + " vec4 lm = texture2D(lightmap, gl_TexCoord[1].xy);\n" + " diffuse *= colorparams;\n" + " gl_FragColor = diffuse * lm;\n" + "}\n"; + + GLuint vs = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vs, 1, &vertexShader, NULL); + glCompileShader(vs); + glGetShaderiv(vs, GL_COMPILE_STATUS, &ok); + assert(ok); + + GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fs, 1, &fragmentShader, NULL); + glCompileShader(fs); + glGetShaderiv(fs, GL_COMPILE_STATUS, &ok); + assert(ok); + + GLuint program = glCreateProgram(); + + glAttachShader(program, vs); + glAttachShader(program, fs); + glLinkProgram(program); + glGetProgramiv(program, GL_LINK_STATUS, &ok); + assert(ok); + + glUseProgram(program); + + GLint lightmapLocation = glGetUniformLocation(program, "lightmap"); + assert(lightmapLocation >= 0); + glUniform1i(lightmapLocation, 1); // sampler2D? Is it the texture unit? + + GLint diffusemapLocation = glGetUniformLocation(program, "diffusemap"); + assert(diffusemapLocation >= 0); + glUniform1i(diffusemapLocation, 0); + + GLint texgenscrollLocation = glGetUniformLocation(program, "texgenscroll"); + assert(texgenscrollLocation >= 0); + + GLint colorparamsLocation = glGetUniformLocation(program, "colorparams"); + assert(colorparamsLocation >= 0); + + GLfloat texgenscrollData[] = { 0, 0, 0, 0 }; + glUniform4fv(texgenscrollLocation, 1, texgenscrollData); + + GLfloat colorparamsData[] = { 2, 2, 2, 1 }; + glUniform4fv(colorparamsLocation, 1, colorparamsData); + + glDrawArrays(GL_TRIANGLES, 16, 16); + + // END + + SDL_GL_SwapBuffers(); + + verify(); + +#if !EMSCRIPTEN + SDL_Delay(1500); +#endif + + SDL_Quit(); + + return 0; +} diff --git a/tests/cubegeom_normal_dap_far_glda_quad.c b/tests/cubegeom_normal_dap_far_glda_quad.c new file mode 100644 index 00000000..aa6383b8 --- /dev/null +++ b/tests/cubegeom_normal_dap_far_glda_quad.c @@ -0,0 +1,280 @@ +/* +THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION +AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN. + +THE ORIGINAL AUTHOR IS KYLE FOLEY. + +THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY +OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF +MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, +ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE +RESULTING FROM THE USE, MODIFICATION, OR +REDISTRIBUTION OF THIS SOFTWARE. +*/ + +#if !EMSCRIPTEN +#define USE_GLEW 1 +#endif + +#if USE_GLEW +#include "GL/glew.h" +#endif + +#include "SDL/SDL.h" +#if !USE_GLEW +#include "SDL/SDL_opengl.h" +#endif + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +void verify() { + int width = 640, height = 480; + unsigned char *data = (unsigned char*)malloc(width*height*4); + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); + int sum = 0; + for (int x = 0; x < width*height*4; x++) { + if (x % 4 != 3) sum += x * data[x]; + } +#if EMSCRIPTEN + int result = sum; + REPORT_RESULT(); +#endif +} + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { + printf("Unable to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); + screen = SDL_SetVideoMode( 640, 480, 24, SDL_OPENGL ); + if ( !screen ) { + printf("Unable to set video mode: %s\n", SDL_GetError()); + return 1; + } + + glClearColor( 0, 0, 0, 0 ); + glClear( GL_COLOR_BUFFER_BIT ); + + // Create a texture + + GLuint texture; + glGenTextures( 1, &texture ); + glBindTexture( GL_TEXTURE_2D, texture ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + GLubyte textureData[16*16*4]; + for (int x = 0; x < 16; x++) { + for (int y = 0; y < 16; y++) { + *((int*)&textureData[(x*16 + y) * 4]) = x*16 + ((y*16) << 8); + } + } + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, + GL_RGBA, GL_UNSIGNED_BYTE, textureData ); + + // Create a second texture + + GLuint texture2; + glGenTextures( 1, &texture2 ); + glBindTexture( GL_TEXTURE_2D, texture2 ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + GLubyte texture2Data[] = { 0xff, 0, 0, 0xff, + 0, 0xff, 0, 0xaa, + 0, 0, 0xff, 0x55, + 0x80, 0x90, 0x70, 0 }; + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, + GL_RGBA, GL_UNSIGNED_BYTE, texture2Data ); + + // BEGIN + +#if USE_GLEW + glewInit(); +#endif + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + // original: glFrustum(-0.6435469817188064, 0.6435469817188064 ,-0.48266022190470925, 0.48266022190470925 ,0.5400000214576721, 2048); + glFrustum(-0.6435469817188064, 0.1435469817188064 ,-0.48266022190470925, 0.88266022190470925 ,0.5400000214576721, 2048); + glRotatef(-30, 1, 1, 1); + //GLfloat pm[] = { 1.372136116027832, 0, 0, 0, 0, 0.7910231351852417, 0, 0, -0.6352481842041016, 0.29297152161598206, -1.0005275011062622, -1, 0, 0, -1.080284833908081, 0 }; + //glLoadMatrixf(pm); + + glMatrixMode(GL_MODELVIEW); + GLfloat matrixData[] = { -1, 0, 0, 0, + 0, 0,-1, 0, + 0, 1, 0, 0, + 0, 0, 0, 1 }; + glLoadMatrixf(matrixData); + //glTranslated(-512,-512,-527); // XXX this should be uncommented, but if it is then nothing is shown + + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + + glClear(GL_DEPTH_BUFFER_BIT); + + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glActiveTexture(GL_TEXTURE0); + + glEnableClientState(GL_VERTEX_ARRAY); + + GLubyte arrayData[] = { +/* +[0, 0, 0, 67] ==> 128 float +[0, 0, 128, 67] ==> 256 float +[0, 0, 0, 68] ==> 512 float +[0, 0, 128, 68] ==> 1024 float + +[vertex x ] [vertex y ] [vertex z ] [nr] [texture u ] [texture v ] [lm u ] [lm v ] [color r,g,b,a ] */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // ignorable ones + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + + 0, 0, 10, 0, 0, 0, 40, 0, 0, 0, 10, 68, 11, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 0 + 0, 0, 20, 68, 0, 0, 50, 0, 0, 0, 20, 68, 23, 20, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 1 + 0, 0, 30, 68, 0, 0, 60, 68, 0, 0, 30, 68, 35, 30, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 2 + 0, 0, 40, 0, 0, 0, 70, 68, 0, 0, 40, 68, 47, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 3 + 0, 0, 50, 68, 0, 0, 80, 0, 0, 0, 50, 68, 51, 50, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 4 + 0, 0, 128, 68, 0, 0, 90, 0, 0, 0, 60, 68, 64, 60, 0, 0, 0, 0, 128, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 5 + 0, 0, 128, 68, 0, 0, 100, 68, 0, 0, 70, 68, 70, 70, 0, 0, 0, 0, 128, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 6 + 0, 0, 60, 68, 0, 0, 110, 68, 0, 0, 80, 68, 89, 80, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 7 + 0, 0, 70, 0, 0, 0, 10, 68, 0, 0, 90, 68, 94, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 8 + 0, 0, 80, 68, 0, 0, 20, 68, 0, 0, 100, 68, 20, 10, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 9 + 0, 0, 90, 68, 0, 0, 128, 68, 0, 0, 110, 68, 31, 20, 0, 0, 0, 0, 0, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 10 + 0, 0, 100, 0, 0, 0, 128, 68, 0, 0, 120, 68, 42, 30, 0, 0, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 11 + 0, 0, 110, 68, 0, 0, 55, 68, 0, 0, 5, 68, 53, 40, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 12 + 0, 0, 128, 68, 0, 0, 75, 68, 0, 0, 15, 68, 64, 50, 0, 0, 0, 0, 128, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 13 + 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 25, 68, 75, 60, 0, 0, 0, 0, 128, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 14 + 0, 0, 55, 68, 0, 0, 128, 68, 0, 0, 55, 68, 86, 70, 0, 0, 0, 0, 0, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 15 + + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + }; + + // sauer vertex data is apparently 0-12: V3F, 12: N1B, 16-24: T2F, 24-28: T2S, 28-32: C4B + glVertexPointer(3, GL_FLOAT, 32, (void*)&arrayData[0]); + glTexCoordPointer(2, GL_FLOAT, 32, (void*)&arrayData[16]); + glClientActiveTexture(GL_TEXTURE1); // XXX seems to be ignored in native build + glTexCoordPointer(2, GL_SHORT, 32, (void*)&arrayData[24]); + glClientActiveTexture(GL_TEXTURE0); // likely not needed, it is a cleanup + glNormalPointer(GL_BYTE, 32, (void*)&arrayData[12]); + glColorPointer(4, GL_UNSIGNED_BYTE, 32, (void*)&arrayData[28]); + + glBindTexture(GL_TEXTURE_2D, texture); // diffuse? + glActiveTexture(GL_TEXTURE0); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, texture2); // lightmap? + glActiveTexture(GL_TEXTURE0); + + GLint ok; + + const char *vertexShader = "uniform vec4 texgenscroll;\n" + "void main(void)\n" + "{\n" + " gl_Position = ftransform();\n" + " gl_TexCoord[0].xy = gl_MultiTexCoord0.xy/10000.0 + (0.001*texgenscroll.xy) + gl_Normal.xy;\n" // added /100 here + " gl_TexCoord[1].xy = gl_MultiTexCoord1.xy/100.0 * 3.051851e-05;\n" + "}\n"; + const char *fragmentShader = "uniform vec4 colorparams;\n" + "uniform sampler2D diffusemap, lightmap;\n" + "void main(void)\n" + "{\n" + " vec4 diffuse = texture2D(diffusemap, gl_TexCoord[0].xy);\n" + " vec4 lm = texture2D(lightmap, gl_TexCoord[1].xy);\n" + " diffuse *= colorparams;\n" + " gl_FragColor = diffuse * lm;\n" + "}\n"; + + GLuint vs = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vs, 1, &vertexShader, NULL); + glCompileShader(vs); + glGetShaderiv(vs, GL_COMPILE_STATUS, &ok); + assert(ok); + + GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fs, 1, &fragmentShader, NULL); + glCompileShader(fs); + glGetShaderiv(fs, GL_COMPILE_STATUS, &ok); + assert(ok); + + GLuint program = glCreateProgram(); + + glAttachShader(program, vs); + glAttachShader(program, fs); + glLinkProgram(program); + glGetProgramiv(program, GL_LINK_STATUS, &ok); + assert(ok); + + glUseProgram(program); + + GLint lightmapLocation = glGetUniformLocation(program, "lightmap"); + assert(lightmapLocation >= 0); + glUniform1i(lightmapLocation, 1); // sampler2D? Is it the texture unit? + + GLint diffusemapLocation = glGetUniformLocation(program, "diffusemap"); + assert(diffusemapLocation >= 0); + glUniform1i(diffusemapLocation, 0); + + GLint texgenscrollLocation = glGetUniformLocation(program, "texgenscroll"); + assert(texgenscrollLocation >= 0); + + GLint colorparamsLocation = glGetUniformLocation(program, "colorparams"); + assert(colorparamsLocation >= 0); + + GLfloat texgenscrollData[] = { 0, 0, 0, 0 }; + glUniform4fv(texgenscrollLocation, 1, texgenscrollData); + + GLfloat colorparamsData[] = { 2, 2, 2, 1 }; + glUniform4fv(colorparamsLocation, 1, colorparamsData); + + glDrawArrays(GL_QUADS, 16, 12); + + // END + + SDL_GL_SwapBuffers(); + + verify(); + +#if !EMSCRIPTEN + SDL_Delay(1500); +#endif + + SDL_Quit(); + + return 0; +} diff --git a/tests/cubegeom_normal_dap_far_range.c b/tests/cubegeom_normal_dap_far_range.c new file mode 100644 index 00000000..eb54c22a --- /dev/null +++ b/tests/cubegeom_normal_dap_far_range.c @@ -0,0 +1,289 @@ +/* +THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION +AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN. + +THE ORIGINAL AUTHOR IS KYLE FOLEY. + +THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY +OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF +MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, +ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE +RESULTING FROM THE USE, MODIFICATION, OR +REDISTRIBUTION OF THIS SOFTWARE. +*/ + +#if !EMSCRIPTEN +#define USE_GLEW 1 +#endif + +#if USE_GLEW +#include "GL/glew.h" +#endif + +#include "SDL/SDL.h" +#if !USE_GLEW +#include "SDL/SDL_opengl.h" +#endif + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +void verify() { + int width = 640, height = 480; + unsigned char *data = (unsigned char*)malloc(width*height*4); + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); + int sum = 0; + for (int x = 0; x < width*height*4; x++) { + if (x % 4 != 3) sum += x * data[x]; + } +#if EMSCRIPTEN + int result = sum; + REPORT_RESULT(); +#endif +} + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { + printf("Unable to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); + screen = SDL_SetVideoMode( 640, 480, 24, SDL_OPENGL ); + if ( !screen ) { + printf("Unable to set video mode: %s\n", SDL_GetError()); + return 1; + } + + glClearColor( 0, 0, 0, 0 ); + glClear( GL_COLOR_BUFFER_BIT ); + + // Create a texture + + GLuint texture; + glGenTextures( 1, &texture ); + glBindTexture( GL_TEXTURE_2D, texture ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + GLubyte textureData[16*16*4]; + for (int x = 0; x < 16; x++) { + for (int y = 0; y < 16; y++) { + *((int*)&textureData[(x*16 + y) * 4]) = x*16 + ((y*16) << 8); + } + } + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, + GL_RGBA, GL_UNSIGNED_BYTE, textureData ); + + // Create a second texture + + GLuint texture2; + glGenTextures( 1, &texture2 ); + glBindTexture( GL_TEXTURE_2D, texture2 ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + GLubyte texture2Data[] = { 0xff, 0, 0, 0xff, + 0, 0xff, 0, 0xaa, + 0, 0, 0xff, 0x55, + 0x80, 0x90, 0x70, 0 }; + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, + GL_RGBA, GL_UNSIGNED_BYTE, texture2Data ); + + // BEGIN + +#if USE_GLEW + glewInit(); +#endif + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + // original: glFrustum(-0.6435469817188064, 0.6435469817188064 ,-0.48266022190470925, 0.48266022190470925 ,0.5400000214576721, 2048); + glFrustum(-0.6435469817188064, 0.1435469817188064 ,-0.48266022190470925, 0.88266022190470925 ,0.5400000214576721, 2048); + glRotatef(-30, 1, 1, 1); + //GLfloat pm[] = { 1.372136116027832, 0, 0, 0, 0, 0.7910231351852417, 0, 0, -0.6352481842041016, 0.29297152161598206, -1.0005275011062622, -1, 0, 0, -1.080284833908081, 0 }; + //glLoadMatrixf(pm); + + glMatrixMode(GL_MODELVIEW); + GLfloat matrixData[] = { -1, 0, 0, 0, + 0, 0,-1, 0, + 0, 1, 0, 0, + 0, 0, 0, 1 }; + glLoadMatrixf(matrixData); + //glTranslated(-512,-512,-527); // XXX this should be uncommented, but if it is then nothing is shown + + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + + glClear(GL_DEPTH_BUFFER_BIT); + + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glActiveTexture(GL_TEXTURE0); + + glEnableClientState(GL_VERTEX_ARRAY); + + GLubyte arrayData[] = { +/* +[0, 0, 0, 67] ==> 128 float +[0, 0, 128, 67] ==> 256 float +[0, 0, 0, 68] ==> 512 float +[0, 0, 128, 68] ==> 1024 float + +[vertex x ] [vertex y ] [vertex z ] [nr] [texture u ] [texture v ] [lm u ] [lm v ] [color r,g,b,a ] */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // ignorable ones + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 11, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 0 + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 23, 20, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 1 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 35, 30, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 2 + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 47, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 3 + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 51, 50, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 4 + 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 68, 64, 60, 0, 0, 0, 0, 128, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 5 + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 70, 70, 0, 0, 0, 0, 128, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 6 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 89, 80, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 7 + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 94, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 8 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 20, 10, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 9 + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 31, 20, 0, 0, 0, 0, 0, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 10 + 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 68, 42, 30, 0, 0, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 11 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 53, 40, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 12 + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 64, 50, 0, 0, 0, 0, 128, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 13 + 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 68, 75, 60, 0, 0, 0, 0, 128, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 14 + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 86, 70, 0, 0, 0, 0, 0, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 15 + + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + }; + + GLushort elementData[] = { 1, 2, 0, 2, 3, 0, 5, 6, 4, 6, 7, 4, 9, 10, 8, 10, 11, 8, 13, 14, 12, 14, 15, 12 }; + assert(sizeof(elementData) == 48); + for (int i = 0; i < 24; i++) { + elementData[i] += 16; + } + + // sauer vertex data is apparently 0-12: V3F, 12: N1B, 16-24: T2F, 24-28: T2S, 28-32: C4B + glVertexPointer(3, GL_FLOAT, 32, (void*)&arrayData[0]); + glTexCoordPointer(2, GL_FLOAT, 32, (void*)&arrayData[16]); + glClientActiveTexture(GL_TEXTURE1); // XXX seems to be ignored in native build + glTexCoordPointer(2, GL_SHORT, 32, (void*)&arrayData[24]); + glClientActiveTexture(GL_TEXTURE0); // likely not needed, it is a cleanup + glNormalPointer(GL_BYTE, 32, (void*)&arrayData[12]); + glColorPointer(4, GL_UNSIGNED_BYTE, 32, (void*)&arrayData[28]); + + glBindTexture(GL_TEXTURE_2D, texture); // diffuse? + glActiveTexture(GL_TEXTURE0); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, texture2); // lightmap? + glActiveTexture(GL_TEXTURE0); + + GLint ok; + + const char *vertexShader = "uniform vec4 texgenscroll;\n" + "void main(void)\n" + "{\n" + " gl_Position = ftransform();\n" + " gl_TexCoord[0].xy = gl_MultiTexCoord0.xy/10000.0 + (0.001*texgenscroll.xy) + gl_Normal.xy;\n" // added /100 here + " gl_TexCoord[1].xy = gl_MultiTexCoord1.xy/100.0 * 3.051851e-05;\n" + "}\n"; + const char *fragmentShader = "uniform vec4 colorparams;\n" + "uniform sampler2D diffusemap, lightmap;\n" + "void main(void)\n" + "{\n" + " vec4 diffuse = texture2D(diffusemap, gl_TexCoord[0].xy);\n" + " vec4 lm = texture2D(lightmap, gl_TexCoord[1].xy);\n" + " diffuse *= colorparams;\n" + " gl_FragColor = diffuse * lm;\n" + "}\n"; + + GLuint vs = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vs, 1, &vertexShader, NULL); + glCompileShader(vs); + glGetShaderiv(vs, GL_COMPILE_STATUS, &ok); + assert(ok); + + GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fs, 1, &fragmentShader, NULL); + glCompileShader(fs); + glGetShaderiv(fs, GL_COMPILE_STATUS, &ok); + assert(ok); + + GLuint program = glCreateProgram(); + + glAttachShader(program, vs); + glAttachShader(program, fs); + glLinkProgram(program); + glGetProgramiv(program, GL_LINK_STATUS, &ok); + assert(ok); + + glUseProgram(program); + + GLint lightmapLocation = glGetUniformLocation(program, "lightmap"); + assert(lightmapLocation >= 0); + glUniform1i(lightmapLocation, 1); // sampler2D? Is it the texture unit? + + GLint diffusemapLocation = glGetUniformLocation(program, "diffusemap"); + assert(diffusemapLocation >= 0); + glUniform1i(diffusemapLocation, 0); + + GLint texgenscrollLocation = glGetUniformLocation(program, "texgenscroll"); + assert(texgenscrollLocation >= 0); + + GLint colorparamsLocation = glGetUniformLocation(program, "colorparams"); + assert(colorparamsLocation >= 0); + + GLfloat texgenscrollData[] = { 0, 0, 0, 0 }; + glUniform4fv(texgenscrollLocation, 1, texgenscrollData); + + GLfloat colorparamsData[] = { 2, 2, 2, 1 }; + glUniform4fv(colorparamsLocation, 1, colorparamsData); + + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)&elementData[12/sizeof(GLushort)]); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)&elementData[ 0/sizeof(GLushort)]); + glDrawRangeElements(GL_TRIANGLES, 8+16, 11+16, 6, GL_UNSIGNED_SHORT, (void*)&elementData[24/sizeof(GLushort)]); + glDrawRangeElements(GL_TRIANGLES, 12+16, 15+16, 6, GL_UNSIGNED_SHORT, (void*)&elementData[36/sizeof(GLushort)]); + + // END + + SDL_GL_SwapBuffers(); + + verify(); + +#if !EMSCRIPTEN + SDL_Delay(1500); +#endif + + SDL_Quit(); + + return 0; +} diff --git a/tests/cubegeom_pre.c b/tests/cubegeom_pre.c new file mode 100644 index 00000000..8001a2b8 --- /dev/null +++ b/tests/cubegeom_pre.c @@ -0,0 +1,307 @@ +/* +THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION +AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN. + +THE ORIGINAL AUTHOR IS KYLE FOLEY. + +THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY +OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF +MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, +ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE +RESULTING FROM THE USE, MODIFICATION, OR +REDISTRIBUTION OF THIS SOFTWARE. +*/ + +#if !EMSCRIPTEN +#define USE_GLEW 1 +#endif + +#if USE_GLEW +#include "GL/glew.h" +#endif + +#include "SDL/SDL.h" +#if !USE_GLEW +#include "SDL/SDL_opengl.h" +#endif + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +void verify() { + int width = 640, height = 480; + unsigned char *data = (unsigned char*)malloc(width*height*4); + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); + int sum = 0; + for (int x = 0; x < width*height*4; x++) { + if (x % 4 != 3) sum += x * data[x]; + } +#if EMSCRIPTEN + int result = sum; + REPORT_RESULT(); +#endif +} + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { + printf("Unable to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); + screen = SDL_SetVideoMode( 640, 480, 24, SDL_OPENGL ); + if ( !screen ) { + printf("Unable to set video mode: %s\n", SDL_GetError()); + return 1; + } + + glClearColor( 0, 0, 0, 0 ); + glClear( GL_COLOR_BUFFER_BIT ); + + // Create a texture + + GLuint texture; + glGenTextures( 1, &texture ); + glBindTexture( GL_TEXTURE_2D, texture ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + GLubyte textureData[16*16*4]; + for (int x = 0; x < 16; x++) { + for (int y = 0; y < 16; y++) { + *((int*)&textureData[(x*16 + y) * 4]) = x*16 + ((y*16) << 8); + } + } + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, + GL_RGBA, GL_UNSIGNED_BYTE, textureData ); + + // Create a second texture + + GLuint texture2; + glGenTextures( 1, &texture2 ); + glBindTexture( GL_TEXTURE_2D, texture2 ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + GLubyte texture2Data[] = { 0xff, 0, 0, 0xff, + 0, 0xff, 0, 0xaa, + 0, 0, 0xff, 0x55, + 0x80, 0x90, 0x70, 0 }; + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, + GL_RGBA, GL_UNSIGNED_BYTE, texture2Data ); + + // BEGIN + +#if USE_GLEW + glewInit(); +#endif + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + // original: glFrustum(-0.6435469817188064, 0.6435469817188064 ,-0.48266022190470925, 0.48266022190470925 ,0.5400000214576721, 2048); + //glFrustum(-0.6435469817188064, 0.1435469817188064 ,-0.48266022190470925, 0.88266022190470925 ,0.5400000214576721, 2048); + GLfloat pm[] = { 1.372136116027832, 0, 0, 0, 0, 0.7910231351852417, 0, 0, -0.6352481842041016, 0.29297152161598206, -1.0005275011062622, -1, 0, 0, -1.080284833908081, 0 }; + glLoadMatrixf(pm); + + glMatrixMode(GL_MODELVIEW); + GLfloat matrixData[] = { -1, 0, 0, 0, + 0, 0,-1, 0, + 0, 1, 0, 0, + 0, 0, 0, 1 }; + glLoadMatrixf(matrixData); + + glActiveTexture(GL_TEXTURE0); + + GLuint arrayBuffer, elementBuffer; + glGenBuffers(1, &arrayBuffer); + glGenBuffers(1, &elementBuffer); + + GLubyte arrayData[] = { +/* +[0, 0, 0, 67] ==> 128 float +[0, 0, 128, 67] ==> 256 float +[0, 0, 0, 68] ==> 512 float +[0, 0, 128, 68] ==> 1024 float + +[vertex x ] [vertex y ] [vertex z ] [nr] [texture u ] [texture v ] [lm u ] [lm v ] [color r,g,b,a ] */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 0 + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 1 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 2 + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 3 + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 4 + 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 5 + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 6 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 7 + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 8 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 9 + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 10 + 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 11 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 12 + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 13 + 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 14 + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 15 + + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128 + }; + assert(sizeof(arrayData) == 1408); + glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(arrayData), arrayData, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + GLushort elementData[] = { 1, 2, 0, 2, 3, 0, 5, 6, 4, 6, 7, 4, 9, 10, 8, 10, 11, 8, 13, 14, 12, 14, 15, 12 }; + assert(sizeof(elementData) == 48); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elementData), elementData, GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer); + + glBindTexture(GL_TEXTURE_2D, texture); // diffuse? + glActiveTexture(GL_TEXTURE0); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, texture2); // lightmap? + glActiveTexture(GL_TEXTURE0); + + GLint ok; + + const char *vertexShader = "attribute vec4 a_position;\n" + "attribute vec4 a_texCoord0;\n" + "uniform mat4 u_modelView;\n" + "uniform mat4 u_projection;\n" + "varying vec4 v_texCoord0;\n" + "void main(void)\n" + "{\n" + " gl_Position = (u_projection * u_modelView * a_position) + vec4(200, 0, 0, 0);\n" + " v_texCoord0.xy = a_texCoord0.xy/20.0;\n" // added /20 here + "}\n"; + const char *fragmentShader = "uniform sampler2D diffusemap;\n" + "varying vec4 v_texCoord0;\n" + "void main(void)\n" + "{\n" + " vec4 diffuse = texture2D(diffusemap, v_texCoord0.xy);\n" + " gl_FragColor = diffuse;\n" + "}\n"; + + GLuint vs = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vs, 1, &vertexShader, NULL); + glCompileShader(vs); + glGetShaderiv(vs, GL_COMPILE_STATUS, &ok); + if (!ok) { + printf("Shader compilation error with vertex\n"); + GLint infoLen = 0; + glGetShaderiv (vs, GL_INFO_LOG_LENGTH, &infoLen); + if (infoLen > 1) + { + char* infoLog = (char *)malloc(sizeof(char) * infoLen+1); + glGetShaderInfoLog(vs, infoLen, NULL, infoLog); + printf("Error compiling shader:\n%s\n", infoLog); + } + } + + GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fs, 1, &fragmentShader, NULL); + glCompileShader(fs); + glGetShaderiv(fs, GL_COMPILE_STATUS, &ok); + if (!ok) { + printf("Shader compilation error with fragment\n"); + GLint infoLen = 0; + glGetShaderiv (vs, GL_INFO_LOG_LENGTH, &infoLen); + if (infoLen > 1) + { + char* infoLog = (char *)malloc(sizeof(char) * infoLen+1); + glGetShaderInfoLog(vs, infoLen, NULL, infoLog); + printf("Error compiling shader:\n%s\n", infoLog); + } + } + + GLuint program = glCreateProgram(); + + glAttachShader(program, vs); + glAttachShader(program, fs); + glLinkProgram(program); + glGetProgramiv(program, GL_LINK_STATUS, &ok); + assert(ok); + + glUseProgram(program); + + GLint diffusemapLocation = glGetUniformLocation(program, "diffusemap"); + assert(diffusemapLocation >= 0); + glUniform1i(diffusemapLocation, 0); + + { + GLfloat data[16]; + glGetFloatv(GL_MODELVIEW_MATRIX, data); + printf("Modelview: "); + for (int i = 0; i < 16; i++) printf("%.3f, ", data[i]); + printf("\n"); + GLint modelViewLocation = glGetUniformLocation(program, "u_modelView"); + assert(modelViewLocation >= 0); + glUniformMatrix4fv(modelViewLocation, 1, GL_FALSE, data); + } + { + GLfloat data[16]; + glGetFloatv(GL_PROJECTION_MATRIX, data); + printf("Projection: "); + for (int i = 0; i < 16; i++) printf("%.3f, ", data[i]); + printf("\n"); + GLint projectionLocation = glGetUniformLocation(program, "u_projection"); + assert(projectionLocation >= 0); + glUniformMatrix4fv(projectionLocation, 1, GL_FALSE, data); + } + + glBindAttribLocation(program, 0, "a_position"); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 32, (void*)0); + glEnableVertexAttribArray(0); + + glBindAttribLocation(program, 1, "a_texCoord0"); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 32, (void*)16); + glEnableVertexAttribArray(1); + + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)12); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*) 0); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)24); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)36); + + // END + + SDL_GL_SwapBuffers(); + + verify(); + +#if !EMSCRIPTEN + SDL_Delay(1500); +#endif + + SDL_Quit(); + + return 0; +} diff --git a/tests/cubegeom_pre2.c b/tests/cubegeom_pre2.c new file mode 100644 index 00000000..ae8dcf9f --- /dev/null +++ b/tests/cubegeom_pre2.c @@ -0,0 +1,348 @@ +/* +THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION +AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN. + +THE ORIGINAL AUTHOR IS KYLE FOLEY. + +THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY +OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF +MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, +ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE +RESULTING FROM THE USE, MODIFICATION, OR +REDISTRIBUTION OF THIS SOFTWARE. +*/ + +#if !EMSCRIPTEN +#define USE_GLEW 1 +#endif + +#if USE_GLEW +#include "GL/glew.h" +#endif + +#include "SDL/SDL.h" +#if !USE_GLEW +#include "SDL/SDL_opengl.h" +#endif + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +void verify() { + int width = 640, height = 480; + unsigned char *data = (unsigned char*)malloc(width*height*4); + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); + int sum = 0; + for (int x = 0; x < width*height*4; x++) { + if (x % 4 != 3) sum += x * data[x]; + } +#if EMSCRIPTEN + int result = sum; + REPORT_RESULT(); +#endif +} + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { + printf("Unable to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); + screen = SDL_SetVideoMode( 640, 480, 24, SDL_OPENGL ); + if ( !screen ) { + printf("Unable to set video mode: %s\n", SDL_GetError()); + return 1; + } + + glClearColor( 0, 0, 0, 0 ); + glClear( GL_COLOR_BUFFER_BIT ); + + // Create a texture + + GLuint texture; + glGenTextures( 1, &texture ); + glBindTexture( GL_TEXTURE_2D, texture ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + GLubyte textureData[16*16*4]; + for (int x = 0; x < 16; x++) { + for (int y = 0; y < 16; y++) { + *((int*)&textureData[(x*16 + y) * 4]) = x*16 + ((y*16) << 8); + } + } + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, + GL_RGBA, GL_UNSIGNED_BYTE, textureData ); + + // Create a second texture + + GLuint texture2; + glGenTextures( 1, &texture2 ); + glBindTexture( GL_TEXTURE_2D, texture2 ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + GLubyte texture2Data[] = { 0xff, 0, 0, 0xff, + 0, 0xff, 0, 0xaa, + 0, 0, 0xff, 0x55, + 0x80, 0x90, 0x70, 0 }; + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, + GL_RGBA, GL_UNSIGNED_BYTE, texture2Data ); + + // BEGIN + +#if USE_GLEW + glewInit(); +#endif + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + // original: glFrustum(-0.6435469817188064, 0.6435469817188064 ,-0.48266022190470925, 0.48266022190470925 ,0.5400000214576721, 2048); + //glFrustum(-0.6435469817188064, 0.1435469817188064 ,-0.48266022190470925, 0.88266022190470925 ,0.5400000214576721, 2048); + GLfloat pm[] = { 1.372136116027832, 0, 0, 0, 0, 0.7910231351852417, 0, 0, -0.6352481842041016, 0.29297152161598206, -1.0005275011062622, -1, 0, 0, -1.080284833908081, 0 }; + glLoadMatrixf(pm); + + glMatrixMode(GL_MODELVIEW); + GLfloat matrixData[] = { -1, 0, 0, 0, + 0, 0,-1, 0, + 0, 1, 0, 0, + 0, 0, 0, 1 }; + glLoadMatrixf(matrixData); + //glTranslated(-512,-512,-527); // XXX this should be uncommented, but if it is then nothing is shown + +// glEnable(GL_CULL_FACE); + // glEnable(GL_DEPTH_TEST); + + //glClear(GL_DEPTH_BUFFER_BIT); + +// glEnableClientState(GL_NORMAL_ARRAY); + // glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glActiveTexture(GL_TEXTURE0); + + glEnableClientState(GL_VERTEX_ARRAY); + + GLuint arrayBuffer, elementBuffer; + glGenBuffers(1, &arrayBuffer); + glGenBuffers(1, &elementBuffer); + + GLubyte arrayData[] = { +/* +[0, 0, 0, 67] ==> 128 float +[0, 0, 128, 67] ==> 256 float +[0, 0, 0, 68] ==> 512 float +[0, 0, 128, 68] ==> 1024 float + +[vertex x ] [vertex y ] [vertex z ] [nr] [texture u ] [texture v ] [lm u ] [lm v ] [color r,g,b,a ] */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 0 + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 1 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 2 + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 3 + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 4 + 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 5 + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 6 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 7 + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 8 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 9 + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 10 + 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 11 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 12 + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 13 + 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 14 + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 15 + + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128 + }; + assert(sizeof(arrayData) == 1408); + glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(arrayData), arrayData, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + GLushort elementData[] = { 1, 2, 0, 2, 3, 0, 5, 6, 4, 6, 7, 4, 9, 10, 8, 10, 11, 8, 13, 14, 12, 14, 15, 12 }; + assert(sizeof(elementData) == 48); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elementData), elementData, GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer); + + // sauer vertex data is apparently 0-12: V3F, 12: N1B, 16-24: T2F, 24-28: T2S, 28-32: C4B + glVertexPointer(3, GL_FLOAT, 32, (void*)0); // all these apply to the ARRAY_BUFFER that is bound + glTexCoordPointer(2, GL_FLOAT, 32, (void*)16); +// glClientActiveTexture(GL_TEXTURE1); // XXX seems to be ignored in native build +// glTexCoordPointer(2, GL_SHORT, 32, (void*)24); +// glClientActiveTexture(GL_TEXTURE0); // likely not needed, it is a cleanup +// glNormalPointer(GL_BYTE, 32, (void*)12); +// glColorPointer(4, GL_UNSIGNED_BYTE, 32, (void*)28); + + glBindTexture(GL_TEXTURE_2D, texture); // diffuse? + glActiveTexture(GL_TEXTURE0); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, texture2); // lightmap? + glActiveTexture(GL_TEXTURE0); + + GLint ok; + + const char *vertexShader = "uniform mat4 u_modelView;\n" + "uniform mat4 u_projection;\n" + "varying vec4 v_texCoord0;\n" + "void main(void)\n" + "{\n" // (gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex) + // (u_projection * u_modelView * a_position) + " gl_Position = (u_projection * u_modelView * gl_Vertex) + vec4(200, 0, 0, 0);\n" + " v_texCoord0.xy = gl_MultiTexCoord0.xy/20.0;\n" // added /100 here + "}\n"; + const char *fragmentShader = "uniform sampler2D diffusemap;\n" + "varying vec4 v_texCoord0;\n" + "void main(void)\n" + "{\n" + " vec4 diffuse = texture2D(diffusemap, v_texCoord0.xy);\n" + " gl_FragColor = diffuse;\n" + "}\n"; + + GLuint vs = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vs, 1, &vertexShader, NULL); + glCompileShader(vs); + glGetShaderiv(vs, GL_COMPILE_STATUS, &ok); + if (!ok) { + printf("Shader compilation error with vertex\n"); + GLint infoLen = 0; + glGetShaderiv (vs, GL_INFO_LOG_LENGTH, &infoLen); + if (infoLen > 1) + { + char* infoLog = (char *)malloc(sizeof(char) * infoLen+1); + glGetShaderInfoLog(vs, infoLen, NULL, infoLog); + printf("Error compiling shader:\n%s\n", infoLog); + } + } + + GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fs, 1, &fragmentShader, NULL); + glCompileShader(fs); + glGetShaderiv(fs, GL_COMPILE_STATUS, &ok); + if (!ok) { + printf("Shader compilation error with fragment\n"); + GLint infoLen = 0; + glGetShaderiv (vs, GL_INFO_LOG_LENGTH, &infoLen); + if (infoLen > 1) + { + char* infoLog = (char *)malloc(sizeof(char) * infoLen+1); + glGetShaderInfoLog(vs, infoLen, NULL, infoLog); + printf("Error compiling shader:\n%s\n", infoLog); + } + } + + GLuint program = glCreateProgram(); + + glAttachShader(program, vs); + glAttachShader(program, fs); + glLinkProgram(program); + glGetProgramiv(program, GL_LINK_STATUS, &ok); + assert(ok); + + glUseProgram(program); + + //GLint lightmapLocation = glGetUniformLocation(program, "lightmap"); + //assert(lightmapLocation >= 0); + //glUniform1i(lightmapLocation, 1); // sampler2D? Is it the texture unit? + + GLint diffusemapLocation = glGetUniformLocation(program, "diffusemap"); + assert(diffusemapLocation >= 0); + glUniform1i(diffusemapLocation, 0); + + //GLint texgenscrollLocation = glGetUniformLocation(program, "texgenscroll"); + //assert(texgenscrollLocation >= 0); + + //GLint colorparamsLocation = glGetUniformLocation(program, "colorparams"); + //assert(colorparamsLocation >= 0); + + //GLfloat texgenscrollData[] = { 0, 0, 0, 0 }; + //glUniform4fv(texgenscrollLocation, 1, texgenscrollData); + + //GLfloat colorparamsData[] = { 2, 2, 2, 1 }; + //glUniform4fv(colorparamsLocation, 1, colorparamsData); + + { + GLfloat data[16]; + glGetFloatv(GL_MODELVIEW_MATRIX, data); + printf("Modelview: "); + for (int i = 0; i < 16; i++) printf("%.3f, ", data[i]); + printf("\n"); + //memset(data, 0, 16*4); + GLint modelViewLocation = glGetUniformLocation(program, "u_modelView"); + assert(modelViewLocation >= 0); + glUniformMatrix4fv(modelViewLocation, 1, GL_FALSE, data); + } + { + GLfloat data[16]; + glGetFloatv(GL_PROJECTION_MATRIX, data); + printf("Projection: "); + for (int i = 0; i < 16; i++) printf("%.3f, ", data[i]); + printf("\n"); + //memset(data, 0, 16*4); + GLint projectionLocation = glGetUniformLocation(program, "u_projection"); + assert(projectionLocation >= 0); + glUniformMatrix4fv(projectionLocation, 1, GL_FALSE, data); + } + +/* + glBindAttribLocation(program, 0, "a_position"); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 32, (void*)0); + glEnableVertexAttribArray(0); + + glBindAttribLocation(program, 1, "v_texCoord0"); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 32, (void*)16); + glEnableVertexAttribArray(1); +*/ + + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)12); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*) 0); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)24); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)36); + + // END + + SDL_GL_SwapBuffers(); + + verify(); + +#if !EMSCRIPTEN + SDL_Delay(1500); +#endif + + // SDL_Quit(); + + return 0; +} + diff --git a/tests/cubegeom_pre3.c b/tests/cubegeom_pre3.c new file mode 100644 index 00000000..a1f811b6 --- /dev/null +++ b/tests/cubegeom_pre3.c @@ -0,0 +1,348 @@ +/* +THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION +AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN. + +THE ORIGINAL AUTHOR IS KYLE FOLEY. + +THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY +OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF +MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, +ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE +RESULTING FROM THE USE, MODIFICATION, OR +REDISTRIBUTION OF THIS SOFTWARE. +*/ + +#if !EMSCRIPTEN +#define USE_GLEW 1 +#endif + +#if USE_GLEW +#include "GL/glew.h" +#endif + +#include "SDL/SDL.h" +#if !USE_GLEW +#include "SDL/SDL_opengl.h" +#endif + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +void verify() { + int width = 640, height = 480; + unsigned char *data = (unsigned char*)malloc(width*height*4); + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); + int sum = 0; + for (int x = 0; x < width*height*4; x++) { + if (x % 4 != 3) sum += x * data[x]; + } +#if EMSCRIPTEN + int result = sum; + REPORT_RESULT(); +#endif +} + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { + printf("Unable to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); + screen = SDL_SetVideoMode( 640, 480, 24, SDL_OPENGL ); + if ( !screen ) { + printf("Unable to set video mode: %s\n", SDL_GetError()); + return 1; + } + + glClearColor( 0, 0, 0, 0 ); + glClear( GL_COLOR_BUFFER_BIT ); + + // Create a texture + + GLuint texture; + glGenTextures( 1, &texture ); + glBindTexture( GL_TEXTURE_2D, texture ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + GLubyte textureData[16*16*4]; + for (int x = 0; x < 16; x++) { + for (int y = 0; y < 16; y++) { + *((int*)&textureData[(x*16 + y) * 4]) = x*16 + ((y*16) << 8); + } + } + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, + GL_RGBA, GL_UNSIGNED_BYTE, textureData ); + + // Create a second texture + + GLuint texture2; + glGenTextures( 1, &texture2 ); + glBindTexture( GL_TEXTURE_2D, texture2 ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + GLubyte texture2Data[] = { 0xff, 0, 0, 0xff, + 0, 0xff, 0, 0xaa, + 0, 0, 0xff, 0x55, + 0x80, 0x90, 0x70, 0 }; + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, + GL_RGBA, GL_UNSIGNED_BYTE, texture2Data ); + + // BEGIN + +#if USE_GLEW + glewInit(); +#endif + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + // original: glFrustum(-0.6435469817188064, 0.6435469817188064 ,-0.48266022190470925, 0.48266022190470925 ,0.5400000214576721, 2048); + glFrustum(-0.6435469817188064, 0.1435469817188064 ,-0.48266022190470925, 0.88266022190470925 ,0.5400000214576721, 2048); + //GLfloat pm[] = { 1.372136116027832, 0, 0, 0, 0, 0.7910231351852417, 0, 0, -0.6352481842041016, 0.29297152161598206, -1.0005275011062622, -1, 0, 0, -1.080284833908081, 0 }; + //glLoadMatrixf(pm); + + glMatrixMode(GL_MODELVIEW); + GLfloat matrixData[] = { -1, 0, 0, 0, + 0, 0,-1, 0, + 0, 1, 0, 0, + 0, 0, 0, 1 }; + glLoadMatrixf(matrixData); + //glTranslated(-512,-512,-527); // XXX this should be uncommented, but if it is then nothing is shown + + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + + glClear(GL_DEPTH_BUFFER_BIT); + + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glActiveTexture(GL_TEXTURE0); + + glEnableClientState(GL_VERTEX_ARRAY); + + GLuint arrayBuffer, elementBuffer; + glGenBuffers(1, &arrayBuffer); + glGenBuffers(1, &elementBuffer); + + GLubyte arrayData[] = { +/* +[0, 0, 0, 67] ==> 128 float +[0, 0, 128, 67] ==> 256 float +[0, 0, 0, 68] ==> 512 float +[0, 0, 128, 68] ==> 1024 float + +[vertex x ] [vertex y ] [vertex z ] [nr] [texture u ] [texture v ] [lm u ] [lm v ] [color r,g,b,a ] */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 0 + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 1 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 2 + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 3 + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 4 + 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 5 + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 6 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 7 + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 8 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 9 + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 10 + 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 11 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 12 + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 13 + 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 14 + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 15 + + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128 + }; + assert(sizeof(arrayData) == 1408); + glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(arrayData), arrayData, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + GLushort elementData[] = { 1, 2, 0, 2, 3, 0, 5, 6, 4, 6, 7, 4, 9, 10, 8, 10, 11, 8, 13, 14, 12, 14, 15, 12 }; + assert(sizeof(elementData) == 48); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elementData), elementData, GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer); + + // sauer vertex data is apparently 0-12: V3F, 12: N1B, 16-24: T2F, 24-28: T2S, 28-32: C4B + glVertexPointer(3, GL_FLOAT, 32, (void*)0); // all these apply to the ARRAY_BUFFER that is bound + glTexCoordPointer(2, GL_FLOAT, 32, (void*)16); + glClientActiveTexture(GL_TEXTURE1); // XXX seems to be ignored in native build + glTexCoordPointer(2, GL_SHORT, 32, (void*)24); + glClientActiveTexture(GL_TEXTURE0); // likely not needed, it is a cleanup + glNormalPointer(GL_BYTE, 32, (void*)12); + glColorPointer(4, GL_UNSIGNED_BYTE, 32, (void*)28); + + glBindTexture(GL_TEXTURE_2D, texture); // diffuse? + glActiveTexture(GL_TEXTURE0); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, texture2); // lightmap? + glActiveTexture(GL_TEXTURE0); + + GLint ok; + + const char *vertexShader = "uniform mat4 u_modelView;\n" + "uniform mat4 u_projection;\n" + "varying vec4 v_texCoord0;\n" + "void main(void)\n" + "{\n" // (gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex) + // (u_projection * u_modelView * a_position) + " gl_Position = (u_projection * u_modelView * gl_Vertex) + vec4(200, 0, 0, 0);\n" + " v_texCoord0.xy = gl_MultiTexCoord0.xy/20.0;\n" // added /100 here + "}\n"; + const char *fragmentShader = "uniform sampler2D diffusemap;\n" + "varying vec4 v_texCoord0;\n" + "void main(void)\n" + "{\n" + " vec4 diffuse = texture2D(diffusemap, v_texCoord0.xy);\n" + " gl_FragColor = diffuse;\n" + "}\n"; + + GLuint vs = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vs, 1, &vertexShader, NULL); + glCompileShader(vs); + glGetShaderiv(vs, GL_COMPILE_STATUS, &ok); + if (!ok) { + printf("Shader compilation error with vertex\n"); + GLint infoLen = 0; + glGetShaderiv (vs, GL_INFO_LOG_LENGTH, &infoLen); + if (infoLen > 1) + { + char* infoLog = (char *)malloc(sizeof(char) * infoLen+1); + glGetShaderInfoLog(vs, infoLen, NULL, infoLog); + printf("Error compiling shader:\n%s\n", infoLog); + } + } + + GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fs, 1, &fragmentShader, NULL); + glCompileShader(fs); + glGetShaderiv(fs, GL_COMPILE_STATUS, &ok); + if (!ok) { + printf("Shader compilation error with fragment\n"); + GLint infoLen = 0; + glGetShaderiv (vs, GL_INFO_LOG_LENGTH, &infoLen); + if (infoLen > 1) + { + char* infoLog = (char *)malloc(sizeof(char) * infoLen+1); + glGetShaderInfoLog(vs, infoLen, NULL, infoLog); + printf("Error compiling shader:\n%s\n", infoLog); + } + } + + GLuint program = glCreateProgram(); + + glAttachShader(program, vs); + glAttachShader(program, fs); + glLinkProgram(program); + glGetProgramiv(program, GL_LINK_STATUS, &ok); + assert(ok); + + glUseProgram(program); + + //GLint lightmapLocation = glGetUniformLocation(program, "lightmap"); + //assert(lightmapLocation >= 0); + //glUniform1i(lightmapLocation, 1); // sampler2D? Is it the texture unit? + + GLint diffusemapLocation = glGetUniformLocation(program, "diffusemap"); + assert(diffusemapLocation >= 0); + glUniform1i(diffusemapLocation, 0); + + //GLint texgenscrollLocation = glGetUniformLocation(program, "texgenscroll"); + //assert(texgenscrollLocation >= 0); + + //GLint colorparamsLocation = glGetUniformLocation(program, "colorparams"); + //assert(colorparamsLocation >= 0); + + //GLfloat texgenscrollData[] = { 0, 0, 0, 0 }; + //glUniform4fv(texgenscrollLocation, 1, texgenscrollData); + + //GLfloat colorparamsData[] = { 2, 2, 2, 1 }; + //glUniform4fv(colorparamsLocation, 1, colorparamsData); + + { + GLfloat data[16]; + glGetFloatv(GL_MODELVIEW_MATRIX, data); + printf("Modelview: "); + for (int i = 0; i < 16; i++) printf("%.3f, ", data[i]); + printf("\n"); + //memset(data, 0, 16*4); + GLint modelViewLocation = glGetUniformLocation(program, "u_modelView"); + assert(modelViewLocation >= 0); + glUniformMatrix4fv(modelViewLocation, 1, GL_FALSE, data); + } + { + GLfloat data[16]; + glGetFloatv(GL_PROJECTION_MATRIX, data); + printf("Projection: "); + for (int i = 0; i < 16; i++) printf("%.3f, ", data[i]); + printf("\n"); + //memset(data, 0, 16*4); + GLint projectionLocation = glGetUniformLocation(program, "u_projection"); + assert(projectionLocation >= 0); + glUniformMatrix4fv(projectionLocation, 1, GL_FALSE, data); + } + +/* + glBindAttribLocation(program, 0, "a_position"); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 32, (void*)0); + glEnableVertexAttribArray(0); + + glBindAttribLocation(program, 1, "v_texCoord0"); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 32, (void*)16); + glEnableVertexAttribArray(1); +*/ + + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)12); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*) 0); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)24); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)36); + + // END + + SDL_GL_SwapBuffers(); + + verify(); + +#if !EMSCRIPTEN + SDL_Delay(1500); +#endif + + // SDL_Quit(); + + return 0; +} + diff --git a/tests/cubegeom_texturematrix.c b/tests/cubegeom_texturematrix.c new file mode 100644 index 00000000..229bf2a8 --- /dev/null +++ b/tests/cubegeom_texturematrix.c @@ -0,0 +1,312 @@ +/* +THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION +AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN. + +THE ORIGINAL AUTHOR IS KYLE FOLEY. + +THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY +OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF +MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, +ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE +RESULTING FROM THE USE, MODIFICATION, OR +REDISTRIBUTION OF THIS SOFTWARE. +*/ + +#if !EMSCRIPTEN +#define USE_GLEW 1 +#endif + +#if USE_GLEW +#include "GL/glew.h" +#endif + +#include "SDL/SDL.h" +#if !USE_GLEW +#include "SDL/SDL_opengl.h" +#endif + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +void verify() { + int width = 640, height = 480; + unsigned char *data = (unsigned char*)malloc(width*height*4); + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); + int sum = 0; + for (int x = 0; x < width*height*4; x++) { + if (x % 4 != 3) sum += x * data[x]; + } +#if EMSCRIPTEN + int result = sum; + REPORT_RESULT(); +#endif +} + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { + printf("Unable to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); + screen = SDL_SetVideoMode( 640, 480, 24, SDL_OPENGL ); + if ( !screen ) { + printf("Unable to set video mode: %s\n", SDL_GetError()); + return 1; + } + + glClearColor( 0, 0, 0, 0 ); + glClear( GL_COLOR_BUFFER_BIT ); + + // Create a texture + + GLuint texture; + glGenTextures( 1, &texture ); + glBindTexture( GL_TEXTURE_2D, texture ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + GLubyte textureData[16*16*4]; + for (int x = 0; x < 16; x++) { + for (int y = 0; y < 16; y++) { + *((int*)&textureData[(x*16 + y) * 4]) = x*16 + ((y*16) << 8); + } + } + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, + GL_RGBA, GL_UNSIGNED_BYTE, textureData ); + + // Create a second texture + + GLuint texture2; + glGenTextures( 1, &texture2 ); + glBindTexture( GL_TEXTURE_2D, texture2 ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + GLubyte texture2Data[] = { 0xff, 0, 0, 0xff, + 0, 0xff, 0, 0xaa, + 0, 0, 0xff, 0x55, + 0x80, 0x90, 0x70, 0 }; + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, + GL_RGBA, GL_UNSIGNED_BYTE, texture2Data ); + + // BEGIN + +#if USE_GLEW + glewInit(); +#endif + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + // original: glFrustum(-0.6435469817188064, 0.6435469817188064 ,-0.48266022190470925, 0.48266022190470925 ,0.5400000214576721, 2048); + glFrustum(-0.6435469817188064, 0.1435469817188064 ,-0.48266022190470925, 0.88266022190470925 ,0.5400000214576721, 2048); + glRotatef(-30, 1, 1, 1); + //GLfloat pm[] = { 1.372136116027832, 0, 0, 0, 0, 0.7910231351852417, 0, 0, -0.6352481842041016, 0.29297152161598206, -1.0005275011062622, -1, 0, 0, -1.080284833908081, 0 }; + //glLoadMatrixf(pm); + + glMatrixMode(GL_MODELVIEW); + GLfloat matrixData[] = { -1, 0, 0, 0, + 0, 0,-1, 0, + 0, 1, 0, 0, + 0, 0, 0, 1 }; + glLoadMatrixf(matrixData); + + glActiveTexture(GL_TEXTURE0); // TODO: try 1 + glMatrixMode(GL_TEXTURE); + GLfloat tm[] = { 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5 }; + glLoadMatrixf(tm); + + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + + glClear(GL_DEPTH_BUFFER_BIT); + + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glActiveTexture(GL_TEXTURE0); + + glEnableClientState(GL_VERTEX_ARRAY); + + GLuint arrayBuffer, elementBuffer; + glGenBuffers(1, &arrayBuffer); + glGenBuffers(1, &elementBuffer); + + GLubyte arrayData[] = { +/* +[0, 0, 0, 67] ==> 128 float +[0, 0, 128, 67] ==> 256 float +[0, 0, 0, 68] ==> 512 float +[0, 0, 128, 68] ==> 1024 float + +[vertex x ] [vertex y ] [vertex z ] [nr] [texture u ] [texture v ] [lm u ] [lm v ] [color r,g,b,a ] */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 128, 255, 128, // 0 + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 255, 128, // 1 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 64, 255, 128, // 2 + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 255, 255, // 3 + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 196, 128, 255, 128, // 4 + 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 255, 128, // 5 + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 255, 128, // 6 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 64, 255, 0, // 7 + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 64, 128, 255, 128, // 8 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 0, 255, 128, // 9 + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 255, 128, // 10 + 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 255, 0, // 11 + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 100, 128, 255, 128, // 12 + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 0, 255, 128, // 13 + 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 255, 128, // 14 + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 255, 0, // 15 + + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128 + }; + assert(sizeof(arrayData) == 1408); + glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(arrayData), arrayData, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + GLushort elementData[] = { 1, 2, 0, 2, 3, 0, 5, 6, 4, 6, 7, 4, 9, 10, 8, 10, 11, 8, 13, 14, 12, 14, 15, 12 }; + assert(sizeof(elementData) == 48); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elementData), elementData, GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer); + + // sauer vertex data is apparently 0-12: V3F, 12: N1B, 16-24: T2F, 24-28: T2S, 28-32: C4B + glVertexPointer(3, GL_FLOAT, 32, (void*)0); // all these apply to the ARRAY_BUFFER that is bound + glTexCoordPointer(2, GL_FLOAT, 32, (void*)16); + glClientActiveTexture(GL_TEXTURE1); // XXX seems to be ignored in native build + glTexCoordPointer(2, GL_SHORT, 32, (void*)24); + glClientActiveTexture(GL_TEXTURE0); // likely not needed, it is a cleanup + glNormalPointer(GL_BYTE, 32, (void*)12); + glColorPointer(4, GL_UNSIGNED_BYTE, 32, (void*)28); + + glBindTexture(GL_TEXTURE_2D, texture); // diffuse? + glActiveTexture(GL_TEXTURE0); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, texture2); // lightmap? + glActiveTexture(GL_TEXTURE0); + + GLint ok; + + const char *vertexShader = "uniform vec4 texgenscroll;\n" + "void main(void)\n" + "{\n" + " gl_Position = gl_TextureMatrix[0] * ftransform();\n" + " gl_TexCoord[0].xy = gl_MultiTexCoord0.xy/100.0 + texgenscroll.xy;\n" // added /100 here + " gl_TexCoord[1] = gl_Color;\n" + "}\n"; + const char *fragmentShader = "uniform vec4 colorparams;\n" + "uniform sampler2D diffusemap, lightmap;\n" + "void main(void)\n" + "{\n" + " vec4 diffuse = texture2D(diffusemap, gl_TexCoord[0].xy);\n" + " vec4 lm = texture2D(lightmap, gl_TexCoord[1].xy);\n" + " diffuse *= colorparams;\n" + " gl_FragColor = (diffuse * lm * 0.2) + gl_TexCoord[1];\n" + "}\n"; + + GLuint vs = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vs, 1, &vertexShader, NULL); + glCompileShader(vs); + glGetShaderiv ( vs, GL_COMPILE_STATUS, &ok ); + if ( !ok ) + { + GLint infoLen = 0; + glGetShaderiv ( vs, GL_INFO_LOG_LENGTH, &infoLen ); + if ( infoLen > 1 ) + { + char* infoLog = (char*)malloc (sizeof(char) * infoLen ); + glGetShaderInfoLog ( vs, infoLen, NULL, infoLog ); + printf ( "Error compiling shader:\n%s\n", infoLog ); + free ( infoLog ); + } + glDeleteShader ( vs ); + return 0; + } + + GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fs, 1, &fragmentShader, NULL); + glCompileShader(fs); + glGetShaderiv(fs, GL_COMPILE_STATUS, &ok); + assert(ok); + + GLuint program = glCreateProgram(); + + glAttachShader(program, vs); + glAttachShader(program, fs); + glLinkProgram(program); + glGetProgramiv(program, GL_LINK_STATUS, &ok); + assert(ok); + + glUseProgram(program); + + GLint lightmapLocation = glGetUniformLocation(program, "lightmap"); + assert(lightmapLocation >= 0); + glUniform1i(lightmapLocation, 1); // sampler2D? Is it the texture unit? + + GLint diffusemapLocation = glGetUniformLocation(program, "diffusemap"); + assert(diffusemapLocation >= 0); + glUniform1i(diffusemapLocation, 0); + + GLint texgenscrollLocation = glGetUniformLocation(program, "texgenscroll"); + assert(texgenscrollLocation >= 0); + + GLint colorparamsLocation = glGetUniformLocation(program, "colorparams"); + assert(colorparamsLocation >= 0); + + GLfloat texgenscrollData[] = { 0, 0, 0, 0 }; + glUniform4fv(texgenscrollLocation, 1, texgenscrollData); + + GLfloat colorparamsData[] = { 2, 2, 2, 1 }; + glUniform4fv(colorparamsLocation, 1, colorparamsData); + + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)12); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*) 0); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)24); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)36); + + // END + + SDL_GL_SwapBuffers(); + + verify(); + +#if !EMSCRIPTEN + SDL_Delay(1500); +#endif + + SDL_Quit(); + + return 0; +} diff --git a/tests/emscripten_api_browser.cpp b/tests/emscripten_api_browser.cpp new file mode 100644 index 00000000..20e2dbb5 --- /dev/null +++ b/tests/emscripten_api_browser.cpp @@ -0,0 +1,68 @@ +#include<stdio.h> +#include<math.h> +#include<stdlib.h> +#include<SDL.h> +#include<emscripten.h> +#include<assert.h> + +int last = 0; + +extern "C" { + +bool fived = false; +void five() { + fived = true; + emscripten_resume_main_loop(); +} + +void mainey() { + static int counter = 0; + printf("mainey: %d\n", counter++); + if (counter == 20) { + emscripten_pause_main_loop(); + emscripten_async_call(five, 1000); + } else if (counter == 22) { // very soon after 20, so without pausing we fail + int result = fived; + REPORT_RESULT(); + } +} + +void four() { + printf("four!\n"); + emscripten_set_main_loop(mainey, 0); +} + +void __attribute__((used)) third() { + int now = SDL_GetTicks(); + printf("thard! %d\n", now); + assert(fabs(now - last - 1000) < 500); + emscripten_async_call(four, -1); // triggers requestAnimationFrame +} + +void second() { + int now = SDL_GetTicks(); + printf("sacond! %d\n", now); + assert(fabs(now - last - 500) < 250); + last = now; + emscripten_async_run_script("_third()", 1000); +} + +} + +void never() { + int result = 0; + REPORT_RESULT(); +} + +int main() { + SDL_Init(0); + last = SDL_GetTicks(); + printf("frist! %d\n", last); + + atexit(never); // should never be called - it is wrong to exit the runtime orderly if we have async calls! + + emscripten_async_call(second, 500); + + return 1; +} + diff --git a/tests/emscripten_fs_api_browser.cpp b/tests/emscripten_fs_api_browser.cpp new file mode 100644 index 00000000..07469f34 --- /dev/null +++ b/tests/emscripten_fs_api_browser.cpp @@ -0,0 +1,69 @@ +#include<stdio.h> +#include<emscripten.h> +#include<assert.h> +#include <string.h> + +extern "C" { + +int result = 1; +int get_count = 0; + +void wait_wgets() { + if (get_count == 2) { + emscripten_cancel_main_loop(); + REPORT_RESULT(); + } +} + +void onLoaded(const char* file) { + if (strcmp(file, "/tmp/test.html")) { + result = 0; + } + + printf("loaded: %s\n", file); + + if (FILE * f = fopen(file, "r")) { + printf("exists: %s\n", file); + int c = fgetc (f); + if (c == EOF) { + printf("file empty: %s\n", file); + result = 0; + } + fclose(f); + } else { + result = 0; + printf("!exists: %s\n", file); + } + + get_count++; +} + +void onError(const char* file) { + if (strcmp(file, "/tmp/null")) { + result = 0; + } + + printf("error: %s\n", file); + get_count++; +} + +int main() { + emscripten_async_wget( + "http://localhost:8888/this_is_not_a_file", + "/tmp/null", + onLoaded, + onError); + + emscripten_async_wget( + "http://localhost:8888/test.html", + "/tmp/test.html", + onLoaded, + onError); + + emscripten_set_main_loop(wait_wgets, 0); + + return 0; +} + +} + diff --git a/tests/fcntl/src.c b/tests/fcntl/src.c index 5b40ec79..c8c71c8a 100644 --- a/tests/fcntl/src.c +++ b/tests/fcntl/src.c @@ -45,7 +45,7 @@ int main() { printf("\n"); errno = 0; - flock lk; + struct flock lk; lk.l_type = 42; printf("F_GETLK: %d\n", fcntl(f, F_GETLK, &lk)); printf("errno: %d\n", errno); diff --git a/tests/float_tex.cpp b/tests/float_tex.cpp new file mode 100644 index 00000000..475f2bee --- /dev/null +++ b/tests/float_tex.cpp @@ -0,0 +1,136 @@ +#define GL_GLEXT_PROTOTYPES +#define EGL_EGLEXT_PROTOTYPES +#include <cmath> +#include <iostream> +#include <vector> +extern "C" { +#include <GL/gl.h> +#include <GL/glut.h> +} +static const char vertex_shader[] = + "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "attribute float indices;\n" + "uniform sampler2D nodeInfo;\n" + "varying vec4 color;" + "\n" + "void main(void)\n" + "{\n" + " float s = (indices + 0.5) / 512.; \n" + " vec4 v = texture2D(nodeInfo, vec2( s, 0.5));\n" + " gl_Position = vec4(v.x, v.y, 0.5, 1.);\n" + " gl_PointSize = v.z;\n" + " color = vec4(0.5 + v.w/2., 0.5 + 0.5 * v.w/2., 0.5, 1);\n" + "}\n"; +static const char fragment_shader[] = + "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "\n" + "varying vec4 color;\n" + "void main(void)\n" + "{\n" + " float dst = distance(vec2(0.5, 0.5), gl_PointCoord); \n" + " gl_FragColor = color;\n" + " if ( dst > 0.3) {" + " gl_FragColor = vec4(0., 0., 0.5, 0.2);\n" + "}\n" + "if ( dst > 0.5) discard;\n" + "}"; +struct NodeInfo { //structure that we want to transmit to our shaders + float x; + float y; + float s; + float c; +}; +GLuint nodeTexture; //texture id used to bind +GLuint nodeSamplerLocation; //shader sampler address +GLuint indicesAttributeLocation; //shader attribute address +GLuint indicesVBO; //Vertex Buffer Object Id; +const int nbNodes = 512; +NodeInfo * data = new NodeInfo[nbNodes]; //our data that will be transmitted using float texture. +double alpha = 0; //use to make a simple funny effect; +static void updateFloatTexture() { + int count = 0; + for (float x=0; x < nbNodes; ++x ) { + data[count].x = 0.2*pow(cos(alpha), 3) + (sin(alpha)*3. + 3.5) * x/nbNodes * cos(alpha + x/nbNodes * 16. * M_PI); + data[count].y = 0.2*pow(sin(alpha), 3) + (sin(alpha)*3. + 3.5) * x/nbNodes * sin(alpha + x/nbNodes * 16. * M_PI); + data[count].s = (16. + 16. * cos(alpha + x/nbNodes * 32. * M_PI)) + 8.;// * fmod(x/nbNodes + alpha, 1.) + 5.; + data[count].c = 0.5 + 0.5 * sin(alpha + x/nbNodes * 32. * M_PI); + ++count; + } + glBindTexture(GL_TEXTURE_2D, nodeTexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, nbNodes, 1, 0, GL_RGBA, GL_FLOAT, data); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glBindTexture(GL_TEXTURE_2D, NULL); + alpha -= 0.001; +} +static void glut_draw_callback(void) { + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glClearColor(1., 1., 1., 0.); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glActiveTexture(GL_TEXTURE0); + updateFloatTexture(); //we change the texture each time to create the effect (it is just for the test) + glBindTexture(GL_TEXTURE_2D, nodeTexture); + glUniform1i(nodeSamplerLocation, GL_TEXTURE0); + glEnableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, indicesVBO); + glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL); + glDrawArrays(GL_POINTS, 0, nbNodes); + glutSwapBuffers(); +} +GLuint createShader(const char source[], int type) { + char msg[512]; + GLuint shader = glCreateShader(type); + glShaderSource(shader, 1, (const GLchar**)(&source), NULL); + glCompileShader(shader); + glGetShaderInfoLog(shader, sizeof msg, NULL, msg); + std::cout << "Shader info: " << msg << std::endl; + return shader; +} +static void gl_init(void) { + GLuint program = glCreateProgram(); + glAttachShader(program, createShader(vertex_shader , GL_VERTEX_SHADER)); + glAttachShader(program, createShader(fragment_shader, GL_FRAGMENT_SHADER)); + glLinkProgram(program); + char msg[512]; + glGetProgramInfoLog(program, sizeof msg, NULL, msg); + std::cout << "info: " << msg << std::endl; + glUseProgram(program); + std::vector<float> elements(nbNodes); + int count = 0; + for (float x=0; x < nbNodes; ++x ) { + elements[count] = count; + ++count; + } + /*Create one texture to store all the needed information */ + glGenTextures(1, &nodeTexture); + /* Store the vertices in a vertex buffer object (VBO) */ + glGenBuffers(1, &indicesVBO); + glBindBuffer(GL_ARRAY_BUFFER, indicesVBO); + glBufferData(GL_ARRAY_BUFFER, elements.size() * sizeof(uint), &elements[0], GL_STATIC_DRAW); + /* Get the locations of the uniforms so we can access them */ + nodeSamplerLocation = glGetUniformLocation(program, "nodeInfo"); + glBindAttribLocation(program, 0, "indices"); + //Enable glPoint size in shader, always enable in Open Gl ES 2. + glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); + glEnable(GL_POINT_SPRITE); +} +int main(int argc, char *argv[]) { + glutInit(&argc, argv); + glutInitWindowSize(640, 480); + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); + glutCreateWindow("Simple FLOAT Texture Test"); + /* Set up glut callback functions */ + glutDisplayFunc(glut_draw_callback ); + gl_init(); + glutMainLoop(); + return 0; +} + + diff --git a/tests/float_tex.png b/tests/float_tex.png Binary files differnew file mode 100644 index 00000000..8c3c6502 --- /dev/null +++ b/tests/float_tex.png diff --git a/tests/gl_matrix_identity.c b/tests/gl_matrix_identity.c new file mode 100644 index 00000000..98b1c21f --- /dev/null +++ b/tests/gl_matrix_identity.c @@ -0,0 +1,129 @@ +/* +THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION +AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN. + +THE ORIGINAL AUTHOR IS KYLE FOLEY. + +THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY +OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF +MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, +ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE +RESULTING FROM THE USE, MODIFICATION, OR +REDISTRIBUTION OF THIS SOFTWARE. +*/ + +#if !EMSCRIPTEN +#define USE_GLEW 1 +#endif + +#if USE_GLEW +#include "GL/glew.h" +#endif + +#include "SDL/SDL.h" +#if !USE_GLEW +#include "SDL/SDL_opengl.h" +#endif + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +void verify() { + int width = 640, height = 480; + unsigned char *data = (unsigned char*)malloc(width*height*4); + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); + int sum = 0; + for (int x = 0; x < width*height*4; x++) { + if (x % 4 != 3) sum += x * data[x]; + } +#if EMSCRIPTEN + int result = sum; + REPORT_RESULT(); +#endif +} + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { + printf("Unable to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); + screen = SDL_SetVideoMode( 640, 480, 24, SDL_OPENGL ); + if ( !screen ) { + printf("Unable to set video mode: %s\n", SDL_GetError()); + return 1; + } + + // Create a texture + + GLuint texture; + glGenTextures( 1, &texture ); + glBindTexture( GL_TEXTURE_2D, texture ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); + GLubyte textureData[] = { 0x7f, 0, 0, + 0, 0xff, 0, + 0x7f, 0, 0, + 0, 0xff, 0}; + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, + GL_RGB, GL_UNSIGNED_BYTE, textureData ); + + + // BEGIN + +#if USE_GLEW + glewInit(); +#endif + + glClearColor( 0, 0, 0.5, 1.0 ); + glClear( GL_COLOR_BUFFER_BIT ); + + glColor4f(0.8, 0.8, 0.8, 1); + + glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + glEnable(GL_TEXTURE_2D); + glDisable(GL_BLEND); + + const int kRowSize = 20; + GLuint buffer; + glGenBuffers(1, &buffer); + glBindBuffer(GL_ARRAY_BUFFER, buffer); + float fbuf[] = {0, 1, 0, 0, 1, + 1, 1, 0, 1, 1, + 1, 0, 0, 1, 0, + 0, 1, 0, 0, 1, + 1, 0, 0, 1, 0, + 0, 0, 0, 0, 0}; + glBufferData(GL_ARRAY_BUFFER, sizeof(fbuf) * sizeof(float), fbuf, GL_STATIC_DRAW); + + glTexCoordPointer(2, GL_FLOAT, kRowSize, (GLvoid*)(3*4)); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glVertexPointer(3, GL_FLOAT, kRowSize, 0); + glEnableClientState(GL_VERTEX_ARRAY); + + glDrawArrays(GL_TRIANGLES, 0, 6); + + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + + // END + + SDL_GL_SwapBuffers(); + + verify(); + +#if !EMSCRIPTEN + SDL_Delay(1500); +#endif + + SDL_Quit(); + + return 0; +} diff --git a/tests/gl_ps.c b/tests/gl_ps.c new file mode 100644 index 00000000..81579c1d --- /dev/null +++ b/tests/gl_ps.c @@ -0,0 +1,230 @@ +/******************************************************************* + * * + * Using SDL With OpenGL * + * * + * Tutorial by Kyle Foley (sdw) * + * * + * http://gpwiki.org/index.php/SDL:Tutorials:Using_SDL_with_OpenGL * + * * + *******************************************************************/ + +/* +THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION +AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN. + +THE ORIGINAL AUTHOR IS KYLE FOLEY. + +THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY +OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF +MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, +ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE +RESULTING FROM THE USE, MODIFICATION, OR +REDISTRIBUTION OF THIS SOFTWARE. +*/ + +#if !EMSCRIPTEN +#define USE_GLEW 1 +#endif + +#if USE_GLEW +#include "GL/glew.h" +#endif + +#include "SDL/SDL.h" +#include "SDL/SDL_image.h" +#if !USE_GLEW +#include "SDL/SDL_opengl.h" +#endif + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +void shaders() { +#if USE_GLEW + glewInit(); +#endif + + GLint ok; + + const char *vertexShader = "void main(void) \n" + "{ \n" + " gl_Position = ftransform(); \n" + " gl_TexCoord[0] = gl_MultiTexCoord0; \n" + " gl_FrontColor = gl_Color; \n" + "} \n"; + const char *fragmentShader = "uniform sampler2D tex0; \n" + "void main(void) \n" + "{ \n" + " gl_FragColor = gl_Color * texture2D(tex0, gl_TexCoord[0].xy); \n" + "} \n"; + + GLuint vs = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vs, 1, &vertexShader, NULL); + glCompileShader(vs); + glGetShaderiv(vs, GL_COMPILE_STATUS, &ok); + assert(ok); + + GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fs, 1, &fragmentShader, NULL); + glCompileShader(fs); + glGetShaderiv(fs, GL_COMPILE_STATUS, &ok); + assert(ok); + + GLuint program = glCreateProgram(); + + glAttachShader(program, vs); + glAttachShader(program, fs); + glLinkProgram(program); + glGetProgramiv(program, GL_LINK_STATUS, &ok); + assert(ok); + + glUseProgram(program); + + { + // Also, check getting the error log + const char *fakeVertexShader = "atbute ve4 blarg; ### AAA\n"; + GLuint vs = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vs, 1, &fakeVertexShader, NULL); + glCompileShader(vs); + glGetShaderiv(vs, GL_COMPILE_STATUS, &ok); + assert(!ok); + GLint infoLen = 0; + glGetShaderiv(vs, GL_INFO_LOG_LENGTH, &infoLen); + assert(infoLen > 1); + } +} + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + + // Slightly different SDL initialization + if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { + printf("Unable to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // *new* + + screen = SDL_SetVideoMode( 640, 480, 16, SDL_OPENGL ); // *changed* + if ( !screen ) { + printf("Unable to set video mode: %s\n", SDL_GetError()); + return 1; + } + + // Set the OpenGL state after creating the context with SDL_SetVideoMode + + glClearColor( 0, 0, 0, 0 ); + +#if !EMSCRIPTEN + glEnable( GL_TEXTURE_2D ); // Need this to display a texture XXX unnecessary in OpenGL ES 2.0/WebGL +#endif + + glViewport( 0, 0, 640, 480 ); + + glMatrixMode( GL_PROJECTION ); + GLfloat matrixData[] = { 2.0/640, 0, 0, 0, + 0, -2.0/480, 0, 0, + 0, 0, -1, 0, + -1, 1, 0, 1 }; + glLoadMatrixf(matrixData); // test loadmatrix + + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + + // Load the OpenGL texture + + GLuint texture; // Texture object handle + SDL_Surface *surface; // Gives us the information to make the texture + + if ( (surface = IMG_Load("screenshot.png")) ) { + + // Check that the image's width is a power of 2 + if ( (surface->w & (surface->w - 1)) != 0 ) { + printf("warning: image.bmp's width is not a power of 2\n"); + } + + // Also check if the height is a power of 2 + if ( (surface->h & (surface->h - 1)) != 0 ) { + printf("warning: image.bmp's height is not a power of 2\n"); + } + + // Have OpenGL generate a texture object handle for us + glGenTextures( 1, &texture ); + + // Bind the texture object + glBindTexture( GL_TEXTURE_2D, texture ); + + // Set the texture's stretching properties + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + + //SDL_LockSurface(surface); + + // Add some greyness + memset(surface->pixels, 0x66, surface->w*surface->h); + + // Edit the texture object's image data using the information SDL_Surface gives us + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0, + GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels ); + + //SDL_UnlockSurface(surface); + } + else { + printf("SDL could not load image.bmp: %s\n", SDL_GetError()); + SDL_Quit(); + return 1; + } + + // Free the SDL_Surface only if it was successfully created + if ( surface ) { + SDL_FreeSurface( surface ); + } + + // Clear the screen before drawing + glClear( GL_COLOR_BUFFER_BIT ); + + shaders(); + + // Bind the texture to which subsequent calls refer to + glBindTexture( GL_TEXTURE_2D, texture ); + + // Use clientside vertex pointers to render two items + GLfloat vertexData[] = { 0, 0, 10, 10, // texture2, position2 + 1, 0, 300, 10, + 1, 1, 300, 128, + 0, 1, 10, 128, + 0, 0.5, 410, 10, + 1, 0.5, 600, 10, + 1, 1, 630, 200, + 0.5, 1, 310, 250, + 0, 0, 100, 300, + 1, 0, 300, 300, + 1, 1, 300, 400, + 0, 1, 100, 400 }; + + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, 4*4, &vertexData[0]); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 4*4, &vertexData[2]); + + glDrawArrays(GL_QUADS, 0, 12); + + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + + SDL_GL_SwapBuffers(); + +#if !EMSCRIPTEN + // Wait for 3 seconds to give us a chance to see the image + SDL_Delay(3000); +#endif + + // Now we can delete the OpenGL texture and close down SDL + glDeleteTextures( 1, &texture ); + + SDL_Quit(); + + return 0; +} diff --git a/tests/gl_ps.png b/tests/gl_ps.png Binary files differnew file mode 100644 index 00000000..185f7166 --- /dev/null +++ b/tests/gl_ps.png diff --git a/tests/glshaderinfo.cpp b/tests/glshaderinfo.cpp new file mode 100644 index 00000000..8ec393a8 --- /dev/null +++ b/tests/glshaderinfo.cpp @@ -0,0 +1,52 @@ +#define GL_GLEXT_PROTOTYPES +#define EGL_EGLEXT_PROTOTYPES + +#define _GNU_SOURCE + +#include <math.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <sys/time.h> +#include <unistd.h> +#ifdef __APPLE__ +#include <OpenGL/gl.h> +#include <Glut/glut.h> +#else +#include <GL/gl.h> +#include <GL/glut.h> +#endif + +#include <assert.h> +#include <emscripten.h> + +int main(int argc, char *argv[]) +{ + /* Initialize the window */ + glutInit(&argc, argv); + glutInitWindowSize(300, 300); + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); + + glutCreateWindow("es2gears"); + + GLint shaderCompiler; + glGetIntegerv(GL_SHADER_COMPILER, &shaderCompiler); + + GLint numShaderBinaryFormats; + glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &numShaderBinaryFormats); + + printf("%d,%d\n", shaderCompiler, numShaderBinaryFormats); + + if (!shaderCompiler && numShaderBinaryFormats == 0) { + printf("In current environment, the GLES2 implementation IS NOT standard conforming! " + "GL_SHADER_COMPILER == GL_FALSE and GL_NUM_SHADER_BINARY_FORMATS == 0! " + "In GLES2 spec, either compiling shaders or binary shaders must be supported! (Section 2.10 - Vertex Shaders)\n"); + int result = 0; + REPORT_RESULT(); + } else { + assert(numShaderBinaryFormats == 0); + int result = 1; + REPORT_RESULT(); + } + return 0; +} diff --git a/tests/hello_world_gles.c b/tests/hello_world_gles.c index 6f7a4324..78595a49 100644 --- a/tests/hello_world_gles.c +++ b/tests/hello_world_gles.c @@ -1,16 +1,16 @@ /* * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -23,7 +23,7 @@ * Ported to GLES2. * Kristian Høgsberg <krh@bitplanet.net> * May 3, 2010 - * + * * Improve GLES2 port: * * Refactor gear drawing. * * Use correct normals for surfaces. @@ -113,15 +113,15 @@ static GLfloat ProjectionMatrix[16]; /** The direction of the directional light for the scene */ static const GLfloat LightSourcePosition[4] = { 5.0, 5.0, 10.0, 1.0}; -/** +/** * Fills a gear vertex. - * + * * @param v the vertex to fill * @param x the x coordinate * @param y the y coordinate * @param z the z coortinate - * @param n pointer to the normal table - * + * @param n pointer to the normal table + * * @return the operation error code */ static GearVertex * @@ -139,13 +139,13 @@ vert(GearVertex *v, GLfloat x, GLfloat y, GLfloat z, GLfloat n[3]) /** * Create a gear wheel. - * + * * @param inner_radius radius of hole at center * @param outer_radius radius at center of teeth * @param width width of gear * @param teeth number of teeth * @param tooth_depth depth of tooth - * + * * @return pointer to the constructed struct gear */ static struct gear * @@ -289,11 +289,11 @@ create_gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, return gear; } -/** +/** * Multiplies two 4x4 matrices. - * + * * The result is stored in matrix m. - * + * * @param m the first matrix to multiply * @param n the second matrix to multiply */ @@ -316,9 +316,9 @@ multiply(GLfloat *m, const GLfloat *n) memcpy(m, &tmp, sizeof tmp); } -/** +/** * Rotates a 4x4 matrix. - * + * * @param[in,out] m the matrix to rotate * @param angle the angle to rotate * @param x the x component of the direction to rotate to @@ -333,7 +333,7 @@ rotate(GLfloat *m, GLfloat angle, GLfloat x, GLfloat y, GLfloat z) sincos(angle, &s, &c); GLfloat r[16] = { x * x * (1 - c) + c, y * x * (1 - c) + z * s, x * z * (1 - c) - y * s, 0, - x * y * (1 - c) - z * s, y * y * (1 - c) + c, y * z * (1 - c) + x * s, 0, + x * y * (1 - c) - z * s, y * y * (1 - c) + c, y * z * (1 - c) + x * s, 0, x * z * (1 - c) + y * s, y * z * (1 - c) - x * s, z * z * (1 - c) + c, 0, 0, 0, 0, 1 }; @@ -342,9 +342,9 @@ rotate(GLfloat *m, GLfloat angle, GLfloat x, GLfloat y, GLfloat z) } -/** +/** * Translates a 4x4 matrix. - * + * * @param[in,out] m the matrix to translate * @param x the x component of the direction to translate to * @param y the y component of the direction to translate to @@ -358,9 +358,9 @@ translate(GLfloat *m, GLfloat x, GLfloat y, GLfloat z) multiply(m, t); } -/** +/** * Creates an identity 4x4 matrix. - * + * * @param m the matrix make an identity matrix */ static void @@ -376,12 +376,12 @@ identity(GLfloat *m) memcpy(m, t, sizeof(t)); } -/** +/** * Transposes a 4x4 matrix. * * @param m the matrix to transpose */ -static void +static void transpose(GLfloat *m) { GLfloat t[16] = { @@ -420,9 +420,9 @@ invert(GLfloat *m) multiply(m, t); } -/** +/** * Calculate a perspective projection transformation. - * + * * @param m the matrix to save the transformation in * @param fovy the field of view in the y direction * @param aspect the view aspect ratio @@ -485,7 +485,7 @@ draw_gear(struct gear *gear, GLfloat *transform, glUniformMatrix4fv(ModelViewProjectionMatrix_location, 1, GL_FALSE, model_view_projection); - /* + /* * Create and set the NormalMatrix. It's the inverse transpose of the * ModelView matrix. */ @@ -520,7 +520,7 @@ draw_gear(struct gear *gear, GLfloat *transform, glDisableVertexAttribArray(0); } -/** +/** * Draws the gears. */ static void @@ -549,9 +549,9 @@ gears_draw(void) glutSwapBuffers(); } -/** +/** * Handles a new window size or exposure. - * + * * @param width the window width * @param height the window height */ @@ -565,9 +565,9 @@ gears_reshape(int width, int height) glViewport(0, 0, (GLint) width, (GLint) height); } -/** +/** * Handles special glut events. - * + * * @param special the event to handle. */ static void @@ -586,6 +586,9 @@ gears_special(int special, int crap, int morecrap) case GLUT_KEY_DOWN: view_rot[0] -= 5.0; break; + case GLUT_KEY_F11: + glutFullScreen(); + break; } } diff --git a/tests/msvc10/README.txt b/tests/msvc10/README.txt new file mode 100644 index 00000000..49a2a478 --- /dev/null +++ b/tests/msvc10/README.txt @@ -0,0 +1,5 @@ +This folder contains Visual Studio 2010 project files for Emscripten tests. + +Building the solution requires the vs-tool plugin, which enables Emscripten builds to be invoked from within Visual Studio. + +Find the vs-tool plugin from here https://github.com/juj/vs-tool diff --git a/tests/msvc10/dlmalloc_test.vcxproj b/tests/msvc10/dlmalloc_test.vcxproj new file mode 100644 index 00000000..087ff17f --- /dev/null +++ b/tests/msvc10/dlmalloc_test.vcxproj @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{A44C4C27-F173-47D0-8626-59A21D86AC1E}</ProjectGuid> + <RootNamespace>dlmalloc_test</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\dlmalloc_test.c" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/emscripten_api_browser.vcxproj b/tests/msvc10/emscripten_api_browser.vcxproj new file mode 100644 index 00000000..9f4a05fd --- /dev/null +++ b/tests/msvc10/emscripten_api_browser.vcxproj @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{65E0ED61-A813-4AEB-8DB0-A58657858EE2}</ProjectGuid> + <RootNamespace>emscripten_api_browser</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\emscripten_api_browser.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/fannkuch.vcxproj b/tests/msvc10/fannkuch.vcxproj new file mode 100644 index 00000000..9b325ea3 --- /dev/null +++ b/tests/msvc10/fannkuch.vcxproj @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{C29BBEE3-02D1-459A-B8BA-832A3439F12D}</ProjectGuid> + <RootNamespace>fannkuch</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\fannkuch.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/fasta.vcxproj b/tests/msvc10/fasta.vcxproj new file mode 100644 index 00000000..d0c10027 --- /dev/null +++ b/tests/msvc10/fasta.vcxproj @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{DDB7FF8E-EC42-4406-832C-F2B043D8760E}</ProjectGuid> + <RootNamespace>fasta</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\fasta.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/files.vcxproj b/tests/msvc10/files.vcxproj new file mode 100644 index 00000000..cba0f3a0 --- /dev/null +++ b/tests/msvc10/files.vcxproj @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{BE6A123E-9729-44A3-976F-3C06A3724894}</ProjectGuid> + <RootNamespace>files</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\files.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/glbook_10_MultiTexture.vcxproj b/tests/msvc10/glbook_10_MultiTexture.vcxproj new file mode 100644 index 00000000..b59fda0a --- /dev/null +++ b/tests/msvc10/glbook_10_MultiTexture.vcxproj @@ -0,0 +1,110 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{A2D564BE-34DE-43DC-B8F9-605CEF4BFC4B}</ProjectGuid> + <RootNamespace>glbook_10_MultiTexture</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <ClCompile> + <AdditionalIncludeDirectories>$(SolutionDir)../glbook/Common</AdditionalIncludeDirectories> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <ClCompile> + <AdditionalIncludeDirectories>$(SolutionDir)../glbook/Common</AdditionalIncludeDirectories> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <None Include="..\glbook\Chapter_10\MultiTexture\basemap.tga" /> + <None Include="..\glbook\Chapter_10\MultiTexture\lightmap.tga" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\glbook\Chapter_10\MultiTexture\MultiTexture.c" /> + <ClCompile Include="..\glbook\Common\esShader.c" /> + <ClCompile Include="..\glbook\Common\esShapes.c" /> + <ClCompile Include="..\glbook\Common\esTransform.c" /> + <ClCompile Include="..\glbook\Common\esUtil.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\glbook\Common\esUtil.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/glbook_11_Multisample.vcxproj b/tests/msvc10/glbook_11_Multisample.vcxproj new file mode 100644 index 00000000..ae5170be --- /dev/null +++ b/tests/msvc10/glbook_11_Multisample.vcxproj @@ -0,0 +1,106 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{AD9E59DF-1628-4081-8672-212A7103FAAD}</ProjectGuid> + <RootNamespace>glbook_11_Multisample</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <ClCompile> + <AdditionalIncludeDirectories>$(SolutionDir)../glbook/Common</AdditionalIncludeDirectories> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <ClCompile> + <AdditionalIncludeDirectories>$(SolutionDir)../glbook/Common</AdditionalIncludeDirectories> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\glbook\Chapter_11\Multisample\Multisample.c" /> + <ClCompile Include="..\glbook\Common\esShader.c" /> + <ClCompile Include="..\glbook\Common\esShapes.c" /> + <ClCompile Include="..\glbook\Common\esTransform.c" /> + <ClCompile Include="..\glbook\Common\esUtil.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\glbook\Common\esUtil.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/glbook_11_Stencil_Test.vcxproj b/tests/msvc10/glbook_11_Stencil_Test.vcxproj new file mode 100644 index 00000000..d72d7fa6 --- /dev/null +++ b/tests/msvc10/glbook_11_Stencil_Test.vcxproj @@ -0,0 +1,106 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{2D60F3E0-B83A-4442-94D3-AB4B2F068476}</ProjectGuid> + <RootNamespace>glbook_11_Stencil_Test</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <ClCompile> + <AdditionalIncludeDirectories>$(SolutionDir)../glbook/Common</AdditionalIncludeDirectories> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <ClCompile> + <AdditionalIncludeDirectories>$(SolutionDir)../glbook/Common</AdditionalIncludeDirectories> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\glbook\Chapter_11\Stencil_Test\Stencil_Test.c" /> + <ClCompile Include="..\glbook\Common\esShader.c" /> + <ClCompile Include="..\glbook\Common\esShapes.c" /> + <ClCompile Include="..\glbook\Common\esTransform.c" /> + <ClCompile Include="..\glbook\Common\esUtil.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\glbook\Common\esUtil.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/glbook_13_ParticleSystem.vcxproj b/tests/msvc10/glbook_13_ParticleSystem.vcxproj new file mode 100644 index 00000000..458d76fa --- /dev/null +++ b/tests/msvc10/glbook_13_ParticleSystem.vcxproj @@ -0,0 +1,109 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{3E62931D-2795-4BD1-8AA7-55F5440AD293}</ProjectGuid> + <RootNamespace>glbook_13_ParticleSystem</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <ClCompile> + <AdditionalIncludeDirectories>$(SolutionDir)../glbook/Common</AdditionalIncludeDirectories> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <ClCompile> + <AdditionalIncludeDirectories>$(SolutionDir)../glbook/Common</AdditionalIncludeDirectories> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\glbook\Chapter_13\ParticleSystem\ParticleSystem.c" /> + <ClCompile Include="..\glbook\Common\esShader.c" /> + <ClCompile Include="..\glbook\Common\esShapes.c" /> + <ClCompile Include="..\glbook\Common\esTransform.c" /> + <ClCompile Include="..\glbook\Common\esUtil.c" /> + </ItemGroup> + <ItemGroup> + <None Include="..\glbook\Chapter_13\ParticleSystem\smoke.tga" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\glbook\Common\esUtil.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/glbook_15_Hello_Triangle_KD.vcxproj b/tests/msvc10/glbook_15_Hello_Triangle_KD.vcxproj new file mode 100644 index 00000000..654164b3 --- /dev/null +++ b/tests/msvc10/glbook_15_Hello_Triangle_KD.vcxproj @@ -0,0 +1,106 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{A971FFED-3417-452B-B488-6D4F9F257847}</ProjectGuid> + <RootNamespace>glbook_15_Hello_Triangle_KD</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <ClCompile> + <AdditionalIncludeDirectories>$(SolutionDir)../glbook/Common</AdditionalIncludeDirectories> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <ClCompile> + <AdditionalIncludeDirectories>$(SolutionDir)../glbook/Common</AdditionalIncludeDirectories> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\glbook\Chapter_15\Hello_Triangle_KD\Hello_Triangle_KD.c" /> + <ClCompile Include="..\glbook\Common\esShader.c" /> + <ClCompile Include="..\glbook\Common\esShapes.c" /> + <ClCompile Include="..\glbook\Common\esTransform.c" /> + <ClCompile Include="..\glbook\Common\esUtil.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\glbook\Common\esUtil.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/glbook_2_Hello_Triangle.vcxproj b/tests/msvc10/glbook_2_Hello_Triangle.vcxproj new file mode 100644 index 00000000..b992294d --- /dev/null +++ b/tests/msvc10/glbook_2_Hello_Triangle.vcxproj @@ -0,0 +1,106 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\glbook\Chapter_2\Hello_Triangle\Hello_Triangle.c" /> + <ClCompile Include="..\glbook\Common\esShader.c" /> + <ClCompile Include="..\glbook\Common\esShapes.c" /> + <ClCompile Include="..\glbook\Common\esTransform.c" /> + <ClCompile Include="..\glbook\Common\esUtil.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\glbook\Common\esUtil.h" /> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{FA655211-CC00-4827-BBCB-B8749BB7671D}</ProjectGuid> + <RootNamespace>glbook_2_Hello_Triangle</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <ClCompile> + <AdditionalIncludeDirectories>$(SolutionDir)../glbook/Common</AdditionalIncludeDirectories> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <ClCompile> + <AdditionalIncludeDirectories>$(SolutionDir)../glbook/Common</AdditionalIncludeDirectories> + </ClCompile> + </ItemDefinitionGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/glbook_8_Simple_VertexShader.vcxproj b/tests/msvc10/glbook_8_Simple_VertexShader.vcxproj new file mode 100644 index 00000000..fb01c1da --- /dev/null +++ b/tests/msvc10/glbook_8_Simple_VertexShader.vcxproj @@ -0,0 +1,106 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{2FD5F24F-8B73-4C62-81D6-B6B866E5EC5E}</ProjectGuid> + <RootNamespace>glbook_8_Simple_VertexShader</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <ClCompile> + <AdditionalIncludeDirectories>$(SolutionDir)../glbook/Common</AdditionalIncludeDirectories> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <ClCompile> + <AdditionalIncludeDirectories>$(SolutionDir)../glbook/Common</AdditionalIncludeDirectories> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\glbook\Chapter_8\Simple_VertexShader\Simple_VertexShader.c" /> + <ClCompile Include="..\glbook\Common\esShader.c" /> + <ClCompile Include="..\glbook\Common\esShapes.c" /> + <ClCompile Include="..\glbook\Common\esTransform.c" /> + <ClCompile Include="..\glbook\Common\esUtil.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\glbook\Common\esUtil.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/glbook_9_MipMap2D.vcxproj b/tests/msvc10/glbook_9_MipMap2D.vcxproj new file mode 100644 index 00000000..1d747d1d --- /dev/null +++ b/tests/msvc10/glbook_9_MipMap2D.vcxproj @@ -0,0 +1,106 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{9EB49BEC-C7A0-4AEE-AF19-AACB057DE08B}</ProjectGuid> + <RootNamespace>glbook_9_MipMap2D</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <ClCompile> + <AdditionalIncludeDirectories>$(SolutionDir)../glbook/Common</AdditionalIncludeDirectories> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <ClCompile> + <AdditionalIncludeDirectories>$(SolutionDir)../glbook/Common</AdditionalIncludeDirectories> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\glbook\Chapter_9\MipMap2D\MipMap2D.c" /> + <ClCompile Include="..\glbook\Common\esShader.c" /> + <ClCompile Include="..\glbook\Common\esShapes.c" /> + <ClCompile Include="..\glbook\Common\esTransform.c" /> + <ClCompile Include="..\glbook\Common\esUtil.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\glbook\Common\esUtil.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/glbook_9_Simple_Texture2D.vcxproj b/tests/msvc10/glbook_9_Simple_Texture2D.vcxproj new file mode 100644 index 00000000..d9232e5d --- /dev/null +++ b/tests/msvc10/glbook_9_Simple_Texture2D.vcxproj @@ -0,0 +1,106 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{A7C445F9-FCE6-48D5-9343-734071A59185}</ProjectGuid> + <RootNamespace>glbook_9_Simple_Texture2D</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <ClCompile> + <AdditionalIncludeDirectories>$(SolutionDir)../glbook/Common</AdditionalIncludeDirectories> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <ClCompile> + <AdditionalIncludeDirectories>$(SolutionDir)../glbook/Common</AdditionalIncludeDirectories> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\glbook\Chapter_9\Simple_Texture2D\Simple_Texture2D.c" /> + <ClCompile Include="..\glbook\Common\esShader.c" /> + <ClCompile Include="..\glbook\Common\esShapes.c" /> + <ClCompile Include="..\glbook\Common\esTransform.c" /> + <ClCompile Include="..\glbook\Common\esUtil.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\glbook\Common\esUtil.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/glbook_9_Simple_TextureCubemap.vcxproj b/tests/msvc10/glbook_9_Simple_TextureCubemap.vcxproj new file mode 100644 index 00000000..c5c6ee1b --- /dev/null +++ b/tests/msvc10/glbook_9_Simple_TextureCubemap.vcxproj @@ -0,0 +1,106 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{C5500D5B-9489-4109-A6E4-CF8F7E1518E7}</ProjectGuid> + <RootNamespace>glbook_9_Simple_TextureCubemap</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <ClCompile> + <AdditionalIncludeDirectories>$(SolutionDir)../glbook/Common</AdditionalIncludeDirectories> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <ClCompile> + <AdditionalIncludeDirectories>$(SolutionDir)../glbook/Common</AdditionalIncludeDirectories> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\glbook\Chapter_9\Simple_TextureCubemap\Simple_TextureCubemap.c" /> + <ClCompile Include="..\glbook\Common\esShader.c" /> + <ClCompile Include="..\glbook\Common\esShapes.c" /> + <ClCompile Include="..\glbook\Common\esTransform.c" /> + <ClCompile Include="..\glbook\Common\esUtil.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\glbook\Common\esUtil.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/glbook_9_TextureWrap.vcxproj b/tests/msvc10/glbook_9_TextureWrap.vcxproj new file mode 100644 index 00000000..6cfbb0c8 --- /dev/null +++ b/tests/msvc10/glbook_9_TextureWrap.vcxproj @@ -0,0 +1,106 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{982D6A44-9080-4A89-911E-BC1E495267D1}</ProjectGuid> + <RootNamespace>glbook_9_TextureWrap</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <ClCompile> + <AdditionalIncludeDirectories>$(SolutionDir)../glbook/Common</AdditionalIncludeDirectories> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <ClCompile> + <AdditionalIncludeDirectories>$(SolutionDir)../glbook/Common</AdditionalIncludeDirectories> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\glbook\Chapter_9\TextureWrap\TextureWrap.c" /> + <ClCompile Include="..\glbook\Common\esShader.c" /> + <ClCompile Include="..\glbook\Common\esShapes.c" /> + <ClCompile Include="..\glbook\Common\esTransform.c" /> + <ClCompile Include="..\glbook\Common\esUtil.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\glbook\Common\esUtil.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/hashtest.vcxproj b/tests/msvc10/hashtest.vcxproj new file mode 100644 index 00000000..fe0ca2ab --- /dev/null +++ b/tests/msvc10/hashtest.vcxproj @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{61D7F11F-25EE-4C2C-9D73-8601F68B055E}</ProjectGuid> + <RootNamespace>hashtest</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\hashtest.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/hello_libcxx.vcxproj b/tests/msvc10/hello_libcxx.vcxproj new file mode 100644 index 00000000..8bd201e5 --- /dev/null +++ b/tests/msvc10/hello_libcxx.vcxproj @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{19DB739D-7EEB-4B99-BB6D-C12F086B5F24}</ProjectGuid> + <RootNamespace>hello_libcxx</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\hello_libcxx.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/hello_malloc.vcxproj b/tests/msvc10/hello_malloc.vcxproj new file mode 100644 index 00000000..6340257a --- /dev/null +++ b/tests/msvc10/hello_malloc.vcxproj @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{DFBD530C-9163-4558-B607-2A226BCC8DC0}</ProjectGuid> + <RootNamespace>hello_malloc</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\hello_malloc.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/hello_world_c.vcxproj b/tests/msvc10/hello_world_c.vcxproj new file mode 100644 index 00000000..be79a7b8 --- /dev/null +++ b/tests/msvc10/hello_world_c.vcxproj @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{660E83C1-82AC-487C-BF5E-CFB6B82196BC}</ProjectGuid> + <RootNamespace>hello_world_c</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\hello_world.c" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/hello_world_cpp.vcxproj b/tests/msvc10/hello_world_cpp.vcxproj new file mode 100644 index 00000000..31ff3034 --- /dev/null +++ b/tests/msvc10/hello_world_cpp.vcxproj @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{5970CDD4-FB0A-4E66-B7C9-DAD9E580628D}</ProjectGuid> + <RootNamespace>hello_world_cpp</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\hello_world.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/hello_world_file.vcxproj b/tests/msvc10/hello_world_file.vcxproj new file mode 100644 index 00000000..f076aba8 --- /dev/null +++ b/tests/msvc10/hello_world_file.vcxproj @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{EB0B52B6-0177-4CEE-955D-3C7F052E5F5B}</ProjectGuid> + <RootNamespace>hello_world_file</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\hello_world_file.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/hello_world_gles.vcxproj b/tests/msvc10/hello_world_gles.vcxproj new file mode 100644 index 00000000..371a5115 --- /dev/null +++ b/tests/msvc10/hello_world_gles.vcxproj @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\hello_world_gles.c" /> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{6A41CB2E-0022-47E1-89C5-FB2B558BEB91}</ProjectGuid> + <RootNamespace>hello_world_gles</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/hello_world_loop.vcxproj b/tests/msvc10/hello_world_loop.vcxproj new file mode 100644 index 00000000..96d5b697 --- /dev/null +++ b/tests/msvc10/hello_world_loop.vcxproj @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{DB3B6C01-8CF9-4397-843E-403D5063F2DE}</ProjectGuid> + <RootNamespace>hello_world_loop</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\hello_world_loop.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/hello_world_loop_malloc.vcxproj b/tests/msvc10/hello_world_loop_malloc.vcxproj new file mode 100644 index 00000000..3302c42d --- /dev/null +++ b/tests/msvc10/hello_world_loop_malloc.vcxproj @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{5C72F8EA-B852-49F6-A979-DE5011957BC7}</ProjectGuid> + <RootNamespace>hello_world_loop_malloc</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\hello_world_loop_malloc.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/hello_world_sdl.vcxproj b/tests/msvc10/hello_world_sdl.vcxproj new file mode 100644 index 00000000..4b5ef9e3 --- /dev/null +++ b/tests/msvc10/hello_world_sdl.vcxproj @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{DA2F2979-2902-42BC-B8DA-6B18FE2AF444}</ProjectGuid> + <RootNamespace>hello_world_sdl</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\hello_world_sdl.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/new.vcxproj b/tests/msvc10/new.vcxproj new file mode 100644 index 00000000..11ad95ae --- /dev/null +++ b/tests/msvc10/new.vcxproj @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{5190107D-91B3-4EF8-82CB-08381DD19ABB}</ProjectGuid> + <RootNamespace>new</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\new.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/raytrace.vcxproj b/tests/msvc10/raytrace.vcxproj new file mode 100644 index 00000000..9084d044 --- /dev/null +++ b/tests/msvc10/raytrace.vcxproj @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{2F3AD7E0-AA5D-4639-8F6A-53BDBD88EBD8}</ProjectGuid> + <RootNamespace>raytrace</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\raytrace.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/sdl_audio.vcxproj b/tests/msvc10/sdl_audio.vcxproj new file mode 100644 index 00000000..80a48d90 --- /dev/null +++ b/tests/msvc10/sdl_audio.vcxproj @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{F28A1DE1-5949-4AF5-8901-A37871C2514E}</ProjectGuid> + <RootNamespace>sdl_audio</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\sdl_audio.c" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/sdl_canvas.vcxproj b/tests/msvc10/sdl_canvas.vcxproj new file mode 100644 index 00000000..42215b38 --- /dev/null +++ b/tests/msvc10/sdl_canvas.vcxproj @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\sdl_canvas.c" /> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{CE360D01-4362-4FE4-A77E-8EF6E3F623CF}</ProjectGuid> + <RootNamespace>sdl_canvas</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/sdl_gl_read.vcxproj b/tests/msvc10/sdl_gl_read.vcxproj new file mode 100644 index 00000000..de6233c1 --- /dev/null +++ b/tests/msvc10/sdl_gl_read.vcxproj @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{3EA4E5F5-67B6-4F83-95D7-E041FFF787B0}</ProjectGuid> + <RootNamespace>sdl_gl_read</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\sdl_gl_read.c" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/sdl_image.vcxproj b/tests/msvc10/sdl_image.vcxproj new file mode 100644 index 00000000..631ea5cd --- /dev/null +++ b/tests/msvc10/sdl_image.vcxproj @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{5CE874BD-2F32-4579-B682-4B74E5764F13}</ProjectGuid> + <RootNamespace>sdl_image</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\sdl_image.c" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/sdl_key.vcxproj b/tests/msvc10/sdl_key.vcxproj new file mode 100644 index 00000000..3840256a --- /dev/null +++ b/tests/msvc10/sdl_key.vcxproj @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{1C5338A3-7020-4086-AE99-BC79EA3D42C1}</ProjectGuid> + <RootNamespace>sdl_key</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\sdl_key.c" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/sdl_mouse.vcxproj b/tests/msvc10/sdl_mouse.vcxproj new file mode 100644 index 00000000..7d582eb3 --- /dev/null +++ b/tests/msvc10/sdl_mouse.vcxproj @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{D3295E36-57BB-4C42-92D8-2AA150024256}</ProjectGuid> + <RootNamespace>sdl_mouse</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\sdl_mouse.c" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/sdl_ogl.vcxproj b/tests/msvc10/sdl_ogl.vcxproj new file mode 100644 index 00000000..b96eac4d --- /dev/null +++ b/tests/msvc10/sdl_ogl.vcxproj @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{670EA36B-AD2B-4BFC-8DD3-AE024736AFB2}</ProjectGuid> + <RootNamespace>sdl_ogl</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\sdl_ogl.c" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/skinning_test_no_simd.vcxproj b/tests/msvc10/skinning_test_no_simd.vcxproj new file mode 100644 index 00000000..b15dc996 --- /dev/null +++ b/tests/msvc10/skinning_test_no_simd.vcxproj @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{678A07B3-3A25-40E4-8A36-7A399056188A}</ProjectGuid> + <RootNamespace>skinning_test_no_simd</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\skinning_test_no_simd.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/tests_msvc10.sln b/tests/msvc10/tests_msvc10.sln new file mode 100644 index 00000000..67333016 --- /dev/null +++ b/tests/msvc10/tests_msvc10.sln @@ -0,0 +1,286 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hello_world_gles", "hello_world_gles.vcxproj", "{6A41CB2E-0022-47E1-89C5-FB2B558BEB91}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fannkuch", "fannkuch.vcxproj", "{C29BBEE3-02D1-459A-B8BA-832A3439F12D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fasta", "fasta.vcxproj", "{DDB7FF8E-EC42-4406-832C-F2B043D8760E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glbook_9_Simple_Texture2D", "glbook_9_Simple_Texture2D.vcxproj", "{A7C445F9-FCE6-48D5-9343-734071A59185}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glbook_9_Simple_TextureCubemap", "glbook_9_Simple_TextureCubemap.vcxproj", "{C5500D5B-9489-4109-A6E4-CF8F7E1518E7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glbook_9_TextureWrap", "glbook_9_TextureWrap.vcxproj", "{982D6A44-9080-4A89-911E-BC1E495267D1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glbook_10_MultiTexture", "glbook_10_MultiTexture.vcxproj", "{A2D564BE-34DE-43DC-B8F9-605CEF4BFC4B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glbook_11_Multisample", "glbook_11_Multisample.vcxproj", "{AD9E59DF-1628-4081-8672-212A7103FAAD}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glbook_11_Stencil_Test", "glbook_11_Stencil_Test.vcxproj", "{2D60F3E0-B83A-4442-94D3-AB4B2F068476}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glbook_13_ParticleSystem", "glbook_13_ParticleSystem.vcxproj", "{3E62931D-2795-4BD1-8AA7-55F5440AD293}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glbook_15_Hello_Triangle_KD", "glbook_15_Hello_Triangle_KD.vcxproj", "{A971FFED-3417-452B-B488-6D4F9F257847}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glbook_8_Simple_VertexShader", "glbook_8_Simple_VertexShader.vcxproj", "{2FD5F24F-8B73-4C62-81D6-B6B866E5EC5E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glbook_9_MipMap2D", "glbook_9_MipMap2D.vcxproj", "{9EB49BEC-C7A0-4AEE-AF19-AACB057DE08B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "raytrace", "raytrace.vcxproj", "{2F3AD7E0-AA5D-4639-8F6A-53BDBD88EBD8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hello_world_c", "hello_world_c.vcxproj", "{660E83C1-82AC-487C-BF5E-CFB6B82196BC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hello_world_cpp", "hello_world_cpp.vcxproj", "{5970CDD4-FB0A-4E66-B7C9-DAD9E580628D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hello_world_file", "hello_world_file.vcxproj", "{EB0B52B6-0177-4CEE-955D-3C7F052E5F5B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hello_malloc", "hello_malloc.vcxproj", "{DFBD530C-9163-4558-B607-2A226BCC8DC0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hello_libcxx", "hello_libcxx.vcxproj", "{19DB739D-7EEB-4B99-BB6D-C12F086B5F24}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hello_world_loop", "hello_world_loop.vcxproj", "{DB3B6C01-8CF9-4397-843E-403D5063F2DE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hello_world_loop_malloc", "hello_world_loop_malloc.vcxproj", "{5C72F8EA-B852-49F6-A979-DE5011957BC7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hello_world_sdl", "hello_world_sdl.vcxproj", "{DA2F2979-2902-42BC-B8DA-6B18FE2AF444}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dlmalloc_test", "dlmalloc_test.vcxproj", "{A44C4C27-F173-47D0-8626-59A21D86AC1E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "emscripten_api_browser", "emscripten_api_browser.vcxproj", "{65E0ED61-A813-4AEB-8DB0-A58657858EE2}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "files", "files.vcxproj", "{BE6A123E-9729-44A3-976F-3C06A3724894}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hashtest", "hashtest.vcxproj", "{61D7F11F-25EE-4C2C-9D73-8601F68B055E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "new", "new.vcxproj", "{5190107D-91B3-4EF8-82CB-08381DD19ABB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sdl_audio", "sdl_audio.vcxproj", "{F28A1DE1-5949-4AF5-8901-A37871C2514E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sdl_canvas", "sdl_canvas.vcxproj", "{CE360D01-4362-4FE4-A77E-8EF6E3F623CF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sdl_gl_read", "sdl_gl_read.vcxproj", "{3EA4E5F5-67B6-4F83-95D7-E041FFF787B0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sdl_image", "sdl_image.vcxproj", "{5CE874BD-2F32-4579-B682-4B74E5764F13}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sdl_key", "sdl_key.vcxproj", "{1C5338A3-7020-4086-AE99-BC79EA3D42C1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sdl_mouse", "sdl_mouse.vcxproj", "{D3295E36-57BB-4C42-92D8-2AA150024256}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sdl_ogl", "sdl_ogl.vcxproj", "{670EA36B-AD2B-4BFC-8DD3-AE024736AFB2}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "skinning_test_no_simd", "skinning_test_no_simd.vcxproj", "{678A07B3-3A25-40E4-8A36-7A399056188A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "twopart", "twopart.vcxproj", "{C896D890-9132-4A2D-8BA8-0EB6888FEAC2}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glbook_2_Hello_Triangle", "glbook_2_Hello_Triangle.vcxproj", "{FA655211-CC00-4827-BBCB-B8749BB7671D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "gles", "gles", "{9DCFC12B-65CB-4965-9F16-C63B467E2E9E}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "sdl", "sdl", "{70A8D326-5CBD-4C8A-BE84-39B0528C2479}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "other", "other", "{8E55380B-7067-47FF-8B6B-6D656B8D8CC3}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "README", "README", "{AFB0F421-9B24-495D-B961-EA94780F36E5}" + ProjectSection(SolutionItems) = preProject + README.txt = README.txt + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Emscripten = Debug|Emscripten + Release|Emscripten = Release|Emscripten + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6A41CB2E-0022-47E1-89C5-FB2B558BEB91}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {6A41CB2E-0022-47E1-89C5-FB2B558BEB91}.Debug|Emscripten.Build.0 = Debug|Emscripten + {6A41CB2E-0022-47E1-89C5-FB2B558BEB91}.Release|Emscripten.ActiveCfg = Release|Emscripten + {6A41CB2E-0022-47E1-89C5-FB2B558BEB91}.Release|Emscripten.Build.0 = Release|Emscripten + {C29BBEE3-02D1-459A-B8BA-832A3439F12D}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {C29BBEE3-02D1-459A-B8BA-832A3439F12D}.Debug|Emscripten.Build.0 = Debug|Emscripten + {C29BBEE3-02D1-459A-B8BA-832A3439F12D}.Release|Emscripten.ActiveCfg = Release|Emscripten + {C29BBEE3-02D1-459A-B8BA-832A3439F12D}.Release|Emscripten.Build.0 = Release|Emscripten + {DDB7FF8E-EC42-4406-832C-F2B043D8760E}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {DDB7FF8E-EC42-4406-832C-F2B043D8760E}.Debug|Emscripten.Build.0 = Debug|Emscripten + {DDB7FF8E-EC42-4406-832C-F2B043D8760E}.Release|Emscripten.ActiveCfg = Release|Emscripten + {DDB7FF8E-EC42-4406-832C-F2B043D8760E}.Release|Emscripten.Build.0 = Release|Emscripten + {A7C445F9-FCE6-48D5-9343-734071A59185}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {A7C445F9-FCE6-48D5-9343-734071A59185}.Debug|Emscripten.Build.0 = Debug|Emscripten + {A7C445F9-FCE6-48D5-9343-734071A59185}.Release|Emscripten.ActiveCfg = Release|Emscripten + {A7C445F9-FCE6-48D5-9343-734071A59185}.Release|Emscripten.Build.0 = Release|Emscripten + {C5500D5B-9489-4109-A6E4-CF8F7E1518E7}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {C5500D5B-9489-4109-A6E4-CF8F7E1518E7}.Debug|Emscripten.Build.0 = Debug|Emscripten + {C5500D5B-9489-4109-A6E4-CF8F7E1518E7}.Release|Emscripten.ActiveCfg = Release|Emscripten + {C5500D5B-9489-4109-A6E4-CF8F7E1518E7}.Release|Emscripten.Build.0 = Release|Emscripten + {982D6A44-9080-4A89-911E-BC1E495267D1}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {982D6A44-9080-4A89-911E-BC1E495267D1}.Debug|Emscripten.Build.0 = Debug|Emscripten + {982D6A44-9080-4A89-911E-BC1E495267D1}.Release|Emscripten.ActiveCfg = Release|Emscripten + {982D6A44-9080-4A89-911E-BC1E495267D1}.Release|Emscripten.Build.0 = Release|Emscripten + {A2D564BE-34DE-43DC-B8F9-605CEF4BFC4B}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {A2D564BE-34DE-43DC-B8F9-605CEF4BFC4B}.Debug|Emscripten.Build.0 = Debug|Emscripten + {A2D564BE-34DE-43DC-B8F9-605CEF4BFC4B}.Release|Emscripten.ActiveCfg = Release|Emscripten + {A2D564BE-34DE-43DC-B8F9-605CEF4BFC4B}.Release|Emscripten.Build.0 = Release|Emscripten + {AD9E59DF-1628-4081-8672-212A7103FAAD}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {AD9E59DF-1628-4081-8672-212A7103FAAD}.Debug|Emscripten.Build.0 = Debug|Emscripten + {AD9E59DF-1628-4081-8672-212A7103FAAD}.Release|Emscripten.ActiveCfg = Release|Emscripten + {AD9E59DF-1628-4081-8672-212A7103FAAD}.Release|Emscripten.Build.0 = Release|Emscripten + {2D60F3E0-B83A-4442-94D3-AB4B2F068476}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {2D60F3E0-B83A-4442-94D3-AB4B2F068476}.Debug|Emscripten.Build.0 = Debug|Emscripten + {2D60F3E0-B83A-4442-94D3-AB4B2F068476}.Release|Emscripten.ActiveCfg = Release|Emscripten + {2D60F3E0-B83A-4442-94D3-AB4B2F068476}.Release|Emscripten.Build.0 = Release|Emscripten + {3E62931D-2795-4BD1-8AA7-55F5440AD293}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {3E62931D-2795-4BD1-8AA7-55F5440AD293}.Debug|Emscripten.Build.0 = Debug|Emscripten + {3E62931D-2795-4BD1-8AA7-55F5440AD293}.Release|Emscripten.ActiveCfg = Release|Emscripten + {3E62931D-2795-4BD1-8AA7-55F5440AD293}.Release|Emscripten.Build.0 = Release|Emscripten + {A971FFED-3417-452B-B488-6D4F9F257847}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {A971FFED-3417-452B-B488-6D4F9F257847}.Debug|Emscripten.Build.0 = Debug|Emscripten + {A971FFED-3417-452B-B488-6D4F9F257847}.Release|Emscripten.ActiveCfg = Release|Emscripten + {A971FFED-3417-452B-B488-6D4F9F257847}.Release|Emscripten.Build.0 = Release|Emscripten + {2FD5F24F-8B73-4C62-81D6-B6B866E5EC5E}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {2FD5F24F-8B73-4C62-81D6-B6B866E5EC5E}.Debug|Emscripten.Build.0 = Debug|Emscripten + {2FD5F24F-8B73-4C62-81D6-B6B866E5EC5E}.Release|Emscripten.ActiveCfg = Release|Emscripten + {2FD5F24F-8B73-4C62-81D6-B6B866E5EC5E}.Release|Emscripten.Build.0 = Release|Emscripten + {9EB49BEC-C7A0-4AEE-AF19-AACB057DE08B}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {9EB49BEC-C7A0-4AEE-AF19-AACB057DE08B}.Debug|Emscripten.Build.0 = Debug|Emscripten + {9EB49BEC-C7A0-4AEE-AF19-AACB057DE08B}.Release|Emscripten.ActiveCfg = Release|Emscripten + {9EB49BEC-C7A0-4AEE-AF19-AACB057DE08B}.Release|Emscripten.Build.0 = Release|Emscripten + {2F3AD7E0-AA5D-4639-8F6A-53BDBD88EBD8}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {2F3AD7E0-AA5D-4639-8F6A-53BDBD88EBD8}.Debug|Emscripten.Build.0 = Debug|Emscripten + {2F3AD7E0-AA5D-4639-8F6A-53BDBD88EBD8}.Release|Emscripten.ActiveCfg = Release|Emscripten + {2F3AD7E0-AA5D-4639-8F6A-53BDBD88EBD8}.Release|Emscripten.Build.0 = Release|Emscripten + {660E83C1-82AC-487C-BF5E-CFB6B82196BC}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {660E83C1-82AC-487C-BF5E-CFB6B82196BC}.Debug|Emscripten.Build.0 = Debug|Emscripten + {660E83C1-82AC-487C-BF5E-CFB6B82196BC}.Release|Emscripten.ActiveCfg = Release|Emscripten + {660E83C1-82AC-487C-BF5E-CFB6B82196BC}.Release|Emscripten.Build.0 = Release|Emscripten + {5970CDD4-FB0A-4E66-B7C9-DAD9E580628D}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {5970CDD4-FB0A-4E66-B7C9-DAD9E580628D}.Debug|Emscripten.Build.0 = Debug|Emscripten + {5970CDD4-FB0A-4E66-B7C9-DAD9E580628D}.Release|Emscripten.ActiveCfg = Release|Emscripten + {5970CDD4-FB0A-4E66-B7C9-DAD9E580628D}.Release|Emscripten.Build.0 = Release|Emscripten + {EB0B52B6-0177-4CEE-955D-3C7F052E5F5B}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {EB0B52B6-0177-4CEE-955D-3C7F052E5F5B}.Debug|Emscripten.Build.0 = Debug|Emscripten + {EB0B52B6-0177-4CEE-955D-3C7F052E5F5B}.Release|Emscripten.ActiveCfg = Release|Emscripten + {EB0B52B6-0177-4CEE-955D-3C7F052E5F5B}.Release|Emscripten.Build.0 = Release|Emscripten + {DFBD530C-9163-4558-B607-2A226BCC8DC0}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {DFBD530C-9163-4558-B607-2A226BCC8DC0}.Debug|Emscripten.Build.0 = Debug|Emscripten + {DFBD530C-9163-4558-B607-2A226BCC8DC0}.Release|Emscripten.ActiveCfg = Release|Emscripten + {DFBD530C-9163-4558-B607-2A226BCC8DC0}.Release|Emscripten.Build.0 = Release|Emscripten + {19DB739D-7EEB-4B99-BB6D-C12F086B5F24}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {19DB739D-7EEB-4B99-BB6D-C12F086B5F24}.Debug|Emscripten.Build.0 = Debug|Emscripten + {19DB739D-7EEB-4B99-BB6D-C12F086B5F24}.Release|Emscripten.ActiveCfg = Release|Emscripten + {19DB739D-7EEB-4B99-BB6D-C12F086B5F24}.Release|Emscripten.Build.0 = Release|Emscripten + {DB3B6C01-8CF9-4397-843E-403D5063F2DE}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {DB3B6C01-8CF9-4397-843E-403D5063F2DE}.Debug|Emscripten.Build.0 = Debug|Emscripten + {DB3B6C01-8CF9-4397-843E-403D5063F2DE}.Release|Emscripten.ActiveCfg = Release|Emscripten + {DB3B6C01-8CF9-4397-843E-403D5063F2DE}.Release|Emscripten.Build.0 = Release|Emscripten + {5C72F8EA-B852-49F6-A979-DE5011957BC7}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {5C72F8EA-B852-49F6-A979-DE5011957BC7}.Debug|Emscripten.Build.0 = Debug|Emscripten + {5C72F8EA-B852-49F6-A979-DE5011957BC7}.Release|Emscripten.ActiveCfg = Release|Emscripten + {5C72F8EA-B852-49F6-A979-DE5011957BC7}.Release|Emscripten.Build.0 = Release|Emscripten + {DA2F2979-2902-42BC-B8DA-6B18FE2AF444}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {DA2F2979-2902-42BC-B8DA-6B18FE2AF444}.Debug|Emscripten.Build.0 = Debug|Emscripten + {DA2F2979-2902-42BC-B8DA-6B18FE2AF444}.Release|Emscripten.ActiveCfg = Release|Emscripten + {DA2F2979-2902-42BC-B8DA-6B18FE2AF444}.Release|Emscripten.Build.0 = Release|Emscripten + {A44C4C27-F173-47D0-8626-59A21D86AC1E}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {A44C4C27-F173-47D0-8626-59A21D86AC1E}.Debug|Emscripten.Build.0 = Debug|Emscripten + {A44C4C27-F173-47D0-8626-59A21D86AC1E}.Release|Emscripten.ActiveCfg = Release|Emscripten + {A44C4C27-F173-47D0-8626-59A21D86AC1E}.Release|Emscripten.Build.0 = Release|Emscripten + {65E0ED61-A813-4AEB-8DB0-A58657858EE2}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {65E0ED61-A813-4AEB-8DB0-A58657858EE2}.Debug|Emscripten.Build.0 = Debug|Emscripten + {65E0ED61-A813-4AEB-8DB0-A58657858EE2}.Release|Emscripten.ActiveCfg = Release|Emscripten + {65E0ED61-A813-4AEB-8DB0-A58657858EE2}.Release|Emscripten.Build.0 = Release|Emscripten + {BE6A123E-9729-44A3-976F-3C06A3724894}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {BE6A123E-9729-44A3-976F-3C06A3724894}.Debug|Emscripten.Build.0 = Debug|Emscripten + {BE6A123E-9729-44A3-976F-3C06A3724894}.Release|Emscripten.ActiveCfg = Release|Emscripten + {BE6A123E-9729-44A3-976F-3C06A3724894}.Release|Emscripten.Build.0 = Release|Emscripten + {61D7F11F-25EE-4C2C-9D73-8601F68B055E}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {61D7F11F-25EE-4C2C-9D73-8601F68B055E}.Debug|Emscripten.Build.0 = Debug|Emscripten + {61D7F11F-25EE-4C2C-9D73-8601F68B055E}.Release|Emscripten.ActiveCfg = Release|Emscripten + {61D7F11F-25EE-4C2C-9D73-8601F68B055E}.Release|Emscripten.Build.0 = Release|Emscripten + {5190107D-91B3-4EF8-82CB-08381DD19ABB}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {5190107D-91B3-4EF8-82CB-08381DD19ABB}.Debug|Emscripten.Build.0 = Debug|Emscripten + {5190107D-91B3-4EF8-82CB-08381DD19ABB}.Release|Emscripten.ActiveCfg = Release|Emscripten + {5190107D-91B3-4EF8-82CB-08381DD19ABB}.Release|Emscripten.Build.0 = Release|Emscripten + {F28A1DE1-5949-4AF5-8901-A37871C2514E}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {F28A1DE1-5949-4AF5-8901-A37871C2514E}.Debug|Emscripten.Build.0 = Debug|Emscripten + {F28A1DE1-5949-4AF5-8901-A37871C2514E}.Release|Emscripten.ActiveCfg = Release|Emscripten + {F28A1DE1-5949-4AF5-8901-A37871C2514E}.Release|Emscripten.Build.0 = Release|Emscripten + {CE360D01-4362-4FE4-A77E-8EF6E3F623CF}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {CE360D01-4362-4FE4-A77E-8EF6E3F623CF}.Debug|Emscripten.Build.0 = Debug|Emscripten + {CE360D01-4362-4FE4-A77E-8EF6E3F623CF}.Release|Emscripten.ActiveCfg = Release|Emscripten + {CE360D01-4362-4FE4-A77E-8EF6E3F623CF}.Release|Emscripten.Build.0 = Release|Emscripten + {3EA4E5F5-67B6-4F83-95D7-E041FFF787B0}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {3EA4E5F5-67B6-4F83-95D7-E041FFF787B0}.Debug|Emscripten.Build.0 = Debug|Emscripten + {3EA4E5F5-67B6-4F83-95D7-E041FFF787B0}.Release|Emscripten.ActiveCfg = Release|Emscripten + {3EA4E5F5-67B6-4F83-95D7-E041FFF787B0}.Release|Emscripten.Build.0 = Release|Emscripten + {5CE874BD-2F32-4579-B682-4B74E5764F13}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {5CE874BD-2F32-4579-B682-4B74E5764F13}.Debug|Emscripten.Build.0 = Debug|Emscripten + {5CE874BD-2F32-4579-B682-4B74E5764F13}.Release|Emscripten.ActiveCfg = Release|Emscripten + {5CE874BD-2F32-4579-B682-4B74E5764F13}.Release|Emscripten.Build.0 = Release|Emscripten + {1C5338A3-7020-4086-AE99-BC79EA3D42C1}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {1C5338A3-7020-4086-AE99-BC79EA3D42C1}.Debug|Emscripten.Build.0 = Debug|Emscripten + {1C5338A3-7020-4086-AE99-BC79EA3D42C1}.Release|Emscripten.ActiveCfg = Release|Emscripten + {1C5338A3-7020-4086-AE99-BC79EA3D42C1}.Release|Emscripten.Build.0 = Release|Emscripten + {D3295E36-57BB-4C42-92D8-2AA150024256}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {D3295E36-57BB-4C42-92D8-2AA150024256}.Debug|Emscripten.Build.0 = Debug|Emscripten + {D3295E36-57BB-4C42-92D8-2AA150024256}.Release|Emscripten.ActiveCfg = Release|Emscripten + {D3295E36-57BB-4C42-92D8-2AA150024256}.Release|Emscripten.Build.0 = Release|Emscripten + {670EA36B-AD2B-4BFC-8DD3-AE024736AFB2}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {670EA36B-AD2B-4BFC-8DD3-AE024736AFB2}.Debug|Emscripten.Build.0 = Debug|Emscripten + {670EA36B-AD2B-4BFC-8DD3-AE024736AFB2}.Release|Emscripten.ActiveCfg = Release|Emscripten + {670EA36B-AD2B-4BFC-8DD3-AE024736AFB2}.Release|Emscripten.Build.0 = Release|Emscripten + {678A07B3-3A25-40E4-8A36-7A399056188A}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {678A07B3-3A25-40E4-8A36-7A399056188A}.Debug|Emscripten.Build.0 = Debug|Emscripten + {678A07B3-3A25-40E4-8A36-7A399056188A}.Release|Emscripten.ActiveCfg = Release|Emscripten + {678A07B3-3A25-40E4-8A36-7A399056188A}.Release|Emscripten.Build.0 = Release|Emscripten + {C896D890-9132-4A2D-8BA8-0EB6888FEAC2}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {C896D890-9132-4A2D-8BA8-0EB6888FEAC2}.Debug|Emscripten.Build.0 = Debug|Emscripten + {C896D890-9132-4A2D-8BA8-0EB6888FEAC2}.Release|Emscripten.ActiveCfg = Release|Emscripten + {C896D890-9132-4A2D-8BA8-0EB6888FEAC2}.Release|Emscripten.Build.0 = Release|Emscripten + {FA655211-CC00-4827-BBCB-B8749BB7671D}.Debug|Emscripten.ActiveCfg = Debug|Emscripten + {FA655211-CC00-4827-BBCB-B8749BB7671D}.Debug|Emscripten.Build.0 = Debug|Emscripten + {FA655211-CC00-4827-BBCB-B8749BB7671D}.Release|Emscripten.ActiveCfg = Release|Emscripten + {FA655211-CC00-4827-BBCB-B8749BB7671D}.Release|Emscripten.Build.0 = Release|Emscripten + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {A7C445F9-FCE6-48D5-9343-734071A59185} = {9DCFC12B-65CB-4965-9F16-C63B467E2E9E} + {C5500D5B-9489-4109-A6E4-CF8F7E1518E7} = {9DCFC12B-65CB-4965-9F16-C63B467E2E9E} + {982D6A44-9080-4A89-911E-BC1E495267D1} = {9DCFC12B-65CB-4965-9F16-C63B467E2E9E} + {A2D564BE-34DE-43DC-B8F9-605CEF4BFC4B} = {9DCFC12B-65CB-4965-9F16-C63B467E2E9E} + {AD9E59DF-1628-4081-8672-212A7103FAAD} = {9DCFC12B-65CB-4965-9F16-C63B467E2E9E} + {2D60F3E0-B83A-4442-94D3-AB4B2F068476} = {9DCFC12B-65CB-4965-9F16-C63B467E2E9E} + {3E62931D-2795-4BD1-8AA7-55F5440AD293} = {9DCFC12B-65CB-4965-9F16-C63B467E2E9E} + {A971FFED-3417-452B-B488-6D4F9F257847} = {9DCFC12B-65CB-4965-9F16-C63B467E2E9E} + {2FD5F24F-8B73-4C62-81D6-B6B866E5EC5E} = {9DCFC12B-65CB-4965-9F16-C63B467E2E9E} + {9EB49BEC-C7A0-4AEE-AF19-AACB057DE08B} = {9DCFC12B-65CB-4965-9F16-C63B467E2E9E} + {FA655211-CC00-4827-BBCB-B8749BB7671D} = {9DCFC12B-65CB-4965-9F16-C63B467E2E9E} + {6A41CB2E-0022-47E1-89C5-FB2B558BEB91} = {9DCFC12B-65CB-4965-9F16-C63B467E2E9E} + {DDB7FF8E-EC42-4406-832C-F2B043D8760E} = {8E55380B-7067-47FF-8B6B-6D656B8D8CC3} + {2F3AD7E0-AA5D-4639-8F6A-53BDBD88EBD8} = {8E55380B-7067-47FF-8B6B-6D656B8D8CC3} + {660E83C1-82AC-487C-BF5E-CFB6B82196BC} = {8E55380B-7067-47FF-8B6B-6D656B8D8CC3} + {5970CDD4-FB0A-4E66-B7C9-DAD9E580628D} = {8E55380B-7067-47FF-8B6B-6D656B8D8CC3} + {EB0B52B6-0177-4CEE-955D-3C7F052E5F5B} = {8E55380B-7067-47FF-8B6B-6D656B8D8CC3} + {DFBD530C-9163-4558-B607-2A226BCC8DC0} = {8E55380B-7067-47FF-8B6B-6D656B8D8CC3} + {19DB739D-7EEB-4B99-BB6D-C12F086B5F24} = {8E55380B-7067-47FF-8B6B-6D656B8D8CC3} + {DB3B6C01-8CF9-4397-843E-403D5063F2DE} = {8E55380B-7067-47FF-8B6B-6D656B8D8CC3} + {5C72F8EA-B852-49F6-A979-DE5011957BC7} = {8E55380B-7067-47FF-8B6B-6D656B8D8CC3} + {A44C4C27-F173-47D0-8626-59A21D86AC1E} = {8E55380B-7067-47FF-8B6B-6D656B8D8CC3} + {65E0ED61-A813-4AEB-8DB0-A58657858EE2} = {8E55380B-7067-47FF-8B6B-6D656B8D8CC3} + {BE6A123E-9729-44A3-976F-3C06A3724894} = {8E55380B-7067-47FF-8B6B-6D656B8D8CC3} + {61D7F11F-25EE-4C2C-9D73-8601F68B055E} = {8E55380B-7067-47FF-8B6B-6D656B8D8CC3} + {5190107D-91B3-4EF8-82CB-08381DD19ABB} = {8E55380B-7067-47FF-8B6B-6D656B8D8CC3} + {678A07B3-3A25-40E4-8A36-7A399056188A} = {8E55380B-7067-47FF-8B6B-6D656B8D8CC3} + {C896D890-9132-4A2D-8BA8-0EB6888FEAC2} = {8E55380B-7067-47FF-8B6B-6D656B8D8CC3} + {C29BBEE3-02D1-459A-B8BA-832A3439F12D} = {8E55380B-7067-47FF-8B6B-6D656B8D8CC3} + {F28A1DE1-5949-4AF5-8901-A37871C2514E} = {70A8D326-5CBD-4C8A-BE84-39B0528C2479} + {CE360D01-4362-4FE4-A77E-8EF6E3F623CF} = {70A8D326-5CBD-4C8A-BE84-39B0528C2479} + {3EA4E5F5-67B6-4F83-95D7-E041FFF787B0} = {70A8D326-5CBD-4C8A-BE84-39B0528C2479} + {5CE874BD-2F32-4579-B682-4B74E5764F13} = {70A8D326-5CBD-4C8A-BE84-39B0528C2479} + {1C5338A3-7020-4086-AE99-BC79EA3D42C1} = {70A8D326-5CBD-4C8A-BE84-39B0528C2479} + {D3295E36-57BB-4C42-92D8-2AA150024256} = {70A8D326-5CBD-4C8A-BE84-39B0528C2479} + {670EA36B-AD2B-4BFC-8DD3-AE024736AFB2} = {70A8D326-5CBD-4C8A-BE84-39B0528C2479} + {DA2F2979-2902-42BC-B8DA-6B18FE2AF444} = {70A8D326-5CBD-4C8A-BE84-39B0528C2479} + EndGlobalSection +EndGlobal diff --git a/tests/msvc10/tests_msvc10.vcxproj b/tests/msvc10/tests_msvc10.vcxproj new file mode 100644 index 00000000..bb69b0e6 --- /dev/null +++ b/tests/msvc10/tests_msvc10.vcxproj @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{6FB6B535-11C3-4011-B06B-74ACD387DFCC}</ProjectGuid> + <RootNamespace>tests_msvc10</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup /> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/msvc10/twopart.vcxproj b/tests/msvc10/twopart.vcxproj new file mode 100644 index 00000000..7d299984 --- /dev/null +++ b/tests/msvc10/twopart.vcxproj @@ -0,0 +1,90 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Emscripten"> + <Configuration>Debug</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Emscripten"> + <Configuration>Release</Configuration> + <Platform>Emscripten</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{C896D890-9132-4A2D-8BA8-0EB6888FEAC2}</ProjectGuid> + <RootNamespace>twopart</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <PlatformToolset>emcc</PlatformToolset> + <ConfigurationType>HTMLPage</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Emscripten'"> + <IntDir>$(Platform)\$(ProjectName)_$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\twopart_main.cpp" /> + <ClCompile Include="..\twopart_side.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tests/pre_run_deps.cpp b/tests/pre_run_deps.cpp new file mode 100644 index 00000000..41c06972 --- /dev/null +++ b/tests/pre_run_deps.cpp @@ -0,0 +1,10 @@ +#include <stdio.h> +#include <emscripten.h> + +int main() { + printf("main() called.\n"); + int result = emscripten_run_script_int("Module.okk"); + REPORT_RESULT(); + return 1; +} + diff --git a/tests/runner.py b/tests/runner.py index 673193c5..4bf3f5ee 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -14,7 +14,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, webbrowser, hashlib, threading, platform, BaseHTTPServer, multiprocessing +import os, unittest, tempfile, shutil, time, inspect, sys, math, glob, tempfile, re, difflib, webbrowser, hashlib, threading, platform, BaseHTTPServer, multiprocessing, functools if len(sys.argv) == 1: @@ -79,7 +79,7 @@ class RunnerCore(unittest.TestCase): if not self.save_dir: dirname = tempfile.mkdtemp(prefix='emscripten_test_' + self.__class__.__name__ + '_', dir=TEMP_DIR) else: - dirname = EMSCRIPTEN_TEMP_DIR + dirname = CANONICAL_TEMP_DIR if not os.path.exists(dirname): os.makedirs(dirname) self.working_dir = dirname @@ -259,12 +259,14 @@ process(sys.argv[1]) def run_native(self, filename, args): Popen([filename+'.native'] + args, stdout=PIPE).communicate()[0] - def assertIdentical(self, x, y): - if x != y: - raise Exception("Expected to have '%s' == '%s', diff:\n\n%s" % ( - limit_size(x), limit_size(y), - limit_size(''.join([a.rstrip()+'\n' for a in difflib.unified_diff(x.split('\n'), y.split('\n'), fromfile='expected', tofile='actual')])) - )) + def assertIdentical(self, values, y): + if type(values) not in [list, tuple]: values = [values] + for x in values: + if x == y: return # success + raise Exception("Expected to have '%s' == '%s', diff:\n\n%s" % ( + limit_size(values[0]), limit_size(y), + limit_size(''.join([a.rstrip()+'\n' for a in difflib.unified_diff(x.split('\n'), y.split('\n'), fromfile='expected', tofile='actual')])) + )) def assertContained(self, values, string, additional_info=''): if type(values) not in [list, tuple]: values = [values] @@ -355,7 +357,6 @@ if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv) and 'brows js_engines = filter(lambda engine: engine not in self.banned_js_engines, js_engines) if len(js_engines) == 0: return self.skip('No JS engine present to run this test with. Check %s and settings.py and the paths therein.' % EM_CONFIG) for engine in js_engines: - engine = filter(lambda arg: arg != '-n', engine) # SpiderMonkey issue 716255 js_output = self.run_generated_code(engine, filename + '.o.js', args) if output_nicerizer is not None: js_output = output_nicerizer(js_output) @@ -909,6 +910,84 @@ m_divisor is 1091269979 code = open(os.path.join(self.get_dir(), 'src.cpp.o.js')).read() assert 'goog.math.Long' not in code and 'jsbn' not in code, 'i64 precise math should not have been included if not actually used' + def test_i64_zextneg(self): + if Settings.USE_TYPED_ARRAYS != 2: return self.skip('full i64 stuff only in ta2') + + src = r''' + #include <stdint.h> + #include <stdio.h> + + int main(int argc, char *argv[]) + { + uint8_t byte = 0x80; + uint16_t two = byte; + uint32_t four = byte; + uint64_t eight = byte; + + printf("value: %d,%d,%d,%lld.\n", byte, two, four, eight); + + return 0; + } + ''' + self.do_run(src, 'value: 128,128,128,128.') + + def test_i64_7z(self): + if Settings.USE_TYPED_ARRAYS != 2: return self.skip('full i64 stuff only in ta2') + + src = r''' + #include <stdint.h> + #include <stdio.h> + uint64_t a, b; + int main(int argc, char *argv[]) + { + a = argc; + b = argv[1][0]; + if (a > a + b || a > a + b + 1) { + printf("one %lld, %lld", a, b); + return 0; + } + printf("zero %lld, %lld", a, b); + return 0; + } + ''' + self.do_run(src, 'zero 2, 104', ['hallo']) + + def test_i16_emcc_intrinsic(self): + Settings.CORRECT_SIGNS = 1 # Relevant to this test + + src = r''' + #include <stdio.h> + + int test(unsigned short a, unsigned short b) { + unsigned short result = a; + result += b; + if (result < b) printf("C!"); + return result; + } + + int main(void) { + printf(",%d,", test(0, 0)); + printf(",%d,", test(1, 1)); + printf(",%d,", test(65535, 1)); + printf(",%d,", test(1, 65535)); + printf(",%d,", test(32768, 32767)); + printf(",%d,", test(32768, 32768)); + return 0; + } + ''' + self.do_run(src, ',0,,2,C!,0,C!,0,,65535,C!,0,') + + def test_sha1(self): + if self.emcc_args == None: return self.skip('needs ta2') + + self.do_run(open(path_from_root('tests', 'sha1.c')).read(), 'SHA1=15dd99a1991e0b3826fede3deffc1feba42278e6') + + def test_cube2md5(self): + if self.emcc_args == None: return self.skip('needs emcc') + self.emcc_args += ['--embed-file', 'cube2md5.txt'] + shutil.copyfile(path_from_root('tests', 'cube2md5.txt'), os.path.join(self.get_dir(), 'cube2md5.txt')) + self.do_run(open(path_from_root('tests', 'cube2md5.cpp')).read(), open(path_from_root('tests', 'cube2md5.ok')).read()) + def test_cube2hash(self): # A good test of i64 math if Settings.USE_TYPED_ARRAYS != 2: return self.skip('requires ta2 C-style memory aliasing') @@ -1131,6 +1210,35 @@ m_divisor is 1091269979 ''' self.do_run(src, '*1,10,10.5,1,1.2340,0.00*') + def test_globaldoubles(self): + src = r''' + #include <stdlib.h> + #include <stdio.h> + + double testVu, testVv, testWu, testWv; + + void Test(double _testVu, double _testVv, double _testWu, double _testWv) + { + testVu = _testVu; + testVv = _testVv; + testWu = _testWu; + testWv = _testWv; + printf("BUG?\n"); + printf("Display: Vu=%f Vv=%f Wu=%f Wv=%f\n", testVu, testVv, testWu, testWv); + } + + int main(void) + { + double v1 = 465.1; + double v2 = 465.2; + double v3 = 160.3; + double v4 = 111.4; + Test(v1, v2, v3, v4); + return 0; + } + ''' + self.do_run(src, 'BUG?\nDisplay: Vu=465.100000 Vv=465.200000 Wu=160.300000 Wv=111.400000') + def test_math(self): src = ''' #include <stdio.h> @@ -1341,6 +1449,48 @@ m_divisor is 1091269979 ''' self.do_run(src, '4:10,177,543,def\n4\nwowie\ntoo\n76\n5\n(null)\n/* a comment */\n// another\ntest\n', ['wowie', 'too', '74']) + def test_strndup(self): + src = ''' + //--------------- + //- http://pubs.opengroup.org/onlinepubs/9699919799/functions/strndup.html + //--------------- + + #include <stdio.h> + #include <stdlib.h> + #include <string.h> + + int main(int argc, char **argv) { + const char* source = "strndup - duplicate a specific number of bytes from a string"; + + char* strdup_val = strndup(source, 0); + printf("1:%s\\n", strdup_val); + free(strdup_val); + + strdup_val = strndup(source, 7); + printf("2:%s\\n", strdup_val); + free(strdup_val); + + strdup_val = strndup(source, 1000); + printf("3:%s\\n", strdup_val); + free(strdup_val); + + strdup_val = strndup(source, 60); + printf("4:%s\\n", strdup_val); + free(strdup_val); + + strdup_val = strndup(source, 19); + printf("5:%s\\n", strdup_val); + free(strdup_val); + + strdup_val = strndup(source, -1); + printf("6:%s\\n", strdup_val); + free(strdup_val); + + return 0; + } + ''' + self.do_run(src, '1:\n2:strndup\n3:strndup - duplicate a specific number of bytes from a string\n4:strndup - duplicate a specific number of bytes from a string\n5:strndup - duplicate\n6:\n') + def test_errar(self): src = r''' #include <stdio.h> @@ -1630,6 +1780,9 @@ m_divisor is 1091269979 if self.emcc_args is None: if Building.LLVM_OPTS: return self.skip('optimizing bitcode before emcc can confuse libcxx inclusion') self.emcc_args = [] # libc++ auto-inclusion is only done if we use emcc + else: + if '-O2' in self.emcc_args: + self.emcc_args += ['--closure', '1'] # Use closure here for some additional coverage src = ''' #include <stdio.h> @@ -1710,6 +1863,8 @@ m_divisor is 1091269979 def test_uncaught_exception(self): if self.emcc_args is None: return self.skip('no libcxx inclusion without emcc') + if '-O2' in self.emcc_args: + self.emcc_args += ['--closure', '1'] # Use closure here for some additional coverage Settings.EXCEPTION_DEBUG = 0 # Messes up expected output. Settings.DISABLE_EXCEPTION_CATCHING = 0 @@ -2323,10 +2478,15 @@ m_divisor is 1091269979 #include <stdio.h> #include "emscripten.h" + extern "C" { + void EMSCRIPTEN_KEEPALIVE save_me_aimee() { printf("mann\n"); } + } + int main() { // EMSCRIPTEN_COMMENT("hello from the source"); emscripten_run_script("Module.print('hello world' + '!')"); printf("*%d*\n", emscripten_run_script_int("5*20")); + emscripten_run_script("_save_me_aimee()"); return 0; } ''' @@ -2337,7 +2497,7 @@ def process(filename): # TODO: restore this (see comment in emscripten.h) assert '// hello from the source' in src ''' - self.do_run(src, 'hello world!\n*100*', post_build=check) + self.do_run(src, 'hello world!\n*100*\nmann\n', post_build=check) def test_inlinejs(self): src = r''' @@ -2697,7 +2857,7 @@ def process(filename): output = Popen(['python', EMCC, all_name], stderr=PIPE).communicate() # Check for warning in the generated code generated = open(os.path.join(self.get_dir(), 'src.cpp.o.js')).read() - assert 'Casting a function pointer type to another with a different number of arguments.' in output[1], 'Missing expected warning' + assert 'Casting a function pointer type to another with a different number of arguments' in output[1], 'Missing expected warning' def test_stdlibs(self): if Settings.USE_TYPED_ARRAYS == 2: @@ -2799,6 +2959,45 @@ def process(filename): extra_emscripten_args=['-H', 'libc/time.h']) #extra_emscripten_args=['-H', 'libc/fcntl.h,libc/sys/unistd.h,poll.h,libc/math.h,libc/langinfo.h,libc/time.h']) + def test_intentional_fault(self): + # Some programs intentionally segfault themselves, we should compile that into a throw + src = r''' + int main () { + *(volatile char *)0 = 0; + return 0; + } + ''' + self.do_run(src, 'fault on write to 0') + + def test_trickystring(self): + src = r''' + #include <stdio.h> + + typedef struct + { + int (*f)(void *); + void *d; + char s[16]; + } LMEXFunctionStruct; + + int f(void *user) + { + return 0; + } + + static LMEXFunctionStruct const a[] = + { + {f, (void *)(int)'a', "aa"} + }; + + int main() + { + printf("ok\n"); + return a[0].f(a[0].d); + } + ''' + self.do_run(src, 'ok\n') + def test_statics(self): # static initializers save i16 but load i8 for some reason if Settings.SAFE_HEAP: @@ -3541,9 +3740,14 @@ def process(filename): printf("%g\n", strtod("0", &endptr)); printf("%g\n", strtod("0.", &endptr)); printf("%g\n", strtod("0.0", &endptr)); + printf("%g\n", strtod("-0.0", &endptr)); printf("%g\n", strtod("1", &endptr)); printf("%g\n", strtod("1.", &endptr)); printf("%g\n", strtod("1.0", &endptr)); + printf("%g\n", strtod("z1.0", &endptr)); + printf("%g\n", strtod("0.5", &endptr)); + printf("%g\n", strtod(".5", &endptr)); + printf("%g\n", strtod(".a5", &endptr)); printf("%g\n", strtod("123", &endptr)); printf("%g\n", strtod("123.456", &endptr)); printf("%g\n", strtod("-123.456", &endptr)); @@ -3565,9 +3769,14 @@ def process(filename): 0 0 0 + 0 1 1 1 + 0 + 0.5 + 0.5 + 0 123 123.456 -123.456 @@ -3583,6 +3792,7 @@ def process(filename): ''' self.do_run(src, re.sub(r'\n\s+', '\n', expected)) + self.do_run(src.replace('strtod', 'strtold'), re.sub(r'\n\s+', '\n', expected)) # XXX add real support for long double def test_strtok(self): src = r''' @@ -3763,12 +3973,38 @@ at function.:blag sscanf("-3.03", "%f", &a); printf("%.4f\n", a); + char buffy[100]; + sscanf("cheez some thing moar 123\nyet more\n", "cheez %s", buffy); + printf("|%s|\n", buffy); + sscanf("cheez something\nmoar 123\nyet more\n", "cheez %s", buffy); + printf("|%s|\n", buffy); + sscanf("cheez somethingmoar\tyet more\n", "cheez %s", buffy); + printf("|%s|\n", buffy); + + int numverts = -1; + printf("%d\n", sscanf(" numverts 1499\n", " numverts %d", &numverts)); // white space is the same, even if tab vs space + printf("%d\n", numverts); + + int index; + float u, v; + short start, count; + printf("%d\n", sscanf(" vert 87 ( 0.481565 0.059481 ) 0 1\n", " vert %d ( %f %f ) %hu %hu", &index, &u, &v, &start, &count)); + printf("%d,%.6f,%.6f,%hu,%hu\n", index, u, v, start, count); + + int neg, neg2, neg3 = 0; + printf("%d\n", sscanf("-123 -765 -34-6", "%d %u %d", &neg, &neg2, &neg3)); + printf("%d,%u,%d\n", neg, neg2, neg3); + return 0; } ''' - self.do_run(src, 'en-us : 2\nen-r : 99\nen : 3\n1.234567, 0.000000\n-3.0300') + self.do_run(src, 'en-us : 2\nen-r : 99\nen : 3\n1.234567, 0.000000\n-3.0300\n|some|\n|something|\n|somethingmoar|\n' + + '1\n1499\n' + + '5\n87,0.481565,0.059481,0,1\n' + + '3\n-123,4294966531,-34\n') - # Part 2: doubles + def test_sscanf_2(self): + # doubles if Settings.USE_TYPED_ARRAYS == 2: for ftype in ['float', 'double']: src = r''' @@ -3839,8 +4075,9 @@ def process(filename): var Module = { 'noFSInit': true, 'preRun': function() { - FS.createDataFile('/', 'somefile.binary', [100, 200, 50, 25, 10, 77, 123], true, false); // 200 becomes -56, since signed chars are used in memory FS.createLazyFile('/', 'test.file', 'test.file', true, false); + // Test FS_* exporting + Module['FS_createDataFile']('/', 'somefile.binary', [100, 200, 50, 25, 10, 77, 123], true, false); // 200 becomes -56, since signed chars are used in memory var test_files_input = 'hi there!'; var test_files_input_index = 0; FS.init(function() { @@ -3890,6 +4127,20 @@ def process(filename): ''' self.do_run(src, 'isatty? 0,0,1\ngot: 35\ngot: 45\ngot: 25\ngot: 15\n', post_build=post) + def test_fgetc_unsigned(self): + if self.emcc_args is None: return self.skip('requires emcc') + src = r''' + #include <stdio.h> + int main() { + FILE *file = fopen("file_with_byte_234.txt", "rb"); + int c = fgetc(file); + printf("*%d\n", c); + } + ''' + open('file_with_byte_234.txt', 'wb').write('\xea') + self.emcc_args += ['--embed-file', 'file_with_byte_234.txt'] + self.do_run(src, '*234\n') + def test_folders(self): add_pre_run = ''' def process(filename): @@ -4581,6 +4832,43 @@ def process(filename): self.do_run(src, '*15,15*\n*15,10*\n*6,10*\n*10,0*\n*7,1*') + def test_phiundef(self): + src = r''' +#include <stdlib.h> +#include <stdio.h> + +static int state; + +struct my_struct { + union { + struct { + unsigned char a; + unsigned char b; + } c; + unsigned int d; + } e; + unsigned int f; +}; + +int main(int argc, char **argv) { + struct my_struct r; + + state = 0; + + for (int i=0;i<argc+10;i++) + { + if (state % 2 == 0) + r.e.c.a = 3; + else + printf("%d\n", r.e.c.a); + state++; + } + return 0; +} + ''' + + self.do_run(src, '3\n3\n3\n3\n3\n') + # libc++ tests def test_iostream(self): @@ -4806,6 +5094,8 @@ def process(filename): # print opt, "FAIL" def test_lua(self): + if self.emcc_args is None and Building.LLVM_OPTS: return self.skip('llvm 3.1 and safe llvm opts break lua') + try: os.environ['EMCC_LEAVE_INPUTS_RAW'] = '1' @@ -4903,7 +5193,7 @@ def process(filename): self.do_run(r''' #define SQLITE_DISABLE_LFS #define LONGDOUBLE_TYPE double - #define SQLITE_INT64_TYPE int + #define SQLITE_INT64_TYPE long long int #define SQLITE_THREADSAFE 0 ''' + open(path_from_root('tests', 'sqlite', 'sqlite3.c'), 'r').read() + open(path_from_root('tests', 'sqlite', 'benchmark.c'), 'r').read(), @@ -5281,6 +5571,7 @@ def process(filename): ret = ccall('print_int', null, ['number'], [12]); Module.print(typeof ret); ret = ccall('print_float', null, ['number'], [14.56]); Module.print(typeof ret); ret = ccall('print_string', null, ['string'], ["cheez"]); Module.print(typeof ret); + ret = ccall('print_string', null, ['array'], [[97, 114, 114, 45, 97, 121, 0]]); Module.print(typeof ret); ret = ccall('multi', 'number', ['number', 'number', 'number', 'string'], [2, 1.4, 3, 'more']); Module.print([typeof ret, ret]); var p = ccall('malloc', 'pointer', ['number'], [4]); setValue(p, 650, 'i32'); @@ -5304,7 +5595,7 @@ def process(filename): Settings.EXPORTED_FUNCTIONS = ['_get_int', '_get_float', '_get_string', '_print_int', '_print_float', '_print_string', '_multi', '_pointer', '_malloc'] - self.do_run(src, '*\nnumber,5\nnumber,3.14\nstring,hello world\n12\nundefined\n14.56\nundefined\ncheez\nundefined\nmore\nnumber,10\n650\nnumber,21\n*\natr\n10\nbret\n53\n*\nstack is ok.\n', post_build=post) + self.do_run(src, '*\nnumber,5\nnumber,3.14\nstring,hello world\n12\nundefined\n14.56\nundefined\ncheez\nundefined\narr-ay\nundefined\nmore\nnumber,10\n650\nnumber,21\n*\natr\n10\nbret\n53\n*\nstack is ok.\n', post_build=post) def test_scriptaclass(self): header_filename = os.path.join(self.get_dir(), 'header.h') @@ -5367,6 +5658,7 @@ def process(filename): int value; public: Parent(int val); + Parent(Parent *p, Parent *q); // overload constructor int getVal() { return value; }; // inline should work just fine here, unlike Way 1 before void mulVal(int mul); }; @@ -5404,6 +5696,7 @@ def process(filename): #include "header.h" Parent::Parent(int val) : value(val) { printf("Parent:%d\\n", val); } + Parent::Parent(Parent *p, Parent *q) : value(p->value + q->value) { printf("Parent:%d\\n", value); } void Parent::mulVal(int mul) { value *= mul; } #include "bindingtest.cpp" @@ -6029,6 +6322,120 @@ def process(filename): ''' self.do_run(src, 'hello, world!\ncleanup\nExit Status: 118') + def test_gc(self): + if self.emcc_args == None: return self.skip('needs ta2') + + Settings.GC_SUPPORT = 1 + + src = r''' + #include <stdio.h> + #include <gc.h> + #include <assert.h> + + void *global; + + void finalizer(void *ptr, void *arg) { + printf("finalizing %d (global == %d)\n", (int)arg, ptr == global); + } + + void finalizer2(void *ptr, void *arg) { + printf("finalizing2 %d (global == %d)\n", (int)arg, ptr == global); + } + + int main() { + GC_INIT(); + + void *local, *local2, *local3, *local4; + + // Hold on to global, drop locals + + global = GC_MALLOC(1024); // rooted since in a static allocation + GC_REGISTER_FINALIZER_NO_ORDER(global, finalizer, 0, 0, 0); + printf("alloc %p\n", global); + + local = GC_MALLOC(1024); // not rooted since stack is not scanned + GC_REGISTER_FINALIZER_NO_ORDER(local, finalizer, (void*)1, 0, 0); + printf("alloc %p\n", local); + + assert((char*)local - (char*)global >= 1024 || (char*)global - (char*)local >= 1024); + + local2 = GC_MALLOC(1024); // no finalizer + printf("alloc %p\n", local2); + + local3 = GC_MALLOC(1024); // with finalizable2 + GC_REGISTER_FINALIZER_NO_ORDER(local3, finalizer2, (void*)2, 0, 0); + printf("alloc %p\n", local); + + local4 = GC_MALLOC(1024); // yet another + GC_REGISTER_FINALIZER_NO_ORDER(local4, finalizer2, (void*)3, 0, 0); + printf("alloc %p\n", local); + + printf("basic test\n"); + + GC_FORCE_COLLECT(); + + printf("*\n"); + + GC_FREE(global); // force free will actually work + + // scanning inside objects + + global = GC_MALLOC(12); + GC_REGISTER_FINALIZER_NO_ORDER(global, finalizer, 0, 0, 0); + local = GC_MALLOC(12); + GC_REGISTER_FINALIZER_NO_ORDER(local, finalizer, (void*)1, 0, 0); + local2 = GC_MALLOC_ATOMIC(12); + GC_REGISTER_FINALIZER_NO_ORDER(local2, finalizer, (void*)2, 0, 0); + local3 = GC_MALLOC(12); + GC_REGISTER_FINALIZER_NO_ORDER(local3, finalizer, (void*)3, 0, 0); + local4 = GC_MALLOC(12); + GC_REGISTER_FINALIZER_NO_ORDER(local4, finalizer, (void*)4, 0, 0); + + void **globalData = (void**)global; + globalData[0] = local; + globalData[1] = local2; + + void **localData = (void**)local; + localData[0] = local3; + + void **local2Data = (void**)local2; + local2Data[0] = local4; // actually ignored, because local2 is atomic, so 4 is freeable + + printf("object scan test test\n"); + + GC_FORCE_COLLECT(); + + printf("*\n"); + + GC_FREE(global); // force free will actually work + + printf("*\n"); + + GC_FORCE_COLLECT(); + + printf(".\n"); + + global = 0; + + return 0; + } + ''' + self.do_run(src, '''basic test +finalizing 1 (global == 0) +finalizing2 2 (global == 0) +finalizing2 3 (global == 0) +* +finalizing 0 (global == 1) +object scan test test +finalizing 4 (global == 0) +* +finalizing 0 (global == 1) +* +finalizing 1 (global == 0) +finalizing 2 (global == 0) +finalizing 3 (global == 0) +. +''') # Generate tests for everything def make_run(fullname, name=-1, compiler=-1, llvm_opts=0, embetter=0, quantum_size=0, typed_arrays=0, emcc_args=None): @@ -6121,11 +6528,15 @@ TT = %s # --version output = Popen(['python', compiler, '--version'], stdout=PIPE, stderr=PIPE).communicate() self.assertContained('''emcc (Emscripten GCC-like replacement) 2.0 -Copyright (C) 2011 the Emscripten authors. +Copyright (C) 2012 the Emscripten authors. This is free and open source software under the MIT license. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ''', output[0].replace('\r', ''), output[1].replace('\r', '')) + # -v, without input files + output = Popen(['python', compiler, '-v'], stdout=PIPE, stderr=PIPE).communicate() + self.assertContained('''clang version''', output[1].replace('\r', ''), output[1].replace('\r', '')) + # --help output = Popen(['python', compiler, '--help'], stdout=PIPE, stderr=PIPE).communicate() self.assertContained('''%s [options] file... @@ -6269,7 +6680,7 @@ Options that are modified or new in %s include: assert ('_puts(' in generated) == (opt_level >= 1), 'with opt >= 1, llvm opts are run and they should optimize printf to puts' assert ('function _malloc(bytes) {' in generated) == (not has_malloc), 'If malloc is needed, it should be there, if not not' assert 'function _main() {' in generated, 'Should be unminified, including whitespace' - assert 'function _dump' in generated, 'No inlining by default' + assert ('-O3' in (params+(bc_params or []))) or'function _dump' in generated, 'No inlining by default' # emcc -s RELOOP=1 src.cpp ==> should pass -s to emscripten.py. --typed-arrays is a convenient alias for -s USE_TYPED_ARRAYS for params, test, text in [ @@ -6354,6 +6765,26 @@ f.close() # TODO: test normal project linking, static and dynamic: get_library should not need to be told what to link! # TODO: deprecate llvm optimizations, dlmalloc, etc. in emscripten.py. + def test_catch_undef(self): + open(os.path.join(self.get_dir(), 'test.cpp'), 'w').write(r''' + #include <vector> + #include <stdio.h> + + class Test { + public: + std::vector<int> vector; + }; + + Test globalInstance; + + int main() { + printf("hello, world!\n"); + return 1; + } + ''') + Popen(['python', EMCC, os.path.join(self.get_dir(), 'test.cpp'), '-fcatch-undefined-behavior']).communicate() + self.assertContained('hello, world!', run_js(os.path.join(self.get_dir(), 'a.out.js'))) + def test_l_link(self): # Linking with -lLIBNAME and -L/DIRNAME should work @@ -6412,6 +6843,38 @@ f.close() Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), os.path.join(self.get_dir(), 'subdir', 'libfile.so'), '-L.']).communicate() self.assertContained('hello from lib', run_js(os.path.join(self.get_dir(), 'a.out.js'))) + def test_js_libraries(self): + open(os.path.join(self.get_dir(), 'main.cpp'), 'w').write(''' + #include <stdio.h> + extern "C" { + extern void printey(); + extern int calcey(int x, int y); + } + int main() { + printey(); + printf("*%d*\\n", calcey(10, 22)); + return 0; + } + ''') + open(os.path.join(self.get_dir(), 'mylib1.js'), 'w').write(''' + mergeInto(LibraryManager.library, { + printey: function() { + Module.print('hello from lib!'); + } + }); + ''') + open(os.path.join(self.get_dir(), 'mylib2.js'), 'w').write(''' + mergeInto(LibraryManager.library, { + calcey: function(x, y) { + return x + y; + } + }); + ''') + + Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--js-library', os.path.join(self.get_dir(), 'mylib1.js'), + '--js-library', os.path.join(self.get_dir(), 'mylib2.js')]).communicate() + self.assertContained('hello from lib!\n*32*\n', run_js(os.path.join(self.get_dir(), 'a.out.js'))) + def test_identical_basenames(self): # Issue 287: files in different dirs but with the same basename get confused as the same, # causing multiply defined symbol errors @@ -6445,6 +6908,30 @@ f.close() Popen(['python', EMCC, os.path.join(self.get_dir(), 'foo', 'main.o'), os.path.join(self.get_dir(), 'bar', 'main.o')]).communicate() self.assertContained('hello there', run_js(os.path.join(self.get_dir(), 'a.out.js'))) + def test_remove_duplicates(self): + # can happen with .a files. we do a best-effort, removing dupes + open(os.path.join(self.get_dir(), 'main.cpp'), 'w').write(''' + #include<stdio.h> + void printey() { printf("bye bye\\n"); } + int main() { + printey(); + return 0; + } + ''') + open(os.path.join(self.get_dir(), 'side.cpp'), 'w').write(''' + #include<stdio.h> + void printey() { printf("bye bye\\n"); } + ''') + + # without --remove-duplicates, we fail + err = Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), os.path.join(self.get_dir(), 'side.cpp')], stderr=PIPE).communicate()[1] + assert not os.path.exists('a.out.js') + assert 'multiply' in err + + # with it, we succeed + err = Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), os.path.join(self.get_dir(), 'side.cpp'), '--remove-duplicates'], stderr=PIPE).communicate()[1] + self.assertContained('bye bye', run_js(os.path.join(self.get_dir(), 'a.out.js'))) + def test_embed_file(self): open(os.path.join(self.get_dir(), 'somefile.txt'), 'w').write('''hello from a file with lots of data and stuff in it thank you very much''') open(os.path.join(self.get_dir(), 'main.cpp'), 'w').write(r''' @@ -6463,6 +6950,10 @@ f.close() Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--embed-file', 'somefile.txt']).communicate() self.assertContained('|hello from a file wi|', run_js(os.path.join(self.get_dir(), 'a.out.js'))) + # preload twice, should not err + Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--embed-file', 'somefile.txt', '--embed-file', 'somefile.txt']).communicate() + self.assertContained('|hello from a file wi|', run_js(os.path.join(self.get_dir(), 'a.out.js'))) + def test_multidynamic_link(self): # Linking the same dynamic library in will error, normally, since we statically link it, causing dupe symbols # A workaround is to use --ignore-dynamic-linking, see emcc --help for details @@ -6538,6 +7029,38 @@ f.close() Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--pre-js', 'before.js', '--post-js', 'after.js']).communicate() self.assertContained('hello from main\nhello from js\n', run_js(os.path.join(self.get_dir(), 'a.out.js'))) + def test_sdl_endianness(self): + open(os.path.join(self.get_dir(), 'main.cpp'), 'w').write(r''' + #include <stdio.h> + #include <SDL/SDL.h> + + int main() { + printf("%d, %d, %d\n", SDL_BYTEORDER, SDL_LIL_ENDIAN, SDL_BIG_ENDIAN); + return 0; + } + ''') + Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp')]).communicate() + self.assertContained('1234, 1234, 4321\n', run_js(os.path.join(self.get_dir(), 'a.out.js'))) + + def test_warn_undefined(self): + open(os.path.join(self.get_dir(), 'main.cpp'), 'w').write(r''' + #include <stdio.h> + + extern "C" { + void something(); + } + + int main() { + something(); + return 0; + } + ''') + output = Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), '-s', 'WARN_ON_UNDEFINED_SYMBOLS=1'], stderr=PIPE).communicate() + self.assertContained('Unresolved symbol: _something\n', output[1]) + + output = Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp')], stderr=PIPE).communicate() + self.assertNotContained('Unresolved symbol: _something\n', output[1]) + def test_prepost(self): open(os.path.join(self.get_dir(), 'main.cpp'), 'w').write(''' #include <stdio.h> @@ -6574,10 +7097,47 @@ f.close() open(os.path.join(self.get_dir(), 'a.out.js'), 'w').write(src) assert 'hello from main' in run_js(os.path.join(self.get_dir(), 'a.out.js')), 'main should print when called manually' + def test_prepost2(self): + open(os.path.join(self.get_dir(), 'main.cpp'), 'w').write(''' + #include <stdio.h> + int main() { + printf("hello from main\\n"); + return 0; + } + ''') + open(os.path.join(self.get_dir(), 'pre.js'), 'w').write(''' + var Module = { + preRun: function() { Module.print('pre-run') }, + }; + ''') + open(os.path.join(self.get_dir(), 'pre2.js'), 'w').write(''' + Module.postRun = function() { Module.print('post-run') }; + ''') + Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--pre-js', 'pre.js', '--pre-js', 'pre2.js']).communicate() + self.assertContained('pre-run\nhello from main\npost-run\n', run_js(os.path.join(self.get_dir(), 'a.out.js'))) + + def test_prepre(self): + open(os.path.join(self.get_dir(), 'main.cpp'), 'w').write(''' + #include <stdio.h> + int main() { + printf("hello from main\\n"); + return 0; + } + ''') + open(os.path.join(self.get_dir(), 'pre.js'), 'w').write(''' + var Module = { + preRun: [function() { Module.print('pre-run') }], + }; + ''') + open(os.path.join(self.get_dir(), 'pre2.js'), 'w').write(''' + Module.preRun.push(function() { Module.print('prepre') }); + ''') + Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--pre-js', 'pre.js', '--pre-js', 'pre2.js']).communicate() + self.assertContained('prepre\npre-run\nhello from main\n', run_js(os.path.join(self.get_dir(), 'a.out.js'))) + 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() - output = Popen([NODE_JS, COFFEESCRIPT, VARIABLE_ELIMINATOR], stdin=PIPE, stdout=PIPE).communicate(input)[0] + output = Popen([NODE_JS, COFFEESCRIPT, VARIABLE_ELIMINATOR, path_from_root('tools', 'eliminator', 'eliminator-test.js')], stdout=PIPE).communicate()[0] self.assertIdentical(expected, output) def test_fix_closure(self): @@ -6597,6 +7157,8 @@ f.close() ['simplifyExpressionsPre', 'optimizeShiftsConservative']), (path_from_root('tools', 'test-js-optimizer-t2.js'), open(path_from_root('tools', 'test-js-optimizer-t2-output.js')).read(), ['simplifyExpressionsPre', 'optimizeShiftsAggressive']), + (path_from_root('tools', 'test-js-optimizer-regs.js'), open(path_from_root('tools', 'test-js-optimizer-regs-output.js')).read(), + ['registerize']), ]: output = Popen([NODE_JS, JS_OPTIMIZER, input] + passes, stdin=PIPE, stdout=PIPE).communicate()[0] self.assertIdentical(expected, output.replace('\n\n', '\n')) @@ -6608,6 +7170,15 @@ f.close() assert 'foo.o: ' in output, '-%s failed to produce the right output: %s' % (opt, output) assert 'error' not in err, 'Unexpected stderr: ' + err + def test_scons(self): # also incidentally tests c++11 integration in llvm 3.1 + try_delete(os.path.join(self.get_dir(), 'test')) + shutil.copytree(path_from_root('tests', 'scons'), os.path.join(self.get_dir(), 'test')) + shutil.copytree(path_from_root('tools', 'scons', 'site_scons'), os.path.join(self.get_dir(), 'test', 'site_scons')) + os.chdir(os.path.join(self.get_dir(), 'test')) + Popen(['scons']).communicate() + output = run_js('scons_integration.js') + assert 'If you see this - the world is all right!' in output + def test_llvm_nativizer(self): # avoid impure_ptr problems etc. shutil.copyfile(path_from_root('tests', 'files.cpp'), os.path.join(self.get_dir(), 'files.cpp')) @@ -6632,36 +7203,125 @@ fscanfed: 10 - hello ''', output[0]) self.assertIdentical('texte\n', output[1]) + def test_emconfig(self): + output = Popen(['python', EMCONFIG, 'LLVM_ROOT'], stdout=PIPE, stderr=PIPE).communicate()[0] + assert output == LLVM_ROOT + "\n" + invalid = 'Usage: em-config VAR_NAME\n' + # Don't accept variables that do not exist + output = Popen(['python', EMCONFIG, 'VAR_WHICH_DOES_NOT_EXIST'], stdout=PIPE, stderr=PIPE).communicate()[0] + assert output == invalid + # Don't accept no arguments + output = Popen(['python', EMCONFIG], stdout=PIPE, stderr=PIPE).communicate()[0] + assert output == invalid + # Don't accept more than one variable + output = Popen(['python', EMCONFIG, 'LLVM_ROOT', 'EMCC'], stdout=PIPE, stderr=PIPE).communicate()[0] + assert output == invalid + # Don't accept arbitrary python code + output = Popen(['python', EMCONFIG, 'sys.argv[1]'], stdout=PIPE, stderr=PIPE).communicate()[0] + assert output == invalid + + def test_link_s(self): + # -s OPT=VALUE can conflict with -s as a linker option. We warn and ignore + open(os.path.join(self.get_dir(), 'main.cpp'), 'w').write(r''' + extern "C" { + void something(); + } + + int main() { + something(); + return 0; + } + ''') + open(os.path.join(self.get_dir(), 'supp.cpp'), 'w').write(r''' + #include <stdio.h> + + extern "C" { + void something() { + printf("yello\n"); + } + } + ''') + Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), '-o', 'main.o']).communicate() + Popen(['python', EMCC, os.path.join(self.get_dir(), 'supp.cpp'), '-o', 'supp.o']).communicate() + + output = Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.o'), '-s', os.path.join(self.get_dir(), 'supp.o'), '-s', 'SAFE_HEAP=1'], stderr=PIPE).communicate() + self.assertContained('emcc: warning: treating -s as linker option', output[1]) + output = run_js('a.out.js') + assert 'yello' in output, 'code works' + code = open('a.out.js').read() + assert 'SAFE_HEAP' in code, 'valid -s option had an effect' + + def test_crunch(self): + # crunch should not be run if a .crn exists that is more recent than the .dds + shutil.copyfile(path_from_root('tests', 'ship.dds'), 'ship.dds') + time.sleep(0.1) + Popen(['python', FILE_PACKAGER, 'test.data', '--pre-run', '--crunch=32', '--preload', 'ship.dds'], stdout=open('pre.js', 'w')).communicate() + assert os.stat('test.data').st_size < 0.25*os.stat('ship.dds').st_size, 'Compressed should be much smaller than dds' + crunch_time = os.stat('ship.crn').st_mtime + dds_time = os.stat('ship.dds').st_mtime + assert crunch_time > dds_time, 'Crunch is more recent' + # run again, should not recrunch! + time.sleep(0.1) + Popen(['python', FILE_PACKAGER, 'test.data', '--pre-run', '--crunch=32', '--preload', 'ship.dds'], stdout=open('pre.js', 'w')).communicate() + assert crunch_time == os.stat('ship.crn').st_mtime, 'Crunch is unchanged' + # update dds, so should recrunch + time.sleep(0.1) + os.utime('ship.dds', None) + Popen(['python', FILE_PACKAGER, 'test.data', '--pre-run', '--crunch=32', '--preload', 'ship.dds'], stdout=open('pre.js', 'w')).communicate() + assert crunch_time < os.stat('ship.crn').st_mtime, 'Crunch was changed' + elif 'browser' in str(sys.argv): # Browser tests. + # Run a server and a web page. When a test runs, we tell the server about it, + # which tells the web page, which then opens a window with the test. Doing + # it this way then allows the page to close() itself when done. + + def harness_server_func(q): + class TestServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): + def do_GET(s): + s.send_response(200) + s.send_header("Content-type", "text/html") + s.end_headers() + if s.path == '/run_harness': + s.wfile.write(open(path_from_root('tests', 'browser_harness.html')).read()) + else: + result = 'False' + if not q.empty(): + result = q.get() + s.wfile.write(result) + s.wfile.close() + httpd = BaseHTTPServer.HTTPServer(('localhost', 9999), TestServerHandler) + httpd.serve_forever() # test runner will kill us + + def server_func(dir, q): + class TestServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): + def do_GET(s): + if 'report_' in s.path: + q.put(s.path) + else: + filename = s.path[1:] + if os.path.exists(filename): + s.send_response(200) + s.send_header("Content-type", "text/html") + s.end_headers() + s.wfile.write(open(filename).read()) + s.wfile.close() + else: + s.send_response(500) + s.send_header("Content-type", "text/html") + s.end_headers() + os.chdir(dir) + httpd = BaseHTTPServer.HTTPServer(('localhost', 8888), TestServerHandler) + httpd.serve_forever() # test runner will kill us + class browser(RunnerCore): def __init__(self, *args, **kwargs): super(browser, self).__init__(*args, **kwargs) if hasattr(browser, 'harness_server'): return - - # Run a server and a web page. When a test runs, we tell the server about it, - # which tells the web page, which then opens a window with the test. Doing - # it this way then allows the page to close() itself when done. - def server_func(q): - class TestServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): - def do_GET(s): - s.send_response(200) - s.send_header("Content-type", "text/html") - s.end_headers() - if s.path == '/run_harness': - s.wfile.write(open(path_from_root('tests', 'browser_harness.html')).read()) - else: - result = 'False' - if not q.empty(): - result = q.get() - s.wfile.write(result) - s.wfile.close() - httpd = BaseHTTPServer.HTTPServer(('localhost', 9999), TestServerHandler) - httpd.serve_forever() # test runner will kill us browser.harness_queue = multiprocessing.Queue() - browser.harness_server = multiprocessing.Process(target=server_func, args=(browser.harness_queue,)) + browser.harness_server = multiprocessing.Process(target=harness_server_func, args=(browser.harness_queue,)) browser.harness_server.start() print '[Browser harness server on process %d]' % browser.harness_server.pid webbrowser.open_new('http://localhost:9999/run_harness') @@ -6672,44 +7332,29 @@ elif 'browser' in str(sys.argv): browser.harness_server.terminate() delattr(browser, 'harness_server') print '[Browser harness server terminated]' + # On Windows, shutil.rmtree() in tearDown() raises this exception if we do not wait a bit: + # WindowsError: [Error 32] The process cannot access the file because it is being used by another process. + time.sleep(0.1) def run_browser(self, html_file, message, expectedResult=None): if expectedResult is not None: try: - def server_func(q): - class TestServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): - def do_GET(s): - if 'report_' in s.path: - q.put(s.path) - else: - filename = s.path[1:] - if os.path.exists(filename): - s.send_response(200) - s.send_header("Content-type", "text/html") - s.end_headers() - s.wfile.write(open(filename).read()) - s.wfile.close() - else: - s.send_response(500) - s.send_header("Content-type", "text/html") - s.end_headers() - os.chdir(self.get_dir()) - httpd = BaseHTTPServer.HTTPServer(('localhost', 8888), TestServerHandler) - httpd.serve_forever() # test runner will kill us queue = multiprocessing.Queue() - server = multiprocessing.Process(target=server_func, args=(queue,)) + server = multiprocessing.Process(target=functools.partial(server_func, self.get_dir()), args=(queue,)) server.start() browser.harness_queue.put('http://localhost:8888/' + html_file) output = '[no http server activity]' start = time.time() - while time.time() - start < 5: + while time.time() - start < 60: if not queue.empty(): output = queue.get() break time.sleep(0.1) + self.assertIdentical(expectedResult, output) finally: server.terminate() + time.sleep(0.1) # see comment about Windows above else: webbrowser.open_new(os.path.abspath(html_file)) print 'A web browser window should have opened a page containing the results of a part of this test.' @@ -6778,9 +7423,9 @@ elif 'browser' in str(sys.argv): img.src = '%s'; }; Module['postRun'] = doReftest; - Module['preRun'] = function() { - setTimeout(doReftest, 0); // if run() throws an exception and postRun is not called, this will kick in - }; + Module['preRun'].push(function() { + setTimeout(doReftest, 1000); // if run() throws an exception and postRun is not called, this will kick in + }); ''' % basename) def test_html(self): @@ -6789,6 +7434,17 @@ elif 'browser' in str(sys.argv): output = Popen(['python', EMCC, path_from_root('tests', 'hello_world_sdl.cpp'), '-o', 'something.html', '--pre-js', 'reftest.js']).communicate() self.run_browser('something.html', 'You should see "hello, world!" and a colored cube.', '/report_result?0') + def build_native_lzma(self): + lzma_native = path_from_root('third_party', 'lzma.js', 'lzma-native') + if os.path.isfile(lzma_native) and os.access(lzma_native, os.X_OK): return + + cwd = os.getcwd() + try: + os.chdir(path_from_root('third_party', 'lzma.js')) + Popen(['sh', './doit.sh']).communicate() + finally: + os.chdir(cwd) + def test_compression(self): open(os.path.join(self.get_dir(), 'main.cpp'), 'w').write(self.with_report_result(r''' #include <stdio.h> @@ -6801,6 +7457,7 @@ elif 'browser' in str(sys.argv): } ''')) + self.build_native_lzma() Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), '-o', 'page.html', '--compression', '%s,%s,%s' % (path_from_root('third_party', 'lzma.js', 'lzma-native'), path_from_root('third_party', 'lzma.js', 'lzma-decoder.js'), @@ -6813,27 +7470,47 @@ elif 'browser' in str(sys.argv): def test_preload_file(self): open(os.path.join(self.get_dir(), 'somefile.txt'), 'w').write('''load me right before running the code please''') - open(os.path.join(self.get_dir(), 'main.cpp'), 'w').write(self.with_report_result(r''' - #include <stdio.h> - #include <string.h> - #include <emscripten.h> - int main() { - FILE *f = fopen("somefile.txt", "r"); - char buf[100]; - fread(buf, 1, 20, f); - buf[20] = 0; - fclose(f); - printf("|%s|\n", buf); + def make_main(path): + print path + open(os.path.join(self.get_dir(), 'main.cpp'), 'w').write(self.with_report_result(r''' + #include <stdio.h> + #include <string.h> + #include <emscripten.h> + int main() { + FILE *f = fopen("%s", "r"); + char buf[100]; + fread(buf, 1, 20, f); + buf[20] = 0; + fclose(f); + printf("|%%s|\n", buf); - int result = !strcmp("load me right before", buf); - REPORT_RESULT(); - return 0; - } - ''')) + int result = !strcmp("load me right before", buf); + REPORT_RESULT(); + return 0; + } + ''' % path)) + make_main('somefile.txt') Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--preload-file', 'somefile.txt', '-o', 'page.html']).communicate() self.run_browser('page.html', 'You should see |load me right before|.', '/report_result?1') + # By absolute path + + make_main(os.path.join(self.get_dir(), 'somefile.txt')) + Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--preload-file', os.path.join(self.get_dir(), 'somefile.txt'), '-o', 'page.html']).communicate() + self.run_browser('page.html', 'You should see |load me right before|.', '/report_result?1') + + # With FS.preloadFile + + open(os.path.join(self.get_dir(), 'pre.js'), 'w').write(''' + Module.preRun = function() { + FS.createPreloadedFile('/', 'someotherfile.txt', 'somefile.txt', true, false); + }; + ''') + make_main('someotherfile.txt') + Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--pre-js', 'pre.js', '-o', 'page.html']).communicate() + self.run_browser('page.html', 'You should see |load me right before|.', '/report_result?1') + def test_multifile(self): # a few files inside a directory self.clear() @@ -6903,6 +7580,7 @@ elif 'browser' in str(sys.argv): } ''')) + self.build_native_lzma() Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), '-o', 'page.html', '--preload-file', 'datafile.txt', '--preload-file', 'datafile2.txt', '--compression', '%s,%s,%s' % (path_from_root('third_party', 'lzma.js', 'lzma-native'), path_from_root('third_party', 'lzma.js', 'lzma-decoder.js'), @@ -6914,11 +7592,11 @@ elif 'browser' in str(sys.argv): self.run_browser('page.html', '', '/report_result?1') def test_sdl_image(self): - # load an image file, get pixel data + # load an image file, get pixel data. Also O2 coverage for --preload-file shutil.copyfile(path_from_root('tests', 'screenshot.jpg'), os.path.join(self.get_dir(), 'screenshot.jpg')) open(os.path.join(self.get_dir(), 'sdl_image.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_image.c')).read())) - Popen(['python', EMCC, os.path.join(self.get_dir(), 'sdl_image.c'), '--preload-file', 'screenshot.jpg', '-o', 'page.html']).communicate() + Popen(['python', EMCC, os.path.join(self.get_dir(), 'sdl_image.c'), '-O2', '--preload-file', 'screenshot.jpg', '-o', 'page.html']).communicate() self.run_browser('page.html', '', '/report_result?600') def test_sdl_image_compressed(self): @@ -6931,6 +7609,7 @@ elif 'browser' in str(sys.argv): shutil.copyfile(image, os.path.join(self.get_dir(), basename)) open(os.path.join(self.get_dir(), 'sdl_image.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_image.c')).read()).replace('screenshot.jpg', basename)) + self.build_native_lzma() Popen(['python', EMCC, os.path.join(self.get_dir(), 'sdl_image.c'), '--preload-file', basename, '-o', 'page.html', '--compression', '%s,%s,%s' % (path_from_root('third_party', 'lzma.js', 'lzma-native'), path_from_root('third_party', 'lzma.js', 'lzma-decoder.js'), @@ -6998,10 +7677,11 @@ elif 'browser' in str(sys.argv): Module['canvas'].dispatchEvent(event1); } } + window['simulateMouseEvent'] = simulateMouseEvent; ''') open(os.path.join(self.get_dir(), 'sdl_mouse.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_mouse.c')).read())) - Popen(['python', EMCC, os.path.join(self.get_dir(), 'sdl_mouse.c'), '-o', 'page.html', '--pre-js', 'pre.js']).communicate() + Popen(['python', EMCC, os.path.join(self.get_dir(), 'sdl_mouse.c'), '-O2', '--minify', '0', '-o', 'page.html', '--pre-js', 'pre.js']).communicate() self.run_browser('page.html', '', '/report_result?740') def test_sdl_audio(self): @@ -7013,6 +7693,75 @@ elif 'browser' in str(sys.argv): Popen(['python', EMCC, '-O2', '--minify', '0', os.path.join(self.get_dir(), 'sdl_audio.c'), '--preload-file', 'sound.ogg', '--preload-file', 'sound2.wav', '-o', 'page.html', '-s', 'EXPORTED_FUNCTIONS=["_main", "_play", "_play2"]']).communicate() self.run_browser('page.html', '', '/report_result?1') + def test_sdl_audio_quickload(self): + open(os.path.join(self.get_dir(), 'sdl_audio_quickload.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_audio_quickload.c')).read())) + + # use closure to check for a possible bug with closure minifying away newer Audio() attributes + Popen(['python', EMCC, '-O2', '--minify', '0', os.path.join(self.get_dir(), 'sdl_audio_quickload.c'), '-o', 'page.html', '-s', 'EXPORTED_FUNCTIONS=["_main", "_play"]']).communicate() + self.run_browser('page.html', '', '/report_result?1') + + def test_sdl_gl_read(self): + # SDL, OpenGL, readPixels + open(os.path.join(self.get_dir(), 'sdl_gl_read.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_gl_read.c')).read())) + Popen(['python', EMCC, os.path.join(self.get_dir(), 'sdl_gl_read.c'), '-o', 'something.html']).communicate() + self.run_browser('something.html', '.', '/report_result?1') + + def test_sdl_ogl(self): + # SDL, OpenGL, textures, immediate mode. Closure for more coverage + shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png')) + self.reftest(path_from_root('tests', 'screenshot-gray-purple.png')) + Popen(['python', EMCC, path_from_root('tests', 'sdl_ogl.c'), '-O2', '--minify', '0', '-o', 'something.html', '--pre-js', 'reftest.js', '--preload-file', 'screenshot.png']).communicate() + self.run_browser('something.html', 'You should see an image with gray at the top.', '/report_result?0') + + def test_sdl_ogl_defaultmatrixmode(self): + # SDL, OpenGL, textures, immediate mode. Closure for more coverage + shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png')) + self.reftest(path_from_root('tests', 'screenshot-gray-purple.png')) + Popen(['python', EMCC, path_from_root('tests', 'sdl_ogl_defaultMatrixMode.c'), '--minify', '0', '-o', 'something.html', '--pre-js', 'reftest.js', '--preload-file', 'screenshot.png']).communicate() + self.run_browser('something.html', 'You should see an image with gray at the top.', '/report_result?0') + + def test_sdl_ogl_p(self): + # Immediate mode with pointers + shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png')) + self.reftest(path_from_root('tests', 'screenshot-gray.png')) + Popen(['python', EMCC, path_from_root('tests', 'sdl_ogl_p.c'), '-o', 'something.html', '--pre-js', 'reftest.js', '--preload-file', 'screenshot.png']).communicate() + self.run_browser('something.html', 'You should see an image with gray at the top.', '/report_result?0') + + def test_sdl_fog_simple(self): + # SDL, OpenGL, textures, fog, immediate mode. Closure for more coverage + shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png')) + self.reftest(path_from_root('tests', 'screenshot-fog-simple.png')) + Popen(['python', EMCC, path_from_root('tests', 'sdl_fog_simple.c'), '-O2', '--minify', '0', '-o', 'something.html', '--pre-js', 'reftest.js', '--preload-file', 'screenshot.png']).communicate() + self.run_browser('something.html', 'You should see an image with fog.', '/report_result?0') + + def test_sdl_fog_negative(self): + # SDL, OpenGL, textures, fog, immediate mode. Closure for more coverage + shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png')) + self.reftest(path_from_root('tests', 'screenshot-fog-negative.png')) + Popen(['python', EMCC, path_from_root('tests', 'sdl_fog_negative.c'), '-o', 'something.html', '--pre-js', 'reftest.js', '--preload-file', 'screenshot.png']).communicate() + self.run_browser('something.html', 'You should see an image with fog.', '/report_result?0') + + def test_sdl_fog_density(self): + # SDL, OpenGL, textures, fog, immediate mode. Closure for more coverage + shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png')) + self.reftest(path_from_root('tests', 'screenshot-fog-density.png')) + Popen(['python', EMCC, path_from_root('tests', 'sdl_fog_density.c'), '-o', 'something.html', '--pre-js', 'reftest.js', '--preload-file', 'screenshot.png']).communicate() + self.run_browser('something.html', 'You should see an image with fog.', '/report_result?0') + + def test_sdl_fog_exp2(self): + # SDL, OpenGL, textures, fog, immediate mode. Closure for more coverage + shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png')) + self.reftest(path_from_root('tests', 'screenshot-fog-exp2.png')) + Popen(['python', EMCC, path_from_root('tests', 'sdl_fog_exp2.c'), '-o', 'something.html', '--pre-js', 'reftest.js', '--preload-file', 'screenshot.png']).communicate() + self.run_browser('something.html', 'You should see an image with fog.', '/report_result?0') + + def test_sdl_fog_linear(self): + # SDL, OpenGL, textures, fog, immediate mode. Closure for more coverage + shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png')) + self.reftest(path_from_root('tests', 'screenshot-fog-linear.png')) + Popen(['python', EMCC, path_from_root('tests', 'sdl_fog_linear.c'), '-o', 'something.html', '--pre-js', 'reftest.js', '--preload-file', 'screenshot.png']).communicate() + self.run_browser('something.html', 'You should see an image with fog.', '/report_result?0') + def test_worker(self): # Test running in a web worker output = Popen(['python', EMCC, path_from_root('tests', 'hello_world_worker.cpp'), '-o', 'worker.js'], stdout=PIPE, stderr=PIPE).communicate() @@ -7093,6 +7842,141 @@ elif 'browser' in str(sys.argv): Popen(['python', EMCC, program, '-o', 'program.html', '--pre-js', 'reftest.js'] + args).communicate() self.run_browser('program.html', '', '/report_result?0') + def btest(self, filename, expected=None, reference=None, reference_slack=0, args=[]): # TODO: use in all other tests + if not reference: + open(os.path.join(self.get_dir(), filename), 'w').write(self.with_report_result(open(path_from_root('tests', filename)).read())) + else: + expected = [str(i) for i in range(0, reference_slack+1)] + shutil.copyfile(path_from_root('tests', filename), os.path.join(self.get_dir(), filename)) + self.reftest(path_from_root('tests', reference)) + args += ['--pre-js', 'reftest.js'] + Popen(['python', EMCC, os.path.join(self.get_dir(), filename), '-o', 'test.html'] + args).communicate() + if type(expected) is str: expected = [expected] + self.run_browser('test.html', '.', ['/report_result?' + e for e in expected]) + + def test_emscripten_api(self): + self.btest('emscripten_api_browser.cpp', '1') + + def test_emscripten_fs_api(self): + self.btest('emscripten_fs_api_browser.cpp', '1') + + def test_gc(self): + self.btest('browser_gc.cpp', '1') + + def test_glshaderinfo(self): + self.btest('glshaderinfo.cpp', '1') + + def test_sdlglshader(self): + self.btest('sdlglshader.c', reference='sdlglshader.png', args=['--closure', '1']) + + def test_gl_ps(self): + # pointers and a shader + shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png')) + self.btest('gl_ps.c', reference='gl_ps.png', args=['--preload-file', 'screenshot.png']) + + def test_matrix_identity(self): + self.btest('gl_matrix_identity.c', expected=['-1882984448', '460451840']) + + def test_cubegeom_pre(self): + self.btest('cubegeom_pre.c', expected='-1472804742') + + def test_cubegeom_pre2(self): + self.btest('cubegeom_pre2.c', expected='-1472804742', args=['-s', 'GL_DEBUG=1']) # some coverage for GL_DEBUG not breaking the build + + def test_cubegeom_pre3(self): + self.btest('cubegeom_pre3.c', expected='-1472804742') + + def test_cubegeom(self): + self.btest('cubegeom.c', expected=['188641320', '1522377227']) + + def test_cubegeom_color(self): + self.btest('cubegeom_color.c', expected='588472350') + + def test_cubegeom_normal(self): + self.btest('cubegeom_normal.c', expected='752917084') + + def test_cubegeom_normal_dap(self): # draw is given a direct pointer to clientside memory, no element array buffer + self.btest('cubegeom_normal_dap.c', expected='752917084') + + def test_cubegeom_normal_dap_far(self): # indices do nto start from 0 + self.btest('cubegeom_normal_dap_far.c', expected='752917084') + + def test_cubegeom_normal_dap_far_range(self): # glDrawRangeElements + self.btest('cubegeom_normal_dap_far_range.c', expected='752917084') + + def test_cubegeom_normal_dap_far_glda(self): # use glDrawArrays + self.btest('cubegeom_normal_dap_far_glda.c', expected='-218745386') + + def test_cubegeom_normal_dap_far_glda_quad(self): # with quad + self.btest('cubegeom_normal_dap_far_glda_quad.c', expected='1757386625') + + def test_cubegeom_mt(self): + self.btest('cubegeom_mt.c', expected='-457159152') # multitexture + + def test_cubegeom_color2(self): + self.btest('cubegeom_color2.c', expected='1121999515') + + def test_cubegeom_texturematrix(self): + self.btest('cubegeom_texturematrix.c', expected='1297500583') + + def test_cubegeom_fog(self): + self.btest('cubegeom_fog.c', expected='1617140399') + + def test_cube_explosion(self): + self.btest('cube_explosion.c', expected='667220544') + + def test_sdl_canvas_palette(self): + self.btest('sdl_canvas_palette.c', reference='sdl_canvas_palette.png') + + def test_sdl_maprgba(self): + self.btest('sdl_maprgba.c', reference='sdl_maprgba.png', reference_slack=3) + + def zzztest_sdl_canvas_palette_2(self): # XXX disabled until we have proper automation + open(os.path.join(self.get_dir(), 'sdl_canvas_palette_2.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_canvas_palette_2.c')).read())) + open(os.path.join(self.get_dir(), 'pre.js'), 'w').write('Module[\'preRun\'] = function() { SDL.defaults.copyOnLock = false }') + + Popen(['python', EMCC, os.path.join(self.get_dir(), 'sdl_canvas_palette_2.c'), '-o', 'page.html', '--pre-js', 'pre.js']).communicate() + self.run_browser('page.html', '') + + def test_s3tc(self): + shutil.copyfile(path_from_root('tests', 'screenshot.dds'), os.path.join(self.get_dir(), 'screenshot.dds')) + self.btest('s3tc.c', reference='s3tc.png', args=['--preload-file', 'screenshot.dds']) + + def test_s3tc_crunch(self): + shutil.copyfile(path_from_root('tests', 'ship.dds'), 'ship.dds') + shutil.copyfile(path_from_root('tests', 'bloom.dds'), 'bloom.dds') + shutil.copyfile(path_from_root('tests', 'water.dds'), 'water.dds') + Popen(['python', FILE_PACKAGER, 'test.data', '--pre-run', '--crunch', '--preload', 'ship.dds', 'bloom.dds', 'water.dds'], stdout=open('pre.js', 'w')).communicate() + assert os.stat('test.data').st_size < 0.5*(os.stat('ship.dds').st_size+os.stat('bloom.dds').st_size+os.stat('water.dds').st_size), 'Compressed should be smaller than dds' + shutil.move('ship.dds', 'ship.donotfindme.dds') # make sure we load from the compressed + shutil.move('bloom.dds', 'bloom.donotfindme.dds') # make sure we load from the compressed + shutil.move('water.dds', 'water.donotfindme.dds') # make sure we load from the compressed + self.btest('s3tc_crunch.c', reference='s3tc_crunch.png', args=['--pre-js', 'pre.js']) + + def test_aniso(self): + shutil.copyfile(path_from_root('tests', 'water.dds'), 'water.dds') + self.btest('aniso.c', reference='aniso.png', reference_slack=2, args=['--preload-file', 'water.dds']) + + def test_tex_nonbyte(self): + self.btest('tex_nonbyte.c', reference='tex_nonbyte.png') + + def test_float_tex(self): + self.btest('float_tex.cpp', reference='float_tex.png') + + def test_pre_run_deps(self): + # Adding a dependency in preRun will delay run + open(os.path.join(self.get_dir(), 'pre.js'), 'w').write(''' + Module.preRun = function() { + addRunDependency(); + Module.print('preRun called, added a dependency...'); + setTimeout(function() { + Module.okk = 10; + removeRunDependency() + }, 2000); + }; + ''') + self.btest('pre_run_deps.cpp', expected='10', args=['--pre-js', 'pre.js']) + elif 'benchmark' in str(sys.argv): # Benchmarks. Run them with argument |benchmark|. To run a specific test, do # |benchmark.test_X|. @@ -7188,10 +8072,9 @@ elif 'benchmark' in str(sys.argv): try_delete(final_filename) output = Popen(['python', EMCC, filename, '-O3', - '-s', 'INLINING_LIMIT=0', '-s', 'TOTAL_MEMORY=100*1024*1024', '-s', 'FAST_MEMORY=10*1024*1024', '-o', final_filename] + emcc_args, stdout=PIPE, stderr=self.stderr_redirect).communicate() - assert os.path.exists(final_filename), 'Failed to compile file: ' + '\n'.join(output) + assert os.path.exists(final_filename), 'Failed to compile file: ' + output[0] # Run JS global total_times, tests_done @@ -7558,6 +8441,24 @@ elif 'sanity' in str(sys.argv): assert mtime(SANITY_FILE) >= mtime(CONFIG_FILE) self.assertNotContained(SANITY_FAIL_MESSAGE, output) + # emcc should be configurable directly from EM_CONFIG without any config file + restore() + config = open(CONFIG_FILE, 'r').read() + os.environ['EM_CONFIG'] = config + wipe() + dirname = tempfile.mkdtemp(prefix='emscripten_test_' + self.__class__.__name__ + '_', dir=TEMP_DIR) + open(os.path.join(dirname, 'main.cpp'), 'w').write(''' + #include <stdio.h> + int main() { + printf("hello from emcc with no config file\\n"); + return 0; + } + ''') + Popen(['python', EMCC, os.path.join(dirname, 'main.cpp'), '-o', os.path.join(dirname, 'a.out.js')]).communicate() + self.assertContained('hello from emcc with no config file', run_js(os.path.join(dirname, 'a.out.js'))) + del os.environ['EM_CONFIG'] + shutil.rmtree(dirname) + def test_emcc_caching(self): INCLUDING_MESSAGE = 'emcc: including X' BUILDING_MESSAGE = 'emcc: building X for cache' @@ -7600,9 +8501,10 @@ elif 'sanity' in str(sys.argv): assert os.path.exists(EMCC_CACHE) assert os.path.exists(os.path.join(EMCC_CACHE, libname + '.bc')) if libname == 'libcxx': - assert os.stat(os.path.join(EMCC_CACHE, libname + '.bc')).st_size > 4000000, 'libc++ is big' - assert os.stat(basebc_name).st_size > 4000000, 'libc++ is indeed big' - assert os.stat(dcebc_name).st_size < 2000000, 'Dead code elimination must remove most of libc++' + print os.stat(os.path.join(EMCC_CACHE, libname + '.bc')).st_size, os.stat(basebc_name).st_size, os.stat(dcebc_name).st_size + assert os.stat(os.path.join(EMCC_CACHE, libname + '.bc')).st_size > 2000000, 'libc++ is big' + assert os.stat(basebc_name).st_size > 2000000, 'libc++ is indeed big' + assert os.stat(dcebc_name).st_size < 1500000, 'Dead code elimination must remove most of libc++' finally: if emcc_debug: os.environ['EMCC_DEBUG'] = emcc_debug diff --git a/tests/s3tc.c b/tests/s3tc.c new file mode 100644 index 00000000..c2736feb --- /dev/null +++ b/tests/s3tc.c @@ -0,0 +1,158 @@ +/******************************************************************* + * * + * Using SDL With OpenGL * + * * + * Tutorial by Kyle Foley (sdw) * + * * + * http://gpwiki.org/index.php/SDL:Tutorials:Using_SDL_with_OpenGL * + * * + *******************************************************************/ + +/* +THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION +AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN. + +THE ORIGINAL AUTHOR IS KYLE FOLEY. + +THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY +OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF +MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, +ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE +RESULTING FROM THE USE, MODIFICATION, OR +REDISTRIBUTION OF THIS SOFTWARE. +*/ + +#include "SDL/SDL.h" +#include "SDL/SDL_image.h" +#include "SDL/SDL_opengl.h" + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +int hasext(const char *exts, const char *ext) // from cube2, zlib licensed +{ + int len = strlen(ext); + if(len) for(const char *cur = exts; (cur = strstr(cur, ext)); cur += len) + { + if((cur == exts || cur[-1] == ' ') && (cur[len] == ' ' || !cur[len])) return 1; + } + return 0; +} + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + + // Slightly different SDL initialization + if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { + printf("Unable to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // *new* + + screen = SDL_SetVideoMode( 640, 480, 16, SDL_OPENGL ); // *changed* + if ( !screen ) { + printf("Unable to set video mode: %s\n", SDL_GetError()); + return 1; + } + + // Check extensions + + const char *exts = (const char *)glGetString(GL_EXTENSIONS); + assert(hasext(exts, "GL_ARB_texture_compression")); + assert(hasext(exts, "GL_EXT_texture_compression_s3tc")); + + // Set the OpenGL state after creating the context with SDL_SetVideoMode + + glClearColor( 0, 0, 0, 0 ); + +#if !EMSCRIPTEN + glEnable( GL_TEXTURE_2D ); // Need this to display a texture XXX unnecessary in OpenGL ES 2.0/WebGL +#endif + + glViewport( 0, 0, 640, 480 ); + + glMatrixMode( GL_PROJECTION ); + GLfloat matrixData[] = { 2.0/640, 0, 0, 0, + 0, -2.0/480, 0, 0, + 0, 0, -1, 0, + -1, 1, 0, 1 }; + glLoadMatrixf(matrixData); // test loadmatrix + + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + + + // Load the OpenGL texture + + GLuint texture; + + #define DDS_SIZE 262272 + FILE *dds = fopen("screenshot.dds", "rb"); + char *ddsdata = (char*)malloc(512*512*4);//DDS_SIZE); + assert(fread(ddsdata, 1, DDS_SIZE, dds) == DDS_SIZE); + fclose(dds); + + glGenTextures( 1, &texture ); + glBindTexture( GL_TEXTURE_2D, texture ); + + assert(!glGetError()); + glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, 512, 512, 0, DDS_SIZE-128, ddsdata+128); + assert(!glGetError()); + + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + + + // Prepare and Render + + // Clear the screen before drawing + glClear( GL_COLOR_BUFFER_BIT ); + + // Bind the texture to which subsequent calls refer to + glBindTexture( GL_TEXTURE_2D, texture ); + + // Use clientside vertex pointers to render two items + GLfloat vertexData[] = { 0, 0, 10, 10, // texture2, position2 + 1, 0, 300, 10, + 1, 1, 300, 128, + 0, 1, 10, 128, + 0, 0.5, 410, 10, + 1, 0.5, 600, 10, + 1, 1, 630, 200, + 0.5, 1, 310, 250 }; + + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, 4*4, &vertexData[0]); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 4*4, &vertexData[2]); + + glDrawArrays(GL_QUADS, 0, 8); + + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + + // Render the last item using oldschool glBegin etc + glBegin( GL_TRIANGLE_STRIP ); + glTexCoord2i( 0, 0 ); glVertex3f( 100, 300, 0 ); + glTexCoord2i( 1, 0 ); glVertex3f( 300, 300, 0 ); + glTexCoord2i( 1, 1 ); glVertex3f( 300, 400, 0 ); + glTexCoord2i( 0, 1 ); glVertex3f( 500, 410, 0 ); + glEnd(); + + SDL_GL_SwapBuffers(); + +#if !EMSCRIPTEN + // Wait for 3 seconds to give us a chance to see the image + SDL_Delay(1500); +#endif + + // Now we can delete the OpenGL texture and close down SDL + glDeleteTextures( 1, &texture ); + + SDL_Quit(); + + return 0; +} diff --git a/tests/s3tc.png b/tests/s3tc.png Binary files differnew file mode 100644 index 00000000..893ab397 --- /dev/null +++ b/tests/s3tc.png diff --git a/tests/s3tc_crunch.c b/tests/s3tc_crunch.c new file mode 100644 index 00000000..57974109 --- /dev/null +++ b/tests/s3tc_crunch.c @@ -0,0 +1,210 @@ +/******************************************************************* + * * + * Using SDL With OpenGL * + * * + * Tutorial by Kyle Foley (sdw) * + * * + * http://gpwiki.org/index.php/SDL:Tutorials:Using_SDL_with_OpenGL * + * * + *******************************************************************/ + +/* +THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION +AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN. + +THE ORIGINAL AUTHOR IS KYLE FOLEY. + +THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY +OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF +MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, +ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE +RESULTING FROM THE USE, MODIFICATION, OR +REDISTRIBUTION OF THIS SOFTWARE. +*/ + +#include "SDL/SDL.h" +#include "SDL/SDL_image.h" +#include "SDL/SDL_opengl.h" + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +int hasext(const char *exts, const char *ext) // from cube2, zlib licensed +{ + int len = strlen(ext); + if(len) for(const char *cur = exts; (cur = strstr(cur, ext)); cur += len) + { + if((cur == exts || cur[-1] == ' ') && (cur[len] == ' ' || !cur[len])) return 1; + } + return 0; +} + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + + // Slightly different SDL initialization + if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { + printf("Unable to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // *new* + + screen = SDL_SetVideoMode( 640, 480, 16, SDL_OPENGL ); // *changed* + if ( !screen ) { + printf("Unable to set video mode: %s\n", SDL_GetError()); + return 1; + } + + // Check extensions + + const char *exts = (const char *)glGetString(GL_EXTENSIONS); + assert(hasext(exts, "GL_ARB_texture_compression")); + assert(hasext(exts, "GL_EXT_texture_compression_s3tc")); + + // Set the OpenGL state after creating the context with SDL_SetVideoMode + + glClearColor( 0, 0, 0, 0 ); + +#if !EMSCRIPTEN + glEnable( GL_TEXTURE_2D ); // Need this to display a texture XXX unnecessary in OpenGL ES 2.0/WebGL +#endif + + glViewport( 0, 0, 640, 480 ); + + glMatrixMode( GL_PROJECTION ); + GLfloat matrixData[] = { 2.0/640, 0, 0, 0, + 0, -2.0/480, 0, 0, + 0, 0, -1, 0, + -1, 1, 0, 1 }; + glLoadMatrixf(matrixData); // test loadmatrix + + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + + + // Load the OpenGL textures + + GLuint texture; + + { + const int DDS_SIZE = 65664; + FILE *dds = fopen("ship.dds", "rb"); + assert(dds); + char *ddsdata = (char*)malloc(DDS_SIZE); + assert(fread(ddsdata, 1, DDS_SIZE, dds) == DDS_SIZE); + fclose(dds); + + glGenTextures( 1, &texture ); + glBindTexture( GL_TEXTURE_2D, texture ); + + assert(!glGetError()); + glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, 256, 256, 0, DDS_SIZE-128, ddsdata+128); + assert(!glGetError()); + + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + } + + // second texture + + GLuint texture2; + + { + const int DDS_SIZE = 32896; + FILE *dds = fopen("bloom.dds", "rb"); + assert(dds); + char *ddsdata = (char*)malloc(DDS_SIZE); + assert(fread(ddsdata, 1, DDS_SIZE, dds) == DDS_SIZE); + fclose(dds); + + glGenTextures( 1, &texture2 ); + glBindTexture( GL_TEXTURE_2D, texture2 ); + + assert(!glGetError()); + glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 256, 256, 0, DDS_SIZE-128, ddsdata+128); + assert(!glGetError()); + + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + } + + // third, a non-square texture with mipmaps + + GLuint texture3; + + { + const int DDS_SIZE = 43920; + FILE *dds = fopen("water.dds", "rb"); + assert(dds); + char *ddsdata = (char*)malloc(DDS_SIZE); + assert(fread(ddsdata, 1, DDS_SIZE, dds) == DDS_SIZE); + fclose(dds); + + glGenTextures( 1, &texture3 ); + glBindTexture( GL_TEXTURE_2D, texture3 ); + + assert(!glGetError()); + glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, 512, 64, 0, 512*64, ddsdata+128); + assert(!glGetError()); + + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + } + + // Prepare and Render + + // Clear the screen before drawing + glClear( GL_COLOR_BUFFER_BIT ); + + // Bind the texture to which subsequent calls refer to + glBindTexture( GL_TEXTURE_2D, texture ); + + // Use clientside vertex pointers to render two items + GLfloat vertexData[] = { 0, 0, 10, 10, // texture2, position2 + 1, 0, 300, 10, + 1, 1, 300, 128, + 0, 1, 10, 128, + 0, 0.5, 410, 10, + 1, 0.5, 600, 10, + 1, 1, 630, 200, + 0.5, 1, 310, 250 }; + + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, 4*4, &vertexData[0]); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 4*4, &vertexData[2]); + + glDrawArrays(GL_QUADS, 0, 4); + + glBindTexture( GL_TEXTURE_2D, texture3 ); + glDrawArrays(GL_QUADS, 4, 4); + + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + + // Render the last item using oldschool glBegin etc + glBindTexture( GL_TEXTURE_2D, texture2 ); + glBegin( GL_TRIANGLE_STRIP ); + glTexCoord2i( 0, 0 ); glVertex3f( 100, 300, 0 ); + glTexCoord2i( 1, 0 ); glVertex3f( 300, 300, 0 ); + glTexCoord2i( 1, 1 ); glVertex3f( 300, 400, 0 ); + glTexCoord2i( 0, 1 ); glVertex3f( 500, 410, 0 ); + glEnd(); + + SDL_GL_SwapBuffers(); + +#if !EMSCRIPTEN + // Wait for 3 seconds to give us a chance to see the image + SDL_Delay(1500); +#endif + + // Now we can delete the OpenGL texture and close down SDL + glDeleteTextures( 1, &texture ); + + SDL_Quit(); + + return 0; +} diff --git a/tests/s3tc_crunch.png b/tests/s3tc_crunch.png Binary files differnew file mode 100644 index 00000000..383d4c5b --- /dev/null +++ b/tests/s3tc_crunch.png diff --git a/tests/scons/SConstruct b/tests/scons/SConstruct new file mode 100644 index 00000000..facdff0a --- /dev/null +++ b/tests/scons/SConstruct @@ -0,0 +1,5 @@ +env = Environment() +env.Tool('emscripten') +env.Append(CXXFLAGS='-std=c++11') +env.Program('scons_integration', ['integration.cpp', 'other.c']) + diff --git a/tests/scons/integration.cpp b/tests/scons/integration.cpp new file mode 100644 index 00000000..c3d2031a --- /dev/null +++ b/tests/scons/integration.cpp @@ -0,0 +1,14 @@ + +#include <string> +#include <iostream> + +int main() { + std::string output("If you see this - the world is all right!"); + + auto func = [=](std::string text) -> int { + std::cout << text << std::endl; + return 5; + }; + + return func(output); +} diff --git a/tests/scons/other.c b/tests/scons/other.c new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/tests/scons/other.c diff --git a/tests/screenshot-fog-density.png b/tests/screenshot-fog-density.png Binary files differnew file mode 100644 index 00000000..cd1f6f1b --- /dev/null +++ b/tests/screenshot-fog-density.png diff --git a/tests/screenshot-fog-exp2.png b/tests/screenshot-fog-exp2.png Binary files differnew file mode 100644 index 00000000..cd5e6a63 --- /dev/null +++ b/tests/screenshot-fog-exp2.png diff --git a/tests/screenshot-fog-linear.png b/tests/screenshot-fog-linear.png Binary files differnew file mode 100644 index 00000000..57534566 --- /dev/null +++ b/tests/screenshot-fog-linear.png diff --git a/tests/screenshot-fog-negative.png b/tests/screenshot-fog-negative.png Binary files differnew file mode 100644 index 00000000..5b18a201 --- /dev/null +++ b/tests/screenshot-fog-negative.png diff --git a/tests/screenshot-fog-simple.png b/tests/screenshot-fog-simple.png Binary files differnew file mode 100644 index 00000000..527768fc --- /dev/null +++ b/tests/screenshot-fog-simple.png diff --git a/tests/screenshot-gray-purple.png b/tests/screenshot-gray-purple.png Binary files differnew file mode 100644 index 00000000..514b29a1 --- /dev/null +++ b/tests/screenshot-gray-purple.png diff --git a/tests/screenshot-gray.png b/tests/screenshot-gray.png Binary files differnew file mode 100644 index 00000000..16e45a7a --- /dev/null +++ b/tests/screenshot-gray.png diff --git a/tests/screenshot.dds b/tests/screenshot.dds Binary files differnew file mode 100644 index 00000000..de31ea11 --- /dev/null +++ b/tests/screenshot.dds diff --git a/tests/screenshot.png b/tests/screenshot.png Binary files differnew file mode 100644 index 00000000..44cf844a --- /dev/null +++ b/tests/screenshot.png diff --git a/tests/sdl_audio.c b/tests/sdl_audio.c index 4927d868..938df3c4 100644 --- a/tests/sdl_audio.c +++ b/tests/sdl_audio.c @@ -10,14 +10,23 @@ void play2(); void play() { int channel = Mix_PlayChannel(-1, sound, 1); - assert(channel >= 0); + assert(channel == 0); emscripten_run_script("setTimeout(Module['_play2'], 500)"); } +void done(int channel) { + assert(channel == 1); + + int result = 1; + REPORT_RESULT(); +} + void play2() { + Mix_ChannelFinished(done); + int channel2 = Mix_PlayChannel(-1, sound2, 1); - assert(channel2 >= 0); + assert(channel2 == 1); } int main(int argc, char **argv) { @@ -42,9 +51,6 @@ int main(int argc, char **argv) { printf("you should hear two sounds. press the button to replay!\n"); - int result = 1; - REPORT_RESULT(); - return 0; } diff --git a/tests/sdl_audio_quickload.c b/tests/sdl_audio_quickload.c new file mode 100644 index 00000000..1525d048 --- /dev/null +++ b/tests/sdl_audio_quickload.c @@ -0,0 +1,44 @@ +#include <stdio.h> +#include <stdlib.h> +#include <SDL/SDL.h> +#include <SDL/SDL_mixer.h> +#include <assert.h> +#include <limits.h> +#include <emscripten.h> + +Mix_Chunk *sound; + +void play() { + int channel = Mix_PlayChannel(-1, sound, 1); + assert(channel == 0); + + int result = 1; + REPORT_RESULT(); +} + +int main(int argc, char **argv) { + SDL_Init(SDL_INIT_AUDIO); + + int ret = Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 1024); + assert(ret == 0); + + Uint16* buffer = (Uint16*)malloc(10*44100*sizeof(Uint16)); + for (Uint32 i = 0; i < 10*44100; ++i) { + buffer[i] = (i * 5) % UINT32_MAX; + } + sound = Mix_QuickLoad_RAW((Uint8*) buffer, 10*44100*sizeof(Uint16)); + assert(sound); + + play(); + + emscripten_run_script("element = document.createElement('input');" + "element.setAttribute('type', 'button');" + "element.setAttribute('value', 'replay!');" + "element.setAttribute('onclick', 'Module[\"_play\"]()');" + "document.body.appendChild(element);"); + + printf("you should one sounds. press the button to replay!\n"); + + return 0; +} + diff --git a/tests/sdl_canvas_palette.c b/tests/sdl_canvas_palette.c new file mode 100644 index 00000000..316aa44a --- /dev/null +++ b/tests/sdl_canvas_palette.c @@ -0,0 +1,58 @@ +#include <stdio.h> +#include <SDL/SDL.h> +#include <emscripten.h> + +int main() { + SDL_Init(SDL_INIT_VIDEO); + SDL_Surface *screen = SDL_SetVideoMode(600, 400, 8, SDL_HWSURFACE | SDL_HWPALETTE); + + //initialize sdl palette + //with red green and blue + //colors + SDL_Color pal[3]; + pal[0].r = 255; + pal[0].g = 0; + pal[0].b = 0; + pal[0].unused = 0; + + pal[1].r = 0; + pal[1].g = 255; + pal[1].b = 0; + pal[1].unused = 0; + + pal[2].r = 0; + pal[2].g = 0; + pal[2].b = 255; + pal[2].unused = 0; + + SDL_SetColors(screen, pal, 0, 3); + + SDL_FillRect(screen, NULL, 0); + + { + SDL_Rect rect = { 300, 0, 300, 200 }; + SDL_FillRect(screen, &rect, 1); + } + + { + SDL_Rect rect = { 0, 200, 600, 200 }; + SDL_FillRect(screen, &rect, 2); + } + + //changing green color + //to yellow + pal[1].r = 255; + SDL_SetColors(screen, pal, 1, 1); + + { + SDL_Rect rect = { 300, 200, 300, 200 }; + SDL_FillRect(screen, &rect, 1); + } + + printf("you should see red, blue and yellow rectangles\n"); + + SDL_Quit(); + + return 0; +} + diff --git a/tests/sdl_canvas_palette.png b/tests/sdl_canvas_palette.png Binary files differnew file mode 100644 index 00000000..a52844b6 --- /dev/null +++ b/tests/sdl_canvas_palette.png diff --git a/tests/sdl_canvas_palette_2.c b/tests/sdl_canvas_palette_2.c new file mode 100644 index 00000000..db051b2b --- /dev/null +++ b/tests/sdl_canvas_palette_2.c @@ -0,0 +1,77 @@ +#include <stdio.h> +#include <SDL/SDL.h> +#include <emscripten.h> + +static const int COLOR_COUNT = 32; + +static SDL_Surface *screen; +static SDL_Color pal[COLOR_COUNT +1]; + +void initializePalette() { + //initialize sdl palette + //with red green and blue + //colors + pal[0].r = 0; + pal[0].g = 0; + pal[0].b = 0; + pal[0].unused = 0; + + for (int i=1; i< 1 + COLOR_COUNT; i++) { + pal[i].r = 255 / COLOR_COUNT * i; + pal[i].g = 0; + pal[i].b = 0; + pal[i].unused = 0; + } + + SDL_SetColors(screen, pal, 0, 1 + COLOR_COUNT); +} + +void animatePalette() { + SDL_Color temporary; + temporary = pal[1]; + for (int i=2; i< 1 + COLOR_COUNT; i++) { + pal[i-1] = pal[i]; + } + pal[COLOR_COUNT] = temporary; + + SDL_SetColors(screen, pal, 1, COLOR_COUNT); + + //refreshing + SDL_LockSurface(screen); + SDL_UnlockSurface(screen); + + printf("yet another cycle\n"); +} + +int main() { + SDL_Init(SDL_INIT_VIDEO); + screen = SDL_SetVideoMode(600, 400, 8, SDL_HWSURFACE | SDL_HWPALETTE); + + //test empty pallete + SDL_LockSurface(screen); + SDL_UnlockSurface(screen); + + initializePalette(); + + //palette is red yellow blue + SDL_LockSurface(screen); + int size = screen->h * screen->pitch; + char *color = screen->pixels; + int divider = size / COLOR_COUNT; + int i = 0; + while (i < size) { + *color = 1 + (i / divider); //red + color++; + i++; + } + SDL_UnlockSurface(screen); + + //Animation + printf("you should see red gradient animation\n"); + emscripten_set_main_loop(animatePalette, 0); + + SDL_Quit(); + + return 0; +} + diff --git a/tests/sdl_fog_density.c b/tests/sdl_fog_density.c new file mode 100644 index 00000000..95773419 --- /dev/null +++ b/tests/sdl_fog_density.c @@ -0,0 +1,183 @@ +/******************************************************************* + * * + * Using SDL With OpenGL * + * * + * Tutorial by Kyle Foley (sdw) * + * * + * http://gpwiki.org/index.php/SDL:Tutorials:Using_SDL_with_OpenGL * + * * + *******************************************************************/ + +/* +THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION +AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN. + +THE ORIGINAL AUTHOR IS KYLE FOLEY. + +THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY +OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF +MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, +ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE +RESULTING FROM THE USE, MODIFICATION, OR +REDISTRIBUTION OF THIS SOFTWARE. +*/ + +#include "SDL/SDL.h" +#include "SDL/SDL_image.h" +#include "SDL/SDL_opengl.h" + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + + // Slightly different SDL initialization + if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { + printf("Unable to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // *new* + + screen = SDL_SetVideoMode( 640, 480, 16, SDL_OPENGL ); // *changed* + if ( !screen ) { + printf("Unable to set video mode: %s\n", SDL_GetError()); + return 1; + } + + // Set the OpenGL state after creating the context with SDL_SetVideoMode + + glClearColor( 0, 0, 0, 0 ); + +#if !EMSCRIPTEN + glEnable( GL_TEXTURE_2D ); // Need this to display a texture XXX unnecessary in OpenGL ES 2.0/WebGL +#endif + + glViewport( 0, 0, 640, 480 ); + + glMatrixMode( GL_PROJECTION ); + glPushMatrix(); // just for testing + glLoadIdentity(); + + glOrtho( 0, 640, 480, 0, -1000, 1000 ); + + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + + // Load the OpenGL texture + + GLuint texture; // Texture object handle + SDL_Surface *surface; // Gives us the information to make the texture + + if ( (surface = IMG_Load("screenshot.png")) ) { + + // Check that the image's width is a power of 2 + if ( (surface->w & (surface->w - 1)) != 0 ) { + printf("warning: image.bmp's width is not a power of 2\n"); + } + + // Also check if the height is a power of 2 + if ( (surface->h & (surface->h - 1)) != 0 ) { + printf("warning: image.bmp's height is not a power of 2\n"); + } + + // Have OpenGL generate a texture object handle for us + glGenTextures( 1, &texture ); + + // Bind the texture object + glBindTexture( GL_TEXTURE_2D, texture ); + + // Set the texture's stretching properties + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + + //SDL_LockSurface(surface); + + // Add some greyness + memset(surface->pixels, 0x66, surface->w*surface->h); + + // Edit the texture object's image data using the information SDL_Surface gives us + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0, + GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels ); + + //SDL_UnlockSurface(surface); + } + else { + printf("SDL could not load image.bmp: %s\n", SDL_GetError()); + SDL_Quit(); + return 1; + } + + // Free the SDL_Surface only if it was successfully created + if ( surface ) { + SDL_FreeSurface( surface ); + } + + // Clear the screen before drawing + glClear( GL_COLOR_BUFFER_BIT ); + + // Bind the texture to which subsequent calls refer to + glBindTexture( GL_TEXTURE_2D, texture ); + + glEnable(GL_FOG); + GLfloat fogColor[] = { 1.0, 0.5, 0.5, 0.05 }; + glFogfv(GL_FOG_COLOR, fogColor); + glFogf(GL_FOG_DENSITY, 0.2); + + assert(glIsEnabled(GL_FOG)); + + glBegin( GL_QUADS ); + glTexCoord2i( 0, 0 ); glVertex3f( 10, 10, 10 ); + glTexCoord2i( 1, 0 ); glVertex3f( 300, 10, 10 ); + glTexCoord2i( 1, 1 ); glVertex3f( 300, 128, 10 ); + glTexCoord2i( 0, 1 ); glVertex3f( 10, 128, 10 ); + + glTexCoord2f( 0, 0.5 ); glVertex3f( 410, 10, 5 ); + glTexCoord2f( 1, 0.5 ); glVertex3f( 600, 10, 6 ); + glTexCoord2f( 1, 1 ); glVertex3f( 630, 200, 7 ); + glTexCoord2f( 0.5, 1 ); glVertex3f( 310, 250, 8 ); + glEnd(); + + glBegin( GL_TRIANGLE_STRIP ); + glTexCoord2i( 0, 0 ); glVertex3f( 100, 300, 1 ); + glTexCoord2i( 1, 0 ); glVertex3f( 300, 300, 1 ); + glTexCoord2i( 1, 1 ); glVertex3f( 300, 400, 1 ); + glTexCoord2i( 0, 1 ); glVertex3f( 500, 410, 1 ); + glEnd(); + +#if !EMSCRIPTEN + glDisable(GL_TEXTURE_2D); +#endif + + glColor3ub(90, 255, 255); + glBegin( GL_QUADS ); + glVertex3f( 10, 410, 5 ); + glVertex3f( 300, 410, 50 ); + glVertex3f( 300, 480, 100 ); + glVertex3f( 10, 470, 5 ); + glEnd(); + + glBegin( GL_QUADS ); + glColor3f(1.0, 0, 1.0); glVertex3f( 410, 410, 10 ); + glColor3f(0, 1.0, 0); glVertex3f( 600, 410, 10 ); + glColor3f(0, 0, 1.0); glVertex3f( 600, 480, 10 ); + glColor3f(1.0, 1.0, 1.0); glVertex3f( 410, 470, 10 ); + glEnd(); + + SDL_GL_SwapBuffers(); + +#if !EMSCRIPTEN + // Wait for 3 seconds to give us a chance to see the image + SDL_Delay(30000); +#endif + + // Now we can delete the OpenGL texture and close down SDL + glDeleteTextures( 1, &texture ); + + SDL_Quit(); + + return 0; +} diff --git a/tests/sdl_fog_exp2.c b/tests/sdl_fog_exp2.c new file mode 100644 index 00000000..a09a5e3d --- /dev/null +++ b/tests/sdl_fog_exp2.c @@ -0,0 +1,184 @@ +/******************************************************************* + * * + * Using SDL With OpenGL * + * * + * Tutorial by Kyle Foley (sdw) * + * * + * http://gpwiki.org/index.php/SDL:Tutorials:Using_SDL_with_OpenGL * + * * + *******************************************************************/ + +/* +THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION +AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN. + +THE ORIGINAL AUTHOR IS KYLE FOLEY. + +THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY +OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF +MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, +ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE +RESULTING FROM THE USE, MODIFICATION, OR +REDISTRIBUTION OF THIS SOFTWARE. +*/ + +#include "SDL/SDL.h" +#include "SDL/SDL_image.h" +#include "SDL/SDL_opengl.h" + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + + // Slightly different SDL initialization + if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { + printf("Unable to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // *new* + + screen = SDL_SetVideoMode( 640, 480, 16, SDL_OPENGL ); // *changed* + if ( !screen ) { + printf("Unable to set video mode: %s\n", SDL_GetError()); + return 1; + } + + // Set the OpenGL state after creating the context with SDL_SetVideoMode + + glClearColor( 0, 0, 0, 0 ); + +#if !EMSCRIPTEN + glEnable( GL_TEXTURE_2D ); // Need this to display a texture XXX unnecessary in OpenGL ES 2.0/WebGL +#endif + + glViewport( 0, 0, 640, 480 ); + + glMatrixMode( GL_PROJECTION ); + glPushMatrix(); // just for testing + glLoadIdentity(); + + glOrtho( 0, 640, 480, 0, -1000, 1000 ); + + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + + // Load the OpenGL texture + + GLuint texture; // Texture object handle + SDL_Surface *surface; // Gives us the information to make the texture + + if ( (surface = IMG_Load("screenshot.png")) ) { + + // Check that the image's width is a power of 2 + if ( (surface->w & (surface->w - 1)) != 0 ) { + printf("warning: image.bmp's width is not a power of 2\n"); + } + + // Also check if the height is a power of 2 + if ( (surface->h & (surface->h - 1)) != 0 ) { + printf("warning: image.bmp's height is not a power of 2\n"); + } + + // Have OpenGL generate a texture object handle for us + glGenTextures( 1, &texture ); + + // Bind the texture object + glBindTexture( GL_TEXTURE_2D, texture ); + + // Set the texture's stretching properties + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + + //SDL_LockSurface(surface); + + // Add some greyness + memset(surface->pixels, 0x66, surface->w*surface->h); + + // Edit the texture object's image data using the information SDL_Surface gives us + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0, + GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels ); + + //SDL_UnlockSurface(surface); + } + else { + printf("SDL could not load image.bmp: %s\n", SDL_GetError()); + SDL_Quit(); + return 1; + } + + // Free the SDL_Surface only if it was successfully created + if ( surface ) { + SDL_FreeSurface( surface ); + } + + // Clear the screen before drawing + glClear( GL_COLOR_BUFFER_BIT ); + + // Bind the texture to which subsequent calls refer to + glBindTexture( GL_TEXTURE_2D, texture ); + + glEnable(GL_FOG); + GLfloat fogColor[] = { 1.0, 0.5, 0.5, 0.05 }; + glFogfv(GL_FOG_COLOR, fogColor); + glFogf(GL_FOG_DENSITY, 0.2); + glFogi(GL_FOG_MODE, GL_EXP2); + + assert(glIsEnabled(GL_FOG)); + + glBegin( GL_QUADS ); + glTexCoord2i( 0, 0 ); glVertex3f( 10, 10, 10 ); + glTexCoord2i( 1, 0 ); glVertex3f( 300, 10, 10 ); + glTexCoord2i( 1, 1 ); glVertex3f( 300, 128, 10 ); + glTexCoord2i( 0, 1 ); glVertex3f( 10, 128, 10 ); + + glTexCoord2f( 0, 0.5 ); glVertex3f( 410, 10, 5 ); + glTexCoord2f( 1, 0.5 ); glVertex3f( 600, 10, 6 ); + glTexCoord2f( 1, 1 ); glVertex3f( 630, 200, 7 ); + glTexCoord2f( 0.5, 1 ); glVertex3f( 310, 250, 8 ); + glEnd(); + + glBegin( GL_TRIANGLE_STRIP ); + glTexCoord2i( 0, 0 ); glVertex3f( 100, 300, 1 ); + glTexCoord2i( 1, 0 ); glVertex3f( 300, 300, 1 ); + glTexCoord2i( 1, 1 ); glVertex3f( 300, 400, 1 ); + glTexCoord2i( 0, 1 ); glVertex3f( 500, 410, 1 ); + glEnd(); + +#if !EMSCRIPTEN + glDisable(GL_TEXTURE_2D); +#endif + + glColor3ub(90, 255, 255); + glBegin( GL_QUADS ); + glVertex3f( 10, 410, 5 ); + glVertex3f( 300, 410, 50 ); + glVertex3f( 300, 480, 100 ); + glVertex3f( 10, 470, 5 ); + glEnd(); + + glBegin( GL_QUADS ); + glColor3f(1.0, 0, 1.0); glVertex3f( 410, 410, 10 ); + glColor3f(0, 1.0, 0); glVertex3f( 600, 410, 10 ); + glColor3f(0, 0, 1.0); glVertex3f( 600, 480, 10 ); + glColor3f(1.0, 1.0, 1.0); glVertex3f( 410, 470, 10 ); + glEnd(); + + SDL_GL_SwapBuffers(); + +#if !EMSCRIPTEN + // Wait for 3 seconds to give us a chance to see the image + SDL_Delay(30000); +#endif + + // Now we can delete the OpenGL texture and close down SDL + glDeleteTextures( 1, &texture ); + + SDL_Quit(); + + return 0; +} diff --git a/tests/sdl_fog_linear.c b/tests/sdl_fog_linear.c new file mode 100644 index 00000000..8fc18b7c --- /dev/null +++ b/tests/sdl_fog_linear.c @@ -0,0 +1,185 @@ +/******************************************************************* + * * + * Using SDL With OpenGL * + * * + * Tutorial by Kyle Foley (sdw) * + * * + * http://gpwiki.org/index.php/SDL:Tutorials:Using_SDL_with_OpenGL * + * * + *******************************************************************/ + +/* +THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION +AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN. + +THE ORIGINAL AUTHOR IS KYLE FOLEY. + +THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY +OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF +MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, +ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE +RESULTING FROM THE USE, MODIFICATION, OR +REDISTRIBUTION OF THIS SOFTWARE. +*/ + +#include "SDL/SDL.h" +#include "SDL/SDL_image.h" +#include "SDL/SDL_opengl.h" + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + + // Slightly different SDL initialization + if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { + printf("Unable to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // *new* + + screen = SDL_SetVideoMode( 640, 480, 16, SDL_OPENGL ); // *changed* + if ( !screen ) { + printf("Unable to set video mode: %s\n", SDL_GetError()); + return 1; + } + + // Set the OpenGL state after creating the context with SDL_SetVideoMode + + glClearColor( 0, 0, 0, 0 ); + +#if !EMSCRIPTEN + glEnable( GL_TEXTURE_2D ); // Need this to display a texture XXX unnecessary in OpenGL ES 2.0/WebGL +#endif + + glViewport( 0, 0, 640, 480 ); + + glMatrixMode( GL_PROJECTION ); + glPushMatrix(); // just for testing + glLoadIdentity(); + + glOrtho( 0, 640, 480, 0, -1000, 1000 ); + + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + + // Load the OpenGL texture + + GLuint texture; // Texture object handle + SDL_Surface *surface; // Gives us the information to make the texture + + if ( (surface = IMG_Load("screenshot.png")) ) { + + // Check that the image's width is a power of 2 + if ( (surface->w & (surface->w - 1)) != 0 ) { + printf("warning: image.bmp's width is not a power of 2\n"); + } + + // Also check if the height is a power of 2 + if ( (surface->h & (surface->h - 1)) != 0 ) { + printf("warning: image.bmp's height is not a power of 2\n"); + } + + // Have OpenGL generate a texture object handle for us + glGenTextures( 1, &texture ); + + // Bind the texture object + glBindTexture( GL_TEXTURE_2D, texture ); + + // Set the texture's stretching properties + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + + //SDL_LockSurface(surface); + + // Add some greyness + memset(surface->pixels, 0x66, surface->w*surface->h); + + // Edit the texture object's image data using the information SDL_Surface gives us + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0, + GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels ); + + //SDL_UnlockSurface(surface); + } + else { + printf("SDL could not load image.bmp: %s\n", SDL_GetError()); + SDL_Quit(); + return 1; + } + + // Free the SDL_Surface only if it was successfully created + if ( surface ) { + SDL_FreeSurface( surface ); + } + + // Clear the screen before drawing + glClear( GL_COLOR_BUFFER_BIT ); + + // Bind the texture to which subsequent calls refer to + glBindTexture( GL_TEXTURE_2D, texture ); + + glEnable(GL_FOG); + GLfloat fogColor[] = { 1.0, 0.5, 0.5, 0.05 }; + glFogfv(GL_FOG_COLOR, fogColor); + glFogi(GL_FOG_START, 8); + glFogi(GL_FOG_END, 13); + glFogi(GL_FOG_MODE, GL_LINEAR); + + assert(glIsEnabled(GL_FOG)); + + glBegin( GL_QUADS ); + glTexCoord2i( 0, 0 ); glVertex3f( 10, 10, 10 ); + glTexCoord2i( 1, 0 ); glVertex3f( 300, 10, 10 ); + glTexCoord2i( 1, 1 ); glVertex3f( 300, 128, 10 ); + glTexCoord2i( 0, 1 ); glVertex3f( 10, 128, 10 ); + + glTexCoord2f( 0, 0.5 ); glVertex3f( 410, 10, 5 ); + glTexCoord2f( 1, 0.5 ); glVertex3f( 600, 10, 6 ); + glTexCoord2f( 1, 1 ); glVertex3f( 630, 200, 7 ); + glTexCoord2f( 0.5, 1 ); glVertex3f( 310, 250, 8 ); + glEnd(); + + glBegin( GL_TRIANGLE_STRIP ); + glTexCoord2i( 0, 0 ); glVertex3f( 100, 300, 1 ); + glTexCoord2i( 1, 0 ); glVertex3f( 300, 300, 1 ); + glTexCoord2i( 1, 1 ); glVertex3f( 300, 400, 1 ); + glTexCoord2i( 0, 1 ); glVertex3f( 500, 410, 1 ); + glEnd(); + +#if !EMSCRIPTEN + glDisable(GL_TEXTURE_2D); +#endif + + glColor3ub(90, 255, 255); + glBegin( GL_QUADS ); + glVertex3f( 10, 410, 5 ); + glVertex3f( 300, 410, 50 ); + glVertex3f( 300, 480, 100 ); + glVertex3f( 10, 470, 5 ); + glEnd(); + + glBegin( GL_QUADS ); + glColor3f(1.0, 0, 1.0); glVertex3f( 410, 410, 10 ); + glColor3f(0, 1.0, 0); glVertex3f( 600, 410, 10 ); + glColor3f(0, 0, 1.0); glVertex3f( 600, 480, 10 ); + glColor3f(1.0, 1.0, 1.0); glVertex3f( 410, 470, 10 ); + glEnd(); + + SDL_GL_SwapBuffers(); + +#if !EMSCRIPTEN + // Wait for 3 seconds to give us a chance to see the image + SDL_Delay(30000); +#endif + + // Now we can delete the OpenGL texture and close down SDL + glDeleteTextures( 1, &texture ); + + SDL_Quit(); + + return 0; +} diff --git a/tests/sdl_fog_negative.c b/tests/sdl_fog_negative.c new file mode 100644 index 00000000..2d589a47 --- /dev/null +++ b/tests/sdl_fog_negative.c @@ -0,0 +1,182 @@ +/******************************************************************* + * * + * Using SDL With OpenGL * + * * + * Tutorial by Kyle Foley (sdw) * + * * + * http://gpwiki.org/index.php/SDL:Tutorials:Using_SDL_with_OpenGL * + * * + *******************************************************************/ + +/* +THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION +AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN. + +THE ORIGINAL AUTHOR IS KYLE FOLEY. + +THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY +OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF +MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, +ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE +RESULTING FROM THE USE, MODIFICATION, OR +REDISTRIBUTION OF THIS SOFTWARE. +*/ + +#include "SDL/SDL.h" +#include "SDL/SDL_image.h" +#include "SDL/SDL_opengl.h" + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + + // Slightly different SDL initialization + if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { + printf("Unable to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // *new* + + screen = SDL_SetVideoMode( 640, 480, 16, SDL_OPENGL ); // *changed* + if ( !screen ) { + printf("Unable to set video mode: %s\n", SDL_GetError()); + return 1; + } + + // Set the OpenGL state after creating the context with SDL_SetVideoMode + + glClearColor( 0, 0, 0, 0 ); + +#if !EMSCRIPTEN + glEnable( GL_TEXTURE_2D ); // Need this to display a texture XXX unnecessary in OpenGL ES 2.0/WebGL +#endif + + glViewport( 0, 0, 640, 480 ); + + glMatrixMode( GL_PROJECTION ); + glPushMatrix(); // just for testing + glLoadIdentity(); + + glOrtho( 0, 640, 480, 0, -1000, 1000 ); + + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + + // Load the OpenGL texture + + GLuint texture; // Texture object handle + SDL_Surface *surface; // Gives us the information to make the texture + + if ( (surface = IMG_Load("screenshot.png")) ) { + + // Check that the image's width is a power of 2 + if ( (surface->w & (surface->w - 1)) != 0 ) { + printf("warning: image.bmp's width is not a power of 2\n"); + } + + // Also check if the height is a power of 2 + if ( (surface->h & (surface->h - 1)) != 0 ) { + printf("warning: image.bmp's height is not a power of 2\n"); + } + + // Have OpenGL generate a texture object handle for us + glGenTextures( 1, &texture ); + + // Bind the texture object + glBindTexture( GL_TEXTURE_2D, texture ); + + // Set the texture's stretching properties + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + + //SDL_LockSurface(surface); + + // Add some greyness + memset(surface->pixels, 0x66, surface->w*surface->h); + + // Edit the texture object's image data using the information SDL_Surface gives us + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0, + GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels ); + + //SDL_UnlockSurface(surface); + } + else { + printf("SDL could not load image.bmp: %s\n", SDL_GetError()); + SDL_Quit(); + return 1; + } + + // Free the SDL_Surface only if it was successfully created + if ( surface ) { + SDL_FreeSurface( surface ); + } + + // Clear the screen before drawing + glClear( GL_COLOR_BUFFER_BIT ); + + // Bind the texture to which subsequent calls refer to + glBindTexture( GL_TEXTURE_2D, texture ); + + glEnable(GL_FOG); + GLfloat fogColor[] = { 1.0, 0.5, 0.5, 0.05 }; + glFogfv(GL_FOG_COLOR, fogColor); + + assert(glIsEnabled(GL_FOG)); + + glBegin( GL_QUADS ); + glTexCoord2i( 0, 0 ); glVertex3f( 10, 10, -1 ); + glTexCoord2i( 1, 0 ); glVertex3f( 300, 10, -1 ); + glTexCoord2i( 1, 1 ); glVertex3f( 300, 128, -1 ); + glTexCoord2i( 0, 1 ); glVertex3f( 10, 128, -1 ); + + glTexCoord2f( 0, 0.5 ); glVertex3f( 410, 10, -5 ); + glTexCoord2f( 1, 0.5 ); glVertex3f( 600, 10, -6 ); + glTexCoord2f( 1, 1 ); glVertex3f( 630, 200, -7 ); + glTexCoord2f( 0.5, 1 ); glVertex3f( 310, 250, -8 ); + glEnd(); + + glBegin( GL_TRIANGLE_STRIP ); + glTexCoord2i( 0, 0 ); glVertex3f( 100, 300, -1 ); + glTexCoord2i( 1, 0 ); glVertex3f( 300, 300, -1 ); + glTexCoord2i( 1, 1 ); glVertex3f( 300, 400, -1 ); + glTexCoord2i( 0, 1 ); glVertex3f( 500, 410, -1 ); + glEnd(); + +#if !EMSCRIPTEN + glDisable(GL_TEXTURE_2D); +#endif + + glColor3ub(90, 255, 255); + glBegin( GL_QUADS ); + glVertex3f( 10, 410, -5 ); + glVertex3f( 300, 410, -50 ); + glVertex3f( 300, 480, -100 ); + glVertex3f( 10, 470, -5 ); + glEnd(); + + glBegin( GL_QUADS ); + glColor3f(1.0, 0, 1.0); glVertex3f( 410, 410, -10 ); + glColor3f(0, 1.0, 0); glVertex3f( 600, 410, -10 ); + glColor3f(0, 0, 1.0); glVertex3f( 600, 480, -10 ); + glColor3f(1.0, 1.0, 1.0); glVertex3f( 410, 470, -10 ); + glEnd(); + + SDL_GL_SwapBuffers(); + +#if !EMSCRIPTEN + // Wait for 3 seconds to give us a chance to see the image + SDL_Delay(30000); +#endif + + // Now we can delete the OpenGL texture and close down SDL + glDeleteTextures( 1, &texture ); + + SDL_Quit(); + + return 0; +} diff --git a/tests/sdl_fog_simple.c b/tests/sdl_fog_simple.c new file mode 100644 index 00000000..be023593 --- /dev/null +++ b/tests/sdl_fog_simple.c @@ -0,0 +1,182 @@ +/******************************************************************* + * * + * Using SDL With OpenGL * + * * + * Tutorial by Kyle Foley (sdw) * + * * + * http://gpwiki.org/index.php/SDL:Tutorials:Using_SDL_with_OpenGL * + * * + *******************************************************************/ + +/* +THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION +AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN. + +THE ORIGINAL AUTHOR IS KYLE FOLEY. + +THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY +OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF +MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, +ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE +RESULTING FROM THE USE, MODIFICATION, OR +REDISTRIBUTION OF THIS SOFTWARE. +*/ + +#include "SDL/SDL.h" +#include "SDL/SDL_image.h" +#include "SDL/SDL_opengl.h" + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + + // Slightly different SDL initialization + if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { + printf("Unable to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // *new* + + screen = SDL_SetVideoMode( 640, 480, 16, SDL_OPENGL ); // *changed* + if ( !screen ) { + printf("Unable to set video mode: %s\n", SDL_GetError()); + return 1; + } + + // Set the OpenGL state after creating the context with SDL_SetVideoMode + + glClearColor( 0, 0, 0, 0 ); + +#if !EMSCRIPTEN + glEnable( GL_TEXTURE_2D ); // Need this to display a texture XXX unnecessary in OpenGL ES 2.0/WebGL +#endif + + glViewport( 0, 0, 640, 480 ); + + glMatrixMode( GL_PROJECTION ); + glPushMatrix(); // just for testing + glLoadIdentity(); + + glOrtho( 0, 640, 480, 0, -1000, 1000 ); + + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + + // Load the OpenGL texture + + GLuint texture; // Texture object handle + SDL_Surface *surface; // Gives us the information to make the texture + + if ( (surface = IMG_Load("screenshot.png")) ) { + + // Check that the image's width is a power of 2 + if ( (surface->w & (surface->w - 1)) != 0 ) { + printf("warning: image.bmp's width is not a power of 2\n"); + } + + // Also check if the height is a power of 2 + if ( (surface->h & (surface->h - 1)) != 0 ) { + printf("warning: image.bmp's height is not a power of 2\n"); + } + + // Have OpenGL generate a texture object handle for us + glGenTextures( 1, &texture ); + + // Bind the texture object + glBindTexture( GL_TEXTURE_2D, texture ); + + // Set the texture's stretching properties + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + + //SDL_LockSurface(surface); + + // Add some greyness + memset(surface->pixels, 0x66, surface->w*surface->h); + + // Edit the texture object's image data using the information SDL_Surface gives us + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0, + GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels ); + + //SDL_UnlockSurface(surface); + } + else { + printf("SDL could not load image.bmp: %s\n", SDL_GetError()); + SDL_Quit(); + return 1; + } + + // Free the SDL_Surface only if it was successfully created + if ( surface ) { + SDL_FreeSurface( surface ); + } + + // Clear the screen before drawing + glClear( GL_COLOR_BUFFER_BIT ); + + // Bind the texture to which subsequent calls refer to + glBindTexture( GL_TEXTURE_2D, texture ); + + glEnable(GL_FOG); + GLfloat fogColor[] = { 1.0, 0.5, 0.5, 0.05 }; + glFogfv(GL_FOG_COLOR, fogColor); + + assert(glIsEnabled(GL_FOG)); + + glBegin( GL_QUADS ); + glTexCoord2i( 0, 0 ); glVertex3f( 10, 10, 10 ); + glTexCoord2i( 1, 0 ); glVertex3f( 300, 10, 10 ); + glTexCoord2i( 1, 1 ); glVertex3f( 300, 128, 10 ); + glTexCoord2i( 0, 1 ); glVertex3f( 10, 128, 10 ); + + glTexCoord2f( 0, 0.5 ); glVertex3f( 410, 10, 5 ); + glTexCoord2f( 1, 0.5 ); glVertex3f( 600, 10, 6 ); + glTexCoord2f( 1, 1 ); glVertex3f( 630, 200, 7 ); + glTexCoord2f( 0.5, 1 ); glVertex3f( 310, 250, 8 ); + glEnd(); + + glBegin( GL_TRIANGLE_STRIP ); + glTexCoord2i( 0, 0 ); glVertex3f( 100, 300, 1 ); + glTexCoord2i( 1, 0 ); glVertex3f( 300, 300, 1 ); + glTexCoord2i( 1, 1 ); glVertex3f( 300, 400, 1 ); + glTexCoord2i( 0, 1 ); glVertex3f( 500, 410, 1 ); + glEnd(); + +#if !EMSCRIPTEN + glDisable(GL_TEXTURE_2D); +#endif + + glColor3ub(90, 255, 255); + glBegin( GL_QUADS ); + glVertex3f( 10, 410, 5 ); + glVertex3f( 300, 410, 50 ); + glVertex3f( 300, 480, 100 ); + glVertex3f( 10, 470, 5 ); + glEnd(); + + glBegin( GL_QUADS ); + glColor3f(1.0, 0, 1.0); glVertex3f( 410, 410, 10 ); + glColor3f(0, 1.0, 0); glVertex3f( 600, 410, 10 ); + glColor3f(0, 0, 1.0); glVertex3f( 600, 480, 10 ); + glColor3f(1.0, 1.0, 1.0); glVertex3f( 410, 470, 10 ); + glEnd(); + + SDL_GL_SwapBuffers(); + +#if !EMSCRIPTEN + // Wait for 3 seconds to give us a chance to see the image + SDL_Delay(30000); +#endif + + // Now we can delete the OpenGL texture and close down SDL + glDeleteTextures( 1, &texture ); + + SDL_Quit(); + + return 0; +} diff --git a/tests/sdl_gl_read.c b/tests/sdl_gl_read.c new file mode 100644 index 00000000..552eb8c0 --- /dev/null +++ b/tests/sdl_gl_read.c @@ -0,0 +1,155 @@ +// Built from glbook/hello triange and sdl_ogl, see details there + +#include "SDL/SDL.h" +#include "SDL/SDL_image.h" +#include "SDL/SDL_opengl.h" + +#include <stdio.h> +#include <stdlib.h> + +GLuint programObject; +int width = 512; +int height = 256; + +GLuint LoadShader ( GLenum type, const char *shaderSrc ) +{ + GLuint shader; + GLint compiled; + + shader = glCreateShader ( type ); + if ( shader == 0 ) + return 0; + + glShaderSource ( shader, 1, &shaderSrc, NULL ); + glCompileShader ( shader ); + glGetShaderiv ( shader, GL_COMPILE_STATUS, &compiled ); + if ( !compiled ) + { + GLint infoLen = 0; + glGetShaderiv ( shader, GL_INFO_LOG_LENGTH, &infoLen ); + if ( infoLen > 1 ) + { + char* infoLog = malloc (sizeof(char) * infoLen ); + glGetShaderInfoLog ( shader, infoLen, NULL, infoLog ); + printf ( "Error compiling shader:\n%s\n", infoLog ); + free ( infoLog ); + } + glDeleteShader ( shader ); + return 0; + } + return shader; +} + +int Init () +{ + GLbyte vShaderStr[] = + "attribute vec4 vPosition; \n" + "void main() \n" + "{ \n" + " gl_Position = vPosition; \n" + "} \n"; + + GLbyte fShaderStr[] = + "precision mediump float;\n"\ + "void main() \n" + "{ \n" + " gl_FragColor = vec4 ( 0.0, 0.0, 1.0, 1.0 );\n" + "} \n"; + + GLuint vertexShader; + GLuint fragmentShader; + GLint linked; + + vertexShader = LoadShader ( GL_VERTEX_SHADER, vShaderStr ); + fragmentShader = LoadShader ( GL_FRAGMENT_SHADER, fShaderStr ); + + programObject = glCreateProgram ( ); + if ( programObject == 0 ) + return 0; + + glAttachShader ( programObject, vertexShader ); + glAttachShader ( programObject, fragmentShader ); + glBindAttribLocation ( programObject, 0, "vPosition" ); + glLinkProgram ( programObject ); + glGetProgramiv ( programObject, GL_LINK_STATUS, &linked ); + if ( !linked ) + { + GLint infoLen = 0; + glGetProgramiv ( programObject, GL_INFO_LOG_LENGTH, &infoLen ); + if ( infoLen > 1 ) + { + char* infoLog = malloc (sizeof(char) * infoLen ); + glGetProgramInfoLog ( programObject, infoLen, NULL, infoLog ); + printf ( "Error linking program:\n%s\n", infoLog ); + free ( infoLog ); + } + glDeleteProgram ( programObject ); + return GL_FALSE; + } + + glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f ); + return GL_TRUE; +} + +/// +// Draw a triangle using the shader pair created in Init() +// +void Draw () +{ + GLfloat vVertices[] = { 0.0f, 0.5f, 0.0f, + -0.5f, -0.5f, 0.0f, + 0.5f, -0.5f, 0.0f }; + + // No clientside arrays, so do this in a webgl-friendly manner + GLuint vertexPosObject; + glGenBuffers(1, &vertexPosObject); + glBindBuffer(GL_ARRAY_BUFFER, vertexPosObject); + glBufferData(GL_ARRAY_BUFFER, 9*4, vVertices, GL_STATIC_DRAW); + + glViewport ( 0, 0, width, height ); + glClear ( GL_COLOR_BUFFER_BIT ); + glUseProgram ( programObject ); + + glBindBuffer(GL_ARRAY_BUFFER, vertexPosObject); + glVertexAttribPointer(0 /* ? */, 3, GL_FLOAT, 0, 0, 0); + glEnableVertexAttribArray(0); + + glDrawArrays ( GL_TRIANGLES, 0, 3 ); +} + +void Verify() { + unsigned char *data = malloc(width*height*4); + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); + // Should see some blue, and nothing else + int seen = 0; + int ok = 1; + for (int x = 0; x < width*height; x++) { + seen = seen || data[x*4+2] != 0; + ok = ok && (data[x*4+0] == 0); + ok = ok && (data[x*4+1] == 0); + } + int result = seen && ok; + REPORT_RESULT(); +} + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { + printf("Unable to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + screen = SDL_SetVideoMode(width, height, 32, SDL_OPENGL); + if (!screen) { + printf("Unable to set video mode: %s\n", SDL_GetError()); + return 1; + } + + Init(); + Draw(); + Verify(); + + return 0; +} + diff --git a/tests/sdl_image.c b/tests/sdl_image.c index d934f863..9d8c36f2 100644 --- a/tests/sdl_image.c +++ b/tests/sdl_image.c @@ -4,30 +4,40 @@ #include <assert.h> #include <emscripten.h> -int main() { - SDL_Init(SDL_INIT_VIDEO); - SDL_Surface *screen = SDL_SetVideoMode(600, 450, 32, SDL_SWSURFACE); - - SDL_Surface *image = IMG_Load("screenshot.jpg"); +int testImage(SDL_Surface* screen, const char* fileName) { + SDL_Surface *image = IMG_Load(fileName); if (!image) { printf("IMG_Load: %s\n", IMG_GetError()); - return 1; + return 0; } assert(image->format->BitsPerPixel == 32); assert(image->format->BytesPerPixel == 4); assert(image->pitch == 4*image->w); + int result = image->w; SDL_BlitSurface (image, NULL, screen, NULL); SDL_FreeSurface (image); - SDL_Flip(screen); + return result; +} + +int main() { + SDL_Init(SDL_INIT_VIDEO); + SDL_Surface *screen = SDL_SetVideoMode(600, 450, 32, SDL_SWSURFACE); + + int result = 0; + result = testImage(screen, "screenshot.jpg"); // relative path + assert(result != 0); + result |= testImage(screen, "/screenshot.jpg"); // absolute path + assert(result != 0); + + SDL_Flip(screen); printf("you should see an image.\n"); SDL_Quit(); - int result = image->w; REPORT_RESULT(); return 0; diff --git a/tests/sdl_key.c b/tests/sdl_key.c index 6a5ad694..19b0a3d6 100644 --- a/tests/sdl_key.c +++ b/tests/sdl_key.c @@ -23,8 +23,10 @@ void one() { if (event.key.keysym.scancode == SDL_SCANCODE_B) { printf("b scancode\n"); result *= 17; break; } + printf("unknown key: sym %d scancode %d\n", event.key.keysym.sym, event.key.keysym.scancode); REPORT_RESULT(); - emscripten_run_script("throw 'done'"); + emscripten_run_script("throw 'done'"); // comment this out to leave event handling active. Use the following to log DOM keys: + // addEventListener('keyup', function(event) { console.log(event.keyCode) }, true) } } break; @@ -38,13 +40,13 @@ int main(int argc, char **argv) { SDL_Init(SDL_INIT_VIDEO); SDL_Surface *screen = SDL_SetVideoMode(600, 450, 32, SDL_HWSURFACE); - emscripten_run_script("simulateKeyEvent(38)"); - emscripten_run_script("simulateKeyEvent(40)"); - emscripten_run_script("simulateKeyEvent(37)"); - emscripten_run_script("simulateKeyEvent(39)"); - emscripten_run_script("simulateKeyEvent(32)"); - emscripten_run_script("simulateKeyEvent(97)"); - emscripten_run_script("simulateKeyEvent(98)"); + emscripten_run_script("simulateKeyEvent(38)"); // up + emscripten_run_script("simulateKeyEvent(40)"); // down + emscripten_run_script("simulateKeyEvent(37)"); // left + emscripten_run_script("simulateKeyEvent(39)"); // right + emscripten_run_script("simulateKeyEvent(32)"); // space + emscripten_run_script("simulateKeyEvent(65)"); // a + emscripten_run_script("simulateKeyEvent(66)"); // b emscripten_run_script("simulateKeyEvent(100)"); // trigger the end if (argc == 1337) one(); // keep it alive diff --git a/tests/sdl_maprgba.c b/tests/sdl_maprgba.c new file mode 100644 index 00000000..c87c7524 --- /dev/null +++ b/tests/sdl_maprgba.c @@ -0,0 +1,33 @@ +#include <stdio.h> +#include <SDL/SDL.h> +#include <emscripten.h> + +int main() { + Uint32 c; + SDL_Rect rect = {0,0,300,450}; + + SDL_Init(SDL_INIT_VIDEO); + SDL_Surface *screen = SDL_SetVideoMode(600, 450, 32, SDL_HWSURFACE); + + c = SDL_MapRGB(screen->format, 0xff, 0x00, 0x00); // OPAQUE RED + SDL_FillRect(screen, &rect, c); + rect.x = 300; + c = SDL_MapRGB(screen->format, 0x7f, 0x7f, 0x00); // OPAQUE MUSTARD + SDL_FillRect(screen, &rect, c); + rect.x = 150; + rect.y = 112; + rect.w = 300; + rect.h = 225; + c = SDL_MapRGBA(screen->format, 0xff, 0xff, 0xff, 0xff); // OPAQUE WHITE + SDL_FillRect(screen, &rect, c); + c = SDL_MapRGBA(screen->format, 0x00, 0x00, 0x00, 0x00); // TRANSPARENT BLACK + SDL_FillRect(screen, &rect, c); + SDL_UpdateRect(screen, 0, 0, 600, 450); + + printf("The left half should be red and the right half mustard.\n"); + printf("There should be a white rectangle in the center.\n"); + + SDL_Quit(); + + return 0; +} diff --git a/tests/sdl_maprgba.png b/tests/sdl_maprgba.png Binary files differnew file mode 100644 index 00000000..4f64c7cd --- /dev/null +++ b/tests/sdl_maprgba.png diff --git a/tests/sdl_mouse.c b/tests/sdl_mouse.c index dae3f636..0c10198a 100644 --- a/tests/sdl_mouse.c +++ b/tests/sdl_mouse.c @@ -12,6 +12,7 @@ void one() { switch(event.type) { case SDL_MOUSEMOTION: { SDL_MouseMotionEvent *m = (SDL_MouseMotionEvent*)&event; + assert(m->state == 0); int x, y; SDL_GetMouseState(&x, &y); assert(x == m->x && y == m->y); @@ -33,12 +34,17 @@ void one() { SDL_MouseButtonEvent *m = (SDL_MouseButtonEvent*)&event; printf("button up: %d,%d %d,%d\n", m->button, m->state, m->x, m->y); result += 5 * (m->button + m->state + m->x + m->y); + // Remove another click we want to ignore + assert(SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_MOUSEBUTTONDOWN, SDL_MOUSEBUTTONDOWN) == 1); + assert(SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_MOUSEBUTTONUP, SDL_MOUSEBUTTONUP) == 1); break; } } } } +void main_2(); + int main() { SDL_Init(SDL_INIT_VIDEO); SDL_Surface *screen = SDL_SetVideoMode(600, 450, 32, SDL_HWSURFACE); @@ -46,13 +52,18 @@ int main() { SDL_Rect rect = { 0, 0, 600, 450 }; SDL_FillRect(screen, &rect, 0x2244ffff); - emscripten_run_script("simulateMouseEvent(10, 20, -1)"); // move from 0,0 to 10,20 - emscripten_run_script("simulateMouseEvent(10, 20, 0)"); // click - emscripten_run_script("simulateMouseEvent(30, 77, -1)"); // move some more - emscripten_run_script("simulateMouseEvent(30, 77, 1)"); // trigger the end - - emscripten_set_main_loop(one, 0); + emscripten_async_call(main_2, 3000); // avoid startup delays and intermittent errors return 0; } +void main_2() { + emscripten_run_script("window.simulateMouseEvent(10, 20, -1)"); // move from 0,0 to 10,20 + emscripten_run_script("window.simulateMouseEvent(10, 20, 0)"); // click + emscripten_run_script("window.simulateMouseEvent(10, 20, 0)"); // click some more, but this one should be ignored through PeepEvent + emscripten_run_script("window.simulateMouseEvent(30, 77, -1)"); // move some more + emscripten_run_script("window.simulateMouseEvent(30, 77, 1)"); // trigger the end + + emscripten_set_main_loop(one, 0); +} + diff --git a/tests/sdl_ogl.c b/tests/sdl_ogl.c new file mode 100644 index 00000000..6b6a5b4a --- /dev/null +++ b/tests/sdl_ogl.c @@ -0,0 +1,175 @@ +/******************************************************************* + * * + * Using SDL With OpenGL * + * * + * Tutorial by Kyle Foley (sdw) * + * * + * http://gpwiki.org/index.php/SDL:Tutorials:Using_SDL_with_OpenGL * + * * + *******************************************************************/ + +/* +THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION +AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN. + +THE ORIGINAL AUTHOR IS KYLE FOLEY. + +THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY +OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF +MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, +ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE +RESULTING FROM THE USE, MODIFICATION, OR +REDISTRIBUTION OF THIS SOFTWARE. +*/ + +#include "SDL/SDL.h" +#include "SDL/SDL_image.h" +#include "SDL/SDL_opengl.h" + +#include <stdio.h> +#include <string.h> + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + + // Slightly different SDL initialization + if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { + printf("Unable to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // *new* + + screen = SDL_SetVideoMode( 640, 480, 16, SDL_OPENGL ); // *changed* + if ( !screen ) { + printf("Unable to set video mode: %s\n", SDL_GetError()); + return 1; + } + + // Set the OpenGL state after creating the context with SDL_SetVideoMode + + glClearColor( 0, 0, 0, 0 ); + +#if !EMSCRIPTEN + glEnable( GL_TEXTURE_2D ); // Need this to display a texture XXX unnecessary in OpenGL ES 2.0/WebGL +#endif + + glViewport( 0, 0, 640, 480 ); + + glMatrixMode( GL_PROJECTION ); + glPushMatrix(); // just for testing + glLoadIdentity(); + + glOrtho( 0, 640, 480, 0, -1, 1 ); + + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + + // Load the OpenGL texture + + GLuint texture; // Texture object handle + SDL_Surface *surface; // Gives us the information to make the texture + + if ( (surface = IMG_Load("screenshot.png")) ) { + + // Check that the image's width is a power of 2 + if ( (surface->w & (surface->w - 1)) != 0 ) { + printf("warning: image.bmp's width is not a power of 2\n"); + } + + // Also check if the height is a power of 2 + if ( (surface->h & (surface->h - 1)) != 0 ) { + printf("warning: image.bmp's height is not a power of 2\n"); + } + + // Have OpenGL generate a texture object handle for us + glGenTextures( 1, &texture ); + + // Bind the texture object + glBindTexture( GL_TEXTURE_2D, texture ); + + // Set the texture's stretching properties + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + + //SDL_LockSurface(surface); + + // Add some greyness + memset(surface->pixels, 0x66, surface->w*surface->h); + + // Edit the texture object's image data using the information SDL_Surface gives us + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0, + GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels ); + + //SDL_UnlockSurface(surface); + } + else { + printf("SDL could not load image.bmp: %s\n", SDL_GetError()); + SDL_Quit(); + return 1; + } + + // Free the SDL_Surface only if it was successfully created + if ( surface ) { + SDL_FreeSurface( surface ); + } + + // Clear the screen before drawing + glClear( GL_COLOR_BUFFER_BIT ); + + // Bind the texture to which subsequent calls refer to + glBindTexture( GL_TEXTURE_2D, texture ); + + glBegin( GL_QUADS ); + glTexCoord2i( 0, 0 ); glVertex3f( 10, 10, 0 ); + glTexCoord2i( 1, 0 ); glVertex3f( 300, 10, 0 ); + glTexCoord2i( 1, 1 ); glVertex3f( 300, 128, 0 ); + glTexCoord2i( 0, 1 ); glVertex3f( 10, 128, 0 ); + + glTexCoord2f( 0, 0.5 ); glVertex3f( 410, 10, 0 ); + glTexCoord2f( 1, 0.5 ); glVertex3f( 600, 10, 0 ); + glTexCoord2f( 1, 1 ); glVertex3f( 630, 200, 0 ); + glTexCoord2f( 0.5, 1 ); glVertex3f( 310, 250, 0 ); + glEnd(); + + glBegin( GL_TRIANGLE_STRIP ); + glTexCoord2i( 0, 0 ); glVertex3f( 100, 300, 0 ); + glTexCoord2i( 1, 0 ); glVertex3f( 300, 300, 0 ); + glTexCoord2i( 1, 1 ); glVertex3f( 300, 400, 0 ); + glTexCoord2i( 0, 1 ); glVertex3f( 500, 410, 0 ); + glEnd(); + +#if !EMSCRIPTEN + glDisable(GL_TEXTURE_2D); +#endif + + glColor3ub(90, 255, 255); + glBegin( GL_QUADS ); + glVertex3f( 10, 410, 0 ); + glVertex3f( 300, 410, 0 ); + glVertex3f( 300, 480, 0 ); + glVertex3f( 10, 470, 0 ); + glEnd(); + + glBegin( GL_QUADS ); + glColor3f(1.0, 0, 1.0); glVertex3f( 410, 410, 0 ); + glColor3f(0, 1.0, 0); glVertex3f( 600, 410, 0 ); + glColor3f(0, 0, 1.0); glVertex3f( 600, 480, 0 ); + glColor3f(1.0, 1.0, 1.0); glVertex3f( 410, 470, 0 ); + glEnd(); + + SDL_GL_SwapBuffers(); + +#if !EMSCRIPTEN + // Wait for 3 seconds to give us a chance to see the image + SDL_Delay(3000); +#endif + + // Now we can delete the OpenGL texture and close down SDL + glDeleteTextures( 1, &texture ); + + SDL_Quit(); + + return 0; +} diff --git a/tests/sdl_ogl_defaultMatrixMode.c b/tests/sdl_ogl_defaultMatrixMode.c new file mode 100644 index 00000000..0da0a326 --- /dev/null +++ b/tests/sdl_ogl_defaultMatrixMode.c @@ -0,0 +1,176 @@ +/******************************************************************* + * * + * Using SDL With OpenGL * + * * + * Tutorial by Kyle Foley (sdw) * + * * + * http://gpwiki.org/index.php/SDL:Tutorials:Using_SDL_with_OpenGL * + * * + *******************************************************************/ + +/* +THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION +AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN. + +THE ORIGINAL AUTHOR IS KYLE FOLEY. + +THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY +OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF +MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, +ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE +RESULTING FROM THE USE, MODIFICATION, OR +REDISTRIBUTION OF THIS SOFTWARE. +*/ + +#include "SDL/SDL.h" +#include "SDL/SDL_image.h" +#include "SDL/SDL_opengl.h" + +#include <stdio.h> +#include <string.h> + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + + // Slightly different SDL initialization + if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { + printf("Unable to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // *new* + + screen = SDL_SetVideoMode( 640, 480, 16, SDL_OPENGL ); // *changed* + if ( !screen ) { + printf("Unable to set video mode: %s\n", SDL_GetError()); + return 1; + } + + // Set the OpenGL state after creating the context with SDL_SetVideoMode + + glClearColor( 0, 0, 0, 0 ); + +#if !EMSCRIPTEN + glEnable( GL_TEXTURE_2D ); // Need this to display a texture XXX unnecessary in OpenGL ES 2.0/WebGL +#endif + + glViewport( 0, 0, 640, 480 ); + + // GL_MODELVIEW should be the default... + //glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + + glMatrixMode( GL_PROJECTION ); + glPushMatrix(); // just for testing + glLoadIdentity(); + + glOrtho( 0, 640, 480, 0, -1, 1 ); + + // Load the OpenGL texture + + GLuint texture; // Texture object handle + SDL_Surface *surface; // Gives us the information to make the texture + + if ( (surface = IMG_Load("screenshot.png")) ) { + + // Check that the image's width is a power of 2 + if ( (surface->w & (surface->w - 1)) != 0 ) { + printf("warning: image.bmp's width is not a power of 2\n"); + } + + // Also check if the height is a power of 2 + if ( (surface->h & (surface->h - 1)) != 0 ) { + printf("warning: image.bmp's height is not a power of 2\n"); + } + + // Have OpenGL generate a texture object handle for us + glGenTextures( 1, &texture ); + + // Bind the texture object + glBindTexture( GL_TEXTURE_2D, texture ); + + // Set the texture's stretching properties + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + + //SDL_LockSurface(surface); + + // Add some greyness + memset(surface->pixels, 0x66, surface->w*surface->h); + + // Edit the texture object's image data using the information SDL_Surface gives us + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0, + GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels ); + + //SDL_UnlockSurface(surface); + } + else { + printf("SDL could not load image.bmp: %s\n", SDL_GetError()); + SDL_Quit(); + return 1; + } + + // Free the SDL_Surface only if it was successfully created + if ( surface ) { + SDL_FreeSurface( surface ); + } + + // Clear the screen before drawing + glClear( GL_COLOR_BUFFER_BIT ); + + // Bind the texture to which subsequent calls refer to + glBindTexture( GL_TEXTURE_2D, texture ); + + glBegin( GL_QUADS ); + glTexCoord2i( 0, 0 ); glVertex3f( 10, 10, 0 ); + glTexCoord2i( 1, 0 ); glVertex3f( 300, 10, 0 ); + glTexCoord2i( 1, 1 ); glVertex3f( 300, 128, 0 ); + glTexCoord2i( 0, 1 ); glVertex3f( 10, 128, 0 ); + + glTexCoord2f( 0, 0.5 ); glVertex3f( 410, 10, 0 ); + glTexCoord2f( 1, 0.5 ); glVertex3f( 600, 10, 0 ); + glTexCoord2f( 1, 1 ); glVertex3f( 630, 200, 0 ); + glTexCoord2f( 0.5, 1 ); glVertex3f( 310, 250, 0 ); + glEnd(); + + glBegin( GL_TRIANGLE_STRIP ); + glTexCoord2i( 0, 0 ); glVertex3f( 100, 300, 0 ); + glTexCoord2i( 1, 0 ); glVertex3f( 300, 300, 0 ); + glTexCoord2i( 1, 1 ); glVertex3f( 300, 400, 0 ); + glTexCoord2i( 0, 1 ); glVertex3f( 500, 410, 0 ); + glEnd(); + +#if !EMSCRIPTEN + glDisable(GL_TEXTURE_2D); +#endif + + glColor3ub(90, 255, 255); + glBegin( GL_QUADS ); + glVertex3f( 10, 410, 0 ); + glVertex3f( 300, 410, 0 ); + glVertex3f( 300, 480, 0 ); + glVertex3f( 10, 470, 0 ); + glEnd(); + + glBegin( GL_QUADS ); + glColor3f(1.0, 0, 1.0); glVertex3f( 410, 410, 0 ); + glColor3f(0, 1.0, 0); glVertex3f( 600, 410, 0 ); + glColor3f(0, 0, 1.0); glVertex3f( 600, 480, 0 ); + glColor3f(1.0, 1.0, 1.0); glVertex3f( 410, 470, 0 ); + glEnd(); + + SDL_GL_SwapBuffers(); + +#if !EMSCRIPTEN + // Wait for 3 seconds to give us a chance to see the image + SDL_Delay(3000); +#endif + + // Now we can delete the OpenGL texture and close down SDL + glDeleteTextures( 1, &texture ); + + SDL_Quit(); + + return 0; +} diff --git a/tests/sdl_ogl_p.c b/tests/sdl_ogl_p.c new file mode 100644 index 00000000..949aaa44 --- /dev/null +++ b/tests/sdl_ogl_p.c @@ -0,0 +1,166 @@ +/******************************************************************* + * * + * Using SDL With OpenGL * + * * + * Tutorial by Kyle Foley (sdw) * + * * + * http://gpwiki.org/index.php/SDL:Tutorials:Using_SDL_with_OpenGL * + * * + *******************************************************************/ + +/* +THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION +AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN. + +THE ORIGINAL AUTHOR IS KYLE FOLEY. + +THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY +OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF +MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, +ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE +RESULTING FROM THE USE, MODIFICATION, OR +REDISTRIBUTION OF THIS SOFTWARE. +*/ + +#include "SDL/SDL.h" +#include "SDL/SDL_image.h" +#include "SDL/SDL_opengl.h" + +#include <stdio.h> +#include <string.h> + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + + // Slightly different SDL initialization + if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { + printf("Unable to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // *new* + + screen = SDL_SetVideoMode( 640, 480, 16, SDL_OPENGL ); // *changed* + if ( !screen ) { + printf("Unable to set video mode: %s\n", SDL_GetError()); + return 1; + } + + // Set the OpenGL state after creating the context with SDL_SetVideoMode + + glClearColor( 0, 0, 0, 0 ); + +#if !EMSCRIPTEN + glEnable( GL_TEXTURE_2D ); // Need this to display a texture XXX unnecessary in OpenGL ES 2.0/WebGL +#endif + + glViewport( 0, 0, 640, 480 ); + + glMatrixMode( GL_PROJECTION ); + GLfloat matrixData[] = { 2.0/640, 0, 0, 0, + 0, -2.0/480, 0, 0, + 0, 0, -1, 0, + -1, 1, 0, 1 }; + glLoadMatrixf(matrixData); // test loadmatrix + + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + + // Load the OpenGL texture + + GLuint texture; // Texture object handle + SDL_Surface *surface; // Gives us the information to make the texture + + if ( (surface = IMG_Load("screenshot.png")) ) { + + // Check that the image's width is a power of 2 + if ( (surface->w & (surface->w - 1)) != 0 ) { + printf("warning: image.bmp's width is not a power of 2\n"); + } + + // Also check if the height is a power of 2 + if ( (surface->h & (surface->h - 1)) != 0 ) { + printf("warning: image.bmp's height is not a power of 2\n"); + } + + // Have OpenGL generate a texture object handle for us + glGenTextures( 1, &texture ); + + // Bind the texture object + glBindTexture( GL_TEXTURE_2D, texture ); + + // Set the texture's stretching properties + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + + //SDL_LockSurface(surface); + + // Add some greyness + memset(surface->pixels, 0x66, surface->w*surface->h); + + // Edit the texture object's image data using the information SDL_Surface gives us + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0, + GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels ); + + //SDL_UnlockSurface(surface); + } + else { + printf("SDL could not load image.bmp: %s\n", SDL_GetError()); + SDL_Quit(); + return 1; + } + + // Free the SDL_Surface only if it was successfully created + if ( surface ) { + SDL_FreeSurface( surface ); + } + + // Clear the screen before drawing + glClear( GL_COLOR_BUFFER_BIT ); + + // Bind the texture to which subsequent calls refer to + glBindTexture( GL_TEXTURE_2D, texture ); + + // Use clientside vertex pointers to render two items + GLfloat vertexData[] = { 0, 0, 10, 10, // texture2, position2 + 1, 0, 300, 10, + 1, 1, 300, 128, + 0, 1, 10, 128, + 0, 0.5, 410, 10, + 1, 0.5, 600, 10, + 1, 1, 630, 200, + 0.5, 1, 310, 250 }; + + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, 4*4, &vertexData[0]); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 4*4, &vertexData[2]); + + glDrawArrays(GL_QUADS, 0, 8); + + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + + // Render the last item using oldschool glBegin etc + glBegin( GL_TRIANGLE_STRIP ); + glTexCoord2i( 0, 0 ); glVertex3f( 100, 300, 0 ); + glTexCoord2i( 1, 0 ); glVertex3f( 300, 300, 0 ); + glTexCoord2i( 1, 1 ); glVertex3f( 300, 400, 0 ); + glTexCoord2i( 0, 1 ); glVertex3f( 500, 410, 0 ); + glEnd(); + + SDL_GL_SwapBuffers(); + +#if !EMSCRIPTEN + // Wait for 3 seconds to give us a chance to see the image + SDL_Delay(3000); +#endif + + // Now we can delete the OpenGL texture and close down SDL + glDeleteTextures( 1, &texture ); + + SDL_Quit(); + + return 0; +} diff --git a/tests/sdlglshader.c b/tests/sdlglshader.c new file mode 100644 index 00000000..a096ef20 --- /dev/null +++ b/tests/sdlglshader.c @@ -0,0 +1,153 @@ +/* +THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION +AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN. + +THE ORIGINAL AUTHOR IS KYLE FOLEY. + +THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY +OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF +MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, +ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE +RESULTING FROM THE USE, MODIFICATION, OR +REDISTRIBUTION OF THIS SOFTWARE. +*/ + +#include "SDL/SDL.h" +#include "SDL/SDL_opengl.h" + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +// GL_ARB_shading_language_100, GL_ARB_shader_objects, GL_ARB_fragment_shader, GL_ARB_vertex_shader +PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObject_ = NULL; +PFNGLDELETEOBJECTARBPROC glDeleteObject_ = NULL; +PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObject_ = NULL; +PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObject_ = NULL; +PFNGLSHADERSOURCEARBPROC glShaderSource_ = NULL; +PFNGLCOMPILESHADERARBPROC glCompileShader_ = NULL; +PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameteriv_ = NULL; +PFNGLATTACHOBJECTARBPROC glAttachObject_ = NULL; +PFNGLGETINFOLOGARBPROC glGetInfoLog_ = NULL; +PFNGLLINKPROGRAMARBPROC glLinkProgram_ = NULL; +PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocation_ = NULL; +PFNGLUNIFORM1FARBPROC glUniform1f_ = NULL; +PFNGLUNIFORM2FARBPROC glUniform2f_ = NULL; +PFNGLUNIFORM3FARBPROC glUniform3f_ = NULL; +PFNGLUNIFORM4FARBPROC glUniform4f_ = NULL; +PFNGLUNIFORM1FVARBPROC glUniform1fv_ = NULL; +PFNGLUNIFORM2FVARBPROC glUniform2fv_ = NULL; +PFNGLUNIFORM3FVARBPROC glUniform3fv_ = NULL; +PFNGLUNIFORM4FVARBPROC glUniform4fv_ = NULL; +PFNGLUNIFORM1IARBPROC glUniform1i_ = NULL; +PFNGLBINDATTRIBLOCATIONARBPROC glBindAttribLocation_ = NULL; +PFNGLGETACTIVEUNIFORMARBPROC glGetActiveUniform_ = NULL; + +void initARB() { + glCreateProgramObject_ = (PFNGLCREATEPROGRAMOBJECTARBPROC) SDL_GL_GetProcAddress("glCreateProgramObjectARB"); + glDeleteObject_ = (PFNGLDELETEOBJECTARBPROC) SDL_GL_GetProcAddress("glDeleteObjectARB"); + glUseProgramObject_ = (PFNGLUSEPROGRAMOBJECTARBPROC) SDL_GL_GetProcAddress("glUseProgramObjectARB"); + glCreateShaderObject_ = (PFNGLCREATESHADEROBJECTARBPROC) SDL_GL_GetProcAddress("glCreateShaderObjectARB"); + glShaderSource_ = (PFNGLSHADERSOURCEARBPROC) SDL_GL_GetProcAddress("glShaderSourceARB"); + glCompileShader_ = (PFNGLCOMPILESHADERARBPROC) SDL_GL_GetProcAddress("glCompileShaderARB"); + glGetObjectParameteriv_ = (PFNGLGETOBJECTPARAMETERIVARBPROC) SDL_GL_GetProcAddress("glGetObjectParameterivARB"); + glAttachObject_ = (PFNGLATTACHOBJECTARBPROC) SDL_GL_GetProcAddress("glAttachObjectARB"); + glGetInfoLog_ = (PFNGLGETINFOLOGARBPROC) SDL_GL_GetProcAddress("glGetInfoLogARB"); + glLinkProgram_ = (PFNGLLINKPROGRAMARBPROC) SDL_GL_GetProcAddress("glLinkProgramARB"); + glGetUniformLocation_ = (PFNGLGETUNIFORMLOCATIONARBPROC) SDL_GL_GetProcAddress("glGetUniformLocationARB"); + glUniform1f_ = (PFNGLUNIFORM1FARBPROC) SDL_GL_GetProcAddress("glUniform1fARB"); + glUniform2f_ = (PFNGLUNIFORM2FARBPROC) SDL_GL_GetProcAddress("glUniform2fARB"); + glUniform3f_ = (PFNGLUNIFORM3FARBPROC) SDL_GL_GetProcAddress("glUniform3fARB"); + glUniform4f_ = (PFNGLUNIFORM4FARBPROC) SDL_GL_GetProcAddress("glUniform4fARB"); + glUniform1fv_ = (PFNGLUNIFORM1FVARBPROC) SDL_GL_GetProcAddress("glUniform1fvARB"); + glUniform2fv_ = (PFNGLUNIFORM2FVARBPROC) SDL_GL_GetProcAddress("glUniform2fvARB"); + glUniform3fv_ = (PFNGLUNIFORM3FVARBPROC) SDL_GL_GetProcAddress("glUniform3fvARB"); + glUniform4fv_ = (PFNGLUNIFORM4FVARBPROC) SDL_GL_GetProcAddress("glUniform4fvARB"); + glUniform1i_ = (PFNGLUNIFORM1IARBPROC) SDL_GL_GetProcAddress("glUniform1iARB"); + glBindAttribLocation_ = (PFNGLBINDATTRIBLOCATIONARBPROC) SDL_GL_GetProcAddress("glBindAttribLocationARB"); + glGetActiveUniform_ = (PFNGLGETACTIVEUNIFORMARBPROC) SDL_GL_GetProcAddress("glGetActiveUniformARB"); +} + +void setShaders() { + GLuint v, f, p; + GLint ok; + + const char *vv = "void main() \n" + "{ \n" + " gl_Position = ftransform() + vec4(0.1, -0.25, 0, 0); \n" + "}"; + const char *ff = "void main() \n" + "{ \n" + " gl_FragColor = vec4(gl_FragCoord.y/480.0, gl_FragCoord.x/640.0, 0.66, 1.0); \n" + "}"; + + v = glCreateShaderObject_(GL_VERTEX_SHADER); + f = glCreateShaderObject_(GL_FRAGMENT_SHADER); + + glShaderSource_(v, 1, &vv,NULL); + glShaderSource_(f, 1, &ff,NULL); + + glCompileShader_(v); + glGetObjectParameteriv_(v, GL_OBJECT_COMPILE_STATUS_ARB, &ok); + assert(ok); + + glCompileShader_(f); + glGetObjectParameteriv_(f, GL_OBJECT_COMPILE_STATUS_ARB, &ok); + assert(ok); + + p = glCreateProgramObject_(); + glAttachObject_(p,f); + glAttachObject_(p,v); + + glLinkProgram_(p); + glGetObjectParameteriv_(p, GL_OBJECT_LINK_STATUS_ARB, &ok); + assert(ok); + + glUseProgramObject_(p); +} + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + + assert(SDL_Init(SDL_INIT_VIDEO) == 0); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + screen = SDL_SetVideoMode( 640, 480, 16, SDL_OPENGL ); + assert(screen); + + glClearColor(0, 0, 0, 0); + glViewport(0, 0, 640, 480); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, 640, 480, 0, -1, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glClear(GL_COLOR_BUFFER_BIT); + + initARB(); + setShaders(); + + glColor3f(0, 1, 1); // is overridden by the shader, useful for debugging native builds + glBegin( GL_TRIANGLES ); + glTexCoord2i(0, 0); glVertex3f( 10, 10, 0); + glTexCoord2i(1, 0); glVertex3f( 300, 10, 0); + glTexCoord2i(1, 1); glVertex3f( 300, 328, 0); + glEnd(); + + glColor3f(1, 1, 0); // is overridden by the shader, useful for debugging native builds + glBegin( GL_TRIANGLES ); + glTexCoord2f(0, 0.5); glVertex3f(410, 10, 0); + glTexCoord2f(1, 0.5); glVertex3f(600, 10, 0); + glTexCoord2f(1, 1 ); glVertex3f(630, 400, 0); + glEnd(); + + SDL_GL_SwapBuffers(); + +#if !EMSCRIPTEN + SDL_Delay(3000); +#endif + + SDL_Quit(); + return 0; +} + diff --git a/tests/sdlglshader.png b/tests/sdlglshader.png Binary files differnew file mode 100644 index 00000000..5e52a617 --- /dev/null +++ b/tests/sdlglshader.png diff --git a/tests/sha1.c b/tests/sha1.c new file mode 100644 index 00000000..034939b5 --- /dev/null +++ b/tests/sha1.c @@ -0,0 +1,241 @@ + +/* from valgrind tests */ + +/* ================ sha1.c ================ */ +/* +SHA-1 in C +By Steve Reid <steve@edmweb.com> +100% Public Domain + +Test Vectors (from FIPS PUB 180-1) +"abc" + A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D +"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 +A million repetitions of "a" + 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F +*/ + +/* #define LITTLE_ENDIAN * This should be #define'd already, if true. */ +/* #define SHA1HANDSOFF * Copies data before messing with it. */ + +#define SHA1HANDSOFF + +#include <stdio.h> +#include <string.h> +#include <sys/types.h> /* for u_int*_t */ + +/* ================ sha1.h ================ */ +/* +SHA-1 in C +By Steve Reid <steve@edmweb.com> +100% Public Domain +*/ + +typedef struct { + u_int32_t state[5]; + u_int32_t count[2]; + unsigned char buffer[64]; +} SHA1_CTX; + +void SHA1Transform(u_int32_t state[5], const unsigned char buffer[64]); +void SHA1Init(SHA1_CTX* context); +void SHA1Update(SHA1_CTX* context, const unsigned char* data, u_int32_t len); +void SHA1Final(unsigned char digest[20], SHA1_CTX* context); +/* ================ end of sha1.h ================ */ +#include <endian.h> + +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) + +/* blk0() and blk() perform the initial expand. */ +/* I got the idea of expanding during the round function from SSLeay */ +#if BYTE_ORDER == LITTLE_ENDIAN +#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ + |(rol(block->l[i],8)&0x00FF00FF)) +#elif BYTE_ORDER == BIG_ENDIAN +#define blk0(i) block->l[i] +#else +#error "Endianness not defined!" +#endif +#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ + ^block->l[(i+2)&15]^block->l[i&15],1)) + +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ +#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); +#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); +#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); + + +/* Hash a single 512-bit block. This is the core of the algorithm. */ + +void SHA1Transform(u_int32_t state[5], const unsigned char buffer[64]) +{ +u_int32_t a, b, c, d, e; +typedef union { + unsigned char c[64]; + u_int32_t l[16]; +} CHAR64LONG16; +#ifdef SHA1HANDSOFF +CHAR64LONG16 block[1]; /* use array to appear as a pointer */ + memcpy(block, buffer, 64); +#else + /* The following had better never be used because it causes the + * pointer-to-const buffer to be cast into a pointer to non-const. + * And the result is written through. I threw a "const" in, hoping + * this will cause a diagnostic. + */ +CHAR64LONG16* block = (const CHAR64LONG16*)buffer; +#endif + /* Copy context->state[] to working vars */ + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + /* 4 rounds of 20 operations each. Loop unrolled. */ + R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); + R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); + R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); + R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + /* Wipe variables */ + a = b = c = d = e = 0; +#ifdef SHA1HANDSOFF + memset(block, '\0', sizeof(block)); +#endif +} + + +/* SHA1Init - Initialize new context */ + +void SHA1Init(SHA1_CTX* context) +{ + /* SHA1 initialization constants */ + context->state[0] = 0x67452301; + context->state[1] = 0xEFCDAB89; + context->state[2] = 0x98BADCFE; + context->state[3] = 0x10325476; + context->state[4] = 0xC3D2E1F0; + context->count[0] = context->count[1] = 0; +} + + +/* Run your data through this. */ + +void SHA1Update(SHA1_CTX* context, const unsigned char* data, u_int32_t len) +{ +u_int32_t i; +u_int32_t j; + + j = context->count[0]; + if ((context->count[0] += len << 3) < j) + context->count[1]++; + context->count[1] += (len>>29); + j = (j >> 3) & 63; + if ((j + len) > 63) { + memcpy(&context->buffer[j], data, (i = 64-j)); + SHA1Transform(context->state, context->buffer); + for ( ; i + 63 < len; i += 64) { + SHA1Transform(context->state, &data[i]); + } + j = 0; + } + else i = 0; + memcpy(&context->buffer[j], &data[i], len - i); +} + + +/* Add padding and return the message digest. */ + +void SHA1Final(unsigned char digest[20], SHA1_CTX* context) +{ +unsigned i; +unsigned char finalcount[8]; +unsigned char c; + +#if 0 /* untested "improvement" by DHR */ + /* Convert context->count to a sequence of bytes + * in finalcount. Second element first, but + * big-endian order within element. + * But we do it all backwards. + */ + unsigned char *fcp = &finalcount[8]; + + for (i = 0; i < 2; i++) + { + u_int32_t t = context->count[i]; + int j; + + for (j = 0; j < 4; t >>= 8, j++) + *--fcp = (unsigned char) t; + } +#else + for (i = 0; i < 8; i++) { + finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] + >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ + } +#endif + c = 0200; + SHA1Update(context, &c, 1); + while ((context->count[0] & 504) != 448) { + c = 0000; + SHA1Update(context, &c, 1); + } + SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ + for (i = 0; i < 20; i++) { + digest[i] = (unsigned char) + ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); + } + /* Wipe variables */ + memset(context, '\0', sizeof(*context)); + memset(&finalcount, '\0', sizeof(finalcount)); +} +/* ================ end of sha1.c ================ */ + +#define BUFSIZE 4096 + +int +main(int argc, char **argv) +{ + SHA1_CTX ctx; + unsigned char hash[20], buf[BUFSIZE]; + int i; + + for(i=0;i<BUFSIZE;i++) + buf[i] = i; + + SHA1Init(&ctx); + for(i=0;i<1000;i++) + SHA1Update(&ctx, buf, BUFSIZE); + SHA1Final(hash, &ctx); + + printf("SHA1="); + for(i=0;i<20;i++) + printf("%02x", hash[i]); + printf("\n"); + return 0; +} + diff --git a/tests/ship.dds b/tests/ship.dds Binary files differnew file mode 100644 index 00000000..dd7b04e9 --- /dev/null +++ b/tests/ship.dds diff --git a/tests/sqlite/benchmark.c b/tests/sqlite/benchmark.c index c1385525..802abab1 100644 --- a/tests/sqlite/benchmark.c +++ b/tests/sqlite/benchmark.c @@ -21,6 +21,7 @@ int test(){ "INSERT INTO t2 VALUES(1,13153,'thirteen thousand one hundred fifty three');", "INSERT INTO t2 VALUES(1,987,'some other number');", "SELECT count(*) FROM t2;", + "SELECT datetime('2012-04-16 12:35:57', '+1 days');", "SELECT a, b, c FROM t2;", NULL }; diff --git a/tests/sqlite/benchmark.txt b/tests/sqlite/benchmark.txt index 472221df..622493b3 100644 --- a/tests/sqlite/benchmark.txt +++ b/tests/sqlite/benchmark.txt @@ -1,5 +1,7 @@ count(*) = 2 +datetime('2012-04-16 12:35:57', '+1 days') = 2012-04-17 12:35:57 + a = 1 b = 13153 c = thirteen thousand one hundred fifty three diff --git a/tests/tex_nonbyte.c b/tests/tex_nonbyte.c new file mode 100644 index 00000000..8f2ec162 --- /dev/null +++ b/tests/tex_nonbyte.c @@ -0,0 +1,206 @@ +/******************************************************************* + * * + * Using SDL With OpenGL * + * * + * Tutorial by Kyle Foley (sdw) * + * * + * http://gpwiki.org/index.php/SDL:Tutorials:Using_SDL_with_OpenGL * + * * + *******************************************************************/ + +/* +THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION +AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN. + +THE ORIGINAL AUTHOR IS KYLE FOLEY. + +THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY +OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF +MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, +ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE +RESULTING FROM THE USE, MODIFICATION, OR +REDISTRIBUTION OF THIS SOFTWARE. +*/ + +#if !EMSCRIPTEN +#define USE_GLEW 1 +#endif + +#if USE_GLEW +#include "GL/glew.h" +#endif + +#include "SDL/SDL.h" +#include "SDL/SDL_image.h" +#if !USE_GLEW +#include "SDL/SDL_opengl.h" +#endif + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +void shaders() { +#if USE_GLEW + glewInit(); +#endif + + GLint ok; + + const char *vertexShader = "void main(void) \n" + "{ \n" + " gl_Position = ftransform(); \n" + " gl_TexCoord[0] = gl_MultiTexCoord0; \n" + " gl_FrontColor = gl_Color; \n" + "} \n"; + const char *fragmentShader = "uniform sampler2D tex0; \n" + "void main(void) \n" + "{ \n" + " gl_FragColor = gl_Color * texture2D(tex0, gl_TexCoord[0].xy); \n" + "} \n"; + + GLuint vs = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vs, 1, &vertexShader, NULL); + glCompileShader(vs); + glGetShaderiv(vs, GL_COMPILE_STATUS, &ok); + assert(ok); + + GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fs, 1, &fragmentShader, NULL); + glCompileShader(fs); + glGetShaderiv(fs, GL_COMPILE_STATUS, &ok); + assert(ok); + + GLuint program = glCreateProgram(); + + glAttachShader(program, vs); + glAttachShader(program, fs); + glLinkProgram(program); + glGetProgramiv(program, GL_LINK_STATUS, &ok); + assert(ok); + + glUseProgram(program); + + { + // Also, check getting the error log + const char *fakeVertexShader = "atbute ve4 blarg; ### AAA\n"; + GLuint vs = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vs, 1, &fakeVertexShader, NULL); + glCompileShader(vs); + glGetShaderiv(vs, GL_COMPILE_STATUS, &ok); + assert(!ok); + GLint infoLen = 0; + glGetShaderiv(vs, GL_INFO_LOG_LENGTH, &infoLen); + assert(infoLen > 1); + } +} + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + + // Slightly different SDL initialization + if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { + printf("Unable to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // *new* + + screen = SDL_SetVideoMode( 640, 480, 16, SDL_OPENGL ); // *changed* + if ( !screen ) { + printf("Unable to set video mode: %s\n", SDL_GetError()); + return 1; + } + + // Set the OpenGL state after creating the context with SDL_SetVideoMode + + glClearColor( 0, 0, 0, 0 ); + +#if !EMSCRIPTEN + glEnable( GL_TEXTURE_2D ); // Need this to display a texture XXX unnecessary in OpenGL ES 2.0/WebGL +#endif + + glViewport( 0, 0, 640, 480 ); + + glMatrixMode( GL_PROJECTION ); + GLfloat matrixData[] = { 2.0/640, 0, 0, 0, + 0, -2.0/480, 0, 0, + 0, 0, -1, 0, + -1, 1, 0, 1 }; + glLoadMatrixf(matrixData); // test loadmatrix + + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + + // Load the OpenGL texture + + GLuint texture; // Texture object handle + + // Have OpenGL generate a texture object handle for us + glGenTextures( 1, &texture ); + + // Bind the texture object + glBindTexture( GL_TEXTURE_2D, texture ); + + // Set the texture's stretching properties + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + + int w = 256, h = 256; + GLushort *pixels = (GLushort*)malloc(w*h*2); + for (int x = 0; x < w; x++) + for (int y = 0; y < h; y++) + pixels[w*y + x] = ((x*32)/w) | ((((w-x)*(h-y)*64)/(w*h)) << 5) | (((y*32)/h) << 11); + + // Edit the texture object's image data using the information SDL_Surface gives us + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, + GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels ); + + // Clear the screen before drawing + glClear( GL_COLOR_BUFFER_BIT ); + + shaders(); + + // Bind the texture to which subsequent calls refer to + glBindTexture( GL_TEXTURE_2D, texture ); + + // Use clientside vertex pointers to render two items + GLfloat vertexData[] = { 0, 0, 10, 10, // texture2, position2 + 1, 0, 300, 10, + 1, 1, 300, 128, + 0, 1, 10, 128, + 0, 0.5, 410, 10, + 1, 0.5, 600, 10, + 1, 1, 630, 200, + 0.5, 1, 310, 250, + 0, 0, 100, 300, + 1, 0, 300, 300, + 1, 1, 300, 400, + 0, 1, 100, 400 }; + + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, 4*4, &vertexData[0]); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 4*4, &vertexData[2]); + + glDrawArrays(GL_QUADS, 0, 12); + + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + + SDL_GL_SwapBuffers(); + +#if !EMSCRIPTEN + // Wait for 3 seconds to give us a chance to see the image + SDL_Delay(3000); +#endif + + // Now we can delete the OpenGL texture and close down SDL + glDeleteTextures( 1, &texture ); + + SDL_Quit(); + + return 0; +} + diff --git a/tests/tex_nonbyte.png b/tests/tex_nonbyte.png Binary files differnew file mode 100644 index 00000000..8e542417 --- /dev/null +++ b/tests/tex_nonbyte.png diff --git a/tests/water.dds b/tests/water.dds Binary files differnew file mode 100644 index 00000000..2a78a859 --- /dev/null +++ b/tests/water.dds diff --git a/third_party/lzma.js/doit.sh b/third_party/lzma.js/doit.sh index a8071534..1f530651 100755 --- a/third_party/lzma.js/doit.sh +++ b/third_party/lzma.js/doit.sh @@ -1,5 +1,7 @@ cd lzip +export CXX=`../../../em-config LLVM_ROOT`/clang++ + echo "native" make clean DECODER_ONLY=0 make lzip -j 4 # native build @@ -9,25 +11,25 @@ exit # just build natively, that's it echo "bitcode full (encoder+decoder)" make clean -DECODER_ONLY=0 ~/Dev/emscripten/emmake make lzip -j 4 +DECODER_ONLY=0 ../../../emmake make lzip -j 4 mv lzip lzip-full.bc echo "bitcode decoder only" make clean -DECODER_ONLY=1 ~/Dev/emscripten/emmake make lzip -j 4 +DECODER_ONLY=1 ../../../emmake make lzip -j 4 mv lzip lzip-decoder.bc cd .. echo "javascript full" -~/Dev/emscripten/emcc -O2 lzip/lzip-full.bc -o lzma-full.raw.js +../../emcc -O2 lzip/lzip-full.bc -o lzma-full.raw.js # -s INLINING_LIMIT=0 cat pre.js > lzma-full.js cat lzma-full.raw.js >> lzma-full.js cat post.js >> lzma-full.js echo "javascript decoder" -~/Dev/emscripten/emcc -O2 lzip/lzip-decoder.bc -o lzma-decoder.raw.js +../../emcc -O2 lzip/lzip-decoder.bc -o lzma-decoder.raw.js # -s INLINING_LIMIT=0 cat pre.js > lzma-decoder.js cat lzma-decoder.raw.js >> lzma-decoder.js diff --git a/tools/autodebugger.py b/tools/autodebugger.py index 943ff043..3631548c 100644 --- a/tools/autodebugger.py +++ b/tools/autodebugger.py @@ -13,6 +13,7 @@ import os, sys, re ALLOW_POINTERS = False ALLOW_MISC = True MEMCPY = False +NO_DLMALLOC = True POSTAMBLE = ''' @.emscripten.autodebug.str = private constant [10 x i8] c"AD:%d,%d\\0A\\00", align 1 ; [#uses=1] @@ -206,6 +207,7 @@ for.end: ; preds = %for.body, %entry lines_added = 0 lines = data.split('\n') in_func = False +added_entry = False for i in range(len(lines)): if MEMCPY: if not lines[i].startswith('declare void'): @@ -215,50 +217,55 @@ for i in range(len(lines)): pre = '' if lines[i].startswith('define '): in_func = True + if NO_DLMALLOC and ('@malloc(' in lines[i] or '@free(' in lines[i] or '@sys_alloc(' in lines[i] or '@segment_holding(' in lines[i] or '@init_top(' in lines[i] or '@add_segment(' in lines[i] or '@tmalloc_small(' in lines[i]): + in_func = False + if in_func: + added_entry = False elif lines[i].startswith('}'): in_func = False - elif in_func and ' = alloca' not in lines[i] and lines[i].startswith(' '): + elif in_func and not added_entry and ' = alloca' not in lines[i] and lines[i].startswith(' '): # This is a good place to mark entry to this function - in_func = False + added_entry = True index = i+1+lines_added pre = ' call void @emscripten_autodebug_i32(i32 -1, i32 %d)' % index - elif lines[i].startswith(' ret '): + elif in_func and lines[i].startswith(' ret '): # This is a good place to mark entry to this function index = i+1+lines_added pre = ' call void @emscripten_autodebug_i32(i32 -2, i32 %d)' % index - m = re.match(' store (?P<type>i64|i32|i16|i8|float|double|%?[\w\.\*]+) (?P<var>%?[\w.+_]+), .*', lines[i]) - if m: - index = i+1+lines_added - if m.group('type') in ['i8', 'i16', 'i32', 'i64', 'float', 'double']: - lines[i] += '\n call void @emscripten_autodebug_%s(i32 %d, %s %s)' % (m.group('type'), index, m.group('type'), m.group('var')) - lines_added += 1 - elif ALLOW_POINTERS and m.group('type').endswith('*') and m.group('type').count('*') == 1: - lines[i] += '\n %%ead.%d = ptrtoint %s %s to i32' % (index, m.group('type'), m.group('var')) - lines[i] += '\n call void @emscripten_autodebug_i32(i32 %d, i32 %%ead.%d)' % (index, index) - lines_added += 2 - continue - m = re.match(' %(?P<var>[\w_.]+) = load (?P<type>i64|i32|i16|i8|float|double+)\* [^(].*.*', lines[i]) - if m: - index = i+1+lines_added - lines[i] += '\n call void @emscripten_autodebug_%s(i32 %d, %s %%%s)' % (m.group('type'), index, m.group('type'), m.group('var')) - lines_added += 1 - continue - if ALLOW_MISC: - m = re.match(' %(?P<var>[\w_.]+) = (call|mul|add) (nsw )?(?P<type>i64|i32|i16|i8|float|double+) .*', lines[i]) + if in_func: + m = re.match(' store (?P<type>i64|i32|i16|i8|float|double|%?[\w\.\*]+) (?P<var>%?[\w.+_]+), .*', lines[i]) if m: index = i+1+lines_added - lines[i] += '\n call void @emscripten_autodebug_%s(i32 %d, %s %%%s)' % (m.group('type'), index, m.group('type'), m.group('var')) - lines_added += 1 + if m.group('type') in ['i8', 'i16', 'i32', 'i64', 'float', 'double']: + lines[i] += '\n call void @emscripten_autodebug_%s(i32 %d, %s %s)' % (m.group('type'), index, m.group('type'), m.group('var')) + lines_added += 1 + elif ALLOW_POINTERS and m.group('type').endswith('*') and m.group('type').count('*') == 1: + lines[i] += '\n %%ead.%d = ptrtoint %s %s to i32' % (index, m.group('type'), m.group('var')) + lines[i] += '\n call void @emscripten_autodebug_i32(i32 %d, i32 %%ead.%d)' % (index, index) + lines_added += 2 continue - m = re.match(' call void @llvm\.memcpy\.p0i8\.p0i8\.i32\(i8\* %(?P<dst>[\w_.]+), i8\* %(?P<src>[\w_.]+), i32 8, i32 (?P<align>\d+),.*', lines[i]) + m = re.match(' %(?P<var>[\w_.]+) = load (?P<type>i64|i32|i16|i8|float|double+)\* [^(].*.*', lines[i]) if m: index = i+1+lines_added - lines[i] += '\n %%adpretemp%d = bitcast i8* %%%s to i64*' % (index, m.group('src')) + \ - '\n %%adtemp%d = load i64* %%adpretemp%d, align %s' % (index, index, m.group('align')) + \ - '\n call void @emscripten_autodebug_%s(i32 %d, %s %%adtemp%d)' % ('i64', index, 'i64', index) - lines_added += 3 + lines[i] += '\n call void @emscripten_autodebug_%s(i32 %d, %s %%%s)' % (m.group('type'), index, m.group('type'), m.group('var')) + lines_added += 1 continue + if ALLOW_MISC: + m = re.match(' %(?P<var>[\w_.]+) = (call|mul|add) (nsw )?(?P<type>i64|i32|i16|i8|float|double+) .*', lines[i]) + if m: + index = i+1+lines_added + lines[i] += '\n call void @emscripten_autodebug_%s(i32 %d, %s %%%s)' % (m.group('type'), index, m.group('type'), m.group('var')) + lines_added += 1 + continue + m = re.match(' call void @llvm\.memcpy\.p0i8\.p0i8\.i32\(i8\* %(?P<dst>[\w_.]+), i8\* %(?P<src>[\w_.]+), i32 8, i32 (?P<align>\d+),.*', lines[i]) + if m: + index = i+1+lines_added + lines[i] += '\n %%adpretemp%d = bitcast i8* %%%s to i64*' % (index, m.group('src')) + \ + '\n %%adtemp%d = load i64* %%adpretemp%d, align %s' % (index, index, m.group('align')) + \ + '\n call void @emscripten_autodebug_%s(i32 %d, %s %%adtemp%d)' % ('i64', index, 'i64', index) + lines_added += 3 + continue finally: if len(pre) > 0: diff --git a/tools/bindings_generator.py b/tools/bindings_generator.py index 3fbff13d..0c7c814f 100755 --- a/tools/bindings_generator.py +++ b/tools/bindings_generator.py @@ -671,25 +671,22 @@ def generate_class(generating_classname, classname, clazz): # TODO: deprecate ge has_string_convs = False - # We can assume that NULL is passed for null pointers, so object arguments can always - # have .ptr done on them - justargs_fixed = justargs(args)[:] - for i in range(len(args)): - arg = args[i] - clean = clean_type(arg['type']) - if clean in classes: - justargs_fixed[i] += '.ptr' - elif arg['type'].replace(' ', '').endswith('char*'): - justargs_fixed[i] = 'ensureString(' + justargs_fixed[i] + ')' - has_string_convs = True - calls = '' - if has_string_convs: - calls += 'var stack = Runtime.stackSave();\n'; - calls += 'try {\n' #print 'js loopin', params, '|', len(args)#, args for args in params: + # We can assume that NULL is passed for null pointers, so object arguments can always + # have .ptr done on them + justargs_fixed = justargs(args)[:] + for i in range(len(args)): + arg = args[i] + clean = clean_type(arg['type']) + if clean in classes: + justargs_fixed[i] += '.ptr' + elif arg['type'].replace(' ', '').endswith('char*'): + justargs_fixed[i] = 'ensureString(' + justargs_fixed[i] + ')' + has_string_convs = True + i = len(args) if args != params[0]: calls += ' else ' @@ -715,7 +712,7 @@ def generate_class(generating_classname, classname, clazz): # TODO: deprecate ge calls += '\n' if has_string_convs: - calls += '} finally { Runtime.stackRestore(stack) }\n'; + calls = 'var stack = Runtime.stackSave();\ntry {\n' + calls + '} finally { Runtime.stackRestore(stack) }\n'; print 'Maekin:', classname, generating_classname, mname, mname_suffixed if constructor: diff --git a/tools/bisect_pair.py b/tools/bisect_pair.py index 3b880b28..8eea0d61 100644 --- a/tools/bisect_pair.py +++ b/tools/bisect_pair.py @@ -47,14 +47,12 @@ if len(curr) > 0: chunks.append(curr) # Bisect both sides of the span, until we have a single chunk -low = 0 high = len(chunks) print 'beginning bisection, %d chunks' % high -while high-low > 2: - mid = (low + high)/2 - print ' current status: %d - %d - %d' % (low, mid, high) +for mid in range(high): + print ' current: %d' % mid # Take chunks from the middle and on. This is important because the eliminator removes variables, so starting from the beginning will add errors curr_diff = '\n'.join(map(lambda parts: '\n'.join(parts), chunks[mid:])) + '\n' difff = open('diff.diff', 'w') @@ -64,11 +62,11 @@ while high-low > 2: Popen(['patch', 'middle', 'diff.diff'], stdout=PIPE, stderr=PIPE).communicate() result = run_js('middle', stderr=PIPE) if result == left_result: - high = mid+1 - else: - low = mid + print 'found where it starts to work: %d' % mid + found = mid + break -critical = '\n'.join(chunks[low]) + '\n' +critical = '\n'.join(chunks[found-1]) + '\n' c = open('critical.diff', 'w') c.write(critical) @@ -76,8 +74,8 @@ c.close() print 'sanity check' shutil.copy('middle', 'middle2') Popen(['patch', 'middle2', 'critical.diff'], stdout=PIPE, stderr=PIPE).communicate() -assert run_js('middle', stderr=PIPE) == left_result -assert run_js('middle2', stderr=PIPE) != left_result +assert run_js('middle', stderr=PIPE) == left_result, 'middle was expected %s' % left_result +assert run_js('middle2', stderr=PIPE) != left_result, 'middle2 was expected NOT %s' % left_result print 'middle is like left, middle2 is like right, critical.diff is the difference that matters,' print critical diff --git a/tools/clean_webconsole.py b/tools/clean_webconsole.py index 56bd9e2b..43694179 100644 --- a/tools/clean_webconsole.py +++ b/tools/clean_webconsole.py @@ -2,7 +2,23 @@ Removes timestamp and line info from a webgl log ''' -import os, sys +import os, sys, re + +__rootpath__ = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +def path_from_root(*pathelems): + return os.path.join(__rootpath__, *pathelems) + +def nice(x): + return '0x' + ('0' * (len(x)-6)) + x[2:].upper() + +repdata = open(path_from_root('system', 'include', 'GL', 'gl.h')).readlines() + ['\n'] + \ + open(path_from_root('system', 'include', 'GL', 'glext.h')).readlines() +reps = {} +for rep in repdata: + rep = rep.replace('\t', ' ').replace('\n', '') + parts = filter(lambda part: part != '', rep.split(' ')) + if len(parts) == 3 and parts[0] == '#define': + reps[nice(parts[2])] = '%s (%s)' % (parts[1], parts[2]) lines = sys.stdin.read().split('\n') @@ -10,8 +26,9 @@ for line in lines: if line.startswith('['): line = line[15:] line = line.split(' @ ')[0] + line = re.sub('(0x[\dabcdef]+)', lambda hexx: reps[nice(hexx.group(0))] if nice(hexx.group(0)) in reps else nice(hexx.group(0)), line) print line -for i in range(100): - print +#for i in range(100): +# print diff --git a/tools/crunch-worker.js b/tools/crunch-worker.js new file mode 100644 index 00000000..5c48d009 --- /dev/null +++ b/tools/crunch-worker.js @@ -0,0 +1,124 @@ +// From Brandon Jones' awesome WebGL texture utils, +// https://github.com/toji/webgl-texture-utils +// which in turn based off of Evan Parker's cool work, +// http://www-cs-students.stanford.edu/~eparker/files/crunch/decode_test.html +// +// This combines crunch-worker.js and crn_decomp.js. Minor changes +// to make it work that way, and to return all levels in one array + + /* + * Copyright (c) 2012 Brandon Jones + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not + * be misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + */ + + // Taken from crnlib.h + var cCRNFmtInvalid = -1; + + var cCRNFmtDXT1 = 0; + var cCRNFmtDXT3 = 1; + var cCRNFmtDXT5 = 2; + + // Various DXT5 derivatives + var cCRNFmtDXT5_CCxY = 3; // Luma-chroma + var cCRNFmtDXT5_xGxR = 4; // Swizzled 2-component + var cCRNFmtDXT5_xGBR = 5; // Swizzled 3-component + var cCRNFmtDXT5_AGBR = 6; // Swizzled 4-component + + // ATI 3DC and X360 DXN + var cCRNFmtDXN_XY = 7; + var cCRNFmtDXN_YX = 8; + + // DXT5 alpha blocks only + var cCRNFmtDXT5A = 9; + + function arrayBufferCopy(src, dst, dstByteOffset, numBytes) { + dst.set(src.subarray(0, numBytes), dstByteOffset); + } + + function deCrunch(bytes, filename) { + var srcSize = bytes.length; + var src = Module._malloc(srcSize), + format, internalFormat, dst, dstSize, + width, height, levels, dxtData, rgb565Data, i; + + arrayBufferCopy(bytes, Module.HEAPU8, src, srcSize); + + format = Module._crn_get_dxt_format(src, srcSize); + + if(format != cCRNFmtDXT1 && format != cCRNFmtDXT3 && format != cCRNFmtDXT5) { + throw "Unsupported image format " + format + " for " + filename; + } + width = Module._crn_get_width(src, srcSize); + height = Module._crn_get_height(src, srcSize); + levels = Module._crn_get_levels(src, srcSize); + dstSize = Module._crn_get_uncompressed_size(src, srcSize, 0); + dst = Module._malloc(dstSize); + + var totalSize = 0; + var bytesPerPixel = format == cCRNFmtDXT1 ? 0.5 : 1; + for(i = 0; i < levels; ++i) { + totalSize += width * height * bytesPerPixel; + width *= 0.5; + height *= 0.5; + width = Math.max(width, 4); + height = Math.max(height, 4); + } + + width = Module._crn_get_width(src, srcSize); + height = Module._crn_get_height(src, srcSize); + + var ret = new Uint8Array(totalSize); + var retIndex = 0; + + for(i = 0; i < levels; ++i) { + if(i) { + dstSize = Module._crn_get_uncompressed_size(src, srcSize, i); + } + Module._crn_decompress(src, srcSize, dst, dstSize, i); + ret.set(Module.HEAPU8.subarray(dst, dst+dstSize), retIndex); + retIndex += dstSize; + + width *= 0.5; + height *= 0.5; + } + + Module._free(src); + Module._free(dst); + + return ret; + } + + //=== +function a(b){throw b}var aa=void 0,l=!0,pa=null,n=!1,za=[],Da="object"===typeof process,Ea="object"===typeof window,Fa="function"===typeof importScripts,Ja=!Ea&&!Da&&!Fa;if(Da){print=(function(b){process.stdout.write(b+"\n")});printErr=(function(b){process.stderr.write(b+"\n")});var Ma=require("fs");read=(function(b){var c=Ma.readFileSync(b).toString();!c&&"/"!=b[0]&&(b=__dirname.split("/").slice(0,-1).join("/")+"/src/"+b,c=Ma.readFileSync(b).toString());return c});load=(function(b){Na(read(b))});za=process.argv.slice(2)}else{Ja?(this.read||(this.read=(function(b){snarf(b)})),"undefined"!=typeof scriptArgs?za=scriptArgs:"undefined"!=typeof arguments&&(za=arguments)):Ea?(this.print=printErr=(function(b){console.log(b)}),this.read=(function(b){var c=new XMLHttpRequest;c.open("GET",b,n);c.send(pa);return c.responseText}),this.arguments&&(za=arguments)):Fa?this.load=importScripts:a("Unknown runtime environment. Where are we?")}function Na(b){eval.call(pa,b)}"undefined"==typeof load&&"undefined"!=typeof read&&(this.load=(function(b){Na(read(b))}));"undefined"===typeof printErr&&(this.printErr=(function(){}));"undefined"===typeof print&&(this.print=printErr);try{this.Module=Module}catch(Qa){this.Module=Module={}}Module.arguments||(Module.arguments=za);Module.print&&(print=Module.print);function Wa(b){if(Xa==1){return 1}var c={"%i1":1,"%i8":1,"%i16":2,"%i32":4,"%i64":8,"%float":4,"%double":8}["%"+b];if(!c){if(b[b.length-1]=="*"){c=Xa}else{if(b[0]=="i"){b=parseInt(b.substr(1));Ya(b%8==0);c=b/8}}}return c}function cb(b){var c=q;q=q+b;q=q+3>>2<<2;return c}function db(b){var c=eb;eb=eb+b;eb=eb+3>>2<<2;if(eb>=fb){for(;fb<=eb;){fb=2*fb+4095>>12<<12}var b=v,d=new ArrayBuffer(fb);v=new Int8Array(d);gb=new Int16Array(d);y=new Int32Array(d);z=new Uint8Array(d);A=new Uint16Array(d);C=new Uint32Array(d);lb=new Float32Array(d);mb=new Float64Array(d);v.set(b)}return c}var Xa=4,ub={},vb;function wb(b){print(b+":\n"+Error().stack);a("Assertion: "+b)}function Ya(b,c){b||wb("Assertion failed: "+c)}var Mb=this;Module.ccall=(function(b,c,d,e){try{var g=eval("_"+b)}catch(h){try{g=Mb.Module["_"+b]}catch(j){}}Ya(g,"Cannot call unknown function "+b+" (perhaps LLVM optimizations or closure removed it?)");var i=0,b=e?e.map((function(b){if(d[i++]=="string"){var c=q;cb(b.length+1);Nb(b,c);b=c}return b})):[];return(function(b,c){return c=="string"?Vb(b):b})(g.apply(pa,b),c)});function Wb(b,c,d){d=d||"i8";d[d.length-1]==="*"&&(d="i32");switch(d){case"i1":v[b]=c;break;case"i8":v[b]=c;break;case"i16":gb[b>>1]=c;break;case"i32":y[b>>2]=c;break;case"i64":y[b>>2]=c;break;case"float":lb[b>>2]=c;break;case"double":Yb[0]=c;y[b>>2]=Zb[0];y[b+4>>2]=Zb[1];break;default:wb("invalid type for setValue: "+d)}}Module.setValue=Wb;Module.getValue=(function(b,c){c=c||"i8";c[c.length-1]==="*"&&(c="i32");switch(c){case"i1":return v[b];case"i8":return v[b];case"i16":return gb[b>>1];case"i32":return y[b>>2];case"i64":return y[b>>2];case"float":return lb[b>>2];case"double":return Zb[0]=y[b>>2],Zb[1]=y[b+4>>2],Yb[0];default:wb("invalid type for setValue: "+c)}return pa});var $b=1,D=2;Module.ALLOC_NORMAL=0;Module.ALLOC_STACK=$b;Module.ALLOC_STATIC=D;function G(b,c,d){var e,g;if(typeof b==="number"){e=l;g=b}else{e=n;g=b.length}var h=typeof c==="string"?c:pa,d=[ac,cb,db][d===aa?D:d](Math.max(g,h?1:c.length));if(e){bc(d,0,g);return d}e=0;for(var j;e<g;){var i=b[e];typeof i==="function"&&(i=ub.xa(i));j=h||c[e];if(j===0){e++}else{j=="i64"&&(j="i32");Wb(d+e,i,j);e=e+Wa(j)}}return d}Module.allocate=G;function Vb(b,c){for(var d=typeof c=="undefined",e="",g=0,h,j=String.fromCharCode(0);;){h=String.fromCharCode(z[b+g]);if(d&&h==j){break}e=e+h;g=g+1;if(!d&&g==c){break}}return e}Module.Pointer_stringify=Vb;Module.Array_stringify=(function(b){for(var c="",d=0;d<b.length;d++){c=c+String.fromCharCode(b[d])}return c});var dc,ec=4096,v,z,gb,A,y,C,lb,mb,q,fc,eb,hc=Module.TOTAL_STACK||5242880,fb=Module.TOTAL_MEMORY||10485760;Ya(!!Int32Array&&!!Float64Array&&!!(new Int32Array(1)).subarray&&!!(new Int32Array(1)).set,"Cannot fallback to non-typed array case: Code is too specialized");var ic=new ArrayBuffer(fb);v=new Int8Array(ic);gb=new Int16Array(ic);y=new Int32Array(ic);z=new Uint8Array(ic);A=new Uint16Array(ic);C=new Uint32Array(ic);lb=new Float32Array(ic);mb=new Float64Array(ic);y[0]=255;Ya(255===z[0]&&0===z[3],"Typed arrays 2 must be run on a little-endian system");var kc=jc("(null)");eb=kc.length;for(var lc=0;lc<kc.length;lc++){v[lc]=kc[lc]}Module.HEAP=aa;Module.HEAP8=v;Module.HEAP16=gb;Module.HEAP32=y;Module.HEAPU8=z;Module.HEAPU16=A;Module.HEAPU32=C;Module.HEAPF32=lb;Module.HEAPF64=mb;fc=(q=4*Math.ceil(eb/4))+hc;var mc=8*Math.ceil(fc/8);v.subarray(mc);var Zb=y.subarray(mc>>2);lb.subarray(mc>>2);var Yb=mb.subarray(mc>>3);fc=mc+8;eb=fc+4095>>12<<12;function nc(b){for(;b.length>0;){var c=b.shift(),d=c.r;typeof d==="number"&&(d=dc[d]);d(c.da===aa?pa:c.da)}}var pc=[],qc=[];function rc(b,c){return Array.prototype.slice.call(v.subarray(b,b+c))}Module.Array_copy=rc;Module.TypedArray_copy=(function(b,c){for(var d=new Uint8Array(c),e=0;e<c;++e){d[e]=v[b+e]}return d.buffer});function sc(b){for(var c=0;v[b+c];){c++}return c}Module.String_len=sc;function tc(b,c){var d=sc(b);c&&d++;var e=rc(b,d);c&&(e[d-1]=0);return e}Module.String_copy=tc;function jc(b,c){for(var d=[],e=0;e<b.length;){var g=b.charCodeAt(e);g>255&&(g=g&255);d.push(g);e=e+1}c||d.push(0);return d}Module.intArrayFromString=jc;Module.intArrayToString=(function(b){for(var c=[],d=0;d<b.length;d++){var e=b[d];e>255&&(e=e&255);c.push(String.fromCharCode(e))}return c.join("")});function Nb(b,c,d){for(var e=0;e<b.length;){var g=b.charCodeAt(e);g>255&&(g=g&255);v[c+e]=g;e=e+1}d||(v[c+e]=0)}Module.writeStringToMemory=Nb;var M=[];function uc(b,c){return b>=0?b:c<=32?2*Math.abs(1<<c-1)+b:Math.pow(2,c)+b}function vc(b,c){if(b<=0){return b}var d=c<=32?Math.abs(1<<c-1):Math.pow(2,c-1);if(b>=d&&(c<=32||b>d)){b=-2*d+b}return b}function wc(b){b=b-1|0;b=b>>>16|b;b=b>>>8|b;b=b>>>4|b;b=b>>>2|b;return(b>>>1|b)+1|0}function xc(b,c){var d=M.O|0,e=q;q=q+512;for(var g=e|0,d=(vb=q,q=q+12,y[vb>>2]=d,y[vb+4>>2]=c,y[vb+8>>2]=b,vb),d=yc(M.G|0,d),h=d.length,j=0;j<h;j++){v[g+j]=d[j]}v[g+j]=0;h=(vb=q,q=q+1,q=q+3>>2<<2,y[vb>>2]=0,vb);d=y[zc>>2];j=yc(g,h);g=q;h=G(j,"i8",$b);j=j.length*1;if(j!=0&&Dc(d,h,j)==-1&&Ec[d]){Ec[d].error=l}q=g;q=e}function Fc(b,c,d,e,g){var h,j,i=q;q=q+4;var f=b+4|0;j=(b+8|0)>>2;C[f>>2]>>>0>C[j]>>>0&&xc(M.H|0,2121);Math.floor(2147418112/(e>>>0))>>>0>c>>>0||xc(M.T|0,2122);var k=C[j],o=k>>>0<c>>>0;do{if(o){var m=d?((c|0)==0?0:(c-1&c|0)==0)?c:wc(c):c;(m|0)!=0&m>>>0>k>>>0||xc(M.Y|0,2131);var t=m*e|0;if((g|0)==0){h=b|0;var s,w=y[h>>2],u=t,r=i;s=q;q=q+4;if((w&7|0)==0){if(u>>>0>2147418112){xc(M.m|0,2500);r=0}else{y[s>>2]=u;w=dc[y[Gc>>2]](w,u,s,1,y[Hc>>2]);(r|0)!=0&&(y[r>>2]=y[s>>2]);(w&7|0)!=0&&xc(M.n|0,2552);r=w}}else{xc(M.J|0,2500);r=0}q=s;s=r;if((s|0)==0){m=0;break}y[h>>2]=s}else{s=Ic(t,i);if((s|0)==0){m=0;break}h=(b|0)>>2;dc[g](s,y[h],y[f>>2]);r=y[h];(r|0)!=0&&Jc(r);y[h]=s}h=C[i>>2];y[j]=h>>>0>t>>>0?Math.floor((h>>>0)/(e>>>0)):m}m=1}while(0);q=i;return m}Fc.X=1;function Ic(b,c){var d=q;q=q+4;var e=b+3&-4,e=(e|0)==0?4:e;if(e>>>0>2147418112){xc(M.m|0,2500);e=0}else{y[d>>2]=e;var g=dc[y[Gc>>2]](0,e,d,1,y[Hc>>2]),h=C[d>>2];(c|0)!=0&&(y[c>>2]=h);if((g|0)==0|h>>>0<e>>>0){xc(M.I|0,2500);e=0}else{(g&7|0)!=0&&xc(M.n|0,2527);e=g}}q=d;return e}function Jc(b){if((b|0)!=0){if((b&7|0)==0){dc[y[Gc>>2]](b,0,0,1,y[Hc>>2])}else{xc(M.K|0,2500)}}}function Kc(b,c,d,e){var g,h,j,i,f=b>>2,k=q;q=q+200;var o;i=k>>2;var m=k+64;j=m>>2;var t=k+132,s=(c|0)==0|e>>>0>11;a:do{if(s){var w=0}else{y[f]=c;bc(m,0,68);for(var u=0;;){var r=z[d+u|0];if(r<<24>>24!=0){var x=((r&255)<<2)+m|0;y[x>>2]=y[x>>2]+1|0}var p=u+1|0;if((p|0)==(c|0)){var B=1,I=-1,S=0,Q=0,H=0;break}u=p}for(;;){var J=C[(B<<2>>2)+j];if((J|0)==0){y[((B-1<<2)+28>>2)+f]=0;var K=H,E=Q,da=S,N=I}else{var ka=I>>>0<B>>>0?I:B,ba=S>>>0>B>>>0?S:B,ra=B-1|0;y[(ra<<2>>2)+i]=H;var ia=J+H|0,fa=16-B|0;y[((ra<<2)+28>>2)+f]=(ia-1<<fa|(1<<fa)-1)+1|0;y[((ra<<2)+96>>2)+f]=Q;y[t+(B<<2)>>2]=Q;K=ia;E=J+Q|0;da=ba;N=ka}var Ga=B+1|0;if((Ga|0)==17){break}B=Ga;I=N;S=da;Q=E;H=K<<1}y[f+1]=E;h=(b+172|0)>>2;if(E>>>0>C[h]>>>0){var ta=((E|0)==0?0:(E-1&E|0)==0)?E:c>>>0<wc(E)>>>0?c:wc(E);y[h]=ta;var la=b+176|0,Aa=y[la>>2];if((Aa|0)==0){var xa=ta}else{Lc(Aa);xa=y[h]}var Y,ma=(xa|0)==0?1:xa,ga=Ic((ma<<1)+8|0,0);if((ga|0)==0){var ua=0}else{var Ba=ga+8|0;y[ga+4>>2]=ma;y[ga>>2]=ma^-1;ua=Ba}Y=ua;y[la>>2]=Y;if((Y|0)==0){w=0;break}var Ca=la}else{Ca=b+176|0}var va=b+24|0;v[va]=N&255;v[b+25|0]=da&255;for(var Z=0;;){var sa=z[d+Z|0],T=sa&255;if(sa<<24>>24!=0){(y[(T<<2>>2)+j]|0)==0&&xc(M.Z|0,2274);var ea=(T<<2)+t|0,W=C[ea>>2];y[ea>>2]=W+1|0;W>>>0<E>>>0||xc(M.$|0,2278);gb[y[Ca>>2]+(W<<1)>>1]=Z&65535}var ya=Z+1|0;if((ya|0)==(c|0)){break}Z=ya}var L=z[va],O=(L&255)>>>0<e>>>0?e:0,qa=b+8|0;y[qa>>2]=O;var na=(O|0)!=0;if(na){var U=1<<O,P=b+164|0,F=U>>>0>C[P>>2]>>>0;do{if(F){y[P>>2]=U;var oa=b+168|0,wa=y[oa>>2];(wa|0)!=0&&Mc(wa);var ca,V=(U|0)==0?1:U,ja=Ic((V<<2)+8|0,0);if((ja|0)==0){var Oa=0}else{var hb=ja+8|0;y[ja+4>>2]=V;y[ja>>2]=V^-1;Oa=hb}ca=Oa;y[oa>>2]=ca;if((ca|0)==0){w=0;break a}bc(ca,-1,U<<2);if((O|0)==0){o=26}else{Ra=oa;o=34}}else{var Ha=b+168|0;bc(y[Ha>>2],-1,U<<2);var Ra=Ha;o=34}}while(0);b:do{if(o==34){for(var Za=1;;){var Ob=(y[(Za<<2>>2)+j]|0)==0;c:do{if(!Ob){var xb=O-Za|0,Pb=1<<xb,yb=Za-1|0,ha=C[(yb<<2>>2)+i],Ka,La=b,ib=Za;(ib|0)!=0&ib>>>0<17||xc(M.W|0,1954);var zb=y[La+(ib-1<<2)+28>>2];Ka=(zb|0)==0?-1:(zb-1|0)>>>((16-ib|0)>>>0);if(ha>>>0<=Ka>>>0){for(var Qb=y[((yb<<2)+96>>2)+f]-ha|0,Rb=Za<<16,$a=ha;;){var Sb=A[y[Ca>>2]+(Qb+$a<<1)>>1]&65535;(z[d+Sb|0]&255|0)!=(Za|0)&&xc(M.aa|0,2320);for(var Tb=$a<<xb,cc=Sb|Rb,Ab=0;;){var bb=Ab+Tb|0;bb>>>0<U>>>0||xc(M.ba|0,2326);var ab=C[Ra>>2];if((y[ab+(bb<<2)>>2]|0)==-1){var Ia=ab}else{xc(M.ca|0,2328);Ia=y[Ra>>2]}y[Ia+(bb<<2)>>2]=cc;var Bb=Ab+1|0;if(Bb>>>0>=Pb>>>0){break}Ab=Bb}var Cb=$a+1|0;if(Cb>>>0>Ka>>>0){break c}$a=Cb}}}}while(0);var Db=Za+1|0;if(Db>>>0>O>>>0){break b}Za=Db}}}while(0);var ob=v[va]}else{ob=L}var pb=b+96|0;y[pb>>2]=y[pb>>2]-y[i]|0;var Eb=b+100|0;y[Eb>>2]=y[Eb>>2]-y[i+1]|0;var Fb=b+104|0;y[Fb>>2]=y[Fb>>2]-y[i+2]|0;var qb=b+108|0;y[qb>>2]=y[qb>>2]-y[i+3]|0;var jb=b+112|0;y[jb>>2]=y[jb>>2]-y[i+4]|0;var rb=b+116|0;y[rb>>2]=y[rb>>2]-y[i+5]|0;var Sa=b+120|0;y[Sa>>2]=y[Sa>>2]-y[i+6]|0;var Pa=b+124|0;y[Pa>>2]=y[Pa>>2]-y[i+7]|0;var sb=b+128|0;y[sb>>2]=y[sb>>2]-y[i+8]|0;var Ta=b+132|0;y[Ta>>2]=y[Ta>>2]-y[i+9]|0;var Gb=b+136|0;y[Gb>>2]=y[Gb>>2]-y[i+10]|0;var Hb=b+140|0;y[Hb>>2]=y[Hb>>2]-y[i+11]|0;var Ib=b+144|0;y[Ib>>2]=y[Ib>>2]-y[i+12]|0;var tb=b+148|0;y[tb>>2]=y[tb>>2]-y[i+13]|0;var Jb=b+152|0;y[Jb>>2]=y[Jb>>2]-y[i+14]|0;var Kb=b+156|0;y[Kb>>2]=y[Kb>>2]-y[i+15]|0;var Lb=b+16|0;y[Lb>>2]=0;g=(b+20|0)>>2;y[g]=ob&255;b:do{if(na){for(var kb=O;;){if((kb|0)==0){break b}var Ua=kb-1|0;if((y[(kb<<2>>2)+j]|0)!=0){break}kb=Ua}y[Lb>>2]=y[((Ua<<2)+28>>2)+f];for(var Ub=O+1|0,Va=y[g]=Ub;;){if(Va>>>0>da>>>0){break b}if((y[(Va<<2>>2)+j]|0)!=0){break}Va=Va+1|0}y[g]=Va}}while(0);y[f+23]=-1;y[f+40]=1048575;y[f+3]=32-y[qa>>2]|0;w=1}}while(0);q=k;return w}Kc.X=1;function Lc(b){var c;if((b|0)!=0){c=y[b-4>>2];b=b-8|0;c=(c|0)==0?4:(c|0)==(y[b>>2]^-1|0)?5:4;c==4&&xc(M.p|0,645);Jc(b)}}function Mc(b){var c;if((b|0)!=0){c=y[b-4>>2];b=b-8|0;c=(c|0)==0?4:(c|0)==(y[b>>2]^-1|0)?5:4;c==4&&xc(M.p|0,645);Jc(b)}}function Nc(b){return(z[b|0]&255)<<8|z[b+1|0]&255}function Oc(b){return(z[b+1|0]&255)<<16|(z[b|0]&255)<<24|z[b+3|0]&255|(z[b+2|0]&255)<<8}function Pc(b){return z[b|0]&255}function Qc(b){return z[b+2|0]&255|(z[b|0]&255)<<16|(z[b+1|0]&255)<<8}function Rc(b,c){if(b==0&&c==0||b==9&&c==0){var d=4}else{if(b==1&&c==0||b==2&&c==0||b==7&&c==0||b==8&&c==0||b==3&&c==0||b==4&&c==0||b==5&&c==0||b==6&&c==0){d=8}else{xc(M.M|0,2664);d=0}}return d}function Sc(b,c){return(b|0)==0|c>>>0<74?0:(Nc(b)|0)!=18552?0:Nc(b+2|0)>>>0<74?0:Oc(b+6|0)>>>0>c>>>0?0:b}function Tc(b,c,d){var e=d>>2;if((b|0)==0|c>>>0<74|(d|0)==0){e=0}else{if((y[e]|0)!=40){e=0}else{b=Sc(b,c);if((b|0)==0){e=0}else{y[e+1]=Nc(b+12|0);y[e+2]=Nc(b+14|0);y[e+3]=Pc(b+16|0);y[e+4]=Pc(b+17|0);c=b+18|0;d=d+32|0;y[d>>2]=Pc(c);y[d+4>>2]=0;d=Pc(c);y[e+5]=(d|0)==0?8:(d|0)==9?8:16;y[e+6]=Oc(b+25|0);y[e+7]=Oc(b+29|0);e=1}}}return e}Tc.X=1;function Uc(b){y[b>>2]=0;var c=b+4|0;y[c>>2]=0;y[c+4>>2]=0;y[c+8>>2]=0;v[c+12|0]=0;y[b+20>>2]=0}function Vc(b){var c=y[b+20>>2];if((c|0)!=0&&(c|0)!=0){Wc(c);Jc(c)}Xc(b+4|0)}function Xc(b){var c=b|0,d=y[c>>2];if((d|0)!=0){var e=b+4|0;Jc(d);y[c>>2]=0;y[e>>2]=0;y[b+8>>2]=0}v[b+12|0]=0}function Yc(b,c){var d;d=(b+4|0)>>2;var e=C[d],g=(e|0)==(c|0);do{if(g){var h=1}else{if(e>>>0<=c>>>0){if(C[b+8>>2]>>>0<c>>>0){h=b;if(Fc(h,c,(e+1|0)==(c|0),1,0)){h=1}else{v[h+12|0]=1;h=0}if(!h){h=0;break}h=y[d]}else{h=e}bc(y[b>>2]+h|0,0,c-h|0)}y[d]=c;h=1}}while(0);return h}function Zc(b,c){C[b+4>>2]>>>0>c>>>0||xc(M.g|0,904);return y[b>>2]+c|0}function $c(b){var c=b+4|0,d=y[c+4>>2];(d|0)!=0&d>>>0<8193||xc(M.N|0,2998);var e=b|0;y[e>>2]=d;var g=b+20|0,h=C[g>>2];if((h|0)==0){d=Ic(180,0);if((d|0)==0){d=0}else{if((d|0)==0){d=0}else{y[d+164>>2]=0;y[d+168>>2]=0;y[d+172>>2]=0;y[d+176>>2]=0}}g=y[g>>2]=d;e=y[e>>2]}else{g=h;e=d}var c=Zc(c,0),b=C[b>>2],j;if(b>>>0>16){d=b>>>0>1;a:do{if(d){for(var i=0,h=b;;){i=i+1|0;if(h>>>0<=3){j=i;break a}h=h>>>1}}else{j=0}}while(0);j=(j|0)==32?32:(1<<j>>>0<b>>>0&1)+j|0;j=((j+1|0)>>>0<11?j+1|0:11)&255}else{j=0}return Kc(g,e,c,j)}function ad(b,c){if((c|0)==0){var d=0}else{if(c>>>0>16){var d=bd(b,c-16|0),e=bd(b,16),d=d<<16|e}else{d=bd(b,c)}}return d}function R(b,c){var d,e,g,h;g=C[c+20>>2]>>2;e=(b+20|0)>>2;var j=C[e];if((j|0)<24){d=(b+4|0)>>2;var i=C[d],f=C[b+8>>2];h=i>>>0<f>>>0;if((j|0)<16){if(h){h=i+1|0;i=(z[i]&255)<<8}else{h=i;i=0}if(h>>>0<f>>>0){f=h+1|0;h=z[h]&255}else{f=h;h=0}y[d]=f;y[e]=j+16|0;d=b+16|0;j=(h|i)<<16-j|y[d>>2]}else{if(h){y[d]=i+1|0;i=z[i]&255}else{i=0}y[e]=j+8|0;d=b+16|0;j=i<<24-j|y[d>>2]}y[d>>2]=j}else{j=y[b+16>>2]}d=b+16|0;i=(j>>>16)+1|0;f=i>>>0>C[g+4]>>>0;do{if(f){h=C[g+5];var k=h-1|0,o=i>>>0>C[((k<<2)+28>>2)+g]>>>0;a:do{if(o){for(var m=h;;){var t=m+1|0;if(i>>>0<=C[((m<<2)+28>>2)+g]>>>0){var s=t,w=m;break a}m=t}}else{s=h;w=k}}while(0);h=(j>>>((32-s|0)>>>0))+y[((w<<2)+96>>2)+g]|0;if(h>>>0<C[c>>2]>>>0){r=s;x=A[y[g+44]+(h<<1)>>1]&65535;h=22}else{xc(M.o|0,3267);var u=0;h=23}}else{r=C[y[g+42]+(j>>>((32-y[g+2]|0)>>>0)<<2)>>2];(r|0)==-1&&xc(M.R|0,3245);x=r&65535;r=r>>>16;h=c+4|0;k=x;C[h+4>>2]>>>0>k>>>0||xc(M.g|0,903);if((z[y[h>>2]+k|0]&255|0)==(r|0)){var r=r,x=x}else{xc(M.S|0,3249)}h=22}}while(0);if(h==22){y[d>>2]=y[d>>2]<<r;y[e]=y[e]-r|0;u=x}return u}R.X=1;function cd(b,c,d){if((d|0)==0){b=0}else{y[b>>2]=c;y[b+4>>2]=c;y[b+12>>2]=d;y[b+8>>2]=c+d|0;y[b+16>>2]=0;y[b+20>>2]=0;b=1}return b}function bd(b,c){var d;c>>>0<33||xc(M.P|0,3191);d=(b+20|0)>>2;var e=C[d],g=(e|0)<(c|0);a:do{if(g){for(var h=b+4|0,j=b+8|0,i=b+16|0,f=e;;){var k=y[h>>2];if((k|0)==(y[j>>2]|0)){k=0}else{y[h>>2]=k+1|0;k=z[k]&255}f=f+8|0;y[d]=f;if((f|0)>=33){xc(M.Q|0,3200);f=y[d]}k=k<<32-f|y[i>>2];y[i>>2]=k;if((f|0)>=(c|0)){var o=f,m=k;break a}}}else{o=e;m=y[b+16>>2]}}while(0);y[b+16>>2]=m<<c;y[d]=o-c|0;return m>>>((32-c|0)>>>0)}bd.X=1;function dd(b,c){var d,e=q;q=q+24;a:do{for(var g=0,h=8192;;){h=h>>>1;g=g+1|0;if((h|0)==0){d=g;break a}}}while(0);d=ad(b,d);g=(d|0)==0;do{if(g){h=c;y[h>>2]=0;Xc(h+4|0);var h=h+20|0,j=y[h>>2];if((j|0)!=0){if((j|0)!=0){Wc(j);Jc(j)}y[h>>2]=0}h=1}else{h=c+4|0;if(Yc(h,d)){j=Zc(h,0);bc(j,0,d);j=ad(b,5);if((j|0)==0|j>>>0>21){h=0}else{Uc(e);var i=e+4|0,f=Yc(i,21);a:do{if(f){for(var k=0;;){var o=ad(b,3),m=Zc(i,z[M.C+k|0]&255);v[m]=o&255;k=k+1|0;if((k|0)==(j|0)){break}}if($c(e)){k=0;b:for(;;){for(var m=k>>>0<d>>>0,o=d-k|0,t=(k|0)==0,s=k-1|0;;){if(!m){if((k|0)!=(d|0)){p=0;break a}p=$c(c);break a}var w=R(b,e);if(w>>>0<17){o=Zc(h,k);v[o]=w&255;k=k+1|0;continue b}if((w|0)==17){m=ad(b,3)+3|0;if(m>>>0>o>>>0){p=0;break a}k=m+k|0;continue b}else{if((w|0)==18){m=ad(b,7)+11|0;if(m>>>0>o>>>0){p=0;break a}k=m+k|0;continue b}else{if((w-19|0)>>>0>=2){xc(M.o|0,3141);p=0;break a}w=(w|0)==19?ad(b,2)+3|0:ad(b,6)+7|0;if(t|w>>>0>o>>>0){p=0;break a}var u=Zc(h,s),u=z[u];if(u<<24>>24==0){p=0;break a}var r=w+k|0;if(k>>>0<r>>>0){var x=k;break}}}}for(;;){o=Zc(h,x);m=x+1|0;v[o]=u;if((m|0)==(r|0)){k=r;continue b}x=m}}}else{var p=0}}else{p=0}}while(0);Vc(e);h=p}}else{h=0}}}while(0);q=e;return h}dd.X=1;function ed(b,c,d,e,g,h,j){var i=b+88|0,f=C[i>>2],k=((Nc(f+12|0)>>>(j>>>0)>>>0>1?Nc(f+12|0)>>>(j>>>0):1)+3|0)>>>2,j=((Nc(f+14|0)>>>(j>>>0)>>>0>1?Nc(f+14|0)>>>(j>>>0):1)+3|0)>>>2,f=Pc(f+18|0),f=((f|0)==0?8:(f|0)==9?8:16)*k|0;if((h|0)==0){var o=f,h=5}else{if(f>>>0<=h>>>0&(h&3|0)==0){o=h;h=5}else{var m=0,h=12}}if(h==5){if((o*j|0)>>>0>g>>>0){m=0}else{g=(k+1|0)>>>1;m=(j+1|0)>>>1;if(cd(b+92|0,c,d)){c=Pc(y[i>>2]+18|0);if((c|0)==0){fd(b,e,0,o,k,j,g,m);m=1}else{if((c|0)==2||(c|0)==3||(c|0)==5||(c|0)==6||(c|0)==4){gd(b,e,0,o,k,j,g,m);m=1}else{if((c|0)==9){hd(b,e,0,o,k,j,g,m);m=1}else{if((c|0)==7||(c|0)==8){id(b,e,0,o,k,j,g,m);m=1}else{m=0}}}}}else{m=0}}}return m}ed.X=1;Module._crn_get_width=(function(b,c){var d=q;q=q+40;jd(d);Tc(b,c,d);var e=y[d+4>>2];q=d;return e});Module._crn_get_height=(function(b,c){var d=q;q=q+40;jd(d);Tc(b,c,d);var e=y[d+8>>2];q=d;return e});Module._crn_get_levels=(function(b,c){var d=q;q=q+40;jd(d);Tc(b,c,d);var e=y[d+12>>2];q=d;return e});Module._crn_get_dxt_format=(function(b,c){var d=q;q=q+40;jd(d);Tc(b,c,d);var e=y[(d+32|0)>>2];q=d;return e});Module._crn_get_uncompressed_size=(function(b,c,d){var e=q;q=q+40;jd(e);Tc(b,c,e);b=((C[e+4>>2]>>>(d>>>0))+3|0)>>>2;d=((C[e+8>>2]>>>(d>>>0))+3|0)>>>2;c=e+32|0;c=Rc(y[c>>2],y[c+4>>2])<<1&536870910;q=e;return b*c*d|0});Module._crn_decompress=(function(b,c,d,e,g){var h=q;q=q+44;var j=h+40;jd(h);Tc(b,c,h);var i=((C[h+4>>2]>>>(g>>>0))+3|0)>>>2,f=h+32|0,f=Rc(y[f>>2],y[f+4>>2])<<1&536870910,i=i*f|0,k;if((b|0)==0|c>>>0<62){k=0}else{f=Ic(300,0);if((f|0)==0){f=0}else{if((f|0)==0){f=0}else{y[f>>2]=519686845;y[f+4>>2]=0;y[f+8>>2]=0;y[f+88>>2]=0;var o=(f+92|0)>>2;y[o]=0;y[o+1]=0;y[o+2]=0;y[o+3]=0;y[o+4]=0;y[o+5]=0;Uc(f+116|0);Uc(f+140|0);Uc(f+164|0);Uc(f+188|0);Uc(f+212|0);kd(f+236|0);kd(f+252|0);ld(f+268|0);ld(f+284|0)}}if((f|0)==0){k=0}else{o=Sc(b,c);y[f+88>>2]=o;if((o|0)==0){k=0}else{y[f+4>>2]=b;y[f+8>>2]=c;var c=f+92|0,o=y[f+4>>2],b=(f+88|0)>>2,m=y[b],o=cd(c,o+Qc(m+67|0)|0,Nc(m+65|0));do{if(o){if(dd(c,f+116|0)){m=y[b];if((Nc(m+39|0)|0)==0){if((Nc(m+55|0)|0)==0){m=0;break}}else{if(!dd(c,f+140|0)){m=0;break}if(!dd(c,f+188|0)){m=0;break}m=y[b]}if((Nc(m+55|0)|0)!=0){if(!dd(c,f+164|0)){m=0;break}if(!dd(c,f+212|0)){m=0;break}}m=1}else{m=0}}else{m=0}}while(0);if(m){b=f+88|0;c=y[b>>2];if((Nc(c+39|0)|0)==0){k=c;b=5}else{if(md(f)){if(nd(f)){k=y[b>>2];b=5}else{t=0;b=9}}else{var t=0,b=9}}do{if(b==5){if((Nc(k+55|0)|0)!=0){if(!od(f)){t=0;break}if(!pd(f)){t=0;break}}t=1}}while(0);k=t}else{k=0}}if(k){k=f}else{if((f|0)!=0){qd(f);Jc(f)}k=0}}}j=j|0;y[j>>2]=d;if(!((k|0)==0|(j|0)==0|e>>>0<8|g>>>0>15)&&(y[k>>2]|0)==519686845){t=C[k+88>>2];d=Oc((g<<2)+t+70|0);f=y[k+8>>2];b=g+1|0;t=b>>>0<Pc(t+16|0)>>>0?Oc((b<<2)+t+70|0):f;t>>>0>d>>>0||xc(M.U|0,3705);ed(k,y[k+4>>2]+d|0,t-d|0,j,e,i,g)}if((k|0)!=0&&(y[k>>2]|0)==519686845&&(k|0)!=0){qd(k);Jc(k)}q=h});function ld(b){y[b>>2]=0;y[b+4>>2]=0;y[b+8>>2]=0;v[b+12|0]=0}function kd(b){y[b>>2]=0;y[b+4>>2]=0;y[b+8>>2]=0;v[b+12|0]=0}function jd(b){y[b>>2]=40}function rd(b){var c=b|0,d=y[c>>2];if((d|0)!=0){var e=b+4|0;Jc(d);y[c>>2]=0;y[e>>2]=0;y[b+8>>2]=0}v[b+12|0]=0}function sd(b){var c=b|0,d=y[c>>2];if((d|0)!=0){var e=b+4|0;Jc(d);y[c>>2]=0;y[e>>2]=0;y[b+8>>2]=0}v[b+12|0]=0}function Wc(b){var c=y[b+168>>2];(c|0)!=0&&Mc(c);b=y[b+176>>2];(b|0)!=0&&Lc(b)}function fd(b,c,d,e,g,h,j,i){var f,k,o,m,t,s=q;q=q+24;t=s>>2;var w=s+4;m=w>>2;var d=s+8>>2,u=b+236|0,r=y[u+4>>2],x=b+252|0,p=y[x+4>>2];y[t]=0;y[m]=0;var B=Pc(y[b+88>>2]+17|0),I=e>>>2,S=(B|0)==0;a:do{if(!S){for(var Q=(i|0)==0,H=i-1|0,J=(h&1|0)!=0,K=e<<1,E=b+92|0,da=b+116|0,N=b+188|0,ka=I+1|0,ba=I+2|0,ra=I+3|0,ia=j-1|0,fa=b+140|0,Ga=ia<<4,ta=(g&1|0)!=0,la=0,Aa=1;;){b:do{if(Q){var xa=Aa}else{for(var Y=y[c+(la<<2)>>2],ma=0,ga=Aa;;){if((ma&1|0)==0){var ua=Y,Ba=16,Ca=1,va=j,Z=0}else{ua=Y+Ga|0;Ba=-16;va=Ca=-1;Z=ia}var sa=(ma|0)==(H|0),T=sa&J,ea=(Z|0)==(va|0);c:do{if(ea){var W=ga}else{var ya=sa&J^1,L=ga,O=ua;o=O>>2;for(var qa=Z;;){var na=(L|0)==1?R(E,da)|512:L,L=na&7,na=na>>>3;k=z[M.f+L|0]&255;for(var U=0,P=y[t];;){var F=R(E,fa);y[t]=P+F|0;td(s,r);P=C[t];F=ud(u,P);y[(U<<2>>2)+d]=y[F>>2];U=U+1|0;if(U>>>0>=k>>>0){break}}U=(qa|0)==(ia|0)&ta;k=O>>2;P=T|U;d:do{if(P){for(F=0;;){var oa=F*e|0;f=oa>>2;var wa=O+oa|0,ca=(F|0)==0|ya,V=F<<1,ja=R(E,N);y[m]=y[m]+ja|0;td(w,p);if(U){if(ca){y[wa>>2]=y[((z[(L<<2)+vd+V|0]&255)<<2>>2)+d];V=ud(x,y[m]);y[f+(o+1)]=y[V>>2]}f=R(E,N);y[m]=y[m]+f|0;td(w,p)}else{if(ca){y[wa>>2]=y[((z[(L<<2)+vd+V|0]&255)<<2>>2)+d];wa=ud(x,y[m]);y[f+(o+1)]=y[wa>>2];oa=oa+(O+8)|0;wa=R(E,N);y[m]=y[m]+wa|0;td(w,p);y[oa>>2]=y[((z[(L<<2)+vd+(V|1)|0]&255)<<2>>2)+d];V=ud(x,y[m]);y[f+(o+3)]=y[V>>2]}else{f=R(E,N);y[m]=y[m]+f|0;td(w,p)}}F=F+1|0;if((F|0)==2){break d}}}else{y[k]=y[((z[(L<<2)+vd|0]&255)<<2>>2)+d];F=R(E,N);y[m]=y[m]+F|0;td(w,p);F=ud(x,y[m]);y[o+1]=y[F>>2];y[o+2]=y[((z[(L<<2)+vd+1|0]&255)<<2>>2)+d];F=R(E,N);y[m]=y[m]+F|0;td(w,p);F=ud(x,y[m]);y[o+3]=y[F>>2];y[(I<<2>>2)+k]=y[((z[(L<<2)+vd+2|0]&255)<<2>>2)+d];F=R(E,N);y[m]=y[m]+F|0;td(w,p);F=ud(x,y[m]);y[(ka<<2>>2)+k]=y[F>>2];y[(ba<<2>>2)+k]=y[((z[(L<<2)+vd+3|0]&255)<<2>>2)+d];F=R(E,N);y[m]=y[m]+F|0;td(w,p);F=ud(x,y[m]);y[(ra<<2>>2)+k]=y[F>>2]}}while(0);qa=qa+Ca|0;if((qa|0)==(va|0)){W=na;break c}L=na;O=O+Ba|0;o=O>>2}}}while(0);o=ma+1|0;if((o|0)==(i|0)){xa=W;break b}Y=Y+K|0;ma=o;ga=W}}}while(0);la=la+1|0;if((la|0)==(B|0)){break a}Aa=xa}}}while(0);q=s;return 1}fd.X=1;function qd(b){y[b>>2]=0;sd(b+284|0);sd(b+268|0);rd(b+252|0);rd(b+236|0);var c=b+188|0;Vc(b+212|0);Vc(c);c=b+140|0;Vc(b+164|0);Vc(c);Vc(b+116|0)}qd.X=1;function td(b,c){var d=y[b>>2],e=d-c|0,g=e>>31;y[b>>2]=g&d|e&(g^-1)}function gd(b,c,d,e,g,h,j,i){var f,k,o,m,t,s,w,u,r=q;q=q+48;u=r>>2;var x=r+4;w=x>>2;var p=r+8;s=p>>2;var B=r+12;t=B>>2;m=r+16>>2;var d=r+32>>2,I=b+236|0,S=y[I+4>>2],Q=b+252|0,H=y[Q+4>>2],J=b+268|0,K=y[J+4>>2],E=y[b+88>>2],da=Nc(E+63|0);y[u]=0;y[w]=0;y[s]=0;y[t]=0;var E=Pc(E+17|0),N=(E|0)==0;a:do{if(!N){for(var ka=(i|0)==0,ba=i-1|0,ra=(h&1|0)==0,ia=e<<1,fa=b+92|0,Ga=b+116|0,ta=b+212|0,la=b+188|0,Aa=b+284|0,xa=b+140|0,Y=b+164|0,ma=j-1|0,ga=ma<<5,ua=(g&1|0)!=0,Ba=0,Ca=1;;){b:do{if(ka){var va=Ca}else{for(var Z=y[c+(Ba<<2)>>2],sa=0,T=Ca;;){if((sa&1|0)==0){var ea=Z,W=32,ya=1,L=j,O=0}else{ea=Z+ga|0;W=-32;L=ya=-1;O=ma}var qa=ra|(sa|0)!=(ba|0),na=(O|0)==(L|0);c:do{if(na){var U=T}else{for(var P=T,F=ea,oa=O;;){var wa=(P|0)==1?R(fa,Ga)|512:P,P=wa&7,wa=wa>>>3;o=z[M.f+P|0]&255;for(var ca=0,V=y[s];;){var ja=R(fa,Y);y[s]=V+ja|0;td(p,K);V=C[s];ja=wd(J,V);y[(ca<<2>>2)+d]=A[ja>>1]&65535;ca=ca+1|0;if(ca>>>0>=o>>>0){break}}ca=0;for(V=y[u];;){ja=R(fa,xa);y[u]=V+ja|0;td(r,S);V=C[u];ja=ud(I,V);y[(ca<<2>>2)+m]=y[ja>>2];ca=ca+1|0;if(ca>>>0>=o>>>0){break}}ca=(oa|0)==(ma|0)&ua;V=F;o=V>>2;for(ja=0;;){var Oa=(ja|0)==0|qa;f=ja<<1;k=R(fa,ta);y[t]=y[t]+k|0;td(B,da);k=R(fa,la);y[w]=y[w]+k|0;td(x,H);if(Oa){var hb=V,Ha=z[(P<<2)+vd+f|0]&255;k=wd(Aa,y[t]*3|0)>>1;y[hb>>2]=(A[k]&65535)<<16|y[(Ha<<2>>2)+d];y[o+1]=(A[k+2]&65535)<<16|A[k+1]&65535;y[o+2]=y[(Ha<<2>>2)+m];k=ud(Q,y[w]);y[o+3]=y[k>>2]}k=R(fa,ta);y[t]=y[t]+k|0;td(B,da);k=R(fa,la);y[w]=y[w]+k|0;td(x,H);if(!(ca|Oa^1)){Oa=V+16|0;k=z[(P<<2)+vd+(f|1)|0]&255;f=wd(Aa,y[t]*3|0)>>1;y[Oa>>2]=(A[f]&65535)<<16|y[(k<<2>>2)+d];y[o+5]=(A[f+2]&65535)<<16|A[f+1]&65535;y[o+6]=y[(k<<2>>2)+m];f=ud(Q,y[w]);y[o+7]=y[f>>2]}ja=ja+1|0;if((ja|0)==2){break}V=V+e|0;o=V>>2}oa=oa+ya|0;if((oa|0)==(L|0)){U=wa;break c}P=wa;F=F+W|0}}}while(0);sa=sa+1|0;if((sa|0)==(i|0)){va=U;break b}Z=Z+ia|0;T=U}}}while(0);Ba=Ba+1|0;if((Ba|0)==(E|0)){break a}Ca=va}}}while(0);q=r;return 1}gd.X=1;function hd(b,c,d,e,g,h,j,i){var f,k,o,m,t,s=q;q=q+24;t=s>>2;var w=s+4;m=w>>2;var d=s+8>>2,u=b+268|0,r=y[u+4>>2],x=y[b+88>>2],p=Nc(x+63|0);y[t]=0;y[m]=0;var x=Pc(x+17|0),B=(x|0)==0;a:do{if(!B){for(var I=(i|0)==0,S=i-1|0,Q=(h&1|0)==0,H=e<<1,J=b+92|0,K=b+116|0,E=(g&1|0)==0,da=b+164|0,N=b+212|0,ka=b+284|0,ba=j-1|0,ra=ba<<4,ia=0,fa=1;;){b:do{if(I){var Ga=fa}else{for(var ta=y[c+(ia<<2)>>2],la=0,Aa=fa;;){if((la&1|0)==0){var xa=ta,Y=16,ma=1,ga=j,ua=0}else{xa=ta+ra|0;Y=-16;ga=ma=-1;ua=ba}var Ba=Q|(la|0)!=(S|0),Ca=(ua|0)==(ga|0);c:do{if(Ca){var va=Aa}else{for(var Z=Aa,sa=xa,T=ua;;){var ea=(Z|0)==1?R(J,K)|512:Z,Z=ea&7,ea=ea>>>3,W=z[M.f+Z|0]&255,ya=E|(T|0)!=(ba|0);f=0;for(k=y[t];;){var L=R(J,da);y[t]=k+L|0;td(s,r);k=C[t];L=wd(u,k);y[(f<<2>>2)+d]=A[L>>1]&65535;f=f+1|0;if(f>>>0>=W>>>0){var O=sa;o=O>>2;var qa=0;break}}for(;;){W=O;k=(qa|0)==0|Ba;f=qa<<1;L=R(J,N);y[m]=y[m]+L|0;td(w,p);if(ya){if(k){L=z[(Z<<2)+vd+f|0]&255;k=wd(ka,y[m]*3|0)>>1;y[W>>2]=(A[k]&65535)<<16|y[(L<<2>>2)+d];y[o+1]=(A[k+2]&65535)<<16|A[k+1]&65535;W=O+8|0;k=R(J,N);y[m]=y[m]+k|0;td(w,p);k=z[(Z<<2)+vd+(f|1)|0]&255;f=wd(ka,y[m]*3|0)>>1;y[W>>2]=(A[f]&65535)<<16|y[(k<<2>>2)+d];y[o+3]=(A[f+2]&65535)<<16|A[f+1]&65535}else{W=R(J,N);y[m]=y[m]+W|0;td(w,p)}}else{if(k){k=z[(Z<<2)+vd+f|0]&255;f=wd(ka,y[m]*3|0)>>1;y[W>>2]=(A[f]&65535)<<16|y[(k<<2>>2)+d];y[o+1]=(A[f+2]&65535)<<16|A[f+1]&65535}W=R(J,N);y[m]=y[m]+W|0;td(w,p)}W=qa+1|0;if((W|0)==2){break}O=O+e|0;o=O>>2;qa=W}T=T+ma|0;if((T|0)==(ga|0)){va=ea;break c}Z=ea;sa=sa+Y|0}}}while(0);la=la+1|0;if((la|0)==(i|0)){Ga=va;break b}ta=ta+H|0;Aa=va}}}while(0);ia=ia+1|0;if((ia|0)==(x|0)){break a}fa=Ga}}}while(0);q=s;return 1}hd.X=1;function id(b,c,d,e,g,h,j,i){var f,k,o,m,t,s,w,u,r,x=q;q=q+48;r=x>>2;var p=x+4;u=p>>2;var B=x+8;w=B>>2;var I=x+12;s=I>>2;t=x+16>>2;var d=x+32>>2,S=b+268|0,Q=y[S+4>>2],H=y[b+88>>2],J=Nc(H+63|0);y[r]=0;y[u]=0;y[w]=0;y[s]=0;var H=Pc(H+17|0),K=(H|0)==0;a:do{if(!K){for(var E=(i|0)==0,da=i-1|0,N=(h&1|0)==0,ka=e<<1,ba=b+92|0,ra=b+116|0,ia=b+212|0,fa=b+284|0,Ga=b+164|0,ta=j-1|0,la=ta<<5,Aa=(g&1|0)!=0,xa=0,Y=1;;){b:do{if(E){var ma=Y}else{for(var ga=y[c+(xa<<2)>>2],ua=0,Ba=Y;;){if((ua&1|0)==0){var Ca=ga,va=32,Z=1,sa=j,T=0}else{Ca=ga+la|0;va=-32;sa=Z=-1;T=ta}var ea=N|(ua|0)!=(da|0),W=(T|0)==(sa|0);c:do{if(W){var ya=Ba}else{for(var L=Ba,O=Ca,qa=T;;){var na=(L|0)==1?R(ba,ra)|512:L,L=na&7,na=na>>>3;m=z[M.f+L|0]&255;for(var U=0,P=y[r];;){var F=R(ba,Ga);y[r]=P+F|0;td(x,Q);P=C[r];F=wd(S,P);y[(U<<2>>2)+t]=A[F>>1]&65535;U=U+1|0;if(U>>>0>=m>>>0){break}}U=0;for(P=y[w];;){F=R(ba,Ga);y[w]=P+F|0;td(B,Q);P=C[w];F=wd(S,P);y[(U<<2>>2)+d]=A[F>>1]&65535;U=U+1|0;if(U>>>0>=m>>>0){break}}U=(qa|0)==(ta|0)&Aa;P=O;m=P>>2;for(F=0;;){var oa=(F|0)==0|ea;f=F<<1;k=R(ba,ia);y[u]=y[u]+k|0;td(p,J);k=R(ba,ia);y[s]=y[s]+k|0;td(I,J);if(oa){var wa=P,ca=z[(L<<2)+vd+f|0]&255;o=wd(fa,y[u]*3|0)>>1;k=wd(fa,y[s]*3|0)>>1;y[wa>>2]=(A[o]&65535)<<16|y[(ca<<2>>2)+t];y[m+1]=(A[o+2]&65535)<<16|A[o+1]&65535;y[m+2]=(A[k]&65535)<<16|y[(ca<<2>>2)+d];y[m+3]=(A[k+2]&65535)<<16|A[k+1]&65535}k=R(ba,ia);y[u]=y[u]+k|0;td(p,J);k=R(ba,ia);y[s]=y[s]+k|0;td(I,J);if(!(U|oa^1)){oa=P+16|0;o=z[(L<<2)+vd+(f|1)|0]&255;k=wd(fa,y[u]*3|0)>>1;f=wd(fa,y[s]*3|0)>>1;y[oa>>2]=(A[k]&65535)<<16|y[(o<<2>>2)+t];y[m+5]=(A[k+2]&65535)<<16|A[k+1]&65535;y[m+6]=(A[f]&65535)<<16|y[(o<<2>>2)+d];y[m+7]=(A[f+2]&65535)<<16|A[f+1]&65535}F=F+1|0;if((F|0)==2){break}P=P+e|0;m=P>>2}qa=qa+Z|0;if((qa|0)==(sa|0)){ya=na;break c}L=na;O=O+va|0}}}while(0);ua=ua+1|0;if((ua|0)==(i|0)){ma=ya;break b}ga=ga+ka|0;Ba=ya}}}while(0);xa=xa+1|0;if((xa|0)==(H|0)){break a}Y=ma}}}while(0);q=x;return 1}id.X=1;function wd(b,c){C[b+4>>2]>>>0>c>>>0||xc(M.g|0,904);return(c<<1)+y[b>>2]|0}function ud(b,c){C[b+4>>2]>>>0>c>>>0||xc(M.g|0,904);return(c<<2)+y[b>>2]|0}function xd(b,c){var d;d=(b+4|0)>>2;var e=C[d],g=(e|0)==(c|0);do{if(g){var h=1}else{if(e>>>0<=c>>>0){if(C[b+8>>2]>>>0<c>>>0){h=b;if(Fc(h,c,(e+1|0)==(c|0),2,0)){h=1}else{v[h+12|0]=1;h=0}if(!h){h=0;break}h=y[d]}else{h=e}bc((h<<1)+y[b>>2]|0,0,(c-h|0)<<1)}y[d]=c;h=1}}while(0);return h}function yd(b,c){var d;d=(b+4|0)>>2;var e=C[d],g=(e|0)==(c|0);do{if(g){var h=1}else{if(e>>>0<=c>>>0){if(C[b+8>>2]>>>0<c>>>0){h=b;if(Fc(h,c,(e+1|0)==(c|0),4,0)){h=1}else{v[h+12|0]=1;h=0}if(!h){h=0;break}h=y[d]}else{h=e}bc((h<<2)+y[b>>2]|0,0,(c-h|0)<<2)}y[d]=c;h=1}}while(0);return h}function md(b){var c=q;q=q+48;var d,e=b+88|0,g=Nc(y[e>>2]+39|0),h=b+236|0,j=yd(h,g);do{if(j){var i=b+92|0,f=y[e>>2];if(cd(i,y[b+4>>2]+Qc(f+33|0)|0,Qc(f+36|0))){f=c|0;Uc(f);var k=c+24|0;Uc(k);for(var o=0;;){if(o>>>0>=2){d=9;break}if(!dd(i,c+o*24|0)){var m=0;d=11;break}o=o+1|0}a:do{if(d==9){var t=ud(h,0);if((g|0)==0){m=1}else{for(var s=o=0,w=0,u=0,r=0,x=0,p=0;;){var x=R(i,f)+x&31,r=R(i,k)+r&63,u=R(i,f)+u&31,B=R(i,f)+w|0,w=B&31,s=R(i,k)+s&63,o=R(i,f)+o&31;y[t>>2]=r<<5|x<<11|u|B<<27|s<<21|o<<16;p=p+1|0;if((p|0)==(g|0)){m=1;break a}t=t+4|0}}}}while(0);Vc(k);Vc(f);i=m}else{i=0}}else{i=0}}while(0);q=c;return i}md.X=1;function nd(b){var c=q;q=q+480;var d=c+24,e=c+220,g=c+416,h=y[b+88>>2],j=Nc(h+47|0),i=b+92|0;if(cd(i,y[b+4>>2]+Qc(h+41|0)|0,Qc(h+44|0))){Uc(c);h=dd(i,c);a:do{if(h){for(var f=-3,k=-3,o=0;;){y[d+(o<<2)>>2]=f;y[e+(o<<2)>>2]=k;var f=f+1|0,m=(f|0)>3,k=(m&1)+k|0,o=o+1|0;if((o|0)==49){break}f=m?-3:f}bc(g,0,64);k=b+252|0;if(yd(k,j)){var t=ud(k,0);if((j|0)==0){ba=1}else{for(var k=g|0,o=g+4|0,f=g+8|0,m=g+12|0,s=g+16|0,w=g+20|0,u=g+24|0,r=g+28|0,x=g+32|0,p=g+36|0,B=g+40|0,I=g+44|0,S=g+48|0,Q=g+52|0,H=g+56|0,J=g+60|0,K=0;;){for(var E=0;;){var da=R(i,c),N=E<<1,ka=(N<<2)+g|0;y[ka>>2]=y[ka>>2]+y[d+(da<<2)>>2]&3;N=((N|1)<<2)+g|0;y[N>>2]=y[N>>2]+y[e+(da<<2)>>2]&3;E=E+1|0;if((E|0)==8){break}}y[t>>2]=(z[M.b+y[o>>2]|0]&255)<<2|z[M.b+y[k>>2]|0]&255|(z[M.b+y[f>>2]|0]&255)<<4|(z[M.b+y[m>>2]|0]&255)<<6|(z[M.b+y[s>>2]|0]&255)<<8|(z[M.b+y[w>>2]|0]&255)<<10|(z[M.b+y[u>>2]|0]&255)<<12|(z[M.b+y[r>>2]|0]&255)<<14|(z[M.b+y[x>>2]|0]&255)<<16|(z[M.b+y[p>>2]|0]&255)<<18|(z[M.b+y[B>>2]|0]&255)<<20|(z[M.b+y[I>>2]|0]&255)<<22|(z[M.b+y[S>>2]|0]&255)<<24|(z[M.b+y[Q>>2]|0]&255)<<26|(z[M.b+y[H>>2]|0]&255)<<28|(z[M.b+y[J>>2]|0]&255)<<30;K=K+1|0;if((K|0)==(j|0)){ba=1;break a}t=t+4|0}}}else{var ba=0}}else{ba=0}}while(0);Vc(c);b=ba}else{b=0}q=c;return b}nd.X=1;function od(b){var c=q;q=q+24;var d=y[b+88>>2],e=Nc(d+55|0),g=b+92|0;if(cd(g,y[b+4>>2]+Qc(d+49|0)|0,Qc(d+52|0))){Uc(c);d=dd(g,c);a:do{if(d){var h=b+268|0;if(xd(h,e)){h=wd(h,0);if((e|0)==0){m=1}else{for(var j=0,i=0,f=0;;){var k=R(g,c),o=R(g,c),j=k+j&255,i=o+i&255;gb[h>>1]=(i<<8|j)&65535;f=f+1|0;if((f|0)==(e|0)){m=1;break a}h=h+2|0}}}else{var m=0}}else{m=0}}while(0);Vc(c);b=m}else{b=0}q=c;return b}od.X=1;function pd(b){var c,d=q;q=q+1888;var e=d+24,g=d+924,h=d+1824,j=y[b+88>>2],i=Nc(j+63|0),f=b+92|0;if(cd(f,y[b+4>>2]+Qc(j+57|0)|0,Qc(j+60|0))){Uc(d);j=dd(f,d);a:do{if(j){for(var k=-7,o=-7,m=0;;){y[e+(m<<2)>>2]=k;y[g+(m<<2)>>2]=o;var k=k+1|0,t=(k|0)>7,o=(t&1)+o|0,m=m+1|0;if((m|0)==225){break}k=t?-7:k}bc(h,0,64);o=b+284|0;if(xd(o,i*3|0)){c=wd(o,0);if((i|0)==0){ra=1}else{var o=h|0,m=h+4|0,k=h+8|0,t=h+12|0,s=h+16|0,w=h+20|0,u=h+24|0,r=h+28|0,x=h+32|0,p=h+36|0,B=h+40|0,I=h+44|0,S=h+48|0,Q=h+52|0,H=h+56|0,J=h+60|0,K=c;c=K>>1;for(var E=0;;){for(var da=0;;){var N=R(f,d),ka=da<<1,ba=(ka<<2)+h|0;y[ba>>2]=y[ba>>2]+y[e+(N<<2)>>2]&7;ka=((ka|1)<<2)+h|0;y[ka>>2]=y[ka>>2]+y[g+(N<<2)>>2]&7;da=da+1|0;if((da|0)==8){break}}gb[c]=(z[M.a+y[m>>2]|0]&255)<<3|z[M.a+y[o>>2]|0]&255|(z[M.a+y[k>>2]|0]&255)<<6|(z[M.a+y[t>>2]|0]&255)<<9|(z[M.a+y[s>>2]|0]&255)<<12|(z[M.a+y[w>>2]|0]&255)<<15;gb[c+1]=(z[M.a+y[u>>2]|0]&255)<<2|(z[M.a+y[w>>2]|0]&255)>>>1|(z[M.a+y[r>>2]|0]&255)<<5|(z[M.a+y[x>>2]|0]&255)<<8|(z[M.a+y[p>>2]|0]&255)<<11|(z[M.a+y[B>>2]|0]&255)<<14;gb[c+2]=(z[M.a+y[I>>2]|0]&255)<<1|(z[M.a+y[B>>2]|0]&255)>>>2|(z[M.a+y[S>>2]|0]&255)<<4|(z[M.a+y[Q>>2]|0]&255)<<7|(z[M.a+y[H>>2]|0]&255)<<10|(z[M.a+y[J>>2]|0]&255)<<13;E=E+1|0;if((E|0)==(i|0)){ra=1;break a}K=K+6|0;c=K>>1}}}else{var ra=0}}else{ra=0}}while(0);Vc(d);b=ra}else{b=0}q=d;return b}pd.X=1;function ac(b){if(b>>>0<245){var c=b>>>0<11?16:b+11&-8,d=c>>>3,b=C[X>>2],e=b>>>(d>>>0);if((e&3|0)!=0){var g=(e&1^1)+d|0,c=g<<1,d=(c<<2)+X+40|0,h=(c+2<<2)+X+40|0,e=C[h>>2],c=e+8|0,j=C[c>>2];if((d|0)==(j|0)){y[X>>2]=b&(1<<g^-1)}else{if(j>>>0<C[X+16>>2]>>>0){$();a("Reached an unreachable!")}y[h>>2]=j;y[j+12>>2]=d}b=g<<3;y[e+4>>2]=b|3;b=e+(b|4)|0;y[b>>2]=y[b>>2]|1;g=c;b=38}else{if(c>>>0>C[X+8>>2]>>>0){if((e|0)!=0){var g=2<<d,g=e<<d&(g|-g),d=(g&-g)-1|0,g=d>>>12&16,e=d>>>(g>>>0),d=e>>>5&8,h=e>>>(d>>>0),e=h>>>2&4,j=h>>>(e>>>0),h=j>>>1&2,j=j>>>(h>>>0),i=j>>>1&1,d=(d|g|e|h|i)+(j>>>(i>>>0))|0,g=d<<1,h=(g<<2)+X+40|0,j=(g+2<<2)+X+40|0,e=C[j>>2],g=e+8|0,i=C[g>>2];if((h|0)==(i|0)){y[X>>2]=b&(1<<d^-1)}else{if(i>>>0<C[X+16>>2]>>>0){$();a("Reached an unreachable!")}y[j>>2]=i;y[i+12>>2]=h}h=d<<3;b=h-c|0;y[e+4>>2]=c|3;d=e+c|0;y[e+(c|4)>>2]=b|1;y[e+h>>2]=b;i=C[X+8>>2];if((i|0)!=0){c=y[X+20>>2];h=i>>>2&1073741822;e=(h<<2)+X+40|0;j=C[X>>2];i=1<<(i>>>3);if((j&i|0)==0){y[X>>2]=j|i;j=e;h=(h+2<<2)+X+40|0}else{h=(h+2<<2)+X+40|0;j=C[h>>2];if(j>>>0<C[X+16>>2]>>>0){$();a("Reached an unreachable!")}}y[h>>2]=c;y[j+12>>2]=c;y[(c+8|0)>>2]=j;y[(c+12|0)>>2]=e}y[X+8>>2]=b;y[X+20>>2]=d;b=38}else{if((y[X+4>>2]|0)==0){f=c;b=30}else{b=zd(c);if((b|0)==0){f=c;b=30}else{g=b;b=38}}}}else{var f=c,b=30}}}else{if(b>>>0>4294967231){f=-1;b=30}else{b=b+11&-8;if((y[X+4>>2]|0)==0){f=b;b=30}else{c=Ad(b);if((c|0)==0){f=b;b=30}else{g=c;b=38}}}}if(b==30){c=C[X+8>>2];if(f>>>0>c>>>0){b=C[X+12>>2];if(f>>>0<b>>>0){b=b-f|0;y[X+12>>2]=b;c=C[X+24>>2];y[X+24>>2]=c+f|0;y[f+(c+4)>>2]=b|1;y[c+4>>2]=f|3;g=c+8|0}else{g=Bd(f)}}else{g=c-f|0;b=C[X+20>>2];if(g>>>0>15){y[X+20>>2]=b+f|0;y[X+8>>2]=g;y[f+(b+4)>>2]=g|1;y[b+c>>2]=g;y[b+4>>2]=f|3}else{y[X+8>>2]=0;y[X+20>>2]=0;y[b+4>>2]=c|3;f=c+(b+4)|0;y[f>>2]=y[f>>2]|1}g=b+8|0}}return g}Module._malloc=ac;ac.X=1;function zd(b){var c,d,e=y[X+4>>2],g=(e&-e)-1|0,e=g>>>12&16,h=g>>>(e>>>0),g=h>>>5&8;d=h>>>(g>>>0);var h=d>>>2&4,j=d>>>(h>>>0);d=j>>>1&2;var j=j>>>(d>>>0),i=j>>>1&1,e=g=C[X+((g|e|h|d|i)+(j>>>(i>>>0))<<2)+304>>2];d=e>>2;g=(y[g+4>>2]&-8)-b|0;a:for(;;){for(h=e;;){j=y[h+16>>2];if((j|0)==0){h=y[h+20>>2];if((h|0)==0){break a}}else{h=j}j=(y[h+4>>2]&-8)-b|0;if(j>>>0<g>>>0){e=h;d=e>>2;g=j;continue a}}}var j=e,f=C[X+16>>2],i=j>>>0<f>>>0;do{if(!i){var k=j+b|0,h=k;if(j>>>0<k>>>0){var i=C[d+6],k=C[d+3],o=(k|0)==(e|0);do{if(o){c=e+20|0;var m=y[c>>2];if((m|0)==0){c=e+16|0;m=y[c>>2];if((m|0)==0){m=0;c=m>>2;break}}for(;;){var t=m+20|0,s=y[t>>2];if((s|0)==0){t=m+16|0;s=C[t>>2];if((s|0)==0){break}}c=t;m=s}if(c>>>0<f>>>0){$();a("Reached an unreachable!")}y[c>>2]=0}else{c=C[d+2];if(c>>>0<f>>>0){$();a("Reached an unreachable!")}y[c+12>>2]=k;y[k+8>>2]=c;m=k}c=m>>2}while(0);f=(i|0)==0;a:do{if(!f){k=e+28|0;o=(y[k>>2]<<2)+X+304|0;t=(e|0)==(y[o>>2]|0);do{if(t){y[o>>2]=m;if((m|0)!=0){break}y[X+4>>2]=y[X+4>>2]&(1<<y[k>>2]^-1);break a}if(i>>>0<C[X+16>>2]>>>0){$();a("Reached an unreachable!")}s=i+16|0;(y[s>>2]|0)==(e|0)?y[s>>2]=m:y[i+20>>2]=m;if((m|0)==0){break a}}while(0);if(m>>>0<C[X+16>>2]>>>0){$();a("Reached an unreachable!")}y[c+6]=i;k=C[d+4];if((k|0)!=0){if(k>>>0<C[X+16>>2]>>>0){$();a("Reached an unreachable!")}y[c+4]=k;y[k+24>>2]=m}k=C[d+5];if((k|0)!=0){if(k>>>0<C[X+16>>2]>>>0){$();a("Reached an unreachable!")}y[c+5]=k;y[k+24>>2]=m}}}while(0);if(g>>>0<16){b=g+b|0;y[d+1]=b|3;b=b+(j+4)|0;y[b>>2]=y[b>>2]|1}else{y[d+1]=b|3;y[b+(j+4)>>2]=g|1;y[j+g+b>>2]=g;f=C[X+8>>2];if((f|0)!=0){b=C[X+20>>2];j=f>>>2&1073741822;d=(j<<2)+X+40|0;i=C[X>>2];f=1<<(f>>>3);if((i&f|0)==0){y[X>>2]=i|f;i=d;j=(j+2<<2)+X+40|0}else{j=(j+2<<2)+X+40|0;i=C[j>>2];if(i>>>0<C[X+16>>2]>>>0){$();a("Reached an unreachable!")}}y[j>>2]=b;y[i+12>>2]=b;y[b+8>>2]=i;y[b+12>>2]=d}y[X+8>>2]=g;y[X+20>>2]=h}return e+8|0}}}while(0);$();a("Reached an unreachable!")}zd.X=1;function Bd(b){var c,d;(y[Cd>>2]|0)==0&&Dd();var e=(y[X+440>>2]&4|0)==0;do{if(e){d=y[X+24>>2];if((d|0)==0){d=6}else{d=Ed(d);if((d|0)==0){d=6}else{var g=y[Cd+8>>2],g=b+47-y[X+12>>2]+g&-g;if(g>>>0<2147483647){var h=Fd(g);if((h|0)==(y[d>>2]+y[d+4>>2]|0)){var j=h,i=g;c=h;d=13}else{var f=h,k=g;d=15}}else{d=14}}}if(d==6){d=Fd(0);if((d|0)==-1){d=14}else{var g=y[Cd+8>>2],g=g+(b+47)&-g,h=d,o=y[Cd+4>>2],m=o-1|0,g=(m&h|0)==0?g:g-h+(m+h&-o)|0;if(g>>>0<2147483647){h=Fd(g);if((h|0)==(d|0)){j=d;i=g;c=h;d=13}else{f=h;k=g;d=15}}else{d=14}}}if(d==13){if((j|0)!=-1){var t=i,s=j;d=26;break}f=c;k=i}else{if(d==14){y[X+440>>2]=y[X+440>>2]|4;d=23;break}}d=-k|0;if((f|0)!=-1&k>>>0<2147483647){if(k>>>0<(b+48|0)>>>0){g=y[Cd+8>>2];g=b+47-k+g&-g;if(g>>>0<2147483647){if((Fd(g)|0)==-1){Fd(d);d=22}else{w=g+k|0;d=21}}else{w=k;d=21}}else{var w=k;d=21}}else{w=k;d=21}if(d==21&&(f|0)!=-1){t=w;s=f;d=26;break}y[X+440>>2]=y[X+440>>2]|4}d=23}while(0);if(d==23){e=y[Cd+8>>2];e=e+(b+47)&-e;if(e>>>0<2147483647){e=Fd(e);j=Fd(0);if((j|0)!=-1&(e|0)!=-1&e>>>0<j>>>0){j=j-e|0;if(j>>>0<=(b+40|0)>>>0|(e|0)==-1){d=49}else{t=j;s=e;d=26}}else{d=49}}else{d=49}}a:do{if(d==26){e=y[X+432>>2]+t|0;y[X+432>>2]=e;e>>>0>C[X+436>>2]>>>0&&(y[X+436>>2]=e);e=C[X+24>>2];j=(e|0)==0;b:do{if(j){i=C[X+16>>2];(i|0)==0|s>>>0<i>>>0&&(y[X+16>>2]=s);y[X+444>>2]=s;y[X+448>>2]=t;y[X+456>>2]=0;y[X+36>>2]=y[Cd>>2];y[X+32>>2]=-1;for(i=0;;){c=i<<1;f=(c<<2)+X+40|0;y[X+(c+3<<2)+40>>2]=f;y[X+(c+2<<2)+40>>2]=f;i=i+1|0;if((i|0)==32){break}}Gd(s,t-40|0)}else{f=X+444|0;for(c=f>>2;;){if((f|0)==0){break}i=C[c];f=f+4|0;k=C[f>>2];w=i+k|0;if((s|0)==(w|0)){if((y[c+3]&8|0)!=0){break}c=e;if(!(c>>>0>=i>>>0&c>>>0<w>>>0)){break}y[f>>2]=k+t|0;Gd(y[X+24>>2],y[X+12>>2]+t|0);break b}f=y[c+2];c=f>>2}s>>>0<C[X+16>>2]>>>0&&(y[X+16>>2]=s);c=s+t|0;for(f=X+444|0;;){if((f|0)==0){break}k=f|0;i=C[k>>2];if((i|0)==(c|0)){if((y[f+12>>2]&8|0)!=0){break}y[k>>2]=s;var u=f+4|0;y[u>>2]=y[u>>2]+t|0;u=Hd(s,i,b);d=50;break a}f=y[f+8>>2]}Id(s,t)}}while(0);e=C[X+12>>2];if(e>>>0>b>>>0){u=e-b|0;y[X+12>>2]=u;j=e=C[X+24>>2];y[X+24>>2]=j+b|0;y[b+(j+4)>>2]=u|1;y[e+4>>2]=b|3;u=e+8|0;d=50}else{d=49}}}while(0);if(d==49){y[Jd>>2]=12;u=0}return u}Bd.X=1;function Ad(b){var c,d,e,g,h,j=b>>2,i=-b|0,f=b>>>8;if((f|0)==0){var k=0}else{if(b>>>0>16777215){k=31}else{var o=(f+1048320|0)>>>16&8,m=f<<o,t=(m+520192|0)>>>16&4,s=m<<t,w=(s+245760|0)>>>16&2,u=14-(t|o|w)+(s<<w>>>15)|0,k=b>>>((u+7|0)>>>0)&1|u<<1}}var r=C[X+(k<<2)+304>>2],x=(r|0)==0;a:do{if(x){var p=0,B=i,I=0}else{var S=(k|0)==31?0:25-(k>>>1)|0,Q=0,H=i,J=r;h=J>>2;for(var K=b<<S,E=0;;){var da=y[h+1]&-8,N=da-b|0;if(N>>>0<H>>>0){if((da|0)==(b|0)){p=J;B=N;I=J;break a}var ka=J,ba=N}else{ka=Q;ba=H}var ra=C[h+5],ia=C[((K>>>31<<2)+16>>2)+h],fa=(ra|0)==0|(ra|0)==(ia|0)?E:ra;if((ia|0)==0){p=ka;B=ba;I=fa;break a}Q=ka;H=ba;J=ia;h=J>>2;K=K<<1;E=fa}}}while(0);if((I|0)==0&(p|0)==0){var Ga=2<<k,ta=y[X+4>>2]&(Ga|-Ga);if((ta|0)==0){var la=I}else{var Aa=(ta&-ta)-1|0,xa=Aa>>>12&16,Y=Aa>>>(xa>>>0),ma=Y>>>5&8,ga=Y>>>(ma>>>0),ua=ga>>>2&4,Ba=ga>>>(ua>>>0),Ca=Ba>>>1&2,va=Ba>>>(Ca>>>0),Z=va>>>1&1,la=y[X+((ma|xa|ua|Ca|Z)+(va>>>(Z>>>0))<<2)+304>>2]}}else{la=I}var sa=(la|0)==0;a:do{if(sa){var T=B,ea=p;g=ea>>2}else{var W=la;e=W>>2;for(var ya=B,L=p;;){var O=(y[e+1]&-8)-b|0,qa=O>>>0<ya>>>0,na=qa?O:ya,U=qa?W:L,P=C[e+4];if((P|0)!=0){W=P}else{var F=C[e+5];if((F|0)==0){T=na;ea=U;g=ea>>2;break a}W=F}e=W>>2;ya=na;L=U}}}while(0);var oa=(ea|0)==0;a:do{if(oa){var wa=0}else{if(T>>>0<(y[X+8>>2]-b|0)>>>0){var ca=ea;d=ca>>2;var V=C[X+16>>2],ja=ca>>>0<V>>>0;do{if(!ja){var Oa=ca+b|0,hb=Oa;if(ca>>>0<Oa>>>0){var Ha=C[g+6],Ra=C[g+3],Za=(Ra|0)==(ea|0);do{if(Za){var Ob=ea+20|0,xb=y[Ob>>2];if((xb|0)==0){var Pb=ea+16|0,yb=y[Pb>>2];if((yb|0)==0){var ha=0;c=ha>>2;break}var Ka=Pb,La=yb}else{Ka=Ob;La=xb}for(;;){var ib=La+20|0,zb=y[ib>>2];if((zb|0)!=0){Ka=ib;La=zb}else{var Qb=La+16|0,Rb=C[Qb>>2];if((Rb|0)==0){break}Ka=Qb;La=Rb}}if(Ka>>>0<V>>>0){$();a("Reached an unreachable!")}y[Ka>>2]=0;ha=La}else{var $a=C[g+2];if($a>>>0<V>>>0){$();a("Reached an unreachable!")}y[$a+12>>2]=Ra;y[Ra+8>>2]=$a;ha=Ra}c=ha>>2}while(0);var Sb=(Ha|0)==0;b:do{if(!Sb){var Tb=ea+28|0,cc=(y[Tb>>2]<<2)+X+304|0,Ab=(ea|0)==(y[cc>>2]|0);do{if(Ab){y[cc>>2]=ha;if((ha|0)!=0){break}y[X+4>>2]=y[X+4>>2]&(1<<y[Tb>>2]^-1);break b}if(Ha>>>0<C[X+16>>2]>>>0){$();a("Reached an unreachable!")}var bb=Ha+16|0;(y[bb>>2]|0)==(ea|0)?y[bb>>2]=ha:y[Ha+20>>2]=ha;if((ha|0)==0){break b}}while(0);if(ha>>>0<C[X+16>>2]>>>0){$();a("Reached an unreachable!")}y[c+6]=Ha;var ab=C[g+4];if((ab|0)!=0){if(ab>>>0<C[X+16>>2]>>>0){$();a("Reached an unreachable!")}y[c+4]=ab;y[ab+24>>2]=ha}var Ia=C[g+5];if((Ia|0)!=0){if(Ia>>>0<C[X+16>>2]>>>0){$();a("Reached an unreachable!")}y[c+5]=Ia;y[Ia+24>>2]=ha}}}while(0);var Bb=T>>>0<16;b:do{if(Bb){var Cb=T+b|0;y[g+1]=Cb|3;var Db=Cb+(ca+4)|0;y[Db>>2]=y[Db>>2]|1}else{y[g+1]=b|3;y[j+(d+1)]=T|1;y[(T>>2)+d+j]=T;if(T>>>0<256){var ob=T>>>2&1073741822,pb=(ob<<2)+X+40|0,Eb=C[X>>2],Fb=1<<(T>>>3);if((Eb&Fb|0)==0){y[X>>2]=Eb|Fb;var qb=pb,jb=(ob+2<<2)+X+40|0}else{var rb=(ob+2<<2)+X+40|0,Sa=C[rb>>2];if(Sa>>>0<C[X+16>>2]>>>0){$();a("Reached an unreachable!")}qb=Sa;jb=rb}y[jb>>2]=hb;y[qb+12>>2]=hb;y[j+(d+2)]=qb;y[j+(d+3)]=pb}else{var Pa=Oa,sb=T>>>8;if((sb|0)==0){var Ta=0}else{if(T>>>0>16777215){Ta=31}else{var Gb=(sb+1048320|0)>>>16&8,Hb=sb<<Gb,Ib=(Hb+520192|0)>>>16&4,tb=Hb<<Ib,Jb=(tb+245760|0)>>>16&2,Kb=14-(Ib|Gb|Jb)+(tb<<Jb>>>15)|0,Ta=T>>>((Kb+7|0)>>>0)&1|Kb<<1}}var Lb=(Ta<<2)+X+304|0;y[j+(d+7)]=Ta;var kb=b+(ca+16)|0;y[j+(d+5)]=0;y[kb>>2]=0;var Ua=y[X+4>>2],Ub=1<<Ta;if((Ua&Ub|0)==0){y[X+4>>2]=Ua|Ub;y[Lb>>2]=Pa;y[j+(d+6)]=Lb;y[j+(d+3)]=Pa;y[j+(d+2)]=Pa}else{for(var Va=T<<((Ta|0)==31?0:25-(Ta>>>1)|0),nb=y[Lb>>2];;){if((y[nb+4>>2]&-8|0)==(T|0)){var Ac=nb+8|0,Xb=C[Ac>>2],oc=C[X+16>>2],Bc=nb>>>0<oc>>>0;do{if(!Bc&&Xb>>>0>=oc>>>0){y[Xb+12>>2]=Pa;y[Ac>>2]=Pa;y[j+(d+2)]=Xb;y[j+(d+3)]=nb;y[j+(d+6)]=0;break b}}while(0);$();a("Reached an unreachable!")}var gc=(Va>>>31<<2)+nb+16|0,Cc=C[gc>>2];if((Cc|0)==0){if(gc>>>0>=C[X+16>>2]>>>0){y[gc>>2]=Pa;y[j+(d+6)]=nb;y[j+(d+3)]=Pa;y[j+(d+2)]=Pa;break b}$();a("Reached an unreachable!")}Va=Va<<1;nb=Cc}}}}}while(0);wa=ea+8|0;break a}}}while(0);$();a("Reached an unreachable!")}wa=0}}while(0);return wa}Ad.X=1;function Kd(b){var c;(y[Cd>>2]|0)==0&&Dd();var d=b>>>0<4294967232;a:do{if(d){var e=C[X+24>>2];if((e|0)!=0){var g=C[X+12>>2],h=g>>>0>(b+40|0)>>>0;do{if(h){var j=C[Cd+8>>2],i=(Math.floor(((-40-b-1+g+j|0)>>>0)/(j>>>0))-1)*j|0,f=Ed(e);if((y[f+12>>2]&8|0)==0){var k=Fd(0);c=(f+4|0)>>2;if((k|0)==(y[f>>2]+y[c]|0)){i=Fd(-(i>>>0>2147483646?-2147483648-j|0:i)|0);j=Fd(0);if((i|0)!=-1&j>>>0<k>>>0){i=k-j|0;if((k|0)!=(j|0)){y[c]=y[c]-i|0;y[X+432>>2]=y[X+432>>2]-i|0;Gd(y[X+24>>2],y[X+12>>2]-i|0);c=(k|0)!=(j|0);break a}}}}}}while(0);C[X+12>>2]>>>0>C[X+28>>2]>>>0&&(y[X+28>>2]=-1)}}c=0}while(0);return c&1}Kd.X=1;function Ld(b){var c,d,e,g,h,j,i=b>>2,f,k=(b|0)==0;a:do{if(!k){var o=b-8|0,m=o,t=C[X+16>>2],s=o>>>0<t>>>0;b:do{if(!s){var w=C[b-4>>2],u=w&3;if((u|0)!=1){var r=w&-8;j=r>>2;var x=b+(r-8)|0,p=x,B=(w&1|0)==0;c:do{if(B){var I=C[o>>2];if((u|0)==0){break a}var S=-8-I|0;h=S>>2;var Q=b+S|0,H=Q,J=I+r|0;if(Q>>>0<t>>>0){break b}if((H|0)==(y[X+20>>2]|0)){g=(b+(r-4)|0)>>2;if((y[g]&3|0)!=3){var K=H;e=K>>2;var E=J;break}y[X+8>>2]=J;y[g]=y[g]&-2;y[h+(i+1)]=J|1;y[x>>2]=J;break a}if(I>>>0<256){var da=C[h+(i+2)],N=C[h+(i+3)];if((da|0)==(N|0)){y[X>>2]=y[X>>2]&(1<<(I>>>3)^-1);K=H;e=K>>2;E=J}else{var ka=((I>>>2&1073741822)<<2)+X+40|0,ba=(da|0)!=(ka|0)&da>>>0<t>>>0;do{if(!ba&&(N|0)==(ka|0)|N>>>0>=t>>>0){y[da+12>>2]=N;y[N+8>>2]=da;K=H;e=K>>2;E=J;break c}}while(0);$();a("Reached an unreachable!")}}else{var ra=Q,ia=C[h+(i+6)],fa=C[h+(i+3)],Ga=(fa|0)==(ra|0);do{if(Ga){var ta=S+(b+20)|0,la=y[ta>>2];if((la|0)==0){var Aa=S+(b+16)|0,xa=y[Aa>>2];if((xa|0)==0){var Y=0;d=Y>>2;break}var ma=Aa,ga=xa}else{ma=ta;ga=la;f=21}for(;;){var ua=ga+20|0,Ba=y[ua>>2];if((Ba|0)!=0){ma=ua;ga=Ba}else{var Ca=ga+16|0,va=C[Ca>>2];if((va|0)==0){break}ma=Ca;ga=va}}if(ma>>>0<t>>>0){$();a("Reached an unreachable!")}y[ma>>2]=0;Y=ga}else{var Z=C[h+(i+2)];if(Z>>>0<t>>>0){$();a("Reached an unreachable!")}y[Z+12>>2]=fa;y[fa+8>>2]=Z;Y=fa}d=Y>>2}while(0);if((ia|0)!=0){var sa=S+(b+28)|0,T=(y[sa>>2]<<2)+X+304|0,ea=(ra|0)==(y[T>>2]|0);do{if(ea){y[T>>2]=Y;if((Y|0)!=0){break}y[X+4>>2]=y[X+4>>2]&(1<<y[sa>>2]^-1);K=H;e=K>>2;E=J;break c}if(ia>>>0<C[X+16>>2]>>>0){$();a("Reached an unreachable!")}var W=ia+16|0;(y[W>>2]|0)==(ra|0)?y[W>>2]=Y:y[ia+20>>2]=Y;if((Y|0)==0){K=H;e=K>>2;E=J;break c}}while(0);if(Y>>>0<C[X+16>>2]>>>0){$();a("Reached an unreachable!")}y[d+6]=ia;var ya=C[h+(i+4)];if((ya|0)!=0){if(ya>>>0<C[X+16>>2]>>>0){$();a("Reached an unreachable!")}y[d+4]=ya;y[ya+24>>2]=Y}var L=C[h+(i+5)];if((L|0)!=0){if(L>>>0<C[X+16>>2]>>>0){$();a("Reached an unreachable!")}y[d+5]=L;y[L+24>>2]=Y}}K=H;e=K>>2;E=J}}else{K=m;e=K>>2;E=r}}while(0);var O=K;if(O>>>0<x>>>0){var qa=b+(r-4)|0,na=C[qa>>2];if((na&1|0)!=0){var U=(na&2|0)==0;do{if(U){if((p|0)==(y[X+24>>2]|0)){var P=y[X+12>>2]+E|0;y[X+12>>2]=P;y[X+24>>2]=K;y[e+1]=P|1;if((K|0)==(y[X+20>>2]|0)){y[X+20>>2]=0;y[X+8>>2]=0}if(P>>>0<=C[X+28>>2]>>>0){break a}Kd(0);break a}if((p|0)==(y[X+20>>2]|0)){var F=y[X+8>>2]+E|0;y[X+8>>2]=F;y[X+20>>2]=K;y[e+1]=F|1;y[(O+F|0)>>2]=F;break a}var oa=(na&-8)+E|0,wa=na>>>3,ca=na>>>0<256;c:do{if(ca){var V=C[i+j],ja=C[((r|4)>>2)+i];if((V|0)==(ja|0)){y[X>>2]=y[X>>2]&(1<<wa^-1)}else{var Oa=((na>>>2&1073741822)<<2)+X+40|0;f=(V|0)==(Oa|0)?63:V>>>0<C[X+16>>2]>>>0?66:63;do{if(f==63&&!((ja|0)!=(Oa|0)&&ja>>>0<C[X+16>>2]>>>0)){y[V+12>>2]=ja;y[ja+8>>2]=V;break c}}while(0);$();a("Reached an unreachable!")}}else{var hb=x,Ha=C[j+(i+4)],Ra=C[((r|4)>>2)+i],Za=(Ra|0)==(hb|0);do{if(Za){var Ob=r+(b+12)|0,xb=y[Ob>>2];if((xb|0)==0){var Pb=r+(b+8)|0,yb=y[Pb>>2];if((yb|0)==0){var ha=0;c=ha>>2;break}var Ka=Pb,La=yb}else{Ka=Ob;La=xb;f=73}for(;;){var ib=La+20|0,zb=y[ib>>2];if((zb|0)!=0){Ka=ib;La=zb}else{var Qb=La+16|0,Rb=C[Qb>>2];if((Rb|0)==0){break}Ka=Qb;La=Rb}}if(Ka>>>0<C[X+16>>2]>>>0){$();a("Reached an unreachable!")}y[Ka>>2]=0;ha=La}else{var $a=C[i+j];if($a>>>0<C[X+16>>2]>>>0){$();a("Reached an unreachable!")}y[$a+12>>2]=Ra;y[Ra+8>>2]=$a;ha=Ra}c=ha>>2}while(0);if((Ha|0)!=0){var Sb=r+(b+20)|0,Tb=(y[Sb>>2]<<2)+X+304|0,cc=(hb|0)==(y[Tb>>2]|0);do{if(cc){y[Tb>>2]=ha;if((ha|0)!=0){break}y[X+4>>2]=y[X+4>>2]&(1<<y[Sb>>2]^-1);break c}if(Ha>>>0<C[X+16>>2]>>>0){$();a("Reached an unreachable!")}var Ab=Ha+16|0;(y[Ab>>2]|0)==(hb|0)?y[Ab>>2]=ha:y[Ha+20>>2]=ha;if((ha|0)==0){break c}}while(0);if(ha>>>0<C[X+16>>2]>>>0){$();a("Reached an unreachable!")}y[c+6]=Ha;var bb=C[j+(i+2)];if((bb|0)!=0){if(bb>>>0<C[X+16>>2]>>>0){$();a("Reached an unreachable!")}y[c+4]=bb;y[bb+24>>2]=ha}var ab=C[j+(i+3)];if((ab|0)!=0){if(ab>>>0<C[X+16>>2]>>>0){$();a("Reached an unreachable!")}y[c+5]=ab;y[ab+24>>2]=ha}}}}while(0);y[e+1]=oa|1;y[O+oa>>2]=oa;if((K|0)!=(y[X+20>>2]|0)){var Ia=oa}else{y[X+8>>2]=oa;break a}}else{y[qa>>2]=na&-2;y[e+1]=E|1;Ia=y[O+E>>2]=E}}while(0);if(Ia>>>0<256){var Bb=Ia>>>2&1073741822,Cb=(Bb<<2)+X+40|0,Db=C[X>>2],ob=1<<(Ia>>>3);if((Db&ob|0)==0){y[X>>2]=Db|ob;var pb=Cb,Eb=(Bb+2<<2)+X+40|0}else{var Fb=(Bb+2<<2)+X+40|0,qb=C[Fb>>2];if(qb>>>0<C[X+16>>2]>>>0){$();a("Reached an unreachable!")}pb=qb;Eb=Fb}y[Eb>>2]=K;y[pb+12>>2]=K;y[e+2]=pb;y[e+3]=Cb;break a}var jb=K,rb=Ia>>>8;if((rb|0)==0){var Sa=0}else{if(Ia>>>0>16777215){Sa=31}else{var Pa=(rb+1048320|0)>>>16&8,sb=rb<<Pa,Ta=(sb+520192|0)>>>16&4,Gb=sb<<Ta,Hb=(Gb+245760|0)>>>16&2,Ib=14-(Ta|Pa|Hb)+(Gb<<Hb>>>15)|0,Sa=Ia>>>((Ib+7|0)>>>0)&1|Ib<<1}}var tb=(Sa<<2)+X+304|0;y[e+7]=Sa;y[e+5]=0;y[e+4]=0;var Jb=y[X+4>>2],Kb=1<<Sa,Lb=(Jb&Kb|0)==0;c:do{if(Lb){y[X+4>>2]=Jb|Kb;y[tb>>2]=jb;y[e+6]=tb;y[e+3]=K;y[e+2]=K}else{for(var kb=Ia<<((Sa|0)==31?0:25-(Sa>>>1)|0),Ua=y[tb>>2];;){if((y[Ua+4>>2]&-8|0)==(Ia|0)){var Ub=Ua+8|0,Va=C[Ub>>2],nb=C[X+16>>2],Ac=Ua>>>0<nb>>>0;do{if(!Ac&&Va>>>0>=nb>>>0){y[Va+12>>2]=jb;y[Ub>>2]=jb;y[e+2]=Va;y[e+3]=Ua;y[e+6]=0;break c}}while(0);$();a("Reached an unreachable!")}var Xb=(kb>>>31<<2)+Ua+16|0,oc=C[Xb>>2];if((oc|0)==0){if(Xb>>>0>=C[X+16>>2]>>>0){y[Xb>>2]=jb;y[e+6]=Ua;y[e+3]=K;y[e+2]=K;break c}$();a("Reached an unreachable!")}kb=kb<<1;Ua=oc}}}while(0);var Bc=y[X+32>>2]-1|0;y[X+32>>2]=Bc;if((Bc|0)!=0){break a}var gc=y[X+452>>2],Cc=(gc|0)==0;c:do{if(!Cc){for(var Td=gc;;){var Ud=y[Td+8>>2];if((Ud|0)==0){break c}Td=Ud}}}while(0);y[X+32>>2]=-1;break a}}}}}while(0);$();a("Reached an unreachable!")}}while(0)}Module._free=Ld;Ld.X=1;function Md(b,c){var d,e,g,h=c>>>0>4294967231;a:do{if(h){y[Jd>>2]=12;var j=0}else{g=d=b-8|0;e=(b-4|0)>>2;var i=C[e],f=i&-8,k=f-8|0,o=b+k|0,m=d>>>0<C[X+16>>2]>>>0;do{if(!m){var t=i&3;if((t|0)!=1&(k|0)>-8){d=(b+(f-4)|0)>>2;if((y[d]&1|0)!=0){h=c>>>0<11?16:c+11&-8;if((t|0)==0){var s=0,w,i=y[g+4>>2]&-8;w=h>>>0<256?0:i>>>0>=(h+4|0)>>>0&&(i-h|0)>>>0<=y[Cd+8>>2]<<1>>>0?g:0;g=17}else{if(f>>>0<h>>>0){if((o|0)!=(y[X+24>>2]|0)){g=21}else{d=y[X+12>>2]+f|0;if(d>>>0>h>>>0){s=d-h|0;w=b+(h-8)|0;y[e]=h|i&1|2;y[b+(h-4)>>2]=s|1;y[X+24>>2]=w;y[X+12>>2]=s;s=0;w=g;g=17}else{g=21}}}else{s=f-h|0;if(s>>>0>15){y[e]=h|i&1|2;y[b+(h-4)>>2]=s|3;y[d]=y[d]|1;s=b+h|0}else{s=0}w=g;g=17}}do{if(g==17&&(w|0)!=0){(s|0)!=0&&Ld(s);j=w+8|0;break a}}while(0);g=ac(c);if((g|0)==0){j=0;break a}e=f-((y[e]&3|0)==0?8:4)|0;f=g;i=b;e=e>>>0<c>>>0?e:c;if(e>=20&&i%2==f%2){if(i%4==f%4){for(e=i+e;i%4;){v[f++]=v[i++]}i=i>>2;f=f>>2;for(s=e>>2;i<s;){y[f++]=y[i++]}i=i<<2;for(f=f<<2;i<e;){v[f++]=v[i++]}}else{e=i+e;i%2&&(v[f++]=v[i++]);i=i>>1;f=f>>1;for(s=e>>1;i<s;){gb[f++]=gb[i++]}i=i<<1;f=f<<1;i<e&&(v[f++]=v[i++])}}else{for(;e--;){v[f++]=v[i++]}}Ld(b);j=g;break a}}}}while(0);$();a("Reached an unreachable!")}}while(0);return j}Md.X=1;function Dd(){if((y[Cd>>2]|0)==0){var b=Nd();if((b-1&b|0)==0){y[Cd+8>>2]=b;y[Cd+4>>2]=b;y[Cd+12>>2]=-1;y[Cd+16>>2]=2097152;y[Cd+20>>2]=0;y[X+440>>2]=0;y[Cd>>2]=Math.floor(Date.now()/1e3)&-16^1431655768}else{$();a("Reached an unreachable!")}}}function Od(b){if((b|0)==0){b=0}else{var b=y[b-4>>2],c=b&3,b=(c|0)==1?0:(b&-8)-((c|0)==0?8:4)|0}return b}function Ed(b){var c,d=X+444|0;for(c=d>>2;;){var e=C[c];if(e>>>0<=b>>>0&&(e+y[c+1]|0)>>>0>b>>>0){var g=d;break}c=C[c+2];if((c|0)==0){g=0;break}d=c;c=d>>2}return g}function Gd(b,c){var d=b+8|0,d=(d&7|0)==0?0:-d&7,e=c-d|0;y[X+24>>2]=b+d|0;y[X+12>>2]=e;y[d+(b+4)>>2]=e|1;y[c+(b+4)>>2]=40;y[X+28>>2]=y[Cd+16>>2]}function Hd(b,c,d){var e,g,h,j=c>>2,i=b>>2,f,k=b+8|0,k=(k&7|0)==0?0:-k&7;g=c+8|0;var o=(g&7|0)==0?0:-g&7;h=o>>2;var m=c+o|0,t=k+d|0;g=t>>2;var s=b+t|0,w=m-(b+k)-d|0;y[(k+4>>2)+i]=d|3;d=(m|0)==(y[X+24>>2]|0);a:do{if(d){var u=y[X+12>>2]+w|0;y[X+12>>2]=u;y[X+24>>2]=s;y[g+(i+1)]=u|1}else{if((m|0)==(y[X+20>>2]|0)){u=y[X+8>>2]+w|0;y[X+8>>2]=u;y[X+20>>2]=s;y[g+(i+1)]=u|1;y[(b+u+t|0)>>2]=u}else{var r=C[h+(j+1)];if((r&3|0)==1){var u=r&-8,x=r>>>3,p=r>>>0<256;b:do{if(p){var B=C[((o|8)>>2)+j],I=C[h+(j+3)];if((B|0)==(I|0)){y[X>>2]=y[X>>2]&(1<<x^-1)}else{var S=((r>>>2&1073741822)<<2)+X+40|0;f=(B|0)==(S|0)?15:B>>>0<C[X+16>>2]>>>0?18:15;do{if(f==15&&!((I|0)!=(S|0)&&I>>>0<C[X+16>>2]>>>0)){y[B+12>>2]=I;y[I+8>>2]=B;break b}}while(0);$();a("Reached an unreachable!")}}else{f=m;B=C[((o|24)>>2)+j];I=C[h+(j+3)];S=(I|0)==(f|0);do{if(S){e=o|16;var Q=e+(c+4)|0,H=y[Q>>2];if((H|0)==0){e=c+e|0;H=y[e>>2];if((H|0)==0){H=0;e=H>>2;break}}else{e=Q}for(;;){var Q=H+20|0,J=y[Q>>2];if((J|0)==0){Q=H+16|0;J=C[Q>>2];if((J|0)==0){break}}e=Q;H=J}if(e>>>0<C[X+16>>2]>>>0){$();a("Reached an unreachable!")}y[e>>2]=0}else{e=C[((o|8)>>2)+j];if(e>>>0<C[X+16>>2]>>>0){$();a("Reached an unreachable!")}y[e+12>>2]=I;y[I+8>>2]=e;H=I}e=H>>2}while(0);if((B|0)!=0){I=o+(c+28)|0;S=(y[I>>2]<<2)+X+304|0;Q=(f|0)==(y[S>>2]|0);do{if(Q){y[S>>2]=H;if((H|0)!=0){break}y[X+4>>2]=y[X+4>>2]&(1<<y[I>>2]^-1);break b}if(B>>>0<C[X+16>>2]>>>0){$();a("Reached an unreachable!")}J=B+16|0;(y[J>>2]|0)==(f|0)?y[J>>2]=H:y[B+20>>2]=H;if((H|0)==0){break b}}while(0);if(H>>>0<C[X+16>>2]>>>0){$();a("Reached an unreachable!")}y[e+6]=B;f=o|16;B=C[(f>>2)+j];if((B|0)!=0){if(B>>>0<C[X+16>>2]>>>0){$();a("Reached an unreachable!")}y[e+4]=B;y[B+24>>2]=H}f=C[(f+4>>2)+j];if((f|0)!=0){if(f>>>0<C[X+16>>2]>>>0){$();a("Reached an unreachable!")}y[e+5]=f;y[f+24>>2]=H}}}}while(0);r=c+(u|o)|0;u=u+w|0}else{r=m;u=w}r=r+4|0;y[r>>2]=y[r>>2]&-2;y[g+(i+1)]=u|1;y[(u>>2)+i+g]=u;if(u>>>0<256){x=u>>>2&1073741822;r=(x<<2)+X+40|0;p=C[X>>2];u=1<<(u>>>3);if((p&u|0)==0){y[X>>2]=p|u;u=r;x=(x+2<<2)+X+40|0}else{x=(x+2<<2)+X+40|0;u=C[x>>2];if(u>>>0<C[X+16>>2]>>>0){$();a("Reached an unreachable!")}}y[x>>2]=s;y[u+12>>2]=s;y[g+(i+2)]=u;y[g+(i+3)]=r}else{r=s;p=u>>>8;if((p|0)==0){x=0}else{if(u>>>0>16777215){x=31}else{x=(p+1048320|0)>>>16&8;f=p<<x;p=(f+520192|0)>>>16&4;f=f<<p;B=(f+245760|0)>>>16&2;x=14-(p|x|B)+(f<<B>>>15)|0;x=u>>>((x+7|0)>>>0)&1|x<<1}}p=(x<<2)+X+304|0;y[g+(i+7)]=x;f=t+(b+16)|0;y[g+(i+5)]=0;y[f>>2]=0;f=y[X+4>>2];B=1<<x;if((f&B|0)==0){y[X+4>>2]=f|B;y[p>>2]=r;y[g+(i+6)]=p;y[g+(i+3)]=r;y[g+(i+2)]=r}else{x=u<<((x|0)==31?0:25-(x>>>1)|0);for(p=y[p>>2];;){if((y[p+4>>2]&-8|0)==(u|0)){f=p+8|0;B=C[f>>2];I=C[X+16>>2];S=p>>>0<I>>>0;do{if(!S&&B>>>0>=I>>>0){y[B+12>>2]=r;y[f>>2]=r;y[g+(i+2)]=B;y[g+(i+3)]=p;y[g+(i+6)]=0;break a}}while(0);$();a("Reached an unreachable!")}f=(x>>>31<<2)+p+16|0;B=C[f>>2];if((B|0)==0){if(f>>>0>=C[X+16>>2]>>>0){y[f>>2]=r;y[g+(i+6)]=p;y[g+(i+3)]=r;y[g+(i+2)]=r;break a}$();a("Reached an unreachable!")}x=x<<1;p=B}}}}}}while(0);return b+(k|8)|0}Hd.X=1;function Id(b,c){var d,e,g=C[X+24>>2];e=g>>2;var h=Ed(g),j=y[h>>2];d=y[h+4>>2];var h=j+d|0,i=j+(d-39)|0,j=j+(d-47)+((i&7|0)==0?0:-i&7)|0,j=j>>>0<(g+16|0)>>>0?g:j,i=j+8|0;d=i>>2;Gd(b,c-40|0);y[(j+4|0)>>2]=27;y[d]=y[X+444>>2];y[d+1]=y[X+448>>2];y[d+2]=y[X+452>>2];y[d+3]=y[X+456>>2];y[X+444>>2]=b;y[X+448>>2]=c;y[X+456>>2]=0;y[X+452>>2]=i;d=j+28|0;y[d>>2]=7;i=(j+32|0)>>>0<h>>>0;a:do{if(i){for(var f=d;;){var k=f+4|0;y[k>>2]=7;if((f+8|0)>>>0>=h>>>0){break a}f=k}}}while(0);h=(j|0)==(g|0);a:do{if(!h){d=j-g|0;i=g+d|0;f=d+(g+4)|0;y[f>>2]=y[f>>2]&-2;y[e+1]=d|1;y[i>>2]=d;if(d>>>0<256){f=d>>>2&1073741822;i=(f<<2)+X+40|0;k=C[X>>2];d=1<<(d>>>3);if((k&d|0)==0){y[X>>2]=k|d;d=i;f=(f+2<<2)+X+40|0}else{f=(f+2<<2)+X+40|0;d=C[f>>2];if(d>>>0<C[X+16>>2]>>>0){$();a("Reached an unreachable!")}}y[f>>2]=g;y[d+12>>2]=g;y[e+2]=d;y[e+3]=i}else{i=g;k=d>>>8;if((k|0)==0){f=0}else{if(d>>>0>16777215){f=31}else{var f=(k+1048320|0)>>>16&8,o=k<<f,k=(o+520192|0)>>>16&4,o=o<<k,m=(o+245760|0)>>>16&2,f=14-(k|f|m)+(o<<m>>>15)|0,f=d>>>((f+7|0)>>>0)&1|f<<1}}k=(f<<2)+X+304|0;y[e+7]=f;y[e+5]=0;y[e+4]=0;o=y[X+4>>2];m=1<<f;if((o&m|0)==0){y[X+4>>2]=o|m;y[k>>2]=i;y[e+6]=k;y[e+3]=g;y[e+2]=g}else{f=d<<((f|0)==31?0:25-(f>>>1)|0);for(k=y[k>>2];;){if((y[k+4>>2]&-8|0)==(d|0)){var o=k+8|0,m=C[o>>2],t=C[X+16>>2],s=k>>>0<t>>>0;do{if(!s&&m>>>0>=t>>>0){y[m+12>>2]=i;y[o>>2]=i;y[e+2]=m;y[e+3]=k;y[e+6]=0;break a}}while(0);$();a("Reached an unreachable!")}o=(f>>>31<<2)+k+16|0;m=C[o>>2];if((m|0)==0){if(o>>>0>=C[X+16>>2]>>>0){y[o>>2]=i;y[e+6]=k;y[e+3]=g;y[e+2]=g;break a}$();a("Reached an unreachable!")}f=f<<1;k=m}}}}}while(0)}Id.X=1;function yc(b,c){function d(b){var d;if(b==="double"){d=(Zb[0]=y[c+g>>2],Zb[1]=y[c+g+4>>2],Yb[0])}else{if(b=="i64"){d=[y[c+g>>2],y[c+g+4>>2]]}else{b="i32";d=y[c+g>>2]}}g=g+Math.max(Wa(b),Xa);return d}for(var e=b,g=0,h=[],j,i;;){var f=e;j=v[e];if(j===0){break}i=v[e+1];if(j==37){var k=n,o=n,m=n,t=n;a:for(;;){switch(i){case 43:k=l;break;case 45:o=l;break;case 35:m=l;break;case 48:if(t){break a}else{t=l;break};default:break a}e++;i=v[e+1]}var s=0;if(i==42){s=d("i32");e++;i=v[e+1]}else{for(;i>=48&&i<=57;){s=s*10+(i-48);e++;i=v[e+1]}}var w=n;if(i==46){var u=0,w=l;e++;i=v[e+1];if(i==42){u=d("i32");e++}else{for(;;){i=v[e+1];if(i<48||i>57){break}u=u*10+(i-48);e++}}i=v[e+1]}else{u=6}var r;switch(String.fromCharCode(i)){case"h":i=v[e+2];if(i==104){e++;r=1}else{r=2}break;case"l":i=v[e+2];if(i==108){e++;r=8}else{r=4}break;case"L":case"q":case"j":r=8;break;case"z":case"t":case"I":r=4;break;default:r=pa}r&&e++;i=v[e+1];if(["d","i","u","o","x","X","p"].indexOf(String.fromCharCode(i))!=-1){f=i==100||i==105;r=r||4;j=d("i"+r*8);r==8&&(j=i==117?(j[0]>>>0)+(j[1]>>>0)*4294967296:(j[0]>>>0)+(j[1]|0)*4294967296);r<=4&&(j=(f?vc:uc)(j&Math.pow(256,r)-1,r*8));var x=Math.abs(j),p,f="";if(i==100||i==105){p=vc(j,8*r).toString(10)}else{if(i==117){p=uc(j,8*r).toString(10);j=Math.abs(j)}else{if(i==111){p=(m?"0":"")+x.toString(8)}else{if(i==120||i==88){f=m?"0x":"";if(j<0){j=-j;p=(x-1).toString(16);m=[];for(x=0;x<p.length;x++){m.push((15-parseInt(p[x],16)).toString(16))}for(p=m.join("");p.length<r*2;){p="f"+p}}else{p=x.toString(16)}if(i==88){f=f.toUpperCase();p=p.toUpperCase()}}else{if(i==112){if(x===0){p="(nil)"}else{f="0x";p=x.toString(16)}}}}}}if(w){for(;p.length<u;){p="0"+p}}for(k&&(f=j<0?"-"+f:"+"+f);f.length+p.length<s;){o?p=p+" ":t?p="0"+p:f=" "+f}p=f+p;p.split("").forEach((function(b){h.push(b.charCodeAt(0))}))}else{if(["f","F","e","E","g","G"].indexOf(String.fromCharCode(i))!=-1){j=d("double");if(isNaN(j)){p="nan";t=n}else{if(isFinite(j)){w=n;r=Math.min(u,20);if(i==103||i==71){w=l;u=u||1;r=parseInt(j.toExponential(r).split("e")[1],10);if(u>r&&r>=-4){i=(i==103?"f":"F").charCodeAt(0);u=u-(r+1)}else{i=(i==103?"e":"E").charCodeAt(0);u--}r=Math.min(u,20)}if(i==101||i==69){p=j.toExponential(r);/[eE][-+]\d$/.test(p)&&(p=p.slice(0,-1)+"0"+p.slice(-1))}else{if(i==102||i==70){p=j.toFixed(r)}}f=p.split("e");if(w&&!m){for(;f[0].length>1&&f[0].indexOf(".")!=-1&&(f[0].slice(-1)=="0"||f[0].slice(-1)==".");){f[0]=f[0].slice(0,-1)}}else{for(m&&p.indexOf(".")==-1&&(f[0]=f[0]+".");u>r++;){f[0]=f[0]+"0"}}p=f[0]+(f.length>1?"e"+f[1]:"");i==69&&(p=p.toUpperCase());k&&j>=0&&(p="+"+p)}else{p=(j<0?"-":"")+"inf";t=n}}for(;p.length<s;){p=o?p+" ":t&&(p[0]=="-"||p[0]=="+")?p[0]+"0"+p.slice(1):(t?"0":" ")+p}i<97&&(p=p.toUpperCase());p.split("").forEach((function(b){h.push(b.charCodeAt(0))}))}else{if(i==115){if(k=d("i8*")){k=tc(k);w&&k.length>u&&(k=k.slice(0,u))}else{k=jc("(null)",l)}if(!o){for(;k.length<s--;){h.push(32)}}h=h.concat(k);if(o){for(;k.length<s--;){h.push(32)}}}else{if(i==99){for(o&&h.push(d("i8"));--s>0;){h.push(32)}o||h.push(d("i8"))}else{if(i==110){o=d("i32*");y[o>>2]=h.length}else{if(i==37){h.push(j)}else{for(x=f;x<e+2;x++){h.push(v[x])}}}}}}}e=e+2}else{h.push(j);e=e+1}}return h}var Pd=13,Qd=9,Rd=22,Sd=5,Vd=21,Wd=6;function Xd(b){Jd||(Jd=G([0],"i32",D));y[Jd>>2]=b}var Jd,Yd=0,zc=0,Zd=0,$d=2,Ec=[pa],ae=l;function be(b,c){if(typeof b!=="string"){return pa}c===aa&&(c="/");b&&b[0]=="/"&&(c="");for(var d=(c+"/"+b).split("/").reverse(),e=[""];d.length;){var g=d.pop();g==""||g=="."||(g==".."?e.length>1&&e.pop():e.push(g))}return e.length==1?"/":e.join("/")}function ce(b,c,d){var e={ga:n,l:n,error:0,name:pa,path:pa,object:pa,v:n,z:pa,w:pa},b=be(b);if(b=="/"){e.ga=l;e.l=e.v=l;e.name="/";e.path=e.z="/";e.object=e.w=de}else{if(b!==pa){for(var d=d||0,b=b.slice(1).split("/"),g=de,h=[""];b.length;){if(b.length==1&&g.d){e.v=l;e.z=h.length==1?"/":h.join("/");e.w=g;e.name=b[0]}var j=b.shift();if(g.d){if(g.A){if(!g.c.hasOwnProperty(j)){e.error=2;break}}else{e.error=Pd;break}}else{e.error=20;break}g=g.c[j];if(g.link&&!(c&&b.length==0)){if(d>40){e.error=40;break}e=be(g.link,h.join("/"));return ce([e].concat(b).join("/"),c,d+1)}h.push(j);if(b.length==0){e.l=l;e.path=h.join("/");e.object=g}}}}return e}function ee(b){fe();b=ce(b,aa);if(b.l){return b.object}Xd(b.error);return pa}function ge(b,c,d,e,g){b||(b="/");typeof b==="string"&&(b=ee(b));if(!b){Xd(Pd);a(Error("Parent path must exist."))}if(!b.d){Xd(20);a(Error("Parent must be a folder."))}if(!b.write&&!ae){Xd(Pd);a(Error("Parent folder must be writeable."))}if(!c||c=="."||c==".."){Xd(2);a(Error("Name must not be empty."))}if(b.c.hasOwnProperty(c)){Xd(17);a(Error("Can't overwrite object."))}b.c[c]={A:e===aa?l:e,write:g===aa?n:g,timestamp:Date.now(),fa:$d++};for(var h in d){d.hasOwnProperty(h)&&(b.c[c][h]=d[h])}return b.c[c]}function he(b,c){return ge(b,c,{d:l,h:n,c:{}},l,l)}function ie(){var b="dev/shm/tmp",c=ee("/");c===pa&&a(Error("Invalid parent."));for(b=b.split("/").reverse();b.length;){var d=b.pop();if(d){c.c.hasOwnProperty(d)||he(c,d);c=c.c[d]}}}function je(b,c,d,e){!d&&!e&&a(Error("A device must have at least one callback defined."));var g={h:l,input:d,e:e};g.d=n;return ge(b,c,g,Boolean(d),Boolean(e))}function fe(){de||(de={A:l,write:l,d:l,h:n,timestamp:Date.now(),fa:1,c:{}})}function ke(){var b,c,d;function e(b){if(b===pa||b===10){c.j(c.buffer.join(""));c.buffer=[]}else{c.buffer.push(String.fromCharCode(b))}}Ya(!le,"FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)");le=l;fe();b=b||Module.stdin;c=c||Module.stdout;d=d||Module.stderr;var g=l,h=l,j=l;if(!b){g=n;b=(function(){if(!b.k||!b.k.length){var c;typeof window!="undefined"&&typeof window.prompt=="function"?c=window.prompt("Input: "):typeof readline=="function"&&(c=readline());c||(c="");b.k=jc(c+"\n",l)}return b.k.shift()})}if(!c){h=n;c=e}if(!c.j){c.j=print}if(!c.buffer){c.buffer=[]}if(!d){j=n;d=e}if(!d.j){d.j=print}if(!d.buffer){d.buffer=[]}he("/","tmp");var i=he("/","dev"),f=je(i,"stdin",b),k=je(i,"stdout",pa,c);d=je(i,"stderr",pa,d);je(i,"tty",b,c);Ec[1]={path:"/dev/stdin",object:f,position:0,t:l,i:n,s:n,u:!g,error:n,q:n,B:[]};Ec[2]={path:"/dev/stdout",object:k,position:0,t:n,i:l,s:n,u:!h,error:n,q:n,B:[]};Ec[3]={path:"/dev/stderr",object:d,position:0,t:n,i:l,s:n,u:!j,error:n,q:n,B:[]};Yd=G([1],"void*",D);zc=G([2],"void*",D);Zd=G([3],"void*",D);ie();Ec[Yd]=Ec[1];Ec[zc]=Ec[2];Ec[Zd]=Ec[3];G([G([0,0,0,0,Yd,0,0,0,zc,0,0,0,Zd,0,0,0],"void*",D)],"void*",D)}var le,de;function Dc(b,c,d){var e=Ec[b];if(e){if(e.i){if(d<0){Xd(Rd);return-1}if(e.object.h){if(e.object.e){for(var g=0;g<d;g++){try{e.object.e(v[c+g])}catch(h){Xd(Sd);return-1}}e.object.timestamp=Date.now();return g}Xd(Wd);return-1}g=e.position;b=Ec[b];if(!b||b.object.h){Xd(Qd);c=-1}else{if(b.i){if(b.object.d){Xd(Vd);c=-1}else{if(d<0||g<0){Xd(Rd);c=-1}else{for(var j=b.object.c;j.length<g;){j.push(0)}for(var i=0;i<d;i++){j[g+i]=z[c+i]}b.object.timestamp=Date.now();c=i}}}else{Xd(Pd);c=-1}}if(c!=-1){e.position=e.position+c}return c}Xd(Pd);return-1}Xd(Qd);return-1}function bc(b,c,d){if(d>=20){for(d=b+d;b%4;){v[b++]=c}c<0&&(c=c+256);for(var b=b>>2,e=d>>2,g=c|c<<8|c<<16|c<<24;b<e;){y[b++]=g}for(b=b<<2;b<d;){v[b++]=c}}else{for(;d--;){v[b++]=c}}}function $(){a("ABORT: undefined, at "+Error().stack)}function Nd(){switch(8){case 8:return ec;case 54:case 56:case 21:case 61:case 63:case 22:case 67:case 23:case 24:case 25:case 26:case 27:case 69:case 28:case 101:case 70:case 71:case 29:case 30:case 199:case 75:case 76:case 32:case 43:case 44:case 80:case 46:case 47:case 45:case 48:case 49:case 42:case 82:case 33:case 7:case 108:case 109:case 107:case 112:case 119:case 121:return 200809;case 13:case 104:case 94:case 95:case 34:case 35:case 77:case 81:case 83:case 84:case 85:case 86:case 87:case 88:case 89:case 90:case 91:case 94:case 95:case 110:case 111:case 113:case 114:case 115:case 116:case 117:case 118:case 120:case 40:case 16:case 79:case 19:return-1;case 92:case 93:case 5:case 72:case 6:case 74:case 92:case 93:case 96:case 97:case 98:case 99:case 102:case 103:case 105:return 1;case 38:case 66:case 50:case 51:case 4:return 1024;case 15:case 64:case 41:return 32;case 55:case 37:case 17:return 2147483647;case 18:case 1:return 47839;case 59:case 57:return 99;case 68:case 58:return 2048;case 0:return 2097152;case 3:return 65536;case 14:return 32768;case 73:return 32767;case 39:return 16384;case 60:return 1e3;case 106:return 700;case 52:return 256;case 62:return 255;case 2:return 100;case 65:return 64;case 36:return 20;case 100:return 16;case 20:return 6;case 53:return 4}Xd(Rd);return-1}function Fd(b){if(!me){eb=eb+4095>>12<<12;me=l}var c=eb;b!=0&&db(b);return c}var me;pc.unshift({r:(function(){ae=n;le||ke()})});qc.push({r:(function(){if(le){Ec[2]&&Ec[2].object.e.buffer.length>0&&Ec[2].object.e(10);Ec[3]&&Ec[3].object.e.buffer.length>0&&Ec[3].object.e(10)}})});Xd(0);G(12,"void*",D);Module.ea=(function(b){function c(){for(var b=0;b<3;b++){e.push(0)}}var d=b.length+1,e=[G(jc("/bin/this.program"),"i8",D)];c();for(var g=0;g<d-1;g=g+1){e.push(G(jc(b[g]),"i8",D));c()}e.push(0);e=G(e,"i32",D);return _main(d,e,0)});var Gc,Hc,vd,X,Cd,ne,oe,pe,qe,re;M.G=G([37,115,40,37,117,41,58,32,65,115,115,101,114,116,105,111,110,32,102,97,105,108,117,114,101,58,32,34,37,115,34,10,0],"i8",D);M.H=G([109,95,115,105,122,101,32,60,61,32,109,95,99,97,112,97,99,105,116,121,0],"i8",D);M.O=G([46,47,99,114,110,95,100,101,99,111,109,112,46,104,0],"i8",D);M.T=G([109,105,110,95,110,101,119,95,99,97,112,97,99,105,116,121,32,60,32,40,48,120,55,70,70,70,48,48,48,48,85,32,47,32,101,108,101,109,101,110,116,95,115,105,122,101,41,0],"i8",D);M.Y=G([110,101,119,95,99,97,112,97,99,105,116,121,32,38,38,32,40,110,101,119,95,99,97,112,97,99,105,116,121,32,62,32,109,95,99,97,112,97,99,105,116,121,41,0],"i8",D);M.Z=G([110,117,109,95,99,111,100,101,115,91,99,93,0],"i8",D);M.$=G([115,111,114,116,101,100,95,112,111,115,32,60,32,116,111,116,97,108,95,117,115,101,100,95,115,121,109,115,0],"i8",D);M.aa=G([112,67,111,100,101,115,105,122,101,115,91,115,121,109,95,105,110,100,101,120,93,32,61,61,32,99,111,100,101,115,105,122,101,0],"i8",D);M.ba=G([116,32,60,32,40,49,85,32,60,60,32,116,97,98,108,101,95,98,105,116,115,41,0],"i8",D);M.ca=G([109,95,108,111,111,107,117,112,91,116,93,32,61,61,32,99,85,73,78,84,51,50,95,77,65,88,0],"i8",D);Gc=G([2],["i8* (i8*, i32, i32*, i1, i8*)*",0,0,0,0],D);G([4],["i32 (i8*, i8*)*",0,0,0,0],D);Hc=G(1,"i8*",D);M.m=G([99,114,110,100,95,109,97,108,108,111,99,58,32,115,105,122,101,32,116,111,111,32,98,105,103,0],"i8",D);M.I=G([99,114,110,100,95,109,97,108,108,111,99,58,32,111,117,116,32,111,102,32,109,101,109,111,114,121,0],"i8",D);M.n=G([40,40,117,105,110,116,51,50,41,112,95,110,101,119,32,38,32,40,67,82,78,68,95,77,73,78,95,65,76,76,79,67,95,65,76,73,71,78,77,69,78,84,32,45,32,49,41,41,32,61,61,32,48,0],"i8",D);M.J=G([99,114,110,100,95,114,101,97,108,108,111,99,58,32,98,97,100,32,112,116,114,0],"i8",D);M.K=G([99,114,110,100,95,102,114,101,101,58,32,98,97,100,32,112,116,114,0],"i8",D);M.ma=G([99,114,110,100,95,109,115,105,122,101,58,32,98,97,100,32,112,116,114,0],"i8",D);G([1,0,0,0,2,0,0,0,4,0,0,0,8,0,0,0,16,0,0,0,32,0,0,0,64,0,0,0,128,0,0,0,256,0,0,0,512,0,0,0,1024,0,0,0,2048,0,0,0,4096,0,0,0,8192,0,0,0,16384,0,0,0,32768,0,0,0,65536,0,0,0,131072,0,0,0,262144,0,0,0,524288,0,0,0,1048576,0,0,0,2097152,0,0,0,4194304,0,0,0,8388608,0,0,0,16777216,0,0,0,33554432,0,0,0,67108864,0,0,0,134217728,0,0,0,268435456,0,0,0,536870912,0,0,0,1073741824,0,0,0,-2147483648,0,0,0],["i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0],D);M.M=G([102,97,108,115,101,0],"i8",D);M.na=G([99,114,110,100,95,118,97,108,105,100,97,116,101,95,102,105,108,101,40,38,110,101,119,95,104,101,97,100,101,114,44,32,97,99,116,117,97,108,95,98,97,115,101,95,100,97,116,97,95,115,105,122,101,44,32,78,85,76,76,41,0],"i8",D);M.oa=G([40,116,111,116,97,108,95,115,121,109,115,32,62,61,32,49,41,32,38,38,32,40,116,111,116,97,108,95,115,121,109,115,32,60,61,32,112,114,101,102,105,120,95,99,111,100,105,110,103,58,58,99,77,97,120,83,117,112,112,111,114,116,101,100,83,121,109,115,41,32,38,38,32,40,99,111,100,101,95,115,105,122,101,95,108,105,109,105,116,32,62,61,32,49,41,0],"i8",D);M.N=G([40,116,111,116,97,108,95,115,121,109,115,32,62,61,32,49,41,32,38,38,32,40,116,111,116,97,108,95,115,121,109,115,32,60,61,32,112,114,101,102,105,120,95,99,111,100,105,110,103,58,58,99,77,97,120,83,117,112,112,111,114,116,101,100,83,121,109,115,41,0],"i8",D);M.C=G([17,18,19,20,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15,16],"i8",D);M.o=G([48,0],"i8",D);M.P=G([110,117,109,95,98,105,116,115,32,60,61,32,51,50,85,0],"i8",D);M.Q=G([109,95,98,105,116,95,99,111,117,110,116,32,60,61,32,99,66,105,116,66,117,102,83,105,122,101,0],"i8",D);M.R=G([116,32,33,61,32,99,85,73,78,84,51,50,95,77,65,88,0],"i8",D);M.S=G([109,111,100,101,108,46,109,95,99,111,100,101,95,115,105,122,101,115,91,115,121,109,93,32,61,61,32,108,101,110,0],"i8",D);G([1,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,4,0,0,0,1,0,0,0,0,0,0,0,4,0,0,0,8,0,0,0,4,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,8,0,0,0,3,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,8,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,4,0,0,0,1,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,7,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,4,0,0,0,8,0,0,0,4,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,5,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,8,0,0,0,3,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,8,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,5,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,5,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,6,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,7,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,8,0,0,0],["i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0],D);G([0,0,0,0,0,0,0,0,8,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,4,0,0,0,1,0,0,0,0,0,0,0,4,0,0,0,8,0,0,0,4,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,8,0,0,0,3,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,8,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,5,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,6,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,7,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,8,0,0,0],["i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0],D);M.ha=G([0,3,1,2],"i8",D);M.b=G([0,2,3,1],"i8",D);M.ia=G([0,7,1,2,3,4,5,6],"i8",D);M.a=G([0,2,3,4,5,6,7,1],"i8",D);M.ja=G([1,0,5,4,3,2,6,7],"i8",D);M.ka=G([1,0,7,6,5,4,3,2],"i8",D);M.qa=G([105,110,100,101,120,32,60,32,50,0],"i8",D);M.ra=G([40,108,111,32,60,61,32,48,120,70,70,70,70,85,41,32,38,38,32,40,104,105,32,60,61,32,48,120,70,70,70,70,85,41,0],"i8",D);M.sa=G([40,120,32,60,32,99,68,88,84,66,108,111,99,107,83,105,122,101,41,32,38,38,32,40,121,32,60,32,99,68,88,84,66,108,111,99,107,83,105,122,101,41,0],"i8",D);M.ta=G([118,97,108,117,101,32,60,61,32,48,120,70,70,0],"i8",D);M.ua=G([118,97,108,117,101,32,60,61,32,48,120,70,0],"i8",D);M.va=G([40,108,111,32,60,61,32,48,120,70,70,41,32,38,38,32,40,104,105,32,60,61,32,48,120,70,70,41,0],"i8",D);M.g=G([105,32,60,32,109,95,115,105,122,101,0],"i8",D);M.p=G([110,117,109,32,38,38,32,40,110,117,109,32,61,61,32,126,110,117,109,95,99,104,101,99,107,41,0],"i8",D);M.f=G([1,2,2,3,3,3,3,4],"i8",D);vd=G([0,0,0,0,0,0,1,1,0,1,0,1,0,0,1,2,1,2,0,0,0,1,0,2,1,0,2,0,0,1,2,3],"i8",D);M.U=G([110,101,120,116,95,108,101,118,101,108,95,111,102,115,32,62,32,99,117,114,95,108,101,118,101,108,95,111,102,115,0],"i8",D);M.W=G([40,108,101,110,32,62,61,32,49,41,32,38,38,32,40,108,101,110,32,60,61,32,99,77,97,120,69,120,112,101,99,116,101,100,67,111,100,101,83,105,122,101,41,0],"i8",D);X=G(468,["i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"i32",0,0,0,"i32",0,0,0,"i32",0,0,0,"*",0,0,0,"i32",0,0,0,"*",0,0,0,"i32",0,0,0,"*",0,0,0,"i32",0,0,0],D);Cd=G(24,"i32",D);M.wa=G([109,97,120,32,115,121,115,116,101,109,32,98,121,116,101,115,32,61,32,37,49,48,108,117,10,0],"i8",D);M.la=G([115,121,115,116,101,109,32,98,121,116,101,115,32,32,32,32,32,61,32,37,49,48,108,117,10,0],"i8",D);M.pa=G([105,110,32,117,115,101,32,98,121,116,101,115,32,32,32,32,32,61,32,37,49,48,108,117,10,0],"i8",D);G([0],"i8",D);G(1,"void ()*",D);ne=G([0,0,0,0,0,0,0,0,6,0,0,0,8,0,0,0,10,0,0,0],["*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0],D);G(1,"void*",D);M.V=G([115,116,100,58,58,98,97,100,95,97,108,108,111,99,0],"i8",D);oe=G([0,0,0,0,0,0,0,0,12,0,0,0,14,0,0,0,16,0,0,0],["*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0,"*",0,0,0],D);G(1,"void*",D);M.L=G([98,97,100,95,97,114,114,97,121,95,110,101,119,95,108,101,110,103,116,104,0],"i8",D);M.F=G([83,116,57,98,97,100,95,97,108,108,111,99,0],"i8",D);qe=G(12,"*",D);M.D=G([83,116,50,48,98,97,100,95,97,114,114,97,121,95,110,101,119,95,108,101,110,103,116,104,0],"i8",D);re=G(12,"*",D);y[ne+4>>2]=qe;y[oe+4>>2]=re;pe=G([2,0,0,0,0],["i8*",0,0,0,0],D);y[qe>>2]=pe+8|0;y[qe+4>>2]=M.F|0;y[qe+8>>2]=aa;y[re>>2]=pe+8|0;y[re+4>>2]=M.D|0;y[re+8>>2]=qe;dc=[0,0,(function(b,c,d,e){if((b|0)==0){b=ac(c);(d|0)!=0&&(y[d>>2]=(b|0)==0?0:Od(b));d=b}else{if((c|0)==0){Ld(b);(d|0)!=0&&(y[d>>2]=0);d=0}else{var g=(b|0)==0?ac(c):Md(b,c),h=(g|0)!=0,j=h?g:b;if(h|e^1){b=j}else{g=(b|0)==0?ac(c):Md(b,c);(g|0)==0?g=0:b=g}(d|0)!=0&&(y[d>>2]=Od(b));d=g}}return d}),0,(function(b){return(b|0)==0?0:Od(b)}),0,(function(b){aa(b|0)}),0,(function(b){aa(b|0);(b|0)!=0&&Ld(b)}),0,(function(){return M.V|0}),0,(function(b){aa(b|0)}),0,(function(b){aa(b|0);(b|0)!=0&&Ld(b)}),0,(function(){return M.L|0}),0];Module.FUNCTION_TABLE=dc;function se(b){b=b||Module.arguments;nc(pc);var c=pa;if(Module._main){c=Module.ea(b);Module.noExitRuntime||nc(qc)}return c}Module.run=se;Module.preRun&&Module.preRun();Module.noInitialRun||se();Module.postRun&&Module.postRun() + + //=== + +onmessage = function(msg) { + var start = Date.now(); + var data = deCrunch(new Uint8Array(msg.data.data), msg.data.filename); + postMessage({ + filename: msg.data.filename, + data: data, + callbackID: msg.data.callbackID, + time: Date.now() - start + }); +}; + diff --git a/tools/eliminator/eliminator-test-output.js b/tools/eliminator/eliminator-test-output.js index aac21e87..fd8036bf 100644 --- a/tools/eliminator/eliminator-test-output.js +++ b/tools/eliminator/eliminator-test-output.js @@ -126,4 +126,2724 @@ function llvm3_1() { run($j_0 / 2); } } -// EMSCRIPTEN_GENERATED_FUNCTIONS: ["f", "g", "h", "py", "r", "t", "f2", "f3", "llvm3_1"] +function _inflate($strm, $flush) { + var __stackBase__ = STACKTOP; + STACKTOP += 4; + var __label__; + var $hbuf = __stackBase__; + var $cmp = ($strm | 0) == 0; + $_$2 : do { + if ($cmp) { + var $retval_0 = -2; + } else { + var $0 = HEAPU32[($strm + 28 | 0) >> 2]; + if (($0 | 0) == 0) { + var $retval_0 = -2; + break; + } + var $next_out = $strm + 12 | 0; + var $1 = HEAP32[$next_out >> 2]; + if (($1 | 0) == 0) { + var $retval_0 = -2; + break; + } + var $next_in = $strm | 0; + var $2 = HEAP32[$next_in >> 2]; + if (($2 | 0) == 0) { + if (!((HEAP32[($strm + 4 | 0) >> 2] | 0) == 0)) { + var $retval_0 = -2; + break; + } + } + var $4 = $0; + var $mode = $0 | 0; + var $5 = HEAP32[$mode >> 2]; + if (($5 | 0) == 11) { + HEAP32[$mode >> 2] = 12; + var $8 = HEAP32[$next_out >> 2]; + var $7 = HEAP32[$next_in >> 2]; + var $6 = 12; + } else { + var $8 = $1; + var $7 = $2; + var $6 = $5; + } + var $6; + var $7; + var $8; + var $avail_out = $strm + 16 | 0; + var $9 = HEAP32[$avail_out >> 2]; + var $avail_in15 = $strm + 4 | 0; + var $10 = HEAPU32[$avail_in15 >> 2]; + var $11 = $0 + 56 | 0; + var $13 = $0 + 60 | 0; + var $15 = $0 + 8 | 0; + var $16 = $0 + 24 | 0; + var $arrayidx = $hbuf | 0; + var $arrayidx40 = $hbuf + 1 | 0; + var $17 = $0 + 16 | 0; + var $18 = $0 + 32 | 0; + var $msg = $strm + 24 | 0; + var $19 = $0 + 36 | 0; + var $20 = $0 + 20 | 0; + var $adler = $strm + 48 | 0; + var $21 = $0 + 64 | 0; + var $22 = $0 + 12 | 0; + var $23 = ($flush - 5 | 0) >>> 0 < 2; + var $24 = $0 + 4 | 0; + var $cmp660 = ($flush | 0) == 6; + var $25 = $0 + 7108 | 0; + var $26 = $0 + 84 | 0; + var $27 = $0 + 76 | 0; + var $28 = $0 + 72 | 0; + var $29 = $0 + 7112 | 0; + var $30 = $0 + 68 | 0; + var $31 = $0 + 44 | 0; + var $32 = $0 + 7104 | 0; + var $33 = $0 + 48 | 0; + var $34 = $0 + 52 | 0; + var $35 = $0 + 40 | 0; + var $total_out = $strm + 20 | 0; + var $36 = $0 + 28 | 0; + var $arrayidx199 = $hbuf + 2 | 0; + var $arrayidx202 = $hbuf + 3 | 0; + var $37 = $0 + 96 | 0; + var $38 = $0 + 100 | 0; + var $39 = $0 + 92 | 0; + var $40 = $0 + 104 | 0; + var $lens = $0 + 112 | 0; + var $41 = $lens; + var $next861 = $0 + 108 | 0; + var $42 = $next861; + var $43 = $next861 | 0; + var $arraydecay860_c = $0 + 1328 | 0; + var $44 = $0 + 76 | 0; + var $arraydecay864 = $lens; + var $arraydecay867 = $0 + 752 | 0; + var $45 = $0 + 624 | 0; + var $46 = $0 + 80 | 0; + var $47 = $0 + 88 | 0; + var $48 = $0 + 80 | 0; + var $ret_0 = 0; + var $next_0 = $7; + var $put_0 = $8; + var $have_0 = $10; + var $left_0 = $9; + var $hold_0 = HEAP32[$11 >> 2]; + var $bits_0 = HEAP32[$13 >> 2]; + var $out_0 = $9; + var $49 = $6; + $_$12 : while (1) { + var $49; + var $out_0; + var $bits_0; + var $hold_0; + var $left_0; + var $have_0; + var $put_0; + var $next_0; + var $ret_0; + $_$14 : do { + if (($49 | 0) == 0) { + var $50 = HEAPU32[$15 >> 2]; + if (($50 | 0) == 0) { + HEAP32[$mode >> 2] = 12; + var $ret_0_be = $ret_0; + var $next_0_be = $next_0; + var $put_0_be = $put_0; + var $have_0_be = $have_0; + var $left_0_be = $left_0; + var $hold_0_be = $hold_0; + var $bits_0_be = $bits_0; + var $out_0_be = $out_0; + __label__ = 268; + break; + } + var $next_1 = $next_0; + var $have_1 = $have_0; + var $hold_1 = $hold_0; + var $bits_1 = $bits_0; + while (1) { + var $bits_1; + var $hold_1; + var $have_1; + var $next_1; + if (!($bits_1 >>> 0 < 16)) { + break; + } + if (($have_1 | 0) == 0) { + var $ret_8 = $ret_0; + var $next_58 = $next_1; + var $have_58 = 0; + var $hold_54 = $hold_1; + var $bits_54 = $bits_1; + var $out_4 = $out_0; + break $_$12; + } + var $add = ((HEAPU8[$next_1] & 255) << $bits_1) + $hold_1 | 0; + var $next_1 = $next_1 + 1 | 0; + var $have_1 = $have_1 - 1 | 0; + var $hold_1 = $add; + var $bits_1 = $bits_1 + 8 | 0; + } + if (($50 & 2 | 0) != 0 & ($hold_1 | 0) == 35615) { + var $call = _crc32(0, 0, 0); + HEAP32[$16 >> 2] = $call; + HEAP8[$arrayidx] = 31; + HEAP8[$arrayidx40] = -117; + var $52 = HEAP32[$16 >> 2]; + var $call42 = _crc32($52, $arrayidx, 2); + HEAP32[$16 >> 2] = $call42; + HEAP32[$mode >> 2] = 1; + var $ret_0_be = $ret_0; + var $next_0_be = $next_1; + var $put_0_be = $put_0; + var $have_0_be = $have_1; + var $left_0_be = $left_0; + var $hold_0_be = 0; + var $bits_0_be = 0; + var $out_0_be = $out_0; + __label__ = 268; + break; + } + HEAP32[$17 >> 2] = 0; + var $53 = HEAP32[$18 >> 2]; + if (($53 | 0) == 0) { + var $54 = $50; + } else { + var $done = $53 + 48 | 0; + HEAP32[$done >> 2] = -1; + var $54 = HEAP32[$15 >> 2]; + } + var $54; + var $tobool56 = ($54 & 1 | 0) == 0; + do { + if (!$tobool56) { + if (!((((($hold_1 << 8 & 65280) + ($hold_1 >>> 8) | 0) >>> 0) % 31 | 0) == 0)) { + break; + } + if (($hold_1 & 15 | 0) == 8) { + var $shr74 = $hold_1 >>> 4; + var $sub = $bits_1 - 4 | 0; + var $add77 = ($shr74 & 15) + 8 | 0; + var $55 = HEAPU32[$19 >> 2]; + var $cmp78 = ($55 | 0) == 0; + do { + if (!$cmp78) { + if (!($add77 >>> 0 > $55 >>> 0)) { + break; + } + HEAP32[$msg >> 2] = STRING_TABLE.__str3100 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $ret_0; + var $next_0_be = $next_1; + var $put_0_be = $put_0; + var $have_0_be = $have_1; + var $left_0_be = $left_0; + var $hold_0_be = $shr74; + var $bits_0_be = $sub; + var $out_0_be = $out_0; + __label__ = 268; + break $_$14; + } + HEAP32[$19 >> 2] = $add77; + } while (0); + HEAP32[$20 >> 2] = 1 << $add77; + var $call91 = _adler32(0, 0, 0); + HEAP32[$16 >> 2] = $call91; + HEAP32[$adler >> 2] = $call91; + HEAP32[$mode >> 2] = $hold_1 >>> 12 & 2 ^ 11; + var $ret_0_be = $ret_0; + var $next_0_be = $next_1; + var $put_0_be = $put_0; + var $have_0_be = $have_1; + var $left_0_be = $left_0; + var $hold_0_be = 0; + var $bits_0_be = 0; + var $out_0_be = $out_0; + __label__ = 268; + break $_$14; + } + HEAP32[$msg >> 2] = STRING_TABLE.__str299 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $ret_0; + var $next_0_be = $next_1; + var $put_0_be = $put_0; + var $have_0_be = $have_1; + var $left_0_be = $left_0; + var $hold_0_be = $hold_1; + var $bits_0_be = $bits_1; + var $out_0_be = $out_0; + __label__ = 268; + break $_$14; + } + } while (0); + HEAP32[$msg >> 2] = STRING_TABLE.__str198 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $ret_0; + var $next_0_be = $next_1; + var $put_0_be = $put_0; + var $have_0_be = $have_1; + var $left_0_be = $left_0; + var $hold_0_be = $hold_1; + var $bits_0_be = $bits_1; + var $out_0_be = $out_0; + __label__ = 268; + break; + } else if (($49 | 0) == 1) { + var $next_2 = $next_0; + var $have_2 = $have_0; + var $hold_2 = $hold_0; + var $bits_2 = $bits_0; + while (1) { + var $bits_2; + var $hold_2; + var $have_2; + var $next_2; + if (!($bits_2 >>> 0 < 16)) { + break; + } + if (($have_2 | 0) == 0) { + var $ret_8 = $ret_0; + var $next_58 = $next_2; + var $have_58 = 0; + var $hold_54 = $hold_2; + var $bits_54 = $bits_2; + var $out_4 = $out_0; + break $_$12; + } + var $add113 = ((HEAPU8[$next_2] & 255) << $bits_2) + $hold_2 | 0; + var $next_2 = $next_2 + 1 | 0; + var $have_2 = $have_2 - 1 | 0; + var $hold_2 = $add113; + var $bits_2 = $bits_2 + 8 | 0; + } + HEAP32[$17 >> 2] = $hold_2; + if (!(($hold_2 & 255 | 0) == 8)) { + HEAP32[$msg >> 2] = STRING_TABLE.__str299 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $ret_0; + var $next_0_be = $next_2; + var $put_0_be = $put_0; + var $have_0_be = $have_2; + var $left_0_be = $left_0; + var $hold_0_be = $hold_2; + var $bits_0_be = $bits_2; + var $out_0_be = $out_0; + __label__ = 268; + break; + } + if (($hold_2 & 57344 | 0) == 0) { + var $59 = HEAPU32[$18 >> 2]; + if (($59 | 0) == 0) { + var $60 = $hold_2; + } else { + HEAP32[($59 | 0) >> 2] = $hold_2 >>> 8 & 1; + var $60 = HEAP32[$17 >> 2]; + } + var $60; + if (!(($60 & 512 | 0) == 0)) { + HEAP8[$arrayidx] = $hold_2 & 255; + HEAP8[$arrayidx40] = $hold_2 >>> 8 & 255; + var $61 = HEAP32[$16 >> 2]; + var $call154 = _crc32($61, $arrayidx, 2); + HEAP32[$16 >> 2] = $call154; + } + HEAP32[$mode >> 2] = 2; + var $next_3 = $next_2; + var $have_3 = $have_2; + var $hold_3 = 0; + var $bits_3 = 0; + __label__ = 44; + break; + } + HEAP32[$msg >> 2] = STRING_TABLE.__str4101 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $ret_0; + var $next_0_be = $next_2; + var $put_0_be = $put_0; + var $have_0_be = $have_2; + var $left_0_be = $left_0; + var $hold_0_be = $hold_2; + var $bits_0_be = $bits_2; + var $out_0_be = $out_0; + __label__ = 268; + break; + } else if (($49 | 0) == 2) { + var $next_3 = $next_0; + var $have_3 = $have_0; + var $hold_3 = $hold_0; + var $bits_3 = $bits_0; + __label__ = 44; + } else if (($49 | 0) == 3) { + var $next_4 = $next_0; + var $have_4 = $have_0; + var $hold_4 = $hold_0; + var $bits_4 = $bits_0; + __label__ = 52; + } else if (($49 | 0) == 4) { + var $next_5 = $next_0; + var $have_5 = $have_0; + var $hold_5 = $hold_0; + var $bits_5 = $bits_0; + __label__ = 60; + } else if (($49 | 0) == 5) { + var $next_8 = $next_0; + var $have_8 = $have_0; + var $hold_8 = $hold_0; + var $bits_8 = $bits_0; + __label__ = 71; + } else if (($49 | 0) == 6) { + var $next_11 = $next_0; + var $have_11 = $have_0; + var $hold_9 = $hold_0; + var $bits_9 = $bits_0; + var $89 = HEAP32[$17 >> 2]; + __label__ = 81; + break; + } else if (($49 | 0) == 7) { + var $next_13 = $next_0; + var $have_13 = $have_0; + var $hold_10 = $hold_0; + var $bits_10 = $bits_0; + __label__ = 94; + } else if (($49 | 0) == 8) { + var $next_15 = $next_0; + var $have_15 = $have_0; + var $hold_11 = $hold_0; + var $bits_11 = $bits_0; + __label__ = 107; + } else if (($49 | 0) == 9) { + var $next_18 = $next_0; + var $have_18 = $have_0; + var $hold_14 = $hold_0; + var $bits_14 = $bits_0; + while (1) { + var $bits_14; + var $hold_14; + var $have_18; + var $next_18; + if (!($bits_14 >>> 0 < 32)) { + break; + } + if (($have_18 | 0) == 0) { + var $ret_8 = $ret_0; + var $next_58 = $next_18; + var $have_58 = 0; + var $hold_54 = $hold_14; + var $bits_54 = $bits_14; + var $out_4 = $out_0; + break $_$12; + } + var $add564 = ((HEAPU8[$next_18] & 255) << $bits_14) + $hold_14 | 0; + var $next_18 = $next_18 + 1 | 0; + var $have_18 = $have_18 - 1 | 0; + var $hold_14 = $add564; + var $bits_14 = $bits_14 + 8 | 0; + } + var $add581 = _llvm_bswap_i32($hold_14); + HEAP32[$16 >> 2] = $add581; + HEAP32[$adler >> 2] = $add581; + HEAP32[$mode >> 2] = 10; + var $next_19 = $next_18; + var $have_19 = $have_18; + var $hold_15 = 0; + var $bits_15 = 0; + __label__ = 120; + break; + } else if (($49 | 0) == 10) { + var $next_19 = $next_0; + var $have_19 = $have_0; + var $hold_15 = $hold_0; + var $bits_15 = $bits_0; + __label__ = 120; + } else if (($49 | 0) == 11) { + var $next_20 = $next_0; + var $have_20 = $have_0; + var $hold_16 = $hold_0; + var $bits_16 = $bits_0; + __label__ = 123; + } else if (($49 | 0) == 12) { + var $next_21 = $next_0; + var $have_21 = $have_0; + var $hold_17 = $hold_0; + var $bits_17 = $bits_0; + __label__ = 124; + } else if (($49 | 0) == 13) { + var $and681 = $bits_0 & 7; + var $next_23 = $next_0; + var $have_23 = $have_0; + var $hold_19 = $hold_0 >>> ($and681 >>> 0); + var $bits_19 = $bits_0 - $and681 | 0; + while (1) { + var $bits_19; + var $hold_19; + var $have_23; + var $next_23; + if (!($bits_19 >>> 0 < 32)) { + break; + } + if (($have_23 | 0) == 0) { + var $ret_8 = $ret_0; + var $next_58 = $next_23; + var $have_58 = 0; + var $hold_54 = $hold_19; + var $bits_54 = $bits_19; + var $out_4 = $out_0; + break $_$12; + } + var $add701 = ((HEAPU8[$next_23] & 255) << $bits_19) + $hold_19 | 0; + var $next_23 = $next_23 + 1 | 0; + var $have_23 = $have_23 - 1 | 0; + var $hold_19 = $add701; + var $bits_19 = $bits_19 + 8 | 0; + } + var $and708 = $hold_19 & 65535; + if (!(($and708 | 0) == ($hold_19 >>> 16 ^ 65535 | 0))) { + HEAP32[$msg >> 2] = STRING_TABLE.__str7104 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $ret_0; + var $next_0_be = $next_23; + var $put_0_be = $put_0; + var $have_0_be = $have_23; + var $left_0_be = $left_0; + var $hold_0_be = $hold_19; + var $bits_0_be = $bits_19; + var $out_0_be = $out_0; + __label__ = 268; + break; + } + HEAP32[$21 >> 2] = $and708; + HEAP32[$mode >> 2] = 14; + if ($cmp660) { + var $ret_8 = $ret_0; + var $next_58 = $next_23; + var $have_58 = $have_23; + var $hold_54 = 0; + var $bits_54 = 0; + var $out_4 = $out_0; + break $_$12; + } + var $next_24 = $next_23; + var $have_24 = $have_23; + var $hold_20 = 0; + var $bits_20 = 0; + __label__ = 143; + break; + } else if (($49 | 0) == 14) { + var $next_24 = $next_0; + var $have_24 = $have_0; + var $hold_20 = $hold_0; + var $bits_20 = $bits_0; + __label__ = 143; + } else if (($49 | 0) == 15) { + var $next_25 = $next_0; + var $have_25 = $have_0; + var $hold_21 = $hold_0; + var $bits_21 = $bits_0; + __label__ = 144; + } else if (($49 | 0) == 16) { + var $next_26 = $next_0; + var $have_26 = $have_0; + var $hold_22 = $hold_0; + var $bits_22 = $bits_0; + while (1) { + var $bits_22; + var $hold_22; + var $have_26; + var $next_26; + if (!($bits_22 >>> 0 < 14)) { + break; + } + if (($have_26 | 0) == 0) { + var $ret_8 = $ret_0; + var $next_58 = $next_26; + var $have_58 = 0; + var $hold_54 = $hold_22; + var $bits_54 = $bits_22; + var $out_4 = $out_0; + break $_$12; + } + var $add767 = ((HEAPU8[$next_26] & 255) << $bits_22) + $hold_22 | 0; + var $next_26 = $next_26 + 1 | 0; + var $have_26 = $have_26 - 1 | 0; + var $hold_22 = $add767; + var $bits_22 = $bits_22 + 8 | 0; + } + var $add775 = ($hold_22 & 31) + 257 | 0; + HEAP32[$37 >> 2] = $add775; + var $add782 = ($hold_22 >>> 5 & 31) + 1 | 0; + HEAP32[$38 >> 2] = $add782; + HEAP32[$39 >> 2] = ($hold_22 >>> 10 & 15) + 4 | 0; + var $shr791 = $hold_22 >>> 14; + var $sub792 = $bits_22 - 14 | 0; + if ($add775 >>> 0 > 286 | $add782 >>> 0 > 30) { + HEAP32[$msg >> 2] = STRING_TABLE.__str8105 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $ret_0; + var $next_0_be = $next_26; + var $put_0_be = $put_0; + var $have_0_be = $have_26; + var $left_0_be = $left_0; + var $hold_0_be = $shr791; + var $bits_0_be = $sub792; + var $out_0_be = $out_0; + __label__ = 268; + break; + } + HEAP32[$40 >> 2] = 0; + HEAP32[$mode >> 2] = 17; + var $next_27 = $next_26; + var $have_27 = $have_26; + var $hold_23 = $shr791; + var $bits_23 = $sub792; + __label__ = 154; + break; + } else if (($49 | 0) == 17) { + var $next_27 = $next_0; + var $have_27 = $have_0; + var $hold_23 = $hold_0; + var $bits_23 = $bits_0; + __label__ = 154; + } else if (($49 | 0) == 18) { + var $ret_1_ph = $ret_0; + var $next_29_ph = $next_0; + var $have_29_ph = $have_0; + var $hold_25_ph = $hold_0; + var $bits_25_ph = $bits_0; + __label__ = 164; + } else if (($49 | 0) == 19) { + var $ret_2 = $ret_0; + var $next_37 = $next_0; + var $have_37 = $have_0; + var $hold_33 = $hold_0; + var $bits_33 = $bits_0; + __label__ = 205; + } else if (($49 | 0) == 20) { + var $ret_3 = $ret_0; + var $next_38 = $next_0; + var $have_38 = $have_0; + var $hold_34 = $hold_0; + var $bits_34 = $bits_0; + __label__ = 206; + } else if (($49 | 0) == 21) { + var $ret_4 = $ret_0; + var $next_42 = $next_0; + var $have_42 = $have_0; + var $hold_38 = $hold_0; + var $bits_38 = $bits_0; + var $156 = HEAP32[$28 >> 2]; + __label__ = 227; + break; + } else if (($49 | 0) == 22) { + var $ret_5_ph = $ret_0; + var $next_45_ph = $next_0; + var $have_45_ph = $have_0; + var $hold_41_ph = $hold_0; + var $bits_41_ph = $bits_0; + __label__ = 234; + } else if (($49 | 0) == 23) { + var $ret_6 = $ret_0; + var $next_48 = $next_0; + var $have_48 = $have_0; + var $hold_44 = $hold_0; + var $bits_44 = $bits_0; + var $167 = HEAP32[$28 >> 2]; + __label__ = 248; + break; + } else if (($49 | 0) == 24) { + var $ret_7 = $ret_0; + var $next_51 = $next_0; + var $have_51 = $have_0; + var $hold_47 = $hold_0; + var $bits_47 = $bits_0; + __label__ = 254; + } else if (($49 | 0) == 25) { + if (($left_0 | 0) == 0) { + var $ret_8 = $ret_0; + var $next_58 = $next_0; + var $have_58 = $have_0; + var $hold_54 = $hold_0; + var $bits_54 = $bits_0; + var $out_4 = $out_0; + break $_$12; + } + HEAP8[$put_0] = HEAP32[$21 >> 2] & 255; + HEAP32[$mode >> 2] = 20; + var $ret_0_be = $ret_0; + var $next_0_be = $next_0; + var $put_0_be = $put_0 + 1 | 0; + var $have_0_be = $have_0; + var $left_0_be = $left_0 - 1 | 0; + var $hold_0_be = $hold_0; + var $bits_0_be = $bits_0; + var $out_0_be = $out_0; + __label__ = 268; + break; + } else if (($49 | 0) == 26) { + var $tobool1626 = (HEAP32[$15 >> 2] | 0) == 0; + do { + if (!$tobool1626) { + var $next_52 = $next_0; + var $have_52 = $have_0; + var $hold_48 = $hold_0; + var $bits_48 = $bits_0; + while (1) { + var $bits_48; + var $hold_48; + var $have_52; + var $next_52; + if (!($bits_48 >>> 0 < 32)) { + break; + } + if (($have_52 | 0) == 0) { + var $ret_8 = $ret_0; + var $next_58 = $next_52; + var $have_58 = 0; + var $hold_54 = $hold_48; + var $bits_54 = $bits_48; + var $out_4 = $out_0; + break $_$12; + } + var $add1642 = ((HEAPU8[$next_52] & 255) << $bits_48) + $hold_48 | 0; + var $next_52 = $next_52 + 1 | 0; + var $have_52 = $have_52 - 1 | 0; + var $hold_48 = $add1642; + var $bits_48 = $bits_48 + 8 | 0; + } + var $sub1649 = $out_0 - $left_0 | 0; + var $add1650 = HEAP32[$total_out >> 2] + $sub1649 | 0; + HEAP32[$total_out >> 2] = $add1650; + var $add1651 = HEAP32[$36 >> 2] + $sub1649 | 0; + HEAP32[$36 >> 2] = $add1651; + if (!(($out_0 | 0) == ($left_0 | 0))) { + var $192 = HEAP32[$16 >> 2]; + var $add_ptr1659 = $put_0 + (-$sub1649 | 0) | 0; + if ((HEAP32[$17 >> 2] | 0) == 0) { + var $call1665 = _adler32($192, $add_ptr1659, $sub1649); + var $cond1667 = $call1665; + } else { + var $call1660 = _crc32($192, $add_ptr1659, $sub1649); + var $cond1667 = $call1660; + } + var $cond1667; + HEAP32[$16 >> 2] = $cond1667; + HEAP32[$adler >> 2] = $cond1667; + } + if ((HEAP32[$17 >> 2] | 0) == 0) { + var $add1685 = _llvm_bswap_i32($hold_48); + var $cond1687 = $add1685; + } else { + var $cond1687 = $hold_48; + } + var $cond1687; + if (($cond1687 | 0) == (HEAP32[$16 >> 2] | 0)) { + var $next_53 = $next_52; + var $have_53 = $have_52; + var $hold_49 = 0; + var $bits_49 = 0; + var $out_1 = $left_0; + break; + } + HEAP32[$msg >> 2] = STRING_TABLE.__str17114 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $ret_0; + var $next_0_be = $next_52; + var $put_0_be = $put_0; + var $have_0_be = $have_52; + var $left_0_be = $left_0; + var $hold_0_be = $hold_48; + var $bits_0_be = $bits_48; + var $out_0_be = $left_0; + __label__ = 268; + break $_$14; + } + var $next_53 = $next_0; + var $have_53 = $have_0; + var $hold_49 = $hold_0; + var $bits_49 = $bits_0; + var $out_1 = $out_0; + } while (0); + var $out_1; + var $bits_49; + var $hold_49; + var $have_53; + var $next_53; + HEAP32[$mode >> 2] = 27; + var $next_54 = $next_53; + var $have_54 = $have_53; + var $hold_50 = $hold_49; + var $bits_50 = $bits_49; + var $out_2 = $out_1; + __label__ = 286; + break; + } else if (($49 | 0) == 27) { + var $next_54 = $next_0; + var $have_54 = $have_0; + var $hold_50 = $hold_0; + var $bits_50 = $bits_0; + var $out_2 = $out_0; + __label__ = 286; + } else if (($49 | 0) == 28) { + var $ret_8 = 1; + var $next_58 = $next_0; + var $have_58 = $have_0; + var $hold_54 = $hold_0; + var $bits_54 = $bits_0; + var $out_4 = $out_0; + break $_$12; + } else if (($49 | 0) == 29) { + var $ret_8 = -3; + var $next_58 = $next_0; + var $have_58 = $have_0; + var $hold_54 = $hold_0; + var $bits_54 = $bits_0; + var $out_4 = $out_0; + break $_$12; + } else if (($49 | 0) == 30) { + var $retval_0 = -4; + break $_$2; + } else { + var $retval_0 = -2; + break $_$2; + } + } while (0); + $_$106 : do { + if (__label__ == 44) { + while (1) { + var $bits_3; + var $hold_3; + var $have_3; + var $next_3; + if (!($bits_3 >>> 0 < 32)) { + break; + } + if (($have_3 | 0) == 0) { + var $ret_8 = $ret_0; + var $next_58 = $next_3; + var $have_58 = 0; + var $hold_54 = $hold_3; + var $bits_54 = $bits_3; + var $out_4 = $out_0; + break $_$12; + } + var $add176 = ((HEAPU8[$next_3] & 255) << $bits_3) + $hold_3 | 0; + var $next_3 = $next_3 + 1 | 0; + var $have_3 = $have_3 - 1 | 0; + var $hold_3 = $add176; + var $bits_3 = $bits_3 + 8 | 0; + } + var $63 = HEAP32[$18 >> 2]; + if (!(($63 | 0) == 0)) { + var $time = $63 + 4 | 0; + HEAP32[$time >> 2] = $hold_3; + } + if (!((HEAP32[$17 >> 2] & 512 | 0) == 0)) { + HEAP8[$arrayidx] = $hold_3 & 255; + HEAP8[$arrayidx40] = $hold_3 >>> 8 & 255; + HEAP8[$arrayidx199] = $hold_3 >>> 16 & 255; + HEAP8[$arrayidx202] = $hold_3 >>> 24 & 255; + var $65 = HEAP32[$16 >> 2]; + var $call205 = _crc32($65, $arrayidx, 4); + HEAP32[$16 >> 2] = $call205; + } + HEAP32[$mode >> 2] = 3; + var $next_4 = $next_3; + var $have_4 = $have_3; + var $hold_4 = 0; + var $bits_4 = 0; + __label__ = 52; + break; + } else if (__label__ == 120) { + var $bits_15; + var $hold_15; + var $have_19; + var $next_19; + if ((HEAP32[$22 >> 2] | 0) == 0) { + HEAP32[$next_out >> 2] = $put_0; + HEAP32[$avail_out >> 2] = $left_0; + HEAP32[$next_in >> 2] = $next_19; + HEAP32[$avail_in15 >> 2] = $have_19; + HEAP32[$11 >> 2] = $hold_15; + HEAP32[$13 >> 2] = $bits_15; + var $retval_0 = 2; + break $_$2; + } + var $call602 = _adler32(0, 0, 0); + HEAP32[$16 >> 2] = $call602; + HEAP32[$adler >> 2] = $call602; + HEAP32[$mode >> 2] = 11; + var $next_20 = $next_19; + var $have_20 = $have_19; + var $hold_16 = $hold_15; + var $bits_16 = $bits_15; + __label__ = 123; + break; + } else if (__label__ == 143) { + var $bits_20; + var $hold_20; + var $have_24; + var $next_24; + HEAP32[$mode >> 2] = 15; + var $next_25 = $next_24; + var $have_25 = $have_24; + var $hold_21 = $hold_20; + var $bits_21 = $bits_20; + __label__ = 144; + break; + } else if (__label__ == 154) { + while (1) { + var $bits_23; + var $hold_23; + var $have_27; + var $next_27; + var $122 = HEAPU32[$40 >> 2]; + if (!($122 >>> 0 < HEAPU32[$39 >> 2] >>> 0)) { + break; + } + var $next_28 = $next_27; + var $have_28 = $have_27; + var $hold_24 = $hold_23; + var $bits_24 = $bits_23; + while (1) { + var $bits_24; + var $hold_24; + var $have_28; + var $next_28; + if (!($bits_24 >>> 0 < 3)) { + break; + } + if (($have_28 | 0) == 0) { + var $ret_8 = $ret_0; + var $next_58 = $next_28; + var $have_58 = 0; + var $hold_54 = $hold_24; + var $bits_54 = $bits_24; + var $out_4 = $out_0; + break $_$12; + } + var $add829 = ((HEAPU8[$next_28] & 255) << $bits_24) + $hold_24 | 0; + var $next_28 = $next_28 + 1 | 0; + var $have_28 = $have_28 - 1 | 0; + var $hold_24 = $add829; + var $bits_24 = $bits_24 + 8 | 0; + } + HEAP32[$40 >> 2] = $122 + 1 | 0; + HEAP16[($41 + ((HEAPU16[(_inflate_order + ($122 << 1) | 0) >> 1] & 65535) << 1) | 0) >> 1] = $hold_24 & 65535 & 7; + var $next_27 = $next_28; + var $have_27 = $have_28; + var $hold_23 = $hold_24 >>> 3; + var $bits_23 = $bits_24 - 3 | 0; + } + var $cmp850111 = $122 >>> 0 < 19; + $_$131 : do { + if ($cmp850111) { + var $126 = $122; + while (1) { + var $126; + HEAP32[$40 >> 2] = $126 + 1 | 0; + HEAP16[($41 + ((HEAPU16[(_inflate_order + ($126 << 1) | 0) >> 1] & 65535) << 1) | 0) >> 1] = 0; + var $_pr = HEAPU32[$40 >> 2]; + if (!($_pr >>> 0 < 19)) { + break $_$131; + } + var $126 = $_pr; + } + } + } while (0); + HEAP32[$43 >> 2] = $arraydecay860_c; + HEAP32[$44 >> 2] = $arraydecay860_c; + HEAP32[$26 >> 2] = 7; + var $call868 = _inflate_table(0, $arraydecay864, 19, $42, $26, $arraydecay867); + if (($call868 | 0) == 0) { + HEAP32[$40 >> 2] = 0; + HEAP32[$mode >> 2] = 18; + var $ret_1_ph = 0; + var $next_29_ph = $next_27; + var $have_29_ph = $have_27; + var $hold_25_ph = $hold_23; + var $bits_25_ph = $bits_23; + __label__ = 164; + break; + } + HEAP32[$msg >> 2] = STRING_TABLE.__str9106 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $call868; + var $next_0_be = $next_27; + var $put_0_be = $put_0; + var $have_0_be = $have_27; + var $left_0_be = $left_0; + var $hold_0_be = $hold_23; + var $bits_0_be = $bits_23; + var $out_0_be = $out_0; + __label__ = 268; + break; + } else if (__label__ == 286) { + var $out_2; + var $bits_50; + var $hold_50; + var $have_54; + var $next_54; + var $tobool1702 = (HEAP32[$15 >> 2] | 0) == 0; + do { + if (!$tobool1702) { + if ((HEAP32[$17 >> 2] | 0) == 0) { + var $next_56 = $next_54; + var $have_56 = $have_54; + var $hold_52 = $hold_50; + var $bits_52 = $bits_50; + break; + } + var $next_55 = $next_54; + var $have_55 = $have_54; + var $hold_51 = $hold_50; + var $bits_51 = $bits_50; + while (1) { + var $bits_51; + var $hold_51; + var $have_55; + var $next_55; + if (!($bits_51 >>> 0 < 32)) { + break; + } + if (($have_55 | 0) == 0) { + var $ret_8 = $ret_0; + var $next_58 = $next_55; + var $have_58 = 0; + var $hold_54 = $hold_51; + var $bits_54 = $bits_51; + var $out_4 = $out_2; + break $_$12; + } + var $add1721 = ((HEAPU8[$next_55] & 255) << $bits_51) + $hold_51 | 0; + var $next_55 = $next_55 + 1 | 0; + var $have_55 = $have_55 - 1 | 0; + var $hold_51 = $add1721; + var $bits_51 = $bits_51 + 8 | 0; + } + if (($hold_51 | 0) == (HEAP32[$36 >> 2] | 0)) { + var $next_56 = $next_55; + var $have_56 = $have_55; + var $hold_52 = 0; + var $bits_52 = 0; + break; + } + HEAP32[$msg >> 2] = STRING_TABLE.__str18115 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $ret_0; + var $next_0_be = $next_55; + var $put_0_be = $put_0; + var $have_0_be = $have_55; + var $left_0_be = $left_0; + var $hold_0_be = $hold_51; + var $bits_0_be = $bits_51; + var $out_0_be = $out_2; + __label__ = 268; + break $_$106; + } + var $next_56 = $next_54; + var $have_56 = $have_54; + var $hold_52 = $hold_50; + var $bits_52 = $bits_50; + } while (0); + var $bits_52; + var $hold_52; + var $have_56; + var $next_56; + HEAP32[$mode >> 2] = 28; + var $ret_8 = 1; + var $next_58 = $next_56; + var $have_58 = $have_56; + var $hold_54 = $hold_52; + var $bits_54 = $bits_52; + var $out_4 = $out_2; + break $_$12; + } + } while (0); + $_$148 : do { + if (__label__ == 52) { + while (1) { + var $bits_4; + var $hold_4; + var $have_4; + var $next_4; + if (!($bits_4 >>> 0 < 16)) { + break; + } + if (($have_4 | 0) == 0) { + var $ret_8 = $ret_0; + var $next_58 = $next_4; + var $have_58 = 0; + var $hold_54 = $hold_4; + var $bits_54 = $bits_4; + var $out_4 = $out_0; + break $_$12; + } + var $add227 = ((HEAPU8[$next_4] & 255) << $bits_4) + $hold_4 | 0; + var $next_4 = $next_4 + 1 | 0; + var $have_4 = $have_4 - 1 | 0; + var $hold_4 = $add227; + var $bits_4 = $bits_4 + 8 | 0; + } + var $67 = HEAP32[$18 >> 2]; + if (!(($67 | 0) == 0)) { + var $xflags = $67 + 8 | 0; + HEAP32[$xflags >> 2] = $hold_4 & 255; + var $os = HEAP32[$18 >> 2] + 12 | 0; + HEAP32[$os >> 2] = $hold_4 >>> 8; + } + if (!((HEAP32[$17 >> 2] & 512 | 0) == 0)) { + HEAP8[$arrayidx] = $hold_4 & 255; + HEAP8[$arrayidx40] = $hold_4 >>> 8 & 255; + var $70 = HEAP32[$16 >> 2]; + var $call253 = _crc32($70, $arrayidx, 2); + HEAP32[$16 >> 2] = $call253; + } + HEAP32[$mode >> 2] = 4; + var $next_5 = $next_4; + var $have_5 = $have_4; + var $hold_5 = 0; + var $bits_5 = 0; + __label__ = 60; + break; + } else if (__label__ == 123) { + var $bits_16; + var $hold_16; + var $have_20; + var $next_20; + if ($23) { + var $ret_8 = $ret_0; + var $next_58 = $next_20; + var $have_58 = $have_20; + var $hold_54 = $hold_16; + var $bits_54 = $bits_16; + var $out_4 = $out_0; + break $_$12; + } + var $next_21 = $next_20; + var $have_21 = $have_20; + var $hold_17 = $hold_16; + var $bits_17 = $bits_16; + __label__ = 124; + break; + } else if (__label__ == 144) { + var $bits_21; + var $hold_21; + var $have_25; + var $next_25; + var $119 = HEAPU32[$21 >> 2]; + if (($119 | 0) == 0) { + HEAP32[$mode >> 2] = 11; + var $ret_0_be = $ret_0; + var $next_0_be = $next_25; + var $put_0_be = $put_0; + var $have_0_be = $have_25; + var $left_0_be = $left_0; + var $hold_0_be = $hold_21; + var $bits_0_be = $bits_21; + var $out_0_be = $out_0; + __label__ = 268; + break; + } + var $copy_3 = $119 >>> 0 > $have_25 >>> 0 ? $have_25 : $119; + var $copy_4 = $copy_3 >>> 0 > $left_0 >>> 0 ? $left_0 : $copy_3; + if (($copy_4 | 0) == 0) { + var $ret_8 = $ret_0; + var $next_58 = $next_25; + var $have_58 = $have_25; + var $hold_54 = $hold_21; + var $bits_54 = $bits_21; + var $out_4 = $out_0; + break $_$12; + } + _memcpy($put_0, $next_25, $copy_4, 1); + var $sub744 = $have_25 - $copy_4 | 0; + var $add_ptr745 = $next_25 + $copy_4 | 0; + var $sub746 = $left_0 - $copy_4 | 0; + var $add_ptr747 = $put_0 + $copy_4 | 0; + var $sub749 = HEAP32[$21 >> 2] - $copy_4 | 0; + HEAP32[$21 >> 2] = $sub749; + var $ret_0_be = $ret_0; + var $next_0_be = $add_ptr745; + var $put_0_be = $add_ptr747; + var $have_0_be = $sub744; + var $left_0_be = $sub746; + var $hold_0_be = $hold_21; + var $bits_0_be = $bits_21; + var $out_0_be = $out_0; + __label__ = 268; + break; + } else if (__label__ == 164) { + var $bits_25_ph; + var $hold_25_ph; + var $have_29_ph; + var $next_29_ph; + var $ret_1_ph; + var $next_29 = $next_29_ph; + var $have_29 = $have_29_ph; + var $hold_25 = $hold_25_ph; + var $bits_25 = $bits_25_ph; + $_$167 : while (1) { + var $bits_25; + var $hold_25; + var $have_29; + var $next_29; + var $128 = HEAPU32[$40 >> 2]; + var $129 = HEAPU32[$37 >> 2]; + var $add881 = HEAP32[$38 >> 2] + $129 | 0; + if ($128 >>> 0 < $add881 >>> 0) { + var $sub888 = (1 << HEAP32[$26 >> 2]) - 1 | 0; + var $132 = HEAPU32[$27 >> 2]; + var $next_30 = $next_29; + var $have_30 = $have_29; + var $hold_26 = $hold_25; + var $bits_26 = $bits_25; + while (1) { + var $bits_26; + var $hold_26; + var $have_30; + var $next_30; + var $and889 = $sub888 & $hold_26; + var $conv893 = HEAPU8[$132 + ($and889 << 2) + 1 | 0] & 255; + if (!($conv893 >>> 0 > $bits_26 >>> 0)) { + break; + } + if (($have_30 | 0) == 0) { + var $ret_8 = $ret_1_ph; + var $next_58 = $next_30; + var $have_58 = 0; + var $hold_54 = $hold_26; + var $bits_54 = $bits_26; + var $out_4 = $out_0; + break $_$12; + } + var $add907 = ((HEAPU8[$next_30] & 255) << $bits_26) + $hold_26 | 0; + var $next_30 = $next_30 + 1 | 0; + var $have_30 = $have_30 - 1 | 0; + var $hold_26 = $add907; + var $bits_26 = $bits_26 + 8 | 0; + } + var $tmp26 = HEAPU16[($132 + ($and889 << 2) + 2 | 0) >> 1]; + if (($tmp26 & 65535) < 16) { + var $next_31 = $next_30; + var $have_31 = $have_30; + var $hold_27 = $hold_26; + var $bits_27 = $bits_26; + while (1) { + var $bits_27; + var $hold_27; + var $have_31; + var $next_31; + if (!($bits_27 >>> 0 < $conv893 >>> 0)) { + break; + } + if (($have_31 | 0) == 0) { + var $ret_8 = $ret_1_ph; + var $next_58 = $next_31; + var $have_58 = 0; + var $hold_54 = $hold_27; + var $bits_54 = $bits_27; + var $out_4 = $out_0; + break $_$12; + } + var $add931 = ((HEAPU8[$next_31] & 255) << $bits_27) + $hold_27 | 0; + var $next_31 = $next_31 + 1 | 0; + var $have_31 = $have_31 - 1 | 0; + var $hold_27 = $add931; + var $bits_27 = $bits_27 + 8 | 0; + } + var $shr941 = $hold_27 >>> ($conv893 >>> 0); + var $sub944 = $bits_27 - $conv893 | 0; + HEAP32[$40 >> 2] = $128 + 1 | 0; + HEAP16[($41 + ($128 << 1) | 0) >> 1] = $tmp26; + var $next_29 = $next_31; + var $have_29 = $have_31; + var $hold_25 = $shr941; + var $bits_25 = $sub944; + } else { + if ($tmp26 << 16 >> 16 == 16) { + var $add962 = $conv893 + 2 | 0; + var $next_32 = $next_30; + var $have_32 = $have_30; + var $hold_28 = $hold_26; + var $bits_28 = $bits_26; + while (1) { + var $bits_28; + var $hold_28; + var $have_32; + var $next_32; + if (!($bits_28 >>> 0 < $add962 >>> 0)) { + break; + } + if (($have_32 | 0) == 0) { + var $ret_8 = $ret_1_ph; + var $next_58 = $next_32; + var $have_58 = 0; + var $hold_54 = $hold_28; + var $bits_54 = $bits_28; + var $out_4 = $out_0; + break $_$12; + } + var $add975 = ((HEAPU8[$next_32] & 255) << $bits_28) + $hold_28 | 0; + var $next_32 = $next_32 + 1 | 0; + var $have_32 = $have_32 - 1 | 0; + var $hold_28 = $add975; + var $bits_28 = $bits_28 + 8 | 0; + } + var $shr985 = $hold_28 >>> ($conv893 >>> 0); + var $sub988 = $bits_28 - $conv893 | 0; + if (($128 | 0) == 0) { + HEAP32[$msg >> 2] = STRING_TABLE.__str10107 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $ret_1_ph; + var $next_0_be = $next_32; + var $put_0_be = $put_0; + var $have_0_be = $have_32; + var $left_0_be = $left_0; + var $hold_0_be = $shr985; + var $bits_0_be = $sub988; + var $out_0_be = $out_0; + __label__ = 268; + break $_$148; + } + var $len_0 = HEAP16[($41 + (($128 - 1 | 0) << 1) | 0) >> 1]; + var $next_35 = $next_32; + var $have_35 = $have_32; + var $hold_31 = $shr985 >>> 2; + var $bits_31 = $sub988 - 2 | 0; + var $copy_5 = ($shr985 & 3) + 3 | 0; + } else if ($tmp26 << 16 >> 16 == 17) { + var $add1020 = $conv893 + 3 | 0; + var $next_33 = $next_30; + var $have_33 = $have_30; + var $hold_29 = $hold_26; + var $bits_29 = $bits_26; + while (1) { + var $bits_29; + var $hold_29; + var $have_33; + var $next_33; + if (!($bits_29 >>> 0 < $add1020 >>> 0)) { + break; + } + if (($have_33 | 0) == 0) { + var $ret_8 = $ret_1_ph; + var $next_58 = $next_33; + var $have_58 = 0; + var $hold_54 = $hold_29; + var $bits_54 = $bits_29; + var $out_4 = $out_0; + break $_$12; + } + var $add1033 = ((HEAPU8[$next_33] & 255) << $bits_29) + $hold_29 | 0; + var $next_33 = $next_33 + 1 | 0; + var $have_33 = $have_33 - 1 | 0; + var $hold_29 = $add1033; + var $bits_29 = $bits_29 + 8 | 0; + } + var $shr1043 = $hold_29 >>> ($conv893 >>> 0); + var $len_0 = 0; + var $next_35 = $next_33; + var $have_35 = $have_33; + var $hold_31 = $shr1043 >>> 3; + var $bits_31 = (-3 - $conv893 | 0) + $bits_29 | 0; + var $copy_5 = ($shr1043 & 7) + 3 | 0; + } else { + var $add1061 = $conv893 + 7 | 0; + var $next_34 = $next_30; + var $have_34 = $have_30; + var $hold_30 = $hold_26; + var $bits_30 = $bits_26; + while (1) { + var $bits_30; + var $hold_30; + var $have_34; + var $next_34; + if (!($bits_30 >>> 0 < $add1061 >>> 0)) { + break; + } + if (($have_34 | 0) == 0) { + var $ret_8 = $ret_1_ph; + var $next_58 = $next_34; + var $have_58 = 0; + var $hold_54 = $hold_30; + var $bits_54 = $bits_30; + var $out_4 = $out_0; + break $_$12; + } + var $add1074 = ((HEAPU8[$next_34] & 255) << $bits_30) + $hold_30 | 0; + var $next_34 = $next_34 + 1 | 0; + var $have_34 = $have_34 - 1 | 0; + var $hold_30 = $add1074; + var $bits_30 = $bits_30 + 8 | 0; + } + var $shr1084 = $hold_30 >>> ($conv893 >>> 0); + var $len_0 = 0; + var $next_35 = $next_34; + var $have_35 = $have_34; + var $hold_31 = $shr1084 >>> 7; + var $bits_31 = (-7 - $conv893 | 0) + $bits_30 | 0; + var $copy_5 = ($shr1084 & 127) + 11 | 0; + } + var $copy_5; + var $bits_31; + var $hold_31; + var $have_35; + var $next_35; + var $len_0; + if (($128 + $copy_5 | 0) >>> 0 > $add881 >>> 0) { + HEAP32[$msg >> 2] = STRING_TABLE.__str10107 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $ret_1_ph; + var $next_0_be = $next_35; + var $put_0_be = $put_0; + var $have_0_be = $have_35; + var $left_0_be = $left_0; + var $hold_0_be = $hold_31; + var $bits_0_be = $bits_31; + var $out_0_be = $out_0; + __label__ = 268; + break $_$148; + } + var $copy_6127 = $copy_5; + var $139 = $128; + while (1) { + var $139; + var $copy_6127; + var $dec1111 = $copy_6127 - 1 | 0; + HEAP32[$40 >> 2] = $139 + 1 | 0; + HEAP16[($41 + ($139 << 1) | 0) >> 1] = $len_0; + if (($dec1111 | 0) == 0) { + var $next_29 = $next_35; + var $have_29 = $have_35; + var $hold_25 = $hold_31; + var $bits_25 = $bits_31; + continue $_$167; + } + var $copy_6127 = $dec1111; + var $139 = HEAP32[$40 >> 2]; + } + } + } else { + if ((HEAP32[$mode >> 2] | 0) == 29) { + var $ret_0_be = $ret_1_ph; + var $next_0_be = $next_29; + var $put_0_be = $put_0; + var $have_0_be = $have_29; + var $left_0_be = $left_0; + var $hold_0_be = $hold_25; + var $bits_0_be = $bits_25; + var $out_0_be = $out_0; + __label__ = 268; + break $_$148; + } + if (HEAP16[$45 >> 1] << 16 >> 16 == 0) { + HEAP32[$msg >> 2] = STRING_TABLE.__str11108 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $ret_1_ph; + var $next_0_be = $next_29; + var $put_0_be = $put_0; + var $have_0_be = $have_29; + var $left_0_be = $left_0; + var $hold_0_be = $hold_25; + var $bits_0_be = $bits_25; + var $out_0_be = $out_0; + __label__ = 268; + break $_$148; + } + HEAP32[$43 >> 2] = $arraydecay860_c; + HEAP32[$44 >> 2] = $arraydecay860_c; + HEAP32[$26 >> 2] = 9; + var $call1149 = _inflate_table(1, $arraydecay864, $129, $42, $26, $arraydecay867); + if (!(($call1149 | 0) == 0)) { + HEAP32[$msg >> 2] = STRING_TABLE.__str12109 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $call1149; + var $next_0_be = $next_29; + var $put_0_be = $put_0; + var $have_0_be = $have_29; + var $left_0_be = $left_0; + var $hold_0_be = $hold_25; + var $bits_0_be = $bits_25; + var $out_0_be = $out_0; + __label__ = 268; + break $_$148; + } + var $_c = HEAP32[$42 >> 2]; + HEAP32[$46 >> 2] = $_c; + HEAP32[$47 >> 2] = 6; + var $add_ptr1159 = $arraydecay864 + (HEAP32[$37 >> 2] << 1) | 0; + var $143 = HEAP32[$38 >> 2]; + var $call1165 = _inflate_table(2, $add_ptr1159, $143, $42, $47, $arraydecay867); + if (!(($call1165 | 0) == 0)) { + HEAP32[$msg >> 2] = STRING_TABLE.__str13110 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $call1165; + var $next_0_be = $next_29; + var $put_0_be = $put_0; + var $have_0_be = $have_29; + var $left_0_be = $left_0; + var $hold_0_be = $hold_25; + var $bits_0_be = $bits_25; + var $out_0_be = $out_0; + __label__ = 268; + break $_$148; + } + HEAP32[$mode >> 2] = 19; + if ($cmp660) { + var $ret_8 = 0; + var $next_58 = $next_29; + var $have_58 = $have_29; + var $hold_54 = $hold_25; + var $bits_54 = $bits_25; + var $out_4 = $out_0; + break $_$12; + } + var $ret_2 = 0; + var $next_37 = $next_29; + var $have_37 = $have_29; + var $hold_33 = $hold_25; + var $bits_33 = $bits_25; + __label__ = 205; + break $_$148; + } + } + } + } while (0); + do { + if (__label__ == 60) { + var $bits_5; + var $hold_5; + var $have_5; + var $next_5; + var $71 = HEAPU32[$17 >> 2]; + var $tobool263 = ($71 & 1024 | 0) == 0; + do { + if ($tobool263) { + var $76 = HEAP32[$18 >> 2]; + if (($76 | 0) == 0) { + var $next_7 = $next_5; + var $have_7 = $have_5; + var $hold_7 = $hold_5; + var $bits_7 = $bits_5; + break; + } + var $extra = $76 + 16 | 0; + HEAP32[$extra >> 2] = 0; + var $next_7 = $next_5; + var $have_7 = $have_5; + var $hold_7 = $hold_5; + var $bits_7 = $bits_5; + } else { + var $next_6 = $next_5; + var $have_6 = $have_5; + var $hold_6 = $hold_5; + var $bits_6 = $bits_5; + while (1) { + var $bits_6; + var $hold_6; + var $have_6; + var $next_6; + if (!($bits_6 >>> 0 < 16)) { + break; + } + if (($have_6 | 0) == 0) { + var $ret_8 = $ret_0; + var $next_58 = $next_6; + var $have_58 = 0; + var $hold_54 = $hold_6; + var $bits_54 = $bits_6; + var $out_4 = $out_0; + break $_$12; + } + var $add279 = ((HEAPU8[$next_6] & 255) << $bits_6) + $hold_6 | 0; + var $next_6 = $next_6 + 1 | 0; + var $have_6 = $have_6 - 1 | 0; + var $hold_6 = $add279; + var $bits_6 = $bits_6 + 8 | 0; + } + HEAP32[$21 >> 2] = $hold_6; + var $73 = HEAP32[$18 >> 2]; + if (($73 | 0) == 0) { + var $74 = $71; + } else { + var $extra_len = $73 + 20 | 0; + HEAP32[$extra_len >> 2] = $hold_6; + var $74 = HEAP32[$17 >> 2]; + } + var $74; + if (($74 & 512 | 0) == 0) { + var $next_7 = $next_6; + var $have_7 = $have_6; + var $hold_7 = 0; + var $bits_7 = 0; + break; + } + HEAP8[$arrayidx] = $hold_6 & 255; + HEAP8[$arrayidx40] = $hold_6 >>> 8 & 255; + var $75 = HEAP32[$16 >> 2]; + var $call302 = _crc32($75, $arrayidx, 2); + HEAP32[$16 >> 2] = $call302; + var $next_7 = $next_6; + var $have_7 = $have_6; + var $hold_7 = 0; + var $bits_7 = 0; + } + } while (0); + var $bits_7; + var $hold_7; + var $have_7; + var $next_7; + HEAP32[$mode >> 2] = 5; + var $next_8 = $next_7; + var $have_8 = $have_7; + var $hold_8 = $hold_7; + var $bits_8 = $bits_7; + __label__ = 71; + break; + } else if (__label__ == 124) { + var $bits_17; + var $hold_17; + var $have_21; + var $next_21; + if ((HEAP32[$24 >> 2] | 0) == 0) { + var $next_22 = $next_21; + var $have_22 = $have_21; + var $hold_18 = $hold_17; + var $bits_18 = $bits_17; + while (1) { + var $bits_18; + var $hold_18; + var $have_22; + var $next_22; + if (!($bits_18 >>> 0 < 3)) { + break; + } + if (($have_22 | 0) == 0) { + var $ret_8 = $ret_0; + var $next_58 = $next_22; + var $have_58 = 0; + var $hold_54 = $hold_18; + var $bits_54 = $bits_18; + var $out_4 = $out_0; + break $_$12; + } + var $add641 = ((HEAPU8[$next_22] & 255) << $bits_18) + $hold_18 | 0; + var $next_22 = $next_22 + 1 | 0; + var $have_22 = $have_22 - 1 | 0; + var $hold_18 = $add641; + var $bits_18 = $bits_18 + 8 | 0; + } + HEAP32[$24 >> 2] = $hold_18 & 1; + var $and655 = $hold_18 >>> 1 & 3; + do { + if (($and655 | 0) == 0) { + HEAP32[$mode >> 2] = 13; + } else if (($and655 | 0) == 1) { + _fixedtables($4); + HEAP32[$mode >> 2] = 19; + if (!$cmp660) { + break; + } + var $ret_8 = $ret_0; + var $next_58 = $next_22; + var $have_58 = $have_22; + var $hold_54 = $hold_18 >>> 3; + var $bits_54 = $bits_18 - 3 | 0; + var $out_4 = $out_0; + break $_$12; + } else if (($and655 | 0) == 2) { + HEAP32[$mode >> 2] = 16; + } else if (($and655 | 0) == 3) { + HEAP32[$msg >> 2] = STRING_TABLE.__str6103 | 0; + HEAP32[$mode >> 2] = 29; + } + } while (0); + var $ret_0_be = $ret_0; + var $next_0_be = $next_22; + var $put_0_be = $put_0; + var $have_0_be = $have_22; + var $left_0_be = $left_0; + var $hold_0_be = $hold_18 >>> 3; + var $bits_0_be = $bits_18 - 3 | 0; + var $out_0_be = $out_0; + __label__ = 268; + break; + } + var $and619 = $bits_17 & 7; + HEAP32[$mode >> 2] = 26; + var $ret_0_be = $ret_0; + var $next_0_be = $next_21; + var $put_0_be = $put_0; + var $have_0_be = $have_21; + var $left_0_be = $left_0; + var $hold_0_be = $hold_17 >>> ($and619 >>> 0); + var $bits_0_be = $bits_17 - $and619 | 0; + var $out_0_be = $out_0; + __label__ = 268; + break; + } else if (__label__ == 205) { + var $bits_33; + var $hold_33; + var $have_37; + var $next_37; + var $ret_2; + HEAP32[$mode >> 2] = 20; + var $ret_3 = $ret_2; + var $next_38 = $next_37; + var $have_38 = $have_37; + var $hold_34 = $hold_33; + var $bits_34 = $bits_33; + __label__ = 206; + break; + } + } while (0); + do { + if (__label__ == 71) { + var $bits_8; + var $hold_8; + var $have_8; + var $next_8; + var $77 = HEAPU32[$17 >> 2]; + if (($77 & 1024 | 0) == 0) { + var $next_10 = $next_8; + var $have_10 = $have_8; + var $88 = $77; + } else { + var $78 = HEAPU32[$21 >> 2]; + var $copy_0 = $78 >>> 0 > $have_8 >>> 0 ? $have_8 : $78; + if (($copy_0 | 0) == 0) { + var $next_9 = $next_8; + var $have_9 = $have_8; + var $87 = $78; + var $86 = $77; + } else { + var $79 = HEAPU32[$18 >> 2]; + var $cmp330 = ($79 | 0) == 0; + do { + if ($cmp330) { + var $83 = $77; + } else { + var $80 = HEAP32[($79 + 16 | 0) >> 2]; + if (($80 | 0) == 0) { + var $83 = $77; + break; + } + var $sub341 = HEAP32[($79 + 20 | 0) >> 2] - $78 | 0; + var $add_ptr = $80 + $sub341 | 0; + var $82 = HEAPU32[($79 + 24 | 0) >> 2]; + var $cond351 = ($sub341 + $copy_0 | 0) >>> 0 > $82 >>> 0 ? $82 - $sub341 | 0 : $copy_0; + _memcpy($add_ptr, $next_8, $cond351, 1); + var $83 = HEAP32[$17 >> 2]; + } + } while (0); + var $83; + if (!(($83 & 512 | 0) == 0)) { + var $84 = HEAP32[$16 >> 2]; + var $call358 = _crc32($84, $next_8, $copy_0); + HEAP32[$16 >> 2] = $call358; + } + var $sub361 = $have_8 - $copy_0 | 0; + var $add_ptr362 = $next_8 + $copy_0 | 0; + var $sub364 = HEAP32[$21 >> 2] - $copy_0 | 0; + HEAP32[$21 >> 2] = $sub364; + var $next_9 = $add_ptr362; + var $have_9 = $sub361; + var $87 = $sub364; + var $86 = $83; + } + var $86; + var $87; + var $have_9; + var $next_9; + if (!(($87 | 0) == 0)) { + var $ret_8 = $ret_0; + var $next_58 = $next_9; + var $have_58 = $have_9; + var $hold_54 = $hold_8; + var $bits_54 = $bits_8; + var $out_4 = $out_0; + break $_$12; + } + var $next_10 = $next_9; + var $have_10 = $have_9; + var $88 = $86; + } + var $88; + var $have_10; + var $next_10; + HEAP32[$21 >> 2] = 0; + HEAP32[$mode >> 2] = 6; + var $next_11 = $next_10; + var $have_11 = $have_10; + var $hold_9 = $hold_8; + var $bits_9 = $bits_8; + var $89 = $88; + __label__ = 81; + break; + } else if (__label__ == 206) { + var $bits_34; + var $hold_34; + var $have_38; + var $next_38; + var $ret_3; + if ($have_38 >>> 0 > 5 & $left_0 >>> 0 > 257) { + HEAP32[$next_out >> 2] = $put_0; + HEAP32[$avail_out >> 2] = $left_0; + HEAP32[$next_in >> 2] = $next_38; + HEAP32[$avail_in15 >> 2] = $have_38; + HEAP32[$11 >> 2] = $hold_34; + HEAP32[$13 >> 2] = $bits_34; + _inflate_fast($strm, $out_0); + var $144 = HEAP32[$next_out >> 2]; + var $145 = HEAP32[$avail_out >> 2]; + var $146 = HEAP32[$next_in >> 2]; + var $147 = HEAP32[$avail_in15 >> 2]; + var $148 = HEAP32[$11 >> 2]; + var $149 = HEAP32[$13 >> 2]; + if (!((HEAP32[$mode >> 2] | 0) == 11)) { + var $ret_0_be = $ret_3; + var $next_0_be = $146; + var $put_0_be = $144; + var $have_0_be = $147; + var $left_0_be = $145; + var $hold_0_be = $148; + var $bits_0_be = $149; + var $out_0_be = $out_0; + __label__ = 268; + break; + } + HEAP32[$25 >> 2] = -1; + var $ret_0_be = $ret_3; + var $next_0_be = $146; + var $put_0_be = $144; + var $have_0_be = $147; + var $left_0_be = $145; + var $hold_0_be = $148; + var $bits_0_be = $149; + var $out_0_be = $out_0; + __label__ = 268; + break; + } + HEAP32[$25 >> 2] = 0; + var $sub1213 = (1 << HEAP32[$26 >> 2]) - 1 | 0; + var $152 = HEAPU32[$27 >> 2]; + var $next_39 = $next_38; + var $have_39 = $have_38; + var $hold_35 = $hold_34; + var $bits_35 = $bits_34; + while (1) { + var $bits_35; + var $hold_35; + var $have_39; + var $next_39; + var $and1214 = $sub1213 & $hold_35; + var $tmp22 = HEAPU8[$152 + ($and1214 << 2) + 1 | 0]; + var $conv1218 = $tmp22 & 255; + if (!($conv1218 >>> 0 > $bits_35 >>> 0)) { + break; + } + if (($have_39 | 0) == 0) { + var $ret_8 = $ret_3; + var $next_58 = $next_39; + var $have_58 = 0; + var $hold_54 = $hold_35; + var $bits_54 = $bits_35; + var $out_4 = $out_0; + break $_$12; + } + var $add1232 = ((HEAPU8[$next_39] & 255) << $bits_35) + $hold_35 | 0; + var $next_39 = $next_39 + 1 | 0; + var $have_39 = $have_39 - 1 | 0; + var $hold_35 = $add1232; + var $bits_35 = $bits_35 + 8 | 0; + } + var $tmp21 = HEAPU8[$152 + ($and1214 << 2) | 0]; + var $tmp23 = HEAPU16[($152 + ($and1214 << 2) + 2 | 0) >> 1]; + var $conv1237 = $tmp21 & 255; + var $tobool1238 = $tmp21 << 24 >> 24 == 0; + do { + if ($tobool1238) { + var $next_41 = $next_39; + var $have_41 = $have_39; + var $hold_37 = $hold_35; + var $bits_37 = $bits_35; + var $here_09_0 = 0; + var $here_110_0 = $tmp22; + var $here_211_0 = $tmp23; + var $155 = 0; + } else { + if (!(($conv1237 & 240 | 0) == 0)) { + var $next_41 = $next_39; + var $have_41 = $have_39; + var $hold_37 = $hold_35; + var $bits_37 = $bits_35; + var $here_09_0 = $tmp21; + var $here_110_0 = $tmp22; + var $here_211_0 = $tmp23; + var $155 = 0; + break; + } + var $conv1248 = $tmp23 & 65535; + var $sub1255 = (1 << ($conv1218 + $conv1237 | 0)) - 1 | 0; + var $next_40 = $next_39; + var $have_40 = $have_39; + var $hold_36 = $hold_35; + var $bits_36 = $bits_35; + while (1) { + var $bits_36; + var $hold_36; + var $have_40; + var $next_40; + var $add1260 = (($hold_36 & $sub1255) >>> ($conv1218 >>> 0)) + $conv1248 | 0; + var $tmp19 = HEAPU8[$152 + ($add1260 << 2) + 1 | 0]; + if (!((($tmp19 & 255) + $conv1218 | 0) >>> 0 > $bits_36 >>> 0)) { + break; + } + if (($have_40 | 0) == 0) { + var $ret_8 = $ret_3; + var $next_58 = $next_40; + var $have_58 = 0; + var $hold_54 = $hold_36; + var $bits_54 = $bits_36; + var $out_4 = $out_0; + break $_$12; + } + var $add1281 = ((HEAPU8[$next_40] & 255) << $bits_36) + $hold_36 | 0; + var $next_40 = $next_40 + 1 | 0; + var $have_40 = $have_40 - 1 | 0; + var $hold_36 = $add1281; + var $bits_36 = $bits_36 + 8 | 0; + } + var $tmp20 = HEAP16[($152 + ($add1260 << 2) + 2 | 0) >> 1]; + var $tmp18 = HEAP8[$152 + ($add1260 << 2) | 0]; + var $shr1289 = $hold_36 >>> ($conv1218 >>> 0); + var $sub1292 = $bits_36 - $conv1218 | 0; + HEAP32[$25 >> 2] = $conv1218; + var $next_41 = $next_40; + var $have_41 = $have_40; + var $hold_37 = $shr1289; + var $bits_37 = $sub1292; + var $here_09_0 = $tmp18; + var $here_110_0 = $tmp19; + var $here_211_0 = $tmp20; + var $155 = $conv1218; + } + } while (0); + var $155; + var $here_211_0; + var $here_110_0; + var $here_09_0; + var $bits_37; + var $hold_37; + var $have_41; + var $next_41; + var $conv1302 = $here_110_0 & 255; + var $shr1303 = $hold_37 >>> ($conv1302 >>> 0); + var $sub1306 = $bits_37 - $conv1302 | 0; + HEAP32[$25 >> 2] = $155 + $conv1302 | 0; + HEAP32[$21 >> 2] = $here_211_0 & 65535; + var $conv1317 = $here_09_0 & 255; + if ($here_09_0 << 24 >> 24 == 0) { + HEAP32[$mode >> 2] = 25; + var $ret_0_be = $ret_3; + var $next_0_be = $next_41; + var $put_0_be = $put_0; + var $have_0_be = $have_41; + var $left_0_be = $left_0; + var $hold_0_be = $shr1303; + var $bits_0_be = $sub1306; + var $out_0_be = $out_0; + __label__ = 268; + break; + } + if (!(($conv1317 & 32 | 0) == 0)) { + HEAP32[$25 >> 2] = -1; + HEAP32[$mode >> 2] = 11; + var $ret_0_be = $ret_3; + var $next_0_be = $next_41; + var $put_0_be = $put_0; + var $have_0_be = $have_41; + var $left_0_be = $left_0; + var $hold_0_be = $shr1303; + var $bits_0_be = $sub1306; + var $out_0_be = $out_0; + __label__ = 268; + break; + } + if (($conv1317 & 64 | 0) == 0) { + var $and1341 = $conv1317 & 15; + HEAP32[$28 >> 2] = $and1341; + HEAP32[$mode >> 2] = 21; + var $ret_4 = $ret_3; + var $next_42 = $next_41; + var $have_42 = $have_41; + var $hold_38 = $shr1303; + var $bits_38 = $sub1306; + var $156 = $and1341; + __label__ = 227; + break; + } + HEAP32[$msg >> 2] = STRING_TABLE.__str2171 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $ret_3; + var $next_0_be = $next_41; + var $put_0_be = $put_0; + var $have_0_be = $have_41; + var $left_0_be = $left_0; + var $hold_0_be = $shr1303; + var $bits_0_be = $sub1306; + var $out_0_be = $out_0; + __label__ = 268; + break; + } + } while (0); + do { + if (__label__ == 81) { + var $89; + var $bits_9; + var $hold_9; + var $have_11; + var $next_11; + var $tobool376 = ($89 & 2048 | 0) == 0; + do { + if ($tobool376) { + var $98 = HEAP32[$18 >> 2]; + if (($98 | 0) == 0) { + var $next_12 = $next_11; + var $have_12 = $have_11; + break; + } + var $name428 = $98 + 28 | 0; + HEAP32[$name428 >> 2] = 0; + var $next_12 = $next_11; + var $have_12 = $have_11; + } else { + if (($have_11 | 0) == 0) { + var $ret_8 = $ret_0; + var $next_58 = $next_11; + var $have_58 = 0; + var $hold_54 = $hold_9; + var $bits_54 = $bits_9; + var $out_4 = $out_0; + break $_$12; + } + var $copy_1 = 0; + while (1) { + var $copy_1; + var $inc = $copy_1 + 1 | 0; + var $90 = HEAP8[$next_11 + $copy_1 | 0]; + var $91 = HEAP32[$18 >> 2]; + var $cmp386 = ($91 | 0) == 0; + do { + if (!$cmp386) { + var $name = $91 + 28 | 0; + if ((HEAP32[$name >> 2] | 0) == 0) { + break; + } + var $93 = HEAPU32[$21 >> 2]; + if (!($93 >>> 0 < HEAPU32[($91 + 32 | 0) >> 2] >>> 0)) { + break; + } + HEAP32[$21 >> 2] = $93 + 1 | 0; + HEAP8[HEAP32[$name >> 2] + $93 | 0] = $90; + } + } while (0); + var $tobool405 = $90 << 24 >> 24 != 0; + if (!($tobool405 & $inc >>> 0 < $have_11 >>> 0)) { + break; + } + var $copy_1 = $inc; + } + if (!((HEAP32[$17 >> 2] & 512 | 0) == 0)) { + var $97 = HEAP32[$16 >> 2]; + var $call414 = _crc32($97, $next_11, $inc); + HEAP32[$16 >> 2] = $call414; + } + var $sub417 = $have_11 - $inc | 0; + var $add_ptr418 = $next_11 + $inc | 0; + if ($tobool405) { + var $ret_8 = $ret_0; + var $next_58 = $add_ptr418; + var $have_58 = $sub417; + var $hold_54 = $hold_9; + var $bits_54 = $bits_9; + var $out_4 = $out_0; + break $_$12; + } + var $next_12 = $add_ptr418; + var $have_12 = $sub417; + } + } while (0); + var $have_12; + var $next_12; + HEAP32[$21 >> 2] = 0; + HEAP32[$mode >> 2] = 7; + var $next_13 = $next_12; + var $have_13 = $have_12; + var $hold_10 = $hold_9; + var $bits_10 = $bits_9; + __label__ = 94; + break; + } else if (__label__ == 227) { + var $156; + var $bits_38; + var $hold_38; + var $have_42; + var $next_42; + var $ret_4; + if (($156 | 0) == 0) { + var $next_44 = $next_42; + var $have_44 = $have_42; + var $hold_40 = $hold_38; + var $bits_40 = $bits_38; + var $160 = HEAP32[$21 >> 2]; + } else { + var $next_43 = $next_42; + var $have_43 = $have_42; + var $hold_39 = $hold_38; + var $bits_39 = $bits_38; + while (1) { + var $bits_39; + var $hold_39; + var $have_43; + var $next_43; + if (!($bits_39 >>> 0 < $156 >>> 0)) { + break; + } + if (($have_43 | 0) == 0) { + var $ret_8 = $ret_4; + var $next_58 = $next_43; + var $have_58 = 0; + var $hold_54 = $hold_39; + var $bits_54 = $bits_39; + var $out_4 = $out_0; + break $_$12; + } + var $add1363 = ((HEAPU8[$next_43] & 255) << $bits_39) + $hold_39 | 0; + var $next_43 = $next_43 + 1 | 0; + var $have_43 = $have_43 - 1 | 0; + var $hold_39 = $add1363; + var $bits_39 = $bits_39 + 8 | 0; + } + var $add1375 = HEAP32[$21 >> 2] + (((1 << $156) - 1 | 0) & $hold_39) | 0; + HEAP32[$21 >> 2] = $add1375; + var $add1385 = HEAP32[$25 >> 2] + $156 | 0; + HEAP32[$25 >> 2] = $add1385; + var $next_44 = $next_43; + var $have_44 = $have_43; + var $hold_40 = $hold_39 >>> ($156 >>> 0); + var $bits_40 = $bits_39 - $156 | 0; + var $160 = $add1375; + } + var $160; + var $bits_40; + var $hold_40; + var $have_44; + var $next_44; + HEAP32[$29 >> 2] = $160; + HEAP32[$mode >> 2] = 22; + var $ret_5_ph = $ret_4; + var $next_45_ph = $next_44; + var $have_45_ph = $have_44; + var $hold_41_ph = $hold_40; + var $bits_41_ph = $bits_40; + __label__ = 234; + break; + } + } while (0); + do { + if (__label__ == 94) { + var $bits_10; + var $hold_10; + var $have_13; + var $next_13; + var $tobool436 = (HEAP32[$17 >> 2] & 4096 | 0) == 0; + do { + if ($tobool436) { + var $108 = HEAP32[$18 >> 2]; + if (($108 | 0) == 0) { + var $next_14 = $next_13; + var $have_14 = $have_13; + break; + } + var $comment492 = $108 + 36 | 0; + HEAP32[$comment492 >> 2] = 0; + var $next_14 = $next_13; + var $have_14 = $have_13; + } else { + if (($have_13 | 0) == 0) { + var $ret_8 = $ret_0; + var $next_58 = $next_13; + var $have_58 = 0; + var $hold_54 = $hold_10; + var $bits_54 = $bits_10; + var $out_4 = $out_0; + break $_$12; + } + var $copy_2 = 0; + while (1) { + var $copy_2; + var $inc443 = $copy_2 + 1 | 0; + var $100 = HEAP8[$next_13 + $copy_2 | 0]; + var $101 = HEAP32[$18 >> 2]; + var $cmp447 = ($101 | 0) == 0; + do { + if (!$cmp447) { + var $comment = $101 + 36 | 0; + if ((HEAP32[$comment >> 2] | 0) == 0) { + break; + } + var $103 = HEAPU32[$21 >> 2]; + if (!($103 >>> 0 < HEAPU32[($101 + 40 | 0) >> 2] >>> 0)) { + break; + } + HEAP32[$21 >> 2] = $103 + 1 | 0; + HEAP8[HEAP32[$comment >> 2] + $103 | 0] = $100; + } + } while (0); + var $tobool467 = $100 << 24 >> 24 != 0; + if (!($tobool467 & $inc443 >>> 0 < $have_13 >>> 0)) { + break; + } + var $copy_2 = $inc443; + } + if (!((HEAP32[$17 >> 2] & 512 | 0) == 0)) { + var $107 = HEAP32[$16 >> 2]; + var $call478 = _crc32($107, $next_13, $inc443); + HEAP32[$16 >> 2] = $call478; + } + var $sub481 = $have_13 - $inc443 | 0; + var $add_ptr482 = $next_13 + $inc443 | 0; + if ($tobool467) { + var $ret_8 = $ret_0; + var $next_58 = $add_ptr482; + var $have_58 = $sub481; + var $hold_54 = $hold_10; + var $bits_54 = $bits_10; + var $out_4 = $out_0; + break $_$12; + } + var $next_14 = $add_ptr482; + var $have_14 = $sub481; + } + } while (0); + var $have_14; + var $next_14; + HEAP32[$mode >> 2] = 8; + var $next_15 = $next_14; + var $have_15 = $have_14; + var $hold_11 = $hold_10; + var $bits_11 = $bits_10; + __label__ = 107; + break; + } else if (__label__ == 234) { + var $bits_41_ph; + var $hold_41_ph; + var $have_45_ph; + var $next_45_ph; + var $ret_5_ph; + var $sub1393 = (1 << HEAP32[$47 >> 2]) - 1 | 0; + var $162 = HEAPU32[$48 >> 2]; + var $next_45 = $next_45_ph; + var $have_45 = $have_45_ph; + var $hold_41 = $hold_41_ph; + var $bits_41 = $bits_41_ph; + while (1) { + var $bits_41; + var $hold_41; + var $have_45; + var $next_45; + var $and1394 = $sub1393 & $hold_41; + var $tmp16 = HEAPU8[$162 + ($and1394 << 2) + 1 | 0]; + var $conv1398 = $tmp16 & 255; + if (!($conv1398 >>> 0 > $bits_41 >>> 0)) { + break; + } + if (($have_45 | 0) == 0) { + var $ret_8 = $ret_5_ph; + var $next_58 = $next_45; + var $have_58 = 0; + var $hold_54 = $hold_41; + var $bits_54 = $bits_41; + var $out_4 = $out_0; + break $_$12; + } + var $add1412 = ((HEAPU8[$next_45] & 255) << $bits_41) + $hold_41 | 0; + var $next_45 = $next_45 + 1 | 0; + var $have_45 = $have_45 - 1 | 0; + var $hold_41 = $add1412; + var $bits_41 = $bits_41 + 8 | 0; + } + var $tmp15 = HEAPU8[$162 + ($and1394 << 2) | 0]; + var $tmp17 = HEAPU16[($162 + ($and1394 << 2) + 2 | 0) >> 1]; + var $conv1418 = $tmp15 & 255; + if (($conv1418 & 240 | 0) == 0) { + var $conv1425 = $tmp17 & 65535; + var $sub1432 = (1 << ($conv1398 + $conv1418 | 0)) - 1 | 0; + var $next_46 = $next_45; + var $have_46 = $have_45; + var $hold_42 = $hold_41; + var $bits_42 = $bits_41; + while (1) { + var $bits_42; + var $hold_42; + var $have_46; + var $next_46; + var $add1437 = (($hold_42 & $sub1432) >>> ($conv1398 >>> 0)) + $conv1425 | 0; + var $tmp13 = HEAPU8[$162 + ($add1437 << 2) + 1 | 0]; + if (!((($tmp13 & 255) + $conv1398 | 0) >>> 0 > $bits_42 >>> 0)) { + break; + } + if (($have_46 | 0) == 0) { + var $ret_8 = $ret_5_ph; + var $next_58 = $next_46; + var $have_58 = 0; + var $hold_54 = $hold_42; + var $bits_54 = $bits_42; + var $out_4 = $out_0; + break $_$12; + } + var $add1458 = ((HEAPU8[$next_46] & 255) << $bits_42) + $hold_42 | 0; + var $next_46 = $next_46 + 1 | 0; + var $have_46 = $have_46 - 1 | 0; + var $hold_42 = $add1458; + var $bits_42 = $bits_42 + 8 | 0; + } + var $tmp14 = HEAP16[($162 + ($add1437 << 2) + 2 | 0) >> 1]; + var $tmp12 = HEAP8[$162 + ($add1437 << 2) | 0]; + var $shr1466 = $hold_42 >>> ($conv1398 >>> 0); + var $sub1469 = $bits_42 - $conv1398 | 0; + var $add1475 = HEAP32[$25 >> 2] + $conv1398 | 0; + HEAP32[$25 >> 2] = $add1475; + var $next_47 = $next_46; + var $have_47 = $have_46; + var $hold_43 = $shr1466; + var $bits_43 = $sub1469; + var $here_09_1 = $tmp12; + var $here_110_1 = $tmp13; + var $here_211_1 = $tmp14; + var $166 = $add1475; + } else { + var $next_47 = $next_45; + var $have_47 = $have_45; + var $hold_43 = $hold_41; + var $bits_43 = $bits_41; + var $here_09_1 = $tmp15; + var $here_110_1 = $tmp16; + var $here_211_1 = $tmp17; + var $166 = HEAP32[$25 >> 2]; + } + var $166; + var $here_211_1; + var $here_110_1; + var $here_09_1; + var $bits_43; + var $hold_43; + var $have_47; + var $next_47; + var $conv1479 = $here_110_1 & 255; + var $shr1480 = $hold_43 >>> ($conv1479 >>> 0); + var $sub1483 = $bits_43 - $conv1479 | 0; + HEAP32[$25 >> 2] = $166 + $conv1479 | 0; + var $conv1491 = $here_09_1 & 255; + if (($conv1491 & 64 | 0) == 0) { + HEAP32[$30 >> 2] = $here_211_1 & 65535; + var $and1502 = $conv1491 & 15; + HEAP32[$28 >> 2] = $and1502; + HEAP32[$mode >> 2] = 23; + var $ret_6 = $ret_5_ph; + var $next_48 = $next_47; + var $have_48 = $have_47; + var $hold_44 = $shr1480; + var $bits_44 = $sub1483; + var $167 = $and1502; + __label__ = 248; + break; + } + HEAP32[$msg >> 2] = STRING_TABLE.__str1170 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $ret_5_ph; + var $next_0_be = $next_47; + var $put_0_be = $put_0; + var $have_0_be = $have_47; + var $left_0_be = $left_0; + var $hold_0_be = $shr1480; + var $bits_0_be = $sub1483; + var $out_0_be = $out_0; + __label__ = 268; + break; + } + } while (0); + $_$359 : do { + if (__label__ == 107) { + var $bits_11; + var $hold_11; + var $have_15; + var $next_15; + var $109 = HEAPU32[$17 >> 2]; + var $tobool499 = ($109 & 512 | 0) == 0; + do { + if (!$tobool499) { + var $next_16 = $next_15; + var $have_16 = $have_15; + var $hold_12 = $hold_11; + var $bits_12 = $bits_11; + while (1) { + var $bits_12; + var $hold_12; + var $have_16; + var $next_16; + if (!($bits_12 >>> 0 < 16)) { + break; + } + if (($have_16 | 0) == 0) { + var $ret_8 = $ret_0; + var $next_58 = $next_16; + var $have_58 = 0; + var $hold_54 = $hold_12; + var $bits_54 = $bits_12; + var $out_4 = $out_0; + break $_$12; + } + var $add515 = ((HEAPU8[$next_16] & 255) << $bits_12) + $hold_12 | 0; + var $next_16 = $next_16 + 1 | 0; + var $have_16 = $have_16 - 1 | 0; + var $hold_12 = $add515; + var $bits_12 = $bits_12 + 8 | 0; + } + if (($hold_12 | 0) == (HEAP32[$16 >> 2] & 65535 | 0)) { + var $next_17 = $next_16; + var $have_17 = $have_16; + var $hold_13 = 0; + var $bits_13 = 0; + break; + } + HEAP32[$msg >> 2] = STRING_TABLE.__str5102 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $ret_0; + var $next_0_be = $next_16; + var $put_0_be = $put_0; + var $have_0_be = $have_16; + var $left_0_be = $left_0; + var $hold_0_be = $hold_12; + var $bits_0_be = $bits_12; + var $out_0_be = $out_0; + __label__ = 268; + break $_$359; + } + var $next_17 = $next_15; + var $have_17 = $have_15; + var $hold_13 = $hold_11; + var $bits_13 = $bits_11; + } while (0); + var $bits_13; + var $hold_13; + var $have_17; + var $next_17; + var $112 = HEAPU32[$18 >> 2]; + if (!(($112 | 0) == 0)) { + HEAP32[($112 + 44 | 0) >> 2] = $109 >>> 9 & 1; + var $done543 = HEAP32[$18 >> 2] + 48 | 0; + HEAP32[$done543 >> 2] = 1; + } + var $call545 = _crc32(0, 0, 0); + HEAP32[$16 >> 2] = $call545; + HEAP32[$adler >> 2] = $call545; + HEAP32[$mode >> 2] = 11; + var $ret_0_be = $ret_0; + var $next_0_be = $next_17; + var $put_0_be = $put_0; + var $have_0_be = $have_17; + var $left_0_be = $left_0; + var $hold_0_be = $hold_13; + var $bits_0_be = $bits_13; + var $out_0_be = $out_0; + __label__ = 268; + break; + } else if (__label__ == 248) { + var $167; + var $bits_44; + var $hold_44; + var $have_48; + var $next_48; + var $ret_6; + if (($167 | 0) == 0) { + var $next_50 = $next_48; + var $have_50 = $have_48; + var $hold_46 = $hold_44; + var $bits_46 = $bits_44; + } else { + var $next_49 = $next_48; + var $have_49 = $have_48; + var $hold_45 = $hold_44; + var $bits_45 = $bits_44; + while (1) { + var $bits_45; + var $hold_45; + var $have_49; + var $next_49; + if (!($bits_45 >>> 0 < $167 >>> 0)) { + break; + } + if (($have_49 | 0) == 0) { + var $ret_8 = $ret_6; + var $next_58 = $next_49; + var $have_58 = 0; + var $hold_54 = $hold_45; + var $bits_54 = $bits_45; + var $out_4 = $out_0; + break $_$12; + } + var $add1524 = ((HEAPU8[$next_49] & 255) << $bits_45) + $hold_45 | 0; + var $next_49 = $next_49 + 1 | 0; + var $have_49 = $have_49 - 1 | 0; + var $hold_45 = $add1524; + var $bits_45 = $bits_45 + 8 | 0; + } + var $add1536 = HEAP32[$30 >> 2] + (((1 << $167) - 1 | 0) & $hold_45) | 0; + HEAP32[$30 >> 2] = $add1536; + var $add1546 = HEAP32[$25 >> 2] + $167 | 0; + HEAP32[$25 >> 2] = $add1546; + var $next_50 = $next_49; + var $have_50 = $have_49; + var $hold_46 = $hold_45 >>> ($167 >>> 0); + var $bits_46 = $bits_45 - $167 | 0; + } + var $bits_46; + var $hold_46; + var $have_50; + var $next_50; + HEAP32[$mode >> 2] = 24; + var $ret_7 = $ret_6; + var $next_51 = $next_50; + var $have_51 = $have_50; + var $hold_47 = $hold_46; + var $bits_47 = $bits_46; + __label__ = 254; + break; + } + } while (0); + $_$380 : do { + if (__label__ == 254) { + var $bits_47; + var $hold_47; + var $have_51; + var $next_51; + var $ret_7; + if (($left_0 | 0) == 0) { + var $ret_8 = $ret_7; + var $next_58 = $next_51; + var $have_58 = $have_51; + var $hold_54 = $hold_47; + var $bits_54 = $bits_47; + var $out_4 = $out_0; + break $_$12; + } + var $sub1554 = $out_0 - $left_0 | 0; + var $171 = HEAPU32[$30 >> 2]; + var $cmp1556 = $171 >>> 0 > $sub1554 >>> 0; + do { + if ($cmp1556) { + var $sub1560 = $171 - $sub1554 | 0; + var $cmp1561 = $sub1560 >>> 0 > HEAPU32[$31 >> 2] >>> 0; + do { + if ($cmp1561) { + if ((HEAP32[$32 >> 2] | 0) == 0) { + break; + } + HEAP32[$msg >> 2] = STRING_TABLE.__str169 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $ret_7; + var $next_0_be = $next_51; + var $put_0_be = $put_0; + var $have_0_be = $have_51; + var $left_0_be = $left_0; + var $hold_0_be = $hold_47; + var $bits_0_be = $bits_47; + var $out_0_be = $out_0; + break $_$380; + } + } while (0); + var $174 = HEAPU32[$33 >> 2]; + if ($sub1560 >>> 0 > $174 >>> 0) { + var $sub1574 = $sub1560 - $174 | 0; + var $from_0 = HEAP32[$34 >> 2] + (HEAP32[$35 >> 2] - $sub1574 | 0) | 0; + var $copy_7 = $sub1574; + } else { + var $from_0 = HEAP32[$34 >> 2] + ($174 - $sub1560 | 0) | 0; + var $copy_7 = $sub1560; + } + var $copy_7; + var $from_0; + var $178 = HEAPU32[$21 >> 2]; + if (!($copy_7 >>> 0 > $178 >>> 0)) { + var $from_1 = $from_0; + var $copy_8 = $copy_7; + var $180 = $178; + break; + } + var $from_1 = $from_0; + var $copy_8 = $178; + var $180 = $178; + } else { + var $179 = HEAP32[$21 >> 2]; + var $from_1 = $put_0 + (-$171 | 0) | 0; + var $copy_8 = $179; + var $180 = $179; + } + } while (0); + var $180; + var $copy_8; + var $from_1; + var $copy_9 = $copy_8 >>> 0 > $left_0 >>> 0 ? $left_0 : $copy_8; + HEAP32[$21 >> 2] = $180 - $copy_9 | 0; + var $181 = $copy_8 ^ -1; + var $182 = $left_0 ^ -1; + var $umax = $181 >>> 0 > $182 >>> 0 ? $181 : $182; + var $from_2 = $from_1; + var $put_1 = $put_0; + var $copy_10 = $copy_9; + while (1) { + var $copy_10; + var $put_1; + var $from_2; + var $184 = HEAP8[$from_2]; + HEAP8[$put_1] = $184; + var $dec1605 = $copy_10 - 1 | 0; + if (($dec1605 | 0) == 0) { + break; + } + var $from_2 = $from_2 + 1 | 0; + var $put_1 = $put_1 + 1 | 0; + var $copy_10 = $dec1605; + } + var $sub1598 = $left_0 - $copy_9 | 0; + var $scevgep632 = $put_0 + ($umax ^ -1) | 0; + if (!((HEAP32[$21 >> 2] | 0) == 0)) { + var $ret_0_be = $ret_7; + var $next_0_be = $next_51; + var $put_0_be = $scevgep632; + var $have_0_be = $have_51; + var $left_0_be = $sub1598; + var $hold_0_be = $hold_47; + var $bits_0_be = $bits_47; + var $out_0_be = $out_0; + break; + } + HEAP32[$mode >> 2] = 20; + var $ret_0_be = $ret_7; + var $next_0_be = $next_51; + var $put_0_be = $scevgep632; + var $have_0_be = $have_51; + var $left_0_be = $sub1598; + var $hold_0_be = $hold_47; + var $bits_0_be = $bits_47; + var $out_0_be = $out_0; + } + } while (0); + var $out_0_be; + var $bits_0_be; + var $hold_0_be; + var $left_0_be; + var $have_0_be; + var $put_0_be; + var $next_0_be; + var $ret_0_be; + var $ret_0 = $ret_0_be; + var $next_0 = $next_0_be; + var $put_0 = $put_0_be; + var $have_0 = $have_0_be; + var $left_0 = $left_0_be; + var $hold_0 = $hold_0_be; + var $bits_0 = $bits_0_be; + var $out_0 = $out_0_be; + var $49 = HEAP32[$mode >> 2]; + } + var $out_4; + var $bits_54; + var $hold_54; + var $have_58; + var $next_58; + var $ret_8; + HEAP32[$next_out >> 2] = $put_0; + HEAP32[$avail_out >> 2] = $left_0; + HEAP32[$next_in >> 2] = $next_58; + HEAP32[$avail_in15 >> 2] = $have_58; + HEAP32[$11 >> 2] = $hold_54; + HEAP32[$13 >> 2] = $bits_54; + var $tobool1755 = (HEAP32[$35 >> 2] | 0) == 0; + do { + if ($tobool1755) { + if (!(HEAPU32[$mode >> 2] >>> 0 < 26)) { + __label__ = 300; + break; + } + if (($out_4 | 0) == (HEAP32[$avail_out >> 2] | 0)) { + __label__ = 300; + break; + } + __label__ = 298; + break; + } else { + __label__ = 298; + } + } while (0); + do { + if (__label__ == 298) { + var $call1765 = _updatewindow($strm, $out_4); + if (($call1765 | 0) == 0) { + break; + } + HEAP32[$mode >> 2] = 30; + var $retval_0 = -4; + break $_$2; + } + } while (0); + var $202 = HEAPU32[$avail_in15 >> 2]; + var $203 = HEAPU32[$avail_out >> 2]; + var $sub1774 = $out_4 - $203 | 0; + var $total_in = $strm + 8 | 0; + var $add1775 = ($10 - $202 | 0) + HEAP32[$total_in >> 2] | 0; + HEAP32[$total_in >> 2] = $add1775; + var $add1777 = HEAP32[$total_out >> 2] + $sub1774 | 0; + HEAP32[$total_out >> 2] = $add1777; + var $add1779 = HEAP32[$36 >> 2] + $sub1774 | 0; + HEAP32[$36 >> 2] = $add1779; + var $tobool1783 = ($out_4 | 0) == ($203 | 0); + if (!((HEAP32[$15 >> 2] | 0) == 0 | $tobool1783)) { + var $209 = HEAP32[$16 >> 2]; + var $add_ptr1791 = HEAP32[$next_out >> 2] + (-$sub1774 | 0) | 0; + if ((HEAP32[$17 >> 2] | 0) == 0) { + var $call1798 = _adler32($209, $add_ptr1791, $sub1774); + var $cond1800 = $call1798; + } else { + var $call1792 = _crc32($209, $add_ptr1791, $sub1774); + var $cond1800 = $call1792; + } + var $cond1800; + HEAP32[$16 >> 2] = $cond1800; + HEAP32[$adler >> 2] = $cond1800; + } + var $cond1807 = (HEAP32[$24 >> 2] | 0) != 0 ? 64 : 0; + var $213 = HEAP32[$mode >> 2]; + var $cond1812 = ($213 | 0) == 11 ? 128 : 0; + if (($213 | 0) == 19) { + var $214 = 256; + } else { + var $phitmp = ($213 | 0) == 14 ? 256 : 0; + var $214 = $phitmp; + } + var $214; + var $add1821 = (($cond1807 + HEAP32[$13 >> 2] | 0) + $cond1812 | 0) + $214 | 0; + HEAP32[($strm + 44 | 0) >> 2] = $add1821; + var $ret_9 = (($10 | 0) == ($202 | 0) & $tobool1783 | ($flush | 0) == 4) & ($ret_8 | 0) == 0 ? -5 : $ret_8; + var $retval_0 = $ret_9; + } + } while (0); + var $retval_0; + STACKTOP = __stackBase__; + return $retval_0; + return null; +} +// EMSCRIPTEN_GENERATED_FUNCTIONS: ["f", "g", "h", "py", "r", "t", "f2", "f3", "llvm3_1", "_inflate"] diff --git a/tools/eliminator/eliminator-test.js b/tools/eliminator/eliminator-test.js index 55f74d67..a2d62a25 100644 --- a/tools/eliminator/eliminator-test.js +++ b/tools/eliminator/eliminator-test.js @@ -140,4 +140,3304 @@ function llvm3_1() { run($j_0 / 2); } } -// EMSCRIPTEN_GENERATED_FUNCTIONS: ["f", "g", "h", "py", "r", "t", "f2", "f3", "llvm3_1"] +function _inflate($strm, $flush) { + var __stackBase__ = STACKTOP; + STACKTOP += 4; + var __label__; + var $hbuf = __stackBase__; + var $cmp = ($strm | 0) == 0; + $_$2 : do { + if ($cmp) { + var $retval_0 = -2; + } else { + var $state1 = $strm + 28 | 0; + var $0 = HEAPU32[$state1 >> 2]; + var $cmp2 = ($0 | 0) == 0; + if ($cmp2) { + var $retval_0 = -2; + break; + } + var $next_out = $strm + 12 | 0; + var $1 = HEAP32[$next_out >> 2]; + var $cmp4 = ($1 | 0) == 0; + if ($cmp4) { + var $retval_0 = -2; + break; + } + var $next_in = $strm | 0; + var $2 = HEAP32[$next_in >> 2]; + var $cmp6 = ($2 | 0) == 0; + if ($cmp6) { + var $avail_in = $strm + 4 | 0; + var $3 = HEAP32[$avail_in >> 2]; + var $cmp7 = ($3 | 0) == 0; + if (!$cmp7) { + var $retval_0 = -2; + break; + } + } + var $4 = $0; + var $mode = $0 | 0; + var $5 = HEAP32[$mode >> 2]; + var $cmp9 = ($5 | 0) == 11; + if ($cmp9) { + HEAP32[$mode >> 2] = 12; + var $_pre = HEAP32[$next_out >> 2]; + var $_pre882 = HEAP32[$next_in >> 2]; + var $8 = $_pre; + var $7 = $_pre882; + var $6 = 12; + } else { + var $8 = $1; + var $7 = $2; + var $6 = $5; + } + var $6; + var $7; + var $8; + var $avail_out = $strm + 16 | 0; + var $9 = HEAP32[$avail_out >> 2]; + var $avail_in15 = $strm + 4 | 0; + var $10 = HEAPU32[$avail_in15 >> 2]; + var $11 = $0 + 56 | 0; + var $12 = HEAP32[$11 >> 2]; + var $13 = $0 + 60 | 0; + var $14 = HEAP32[$13 >> 2]; + var $15 = $0 + 8 | 0; + var $16 = $0 + 24 | 0; + var $arrayidx = $hbuf | 0; + var $arrayidx40 = $hbuf + 1 | 0; + var $17 = $0 + 16 | 0; + var $head = $0 + 32 | 0; + var $18 = $head; + var $msg = $strm + 24 | 0; + var $19 = $0 + 36 | 0; + var $20 = $0 + 20 | 0; + var $adler = $strm + 48 | 0; + var $21 = $0 + 64 | 0; + var $22 = $0 + 12 | 0; + var $flush_off = $flush - 5 | 0; + var $23 = $flush_off >>> 0 < 2; + var $24 = $0 + 4 | 0; + var $cmp660 = ($flush | 0) == 6; + var $25 = $0 + 7108 | 0; + var $26 = $0 + 84 | 0; + var $lencode1215 = $0 + 76 | 0; + var $27 = $lencode1215; + var $28 = $0 + 72 | 0; + var $29 = $0 + 7112 | 0; + var $30 = $0 + 68 | 0; + var $31 = $0 + 44 | 0; + var $32 = $0 + 7104 | 0; + var $33 = $0 + 48 | 0; + var $window = $0 + 52 | 0; + var $34 = $window; + var $35 = $0 + 40 | 0; + var $total_out = $strm + 20 | 0; + var $36 = $0 + 28 | 0; + var $arrayidx199 = $hbuf + 2 | 0; + var $arrayidx202 = $hbuf + 3 | 0; + var $37 = $0 + 96 | 0; + var $38 = $0 + 100 | 0; + var $39 = $0 + 92 | 0; + var $40 = $0 + 104 | 0; + var $lens = $0 + 112 | 0; + var $41 = $lens; + var $codes = $0 + 1328 | 0; + var $next861 = $0 + 108 | 0; + var $42 = $next861; + var $43 = $next861 | 0; + var $arraydecay860_c = $codes; + var $44 = $0 + 76 | 0; + var $arraydecay864 = $lens; + var $work = $0 + 752 | 0; + var $arraydecay867 = $work; + var $arrayidx1128 = $0 + 624 | 0; + var $45 = $arrayidx1128; + var $46 = $0 + 80 | 0; + var $47 = $0 + 88 | 0; + var $distcode1395 = $0 + 80 | 0; + var $48 = $distcode1395; + var $ret_0 = 0; + var $next_0 = $7; + var $put_0 = $8; + var $have_0 = $10; + var $left_0 = $9; + var $hold_0 = $12; + var $bits_0 = $14; + var $out_0 = $9; + var $49 = $6; + $_$12 : while (1) { + var $49; + var $out_0; + var $bits_0; + var $hold_0; + var $left_0; + var $have_0; + var $put_0; + var $next_0; + var $ret_0; + $_$14 : do { + if (($49 | 0) == 0) { + var $50 = HEAPU32[$15 >> 2]; + var $cmp19 = ($50 | 0) == 0; + if ($cmp19) { + HEAP32[$mode >> 2] = 12; + var $ret_0_be = $ret_0; + var $next_0_be = $next_0; + var $put_0_be = $put_0; + var $have_0_be = $have_0; + var $left_0_be = $left_0; + var $hold_0_be = $hold_0; + var $bits_0_be = $bits_0; + var $out_0_be = $out_0; + __label__ = 268; + break; + } + var $next_1 = $next_0; + var $have_1 = $have_0; + var $hold_1 = $hold_0; + var $bits_1 = $bits_0; + while (1) { + var $bits_1; + var $hold_1; + var $have_1; + var $next_1; + var $cmp24 = $bits_1 >>> 0 < 16; + if (!$cmp24) { + break; + } + var $cmp26 = ($have_1 | 0) == 0; + if ($cmp26) { + var $ret_8 = $ret_0; + var $next_58 = $next_1; + var $have_58 = 0; + var $hold_54 = $hold_1; + var $bits_54 = $bits_1; + var $out_4 = $out_0; + break $_$12; + } + // XXX first chunk with a difference (no impact) + var $dec = $have_1 - 1 | 0; + var $incdec_ptr = $next_1 + 1 | 0; + var $51 = HEAPU8[$next_1]; + var $conv = $51 & 255; + var $shl = $conv << $bits_1; + var $add = $shl + $hold_1 | 0; + var $add29 = $bits_1 + 8 | 0; + var $next_1 = $incdec_ptr; + var $have_1 = $dec; + var $hold_1 = $add; + var $bits_1 = $add29; + } + var $and = $50 & 2; + var $tobool = ($and | 0) != 0; + var $cmp34 = ($hold_1 | 0) == 35615; + var $or_cond = $tobool & $cmp34; + if ($or_cond) { + var $call = _crc32(0, 0, 0); + HEAP32[$16 >> 2] = $call; + HEAP8[$arrayidx] = 31; + HEAP8[$arrayidx40] = -117; + var $52 = HEAP32[$16 >> 2]; + var $call42 = _crc32($52, $arrayidx, 2); + HEAP32[$16 >> 2] = $call42; + HEAP32[$mode >> 2] = 1; + var $ret_0_be = $ret_0; + var $next_0_be = $next_1; + var $put_0_be = $put_0; + var $have_0_be = $have_1; + var $left_0_be = $left_0; + var $hold_0_be = 0; + var $bits_0_be = 0; + var $out_0_be = $out_0; + __label__ = 268; + break; + } + HEAP32[$17 >> 2] = 0; + var $53 = HEAP32[$18 >> 2]; + var $cmp49 = ($53 | 0) == 0; + if ($cmp49) { + var $54 = $50; + } else { + var $done = $53 + 48 | 0; + HEAP32[$done >> 2] = -1; + var $_pre884 = HEAP32[$15 >> 2]; + var $54 = $_pre884; + } + var $54; + var $and55 = $54 & 1; + var $tobool56 = ($and55 | 0) == 0; + do { + if (!$tobool56) { + var $and58 = $hold_1 << 8; + var $shl59 = $and58 & 65280; + var $shr60 = $hold_1 >>> 8; + var $add61 = $shl59 + $shr60 | 0; + var $rem = ($add61 >>> 0) % 31; + var $tobool62 = ($rem | 0) == 0; + if (!$tobool62) { + break; + } + var $and66 = $hold_1 & 15; + var $cmp67 = ($and66 | 0) == 8; + if ($cmp67) { + var $shr74 = $hold_1 >>> 4; + var $sub = $bits_1 - 4 | 0; + var $and76 = $shr74 & 15; + var $add77 = $and76 + 8 | 0; + var $55 = HEAPU32[$19 >> 2]; + var $cmp78 = ($55 | 0) == 0; + do { + if (!$cmp78) { + var $cmp83 = $add77 >>> 0 > $55 >>> 0; + if (!$cmp83) { + break; + } + HEAP32[$msg >> 2] = STRING_TABLE.__str3100 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $ret_0; + var $next_0_be = $next_1; + var $put_0_be = $put_0; + var $have_0_be = $have_1; + var $left_0_be = $left_0; + var $hold_0_be = $shr74; + var $bits_0_be = $sub; + var $out_0_be = $out_0; + __label__ = 268; + break $_$14; + } + HEAP32[$19 >> 2] = $add77; + } while (0); + var $shl90 = 1 << $add77; + HEAP32[$20 >> 2] = $shl90; + var $call91 = _adler32(0, 0, 0); + HEAP32[$16 >> 2] = $call91; + HEAP32[$adler >> 2] = $call91; + var $and93 = $hold_1 >>> 12; + var $56 = $and93 & 2; + var $57 = $56 ^ 11; + HEAP32[$mode >> 2] = $57; + var $ret_0_be = $ret_0; + var $next_0_be = $next_1; + var $put_0_be = $put_0; + var $have_0_be = $have_1; + var $left_0_be = $left_0; + var $hold_0_be = 0; + var $bits_0_be = 0; + var $out_0_be = $out_0; + __label__ = 268; + break $_$14; + } + HEAP32[$msg >> 2] = STRING_TABLE.__str299 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $ret_0; + var $next_0_be = $next_1; + var $put_0_be = $put_0; + var $have_0_be = $have_1; + var $left_0_be = $left_0; + var $hold_0_be = $hold_1; + var $bits_0_be = $bits_1; + var $out_0_be = $out_0; + __label__ = 268; + break $_$14; + } + } while (0); + HEAP32[$msg >> 2] = STRING_TABLE.__str198 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $ret_0; + var $next_0_be = $next_1; + var $put_0_be = $put_0; + var $have_0_be = $have_1; + var $left_0_be = $left_0; + var $hold_0_be = $hold_1; + var $bits_0_be = $bits_1; + var $out_0_be = $out_0; + __label__ = 268; + break; + } else if (($49 | 0) == 1) { + var $next_2 = $next_0; + var $have_2 = $have_0; + var $hold_2 = $hold_0; + var $bits_2 = $bits_0; + while (1) { + var $bits_2; + var $hold_2; + var $have_2; + var $next_2; + var $cmp101 = $bits_2 >>> 0 < 16; + if (!$cmp101) { + break; + } + var $cmp105 = ($have_2 | 0) == 0; + if ($cmp105) { + var $ret_8 = $ret_0; + var $next_58 = $next_2; + var $have_58 = 0; + var $hold_54 = $hold_2; + var $bits_54 = $bits_2; + var $out_4 = $out_0; + break $_$12; + } + var $dec109 = $have_2 - 1 | 0; + var $incdec_ptr110 = $next_2 + 1 | 0; + var $58 = HEAPU8[$next_2]; + var $conv111 = $58 & 255; + var $shl112 = $conv111 << $bits_2; + var $add113 = $shl112 + $hold_2 | 0; + var $add114 = $bits_2 + 8 | 0; + var $next_2 = $incdec_ptr110; + var $have_2 = $dec109; + var $hold_2 = $add113; + var $bits_2 = $add114; + } + HEAP32[$17 >> 2] = $hold_2; + var $and120 = $hold_2 & 255; + var $cmp121 = ($and120 | 0) == 8; + if (!$cmp121) { + HEAP32[$msg >> 2] = STRING_TABLE.__str299 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $ret_0; + var $next_0_be = $next_2; + var $put_0_be = $put_0; + var $have_0_be = $have_2; + var $left_0_be = $left_0; + var $hold_0_be = $hold_2; + var $bits_0_be = $bits_2; + var $out_0_be = $out_0; + __label__ = 268; + break; + } + var $and128 = $hold_2 & 57344; + var $tobool129 = ($and128 | 0) == 0; + if ($tobool129) { + var $59 = HEAPU32[$18 >> 2]; + var $cmp135 = ($59 | 0) == 0; + if ($cmp135) { + var $60 = $hold_2; + } else { + var $shr138 = $hold_2 >>> 8; + var $and139 = $shr138 & 1; + var $text = $59 | 0; + HEAP32[$text >> 2] = $and139; + var $_pre887 = HEAP32[$17 >> 2]; + var $60 = $_pre887; + } + var $60; + var $and143 = $60 & 512; + var $tobool144 = ($and143 | 0) == 0; + if (!$tobool144) { + var $conv147 = $hold_2 & 255; + HEAP8[$arrayidx] = $conv147; + var $shr149 = $hold_2 >>> 8; + var $conv150 = $shr149 & 255; + HEAP8[$arrayidx40] = $conv150; + var $61 = HEAP32[$16 >> 2]; + var $call154 = _crc32($61, $arrayidx, 2); + HEAP32[$16 >> 2] = $call154; + } + HEAP32[$mode >> 2] = 2; + var $next_3 = $next_2; + var $have_3 = $have_2; + var $hold_3 = 0; + var $bits_3 = 0; + __label__ = 44; + break; + } + HEAP32[$msg >> 2] = STRING_TABLE.__str4101 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $ret_0; + var $next_0_be = $next_2; + var $put_0_be = $put_0; + var $have_0_be = $have_2; + var $left_0_be = $left_0; + var $hold_0_be = $hold_2; + var $bits_0_be = $bits_2; + var $out_0_be = $out_0; + __label__ = 268; + break; + } else if (($49 | 0) == 2) { + var $next_3 = $next_0; + var $have_3 = $have_0; + var $hold_3 = $hold_0; + var $bits_3 = $bits_0; + __label__ = 44; + } else if (($49 | 0) == 3) { + var $next_4 = $next_0; + var $have_4 = $have_0; + var $hold_4 = $hold_0; + var $bits_4 = $bits_0; + __label__ = 52; + } else if (($49 | 0) == 4) { + var $next_5 = $next_0; + var $have_5 = $have_0; + var $hold_5 = $hold_0; + var $bits_5 = $bits_0; + __label__ = 60; + } else if (($49 | 0) == 5) { + var $next_8 = $next_0; + var $have_8 = $have_0; + var $hold_8 = $hold_0; + var $bits_8 = $bits_0; + __label__ = 71; + } else if (($49 | 0) == 6) { + var $_pre888 = HEAP32[$17 >> 2]; + var $next_11 = $next_0; + var $have_11 = $have_0; + var $hold_9 = $hold_0; + var $bits_9 = $bits_0; + var $89 = $_pre888; + __label__ = 81; + break; + } else if (($49 | 0) == 7) { + var $next_13 = $next_0; + var $have_13 = $have_0; + var $hold_10 = $hold_0; + var $bits_10 = $bits_0; + __label__ = 94; + } else if (($49 | 0) == 8) { + var $next_15 = $next_0; + var $have_15 = $have_0; + var $hold_11 = $hold_0; + var $bits_11 = $bits_0; + __label__ = 107; + } else if (($49 | 0) == 9) { + var $next_18 = $next_0; + var $have_18 = $have_0; + var $hold_14 = $hold_0; + var $bits_14 = $bits_0; + while (1) { + var $bits_14; + var $hold_14; + var $have_18; + var $next_18; + var $cmp552 = $bits_14 >>> 0 < 32; + if (!$cmp552) { + break; + } + var $cmp556 = ($have_18 | 0) == 0; + if ($cmp556) { + var $ret_8 = $ret_0; + var $next_58 = $next_18; + var $have_58 = 0; + var $hold_54 = $hold_14; + var $bits_54 = $bits_14; + var $out_4 = $out_0; + break $_$12; + } + var $dec560 = $have_18 - 1 | 0; + var $incdec_ptr561 = $next_18 + 1 | 0; + var $114 = HEAPU8[$next_18]; + var $conv562 = $114 & 255; + var $shl563 = $conv562 << $bits_14; + var $add564 = $shl563 + $hold_14 | 0; + var $add565 = $bits_14 + 8 | 0; + var $next_18 = $incdec_ptr561; + var $have_18 = $dec560; + var $hold_14 = $add564; + var $bits_14 = $add565; + } + var $add581 = _llvm_bswap_i32($hold_14); + HEAP32[$16 >> 2] = $add581; + HEAP32[$adler >> 2] = $add581; + HEAP32[$mode >> 2] = 10; + var $next_19 = $next_18; + var $have_19 = $have_18; + var $hold_15 = 0; + var $bits_15 = 0; + __label__ = 120; + break; + } else if (($49 | 0) == 10) { + var $next_19 = $next_0; + var $have_19 = $have_0; + var $hold_15 = $hold_0; + var $bits_15 = $bits_0; + __label__ = 120; + } else if (($49 | 0) == 11) { + var $next_20 = $next_0; + var $have_20 = $have_0; + var $hold_16 = $hold_0; + var $bits_16 = $bits_0; + __label__ = 123; + } else if (($49 | 0) == 12) { + var $next_21 = $next_0; + var $have_21 = $have_0; + var $hold_17 = $hold_0; + var $bits_17 = $bits_0; + __label__ = 124; + } else if (($49 | 0) == 13) { + var $and681 = $bits_0 & 7; + var $shr682 = $hold_0 >>> ($and681 >>> 0); + var $sub684 = $bits_0 - $and681 | 0; + var $next_23 = $next_0; + var $have_23 = $have_0; + var $hold_19 = $shr682; + var $bits_19 = $sub684; + while (1) { + var $bits_19; + var $hold_19; + var $have_23; + var $next_23; + var $cmp689 = $bits_19 >>> 0 < 32; + if (!$cmp689) { + break; + } + var $cmp693 = ($have_23 | 0) == 0; + if ($cmp693) { + var $ret_8 = $ret_0; + var $next_58 = $next_23; + var $have_58 = 0; + var $hold_54 = $hold_19; + var $bits_54 = $bits_19; + var $out_4 = $out_0; + break $_$12; + } + var $dec697 = $have_23 - 1 | 0; + var $incdec_ptr698 = $next_23 + 1 | 0; + var $118 = HEAPU8[$next_23]; + var $conv699 = $118 & 255; + var $shl700 = $conv699 << $bits_19; + var $add701 = $shl700 + $hold_19 | 0; + var $add702 = $bits_19 + 8 | 0; + var $next_23 = $incdec_ptr698; + var $have_23 = $dec697; + var $hold_19 = $add701; + var $bits_19 = $add702; + } + var $and708 = $hold_19 & 65535; + var $shr709 = $hold_19 >>> 16; + var $xor = $shr709 ^ 65535; + var $cmp710 = ($and708 | 0) == ($xor | 0); + if (!$cmp710) { + HEAP32[$msg >> 2] = STRING_TABLE.__str7104 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $ret_0; + var $next_0_be = $next_23; + var $put_0_be = $put_0; + var $have_0_be = $have_23; + var $left_0_be = $left_0; + var $hold_0_be = $hold_19; + var $bits_0_be = $bits_19; + var $out_0_be = $out_0; + __label__ = 268; + break; + } + HEAP32[$21 >> 2] = $and708; + HEAP32[$mode >> 2] = 14; + if ($cmp660) { + var $ret_8 = $ret_0; + var $next_58 = $next_23; + var $have_58 = $have_23; + var $hold_54 = 0; + var $bits_54 = 0; + var $out_4 = $out_0; + break $_$12; + } + var $next_24 = $next_23; + var $have_24 = $have_23; + var $hold_20 = 0; + var $bits_20 = 0; + __label__ = 143; + break; + } else if (($49 | 0) == 14) { + var $next_24 = $next_0; + var $have_24 = $have_0; + var $hold_20 = $hold_0; + var $bits_20 = $bits_0; + __label__ = 143; + } else if (($49 | 0) == 15) { + var $next_25 = $next_0; + var $have_25 = $have_0; + var $hold_21 = $hold_0; + var $bits_21 = $bits_0; + __label__ = 144; + } else if (($49 | 0) == 16) { + var $next_26 = $next_0; + var $have_26 = $have_0; + var $hold_22 = $hold_0; + var $bits_22 = $bits_0; + while (1) { + var $bits_22; + var $hold_22; + var $have_26; + var $next_26; + var $cmp755 = $bits_22 >>> 0 < 14; + if (!$cmp755) { + break; + } + var $cmp759 = ($have_26 | 0) == 0; + if ($cmp759) { + var $ret_8 = $ret_0; + var $next_58 = $next_26; + var $have_58 = 0; + var $hold_54 = $hold_22; + var $bits_54 = $bits_22; + var $out_4 = $out_0; + break $_$12; + } + var $dec763 = $have_26 - 1 | 0; + var $incdec_ptr764 = $next_26 + 1 | 0; + var $121 = HEAPU8[$next_26]; + var $conv765 = $121 & 255; + var $shl766 = $conv765 << $bits_22; + var $add767 = $shl766 + $hold_22 | 0; + var $add768 = $bits_22 + 8 | 0; + var $next_26 = $incdec_ptr764; + var $have_26 = $dec763; + var $hold_22 = $add767; + var $bits_22 = $add768; + } + var $and774 = $hold_22 & 31; + var $add775 = $and774 + 257 | 0; + HEAP32[$37 >> 2] = $add775; + var $shr777 = $hold_22 >>> 5; + var $and781 = $shr777 & 31; + var $add782 = $and781 + 1 | 0; + HEAP32[$38 >> 2] = $add782; + var $shr784 = $hold_22 >>> 10; + var $and788 = $shr784 & 15; + var $add789 = $and788 + 4 | 0; + HEAP32[$39 >> 2] = $add789; + var $shr791 = $hold_22 >>> 14; + var $sub792 = $bits_22 - 14 | 0; + var $cmp796 = $add775 >>> 0 > 286; + var $cmp800 = $add782 >>> 0 > 30; + var $or_cond894 = $cmp796 | $cmp800; + if ($or_cond894) { + HEAP32[$msg >> 2] = STRING_TABLE.__str8105 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $ret_0; + var $next_0_be = $next_26; + var $put_0_be = $put_0; + var $have_0_be = $have_26; + var $left_0_be = $left_0; + var $hold_0_be = $shr791; + var $bits_0_be = $sub792; + var $out_0_be = $out_0; + __label__ = 268; + break; + } + HEAP32[$40 >> 2] = 0; + HEAP32[$mode >> 2] = 17; + var $next_27 = $next_26; + var $have_27 = $have_26; + var $hold_23 = $shr791; + var $bits_23 = $sub792; + __label__ = 154; + break; + } else if (($49 | 0) == 17) { + var $next_27 = $next_0; + var $have_27 = $have_0; + var $hold_23 = $hold_0; + var $bits_23 = $bits_0; + __label__ = 154; + } else if (($49 | 0) == 18) { + var $ret_1_ph = $ret_0; + var $next_29_ph = $next_0; + var $have_29_ph = $have_0; + var $hold_25_ph = $hold_0; + var $bits_25_ph = $bits_0; + __label__ = 164; + } else if (($49 | 0) == 19) { + var $ret_2 = $ret_0; + var $next_37 = $next_0; + var $have_37 = $have_0; + var $hold_33 = $hold_0; + var $bits_33 = $bits_0; + __label__ = 205; + } else if (($49 | 0) == 20) { + var $ret_3 = $ret_0; + var $next_38 = $next_0; + var $have_38 = $have_0; + var $hold_34 = $hold_0; + var $bits_34 = $bits_0; + __label__ = 206; + } else if (($49 | 0) == 21) { + var $_pre889 = HEAP32[$28 >> 2]; + var $ret_4 = $ret_0; + var $next_42 = $next_0; + var $have_42 = $have_0; + var $hold_38 = $hold_0; + var $bits_38 = $bits_0; + var $156 = $_pre889; + __label__ = 227; + break; + } else if (($49 | 0) == 22) { + var $ret_5_ph = $ret_0; + var $next_45_ph = $next_0; + var $have_45_ph = $have_0; + var $hold_41_ph = $hold_0; + var $bits_41_ph = $bits_0; + __label__ = 234; + } else if (($49 | 0) == 23) { + var $_pre891 = HEAP32[$28 >> 2]; + var $ret_6 = $ret_0; + var $next_48 = $next_0; + var $have_48 = $have_0; + var $hold_44 = $hold_0; + var $bits_44 = $bits_0; + var $167 = $_pre891; + __label__ = 248; + break; + } else if (($49 | 0) == 24) { + var $ret_7 = $ret_0; + var $next_51 = $next_0; + var $have_51 = $have_0; + var $hold_47 = $hold_0; + var $bits_47 = $bits_0; + __label__ = 254; + } else if (($49 | 0) == 25) { + var $cmp1615 = ($left_0 | 0) == 0; + if ($cmp1615) { + var $ret_8 = $ret_0; + var $next_58 = $next_0; + var $have_58 = $have_0; + var $hold_54 = $hold_0; + var $bits_54 = $bits_0; + var $out_4 = $out_0; + break $_$12; + } + var $186 = HEAP32[$21 >> 2]; + var $conv1620 = $186 & 255; + var $incdec_ptr1621 = $put_0 + 1 | 0; + HEAP8[$put_0] = $conv1620; + var $dec1622 = $left_0 - 1 | 0; + HEAP32[$mode >> 2] = 20; + var $ret_0_be = $ret_0; + var $next_0_be = $next_0; + var $put_0_be = $incdec_ptr1621; + var $have_0_be = $have_0; + var $left_0_be = $dec1622; + var $hold_0_be = $hold_0; + var $bits_0_be = $bits_0; + var $out_0_be = $out_0; + __label__ = 268; + break; + } else if (($49 | 0) == 26) { + var $187 = HEAP32[$15 >> 2]; + var $tobool1626 = ($187 | 0) == 0; + do { + if (!$tobool1626) { + var $next_52 = $next_0; + var $have_52 = $have_0; + var $hold_48 = $hold_0; + var $bits_48 = $bits_0; + while (1) { + var $bits_48; + var $hold_48; + var $have_52; + var $next_52; + var $cmp1630 = $bits_48 >>> 0 < 32; + if (!$cmp1630) { + break; + } + var $cmp1634 = ($have_52 | 0) == 0; + if ($cmp1634) { + var $ret_8 = $ret_0; + var $next_58 = $next_52; + var $have_58 = 0; + var $hold_54 = $hold_48; + var $bits_54 = $bits_48; + var $out_4 = $out_0; + break $_$12; + } + var $dec1638 = $have_52 - 1 | 0; + var $incdec_ptr1639 = $next_52 + 1 | 0; + var $188 = HEAPU8[$next_52]; + var $conv1640 = $188 & 255; + var $shl1641 = $conv1640 << $bits_48; + var $add1642 = $shl1641 + $hold_48 | 0; + var $add1643 = $bits_48 + 8 | 0; + var $next_52 = $incdec_ptr1639; + var $have_52 = $dec1638; + var $hold_48 = $add1642; + var $bits_48 = $add1643; + } + var $sub1649 = $out_0 - $left_0 | 0; + var $189 = HEAP32[$total_out >> 2]; + var $add1650 = $189 + $sub1649 | 0; + HEAP32[$total_out >> 2] = $add1650; + var $190 = HEAP32[$36 >> 2]; + var $add1651 = $190 + $sub1649 | 0; + HEAP32[$36 >> 2] = $add1651; + var $tobool1652 = ($out_0 | 0) == ($left_0 | 0); + if (!$tobool1652) { + var $191 = HEAP32[$17 >> 2]; + var $tobool1655 = ($191 | 0) == 0; + var $192 = HEAP32[$16 >> 2]; + var $idx_neg1658 = -$sub1649 | 0; + var $add_ptr1659 = $put_0 + $idx_neg1658 | 0; + if ($tobool1655) { + var $call1665 = _adler32($192, $add_ptr1659, $sub1649); + var $cond1667 = $call1665; + } else { + var $call1660 = _crc32($192, $add_ptr1659, $sub1649); + var $cond1667 = $call1660; + } + var $cond1667; + HEAP32[$16 >> 2] = $cond1667; + HEAP32[$adler >> 2] = $cond1667; + } + var $193 = HEAP32[$17 >> 2]; + var $tobool1672 = ($193 | 0) == 0; + if ($tobool1672) { + var $add1685 = _llvm_bswap_i32($hold_48); + var $cond1687 = $add1685; + } else { + var $cond1687 = $hold_48; + } + var $cond1687; + var $194 = HEAP32[$16 >> 2]; + var $cmp1689 = ($cond1687 | 0) == ($194 | 0); + if ($cmp1689) { + var $next_53 = $next_52; + var $have_53 = $have_52; + var $hold_49 = 0; + var $bits_49 = 0; + var $out_1 = $left_0; + break; + } + HEAP32[$msg >> 2] = STRING_TABLE.__str17114 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $ret_0; + var $next_0_be = $next_52; + var $put_0_be = $put_0; + var $have_0_be = $have_52; + var $left_0_be = $left_0; + var $hold_0_be = $hold_48; + var $bits_0_be = $bits_48; + var $out_0_be = $left_0; + __label__ = 268; + break $_$14; + } + var $next_53 = $next_0; + var $have_53 = $have_0; + var $hold_49 = $hold_0; + var $bits_49 = $bits_0; + var $out_1 = $out_0; + } while (0); + var $out_1; + var $bits_49; + var $hold_49; + var $have_53; + var $next_53; + HEAP32[$mode >> 2] = 27; + var $next_54 = $next_53; + var $have_54 = $have_53; + var $hold_50 = $hold_49; + var $bits_50 = $bits_49; + var $out_2 = $out_1; + __label__ = 286; + break; + } else if (($49 | 0) == 27) { + var $next_54 = $next_0; + var $have_54 = $have_0; + var $hold_50 = $hold_0; + var $bits_50 = $bits_0; + var $out_2 = $out_0; + __label__ = 286; + } else if (($49 | 0) == 28) { + var $ret_8 = 1; + var $next_58 = $next_0; + var $have_58 = $have_0; + var $hold_54 = $hold_0; + var $bits_54 = $bits_0; + var $out_4 = $out_0; + break $_$12; + } else if (($49 | 0) == 29) { + var $ret_8 = -3; + var $next_58 = $next_0; + var $have_58 = $have_0; + var $hold_54 = $hold_0; + var $bits_54 = $bits_0; + var $out_4 = $out_0; + break $_$12; + } else if (($49 | 0) == 30) { + var $retval_0 = -4; + break $_$2; + } else { + var $retval_0 = -2; + break $_$2; + } + } while (0); + $_$106 : do { + if (__label__ == 44) { + while (1) { + var $bits_3; + var $hold_3; + var $have_3; + var $next_3; + var $cmp164 = $bits_3 >>> 0 < 32; + if (!$cmp164) { + break; + } + var $cmp168 = ($have_3 | 0) == 0; + if ($cmp168) { + var $ret_8 = $ret_0; + var $next_58 = $next_3; + var $have_58 = 0; + var $hold_54 = $hold_3; + var $bits_54 = $bits_3; + var $out_4 = $out_0; + break $_$12; + } + var $dec172 = $have_3 - 1 | 0; + var $incdec_ptr173 = $next_3 + 1 | 0; + var $62 = HEAPU8[$next_3]; + var $conv174 = $62 & 255; + var $shl175 = $conv174 << $bits_3; + var $add176 = $shl175 + $hold_3 | 0; + var $add177 = $bits_3 + 8 | 0; + var $next_3 = $incdec_ptr173; + var $have_3 = $dec172; + var $hold_3 = $add176; + var $bits_3 = $add177; + } + var $63 = HEAP32[$18 >> 2]; + var $cmp182 = ($63 | 0) == 0; + if (!$cmp182) { + var $time = $63 + 4 | 0; + HEAP32[$time >> 2] = $hold_3; + } + var $64 = HEAP32[$17 >> 2]; + var $and188 = $64 & 512; + var $tobool189 = ($and188 | 0) == 0; + if (!$tobool189) { + var $conv192 = $hold_3 & 255; + HEAP8[$arrayidx] = $conv192; + var $shr194 = $hold_3 >>> 8; + var $conv195 = $shr194 & 255; + HEAP8[$arrayidx40] = $conv195; + var $shr197 = $hold_3 >>> 16; + var $conv198 = $shr197 & 255; + HEAP8[$arrayidx199] = $conv198; + var $shr200 = $hold_3 >>> 24; + var $conv201 = $shr200 & 255; + HEAP8[$arrayidx202] = $conv201; + var $65 = HEAP32[$16 >> 2]; + var $call205 = _crc32($65, $arrayidx, 4); + HEAP32[$16 >> 2] = $call205; + } + HEAP32[$mode >> 2] = 3; + var $next_4 = $next_3; + var $have_4 = $have_3; + var $hold_4 = 0; + var $bits_4 = 0; + __label__ = 52; + break; + } else if (__label__ == 120) { + var $bits_15; + var $hold_15; + var $have_19; + var $next_19; + var $115 = HEAP32[$22 >> 2]; + var $cmp589 = ($115 | 0) == 0; + if ($cmp589) { + HEAP32[$next_out >> 2] = $put_0; + HEAP32[$avail_out >> 2] = $left_0; + HEAP32[$next_in >> 2] = $next_19; + HEAP32[$avail_in15 >> 2] = $have_19; + HEAP32[$11 >> 2] = $hold_15; + HEAP32[$13 >> 2] = $bits_15; + var $retval_0 = 2; + break $_$2; + } + var $call602 = _adler32(0, 0, 0); + HEAP32[$16 >> 2] = $call602; + HEAP32[$adler >> 2] = $call602; + HEAP32[$mode >> 2] = 11; + var $next_20 = $next_19; + var $have_20 = $have_19; + var $hold_16 = $hold_15; + var $bits_16 = $bits_15; + __label__ = 123; + break; + } else if (__label__ == 143) { + var $bits_20; + var $hold_20; + var $have_24; + var $next_24; + HEAP32[$mode >> 2] = 15; + var $next_25 = $next_24; + var $have_25 = $have_24; + var $hold_21 = $hold_20; + var $bits_21 = $bits_20; + __label__ = 144; + break; + } else if (__label__ == 154) { + while (1) { + var $bits_23; + var $hold_23; + var $have_27; + var $next_27; + var $122 = HEAPU32[$40 >> 2]; + var $123 = HEAPU32[$39 >> 2]; + var $cmp812 = $122 >>> 0 < $123 >>> 0; + if (!$cmp812) { + break; + } + var $next_28 = $next_27; + var $have_28 = $have_27; + var $hold_24 = $hold_23; + var $bits_24 = $bits_23; + while (1) { + var $bits_24; + var $hold_24; + var $have_28; + var $next_28; + var $cmp817 = $bits_24 >>> 0 < 3; + if (!$cmp817) { + break; + } + var $cmp821 = ($have_28 | 0) == 0; + if ($cmp821) { + var $ret_8 = $ret_0; + var $next_58 = $next_28; + var $have_58 = 0; + var $hold_54 = $hold_24; + var $bits_54 = $bits_24; + var $out_4 = $out_0; + break $_$12; + } + var $dec825 = $have_28 - 1 | 0; + var $incdec_ptr826 = $next_28 + 1 | 0; + var $124 = HEAPU8[$next_28]; + var $conv827 = $124 & 255; + var $shl828 = $conv827 << $bits_24; + var $add829 = $shl828 + $hold_24 | 0; + var $add830 = $bits_24 + 8 | 0; + var $next_28 = $incdec_ptr826; + var $have_28 = $dec825; + var $hold_24 = $add829; + var $bits_24 = $add830; + } + var $hold_24_tr = $hold_24 & 65535; + var $conv837 = $hold_24_tr & 7; + var $inc839 = $122 + 1 | 0; + HEAP32[$40 >> 2] = $inc839; + var $arrayidx840 = _inflate_order + ($122 << 1) | 0; + var $125 = HEAPU16[$arrayidx840 >> 1]; + var $idxprom = $125 & 65535; + var $arrayidx841 = $41 + ($idxprom << 1) | 0; + HEAP16[$arrayidx841 >> 1] = $conv837; + var $shr843 = $hold_24 >>> 3; + var $sub844 = $bits_24 - 3 | 0; + var $next_27 = $next_28; + var $have_27 = $have_28; + var $hold_23 = $shr843; + var $bits_23 = $sub844; + } + var $cmp850111 = $122 >>> 0 < 19; + $_$131 : do { + if ($cmp850111) { + var $126 = $122; + while (1) { + var $126; + var $inc854 = $126 + 1 | 0; + HEAP32[$40 >> 2] = $inc854; + var $arrayidx855 = _inflate_order + ($126 << 1) | 0; + var $127 = HEAPU16[$arrayidx855 >> 1]; + var $idxprom856 = $127 & 65535; + var $arrayidx858 = $41 + ($idxprom856 << 1) | 0; + HEAP16[$arrayidx858 >> 1] = 0; + var $_pr = HEAPU32[$40 >> 2]; + var $cmp850 = $_pr >>> 0 < 19; + if (!$cmp850) { + break $_$131; + } + var $126 = $_pr; + } + } + } while (0); + HEAP32[$43 >> 2] = $arraydecay860_c; + HEAP32[$44 >> 2] = $arraydecay860_c; + HEAP32[$26 >> 2] = 7; + var $call868 = _inflate_table(0, $arraydecay864, 19, $42, $26, $arraydecay867); + var $tobool869 = ($call868 | 0) == 0; + if ($tobool869) { + HEAP32[$40 >> 2] = 0; + HEAP32[$mode >> 2] = 18; + var $ret_1_ph = 0; + var $next_29_ph = $next_27; + var $have_29_ph = $have_27; + var $hold_25_ph = $hold_23; + var $bits_25_ph = $bits_23; + __label__ = 164; + break; + } + HEAP32[$msg >> 2] = STRING_TABLE.__str9106 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $call868; + var $next_0_be = $next_27; + var $put_0_be = $put_0; + var $have_0_be = $have_27; + var $left_0_be = $left_0; + var $hold_0_be = $hold_23; + var $bits_0_be = $bits_23; + var $out_0_be = $out_0; + __label__ = 268; + break; + } else if (__label__ == 286) { + var $out_2; + var $bits_50; + var $hold_50; + var $have_54; + var $next_54; + var $195 = HEAP32[$15 >> 2]; + var $tobool1702 = ($195 | 0) == 0; + do { + if (!$tobool1702) { + var $196 = HEAP32[$17 >> 2]; + var $tobool1705 = ($196 | 0) == 0; + if ($tobool1705) { + var $next_56 = $next_54; + var $have_56 = $have_54; + var $hold_52 = $hold_50; + var $bits_52 = $bits_50; + break; + } + var $next_55 = $next_54; + var $have_55 = $have_54; + var $hold_51 = $hold_50; + var $bits_51 = $bits_50; + while (1) { + var $bits_51; + var $hold_51; + var $have_55; + var $next_55; + var $cmp1709 = $bits_51 >>> 0 < 32; + if (!$cmp1709) { + break; + } + var $cmp1713 = ($have_55 | 0) == 0; + if ($cmp1713) { + var $ret_8 = $ret_0; + var $next_58 = $next_55; + var $have_58 = 0; + var $hold_54 = $hold_51; + var $bits_54 = $bits_51; + var $out_4 = $out_2; + break $_$12; + } + var $dec1717 = $have_55 - 1 | 0; + var $incdec_ptr1718 = $next_55 + 1 | 0; + var $197 = HEAPU8[$next_55]; + var $conv1719 = $197 & 255; + var $shl1720 = $conv1719 << $bits_51; + var $add1721 = $shl1720 + $hold_51 | 0; + var $add1722 = $bits_51 + 8 | 0; + var $next_55 = $incdec_ptr1718; + var $have_55 = $dec1717; + var $hold_51 = $add1721; + var $bits_51 = $add1722; + } + var $198 = HEAP32[$36 >> 2]; + var $cmp1729 = ($hold_51 | 0) == ($198 | 0); + if ($cmp1729) { + var $next_56 = $next_55; + var $have_56 = $have_55; + var $hold_52 = 0; + var $bits_52 = 0; + break; + } + HEAP32[$msg >> 2] = STRING_TABLE.__str18115 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $ret_0; + var $next_0_be = $next_55; + var $put_0_be = $put_0; + var $have_0_be = $have_55; + var $left_0_be = $left_0; + var $hold_0_be = $hold_51; + var $bits_0_be = $bits_51; + var $out_0_be = $out_2; + __label__ = 268; + break $_$106; + } + var $next_56 = $next_54; + var $have_56 = $have_54; + var $hold_52 = $hold_50; + var $bits_52 = $bits_50; + } while (0); + var $bits_52; + var $hold_52; + var $have_56; + var $next_56; + HEAP32[$mode >> 2] = 28; + var $ret_8 = 1; + var $next_58 = $next_56; + var $have_58 = $have_56; + var $hold_54 = $hold_52; + var $bits_54 = $bits_52; + var $out_4 = $out_2; + break $_$12; + } + } while (0); + $_$148 : do { + if (__label__ == 52) { + while (1) { + var $bits_4; + var $hold_4; + var $have_4; + var $next_4; + var $cmp215 = $bits_4 >>> 0 < 16; + if (!$cmp215) { + break; + } + var $cmp219 = ($have_4 | 0) == 0; + if ($cmp219) { + var $ret_8 = $ret_0; + var $next_58 = $next_4; + var $have_58 = 0; + var $hold_54 = $hold_4; + var $bits_54 = $bits_4; + var $out_4 = $out_0; + break $_$12; + } + var $dec223 = $have_4 - 1 | 0; + var $incdec_ptr224 = $next_4 + 1 | 0; + var $66 = HEAPU8[$next_4]; + var $conv225 = $66 & 255; + var $shl226 = $conv225 << $bits_4; + var $add227 = $shl226 + $hold_4 | 0; + var $add228 = $bits_4 + 8 | 0; + var $next_4 = $incdec_ptr224; + var $have_4 = $dec223; + var $hold_4 = $add227; + var $bits_4 = $add228; + } + var $67 = HEAP32[$18 >> 2]; + var $cmp233 = ($67 | 0) == 0; + if (!$cmp233) { + var $and236 = $hold_4 & 255; + var $xflags = $67 + 8 | 0; + HEAP32[$xflags >> 2] = $and236; + var $shr238 = $hold_4 >>> 8; + var $68 = HEAP32[$18 >> 2]; + var $os = $68 + 12 | 0; + HEAP32[$os >> 2] = $shr238; + } + var $69 = HEAP32[$17 >> 2]; + var $and242 = $69 & 512; + var $tobool243 = ($and242 | 0) == 0; + if (!$tobool243) { + var $conv246 = $hold_4 & 255; + HEAP8[$arrayidx] = $conv246; + var $shr248 = $hold_4 >>> 8; + var $conv249 = $shr248 & 255; + HEAP8[$arrayidx40] = $conv249; + var $70 = HEAP32[$16 >> 2]; + var $call253 = _crc32($70, $arrayidx, 2); + HEAP32[$16 >> 2] = $call253; + } + HEAP32[$mode >> 2] = 4; + var $next_5 = $next_4; + var $have_5 = $have_4; + var $hold_5 = 0; + var $bits_5 = 0; + __label__ = 60; + break; + } else if (__label__ == 123) { + var $bits_16; + var $hold_16; + var $have_20; + var $next_20; + if ($23) { + var $ret_8 = $ret_0; + var $next_58 = $next_20; + var $have_58 = $have_20; + var $hold_54 = $hold_16; + var $bits_54 = $bits_16; + var $out_4 = $out_0; + break $_$12; + } + var $next_21 = $next_20; + var $have_21 = $have_20; + var $hold_17 = $hold_16; + var $bits_17 = $bits_16; + __label__ = 124; + break; + } else if (__label__ == 144) { + var $bits_21; + var $hold_21; + var $have_25; + var $next_25; + var $119 = HEAPU32[$21 >> 2]; + var $tobool730 = ($119 | 0) == 0; + if ($tobool730) { + HEAP32[$mode >> 2] = 11; + var $ret_0_be = $ret_0; + var $next_0_be = $next_25; + var $put_0_be = $put_0; + var $have_0_be = $have_25; + var $left_0_be = $left_0; + var $hold_0_be = $hold_21; + var $bits_0_be = $bits_21; + var $out_0_be = $out_0; + __label__ = 268; + break; + } + var $cmp732 = $119 >>> 0 > $have_25 >>> 0; + var $copy_3 = $cmp732 ? $have_25 : $119; + var $cmp736 = $copy_3 >>> 0 > $left_0 >>> 0; + var $copy_4 = $cmp736 ? $left_0 : $copy_3; + var $cmp740 = ($copy_4 | 0) == 0; + if ($cmp740) { + var $ret_8 = $ret_0; + var $next_58 = $next_25; + var $have_58 = $have_25; + var $hold_54 = $hold_21; + var $bits_54 = $bits_21; + var $out_4 = $out_0; + break $_$12; + } + _memcpy($put_0, $next_25, $copy_4, 1); + var $sub744 = $have_25 - $copy_4 | 0; + var $add_ptr745 = $next_25 + $copy_4 | 0; + var $sub746 = $left_0 - $copy_4 | 0; + var $add_ptr747 = $put_0 + $copy_4 | 0; + var $120 = HEAP32[$21 >> 2]; + var $sub749 = $120 - $copy_4 | 0; + HEAP32[$21 >> 2] = $sub749; + var $ret_0_be = $ret_0; + var $next_0_be = $add_ptr745; + var $put_0_be = $add_ptr747; + var $have_0_be = $sub744; + var $left_0_be = $sub746; + var $hold_0_be = $hold_21; + var $bits_0_be = $bits_21; + var $out_0_be = $out_0; + __label__ = 268; + break; + } else if (__label__ == 164) { + var $bits_25_ph; + var $hold_25_ph; + var $have_29_ph; + var $next_29_ph; + var $ret_1_ph; + var $next_29 = $next_29_ph; + var $have_29 = $have_29_ph; + var $hold_25 = $hold_25_ph; + var $bits_25 = $bits_25_ph; + $_$167 : while (1) { + var $bits_25; + var $hold_25; + var $have_29; + var $next_29; + var $128 = HEAPU32[$40 >> 2]; + var $129 = HEAPU32[$37 >> 2]; + var $130 = HEAP32[$38 >> 2]; + var $add881 = $130 + $129 | 0; + var $cmp882 = $128 >>> 0 < $add881 >>> 0; + if ($cmp882) { + var $131 = HEAP32[$26 >> 2]; + var $shl887 = 1 << $131; + var $sub888 = $shl887 - 1 | 0; + var $132 = HEAPU32[$27 >> 2]; + var $next_30 = $next_29; + var $have_30 = $have_29; + var $hold_26 = $hold_25; + var $bits_26 = $bits_25; + while (1) { + var $bits_26; + var $hold_26; + var $have_30; + var $next_30; + var $and889 = $sub888 & $hold_26; + var $arrayidx891_1 = $132 + ($and889 << 2) + 1 | 0; + var $tmp25 = HEAPU8[$arrayidx891_1]; + var $conv893 = $tmp25 & 255; + var $cmp894 = $conv893 >>> 0 > $bits_26 >>> 0; + if (!$cmp894) { + break; + } + var $cmp899 = ($have_30 | 0) == 0; + if ($cmp899) { + var $ret_8 = $ret_1_ph; + var $next_58 = $next_30; + var $have_58 = 0; + var $hold_54 = $hold_26; + var $bits_54 = $bits_26; + var $out_4 = $out_0; + break $_$12; + } + var $dec903 = $have_30 - 1 | 0; + var $incdec_ptr904 = $next_30 + 1 | 0; + var $133 = HEAPU8[$next_30]; + var $conv905 = $133 & 255; + var $shl906 = $conv905 << $bits_26; + var $add907 = $shl906 + $hold_26 | 0; + var $add908 = $bits_26 + 8 | 0; + var $next_30 = $incdec_ptr904; + var $have_30 = $dec903; + var $hold_26 = $add907; + var $bits_26 = $add908; + } + var $arrayidx891_2 = $132 + ($and889 << 2) + 2 | 0; + var $tmp26 = HEAPU16[$arrayidx891_2 >> 1]; + var $cmp912 = ($tmp26 & 65535) < 16; + if ($cmp912) { + var $next_31 = $next_30; + var $have_31 = $have_30; + var $hold_27 = $hold_26; + var $bits_27 = $bits_26; + while (1) { + var $bits_27; + var $hold_27; + var $have_31; + var $next_31; + var $cmp919 = $bits_27 >>> 0 < $conv893 >>> 0; + if (!$cmp919) { + break; + } + var $cmp923 = ($have_31 | 0) == 0; + if ($cmp923) { + var $ret_8 = $ret_1_ph; + var $next_58 = $next_31; + var $have_58 = 0; + var $hold_54 = $hold_27; + var $bits_54 = $bits_27; + var $out_4 = $out_0; + break $_$12; + } + var $dec927 = $have_31 - 1 | 0; + var $incdec_ptr928 = $next_31 + 1 | 0; + var $134 = HEAPU8[$next_31]; + var $conv929 = $134 & 255; + var $shl930 = $conv929 << $bits_27; + var $add931 = $shl930 + $hold_27 | 0; + var $add932 = $bits_27 + 8 | 0; + var $next_31 = $incdec_ptr928; + var $have_31 = $dec927; + var $hold_27 = $add931; + var $bits_27 = $add932; + } + var $shr941 = $hold_27 >>> ($conv893 >>> 0); + var $sub944 = $bits_27 - $conv893 | 0; + var $inc949 = $128 + 1 | 0; + HEAP32[$40 >> 2] = $inc949; + var $arrayidx951 = $41 + ($128 << 1) | 0; + HEAP16[$arrayidx951 >> 1] = $tmp26; + var $next_29 = $next_31; + var $have_29 = $have_31; + var $hold_25 = $shr941; + var $bits_25 = $sub944; + } else { + if ($tmp26 << 16 >> 16 == 16) { + var $add962 = $conv893 + 2 | 0; + var $next_32 = $next_30; + var $have_32 = $have_30; + var $hold_28 = $hold_26; + var $bits_28 = $bits_26; + while (1) { + var $bits_28; + var $hold_28; + var $have_32; + var $next_32; + var $cmp963 = $bits_28 >>> 0 < $add962 >>> 0; + if (!$cmp963) { + break; + } + var $cmp967 = ($have_32 | 0) == 0; + if ($cmp967) { + var $ret_8 = $ret_1_ph; + var $next_58 = $next_32; + var $have_58 = 0; + var $hold_54 = $hold_28; + var $bits_54 = $bits_28; + var $out_4 = $out_0; + break $_$12; + } + var $dec971 = $have_32 - 1 | 0; + var $incdec_ptr972 = $next_32 + 1 | 0; + var $135 = HEAPU8[$next_32]; + var $conv973 = $135 & 255; + var $shl974 = $conv973 << $bits_28; + var $add975 = $shl974 + $hold_28 | 0; + var $add976 = $bits_28 + 8 | 0; + var $next_32 = $incdec_ptr972; + var $have_32 = $dec971; + var $hold_28 = $add975; + var $bits_28 = $add976; + } + var $shr985 = $hold_28 >>> ($conv893 >>> 0); + var $sub988 = $bits_28 - $conv893 | 0; + var $cmp992 = ($128 | 0) == 0; + if ($cmp992) { + HEAP32[$msg >> 2] = STRING_TABLE.__str10107 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $ret_1_ph; + var $next_0_be = $next_32; + var $put_0_be = $put_0; + var $have_0_be = $have_32; + var $left_0_be = $left_0; + var $hold_0_be = $shr985; + var $bits_0_be = $sub988; + var $out_0_be = $out_0; + __label__ = 268; + break $_$148; + } + var $sub999 = $128 - 1 | 0; + var $arrayidx1001 = $41 + ($sub999 << 1) | 0; + var $136 = HEAP16[$arrayidx1001 >> 1]; + var $and1003 = $shr985 & 3; + var $add1004 = $and1003 + 3 | 0; + var $shr1006 = $shr985 >>> 2; + var $sub1007 = $sub988 - 2 | 0; + var $len_0 = $136; + var $next_35 = $next_32; + var $have_35 = $have_32; + var $hold_31 = $shr1006; + var $bits_31 = $sub1007; + var $copy_5 = $add1004; + } else if ($tmp26 << 16 >> 16 == 17) { + var $add1020 = $conv893 + 3 | 0; + var $next_33 = $next_30; + var $have_33 = $have_30; + var $hold_29 = $hold_26; + var $bits_29 = $bits_26; + while (1) { + var $bits_29; + var $hold_29; + var $have_33; + var $next_33; + var $cmp1021 = $bits_29 >>> 0 < $add1020 >>> 0; + if (!$cmp1021) { + break; + } + var $cmp1025 = ($have_33 | 0) == 0; + if ($cmp1025) { + var $ret_8 = $ret_1_ph; + var $next_58 = $next_33; + var $have_58 = 0; + var $hold_54 = $hold_29; + var $bits_54 = $bits_29; + var $out_4 = $out_0; + break $_$12; + } + var $dec1029 = $have_33 - 1 | 0; + var $incdec_ptr1030 = $next_33 + 1 | 0; + var $137 = HEAPU8[$next_33]; + var $conv1031 = $137 & 255; + var $shl1032 = $conv1031 << $bits_29; + var $add1033 = $shl1032 + $hold_29 | 0; + var $add1034 = $bits_29 + 8 | 0; + var $next_33 = $incdec_ptr1030; + var $have_33 = $dec1029; + var $hold_29 = $add1033; + var $bits_29 = $add1034; + } + var $shr1043 = $hold_29 >>> ($conv893 >>> 0); + var $and1049 = $shr1043 & 7; + var $add1050 = $and1049 + 3 | 0; + var $shr1052 = $shr1043 >>> 3; + var $sub1046 = -3 - $conv893 | 0; + var $sub1053 = $sub1046 + $bits_29 | 0; + var $len_0 = 0; + var $next_35 = $next_33; + var $have_35 = $have_33; + var $hold_31 = $shr1052; + var $bits_31 = $sub1053; + var $copy_5 = $add1050; + } else { + var $add1061 = $conv893 + 7 | 0; + var $next_34 = $next_30; + var $have_34 = $have_30; + var $hold_30 = $hold_26; + var $bits_30 = $bits_26; + while (1) { + var $bits_30; + var $hold_30; + var $have_34; + var $next_34; + var $cmp1062 = $bits_30 >>> 0 < $add1061 >>> 0; + if (!$cmp1062) { + break; + } + var $cmp1066 = ($have_34 | 0) == 0; + if ($cmp1066) { + var $ret_8 = $ret_1_ph; + var $next_58 = $next_34; + var $have_58 = 0; + var $hold_54 = $hold_30; + var $bits_54 = $bits_30; + var $out_4 = $out_0; + break $_$12; + } + var $dec1070 = $have_34 - 1 | 0; + var $incdec_ptr1071 = $next_34 + 1 | 0; + var $138 = HEAPU8[$next_34]; + var $conv1072 = $138 & 255; + var $shl1073 = $conv1072 << $bits_30; + var $add1074 = $shl1073 + $hold_30 | 0; + var $add1075 = $bits_30 + 8 | 0; + var $next_34 = $incdec_ptr1071; + var $have_34 = $dec1070; + var $hold_30 = $add1074; + var $bits_30 = $add1075; + } + var $shr1084 = $hold_30 >>> ($conv893 >>> 0); + var $and1090 = $shr1084 & 127; + var $add1091 = $and1090 + 11 | 0; + var $shr1093 = $shr1084 >>> 7; + var $sub1087 = -7 - $conv893 | 0; + var $sub1094 = $sub1087 + $bits_30 | 0; + var $len_0 = 0; + var $next_35 = $next_34; + var $have_35 = $have_34; + var $hold_31 = $shr1093; + var $bits_31 = $sub1094; + var $copy_5 = $add1091; + } + var $copy_5; + var $bits_31; + var $hold_31; + var $have_35; + var $next_35; + var $len_0; + var $add1100 = $128 + $copy_5 | 0; + var $cmp1104 = $add1100 >>> 0 > $add881 >>> 0; + if ($cmp1104) { + HEAP32[$msg >> 2] = STRING_TABLE.__str10107 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $ret_1_ph; + var $next_0_be = $next_35; + var $put_0_be = $put_0; + var $have_0_be = $have_35; + var $left_0_be = $left_0; + var $hold_0_be = $hold_31; + var $bits_0_be = $bits_31; + var $out_0_be = $out_0; + __label__ = 268; + break $_$148; + } + var $copy_6127 = $copy_5; + var $139 = $128; + while (1) { + var $139; + var $copy_6127; + var $dec1111 = $copy_6127 - 1 | 0; + var $inc1116 = $139 + 1 | 0; + HEAP32[$40 >> 2] = $inc1116; + var $arrayidx1118 = $41 + ($139 << 1) | 0; + HEAP16[$arrayidx1118 >> 1] = $len_0; + var $tobool1112 = ($dec1111 | 0) == 0; + if ($tobool1112) { + var $next_29 = $next_35; + var $have_29 = $have_35; + var $hold_25 = $hold_31; + var $bits_25 = $bits_31; + continue $_$167; + } + var $_pre892 = HEAP32[$40 >> 2]; + var $copy_6127 = $dec1111; + var $139 = $_pre892; + } + } + } else { + var $_pr38 = HEAP32[$mode >> 2]; + var $cmp1123 = ($_pr38 | 0) == 29; + if ($cmp1123) { + var $ret_0_be = $ret_1_ph; + var $next_0_be = $next_29; + var $put_0_be = $put_0; + var $have_0_be = $have_29; + var $left_0_be = $left_0; + var $hold_0_be = $hold_25; + var $bits_0_be = $bits_25; + var $out_0_be = $out_0; + __label__ = 268; + break $_$148; + } + var $140 = HEAP16[$45 >> 1]; + var $cmp1130 = $140 << 16 >> 16 == 0; + if ($cmp1130) { + HEAP32[$msg >> 2] = STRING_TABLE.__str11108 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $ret_1_ph; + var $next_0_be = $next_29; + var $put_0_be = $put_0; + var $have_0_be = $have_29; + var $left_0_be = $left_0; + var $hold_0_be = $hold_25; + var $bits_0_be = $bits_25; + var $out_0_be = $out_0; + __label__ = 268; + break $_$148; + } + HEAP32[$43 >> 2] = $arraydecay860_c; + HEAP32[$44 >> 2] = $arraydecay860_c; + HEAP32[$26 >> 2] = 9; + var $call1149 = _inflate_table(1, $arraydecay864, $129, $42, $26, $arraydecay867); + var $tobool1150 = ($call1149 | 0) == 0; + if (!$tobool1150) { + HEAP32[$msg >> 2] = STRING_TABLE.__str12109 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $call1149; + var $next_0_be = $next_29; + var $put_0_be = $put_0; + var $have_0_be = $have_29; + var $left_0_be = $left_0; + var $hold_0_be = $hold_25; + var $bits_0_be = $bits_25; + var $out_0_be = $out_0; + __label__ = 268; + break $_$148; + } + var $141 = HEAP32[$42 >> 2]; + var $_c = $141; + HEAP32[$46 >> 2] = $_c; + HEAP32[$47 >> 2] = 6; + var $142 = HEAP32[$37 >> 2]; + var $add_ptr1159 = $arraydecay864 + ($142 << 1) | 0; + var $143 = HEAP32[$38 >> 2]; + var $call1165 = _inflate_table(2, $add_ptr1159, $143, $42, $47, $arraydecay867); + var $tobool1166 = ($call1165 | 0) == 0; + if (!$tobool1166) { + HEAP32[$msg >> 2] = STRING_TABLE.__str13110 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $call1165; + var $next_0_be = $next_29; + var $put_0_be = $put_0; + var $have_0_be = $have_29; + var $left_0_be = $left_0; + var $hold_0_be = $hold_25; + var $bits_0_be = $bits_25; + var $out_0_be = $out_0; + __label__ = 268; + break $_$148; + } + HEAP32[$mode >> 2] = 19; + if ($cmp660) { + var $ret_8 = 0; + var $next_58 = $next_29; + var $have_58 = $have_29; + var $hold_54 = $hold_25; + var $bits_54 = $bits_25; + var $out_4 = $out_0; + break $_$12; + } + var $ret_2 = 0; + var $next_37 = $next_29; + var $have_37 = $have_29; + var $hold_33 = $hold_25; + var $bits_33 = $bits_25; + __label__ = 205; + break $_$148; + } + } + } + } while (0); + do { + if (__label__ == 60) { + var $bits_5; + var $hold_5; + var $have_5; + var $next_5; + var $71 = HEAPU32[$17 >> 2]; + var $and262 = $71 & 1024; + var $tobool263 = ($and262 | 0) == 0; + do { + if ($tobool263) { + var $76 = HEAP32[$18 >> 2]; + var $cmp310 = ($76 | 0) == 0; + if ($cmp310) { + var $next_7 = $next_5; + var $have_7 = $have_5; + var $hold_7 = $hold_5; + var $bits_7 = $bits_5; + break; + } + var $extra = $76 + 16 | 0; + HEAP32[$extra >> 2] = 0; + var $next_7 = $next_5; + var $have_7 = $have_5; + var $hold_7 = $hold_5; + var $bits_7 = $bits_5; + } else { + var $next_6 = $next_5; + var $have_6 = $have_5; + var $hold_6 = $hold_5; + var $bits_6 = $bits_5; + while (1) { + var $bits_6; + var $hold_6; + var $have_6; + var $next_6; + var $cmp267 = $bits_6 >>> 0 < 16; + if (!$cmp267) { + break; + } + var $cmp271 = ($have_6 | 0) == 0; + if ($cmp271) { + var $ret_8 = $ret_0; + var $next_58 = $next_6; + var $have_58 = 0; + var $hold_54 = $hold_6; + var $bits_54 = $bits_6; + var $out_4 = $out_0; + break $_$12; + } + var $dec275 = $have_6 - 1 | 0; + var $incdec_ptr276 = $next_6 + 1 | 0; + var $72 = HEAPU8[$next_6]; + var $conv277 = $72 & 255; + var $shl278 = $conv277 << $bits_6; + var $add279 = $shl278 + $hold_6 | 0; + var $add280 = $bits_6 + 8 | 0; + var $next_6 = $incdec_ptr276; + var $have_6 = $dec275; + var $hold_6 = $add279; + var $bits_6 = $add280; + } + HEAP32[$21 >> 2] = $hold_6; + var $73 = HEAP32[$18 >> 2]; + var $cmp285 = ($73 | 0) == 0; + if ($cmp285) { + var $74 = $71; + } else { + var $extra_len = $73 + 20 | 0; + HEAP32[$extra_len >> 2] = $hold_6; + var $_pre885 = HEAP32[$17 >> 2]; + var $74 = $_pre885; + } + var $74; + var $and291 = $74 & 512; + var $tobool292 = ($and291 | 0) == 0; + if ($tobool292) { + var $next_7 = $next_6; + var $have_7 = $have_6; + var $hold_7 = 0; + var $bits_7 = 0; + break; + } + var $conv295 = $hold_6 & 255; + HEAP8[$arrayidx] = $conv295; + var $shr297 = $hold_6 >>> 8; + var $conv298 = $shr297 & 255; + HEAP8[$arrayidx40] = $conv298; + var $75 = HEAP32[$16 >> 2]; + var $call302 = _crc32($75, $arrayidx, 2); + HEAP32[$16 >> 2] = $call302; + var $next_7 = $next_6; + var $have_7 = $have_6; + var $hold_7 = 0; + var $bits_7 = 0; + } + } while (0); + var $bits_7; + var $hold_7; + var $have_7; + var $next_7; + HEAP32[$mode >> 2] = 5; + var $next_8 = $next_7; + var $have_8 = $have_7; + var $hold_8 = $hold_7; + var $bits_8 = $bits_7; + __label__ = 71; + break; + } else if (__label__ == 124) { + var $bits_17; + var $hold_17; + var $have_21; + var $next_21; + var $116 = HEAP32[$24 >> 2]; + var $tobool616 = ($116 | 0) == 0; + if ($tobool616) { + var $next_22 = $next_21; + var $have_22 = $have_21; + var $hold_18 = $hold_17; + var $bits_18 = $bits_17; + while (1) { + var $bits_18; + var $hold_18; + var $have_22; + var $next_22; + var $cmp629 = $bits_18 >>> 0 < 3; + if (!$cmp629) { + break; + } + var $cmp633 = ($have_22 | 0) == 0; + if ($cmp633) { + var $ret_8 = $ret_0; + var $next_58 = $next_22; + var $have_58 = 0; + var $hold_54 = $hold_18; + var $bits_54 = $bits_18; + var $out_4 = $out_0; + break $_$12; + } + var $dec637 = $have_22 - 1 | 0; + var $incdec_ptr638 = $next_22 + 1 | 0; + var $117 = HEAPU8[$next_22]; + var $conv639 = $117 & 255; + var $shl640 = $conv639 << $bits_18; + var $add641 = $shl640 + $hold_18 | 0; + var $add642 = $bits_18 + 8 | 0; + var $next_22 = $incdec_ptr638; + var $have_22 = $dec637; + var $hold_18 = $add641; + var $bits_18 = $add642; + } + var $and648 = $hold_18 & 1; + HEAP32[$24 >> 2] = $and648; + var $shr651 = $hold_18 >>> 1; + var $and655 = $shr651 & 3; + do { + if (($and655 | 0) == 0) { + HEAP32[$mode >> 2] = 13; + } else if (($and655 | 0) == 1) { + _fixedtables($4); + HEAP32[$mode >> 2] = 19; + if (!$cmp660) { + break; + } + var $shr664 = $hold_18 >>> 3; + var $sub665 = $bits_18 - 3 | 0; + var $ret_8 = $ret_0; + var $next_58 = $next_22; + var $have_58 = $have_22; + var $hold_54 = $shr664; + var $bits_54 = $sub665; + var $out_4 = $out_0; + break $_$12; + } else if (($and655 | 0) == 2) { + HEAP32[$mode >> 2] = 16; + } else if (($and655 | 0) == 3) { + HEAP32[$msg >> 2] = STRING_TABLE.__str6103 | 0; + HEAP32[$mode >> 2] = 29; + } + } while (0); + var $shr675 = $hold_18 >>> 3; + var $sub676 = $bits_18 - 3 | 0; + var $ret_0_be = $ret_0; + var $next_0_be = $next_22; + var $put_0_be = $put_0; + var $have_0_be = $have_22; + var $left_0_be = $left_0; + var $hold_0_be = $shr675; + var $bits_0_be = $sub676; + var $out_0_be = $out_0; + __label__ = 268; + break; + } + var $and619 = $bits_17 & 7; + var $shr620 = $hold_17 >>> ($and619 >>> 0); + var $sub622 = $bits_17 - $and619 | 0; + HEAP32[$mode >> 2] = 26; + var $ret_0_be = $ret_0; + var $next_0_be = $next_21; + var $put_0_be = $put_0; + var $have_0_be = $have_21; + var $left_0_be = $left_0; + var $hold_0_be = $shr620; + var $bits_0_be = $sub622; + var $out_0_be = $out_0; + __label__ = 268; + break; + } else if (__label__ == 205) { + var $bits_33; + var $hold_33; + var $have_37; + var $next_37; + var $ret_2; + HEAP32[$mode >> 2] = 20; + var $ret_3 = $ret_2; + var $next_38 = $next_37; + var $have_38 = $have_37; + var $hold_34 = $hold_33; + var $bits_34 = $bits_33; + __label__ = 206; + break; + } + } while (0); + do { + if (__label__ == 71) { + var $bits_8; + var $hold_8; + var $have_8; + var $next_8; + var $77 = HEAPU32[$17 >> 2]; + var $and319 = $77 & 1024; + var $tobool320 = ($and319 | 0) == 0; + if ($tobool320) { + var $next_10 = $next_8; + var $have_10 = $have_8; + var $88 = $77; + } else { + var $78 = HEAPU32[$21 >> 2]; + var $cmp323 = $78 >>> 0 > $have_8 >>> 0; + var $copy_0 = $cmp323 ? $have_8 : $78; + var $tobool327 = ($copy_0 | 0) == 0; + if ($tobool327) { + var $next_9 = $next_8; + var $have_9 = $have_8; + var $87 = $78; + var $86 = $77; + } else { + var $79 = HEAPU32[$18 >> 2]; + var $cmp330 = ($79 | 0) == 0; + do { + if ($cmp330) { + var $83 = $77; + } else { + var $extra334 = $79 + 16 | 0; + var $80 = HEAP32[$extra334 >> 2]; + var $cmp335 = ($80 | 0) == 0; + if ($cmp335) { + var $83 = $77; + break; + } + var $extra_len339 = $79 + 20 | 0; + var $81 = HEAP32[$extra_len339 >> 2]; + var $sub341 = $81 - $78 | 0; + var $add_ptr = $80 + $sub341 | 0; + var $add344 = $sub341 + $copy_0 | 0; + var $extra_max = $79 + 24 | 0; + var $82 = HEAPU32[$extra_max >> 2]; + var $cmp346 = $add344 >>> 0 > $82 >>> 0; + var $sub350 = $82 - $sub341 | 0; + var $cond351 = $cmp346 ? $sub350 : $copy_0; + _memcpy($add_ptr, $next_8, $cond351, 1); + var $_pre886 = HEAP32[$17 >> 2]; + var $83 = $_pre886; + } + } while (0); + var $83; + var $and354 = $83 & 512; + var $tobool355 = ($and354 | 0) == 0; + if (!$tobool355) { + var $84 = HEAP32[$16 >> 2]; + var $call358 = _crc32($84, $next_8, $copy_0); + HEAP32[$16 >> 2] = $call358; + } + var $sub361 = $have_8 - $copy_0 | 0; + var $add_ptr362 = $next_8 + $copy_0 | 0; + var $85 = HEAP32[$21 >> 2]; + var $sub364 = $85 - $copy_0 | 0; + HEAP32[$21 >> 2] = $sub364; + var $next_9 = $add_ptr362; + var $have_9 = $sub361; + var $87 = $sub364; + var $86 = $83; + } + var $86; + var $87; + var $have_9; + var $next_9; + var $tobool367 = ($87 | 0) == 0; + if (!$tobool367) { + var $ret_8 = $ret_0; + var $next_58 = $next_9; + var $have_58 = $have_9; + var $hold_54 = $hold_8; + var $bits_54 = $bits_8; + var $out_4 = $out_0; + break $_$12; + } + var $next_10 = $next_9; + var $have_10 = $have_9; + var $88 = $86; + } + var $88; + var $have_10; + var $next_10; + HEAP32[$21 >> 2] = 0; + HEAP32[$mode >> 2] = 6; + var $next_11 = $next_10; + var $have_11 = $have_10; + var $hold_9 = $hold_8; + var $bits_9 = $bits_8; + var $89 = $88; + __label__ = 81; + break; + } else if (__label__ == 206) { + var $bits_34; + var $hold_34; + var $have_38; + var $next_38; + var $ret_3; + var $cmp1179 = $have_38 >>> 0 > 5; + var $cmp1182 = $left_0 >>> 0 > 257; + var $or_cond33 = $cmp1179 & $cmp1182; + if ($or_cond33) { + HEAP32[$next_out >> 2] = $put_0; + HEAP32[$avail_out >> 2] = $left_0; + HEAP32[$next_in >> 2] = $next_38; + HEAP32[$avail_in15 >> 2] = $have_38; + HEAP32[$11 >> 2] = $hold_34; + HEAP32[$13 >> 2] = $bits_34; + _inflate_fast($strm, $out_0); + var $144 = HEAP32[$next_out >> 2]; + var $145 = HEAP32[$avail_out >> 2]; + var $146 = HEAP32[$next_in >> 2]; + var $147 = HEAP32[$avail_in15 >> 2]; + var $148 = HEAP32[$11 >> 2]; + var $149 = HEAP32[$13 >> 2]; + var $150 = HEAP32[$mode >> 2]; + var $cmp1204 = ($150 | 0) == 11; + if (!$cmp1204) { + var $ret_0_be = $ret_3; + var $next_0_be = $146; + var $put_0_be = $144; + var $have_0_be = $147; + var $left_0_be = $145; + var $hold_0_be = $148; + var $bits_0_be = $149; + var $out_0_be = $out_0; + __label__ = 268; + break; + } + HEAP32[$25 >> 2] = -1; + var $ret_0_be = $ret_3; + var $next_0_be = $146; + var $put_0_be = $144; + var $have_0_be = $147; + var $left_0_be = $145; + var $hold_0_be = $148; + var $bits_0_be = $149; + var $out_0_be = $out_0; + __label__ = 268; + break; + } + HEAP32[$25 >> 2] = 0; + var $151 = HEAP32[$26 >> 2]; + var $shl1212 = 1 << $151; + var $sub1213 = $shl1212 - 1 | 0; + var $152 = HEAPU32[$27 >> 2]; + var $next_39 = $next_38; + var $have_39 = $have_38; + var $hold_35 = $hold_34; + var $bits_35 = $bits_34; + while (1) { + var $bits_35; + var $hold_35; + var $have_39; + var $next_39; + var $and1214 = $sub1213 & $hold_35; + var $arrayidx1216_1 = $152 + ($and1214 << 2) + 1 | 0; + var $tmp22 = HEAPU8[$arrayidx1216_1]; + var $conv1218 = $tmp22 & 255; + var $cmp1219 = $conv1218 >>> 0 > $bits_35 >>> 0; + if (!$cmp1219) { + break; + } + var $cmp1224 = ($have_39 | 0) == 0; + if ($cmp1224) { + var $ret_8 = $ret_3; + var $next_58 = $next_39; + var $have_58 = 0; + var $hold_54 = $hold_35; + var $bits_54 = $bits_35; + var $out_4 = $out_0; + break $_$12; + } + var $dec1228 = $have_39 - 1 | 0; + var $incdec_ptr1229 = $next_39 + 1 | 0; + var $153 = HEAPU8[$next_39]; + var $conv1230 = $153 & 255; + var $shl1231 = $conv1230 << $bits_35; + var $add1232 = $shl1231 + $hold_35 | 0; + var $add1233 = $bits_35 + 8 | 0; + var $next_39 = $incdec_ptr1229; + var $have_39 = $dec1228; + var $hold_35 = $add1232; + var $bits_35 = $add1233; + } + var $arrayidx1216_0 = $152 + ($and1214 << 2) | 0; + var $tmp21 = HEAPU8[$arrayidx1216_0]; + var $arrayidx1216_2 = $152 + ($and1214 << 2) + 2 | 0; + var $tmp23 = HEAPU16[$arrayidx1216_2 >> 1]; + var $conv1237 = $tmp21 & 255; + var $tobool1238 = $tmp21 << 24 >> 24 == 0; + do { + if ($tobool1238) { + var $next_41 = $next_39; + var $have_41 = $have_39; + var $hold_37 = $hold_35; + var $bits_37 = $bits_35; + var $here_09_0 = 0; + var $here_110_0 = $tmp22; + var $here_211_0 = $tmp23; + var $155 = 0; + } else { + var $and1242 = $conv1237 & 240; + var $cmp1243 = ($and1242 | 0) == 0; + if (!$cmp1243) { + var $next_41 = $next_39; + var $have_41 = $have_39; + var $hold_37 = $hold_35; + var $bits_37 = $bits_35; + var $here_09_0 = $tmp21; + var $here_110_0 = $tmp22; + var $here_211_0 = $tmp23; + var $155 = 0; + break; + } + var $conv1248 = $tmp23 & 65535; + var $add1253 = $conv1218 + $conv1237 | 0; + var $shl1254 = 1 << $add1253; + var $sub1255 = $shl1254 - 1 | 0; + var $next_40 = $next_39; + var $have_40 = $have_39; + var $hold_36 = $hold_35; + var $bits_36 = $bits_35; + while (1) { + var $bits_36; + var $hold_36; + var $have_40; + var $next_40; + var $and1256 = $hold_36 & $sub1255; + var $shr1259 = $and1256 >>> ($conv1218 >>> 0); + var $add1260 = $shr1259 + $conv1248 | 0; + var $arrayidx1262_1 = $152 + ($add1260 << 2) + 1 | 0; + var $tmp19 = HEAPU8[$arrayidx1262_1]; + var $conv1266 = $tmp19 & 255; + var $add1267 = $conv1266 + $conv1218 | 0; + var $cmp1268 = $add1267 >>> 0 > $bits_36 >>> 0; + if (!$cmp1268) { + break; + } + var $cmp1273 = ($have_40 | 0) == 0; + if ($cmp1273) { + var $ret_8 = $ret_3; + var $next_58 = $next_40; + var $have_58 = 0; + var $hold_54 = $hold_36; + var $bits_54 = $bits_36; + var $out_4 = $out_0; + break $_$12; + } + var $dec1277 = $have_40 - 1 | 0; + var $incdec_ptr1278 = $next_40 + 1 | 0; + var $154 = HEAPU8[$next_40]; + var $conv1279 = $154 & 255; + var $shl1280 = $conv1279 << $bits_36; + var $add1281 = $shl1280 + $hold_36 | 0; + var $add1282 = $bits_36 + 8 | 0; + var $next_40 = $incdec_ptr1278; + var $have_40 = $dec1277; + var $hold_36 = $add1281; + var $bits_36 = $add1282; + } + var $arrayidx1262_2 = $152 + ($add1260 << 2) + 2 | 0; + var $arrayidx1262_0 = $152 + ($add1260 << 2) | 0; + var $tmp20 = HEAP16[$arrayidx1262_2 >> 1]; + var $tmp18 = HEAP8[$arrayidx1262_0]; + var $shr1289 = $hold_36 >>> ($conv1218 >>> 0); + var $sub1292 = $bits_36 - $conv1218 | 0; + HEAP32[$25 >> 2] = $conv1218; + var $next_41 = $next_40; + var $have_41 = $have_40; + var $hold_37 = $shr1289; + var $bits_37 = $sub1292; + var $here_09_0 = $tmp18; + var $here_110_0 = $tmp19; + var $here_211_0 = $tmp20; + var $155 = $conv1218; + } + } while (0); + var $155; + var $here_211_0; + var $here_110_0; + var $here_09_0; + var $bits_37; + var $hold_37; + var $have_41; + var $next_41; + var $conv1302 = $here_110_0 & 255; + var $shr1303 = $hold_37 >>> ($conv1302 >>> 0); + var $sub1306 = $bits_37 - $conv1302 | 0; + var $add1312 = $155 + $conv1302 | 0; + HEAP32[$25 >> 2] = $add1312; + var $conv1314 = $here_211_0 & 65535; + HEAP32[$21 >> 2] = $conv1314; + var $conv1317 = $here_09_0 & 255; + var $cmp1318 = $here_09_0 << 24 >> 24 == 0; + if ($cmp1318) { + HEAP32[$mode >> 2] = 25; + var $ret_0_be = $ret_3; + var $next_0_be = $next_41; + var $put_0_be = $put_0; + var $have_0_be = $have_41; + var $left_0_be = $left_0; + var $hold_0_be = $shr1303; + var $bits_0_be = $sub1306; + var $out_0_be = $out_0; + __label__ = 268; + break; + } + var $and1325 = $conv1317 & 32; + var $tobool1326 = ($and1325 | 0) == 0; + if (!$tobool1326) { + HEAP32[$25 >> 2] = -1; + HEAP32[$mode >> 2] = 11; + var $ret_0_be = $ret_3; + var $next_0_be = $next_41; + var $put_0_be = $put_0; + var $have_0_be = $have_41; + var $left_0_be = $left_0; + var $hold_0_be = $shr1303; + var $bits_0_be = $sub1306; + var $out_0_be = $out_0; + __label__ = 268; + break; + } + var $and1333 = $conv1317 & 64; + var $tobool1334 = ($and1333 | 0) == 0; + if ($tobool1334) { + var $and1341 = $conv1317 & 15; + HEAP32[$28 >> 2] = $and1341; + HEAP32[$mode >> 2] = 21; + var $ret_4 = $ret_3; + var $next_42 = $next_41; + var $have_42 = $have_41; + var $hold_38 = $shr1303; + var $bits_38 = $sub1306; + var $156 = $and1341; + __label__ = 227; + break; + } + HEAP32[$msg >> 2] = STRING_TABLE.__str2171 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $ret_3; + var $next_0_be = $next_41; + var $put_0_be = $put_0; + var $have_0_be = $have_41; + var $left_0_be = $left_0; + var $hold_0_be = $shr1303; + var $bits_0_be = $sub1306; + var $out_0_be = $out_0; + __label__ = 268; + break; + } + } while (0); + do { + if (__label__ == 81) { + var $89; + var $bits_9; + var $hold_9; + var $have_11; + var $next_11; + var $and375 = $89 & 2048; + var $tobool376 = ($and375 | 0) == 0; + do { + if ($tobool376) { + var $98 = HEAP32[$18 >> 2]; + var $cmp424 = ($98 | 0) == 0; + if ($cmp424) { + var $next_12 = $next_11; + var $have_12 = $have_11; + break; + } + var $name428 = $98 + 28 | 0; + HEAP32[$name428 >> 2] = 0; + var $next_12 = $next_11; + var $have_12 = $have_11; + } else { + var $cmp378 = ($have_11 | 0) == 0; + if ($cmp378) { + var $ret_8 = $ret_0; + var $next_58 = $next_11; + var $have_58 = 0; + var $hold_54 = $hold_9; + var $bits_54 = $bits_9; + var $out_4 = $out_0; + break $_$12; + } + var $copy_1 = 0; + while (1) { + var $copy_1; + var $inc = $copy_1 + 1 | 0; + var $arrayidx383 = $next_11 + $copy_1 | 0; + var $90 = HEAP8[$arrayidx383]; + var $91 = HEAP32[$18 >> 2]; + var $cmp386 = ($91 | 0) == 0; + do { + if (!$cmp386) { + var $name = $91 + 28 | 0; + var $92 = HEAP32[$name >> 2]; + var $cmp390 = ($92 | 0) == 0; + if ($cmp390) { + break; + } + var $93 = HEAPU32[$21 >> 2]; + var $name_max = $91 + 32 | 0; + var $94 = HEAPU32[$name_max >> 2]; + var $cmp395 = $93 >>> 0 < $94 >>> 0; + if (!$cmp395) { + break; + } + var $inc400 = $93 + 1 | 0; + HEAP32[$21 >> 2] = $inc400; + var $95 = HEAP32[$name >> 2]; + var $arrayidx403 = $95 + $93 | 0; + HEAP8[$arrayidx403] = $90; + } + } while (0); + var $tobool405 = $90 << 24 >> 24 != 0; + var $cmp406 = $inc >>> 0 < $have_11 >>> 0; + var $or_cond31 = $tobool405 & $cmp406; + if (!$or_cond31) { + break; + } + var $copy_1 = $inc; + } + var $96 = HEAP32[$17 >> 2]; + var $and410 = $96 & 512; + var $tobool411 = ($and410 | 0) == 0; + if (!$tobool411) { + var $97 = HEAP32[$16 >> 2]; + var $call414 = _crc32($97, $next_11, $inc); + HEAP32[$16 >> 2] = $call414; + } + var $sub417 = $have_11 - $inc | 0; + var $add_ptr418 = $next_11 + $inc | 0; + if ($tobool405) { + var $ret_8 = $ret_0; + var $next_58 = $add_ptr418; + var $have_58 = $sub417; + var $hold_54 = $hold_9; + var $bits_54 = $bits_9; + var $out_4 = $out_0; + break $_$12; + } + var $next_12 = $add_ptr418; + var $have_12 = $sub417; + } + } while (0); + var $have_12; + var $next_12; + HEAP32[$21 >> 2] = 0; + HEAP32[$mode >> 2] = 7; + var $next_13 = $next_12; + var $have_13 = $have_12; + var $hold_10 = $hold_9; + var $bits_10 = $bits_9; + __label__ = 94; + break; + } else if (__label__ == 227) { + var $156; + var $bits_38; + var $hold_38; + var $have_42; + var $next_42; + var $ret_4; + var $tobool1346 = ($156 | 0) == 0; + if ($tobool1346) { + var $_pre890 = HEAP32[$21 >> 2]; + var $next_44 = $next_42; + var $have_44 = $have_42; + var $hold_40 = $hold_38; + var $bits_40 = $bits_38; + var $160 = $_pre890; + } else { + var $next_43 = $next_42; + var $have_43 = $have_42; + var $hold_39 = $hold_38; + var $bits_39 = $bits_38; + while (1) { + var $bits_39; + var $hold_39; + var $have_43; + var $next_43; + var $cmp1351 = $bits_39 >>> 0 < $156 >>> 0; + if (!$cmp1351) { + break; + } + var $cmp1355 = ($have_43 | 0) == 0; + if ($cmp1355) { + var $ret_8 = $ret_4; + var $next_58 = $next_43; + var $have_58 = 0; + var $hold_54 = $hold_39; + var $bits_54 = $bits_39; + var $out_4 = $out_0; + break $_$12; + } + var $dec1359 = $have_43 - 1 | 0; + var $incdec_ptr1360 = $next_43 + 1 | 0; + var $157 = HEAPU8[$next_43]; + var $conv1361 = $157 & 255; + var $shl1362 = $conv1361 << $bits_39; + var $add1363 = $shl1362 + $hold_39 | 0; + var $add1364 = $bits_39 + 8 | 0; + var $next_43 = $incdec_ptr1360; + var $have_43 = $dec1359; + var $hold_39 = $add1363; + var $bits_39 = $add1364; + } + var $shl1371 = 1 << $156; + var $sub1372 = $shl1371 - 1 | 0; + var $and1373 = $sub1372 & $hold_39; + var $158 = HEAP32[$21 >> 2]; + var $add1375 = $158 + $and1373 | 0; + HEAP32[$21 >> 2] = $add1375; + var $shr1378 = $hold_39 >>> ($156 >>> 0); + var $sub1380 = $bits_39 - $156 | 0; + var $159 = HEAP32[$25 >> 2]; + var $add1385 = $159 + $156 | 0; + HEAP32[$25 >> 2] = $add1385; + var $next_44 = $next_43; + var $have_44 = $have_43; + var $hold_40 = $shr1378; + var $bits_40 = $sub1380; + var $160 = $add1375; + } + var $160; + var $bits_40; + var $hold_40; + var $have_44; + var $next_44; + HEAP32[$29 >> 2] = $160; + HEAP32[$mode >> 2] = 22; + var $ret_5_ph = $ret_4; + var $next_45_ph = $next_44; + var $have_45_ph = $have_44; + var $hold_41_ph = $hold_40; + var $bits_41_ph = $bits_40; + __label__ = 234; + break; + } + } while (0); + do { + if (__label__ == 94) { + var $bits_10; + var $hold_10; + var $have_13; + var $next_13; + var $99 = HEAP32[$17 >> 2]; + var $and435 = $99 & 4096; + var $tobool436 = ($and435 | 0) == 0; + do { + if ($tobool436) { + var $108 = HEAP32[$18 >> 2]; + var $cmp488 = ($108 | 0) == 0; + if ($cmp488) { + var $next_14 = $next_13; + var $have_14 = $have_13; + break; + } + var $comment492 = $108 + 36 | 0; + HEAP32[$comment492 >> 2] = 0; + var $next_14 = $next_13; + var $have_14 = $have_13; + } else { + var $cmp438 = ($have_13 | 0) == 0; + if ($cmp438) { + var $ret_8 = $ret_0; + var $next_58 = $next_13; + var $have_58 = 0; + var $hold_54 = $hold_10; + var $bits_54 = $bits_10; + var $out_4 = $out_0; + break $_$12; + } + var $copy_2 = 0; + while (1) { + var $copy_2; + var $inc443 = $copy_2 + 1 | 0; + var $arrayidx444 = $next_13 + $copy_2 | 0; + var $100 = HEAP8[$arrayidx444]; + var $101 = HEAP32[$18 >> 2]; + var $cmp447 = ($101 | 0) == 0; + do { + if (!$cmp447) { + var $comment = $101 + 36 | 0; + var $102 = HEAP32[$comment >> 2]; + var $cmp451 = ($102 | 0) == 0; + if ($cmp451) { + break; + } + var $103 = HEAPU32[$21 >> 2]; + var $comm_max = $101 + 40 | 0; + var $104 = HEAPU32[$comm_max >> 2]; + var $cmp456 = $103 >>> 0 < $104 >>> 0; + if (!$cmp456) { + break; + } + var $inc461 = $103 + 1 | 0; + HEAP32[$21 >> 2] = $inc461; + var $105 = HEAP32[$comment >> 2]; + var $arrayidx464 = $105 + $103 | 0; + HEAP8[$arrayidx464] = $100; + } + } while (0); + var $tobool467 = $100 << 24 >> 24 != 0; + var $cmp469 = $inc443 >>> 0 < $have_13 >>> 0; + var $or_cond32 = $tobool467 & $cmp469; + if (!$or_cond32) { + break; + } + var $copy_2 = $inc443; + } + var $106 = HEAP32[$17 >> 2]; + var $and474 = $106 & 512; + var $tobool475 = ($and474 | 0) == 0; + if (!$tobool475) { + var $107 = HEAP32[$16 >> 2]; + var $call478 = _crc32($107, $next_13, $inc443); + HEAP32[$16 >> 2] = $call478; + } + var $sub481 = $have_13 - $inc443 | 0; + var $add_ptr482 = $next_13 + $inc443 | 0; + if ($tobool467) { + var $ret_8 = $ret_0; + var $next_58 = $add_ptr482; + var $have_58 = $sub481; + var $hold_54 = $hold_10; + var $bits_54 = $bits_10; + var $out_4 = $out_0; + break $_$12; + } + var $next_14 = $add_ptr482; + var $have_14 = $sub481; + } + } while (0); + var $have_14; + var $next_14; + HEAP32[$mode >> 2] = 8; + var $next_15 = $next_14; + var $have_15 = $have_14; + var $hold_11 = $hold_10; + var $bits_11 = $bits_10; + __label__ = 107; + break; + } else if (__label__ == 234) { + var $bits_41_ph; + var $hold_41_ph; + var $have_45_ph; + var $next_45_ph; + var $ret_5_ph; + var $161 = HEAP32[$47 >> 2]; + var $shl1392 = 1 << $161; + var $sub1393 = $shl1392 - 1 | 0; + var $162 = HEAPU32[$48 >> 2]; + var $next_45 = $next_45_ph; + var $have_45 = $have_45_ph; + var $hold_41 = $hold_41_ph; + var $bits_41 = $bits_41_ph; + while (1) { + var $bits_41; + var $hold_41; + var $have_45; + var $next_45; + var $and1394 = $sub1393 & $hold_41; + var $arrayidx1396_1 = $162 + ($and1394 << 2) + 1 | 0; + var $tmp16 = HEAPU8[$arrayidx1396_1]; + var $conv1398 = $tmp16 & 255; + var $cmp1399 = $conv1398 >>> 0 > $bits_41 >>> 0; + if (!$cmp1399) { + break; + } + var $cmp1404 = ($have_45 | 0) == 0; + if ($cmp1404) { + var $ret_8 = $ret_5_ph; + var $next_58 = $next_45; + var $have_58 = 0; + var $hold_54 = $hold_41; + var $bits_54 = $bits_41; + var $out_4 = $out_0; + break $_$12; + } + var $dec1408 = $have_45 - 1 | 0; + var $incdec_ptr1409 = $next_45 + 1 | 0; + var $163 = HEAPU8[$next_45]; + var $conv1410 = $163 & 255; + var $shl1411 = $conv1410 << $bits_41; + var $add1412 = $shl1411 + $hold_41 | 0; + var $add1413 = $bits_41 + 8 | 0; + var $next_45 = $incdec_ptr1409; + var $have_45 = $dec1408; + var $hold_41 = $add1412; + var $bits_41 = $add1413; + } + var $arrayidx1396_0 = $162 + ($and1394 << 2) | 0; + var $tmp15 = HEAPU8[$arrayidx1396_0]; + var $arrayidx1396_2 = $162 + ($and1394 << 2) + 2 | 0; + var $tmp17 = HEAPU16[$arrayidx1396_2 >> 1]; + var $conv1418 = $tmp15 & 255; + var $and1419 = $conv1418 & 240; + var $cmp1420 = ($and1419 | 0) == 0; + if ($cmp1420) { + var $conv1425 = $tmp17 & 65535; + var $add1430 = $conv1398 + $conv1418 | 0; + var $shl1431 = 1 << $add1430; + var $sub1432 = $shl1431 - 1 | 0; + var $next_46 = $next_45; + var $have_46 = $have_45; + var $hold_42 = $hold_41; + var $bits_42 = $bits_41; + while (1) { + var $bits_42; + var $hold_42; + var $have_46; + var $next_46; + var $and1433 = $hold_42 & $sub1432; + var $shr1436 = $and1433 >>> ($conv1398 >>> 0); + var $add1437 = $shr1436 + $conv1425 | 0; + var $arrayidx1439_1 = $162 + ($add1437 << 2) + 1 | 0; + var $tmp13 = HEAPU8[$arrayidx1439_1]; + var $conv1443 = $tmp13 & 255; + var $add1444 = $conv1443 + $conv1398 | 0; + var $cmp1445 = $add1444 >>> 0 > $bits_42 >>> 0; + if (!$cmp1445) { + break; + } + var $cmp1450 = ($have_46 | 0) == 0; + if ($cmp1450) { + var $ret_8 = $ret_5_ph; + var $next_58 = $next_46; + var $have_58 = 0; + var $hold_54 = $hold_42; + var $bits_54 = $bits_42; + var $out_4 = $out_0; + break $_$12; + } + var $dec1454 = $have_46 - 1 | 0; + var $incdec_ptr1455 = $next_46 + 1 | 0; + var $164 = HEAPU8[$next_46]; + var $conv1456 = $164 & 255; + var $shl1457 = $conv1456 << $bits_42; + var $add1458 = $shl1457 + $hold_42 | 0; + var $add1459 = $bits_42 + 8 | 0; + var $next_46 = $incdec_ptr1455; + var $have_46 = $dec1454; + var $hold_42 = $add1458; + var $bits_42 = $add1459; + } + var $arrayidx1439_2 = $162 + ($add1437 << 2) + 2 | 0; + var $arrayidx1439_0 = $162 + ($add1437 << 2) | 0; + var $tmp14 = HEAP16[$arrayidx1439_2 >> 1]; + var $tmp12 = HEAP8[$arrayidx1439_0]; + var $shr1466 = $hold_42 >>> ($conv1398 >>> 0); + var $sub1469 = $bits_42 - $conv1398 | 0; + var $165 = HEAP32[$25 >> 2]; + var $add1475 = $165 + $conv1398 | 0; + HEAP32[$25 >> 2] = $add1475; + var $next_47 = $next_46; + var $have_47 = $have_46; + var $hold_43 = $shr1466; + var $bits_43 = $sub1469; + var $here_09_1 = $tmp12; + var $here_110_1 = $tmp13; + var $here_211_1 = $tmp14; + var $166 = $add1475; + } else { + var $_pre893 = HEAP32[$25 >> 2]; + var $next_47 = $next_45; + var $have_47 = $have_45; + var $hold_43 = $hold_41; + var $bits_43 = $bits_41; + var $here_09_1 = $tmp15; + var $here_110_1 = $tmp16; + var $here_211_1 = $tmp17; + var $166 = $_pre893; + } + var $166; + var $here_211_1; + var $here_110_1; + var $here_09_1; + var $bits_43; + var $hold_43; + var $have_47; + var $next_47; + var $conv1479 = $here_110_1 & 255; + var $shr1480 = $hold_43 >>> ($conv1479 >>> 0); + var $sub1483 = $bits_43 - $conv1479 | 0; + var $add1489 = $166 + $conv1479 | 0; + HEAP32[$25 >> 2] = $add1489; + var $conv1491 = $here_09_1 & 255; + var $and1492 = $conv1491 & 64; + var $tobool1493 = ($and1492 | 0) == 0; + if ($tobool1493) { + var $conv1499 = $here_211_1 & 65535; + HEAP32[$30 >> 2] = $conv1499; + var $and1502 = $conv1491 & 15; + HEAP32[$28 >> 2] = $and1502; + HEAP32[$mode >> 2] = 23; + var $ret_6 = $ret_5_ph; + var $next_48 = $next_47; + var $have_48 = $have_47; + var $hold_44 = $shr1480; + var $bits_44 = $sub1483; + var $167 = $and1502; + __label__ = 248; + break; + } + HEAP32[$msg >> 2] = STRING_TABLE.__str1170 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $ret_5_ph; + var $next_0_be = $next_47; + var $put_0_be = $put_0; + var $have_0_be = $have_47; + var $left_0_be = $left_0; + var $hold_0_be = $shr1480; + var $bits_0_be = $sub1483; + var $out_0_be = $out_0; + __label__ = 268; + break; + } + } while (0); + $_$359 : do { + if (__label__ == 107) { + var $bits_11; + var $hold_11; + var $have_15; + var $next_15; + var $109 = HEAPU32[$17 >> 2]; + var $and498 = $109 & 512; + var $tobool499 = ($and498 | 0) == 0; + do { + if (!$tobool499) { + var $next_16 = $next_15; + var $have_16 = $have_15; + var $hold_12 = $hold_11; + var $bits_12 = $bits_11; + while (1) { + var $bits_12; + var $hold_12; + var $have_16; + var $next_16; + var $cmp503 = $bits_12 >>> 0 < 16; + if (!$cmp503) { + break; + } + var $cmp507 = ($have_16 | 0) == 0; + if ($cmp507) { + var $ret_8 = $ret_0; + var $next_58 = $next_16; + var $have_58 = 0; + var $hold_54 = $hold_12; + var $bits_54 = $bits_12; + var $out_4 = $out_0; + break $_$12; + } + var $dec511 = $have_16 - 1 | 0; + var $incdec_ptr512 = $next_16 + 1 | 0; + var $110 = HEAPU8[$next_16]; + var $conv513 = $110 & 255; + var $shl514 = $conv513 << $bits_12; + var $add515 = $shl514 + $hold_12 | 0; + var $add516 = $bits_12 + 8 | 0; + var $next_16 = $incdec_ptr512; + var $have_16 = $dec511; + var $hold_12 = $add515; + var $bits_12 = $add516; + } + var $111 = HEAP32[$16 >> 2]; + var $and523 = $111 & 65535; + var $cmp524 = ($hold_12 | 0) == ($and523 | 0); + if ($cmp524) { + var $next_17 = $next_16; + var $have_17 = $have_16; + var $hold_13 = 0; + var $bits_13 = 0; + break; + } + HEAP32[$msg >> 2] = STRING_TABLE.__str5102 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $ret_0; + var $next_0_be = $next_16; + var $put_0_be = $put_0; + var $have_0_be = $have_16; + var $left_0_be = $left_0; + var $hold_0_be = $hold_12; + var $bits_0_be = $bits_12; + var $out_0_be = $out_0; + __label__ = 268; + break $_$359; + } + var $next_17 = $next_15; + var $have_17 = $have_15; + var $hold_13 = $hold_11; + var $bits_13 = $bits_11; + } while (0); + var $bits_13; + var $hold_13; + var $have_17; + var $next_17; + var $112 = HEAPU32[$18 >> 2]; + var $cmp535 = ($112 | 0) == 0; + if (!$cmp535) { + var $shr53930 = $109 >>> 9; + var $and540 = $shr53930 & 1; + var $hcrc = $112 + 44 | 0; + HEAP32[$hcrc >> 2] = $and540; + var $113 = HEAP32[$18 >> 2]; + var $done543 = $113 + 48 | 0; + HEAP32[$done543 >> 2] = 1; + } + var $call545 = _crc32(0, 0, 0); + HEAP32[$16 >> 2] = $call545; + HEAP32[$adler >> 2] = $call545; + HEAP32[$mode >> 2] = 11; + var $ret_0_be = $ret_0; + var $next_0_be = $next_17; + var $put_0_be = $put_0; + var $have_0_be = $have_17; + var $left_0_be = $left_0; + var $hold_0_be = $hold_13; + var $bits_0_be = $bits_13; + var $out_0_be = $out_0; + __label__ = 268; + break; + } else if (__label__ == 248) { + var $167; + var $bits_44; + var $hold_44; + var $have_48; + var $next_48; + var $ret_6; + var $tobool1507 = ($167 | 0) == 0; + if ($tobool1507) { + var $next_50 = $next_48; + var $have_50 = $have_48; + var $hold_46 = $hold_44; + var $bits_46 = $bits_44; + } else { + var $next_49 = $next_48; + var $have_49 = $have_48; + var $hold_45 = $hold_44; + var $bits_45 = $bits_44; + while (1) { + var $bits_45; + var $hold_45; + var $have_49; + var $next_49; + var $cmp1512 = $bits_45 >>> 0 < $167 >>> 0; + if (!$cmp1512) { + break; + } + var $cmp1516 = ($have_49 | 0) == 0; + if ($cmp1516) { + var $ret_8 = $ret_6; + var $next_58 = $next_49; + var $have_58 = 0; + var $hold_54 = $hold_45; + var $bits_54 = $bits_45; + var $out_4 = $out_0; + break $_$12; + } + // XXX first chunk with a bug-causing difference + var $dec1520 = $have_49 - 1 | 0; + var $incdec_ptr1521 = $next_49 + 1 | 0; + var $168 = HEAPU8[$next_49]; + var $conv1522 = $168 & 255; + var $shl1523 = $conv1522 << $bits_45; + var $add1524 = $shl1523 + $hold_45 | 0; + var $add1525 = $bits_45 + 8 | 0; + var $next_49 = $incdec_ptr1521; + var $have_49 = $dec1520; + var $hold_45 = $add1524; + var $bits_45 = $add1525; + } + var $shl1532 = 1 << $167; + var $sub1533 = $shl1532 - 1 | 0; + var $and1534 = $sub1533 & $hold_45; + var $169 = HEAP32[$30 >> 2]; + var $add1536 = $169 + $and1534 | 0; + HEAP32[$30 >> 2] = $add1536; + var $shr1539 = $hold_45 >>> ($167 >>> 0); + var $sub1541 = $bits_45 - $167 | 0; + var $170 = HEAP32[$25 >> 2]; + var $add1546 = $170 + $167 | 0; + HEAP32[$25 >> 2] = $add1546; + var $next_50 = $next_49; + var $have_50 = $have_49; + var $hold_46 = $shr1539; + var $bits_46 = $sub1541; + } + var $bits_46; + var $hold_46; + var $have_50; + var $next_50; + HEAP32[$mode >> 2] = 24; + var $ret_7 = $ret_6; + var $next_51 = $next_50; + var $have_51 = $have_50; + var $hold_47 = $hold_46; + var $bits_47 = $bits_46; + __label__ = 254; + break; + } + } while (0); + $_$380 : do { + if (__label__ == 254) { + var $bits_47; + var $hold_47; + var $have_51; + var $next_51; + var $ret_7; + var $cmp1550 = ($left_0 | 0) == 0; + if ($cmp1550) { + var $ret_8 = $ret_7; + var $next_58 = $next_51; + var $have_58 = $have_51; + var $hold_54 = $hold_47; + var $bits_54 = $bits_47; + var $out_4 = $out_0; + break $_$12; + } + var $sub1554 = $out_0 - $left_0 | 0; + var $171 = HEAPU32[$30 >> 2]; + var $cmp1556 = $171 >>> 0 > $sub1554 >>> 0; + do { + if ($cmp1556) { + var $sub1560 = $171 - $sub1554 | 0; + var $172 = HEAPU32[$31 >> 2]; + var $cmp1561 = $sub1560 >>> 0 > $172 >>> 0; + do { + if ($cmp1561) { + var $173 = HEAP32[$32 >> 2]; + var $tobool1564 = ($173 | 0) == 0; + if ($tobool1564) { + break; + } + HEAP32[$msg >> 2] = STRING_TABLE.__str169 | 0; + HEAP32[$mode >> 2] = 29; + var $ret_0_be = $ret_7; + var $next_0_be = $next_51; + var $put_0_be = $put_0; + var $have_0_be = $have_51; + var $left_0_be = $left_0; + var $hold_0_be = $hold_47; + var $bits_0_be = $bits_47; + var $out_0_be = $out_0; + break $_$380; + } + } while (0); + var $174 = HEAPU32[$33 >> 2]; + var $cmp1570 = $sub1560 >>> 0 > $174 >>> 0; + if ($cmp1570) { + var $sub1574 = $sub1560 - $174 | 0; + var $175 = HEAP32[$34 >> 2]; + var $176 = HEAP32[$35 >> 2]; + var $sub1575 = $176 - $sub1574 | 0; + var $add_ptr1576 = $175 + $sub1575 | 0; + var $from_0 = $add_ptr1576; + var $copy_7 = $sub1574; + } else { + var $177 = HEAP32[$34 >> 2]; + var $sub1580 = $174 - $sub1560 | 0; + var $add_ptr1581 = $177 + $sub1580 | 0; + var $from_0 = $add_ptr1581; + var $copy_7 = $sub1560; + } + var $copy_7; + var $from_0; + var $178 = HEAPU32[$21 >> 2]; + var $cmp1584 = $copy_7 >>> 0 > $178 >>> 0; + if (!$cmp1584) { + var $from_1 = $from_0; + var $copy_8 = $copy_7; + var $180 = $178; + break; + } + var $from_1 = $from_0; + var $copy_8 = $178; + var $180 = $178; + } else { + var $idx_neg = -$171 | 0; + var $add_ptr1591 = $put_0 + $idx_neg | 0; + var $179 = HEAP32[$21 >> 2]; + var $from_1 = $add_ptr1591; + var $copy_8 = $179; + var $180 = $179; + } + } while (0); + var $180; + var $copy_8; + var $from_1; + var $cmp1594 = $copy_8 >>> 0 > $left_0 >>> 0; + var $copy_9 = $cmp1594 ? $left_0 : $copy_8; + var $sub1600 = $180 - $copy_9 | 0; + HEAP32[$21 >> 2] = $sub1600; + var $181 = $copy_8 ^ -1; + var $182 = $left_0 ^ -1; + var $183 = $181 >>> 0 > $182 >>> 0; + var $umax = $183 ? $181 : $182; + var $from_2 = $from_1; + var $put_1 = $put_0; + var $copy_10 = $copy_9; + while (1) { + var $copy_10; + var $put_1; + var $from_2; + var $incdec_ptr1602 = $from_2 + 1 | 0; + var $184 = HEAP8[$from_2]; + var $incdec_ptr1603 = $put_1 + 1 | 0; + HEAP8[$put_1] = $184; + var $dec1605 = $copy_10 - 1 | 0; + var $tobool1606 = ($dec1605 | 0) == 0; + if ($tobool1606) { + break; + } + var $from_2 = $incdec_ptr1602; + var $put_1 = $incdec_ptr1603; + var $copy_10 = $dec1605; + } + var $sub1598 = $left_0 - $copy_9 | 0; + var $scevgep_sum = $umax ^ -1; + var $scevgep632 = $put_0 + $scevgep_sum | 0; + var $185 = HEAP32[$21 >> 2]; + var $cmp1609 = ($185 | 0) == 0; + if (!$cmp1609) { + var $ret_0_be = $ret_7; + var $next_0_be = $next_51; + var $put_0_be = $scevgep632; + var $have_0_be = $have_51; + var $left_0_be = $sub1598; + var $hold_0_be = $hold_47; + var $bits_0_be = $bits_47; + var $out_0_be = $out_0; + break; + } + HEAP32[$mode >> 2] = 20; + var $ret_0_be = $ret_7; + var $next_0_be = $next_51; + var $put_0_be = $scevgep632; + var $have_0_be = $have_51; + var $left_0_be = $sub1598; + var $hold_0_be = $hold_47; + var $bits_0_be = $bits_47; + var $out_0_be = $out_0; + } + } while (0); + var $out_0_be; + var $bits_0_be; + var $hold_0_be; + var $left_0_be; + var $have_0_be; + var $put_0_be; + var $next_0_be; + var $ret_0_be; + var $_pre883 = HEAP32[$mode >> 2]; + var $ret_0 = $ret_0_be; + var $next_0 = $next_0_be; + var $put_0 = $put_0_be; + var $have_0 = $have_0_be; + var $left_0 = $left_0_be; + var $hold_0 = $hold_0_be; + var $bits_0 = $bits_0_be; + var $out_0 = $out_0_be; + var $49 = $_pre883; + } + var $out_4; + var $bits_54; + var $hold_54; + var $have_58; + var $next_58; + var $ret_8; + HEAP32[$next_out >> 2] = $put_0; + HEAP32[$avail_out >> 2] = $left_0; + HEAP32[$next_in >> 2] = $next_58; + HEAP32[$avail_in15 >> 2] = $have_58; + HEAP32[$11 >> 2] = $hold_54; + HEAP32[$13 >> 2] = $bits_54; + var $199 = HEAP32[$35 >> 2]; + var $tobool1755 = ($199 | 0) == 0; + do { + if ($tobool1755) { + var $200 = HEAPU32[$mode >> 2]; + var $cmp1758 = $200 >>> 0 < 26; + if (!$cmp1758) { + __label__ = 300; + break; + } + var $201 = HEAP32[$avail_out >> 2]; + var $cmp1762 = ($out_4 | 0) == ($201 | 0); + if ($cmp1762) { + __label__ = 300; + break; + } + __label__ = 298; + break; + } else { + __label__ = 298; + } + } while (0); + do { + if (__label__ == 298) { + var $call1765 = _updatewindow($strm, $out_4); + var $tobool1766 = ($call1765 | 0) == 0; + if ($tobool1766) { + break; + } + HEAP32[$mode >> 2] = 30; + var $retval_0 = -4; + break $_$2; + } + } while (0); + var $202 = HEAPU32[$avail_in15 >> 2]; + var $203 = HEAPU32[$avail_out >> 2]; + var $sub1774 = $out_4 - $203 | 0; + var $total_in = $strm + 8 | 0; + var $204 = HEAP32[$total_in >> 2]; + var $sub1772 = $10 - $202 | 0; + var $add1775 = $sub1772 + $204 | 0; + HEAP32[$total_in >> 2] = $add1775; + var $205 = HEAP32[$total_out >> 2]; + var $add1777 = $205 + $sub1774 | 0; + HEAP32[$total_out >> 2] = $add1777; + var $206 = HEAP32[$36 >> 2]; + var $add1779 = $206 + $sub1774 | 0; + HEAP32[$36 >> 2] = $add1779; + var $207 = HEAP32[$15 >> 2]; + var $tobool1781 = ($207 | 0) == 0; + var $tobool1783 = ($out_4 | 0) == ($203 | 0); + var $or_cond34 = $tobool1781 | $tobool1783; + if (!$or_cond34) { + var $208 = HEAP32[$17 >> 2]; + var $tobool1786 = ($208 | 0) == 0; + var $209 = HEAP32[$16 >> 2]; + var $210 = HEAP32[$next_out >> 2]; + var $idx_neg1790 = -$sub1774 | 0; + var $add_ptr1791 = $210 + $idx_neg1790 | 0; + if ($tobool1786) { + var $call1798 = _adler32($209, $add_ptr1791, $sub1774); + var $cond1800 = $call1798; + } else { + var $call1792 = _crc32($209, $add_ptr1791, $sub1774); + var $cond1800 = $call1792; + } + var $cond1800; + HEAP32[$16 >> 2] = $cond1800; + HEAP32[$adler >> 2] = $cond1800; + } + var $211 = HEAP32[$13 >> 2]; + var $212 = HEAP32[$24 >> 2]; + var $tobool1806 = ($212 | 0) != 0; + var $cond1807 = $tobool1806 ? 64 : 0; + var $213 = HEAP32[$mode >> 2]; + var $cmp1810 = ($213 | 0) == 11; + var $cond1812 = $cmp1810 ? 128 : 0; + var $cmp1815 = ($213 | 0) == 19; + if ($cmp1815) { + var $214 = 256; + } else { + var $cmp1818 = ($213 | 0) == 14; + var $phitmp = $cmp1818 ? 256 : 0; + var $214 = $phitmp; + } + var $214; + var $add1808 = $cond1807 + $211 | 0; + var $add1813 = $add1808 + $cond1812 | 0; + var $add1821 = $add1813 + $214 | 0; + var $data_type = $strm + 44 | 0; + HEAP32[$data_type >> 2] = $add1821; + var $cmp1822 = ($10 | 0) == ($202 | 0); + var $or_cond35 = $cmp1822 & $tobool1783; + var $cmp1828 = ($flush | 0) == 4; + var $or_cond36 = $or_cond35 | $cmp1828; + var $cmp1831 = ($ret_8 | 0) == 0; + var $or_cond37 = $or_cond36 & $cmp1831; + var $ret_9 = $or_cond37 ? -5 : $ret_8; + var $retval_0 = $ret_9; + } + } while (0); + var $retval_0; + STACKTOP = __stackBase__; + return $retval_0; + return null; +} +// EMSCRIPTEN_GENERATED_FUNCTIONS: ["f", "g", "h", "py", "r", "t", "f2", "f3", "llvm3_1", "_inflate"] diff --git a/tools/eliminator/eliminator.coffee b/tools/eliminator/eliminator.coffee index a4c98930..05e3788b 100644 --- a/tools/eliminator/eliminator.coffee +++ b/tools/eliminator/eliminator.coffee @@ -107,8 +107,8 @@ class Eliminator # Maps a given single-def variable to the AST expression of its initial value. @initialValue = {} # Maps identifiers to single-def variables which reference it in their - # initial value. - @dependsOn = {} + # initial value, i.e., which other variables it affects. + @affects = {} # Runs the eliminator on a given function body updating the AST in-place. # @returns: The number of variables eliminated, or undefined if skipped. @@ -157,7 +157,7 @@ class Eliminator # Analyzes the initial values of single-def variables. Requires basic variable # stats to have been calculated. Fills the following member variables: - # dependsOn + # affects # dependsOnAGlobal # usesOnlySimpleNodes analyzeInitialValues: -> @@ -170,25 +170,38 @@ class Eliminator else if type is 'name' reference = node[1] if reference != 'undefined' - if not @dependsOn[reference]? then @dependsOn[reference] = {} + if not @affects[reference]? then @affects[reference] = {} if not @isLocal[reference] then @dependsOnAGlobal[varName] = true - @dependsOn[reference][varName] = true + @affects[reference][varName] = true return undefined return undefined - # Updates the dependency graph (@dependsOn) to its transitive closure and + # Updates the dependency graph (@affects) to its transitive closure and # synchronizes @dependsOnAGlobal to the new dependencies. calculateTransitiveDependencies: -> incomplete = true + todo = {} + for element of @affects + todo[element] = 1 + + #process.stdout.write 'pre ' + JSON.stringify(@affects, null, ' ') + '\n' + while incomplete incomplete = false - for target, sources of @dependsOn - for source of sources - for source2 of @dependsOn[source] - if not @dependsOn[target][source2] - if not @isLocal[target] then @dependsOnAGlobal[source2] = true - @dependsOn[target][source2] = true - incomplete = true + nextTodo = {} + for source, targets of @affects + for target of targets + if todo[target] + for target2 of @affects[target] + if not targets[target2] + if not @isLocal[source] then @dependsOnAGlobal[target2] = true + targets[target2] = true + nextTodo[source] = 1 + incomplete = true + todo = nextTodo + + #process.stdout.write 'post ' + JSON.stringify(@affects, null, ' ') + '\n' + return undefined # Analyzes the live ranges of single-def variables. Requires dependencies to @@ -211,8 +224,8 @@ class Eliminator while reference[0] != 'name' reference = reference[1] reference = reference[1] - if @dependsOn[reference]? - for varName of @dependsOn[reference] + if @affects[reference]? + for varName of @affects[reference] if isLive[varName] isLive[varName] = false @@ -264,8 +277,8 @@ class Eliminator if @isSingleDef[varName] isLive[varName] = true # Mark variables that depend on it as no longer live - if @dependsOn[varName]? - for varNameDep of @dependsOn[varName] + if @affects[varName]? + for varNameDep of @affects[varName] if isLive[varNameDep] isLive[varNameDep] = false return node @@ -370,14 +383,8 @@ class ExpressionOptimizer # function, then writes the optimized result to stdout. main = -> # Get the parse tree. - if os.platform().substr(0, 3) != 'win' - src = fs.readFileSync('/dev/stdin').toString() - else - # The following seems to work on windows, but fails on linux.. - src = '' - size = fs.fstatSync(process.stdin.fd).size - if size > 0 - src = fs.readSync(process.stdin.fd, size)[0] + #process.stderr.write(JSON.stringify(process.argv[2]) + '\n') + src = fs.readFileSync(process.argv[2]).toString() throw 'Cannot identify generated functions' if GENERATED_FUNCTIONS_MARKER in src generatedFunctionsLine = src.split('\n').filter (line) -> @@ -386,22 +393,22 @@ main = -> ast = uglify.parser.parse src - #process.stderr.write(JSON.stringify(ast) + '\n') + ##process.stderr.write(JSON.stringify(ast) + '\n') # Run on all functions. traverse ast, (node, type) -> if type in ['defun', 'function'] and isGenerated node[1] # Run the eliminator - process.stderr.write (node[1] || '(anonymous)') + '\n' + #process.stderr.write (node[1] || '(anonymous)') + '\n' eliminated = new Eliminator(node).run() if eliminated? - process.stderr.write " Eliminated #{eliminated} vars.\n" + #process.stderr.write " Eliminated #{eliminated} vars.\n" # Run the expression optimizer new ExpressionOptimizer(node[3]).run() else - process.stderr.write ' Skipped.\n' + #process.stderr.write ' Skipped.\n' return undefined diff --git a/tools/file_packager.py b/tools/file_packager.py new file mode 100644 index 00000000..3844b4ae --- /dev/null +++ b/tools/file_packager.py @@ -0,0 +1,399 @@ +''' +A tool that generates FS API calls to generate a filesystem, and packages the files +to work with that. + +This is called by emcc. You can also call it yourself. + +Usage: + + file_packager.py TARGET [--preload A [B..]] [--embed C [D..]] [--compress COMPRESSION_DATA] [--pre-run] [--crunch[=X]] + +Notes: + + --pre-run Will generate wrapper code that does preloading in Module.preRun. This is necessary if you add this + code before the main file has been loading, which includes necessary components like addRunDependency. + + --crunch=X Will compress dxt files to crn with quality level X. The crunch commandline tool must be present + and CRUNCH should be defined in ~/.emscripten that points to it. JS crunch decompressing code will + be added to convert the crn to dds in the browser. + crunch-worker.js will be generated in the current directory. You should include that file when + packaging your site. + DDS files will not be crunched if the .crn is more recent than the .dds. This prevents a lot of + unneeded computation. + +TODO: You can also provide .crn files yourself, pre-crunched. With this option, they will be decompressed + to dds files in the browser, exactly the same as if this tool compressed them. +''' + +import os, sys, shutil + +from shared import Compression, execute, suffix, unsuffixed +import shared +from subprocess import Popen, PIPE, STDOUT + +data_target = sys.argv[1] + +IMAGE_SUFFIXES = ('.jpg', '.png', '.bmp') +AUDIO_SUFFIXES = ('.ogg', '.wav', '.mp3') +AUDIO_MIMETYPES = { 'ogg': 'audio/ogg', 'wav': 'audio/wav', 'mp3': 'audio/mpeg' } +CRUNCH_INPUT_SUFFIX = '.dds' +CRUNCH_OUTPUT_SUFFIX = '.crn' + +DDS_HEADER_SIZE = 128 + +data_files = [] +in_preload = False +in_embed = False +has_preloaded = False +in_compress = 0 +pre_run = False +crunch = 0 + +for arg in sys.argv[1:]: + if arg == '--preload': + in_preload = True + in_embed = False + has_preloaded = True + in_compress = 0 + elif arg == '--embed': + in_embed = True + in_preload = False + in_compress = 0 + elif arg == '--compress': + Compression.on = True + in_compress = 1 + in_preload = False + in_embed = False + elif arg == '--pre-run': + pre_run = True + in_preload = False + in_embed = False + in_compress = 0 + elif arg.startswith('--crunch'): + from shared import CRUNCH + crunch = arg.split('=')[1] if '=' in arg else '128' + in_preload = False + in_embed = False + in_compress = 0 + elif in_preload: + data_files.append({ 'name': arg, 'mode': 'preload' }) + elif in_embed: + data_files.append({ 'name': arg, 'mode': 'embed' }) + elif in_compress: + if in_compress == 1: + Compression.encoder = arg + in_compress = 2 + elif in_compress == 2: + Compression.decoder = arg + in_compress = 3 + elif in_compress == 3: + Compression.js_name = arg + in_compress = 0 + +code = ''' +function assert(check, msg) { + if (!check) throw msg; +} +''' + +if has_preloaded: + code += ''' + var BlobBuilder = typeof MozBlobBuilder != "undefined" ? MozBlobBuilder : (typeof WebKitBlobBuilder != "undefined" ? WebKitBlobBuilder : console.log("warning: cannot build blobs")); + var URLObject = typeof window != "undefined" ? (window.URL ? window.URL : window.webkitURL) : console.log("warning: cannot create object URLs"); + var hasBlobConstructor; + try { + new Blob(); + hasBlobConstructor = true; + } catch(e) { + hasBlobConstructor = false; + console.log("warning: no blob constructor, cannot create blobs with mimetypes"); + } +''' + + code += 'Module["preloadedImages"] = {}; // maps url to image data\n' + code += 'Module["preloadedAudios"] = {}; // maps url to audio data\n' + +# Expand directories into individual files +def add(mode, dirname, names): + for name in names: + fullname = os.path.join(dirname, name) + if not os.path.isdir(fullname): + data_files.append({ 'name': fullname, 'mode': mode }) + +for file_ in data_files: + if os.path.isdir(file_['name']): + os.path.walk(file_['name'], add, file_['mode']) +data_files = filter(lambda file_: not os.path.isdir(file_['name']), data_files) + +for file_ in data_files: + file_['name'] = file_['name'].replace(os.path.sep, '/') # name in the filesystem, native and emulated + file_['localname'] = file_['name'] # name to actually load from local filesystem, after transformations + +# Remove duplicates (can occur naively, for example preload dir/, preload dir/subdir/) +seen = {} +def was_seen(name): + if seen.get(name): return True + seen[name] = 1 + return False +data_files = filter(lambda file_: not was_seen(file_['name']), data_files) + +# Crunch files +if crunch: + shutil.copyfile(shared.path_from_root('tools', 'crunch-worker.js'), 'crunch-worker.js') + print ''' + var decrunchWorker = new Worker('crunch-worker.js'); + var decrunchCallbacks = []; + decrunchWorker.onmessage = function(msg) { + decrunchCallbacks[msg.data.callbackID](msg.data.data); + console.log('decrunched ' + msg.data.filename + ' in ' + msg.data.time + ' ms, ' + msg.data.data.length + ' bytes'); + decrunchCallbacks[msg.data.callbackID] = null; + }; + function requestDecrunch(filename, data, callback) { + decrunchWorker.postMessage({ + filename: filename, + data: data, + callbackID: decrunchCallbacks.length + }); + decrunchCallbacks.push(callback); + } +''' + + for file_ in data_files: + if file_['name'].endswith(CRUNCH_INPUT_SUFFIX): + # Do not crunch if crunched version exists and is more recent than dds source + crunch_name = unsuffixed(file_['name']) + CRUNCH_OUTPUT_SUFFIX + file_['localname'] = crunch_name + try: + crunch_time = os.stat(crunch_name).st_mtime + dds_time = os.stat(file_['name']).st_mtime + if dds_time < crunch_time: continue + except: + pass # if one of them does not exist, continue on + + # guess at format. this lets us tell crunch to not try to be clever and use odd formats like DXT5_AGBR + try: + format = Popen(['file', file_['name']], stdout=PIPE).communicate()[0] + if 'DXT5' in format: + format = ['-dxt5'] + elif 'DXT1' in format: + format = ['-dxt1'] + else: + raise Exception('unknown format') + except: + format = [] + Popen([CRUNCH, '-file', file_['name'], '-quality', crunch] + format, stdout=sys.stderr).communicate() + shutil.move(os.path.basename(crunch_name), crunch_name) # crunch places files in the current dir + # prepend the dds header + crunched = open(crunch_name, 'rb').read() + c = open(crunch_name, 'wb') + c.write(open(file_['name'], 'rb').read()[:DDS_HEADER_SIZE]) + c.write(crunched) + c.close() + +# Set up folders +partial_dirs = [] +for file_ in data_files: + dirname = os.path.dirname(file_['name']) + dirname = dirname.lstrip('/') # absolute paths start with '/', remove that + if dirname != '': + parts = dirname.split('/') + for i in range(len(parts)): + partial = '/'.join(parts[:i+1]) + if partial not in partial_dirs: + code += '''Module['FS_createFolder']('/%s', '%s', true, true);\n''' % ('/'.join(parts[:i]), parts[i]) + partial_dirs.append(partial) + +if has_preloaded: + # Bundle all datafiles into one archive. Avoids doing lots of simultaneous XHRs which has overhead. + data = open(data_target, 'wb') + start = 0 + for file_ in data_files: + file_['data_start'] = start + curr = open(file_['localname'], 'rb').read() + file_['data_end'] = start + len(curr) + print >> sys.stderr, 'bundling', file_['name'], file_['localname'], file_['data_start'], file_['data_end'] + start += len(curr) + data.write(curr) + data.close() + if Compression.on: + Compression.compress(data_target) + + # Data requests - for getting a block of data out of the big archive - have a similar API to XHRs + code += ''' + function DataRequest() {} + DataRequest.prototype = { + requests: {}, + open: function(mode, name) { + this.requests[name] = this; + }, + send: function() {} + }; + ''' + +counter = 0 +for file_ in data_files: + filename = file_['name'] + if file_['mode'] == 'embed': + # Embed + code += '''Module['FS_createDataFile']('/', '%s', %s, true, true);\n''' % (os.path.basename(filename), str(map(ord, open(file_['localname'], 'rb').read()))) + elif file_['mode'] == 'preload': + # Preload + varname = 'filePreload%d' % counter + counter += 1 + image = filename.endswith(IMAGE_SUFFIXES) + audio = filename.endswith(AUDIO_SUFFIXES) + dds = crunch and filename.endswith(CRUNCH_INPUT_SUFFIX) + + prepare = '' + finish = "Module['removeRunDependency']();\n" + + if image: + finish = ''' + var bb = new BlobBuilder(); + bb.append(byteArray.buffer); + var b = bb.getBlob(); + var url = URLObject.createObjectURL(b); + var img = new Image(); + img.onload = function() { + assert(img.complete, 'Image %(filename)s could not be decoded'); + var canvas = document.createElement('canvas'); + canvas.width = img.width; + canvas.height = img.height; + var ctx = canvas.getContext('2d'); + ctx.drawImage(img, 0, 0); + Module["preloadedImages"]['%(filename)s'] = canvas; + URLObject.revokeObjectURL(url); + Module['removeRunDependency'](); + }; + img.onerror = function(event) { + console.log('Image %(filename)s could not be decoded'); + }; + img.src = url; +''' % { 'filename': filename } + elif audio: + # Need actual blob constructor here, to set the mimetype or else audios fail to decode + finish = ''' + if (hasBlobConstructor) { + var b = new Blob([byteArray.buffer], { type: '%(mimetype)s' }); + var url = URLObject.createObjectURL(b); // XXX we never revoke this! + var audio = new Audio(); + audio.removedDependency = false; + audio['oncanplaythrough'] = function() { // XXX string for closure + audio['oncanplaythrough'] = null; + Module["preloadedAudios"]['%(filename)s'] = audio; + if (!audio.removedDependency) { + Module['removeRunDependency'](); + audio.removedDependency = true; + } + }; + audio.onerror = function(event) { + if (!audio.removedDependency) { + console.log('Audio %(filename)s could not be decoded or timed out trying to decode'); + Module['removeRunDependency'](); + audio.removedDependency = true; + } + }; + setTimeout(audio.onerror, 2000); // workaround for chromium bug 124926 (still no audio with this, but at least we don't hang) + audio.src = url; + } else { + Module["preloadedAudios"]['%(filename)s'] = new Audio(); // empty shim + Module['removeRunDependency'](); + } +''' % { 'filename': filename, 'mimetype': AUDIO_MIMETYPES[suffix(filename)] } + elif dds: + # decompress crunch format into dds + prepare = ''' + var ddsHeader = byteArray.subarray(0, %(dds_header_size)d); + requestDecrunch('%(filename)s', byteArray.subarray(%(dds_header_size)d), function(ddsData) { + byteArray = new Uint8Array(ddsHeader.length + ddsData.length); + byteArray.set(ddsHeader, 0); + byteArray.set(ddsData, %(dds_header_size)d); +''' % { 'filename': filename, 'dds_header_size': DDS_HEADER_SIZE } + + finish = ''' + Module['removeRunDependency'](); + }); +''' + + code += ''' + var %(varname)s = new %(request)s(); + %(varname)s.open('GET', '%(filename)s', true); + %(varname)s.responseType = 'arraybuffer'; + %(varname)s.onload = function() { + var arrayBuffer = %(varname)s.response; + assert(arrayBuffer, 'Loading file %(filename)s failed.'); + var byteArray = arrayBuffer.byteLength ? new Uint8Array(arrayBuffer) : arrayBuffer; + %(prepare)s + Module['FS_createDataFile']('/%(dirname)s', '%(basename)s', byteArray, true, true); + %(finish)s + }; + Module['addRunDependency'](); + %(varname)s.send(null); +''' % { + 'request': 'DataRequest', # In the past we also supported XHRs here + 'varname': varname, + 'filename': filename, + 'dirname': os.path.dirname(filename), + 'basename': os.path.basename(filename), + 'prepare': prepare, + 'finish': finish + } + else: + assert 0 + +if has_preloaded: + # Get the big archive and split it up + use_data = '' + for file_ in data_files: + if file_['mode'] == 'preload': + use_data += ''' + curr = DataRequest.prototype.requests['%s']; + curr.response = byteArray.subarray(%d,%d); + curr.onload(); + ''' % (file_['name'], file_['data_start'], file_['data_end']) + use_data += " Module['removeRunDependency']();\n" + + if Compression.on: + use_data = ''' + Module["decompress"](byteArray, function(decompressed) { + byteArray = new Uint8Array(decompressed); + %s + }); +''' % use_data + + code += ''' + var dataFile = new XMLHttpRequest(); + dataFile.open('GET', '%s', true); + dataFile.responseType = 'arraybuffer'; + dataFile.onload = function() { + var arrayBuffer = dataFile.response; + assert(arrayBuffer, 'Loading data file failed.'); + var byteArray = new Uint8Array(arrayBuffer); + var curr; + %s + }; + Module['addRunDependency'](); + dataFile.send(null); + if (Module['setStatus']) Module['setStatus']('Downloading...'); + ''' % (Compression.compressed_name(data_target) if Compression.on else data_target, use_data) + +if pre_run: + print ''' + if (typeof Module == 'undefined') Module = {}; + if (!Module['preRun']) Module['preRun'] = []; + Module["preRun"].push(function() { +''' + +print code + +if pre_run: + print ' });\n' + +if crunch: + print ''' + if (!Module['postRun']) Module['postRun'] = []; + Module["postRun"].push(function() { + decrunchWorker.terminate(); + }); +''' + diff --git a/tools/ie7_fix.py b/tools/ie7_fix.py new file mode 100644 index 00000000..3cdabb07 --- /dev/null +++ b/tools/ie7_fix.py @@ -0,0 +1,14 @@ +''' +Simple tool to replace string lastchar from array access [] to charAt, for the purpose of IE7 support +''' +import os, sys, re + +inputFilename = sys.argv[1]; +outputFilename = sys.argv[2]; + +inputFiledata = open(inputFilename).read() +outputFile = open(outputFilename, "w") + +outputFile.write(re.sub('type\[type.length - 1\] ===? "\*"', 'type.charAt(type.length - 1) == "*"', inputFiledata)) + +outputFile.close() diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js index b51fe22e..d58c8c6c 100644 --- a/tools/js-optimizer.js +++ b/tools/js-optimizer.js @@ -119,6 +119,8 @@ load('utility.js'); var FUNCTION = set('defun', 'function'); var LOOP = set('do', 'while', 'for'); var LOOP_FLOW = set('break', 'continue'); +var ASSIGN_OR_ALTER = set('assign', 'unary-postfix', 'unary-prefix'); +var CONTROL_FLOW = set('do', 'while', 'for', 'if', 'switch'); var NULL_NODE = ['name', 'null']; var UNDEFINED_NODE = ['unary-prefix', 'void', ['num', 0]]; @@ -669,6 +671,18 @@ function optimizeShiftsInternal(ast, conservative) { } } } + /* XXX - theoretically useful optimization(s), but commented out as not helpful in practice + // Transform (x << 2) >> 2 into x & mask or something even simpler + if (type == 'binary' && node[1] == '>>' && node[3][0] == 'num' && + node[2][0] == 'binary' && node[2][1] == '<<' && node[2][3][0] == 'num' && node[3][1] == node[2][3][1]) { + var subNode = node[2]; + var shifts = node[3][1]; + var mask = ((0xffffffff << shifts) >>> shifts) | 0; + return ['binary', '&', subNode[2], ['num', mask]]; + //return ['binary', '|', subNode[2], ['num', 0]]; + //return subNode[2]; + } + */ }); // Re-combine remaining shifts, to undo the breaking up we did before. may require reordering inside +'s traverse(fun, function(node, type, stack) { @@ -1140,6 +1154,180 @@ function loopOptimizer(ast) { vacuum(ast); } +// Very simple 'registerization', coalescing of variables into a smaller number. +// We do not optimize when there are switches, so this pass only makes sense with +// relooping. +// TODO: Consider how this fits in with the rest of the optimization toolchain. Do +// we still need the eliminator? Closure? And in what order? Perhaps just +// closure simple? +function registerize(ast) { + traverseGeneratedFunctions(ast, function(fun) { + // Replace all var definitions with assignments; we will add var definitions at the top after we registerize + // We also mark local variables - i.e., having a var definition + var localVars = {}; + var hasSwitch = false; // we cannot optimize variables if there is a switch + traverse(fun, function(node, type) { + if (type == 'var') { + node[1].forEach(function(defined) { localVars[defined[0]] = 1 }); + var vars = node[1].filter(function(varr) { return varr[1] }); + if (vars.length > 1) { + var ret = ['stat', []]; + var curr = ret[1]; + for (var i = 0; i < vars.length-1; i++) { + curr[0] = 'seq'; + curr[1] = ['assign', true, ['name', vars[i][0]], vars[i][1]]; + if (i != vars.length-2) curr = curr[2] = []; + } + curr[2] = ['assign', true, ['name', vars[vars.length-1][0]], vars[vars.length-1][1]]; + return ret; + } else if (vars.length == 1) { + return ['stat', ['assign', true, ['name', vars[0][0]], vars[0][1]]]; + } else { + return emptyNode(); + } + } else if (type == 'switch') { + hasSwitch = true; + } + }); + vacuum(fun); + // Find the # of uses of each variable. + // While doing so, check if all a variable's uses are dominated in a simple + // way by a simple assign, if so, then we can assign its register to it + // just for its definition to its last use, and not to the entire toplevel loop, + // we call such variables "optimizable" + var varUses = {}; + var level = 1; + var levelDominations = {}; + var varLevels = {}; + var possibles = {}; + var unoptimizables = {}; + traverse(fun, function(node, type) { + if (type == 'name') { + var name = node[1]; + if (localVars[name]) { + if (!varUses[name]) varUses[name] = 0; + varUses[name]++; + if (possibles[name] && !varLevels[name]) unoptimizables[name] = 1; // used outside of simple domination + } + } else if (type == 'assign' && typeof node[1] != 'string') { + if (node[2] && node[2][0] == 'name') { + var name = node[2][1]; + // if local and not yet used, this might be optimizable if we dominate + // all other uses + if (localVars[name] && !varUses[name] && !varLevels[name]) { + possibles[name] = 1; + varLevels[name] = level; + if (!levelDominations[level]) levelDominations[level] = {}; + levelDominations[level][name] = 1; + } + } + } else if (type in CONTROL_FLOW) { + level++; + } + }, function(node, type) { + if (type in CONTROL_FLOW) { + // Invalidate all dominating on this level, further users make it unoptimizable + for (var name in levelDominations[level]) { + varLevels[name] = 0; + } + levelDominations[level] = null; + level--; + } + }); + var optimizables = {}; + if (!hasSwitch) { + for (var possible in possibles) { + if (!unoptimizables[possible]) optimizables[possible] = 1; + } + } + // Go through the function's code, assigning 'registers'. + // The only tricky bit is to keep variables locked on a register through loops, + // since they can potentially be returned to. Optimizable variables lock onto + // loops that they enter, unoptimizable variables lock in a conservative way + // into the topmost loop. + // Note that we cannot lock onto a variable in a loop if it was used and free'd + // before! (then they could overwrite us in the early part of the loop). For now + // we just use a fresh register to make sure we avoid this, but it could be + // optimized to check for safe registers (free, and not used in this loop level). + var varRegs = {}; // maps variables to the register they will use all their life + var freeRegs = []; + var nextReg = 1; + var fullNames = {}; + var loopRegs = {}; // for each loop nesting level, the list of bound variables + var loops = 0; // 0 is toplevel, 1 is first loop, etc + var saved = 0; + var activeOptimizables = {}; + var optimizableLoops = {}; + function decUse(name) { + if (!varUses[name]) return false; // no uses left, or not a relevant variable + if (optimizables[name]) activeOptimizables[name] = 1; + var reg = varRegs[name]; + if (!reg) { + // acquire register + if (optimizables[name] && freeRegs.length > 0) { + reg = freeRegs.pop(); + saved++; + } else { + reg = nextReg++; + fullNames[reg] = 'r' + reg; // TODO: even smaller names + } + varRegs[name] = reg; + } + varUses[name]--; + assert(varUses[name] >= 0); + if (varUses[name] == 0) { + if (optimizables[name]) delete activeOptimizables[name]; + // If we are not in a loop, or we are optimizable and not bound to a loop + // (we might have been in one but left it), we can free the register now. + if (loops == 0 || (optimizables[name] && !optimizableLoops[name])) { + // free register + freeRegs.push(reg); + } else { + // when the relevant loop is exited, we will free the register + var releventLoop = optimizables[name] ? (optimizableLoops[name] || 1) : 1; + if (!loopRegs[releventLoop]) loopRegs[releventLoop] = []; + loopRegs[releventLoop].push(reg); + } + } + return true; + } + traverse(fun, function(node, type) { // XXX we rely on traversal order being the same as execution order here + if (type == 'name') { + var name = node[1]; + if (decUse(name)) { + node[1] = fullNames[varRegs[name]]; + } + } else if (type in LOOP) { + loops++; + // Active optimizables lock onto this loop, if not locked onto one that encloses this one + for (var name in activeOptimizables) { + if (!optimizableLoops[name]) { + optimizableLoops[name] = loops; + } + } + } + }, function(node, type) { + if (type in LOOP) { + // Free registers that were locked to this loop + if (loopRegs[loops]) { + freeRegs = freeRegs.concat(loopRegs[loops]); + loopRegs[loops] = []; + } + loops--; + } + }); + // Add vars at the beginning + if (nextReg > 1) { + var vars = []; + for (var i = 1; i < nextReg; i++) { + vars.push([fullNames[i]]); + } + getStatements(fun).unshift(['var', vars]); + } + //printErr(fun[1] + ': saved ' + saved + ' / ' + (saved + nextReg - 1) + ' vars through registerization'); // not totally accurate + }); +} + // Passes table var compress = false; @@ -1156,6 +1344,7 @@ var passes = { simplifyExpressionsPost: simplifyExpressionsPost, hoistMultiples: hoistMultiples, loopOptimizer: loopOptimizer, + registerize: registerize, compress: function() { compress = true; } }; diff --git a/tools/scons/site_scons/site_tools/emscripten/emscripten.py b/tools/scons/site_scons/site_tools/emscripten/emscripten.py index cb14b58e..7ccf2c5f 100644 --- a/tools/scons/site_scons/site_tools/emscripten/emscripten.py +++ b/tools/scons/site_scons/site_tools/emscripten/emscripten.py @@ -28,7 +28,7 @@ def generate(env, emscripten_path=None, **kw): env.Replace(CC = os.path.join(emscPath, "emcc" )) env.Replace(CXX = os.path.join(emscPath, "em++" )) - env.Replace(LINK = os.path.join(emscPath, "emld" )) + env.Replace(LINK = os.path.join(emscPath, "emcc" )) # SHLINK and LDMODULE should use LINK so no # need to change them here diff --git a/tools/shared.py b/tools/shared.py index 532f561f..997c0ad9 100644 --- a/tools/shared.py +++ b/tools/shared.py @@ -1,4 +1,4 @@ -import shutil, time, os, sys, json, tempfile, copy, shlex +import shutil, time, os, sys, json, tempfile, copy, shlex, atexit, subprocess from subprocess import Popen, PIPE, STDOUT from tempfile import mkstemp @@ -6,15 +6,22 @@ __rootpath__ = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) def path_from_root(*pathelems): return os.path.join(__rootpath__, *pathelems) -# Config file +# Emscripten configuration is done through the EM_CONFIG environment variable. +# If the string value contained in this environment variable contains newline +# separated definitions, then these definitions will be used to configure +# Emscripten. Otherwise, the string is understood to be a path to a settings +# file that contains the required definitions. EM_CONFIG = os.environ.get('EM_CONFIG') if not EM_CONFIG: EM_CONFIG = '~/.emscripten' -CONFIG_FILE = os.path.expanduser(EM_CONFIG) -if not os.path.exists(CONFIG_FILE): - shutil.copy(path_from_root('settings.py'), CONFIG_FILE) - print >> sys.stderr, ''' +if '\n' in EM_CONFIG: + CONFIG_FILE = None +else: + CONFIG_FILE = os.path.expanduser(EM_CONFIG) + if not os.path.exists(CONFIG_FILE): + shutil.copy(path_from_root('settings.py'), CONFIG_FILE) + print >> sys.stderr, ''' ============================================================================== Welcome to Emscripten! @@ -28,11 +35,12 @@ make sure LLVM_ROOT and NODE_JS are correct. This command will now exit. When you are done editing those paths, re-run it. ============================================================================== ''' % (EM_CONFIG, CONFIG_FILE) - sys.exit(0) + sys.exit(0) try: - exec(open(CONFIG_FILE, 'r').read()) + config_text = open(CONFIG_FILE, 'r').read() if CONFIG_FILE else EM_CONFIG + exec(config_text) except Exception, e: - print >> sys.stderr, 'Error in evaluating %s (at %s): %s' % (EM_CONFIG, CONFIG_FILE, str(e)) + print >> sys.stderr, 'Error in evaluating %s (at %s): %s, text: %s' % (EM_CONFIG, CONFIG_FILE, str(e), config_text) sys.exit(1) # Check that basic stuff we need (a JS engine to compile, Node.js, and Clang and LLVM) @@ -43,6 +51,8 @@ except Exception, e: def check_sanity(force=False): try: if not force: + if not CONFIG_FILE: + return # config stored directly in EM_CONFIG => skip sanity checks settings_mtime = os.stat(CONFIG_FILE).st_mtime sanity_file = CONFIG_FILE + '_sanity' try: @@ -52,6 +62,9 @@ def check_sanity(force=False): except: pass + print >> sys.stderr, '(Emscripten: Config file changed, clearing cache)' # LLVM may have changed, etc. + Cache.erase() + print >> sys.stderr, '(Emscripten: Running sanity checks)' if not check_engine(COMPILER_ENGINE): @@ -68,6 +81,11 @@ def check_sanity(force=False): print >> sys.stderr, 'FATAL: Cannot find %s, check the paths in %s' % (cmd, EM_CONFIG) sys.exit(0) + try: + subprocess.call([JAVA, '-version'], stdout=PIPE, stderr=PIPE) + except: + print >> sys.stderr, 'WARNING: java does not seem to exist, required for closure compiler. -O2 and above will fail. You need to define JAVA in ~/.emscripten (see settings.py)' + if not os.path.exists(CLOSURE_COMPILER): print >> sys.stderr, 'WARNING: Closure compiler (%s) does not exist, check the paths in %s. -O2 and above will fail' % (CLOSURE_COMPILER, EM_CONFIG) @@ -89,7 +107,6 @@ CLANG_CC=os.path.expanduser(os.path.join(LLVM_ROOT, 'clang')) CLANG_CPP=os.path.expanduser(os.path.join(LLVM_ROOT, 'clang++')) CLANG=CLANG_CPP LLVM_LINK=os.path.join(LLVM_ROOT, 'llvm-link') -LLVM_LD=os.path.join(LLVM_ROOT, 'llvm-ld') LLVM_AR=os.path.join(LLVM_ROOT, 'llvm-ar') LLVM_OPT=os.path.expanduser(os.path.join(LLVM_ROOT, 'opt')) LLVM_AS=os.path.expanduser(os.path.join(LLVM_ROOT, 'llvm-as')) @@ -97,6 +114,7 @@ LLVM_DIS=os.path.expanduser(os.path.join(LLVM_ROOT, 'llvm-dis')) LLVM_NM=os.path.expanduser(os.path.join(LLVM_ROOT, 'llvm-nm')) LLVM_INTERPRETER=os.path.expanduser(os.path.join(LLVM_ROOT, 'lli')) LLVM_COMPILER=os.path.expanduser(os.path.join(LLVM_ROOT, 'llc')) +LLVM_EXTRACT=os.path.expanduser(os.path.join(LLVM_ROOT, 'llvm-extract')) COFFEESCRIPT = path_from_root('tools', 'eliminator', 'node_modules', 'coffee-script', 'bin', 'coffee') EMSCRIPTEN = path_from_root('emscripten.py') @@ -105,23 +123,31 @@ NAMESPACER = path_from_root('tools', 'namespacer.py') EMCC = path_from_root('emcc') EMXX = path_from_root('em++') EMAR = path_from_root('emar') -EMLD = path_from_root('emld') EMRANLIB = path_from_root('emranlib') EMLIBTOOL = path_from_root('emlibtool') +EMCONFIG = path_from_root('em-config') EMMAKEN = path_from_root('tools', 'emmaken.py') AUTODEBUGGER = path_from_root('tools', 'autodebugger.py') BINDINGS_GENERATOR = path_from_root('tools', 'bindings_generator.py') EXEC_LLVM = path_from_root('tools', 'exec_llvm.py') VARIABLE_ELIMINATOR = path_from_root('tools', 'eliminator', 'eliminator.coffee') JS_OPTIMIZER = path_from_root('tools', 'js-optimizer.js') +FILE_PACKAGER = path_from_root('tools', 'file_packager.py') # Temp dir. Create a random one, unless EMCC_DEBUG is set, in which case use TEMP_DIR/emscripten_temp +try: + TEMP_DIR +except: + print >> sys.stderr, 'TEMP_DIR not defined in ~/.emscripten, using /tmp' + TEMP_DIR = '/tmp' + +CANONICAL_TEMP_DIR = os.path.join(TEMP_DIR, 'emscripten_temp') EMSCRIPTEN_TEMP_DIR = None if os.environ.get('EMCC_DEBUG'): try: - EMSCRIPTEN_TEMP_DIR = os.path.join(TEMP_DIR, 'emscripten_temp') + EMSCRIPTEN_TEMP_DIR = CANONICAL_TEMP_DIR if not os.path.exists(EMSCRIPTEN_TEMP_DIR): os.makedirs(EMSCRIPTEN_TEMP_DIR) except: @@ -129,6 +155,9 @@ if os.environ.get('EMCC_DEBUG'): if not EMSCRIPTEN_TEMP_DIR: EMSCRIPTEN_TEMP_DIR = tempfile.mkdtemp(prefix='emscripten_temp_') + def clean_temp(): + try_delete(EMSCRIPTEN_TEMP_DIR) + atexit.register(clean_temp) # EM_CONFIG stuff @@ -146,6 +175,12 @@ try: except: CLOSURE_COMPILER = path_from_root('third_party', 'closure-compiler', 'compiler.jar') +try: + JAVA +except: + print >> sys.stderr, 'JAVA not defined in ~/.emscripten, using "java"' + JAVA = 'java' + # Additional compiler options try: @@ -155,7 +190,7 @@ except: # Force a simple, standard target as much as possible: target 32-bit linux, and disable various flags that hint at other platforms COMPILER_OPTS = COMPILER_OPTS + ['-m32', '-U__i386__', '-U__x86_64__', '-U__i386', '-U__x86_64', '-U__SSE__', '-U__SSE2__', '-U__MMX__', '-UX87_DOUBLE_ROUNDING', '-UHAVE_GCC_ASM_FOR_X87', '-DEMSCRIPTEN', '-U__STRICT_ANSI__', '-U__CYGWIN__', - '-D__STDC__', '-Xclang', '-triple=i386-pc-linux-gnu'] + '-D__STDC__', '-Xclang', '-triple=i386-pc-linux-gnu', '-D__IEEE_LITTLE_ENDIAN'] USE_EMSDK = not os.environ.get('EMMAKEN_NO_SDK') @@ -163,8 +198,10 @@ USE_EMSDK = not os.environ.get('EMMAKEN_NO_SDK') if USE_EMSDK: # Disable system C and C++ include directories, and add our own (using -idirafter so they are last, like system dirs, which # allows projects to override them) - EMSDK_OPTS = ['-nostdinc', '-nostdinc++', '-Xclang', '-nobuiltininc', '-Xclang', '-nostdinc++', '-Xclang', '-nostdsysteminc', + # Note that -nostdinc++ is not needed, since -nostdinc implies that! + EMSDK_OPTS = ['-nostdinc', '-Xclang', '-nobuiltininc', '-Xclang', '-nostdsysteminc', '-Xclang', '-isystem' + path_from_root('system', 'include'), + '-Xclang', '-isystem' + path_from_root('system', 'include', 'emscripten'), '-Xclang', '-isystem' + path_from_root('system', 'include', 'bsd'), # posix stuff '-Xclang', '-isystem' + path_from_root('system', 'include', 'libc'), '-Xclang', '-isystem' + path_from_root('system', 'include', 'libcxx'), @@ -172,7 +209,7 @@ if USE_EMSDK: '-Xclang', '-isystem' + path_from_root('system', 'include', 'net'), '-Xclang', '-isystem' + path_from_root('system', 'include', 'SDL'), ] + [ - '-U__APPLE__' + '-U__APPLE__', '-U__linux__' ] COMPILER_OPTS += EMSDK_OPTS else: @@ -180,13 +217,25 @@ else: # Engine tweaks -#if 'strict' not in str(SPIDERMONKEY_ENGINE): # XXX temporarily disable strict mode until we sort out some stuff -# SPIDERMONKEY_ENGINE += ['-e', "options('strict')"] # Strict mode in SpiderMonkey. With V8 we check that fallback to non-strict works too - -if 'gcparam' not in str(SPIDERMONKEY_ENGINE): - SPIDERMONKEY_ENGINE += ['-e', "gcparam('maxBytes', 1024*1024*1024);"] # Our very large files need lots of gc heap - -WINDOWS = sys.platform.startswith ('win') +try: + if 'gcparam' not in str(SPIDERMONKEY_ENGINE): + if type(SPIDERMONKEY_ENGINE) is str: + SPIDERMONKEY_ENGINE = [SPIDERMONKEY_ENGINE] + SPIDERMONKEY_ENGINE += ['-e', "gcparam('maxBytes', 1024*1024*1024);"] # Our very large files need lots of gc heap +except NameError: + pass + +WINDOWS = sys.platform.startswith('win') + +# If we have 'env', we should use that to find python, because |python| may fail while |env python| may work +# (For example, if system python is 3.x while we need 2.x, and env gives 2.x if told to do so.) +ENV_PREFIX = [] +if not WINDOWS: + try: + assert 'Python' in Popen(['env', 'python', '-V'], stdout=PIPE, stderr=STDOUT).communicate()[0] + ENV_PREFIX = ['env'] + except: + pass # Temp file utilities @@ -228,6 +277,8 @@ class TempFiles: def check_engine(engine): # TODO: we call this several times, perhaps cache the results? try: + if not CONFIG_FILE: + return True # config stored directly in EM_CONFIG => skip engine check return 'hello, world!' in run_js(path_from_root('tests', 'hello_world.js'), engine) except Exception, e: print 'Checking JS engine %s failed. Check %s. Details: %s' % (str(engine), EM_CONFIG, str(e)) @@ -243,11 +294,14 @@ def timeout_run(proc, timeout, note='unnamed process'): raise Exception("Timed out: " + note) return proc.communicate()[0] +EM_DEBUG = os.environ.get('EM_DEBUG') + def run_js(filename, engine=None, args=[], check_timeout=False, stdout=PIPE, stderr=None, cwd=None): if engine is None: engine = JS_ENGINES[0] if type(engine) is not list: engine = [engine] - return timeout_run(Popen(engine + [filename] + (['--'] if 'd8' in engine[0] else []) + args, - stdout=stdout, stderr=stderr, cwd=cwd), 15*60 if check_timeout else None, 'Execution') + command = engine + [filename] + (['--'] if 'd8' in engine[0] else []) + args + if EM_DEBUG: print >> sys.stderr, 'run_js: ' + ' '.join(command) + return timeout_run(Popen(command, stdout=stdout, stderr=stderr, cwd=cwd), 15*60 if check_timeout else None, 'Execution') def to_cc(cxx): # By default, LLVM_GCC and CLANG are really the C++ versions. This gets an explicit C version @@ -342,11 +396,12 @@ class Settings: if opt_level >= 2: Settings.RELOOP = 1 if opt_level >= 3: + Settings.INLINING_LIMIT = 0 + Settings.DOUBLE_MODE = 0 + Settings.PRECISE_I64_MATH = 0 Settings.CORRECT_SIGNS = 0 Settings.CORRECT_OVERFLOWS = 0 Settings.CORRECT_ROUNDINGS = 0 - Settings.DOUBLE_MODE = 0 - Settings.PRECISE_I64_MATH = 0 if noisy: print >> sys.stderr, 'Warning: Applying some potentially unsafe optimizations! (Use -O2 if this fails.)' global Settings @@ -461,24 +516,95 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e if configure: # Useful in debugging sometimes to comment this out (and the lines below up to and including the |link| call) Building.configure(configure + configure_args, stdout=open(os.path.join(project_dir, 'configure_'), 'w'), stderr=open(os.path.join(project_dir, 'configure_err'), 'w'), env=env) - Building.make(make + make_args, stdout=open(os.path.join(project_dir, 'make_'), 'w'), - stderr=open(os.path.join(project_dir, 'make_err'), 'w'), env=env) - if cache is not None: - cache[cache_name] = [] - for f in generated_libs: - basename = os.path.basename(f) - cache[cache_name].append((basename, open(f, 'rb').read())) + for i in range(2): # workaround for some build systems that need to be run twice to succeed (e.g. poppler) + Building.make(make + make_args, stdout=open(os.path.join(project_dir, 'make_' + str(i)), 'w'), + stderr=open(os.path.join(project_dir, 'make_err' + str(i)), 'w'), env=env) + try: + if cache is not None: + cache[cache_name] = [] + for f in generated_libs: + basename = os.path.basename(f) + cache[cache_name].append((basename, open(f, 'rb').read())) + break + except: + if i > 0: raise Exception('could not build library ' + name) if old_dir: os.chdir(old_dir) return generated_libs @staticmethod - def link(files, target): + def link(files, target, remove_duplicates=False): + actual_files = [] + unresolved_symbols = set() # necessary for .a linking, see below + resolved_symbols = set() + temp_dir = None + for f in files: + if not Building.is_ar(f): + if Building.is_bitcode(f): + new_symbols = Building.llvm_nm(f) + resolved_symbols = resolved_symbols.union(new_symbols.defs) + unresolved_symbols = unresolved_symbols.union(new_symbols.undefs.difference(resolved_symbols)).difference(new_symbols.defs) + actual_files.append(f) + else: + # Extract object files from ar archives, and link according to gnu ld semantics + # (link in an entire .o from the archive if it supplies symbols still unresolved) + cwd = os.getcwd() + try: + temp_dir = os.path.join(EMSCRIPTEN_TEMP_DIR, 'ar_output_' + str(os.getpid())) + if not os.path.exists(temp_dir): + os.makedirs(temp_dir) + os.chdir(temp_dir) + contents = filter(lambda x: len(x) > 0, Popen([LLVM_AR, 't', f], stdout=PIPE).communicate()[0].split('\n')) + if len(contents) == 0: + print >> sys.stderr, 'Warning: Archive %s appears to be empty (recommendation: link an .so instead of .a)' % f + else: + for content in contents: # ar will silently fail if the directory for the file does not exist, so make all the necessary directories + dirname = os.path.dirname(content) + if dirname and not os.path.exists(dirname): + os.makedirs(dirname) + Popen([LLVM_AR, 'x', f], stdout=PIPE).communicate() # if absolute paths, files will appear there. otherwise, in this directory + contents = map(lambda content: os.path.join(temp_dir, content), contents) + contents = filter(os.path.exists, map(os.path.abspath, contents)) + needed = False # We add or do not add the entire archive. We let llvm dead code eliminate parts we do not need, instead of + # doing intra-dependencies between archive contents + for content in contents: + new_symbols = Building.llvm_nm(content) + # Link in the .o if it provides symbols, *or* this is a singleton archive (which is apparently an exception in gcc ld) + if new_symbols.defs.intersection(unresolved_symbols) or len(files) == 1: + needed = True + if needed: + for content in contents: + if Building.is_bitcode(content): + new_symbols = Building.llvm_nm(content) + resolved_symbols = resolved_symbols.union(new_symbols.defs) + unresolved_symbols = unresolved_symbols.union(new_symbols.undefs.difference(resolved_symbols)).difference(new_symbols.defs) + actual_files.append(content) + finally: + os.chdir(cwd) try_delete(target) - stub = os.path.join(EMSCRIPTEN_TEMP_DIR, 'stub_deleteme') - output = Popen([LLVM_LD, '-disable-opt'] + files + ['-b', target, '-o', stub], stdout=PIPE).communicate()[0] - try_delete(stub) # clean up stub left by the linker - assert os.path.exists(target) and (output is None or 'Could not open input file' not in output), 'Linking error: ' + output + + if remove_duplicates: + # Remove duplicate symbols. This is a workaround for how we compile .a files, we try to + # emulate ld behavior which is permissive TODO: cache llvm-nm results + seen_symbols = set() + print >> sys.stderr, actual_files + for actual in actual_files: + symbols = Building.llvm_nm(actual) + dupes = seen_symbols.intersection(symbols.defs) + if len(dupes) > 0: + print >> sys.stderr, 'emcc: warning: removing duplicates in', actual + for dupe in dupes: + print >> sys.stderr, 'emcc: warning: removing duplicate', dupe + Popen([LLVM_EXTRACT, actual, '-delete', '-glob=' + dupe, '-o', actual], stderr=PIPE).communicate() + Popen([LLVM_EXTRACT, actual, '-delete', '-func=' + dupe, '-o', actual], stderr=PIPE).communicate() + Popen([LLVM_EXTRACT, actual, '-delete', '-glob=.str', '-o', actual], stderr=PIPE).communicate() # garbage that appears here + seen_symbols = seen_symbols.union(symbols.defs) + + # Finish link + output = Popen([LLVM_LINK] + actual_files + ['-o', target], stdout=PIPE).communicate()[0] + assert os.path.exists(target) and (output is None or 'Could not open input file' not in output), 'Linking error: ' + output + '\nemcc: If you get duplicate symbol errors, try --remove-duplicates' + if temp_dir: + try_delete(temp_dir) # Emscripten optimizations that we run on the .ll file @staticmethod @@ -507,12 +633,6 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e shutil.move(filename + '.o', filename + '.o.pre') output = Popen([LLVM_OPT, filename + '.o.pre'] + Building.LLVM_OPT_OPTS + ['-o=' + filename + '.o'], stdout=PIPE).communicate()[0] assert os.path.exists(filename + '.o'), 'Failed to run llvm optimizations: ' + output - #if Building.LLVM_OPTS == 2: - # print 'Unsafe LD!' - # shutil.move(filename + '.o', filename + '.o.pre') - # output = Popen([LLVM_LD, filename + '.o.pre', '-o=' + filename + '.tmp'], stdout=PIPE).communicate()[0] - # assert os.path.exists(filename + '.tmp.bc'), 'Failed to run llvm optimizations: ' + output - # shutil.move(filename + '.tmp.bc', filename + '.o') @staticmethod def llvm_dis(input_filename, output_filename=None): @@ -548,13 +668,15 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e commons = [] for line in output.split('\n'): if len(line) == 0: continue - status, symbol = filter(lambda seg: len(seg) > 0, line.split(' ')) - if status == 'U': - ret.undefs.append(symbol) - elif status != 'C': - ret.defs.append(symbol) - else: - ret.commons.append(symbol) + parts = filter(lambda seg: len(seg) > 0, line.split(' ')) + if len(parts) == 2: # ignore lines with absolute offsets, these are not bitcode anyhow (e.g. |00000630 t d_source_name|) + status, symbol = parts + if status == 'U': + ret.undefs.append(symbol) + elif status != 'C': + ret.defs.append(symbol) + else: + ret.commons.append(symbol) ret.defs = set(ret.defs) ret.undefs = set(ret.undefs) ret.commons = set(ret.commons) @@ -565,13 +687,13 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e if output_filename is None: output_filename = filename + '.o' try_delete(output_filename) - Popen(['python', EMCC, filename] + args + ['-o', output_filename], stdout=stdout, stderr=stderr, env=env).communicate() + Popen(ENV_PREFIX + ['python', EMCC, filename] + args + ['-o', output_filename], stdout=stdout, stderr=stderr, env=env).communicate() assert os.path.exists(output_filename), 'emcc could not create output file' @staticmethod def emar(action, output_filename, filenames, stdout=None, stderr=None, env=None): try_delete(output_filename) - Popen(['python', EMAR, action, output_filename] + filenames, stdout=stdout, stderr=stderr, env=env).communicate() + Popen(ENV_PREFIX + ['python', EMAR, action, output_filename] + filenames, stdout=stdout, stderr=stderr, env=env).communicate() if 'c' in action: assert os.path.exists(output_filename), 'emar could not create output file' @@ -582,7 +704,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e # Run Emscripten settings = Settings.serialize() - compiler_output = timeout_run(Popen(['python', EMSCRIPTEN, filename + ('.o.ll' if append_ext else ''), '-o', filename + '.o.js'] + settings + extra_args, stdout=PIPE), None, 'Compiling') + compiler_output = timeout_run(Popen(ENV_PREFIX + ['python', EMSCRIPTEN, filename + ('.o.ll' if append_ext else ''), '-o', filename + '.o.js'] + settings + extra_args, stdout=PIPE), None, 'Compiling') #print compiler_output # Detect compilation crashes and errors @@ -713,8 +835,8 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e if type(passes) == str: passes = [passes] # XXX Disable crankshaft to work around v8 bug 1895 - output, err = Popen([NODE_JS, '--nocrankshaft', JS_OPTIMIZER, filename] + passes, stdin=PIPE, stdout=PIPE, stderr=PIPE).communicate() - assert len(output) > 0 and not output.startswith('Assertion failed'), 'Error in js optimizer: ' + err + '\n\n' + output + output = Popen([NODE_JS, '--nocrankshaft', JS_OPTIMIZER, filename] + passes, stdout=PIPE).communicate()[0] + assert len(output) > 0 and not output.startswith('Assertion failed'), 'Error in js optimizer: ' + output filename += '.jo.js' f = open(filename, 'w') f.write(output) @@ -729,8 +851,8 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e coffee = path_from_root('tools', 'eliminator', 'node_modules', 'coffee-script', 'bin', 'coffee') eliminator = path_from_root('tools', 'eliminator', 'eliminator.coffee') input = open(filename, 'r').read() - output, err = Popen([NODE_JS, coffee, eliminator], stdin=PIPE, stdout=PIPE, stderr=PIPE).communicate(input) - assert len(output) > 0, 'Error in eliminator: ' + err + '\n\n' + output + output = Popen([NODE_JS, coffee, eliminator, filename], stdout=PIPE).communicate()[0] + assert len(output) > 0, 'Error in eliminator: ' + output filename += '.el.js' f = open(filename, 'w') f.write(output) @@ -744,7 +866,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e # Something like this (adjust memory as needed): # java -Xmx1024m -jar CLOSURE_COMPILER --compilation_level ADVANCED_OPTIMIZATIONS --variable_map_output_file src.cpp.o.js.vars --js src.cpp.o.js --js_output_file src.cpp.o.cc.js - args = ['java', + args = [JAVA, '-Xmx1024m', '-jar', CLOSURE_COMPILER, '--compilation_level', 'ADVANCED_OPTIMIZATIONS', @@ -810,7 +932,9 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e # Permanent cache for dlmalloc and stdlibc++ class Cache: - dirname = os.path.expanduser(os.path.join('~', '.emscripten_cache')) + dirname = os.environ.get('EM_CACHE') + if not dirname: + dirname = os.path.expanduser(os.path.join('~', '.emscripten_cache')) @staticmethod def erase(): @@ -832,3 +956,41 @@ class Cache: shutil.copyfile(creator(), cachename) return cachename +# Compression of code and data for smaller downloads +class Compression: + on = False + + @staticmethod + def compressed_name(filename): + return filename + '.compress' + + @staticmethod + def compress(filename): + execute(Compression.encoder, stdin=open(filename, 'rb'), stdout=open(Compression.compressed_name(filename), 'wb')) + + @staticmethod + def worth_it(original, compressed): + return compressed < original - 1500 # save at least one TCP packet or so + +def execute(cmd, *args, **kw): + try: + return subprocess.Popen(cmd, *args, **kw).communicate() # let compiler frontend print directly, so colors are saved (PIPE kills that) + except: + if not isinstance(cmd, str): + cmd = ' '.join(cmd) + print >> sys.stderr, 'Invoking Process failed: <<< ' + cmd + ' >>>' + raise + +def suffix(name): + parts = name.split('.') + if len(parts) > 1: + return parts[-1] + else: + return None + +def unsuffixed(name): + return '.'.join(name.split('.')[:-1]) + +def unsuffixed_basename(name): + return os.path.basename(unsuffixed(name)) + diff --git a/tools/test-js-optimizer-regs-output.js b/tools/test-js-optimizer-regs-output.js new file mode 100644 index 00000000..a5e97f46 --- /dev/null +++ b/tools/test-js-optimizer-regs-output.js @@ -0,0 +1,228 @@ +function test() { + var r1, r2; + r1 = 0; + f(r1); + r1 += 1; + r2 = r1 + 2; + g(r1, r2); + f(r1); + r1 = cheez(); + r2 = r1 + 2; + g(r2, r2); + r2 = 200; + r2 = 203; + r2 = 205; + r1 = 208; + c(r2); + while (f()) { + r2 = 5; + r1 = 12; + gg(r2, r1 * 2); + r1 = 100; + gg(r1, 20); + } + r1 = f(), r2 = 100, r2 = 1e3, r2 = 1e5; + f(r1()); +} +function primes() { + var r1, r2, r3, r4, r5, r6, r7; + r1 = 2; + r2 = 0; + $_$2 : while (1) { + r3 = r1 | 0; + r4 = _sqrtf(r3); + r3 = 2; + $_$4 : while (1) { + r5 = r3 | 0; + r6 = r5 < r4; + if (!r6) { + r7 = 1; + break $_$4; + } + r6 = (r1 | 0) % (r3 | 0); + r5 = (r6 | 0) == 0; + if (r5) { + r7 = 0; + break $_$4; + } + r5 = r3 + 1 | 0; + r3 = r5; + } + r3 = r7 + r2 | 0; + r4 = r1 + 1 | 0; + r5 = (r3 | 0) < 1e5; + if (r5) { + r1 = r4; + r2 = r3; + } else { + break $_$2; + } + } + r2 = _printf(STRING_TABLE.__str | 0, (tempInt = STACKTOP, STACKTOP += 4, HEAP32[tempInt >> 2] = r1, tempInt)); + return 1; + return null; +} +function atomic() { + var r1, r2, r3, r4; + r1 = STACKTOP; + STACKTOP += 4; + r2 = r1 >> 2; + HEAP32[r2] = 10; + r3 = (tempValue = HEAP32[r2], HEAP32[r2] == 10 && (HEAP32[r2] = 7), tempValue); + r4 = (r3 | 0) == 10 & 1; + r3 = HEAP32[r2]; + r2 = _printf(STRING_TABLE.__str | 0, (tempInt = STACKTOP, STACKTOP += 8, HEAP32[tempInt >> 2] = r3, HEAP32[tempInt + 4 >> 2] = r4, tempInt)); + STACKTOP = r1; + return 0; + return null; +} +function fcntl_open() { + var r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17; + r1 = STACKTOP; + STACKTOP += 84; + r2 = r1; + r3 = r1 + 72; + r4 = r3 | 0; + for (r5 = STRING_TABLE.__ZZ4mainE16nonexistent_name | 0, r6 = r4, r7 = r5 + 12; r5 < r7; r5++, r6++) { + HEAP8[r6] = HEAP8[r5]; + } + r5 = (r2 + 8 | 0) >> 2; + r8 = r2 >> 2; + r9 = r3 + 9 | 0; + r10 = r3 + 10 | 0; + r3 = 0; + while (1) { + r11 = HEAP32[__ZZ4mainE5modes + (r3 << 2) >> 2]; + r12 = r11 | 512; + r13 = r3 + 97 & 255; + r14 = 0; + while (1) { + r15 = (r14 & 1 | 0) == 0 ? r11 : r12; + r16 = (r14 & 2 | 0) == 0 ? r15 : r15 | 2048; + r15 = (r14 & 4 | 0) == 0 ? r16 : r16 | 1024; + r16 = (r14 & 8 | 0) == 0 ? r15 : r15 | 8; + r15 = _printf(STRING_TABLE.__str | 0, (tempInt = STACKTOP, STACKTOP += 8, HEAP32[tempInt >> 2] = r3, HEAP32[tempInt + 4 >> 2] = r14, tempInt)); + r15 = _open(STRING_TABLE.__str2 | 0, r16, (tempInt = STACKTOP, STACKTOP += 4, HEAP32[tempInt >> 2] = 511, tempInt)); + r17 = (r15 | 0) != -1 & 1; + r15 = _printf(STRING_TABLE.__str1 | 0, (tempInt = STACKTOP, STACKTOP += 4, HEAP32[tempInt >> 2] = r17, tempInt)); + r17 = ___errno(); + r15 = HEAP32[r17 >> 2]; + r17 = _printf(STRING_TABLE.__str3 | 0, (tempInt = STACKTOP, STACKTOP += 4, HEAP32[tempInt >> 2] = r15, tempInt)); + r15 = _stat(STRING_TABLE.__str2 | 0, r2); + r15 = HEAP32[r5] & -512; + r17 = _printf(STRING_TABLE.__str4 | 0, (tempInt = STACKTOP, STACKTOP += 4, HEAP32[tempInt >> 2] = r15, tempInt)); + for (r6 = r8, r7 = r6 + 18; r6 < r7; r6++) { + HEAP32[r6] = 0; + } + r15 = _putchar(10); + r15 = ___errno(); + HEAP32[r15 >> 2] = 0; + r15 = _printf(STRING_TABLE.__str6 | 0, (tempInt = STACKTOP, STACKTOP += 8, HEAP32[tempInt >> 2] = r3, HEAP32[tempInt + 4 >> 2] = r14, tempInt)); + r15 = _open(STRING_TABLE.__str7 | 0, r16, (tempInt = STACKTOP, STACKTOP += 4, HEAP32[tempInt >> 2] = 511, tempInt)); + r17 = (r15 | 0) != -1 & 1; + r15 = _printf(STRING_TABLE.__str1 | 0, (tempInt = STACKTOP, STACKTOP += 4, HEAP32[tempInt >> 2] = r17, tempInt)); + r17 = ___errno(); + r15 = HEAP32[r17 >> 2]; + r17 = _printf(STRING_TABLE.__str3 | 0, (tempInt = STACKTOP, STACKTOP += 4, HEAP32[tempInt >> 2] = r15, tempInt)); + r15 = _stat(STRING_TABLE.__str7 | 0, r2); + r15 = HEAP32[r5] & -512; + r17 = _printf(STRING_TABLE.__str4 | 0, (tempInt = STACKTOP, STACKTOP += 4, HEAP32[tempInt >> 2] = r15, tempInt)); + for (r6 = r8, r7 = r6 + 18; r6 < r7; r6++) { + HEAP32[r6] = 0; + } + r15 = _putchar(10); + r15 = ___errno(); + HEAP32[r15 >> 2] = 0; + HEAP8[r9] = r13; + HEAP8[r10] = r14 + 97 & 255; + r15 = _printf(STRING_TABLE.__str8 | 0, (tempInt = STACKTOP, STACKTOP += 8, HEAP32[tempInt >> 2] = r3, HEAP32[tempInt + 4 >> 2] = r14, tempInt)); + r15 = _open(r4, r16, (tempInt = STACKTOP, STACKTOP += 4, HEAP32[tempInt >> 2] = 511, tempInt)); + r17 = (r15 | 0) != -1 & 1; + r15 = _printf(STRING_TABLE.__str1 | 0, (tempInt = STACKTOP, STACKTOP += 4, HEAP32[tempInt >> 2] = r17, tempInt)); + r17 = ___errno(); + r15 = HEAP32[r17 >> 2]; + r17 = _printf(STRING_TABLE.__str3 | 0, (tempInt = STACKTOP, STACKTOP += 4, HEAP32[tempInt >> 2] = r15, tempInt)); + r15 = _stat(r4, r2); + r15 = HEAP32[r5] & -512; + r17 = _printf(STRING_TABLE.__str4 | 0, (tempInt = STACKTOP, STACKTOP += 4, HEAP32[tempInt >> 2] = r15, tempInt)); + for (r6 = r8, r7 = r6 + 18; r6 < r7; r6++) { + HEAP32[r6] = 0; + } + r16 = _putchar(10); + r16 = ___errno(); + HEAP32[r16 >> 2] = 0; + r16 = r14 + 1 | 0; + if ((r16 | 0) == 16) { + break; + } + r14 = r16; + } + r14 = r3 + 1 | 0; + if ((r14 | 0) == 3) { + break; + } + r3 = r14; + } + r3 = _puts(STRING_TABLE._str | 0); + r3 = _creat(STRING_TABLE.__str10 | 0, 511); + r6 = (r3 | 0) != -1 & 1; + r3 = _printf(STRING_TABLE.__str1 | 0, (tempInt = STACKTOP, STACKTOP += 4, HEAP32[tempInt >> 2] = r6, tempInt)); + r6 = ___errno(); + r3 = HEAP32[r6 >> 2]; + r6 = _printf(STRING_TABLE.__str3 | 0, (tempInt = STACKTOP, STACKTOP += 4, HEAP32[tempInt >> 2] = r3, tempInt)); + STACKTOP = r1; + return 0; + return null; +} +function ex() { + var r1, r2; + r1 = STACKTOP; + STACKTOP += 4; + r2 = r1; + r1 = _puts(STRING_TABLE._str17 | 0); + r1 = r2 | 0; + r2 = 0; + while (1) { + r1 = _printf(STRING_TABLE.__str15 | 0, (tempInt = STACKTOP, STACKTOP += 4, HEAP32[tempInt >> 2] = r2, tempInt)); + ((function() { + try { + __THREW__ = false; + return __Z5magici(r2); + } catch (e) { + if (typeof e != "number") throw e; + if (ABORT) throw e; + __THREW__ = true; + return null; + } + }))(); + } +} +function switchey(x) { + var r1, r2, r3, r4, r5, r6, r7, r8; + r1 = 5; + while (1) { + switch (x = f(x, r1)) { + case 1: + g(r1); + r2 = x + 1; + x--; + break; + case 2: + g(r1 * 2); + r3 = x + 22; + r4 = r3 + 5; + x -= 20; + break; + default: + r5 = x + 22; + r6 = r3 + 5; + ch(r5, r6 * r3); + throw 99; + } + } + r7 = x + 1; + p(r1, r7); + r8 = x + 2; + pp(r8); +} +// EMSCRIPTEN_GENERATED_FUNCTIONS: ["test", "primes", "atomic", "fcntl_open", "ex", "switchey"] diff --git a/tools/test-js-optimizer-regs.js b/tools/test-js-optimizer-regs.js new file mode 100644 index 00000000..2aa95b74 --- /dev/null +++ b/tools/test-js-optimizer-regs.js @@ -0,0 +1,233 @@ +function test() { + var i = 0; + f(i); + i+=1; + var j = i + 2; + g(i, j); + f(i); + var i2 = cheez(); + var j2 = i2 + 2; + g(j2, j2); + var k1 = 200; + var k2 = 203; + var k3 = 205; + var k4 = 208; + c(k3); + while (f()) { + var apple = 5; + var orange = 12; + gg(apple, orange*2); + var tangerine = 100; + gg(tangerine, 20); + } + var ck = f(), ck2 = 100, ck3 = 1000, ck4 = 100000; + f(ck()); +} +function primes() { + var __label__; + var $curri_01 = 2; + var $primes_02 = 0; + $_$2 : while (1) { + var $primes_02; + var $curri_01; + var $conv1 = $curri_01 | 0; + var $call = _sqrtf($conv1); + var $j_0 = 2; + $_$4 : while (1) { + var $j_0; + var $conv = $j_0 | 0; + var $cmp2 = $conv < $call; + if (!$cmp2) { + var $ok_0 = 1; + break $_$4; + } + var $rem = ($curri_01 | 0) % ($j_0 | 0); + var $cmp3 = ($rem | 0) == 0; + if ($cmp3) { + var $ok_0 = 0; + break $_$4; + } + var $inc = $j_0 + 1 | 0; + var $j_0 = $inc; + } + var $ok_0; + var $inc5_primes_0 = $ok_0 + $primes_02 | 0; + var $inc7 = $curri_01 + 1 | 0; + var $cmp = ($inc5_primes_0 | 0) < 1e5; + if ($cmp) { + var $curri_01 = $inc7; + var $primes_02 = $inc5_primes_0; + } else { + break $_$2; + } + } + var $call8 = _printf(STRING_TABLE.__str | 0, (tempInt = STACKTOP, STACKTOP += 4, HEAP32[tempInt >> 2] = $curri_01, tempInt)); + return 1; + return null; +} +function atomic() { + var $x$s2; + var __stackBase__ = STACKTOP; + STACKTOP += 4; + var $x$s2 = __stackBase__ >> 2; + HEAP32[$x$s2] = 10; + var $0 = (tempValue = HEAP32[$x$s2], HEAP32[$x$s2] == 10 && (HEAP32[$x$s2] = 7), tempValue); + var $conv = ($0 | 0) == 10 & 1; + var $2 = HEAP32[$x$s2]; + var $call = _printf(STRING_TABLE.__str | 0, (tempInt = STACKTOP, STACKTOP += 8, HEAP32[tempInt >> 2] = $2, HEAP32[tempInt + 4 >> 2] = $conv, tempInt)); + STACKTOP = __stackBase__; + return 0; + return null; +} +function fcntl_open() { + var $1$s2; + var $st_mode$s2; + var __stackBase__ = STACKTOP; + STACKTOP += 84; + var $s = __stackBase__; + var $nonexistent_name = __stackBase__ + 72; + var $0 = $nonexistent_name | 0; + for (var $$src = STRING_TABLE.__ZZ4mainE16nonexistent_name | 0, $$dest = $0, $$stop = $$src + 12; $$src < $$stop; $$src++, $$dest++) { + HEAP8[$$dest] = HEAP8[$$src]; + } + var $st_mode$s2 = ($s + 8 | 0) >> 2; + var $1$s2 = $s >> 2; // critical variable, becomes r8 + var $arrayidx43 = $nonexistent_name + 9 | 0; + var $arrayidx46 = $nonexistent_name + 10 | 0; + var $i_04 = 0; + while (1) { + var $i_04; + var $2 = HEAP32[__ZZ4mainE5modes + ($i_04 << 2) >> 2]; + var $or = $2 | 512; + var $conv42 = $i_04 + 97 & 255; + var $j_03 = 0; + while (1) { + var $j_03; + var $flags_0 = ($j_03 & 1 | 0) == 0 ? $2 : $or; + var $flags_0_or7 = ($j_03 & 2 | 0) == 0 ? $flags_0 : $flags_0 | 2048; + var $flags_2 = ($j_03 & 4 | 0) == 0 ? $flags_0_or7 : $flags_0_or7 | 1024; + var $flags_2_or17 = ($j_03 & 8 | 0) == 0 ? $flags_2 : $flags_2 | 8; + var $call = _printf(STRING_TABLE.__str | 0, (tempInt = STACKTOP, STACKTOP += 8, HEAP32[tempInt >> 2] = $i_04, HEAP32[tempInt + 4 >> 2] = $j_03, tempInt)); + var $call19 = _open(STRING_TABLE.__str2 | 0, $flags_2_or17, (tempInt = STACKTOP, STACKTOP += 4, HEAP32[tempInt >> 2] = 511, tempInt)); + var $conv = ($call19 | 0) != -1 & 1; + var $call21 = _printf(STRING_TABLE.__str1 | 0, (tempInt = STACKTOP, STACKTOP += 4, HEAP32[tempInt >> 2] = $conv, tempInt)); + var $call22 = ___errno(); + var $3 = HEAP32[$call22 >> 2]; + var $call23 = _printf(STRING_TABLE.__str3 | 0, (tempInt = STACKTOP, STACKTOP += 4, HEAP32[tempInt >> 2] = $3, tempInt)); + var $call24 = _stat(STRING_TABLE.__str2 | 0, $s); + var $and25 = HEAP32[$st_mode$s2] & -512; + var $call26 = _printf(STRING_TABLE.__str4 | 0, (tempInt = STACKTOP, STACKTOP += 4, HEAP32[tempInt >> 2] = $and25, tempInt)); + for (var $$dest = $1$s2, $$stop = $$dest + 18; $$dest < $$stop; $$dest++) { + HEAP32[$$dest] = 0; + } + var $putchar = _putchar(10); + var $call28 = ___errno(); + HEAP32[$call28 >> 2] = 0; + var $call29 = _printf(STRING_TABLE.__str6 | 0, (tempInt = STACKTOP, STACKTOP += 8, HEAP32[tempInt >> 2] = $i_04, HEAP32[tempInt + 4 >> 2] = $j_03, tempInt)); + var $call30 = _open(STRING_TABLE.__str7 | 0, $flags_2_or17, (tempInt = STACKTOP, STACKTOP += 4, HEAP32[tempInt >> 2] = 511, tempInt)); + var $conv32 = ($call30 | 0) != -1 & 1; + var $call33 = _printf(STRING_TABLE.__str1 | 0, (tempInt = STACKTOP, STACKTOP += 4, HEAP32[tempInt >> 2] = $conv32, tempInt)); + var $call34 = ___errno(); + var $5 = HEAP32[$call34 >> 2]; + var $call35 = _printf(STRING_TABLE.__str3 | 0, (tempInt = STACKTOP, STACKTOP += 4, HEAP32[tempInt >> 2] = $5, tempInt)); + var $call36 = _stat(STRING_TABLE.__str7 | 0, $s); + var $and38 = HEAP32[$st_mode$s2] & -512; + var $call39 = _printf(STRING_TABLE.__str4 | 0, (tempInt = STACKTOP, STACKTOP += 4, HEAP32[tempInt >> 2] = $and38, tempInt)); + for (var $$dest = $1$s2, $$stop = $$dest + 18; $$dest < $$stop; $$dest++) { + HEAP32[$$dest] = 0; + } + var $putchar1 = _putchar(10); + var $call41 = ___errno(); + HEAP32[$call41 >> 2] = 0; + HEAP8[$arrayidx43] = $conv42; + HEAP8[$arrayidx46] = $j_03 + 97 & 255; + var $call47 = _printf(STRING_TABLE.__str8 | 0, (tempInt = STACKTOP, STACKTOP += 8, HEAP32[tempInt >> 2] = $i_04, HEAP32[tempInt + 4 >> 2] = $j_03, tempInt)); + var $call48 = _open($0, $flags_2_or17, (tempInt = STACKTOP, STACKTOP += 4, HEAP32[tempInt >> 2] = 511, tempInt)); + var $conv50 = ($call48 | 0) != -1 & 1; + var $call51 = _printf(STRING_TABLE.__str1 | 0, (tempInt = STACKTOP, STACKTOP += 4, HEAP32[tempInt >> 2] = $conv50, tempInt)); + var $call52 = ___errno(); + var $7 = HEAP32[$call52 >> 2]; + var $call53 = _printf(STRING_TABLE.__str3 | 0, (tempInt = STACKTOP, STACKTOP += 4, HEAP32[tempInt >> 2] = $7, tempInt)); + var $call55 = _stat($0, $s); + var $and57 = HEAP32[$st_mode$s2] & -512; + var $call58 = _printf(STRING_TABLE.__str4 | 0, (tempInt = STACKTOP, STACKTOP += 4, HEAP32[tempInt >> 2] = $and57, tempInt)); + for (var $$dest = $1$s2, $$stop = $$dest + 18; $$dest < $$stop; $$dest++) { + HEAP32[$$dest] = 0; + } + var $putchar2 = _putchar(10); + var $call60 = ___errno(); + HEAP32[$call60 >> 2] = 0; + var $inc = $j_03 + 1 | 0; + if (($inc | 0) == 16) { + break; + } + var $j_03 = $inc; + } + var $inc62 = $i_04 + 1 | 0; + if (($inc62 | 0) == 3) { + break; + } + var $i_04 = $inc62; + } + var $puts = _puts(STRING_TABLE._str | 0); + var $call65 = _creat(STRING_TABLE.__str10 | 0, 511); + var $conv67 = ($call65 | 0) != -1 & 1; + var $call68 = _printf(STRING_TABLE.__str1 | 0, (tempInt = STACKTOP, STACKTOP += 4, HEAP32[tempInt >> 2] = $conv67, tempInt)); + var $call69 = ___errno(); + var $9 = HEAP32[$call69 >> 2]; + var $call70 = _printf(STRING_TABLE.__str3 | 0, (tempInt = STACKTOP, STACKTOP += 4, HEAP32[tempInt >> 2] = $9, tempInt)); + STACKTOP = __stackBase__; + return 0; + return null; +} +function ex() { + var __stackBase__ = STACKTOP; + STACKTOP += 4; + var $e1 = __stackBase__; + var $puts = _puts(STRING_TABLE._str17 | 0); + var $x41 = $e1 | 0; + var $i_04 = 0; + while (1) { + var $i_04; + var $call1 = _printf(STRING_TABLE.__str15 | 0, (tempInt = STACKTOP, STACKTOP += 4, HEAP32[tempInt >> 2] = $i_04, tempInt)); + ((function() { + try { + __THREW__ = false; + return __Z5magici($i_04); + } catch (e) { + if (typeof e != "number") throw e; + if (ABORT) throw e; + __THREW__ = true; + return null; + } + }))(); + } +} +function switchey(x) { + var a = 5; + while (1) { + switch (x = f(x, a)) { + case 1: + g(a); + var b = x+1; + x--; + break; + case 2: + g(a*2); + var c = x+22; + var d = c+5; + x -= 20; + break; + default: + var c1 = x+22; + var d2 = c+5; + ch(c1, d2*c); + throw 99; + } + } + var aa = x+1; + p(a, aa); + var aaa = x+2; + pp(aaa); +} +// EMSCRIPTEN_GENERATED_FUNCTIONS: ["test", "primes", "atomic", "fcntl_open", "ex", "switchey"] |