diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6f5d0ea --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +build-* +*.dll +*.exe +*.so +*.so.* diff --git a/DIST/web/game.data b/DIST/web/game.data deleted file mode 100644 index 9d842f4..0000000 Binary files a/DIST/web/game.data and /dev/null differ diff --git a/DIST/web/game.html b/DIST/web/game.html deleted file mode 100644 index 47059e8..0000000 --- a/DIST/web/game.html +++ /dev/null @@ -1,1295 +0,0 @@ - - - - - - Emscripten-Generated Code - - - - - image/svg+xml - - -
-
Downloading...
- - - Resize canvas - Lock/hide mouse pointer     - - - - -
- -
- - -
- -
- - - - - - diff --git a/DIST/web/game.js b/DIST/web/game.js deleted file mode 100644 index 1f3c742..0000000 --- a/DIST/web/game.js +++ /dev/null @@ -1,26 +0,0 @@ -var Module;if(typeof Module==="undefined")Module=eval("(function() { try { return Module || {} } catch(e) { return {} } })()");if(!Module.expectedDataFileDownloads){Module.expectedDataFileDownloads=0;Module.finishedDataFileDownloads=0}Module.expectedDataFileDownloads++;((function(){var PACKAGE_PATH;if(typeof window==="object"){PACKAGE_PATH=window["encodeURIComponent"](window.location.pathname.toString().substring(0,window.location.pathname.toString().lastIndexOf("/"))+"/")}else{PACKAGE_PATH=encodeURIComponent(location.pathname.toString().substring(0,location.pathname.toString().lastIndexOf("/"))+"/")}var PACKAGE_NAME="build-emscripten-release/game.data";var REMOTE_PACKAGE_NAME=(Module["filePackagePrefixURL"]||"")+"game.data";var REMOTE_PACKAGE_SIZE=487037;var PACKAGE_UUID="0aba4d1e-27d5-4758-a107-6cae09aa96db";function fetchRemotePackage(packageName,packageSize,callback,errback){var xhr=new XMLHttpRequest;xhr.open("GET",packageName,true);xhr.responseType="arraybuffer";xhr.onprogress=(function(event){var url=packageName;var size=packageSize;if(event.total)size=event.total;if(event.loaded){if(!xhr.addedTotal){xhr.addedTotal=true;if(!Module.dataFileDownloads)Module.dataFileDownloads={};Module.dataFileDownloads[url]={loaded:event.loaded,total:size}}else{Module.dataFileDownloads[url].loaded=event.loaded}var total=0;var loaded=0;var num=0;for(var download in Module.dataFileDownloads){var data=Module.dataFileDownloads[download];total+=data.total;loaded+=data.loaded;num++}total=Math.ceil(total*Module.expectedDataFileDownloads/num);if(Module["setStatus"])Module["setStatus"]("Downloading data... ("+loaded+"/"+total+")")}else if(!Module.dataFileDownloads){if(Module["setStatus"])Module["setStatus"]("Downloading data...")}});xhr.onload=(function(event){var packageData=xhr.response;callback(packageData)});xhr.send(null)}function handleError(error){console.error("package error:",error)}var fetched=null,fetchedCallback=null;fetchRemotePackage(REMOTE_PACKAGE_NAME,REMOTE_PACKAGE_SIZE,(function(data){if(fetchedCallback){fetchedCallback(data);fetchedCallback=null}else{fetched=data}}),handleError);function runWithFS(){function assert(check,msg){if(!check)throw msg+(new Error).stack}Module["FS_createPath"]("/","data",true,true);function DataRequest(start,end,crunched,audio){this.start=start;this.end=end;this.crunched=crunched;this.audio=audio}DataRequest.prototype={requests:{},open:(function(mode,name){this.name=name;this.requests[name]=this;Module["addRunDependency"]("fp "+this.name)}),send:(function(){}),onload:(function(){var byteArray=this.byteArray.subarray(this.start,this.end);this.finish(byteArray)}),finish:(function(byteArray){var that=this;Module["FS_createPreloadedFile"](this.name,null,byteArray,true,true,(function(){Module["removeRunDependency"]("fp "+that.name)}),(function(){if(that.audio){Module["removeRunDependency"]("fp "+that.name)}else{Module.printErr("Preloading file "+that.name+" failed")}}),false,true);this.requests[this.name]=null})};(new DataRequest(0,2344,0,0)).open("GET","/data/arrowshooter_down.png");(new DataRequest(2344,4698,0,0)).open("GET","/data/arrowshooter_left.png");(new DataRequest(4698,7037,0,0)).open("GET","/data/arrowshooter_right.png");(new DataRequest(7037,9313,0,0)).open("GET","/data/arrowshooter_up.png");(new DataRequest(9313,10366,0,0)).open("GET","/data/arrow_down.png");(new DataRequest(10366,11291,0,0)).open("GET","/data/arrow_left.png");(new DataRequest(11291,12228,0,0)).open("GET","/data/arrow_right.png");(new DataRequest(12228,13096,0,0)).open("GET","/data/arrow_up.png");(new DataRequest(13096,15920,0,0)).open("GET","/data/barrel.png");(new DataRequest(15920,18827,0,0)).open("GET","/data/barrel2.png");(new DataRequest(18827,69509,0,1)).open("GET","/data/coin.wav");(new DataRequest(69509,74221,0,0)).open("GET","/data/column.png");(new DataRequest(74221,77808,0,0)).open("GET","/data/column_faded.png");(new DataRequest(77808,123766,0,0)).open("GET","/data/end.png");(new DataRequest(123766,125708,0,0)).open("GET","/data/end_point.png");(new DataRequest(125708,130045,0,0)).open("GET","/data/exit_point.png");(new DataRequest(130045,186059,0,1)).open("GET","/data/Explosion16.wav");(new DataRequest(186059,250159,0,1)).open("GET","/data/Explosion2.wav");(new DataRequest(250159,258818,0,0)).open("GET","/data/fire.png");(new DataRequest(258818,262733,0,0)).open("GET","/data/floor.png");(new DataRequest(262733,266695,0,0)).open("GET","/data/floor_center.png");(new DataRequest(266695,270593,0,0)).open("GET","/data/floor_left.png");(new DataRequest(270593,274545,0,0)).open("GET","/data/floor_right.png");(new DataRequest(274545,280733,0,1)).open("GET","/data/Hit_Hurt10.wav");(new DataRequest(280733,296579,0,1)).open("GET","/data/Hit_Hurt16.wav");(new DataRequest(296579,301561,0,0)).open("GET","/data/hole_lava.png");(new DataRequest(301561,305229,0,0)).open("GET","/data/hole_spiked.png");(new DataRequest(305229,308688,0,0)).open("GET","/data/lamp.png");(new DataRequest(308688,320660,0,1)).open("GET","/data/Laser_Shoot2.wav");(new DataRequest(320660,322e3,0,0)).open("GET","/data/level_00.txt");(new DataRequest(322e3,323144,0,0)).open("GET","/data/level_01.txt");(new DataRequest(323144,324484,0,0)).open("GET","/data/level_02.txt");(new DataRequest(324484,325554,0,0)).open("GET","/data/level_03.txt");(new DataRequest(325554,327089,0,0)).open("GET","/data/level_04.txt");(new DataRequest(327089,328555,0,0)).open("GET","/data/level_05.txt");(new DataRequest(328555,328847,0,0)).open("GET","/data/level_06.txt");(new DataRequest(328847,369638,0,0)).open("GET","/data/logo.png");(new DataRequest(369638,373865,0,0)).open("GET","/data/player_broken.png");(new DataRequest(373865,378163,0,0)).open("GET","/data/player_down.png");(new DataRequest(378163,382654,0,0)).open("GET","/data/player_left.png");(new DataRequest(382654,387128,0,0)).open("GET","/data/player_right.png");(new DataRequest(387128,391201,0,0)).open("GET","/data/player_up.png");(new DataRequest(391201,448215,0,1)).open("GET","/data/Powerup10.wav");(new DataRequest(448215,475099,0,1)).open("GET","/data/Powerup30.wav");(new DataRequest(475099,477906,0,0)).open("GET","/data/rock.png");(new DataRequest(477906,480256,0,0)).open("GET","/data/save_point.png");(new DataRequest(480256,485902,0,0)).open("GET","/data/save_point_active.png");(new DataRequest(485902,487037,0,0)).open("GET","/data/textshadow.png");function processPackageData(arrayBuffer){Module.finishedDataFileDownloads++;assert(arrayBuffer,"Loading data file failed.");var byteArray=new Uint8Array(arrayBuffer);var curr;var ptr=Module["_malloc"](byteArray.length);Module["HEAPU8"].set(byteArray,ptr);DataRequest.prototype.byteArray=Module["HEAPU8"].subarray(ptr,ptr+byteArray.length);DataRequest.prototype.requests["/data/arrowshooter_down.png"].onload();DataRequest.prototype.requests["/data/arrowshooter_left.png"].onload();DataRequest.prototype.requests["/data/arrowshooter_right.png"].onload();DataRequest.prototype.requests["/data/arrowshooter_up.png"].onload();DataRequest.prototype.requests["/data/arrow_down.png"].onload();DataRequest.prototype.requests["/data/arrow_left.png"].onload();DataRequest.prototype.requests["/data/arrow_right.png"].onload();DataRequest.prototype.requests["/data/arrow_up.png"].onload();DataRequest.prototype.requests["/data/barrel.png"].onload();DataRequest.prototype.requests["/data/barrel2.png"].onload();DataRequest.prototype.requests["/data/coin.wav"].onload();DataRequest.prototype.requests["/data/column.png"].onload();DataRequest.prototype.requests["/data/column_faded.png"].onload();DataRequest.prototype.requests["/data/end.png"].onload();DataRequest.prototype.requests["/data/end_point.png"].onload();DataRequest.prototype.requests["/data/exit_point.png"].onload();DataRequest.prototype.requests["/data/Explosion16.wav"].onload();DataRequest.prototype.requests["/data/Explosion2.wav"].onload();DataRequest.prototype.requests["/data/fire.png"].onload();DataRequest.prototype.requests["/data/floor.png"].onload();DataRequest.prototype.requests["/data/floor_center.png"].onload();DataRequest.prototype.requests["/data/floor_left.png"].onload();DataRequest.prototype.requests["/data/floor_right.png"].onload();DataRequest.prototype.requests["/data/Hit_Hurt10.wav"].onload();DataRequest.prototype.requests["/data/Hit_Hurt16.wav"].onload();DataRequest.prototype.requests["/data/hole_lava.png"].onload();DataRequest.prototype.requests["/data/hole_spiked.png"].onload();DataRequest.prototype.requests["/data/lamp.png"].onload();DataRequest.prototype.requests["/data/Laser_Shoot2.wav"].onload();DataRequest.prototype.requests["/data/level_00.txt"].onload();DataRequest.prototype.requests["/data/level_01.txt"].onload();DataRequest.prototype.requests["/data/level_02.txt"].onload();DataRequest.prototype.requests["/data/level_03.txt"].onload();DataRequest.prototype.requests["/data/level_04.txt"].onload();DataRequest.prototype.requests["/data/level_05.txt"].onload();DataRequest.prototype.requests["/data/level_06.txt"].onload();DataRequest.prototype.requests["/data/logo.png"].onload();DataRequest.prototype.requests["/data/player_broken.png"].onload();DataRequest.prototype.requests["/data/player_down.png"].onload();DataRequest.prototype.requests["/data/player_left.png"].onload();DataRequest.prototype.requests["/data/player_right.png"].onload();DataRequest.prototype.requests["/data/player_up.png"].onload();DataRequest.prototype.requests["/data/Powerup10.wav"].onload();DataRequest.prototype.requests["/data/Powerup30.wav"].onload();DataRequest.prototype.requests["/data/rock.png"].onload();DataRequest.prototype.requests["/data/save_point.png"].onload();DataRequest.prototype.requests["/data/save_point_active.png"].onload();DataRequest.prototype.requests["/data/textshadow.png"].onload();Module["removeRunDependency"]("datafile_build-emscripten-release/game.data")}Module["addRunDependency"]("datafile_build-emscripten-release/game.data");if(!Module.preloadResults)Module.preloadResults={};Module.preloadResults[PACKAGE_NAME]={fromCache:false};if(fetched){processPackageData(fetched);fetched=null}else{fetchedCallback=processPackageData}}if(Module["calledRun"]){runWithFS()}else{if(!Module["preRun"])Module["preRun"]=[];Module["preRun"].push(runWithFS)}}))();var Module;if(!Module)Module=(typeof Module!=="undefined"?Module:null)||{};var moduleOverrides={};for(var key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}var ENVIRONMENT_IS_NODE=typeof process==="object"&&typeof require==="function";var ENVIRONMENT_IS_WEB=typeof window==="object";var ENVIRONMENT_IS_WORKER=typeof importScripts==="function";var ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;if(ENVIRONMENT_IS_NODE){if(!Module["print"])Module["print"]=function print(x){process["stdout"].write(x+"\n")};if(!Module["printErr"])Module["printErr"]=function printErr(x){process["stderr"].write(x+"\n")};var nodeFS=require("fs");var nodePath=require("path");Module["read"]=function read(filename,binary){filename=nodePath["normalize"](filename);var ret=nodeFS["readFileSync"](filename);if(!ret&&filename!=nodePath["resolve"](filename)){filename=path.join(__dirname,"..","src",filename);ret=nodeFS["readFileSync"](filename)}if(ret&&!binary)ret=ret.toString();return ret};Module["readBinary"]=function readBinary(filename){return Module["read"](filename,true)};Module["load"]=function load(f){globalEval(read(f))};Module["thisProgram"]=process["argv"][1];Module["arguments"]=process["argv"].slice(2);module["exports"]=Module}else if(ENVIRONMENT_IS_SHELL){if(!Module["print"])Module["print"]=print;if(typeof printErr!="undefined")Module["printErr"]=printErr;if(typeof read!="undefined"){Module["read"]=read}else{Module["read"]=function read(){throw"no read() available (jsc?)"}}Module["readBinary"]=function readBinary(f){return read(f,"binary")};if(typeof scriptArgs!="undefined"){Module["arguments"]=scriptArgs}else if(typeof arguments!="undefined"){Module["arguments"]=arguments}this["Module"]=Module}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){Module["read"]=function read(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(typeof arguments!="undefined"){Module["arguments"]=arguments}if(typeof console!=="undefined"){if(!Module["print"])Module["print"]=function print(x){console.log(x)};if(!Module["printErr"])Module["printErr"]=function printErr(x){console.log(x)}}else{var TRY_USE_DUMP=false;if(!Module["print"])Module["print"]=TRY_USE_DUMP&&typeof dump!=="undefined"?(function(x){dump(x)}):(function(x){})}if(ENVIRONMENT_IS_WEB){window["Module"]=Module}else{Module["load"]=importScripts}}else{throw"Unknown runtime environment. Where are we?"}function globalEval(x){eval.call(null,x)}if(!Module["load"]=="undefined"&&Module["read"]){Module["load"]=function load(f){globalEval(Module["read"](f))}}if(!Module["print"]){Module["print"]=(function(){})}if(!Module["printErr"]){Module["printErr"]=Module["print"]}if(!Module["arguments"]){Module["arguments"]=[]}Module.print=Module["print"];Module.printErr=Module["printErr"];Module["preRun"]=[];Module["postRun"]=[];for(var key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}var Runtime={setTempRet0:(function(value){tempRet0=value}),getTempRet0:(function(){return tempRet0}),stackSave:(function(){return STACKTOP}),stackRestore:(function(stackTop){STACKTOP=stackTop}),forceAlign:(function(target,quantum){quantum=quantum||4;if(quantum==1)return target;if(isNumber(target)&&isNumber(quantum)){return Math.ceil(target/quantum)*quantum}else if(isNumber(quantum)&&isPowerOfTwo(quantum)){return"((("+target+")+"+(quantum-1)+")&"+ -quantum+")"}return"Math.ceil(("+target+")/"+quantum+")*"+quantum}),isNumberType:(function(type){return type in Runtime.INT_TYPES||type in Runtime.FLOAT_TYPES}),isPointerType:function isPointerType(type){return type[type.length-1]=="*"},isStructType:function isStructType(type){if(isPointerType(type))return false;if(isArrayType(type))return true;if(/?/.test(type))return true;return type[0]=="%"},INT_TYPES:{"i1":0,"i8":0,"i16":0,"i32":0,"i64":0},FLOAT_TYPES:{"float":0,"double":0},or64:(function(x,y){var l=x|0|(y|0);var h=(Math.round(x/4294967296)|Math.round(y/4294967296))*4294967296;return l+h}),and64:(function(x,y){var l=(x|0)&(y|0);var h=(Math.round(x/4294967296)&Math.round(y/4294967296))*4294967296;return l+h}),xor64:(function(x,y){var l=(x|0)^(y|0);var h=(Math.round(x/4294967296)^Math.round(y/4294967296))*4294967296;return l+h}),getNativeTypeSize:(function(type){switch(type){case"i1":case"i8":return 1;case"i16":return 2;case"i32":return 4;case"i64":return 8;case"float":return 4;case"double":return 8;default:{if(type[type.length-1]==="*"){return Runtime.QUANTUM_SIZE}else if(type[0]==="i"){var bits=parseInt(type.substr(1));assert(bits%8===0);return bits/8}else{return 0}}}}),getNativeFieldSize:(function(type){return Math.max(Runtime.getNativeTypeSize(type),Runtime.QUANTUM_SIZE)}),dedup:function dedup(items,ident){var seen={};if(ident){return items.filter((function(item){if(seen[item[ident]])return false;seen[item[ident]]=true;return true}))}else{return items.filter((function(item){if(seen[item])return false;seen[item]=true;return true}))}},set:function set(){var args=typeof arguments[0]==="object"?arguments[0]:arguments;var ret={};for(var i=0;i=0){diffs.push(curr-prev)}prev=curr;return curr}));if(type.name_&&type.name_[0]==="["){type.flatSize=parseInt(type.name_.substr(1))*type.flatSize/2}type.flatSize=Runtime.alignMemory(type.flatSize,type.alignSize);if(diffs.length==0){type.flatFactor=type.flatSize}else if(Runtime.dedup(diffs).length==1){type.flatFactor=diffs[0]}type.needsFlattening=type.flatFactor!=1;return type.flatIndexes},generateStructInfo:(function(struct,typeName,offset){var type,alignment;if(typeName){offset=offset||0;type=(typeof Types==="undefined"?Runtime.typeInfo:Types.types)[typeName];if(!type)return null;if(type.fields.length!=struct.length){printErr("Number of named fields must match the type for "+typeName+": possibly duplicate struct names. Cannot return structInfo");return null}alignment=type.flatIndexes}else{var type={fields:struct.map((function(item){return item[0]}))};alignment=Runtime.calculateStructAlignment(type)}var ret={__size__:type.flatSize};if(typeName){struct.forEach((function(item,i){if(typeof item==="string"){ret[item]=alignment[i]+offset}else{var key;for(var k in item)key=k;ret[key]=Runtime.generateStructInfo(item[key],type.fields[i],alignment[i])}}))}else{struct.forEach((function(item,i){ret[item[1]]=alignment[i]}))}return ret}),dynCall:(function(sig,ptr,args){if(args&&args.length){if(!args.splice)args=Array.prototype.slice.call(args);args.splice(0,0,ptr);return Module["dynCall_"+sig].apply(null,args)}else{return Module["dynCall_"+sig].call(null,ptr)}}),functionPointers:[],addFunction:(function(func){for(var i=0;i0)return""}var c1=buffer[0];var c2=buffer[1];var c3=buffer[2];var c4=buffer[3];var ret;if(buffer.length==2){ret=String.fromCharCode((c1&31)<<6|c2&63)}else if(buffer.length==3){ret=String.fromCharCode((c1&15)<<12|(c2&63)<<6|c3&63)}else{var codePoint=(c1&7)<<18|(c2&63)<<12|(c3&63)<<6|c4&63;ret=String.fromCharCode(Math.floor((codePoint-65536)/1024)+55296,(codePoint-65536)%1024+56320)}buffer.length=0;return ret});this.processJSString=function processJSString(string){string=unescape(encodeURIComponent(string));var ret=[];for(var i=0;i=TOTAL_MEMORY)enlargeMemory();return ret}),alignMemory:(function(size,quantum){var ret=size=Math.ceil(size/(quantum?quantum:8))*(quantum?quantum:8);return ret}),makeBigInt:(function(low,high,unsigned){var ret=unsigned?+(low>>>0)+ +(high>>>0)*+4294967296:+(low>>>0)+ +(high|0)*+4294967296;return ret}),GLOBAL_BASE:8,QUANTUM_SIZE:4,__dummy__:0};Module["Runtime"]=Runtime;var __THREW__=0;var ABORT=false;var EXITSTATUS=0;var undef=0;var tempValue,tempInt,tempBigInt,tempInt2,tempBigInt2,tempPair,tempBigIntI,tempBigIntR,tempBigIntS,tempBigIntP,tempBigIntD,tempDouble,tempFloat;var tempI64,tempI64b;var tempRet0,tempRet1,tempRet2,tempRet3,tempRet4,tempRet5,tempRet6,tempRet7,tempRet8,tempRet9;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}var globalScope=this;function getCFunc(ident){var func=Module["_"+ident];if(!func){try{func=eval("_"+ident)}catch(e){}}assert(func,"Cannot call unknown function "+ident+" (perhaps LLVM optimizations or closure removed it?)");return func}var cwrap,ccall;((function(){var stack=0;var JSfuncs={"stackSave":(function(){stack=Runtime.stackSave()}),"stackRestore":(function(){Runtime.stackRestore(stack)}),"arrayToC":(function(arr){var ret=Runtime.stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}),"stringToC":(function(str){var ret=0;if(str!==null&&str!==undefined&&str!==0){ret=Runtime.stackAlloc(str.length+1);writeStringToMemory(str,ret)}return ret})};var toC={"string":JSfuncs["stringToC"],"array":JSfuncs["arrayToC"]};ccall=function ccallFunc(ident,returnType,argTypes,args){var func=getCFunc(ident);var cArgs=[];if(args){for(var i=0;i>0]=value;break;case"i8":HEAP8[ptr>>0]=value;break;case"i16":HEAP16[ptr>>1]=value;break;case"i32":HEAP32[ptr>>2]=value;break;case"i64":tempI64=[value>>>0,(tempDouble=value,+Math_abs(tempDouble)>=+1?tempDouble>+0?(Math_min(+Math_floor(tempDouble/+4294967296),+4294967295)|0)>>>0:~~+Math_ceil((tempDouble- +(~~tempDouble>>>0))/+4294967296)>>>0:0)],HEAP32[ptr>>2]=tempI64[0],HEAP32[ptr+4>>2]=tempI64[1];break;case"float":HEAPF32[ptr>>2]=value;break;case"double":HEAPF64[ptr>>3]=value;break;default:abort("invalid type for setValue: "+type)}}Module["setValue"]=setValue;function getValue(ptr,type,noSafe){type=type||"i8";if(type.charAt(type.length-1)==="*")type="i32";switch(type){case"i1":return HEAP8[ptr>>0];case"i8":return HEAP8[ptr>>0];case"i16":return HEAP16[ptr>>1];case"i32":return HEAP32[ptr>>2];case"i64":return HEAP32[ptr>>2];case"float":return HEAPF32[ptr>>2];case"double":return HEAPF64[ptr>>3];default:abort("invalid type for setValue: "+type)}return null}Module["getValue"]=getValue;var ALLOC_NORMAL=0;var ALLOC_STACK=1;var ALLOC_STATIC=2;var ALLOC_DYNAMIC=3;var ALLOC_NONE=4;Module["ALLOC_NORMAL"]=ALLOC_NORMAL;Module["ALLOC_STACK"]=ALLOC_STACK;Module["ALLOC_STATIC"]=ALLOC_STATIC;Module["ALLOC_DYNAMIC"]=ALLOC_DYNAMIC;Module["ALLOC_NONE"]=ALLOC_NONE;function allocate(slab,types,allocator,ptr){var zeroinit,size;if(typeof slab==="number"){zeroinit=true;size=slab}else{zeroinit=false;size=slab.length}var singleType=typeof types==="string"?types:null;var ret;if(allocator==ALLOC_NONE){ret=ptr}else{ret=[_malloc,Runtime.stackAlloc,Runtime.staticAlloc,Runtime.dynamicAlloc][allocator===undefined?ALLOC_STATIC:allocator](Math.max(size,singleType?1:types.length))}if(zeroinit){var ptr=ret,stop;assert((ret&3)==0);stop=ret+(size&~3);for(;ptr>2]=0}stop=ret+size;while(ptr>0]=0}return ret}if(singleType==="i8"){if(slab.subarray||slab.slice){HEAPU8.set(slab,ret)}else{HEAPU8.set(new Uint8Array(slab),ret)}return ret}var i=0,type,typeSize,previousType;while(i>0];if(t>=128)hasUtf=true;else if(t==0&&!length)break;i++;if(length&&i==length)break}if(!length)length=i;var ret="";if(!hasUtf){var MAX_CHUNK=1024;var curr;while(length>0){curr=String.fromCharCode.apply(String,HEAPU8.subarray(ptr,ptr+Math.min(length,MAX_CHUNK)));ret=ret?ret+curr:curr;ptr+=MAX_CHUNK;length-=MAX_CHUNK}return ret}var utf8=new Runtime.UTF8Processor;for(i=0;i>0];ret+=utf8.processCChar(t)}return ret}Module["Pointer_stringify"]=Pointer_stringify;function UTF16ToString(ptr){var i=0;var str="";while(1){var codeUnit=HEAP16[ptr+i*2>>1];if(codeUnit==0)return str;++i;str+=String.fromCharCode(codeUnit)}}Module["UTF16ToString"]=UTF16ToString;function stringToUTF16(str,outPtr){for(var i=0;i>1]=codeUnit}HEAP16[outPtr+str.length*2>>1]=0}Module["stringToUTF16"]=stringToUTF16;function UTF32ToString(ptr){var i=0;var str="";while(1){var utf32=HEAP32[ptr+i*4>>2];if(utf32==0)return str;++i;if(utf32>=65536){var ch=utf32-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}else{str+=String.fromCharCode(utf32)}}}Module["UTF32ToString"]=UTF32ToString;function stringToUTF32(str,outPtr){var iChar=0;for(var iCodeUnit=0;iCodeUnit=55296&&codeUnit<=57343){var trailSurrogate=str.charCodeAt(++iCodeUnit);codeUnit=65536+((codeUnit&1023)<<10)|trailSurrogate&1023}HEAP32[outPtr+iChar*4>>2]=codeUnit;++iChar}HEAP32[outPtr+iChar*4>>2]=0}Module["stringToUTF32"]=stringToUTF32;function demangle(func){var i=3;var basicTypes={"v":"void","b":"bool","c":"char","s":"short","i":"int","l":"long","f":"float","d":"double","w":"wchar_t","a":"signed char","h":"unsigned char","t":"unsigned short","j":"unsigned int","m":"unsigned long","x":"long long","y":"unsigned long long","z":"..."};var subs=[];var first=true;function dump(x){if(x)Module.print(x);Module.print(func);var pre="";for(var a=0;a"}else{ret=name}paramLoop:while(i0){var c=func[i++];if(c in basicTypes){list.push(basicTypes[c])}else{switch(c){case"P":list.push(parse(true,1,true)[0]+"*");break;case"R":list.push(parse(true,1,true)[0]+"&");break;case"L":{i++;var end=func.indexOf("E",i);var size=end-i;list.push(func.substr(i,size));i+=size+2;break};case"A":{var size=parseInt(func.substr(i));i+=size.toString().length;if(func[i]!=="_")throw"?";i++;list.push(parse(true,1,true)[0]+" ["+size+"]");break};case"E":break paramLoop;default:ret+="?"+c;break paramLoop}}}if(!allowVoid&&list.length===1&&list[0]==="void")list=[];if(rawList){if(ret){list.push(ret+"?")}return list}else{return ret+flushList()}}try{if(func=="Object._main"||func=="_main"){return"main()"}if(typeof func==="number")func=Pointer_stringify(func);if(func[0]!=="_")return func;if(func[1]!=="_")return func;if(func[2]!=="Z")return func;switch(func[3]){case"n":return"operator new()";case"d":return"operator delete()"}return parse()}catch(e){return func}}function demangleAll(text){return text.replace(/__Z[\w\d_]+/g,(function(x){var y=demangle(x);return x===y?x:x+" ["+y+"]"}))}function stackTrace(){var stack=(new Error).stack;return stack?demangleAll(stack):"(no stack trace available)"}var PAGE_SIZE=4096;function alignMemoryPage(x){return x+4095&-4096}var HEAP;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;var STATIC_BASE=0,STATICTOP=0,staticSealed=false;var STACK_BASE=0,STACKTOP=0,STACK_MAX=0;var DYNAMIC_BASE=0,DYNAMICTOP=0;function enlargeMemory(){abort("Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value "+TOTAL_MEMORY+", (2) compile with ALLOW_MEMORY_GROWTH which adjusts the size at runtime but prevents some optimizations, or (3) set Module.TOTAL_MEMORY before the program runs.")}var TOTAL_STACK=Module["TOTAL_STACK"]||5242880;var TOTAL_MEMORY=Module["TOTAL_MEMORY"]||16777216;var FAST_MEMORY=Module["FAST_MEMORY"]||2097152;var totalMemory=4096;while(totalMemory0){var callback=callbacks.shift();if(typeof callback=="function"){callback();continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){Runtime.dynCall("v",func)}else{Runtime.dynCall("vi",func,[callback.arg])}}else{func(callback.arg===undefined?null:callback.arg)}}}var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATEXIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function ensureInitRuntime(){if(runtimeInitialized)return;runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function preMain(){callRuntimeCallbacks(__ATMAIN__)}function exitRuntime(){callRuntimeCallbacks(__ATEXIT__);runtimeInitialized=false}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}Module["addOnPreRun"]=Module.addOnPreRun=addOnPreRun;function addOnInit(cb){__ATINIT__.unshift(cb)}Module["addOnInit"]=Module.addOnInit=addOnInit;function addOnPreMain(cb){__ATMAIN__.unshift(cb)}Module["addOnPreMain"]=Module.addOnPreMain=addOnPreMain;function addOnExit(cb){__ATEXIT__.unshift(cb)}Module["addOnExit"]=Module.addOnExit=addOnExit;function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}Module["addOnPostRun"]=Module.addOnPostRun=addOnPostRun;function intArrayFromString(stringy,dontAddNull,length){var ret=(new Runtime.UTF8Processor).processJSString(stringy);if(length){ret.length=length}if(!dontAddNull){ret.push(0)}return ret}Module["intArrayFromString"]=intArrayFromString;function intArrayToString(array){var ret=[];for(var i=0;i255){chr&=255}ret.push(String.fromCharCode(chr))}return ret.join("")}Module["intArrayToString"]=intArrayToString;function writeStringToMemory(string,buffer,dontAddNull){var array=intArrayFromString(string,dontAddNull);var i=0;while(i>0]=chr;i=i+1}}Module["writeStringToMemory"]=writeStringToMemory;function writeArrayToMemory(array,buffer){for(var i=0;i>0]=array[i]}}Module["writeArrayToMemory"]=writeArrayToMemory;function writeAsciiToMemory(str,buffer,dontAddNull){for(var i=0;i>0]=str.charCodeAt(i)}if(!dontAddNull)HEAP8[buffer+str.length>>0]=0}Module["writeAsciiToMemory"]=writeAsciiToMemory;function unSign(value,bits,ignore){if(value>=0){return value}return bits<=32?2*Math.abs(1<=half&&(bits<=32||value>half)){value=-2*half+value}return value}if(!Math["imul"]||Math["imul"](4294967295,5)!==-5)Math["imul"]=function imul(a,b){var ah=a>>>16;var al=a&65535;var bh=b>>>16;var bl=b&65535;return al*bl+(ah*bl+al*bh<<16)|0};Math.imul=Math["imul"];var Math_abs=Math.abs;var Math_cos=Math.cos;var Math_sin=Math.sin;var Math_tan=Math.tan;var Math_acos=Math.acos;var Math_asin=Math.asin;var Math_atan=Math.atan;var Math_atan2=Math.atan2;var Math_exp=Math.exp;var Math_log=Math.log;var Math_sqrt=Math.sqrt;var Math_ceil=Math.ceil;var Math_floor=Math.floor;var Math_pow=Math.pow;var Math_imul=Math.imul;var Math_fround=Math.fround;var Math_min=Math.min;var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}Module["addRunDependency"]=addRunDependency;function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["removeRunDependency"]=removeRunDependency;Module["preloadedImages"]={};Module["preloadedAudios"]={};var memoryInitializer=null;STATIC_BASE=8;STATICTOP=STATIC_BASE+Runtime.alignMemory(13779);__ATINIT__.push();allocate([0,0,0,0,150,48,7,119,44,97,14,238,186,81,9,153,25,196,109,7,143,244,106,112,53,165,99,233,163,149,100,158,50,136,219,14,164,184,220,121,30,233,213,224,136,217,210,151,43,76,182,9,189,124,177,126,7,45,184,231,145,29,191,144,100,16,183,29,242,32,176,106,72,113,185,243,222,65,190,132,125,212,218,26,235,228,221,109,81,181,212,244,199,133,211,131,86,152,108,19,192,168,107,100,122,249,98,253,236,201,101,138,79,92,1,20,217,108,6,99,99,61,15,250,245,13,8,141,200,32,110,59,94,16,105,76,228,65,96,213,114,113,103,162,209,228,3,60,71,212,4,75,253,133,13,210,107,181,10,165,250,168,181,53,108,152,178,66,214,201,187,219,64,249,188,172,227,108,216,50,117,92,223,69,207,13,214,220,89,61,209,171,172,48,217,38,58,0,222,81,128,81,215,200,22,97,208,191,181,244,180,33,35,196,179,86,153,149,186,207,15,165,189,184,158,184,2,40,8,136,5,95,178,217,12,198,36,233,11,177,135,124,111,47,17,76,104,88,171,29,97,193,61,45,102,182,144,65,220,118,6,113,219,1,188,32,210,152,42,16,213,239,137,133,177,113,31,181,182,6,165,228,191,159,51,212,184,232,162,201,7,120,52,249,0,15,142,168,9,150,24,152,14,225,187,13,106,127,45,61,109,8,151,108,100,145,1,92,99,230,244,81,107,107,98,97,108,28,216,48,101,133,78,0,98,242,237,149,6,108,123,165,1,27,193,244,8,130,87,196,15,245,198,217,176,101,80,233,183,18,234,184,190,139,124,136,185,252,223,29,221,98,73,45,218,21,243,124,211,140,101,76,212,251,88,97,178,77,206,81,181,58,116,0,188,163,226,48,187,212,65,165,223,74,215,149,216,61,109,196,209,164,251,244,214,211,106,233,105,67,252,217,110,52,70,136,103,173,208,184,96,218,115,45,4,68,229,29,3,51,95,76,10,170,201,124,13,221,60,113,5,80,170,65,2,39,16,16,11,190,134,32,12,201,37,181,104,87,179,133,111,32,9,212,102,185,159,228,97,206,14,249,222,94,152,201,217,41,34,152,208,176,180,168,215,199,23,61,179,89,129,13,180,46,59,92,189,183,173,108,186,192,32,131,184,237,182,179,191,154,12,226,182,3,154,210,177,116,57,71,213,234,175,119,210,157,21,38,219,4,131,22,220,115,18,11,99,227,132,59,100,148,62,106,109,13,168,90,106,122,11,207,14,228,157,255,9,147,39,174,0,10,177,158,7,125,68,147,15,240,210,163,8,135,104,242,1,30,254,194,6,105,93,87,98,247,203,103,101,128,113,54,108,25,231,6,107,110,118,27,212,254,224,43,211,137,90,122,218,16,204,74,221,103,111,223,185,249,249,239,190,142,67,190,183,23,213,142,176,96,232,163,214,214,126,147,209,161,196,194,216,56,82,242,223,79,241,103,187,209,103,87,188,166,221,6,181,63,75,54,178,72,218,43,13,216,76,27,10,175,246,74,3,54,96,122,4,65,195,239,96,223,85,223,103,168,239,142,110,49,121,190,105,70,140,179,97,203,26,131,102,188,160,210,111,37,54,226,104,82,149,119,12,204,3,71,11,187,185,22,2,34,47,38,5,85,190,59,186,197,40,11,189,178,146,90,180,43,4,106,179,92,167,255,215,194,49,207,208,181,139,158,217,44,29,174,222,91,176,194,100,155,38,242,99,236,156,163,106,117,10,147,109,2,169,6,9,156,63,54,14,235,133,103,7,114,19,87,0,5,130,74,191,149,20,122,184,226,174,43,177,123,56,27,182,12,155,142,210,146,13,190,213,229,183,239,220,124,33,223,219,11,212,210,211,134,66,226,212,241,248,179,221,104,110,131,218,31,205,22,190,129,91,38,185,246,225,119,176,111,119,71,183,24,230,90,8,136,112,106,15,255,202,59,6,102,92,11,1,17,255,158,101,143,105,174,98,248,211,255,107,97,69,207,108,22,120,226,10,160,238,210,13,215,84,131,4,78,194,179,3,57,97,38,103,167,247,22,96,208,77,71,105,73,219,119,110,62,74,106,209,174,220,90,214,217,102,11,223,64,240,59,216,55,83,174,188,169,197,158,187,222,127,207,178,71,233,255,181,48,28,242,189,189,138,194,186,202,48,147,179,83,166,163,180,36,5,54,208,186,147,6,215,205,41,87,222,84,191,103,217,35,46,122,102,179,184,74,97,196,2,27,104,93,148,43,111,42,55,190,11,180,161,142,12,195,27,223,5,90,141,239,2,45,110,111,32,101,114,114,111,114,44,32,101,118,101,114,121,116,104,105,110,103,32,119,101,110,116,32,111,107,0,0,0,0,110,111,116,104,105,110,103,32,100,111,110,101,32,121,101,116,0,0,0,0,0,0,0,0,101,110,100,32,111,102,32,105,110,112,117,116,32,109,101,109,111,114,121,32,114,101,97,99,104,101,100,32,119,105,116,104,111,117,116,32,104,117,102,102,109,97,110,32,101,110,100,32,99,111,100,101,0,0,0,0,101,114,114,111,114,32,105,110,32,99,111,100,101,32,116,114,101,101,32,109,97,100,101,32,105,116,32,106,117,109,112,32,111,117,116,115,105,100,101,32,111,102,32,104,117,102,102,109,97,110,32,116,114,101,101,0,112,114,111,98,108,101,109,32,119,104,105,108,101,32,112,114,111,99,101,115,115,105,110,103,32,100,121,110,97,109,105,99,32,100,101,102,108,97,116,101,32,98,108,111,99,107,0,0,117,110,101,120,105,115,116,105,110,103,32,99,111,100,101,32,119,104,105,108,101,32,112,114,111,99,101,115,115,105,110,103,32,100,121,110,97,109,105,99,32,100,101,102,108,97,116,101,32,98,108,111,99,107,0,0,101,110,100,32,111,102,32,111,117,116,32,98,117,102,102,101,114,32,109,101,109,111,114,121,32,114,101,97,99,104,101,100,32,119,104,105,108,101,32,105,110,102,108,97,116,105,110,103,0,0,0,0,0,0,0,0,105,110,118,97,108,105,100,32,100,105,115,116,97,110,99,101,32,99,111,100,101,32,119,104,105,108,101,32,105,110,102,108,97,116,105,110,103,0,0,0,105,110,118,97,108,105,100,32,100,101,102,108,97,116,101,32,98,108,111,99,107,32,66,84,89,80,69,32,101,110,99,111,117,110,116,101,114,101,100,32,119,104,105,108,101,32,100,101,99,111,100,105,110,103,0,0,78,76,69,78,32,105,115,32,110,111,116,32,111,110,101,115,32,99,111,109,112,108,101,109,101,110,116,32,111,102,32,76,69,78,32,105,110,32,97,32,100,101,102,108,97,116,101,32,98,108,111,99,107,0,0,0,101,110,100,32,111,102,32,105,110,32,98,117,102,102,101,114,32,109,101,109,111,114,121,32,114,101,97,99,104,101,100,32,119,104,105,108,101,32,105,110,102,108,97,116,105,110,103,0,105,110,118,97,108,105,100,32,70,67,72,69,67,75,32,105,110,32,122,108,105,98,32,104,101,97,100,101,114,0,0,0,105,110,118,97,108,105,100,32,99,111,109,112,114,101,115,115,105,111,110,32,109,101,116,104,111,100,32,105,110,32,122,108,105,98,32,104,101,97,100,101,114,0,0,0,0,0,0,0,70,68,73,67,84,32,101,110,99,111,117,110,116,101,114,101,100,32,105,110,32,122,108,105,98,32,104,101,97,100,101,114,32,119,104,105,108,101,32,105,116,39,115,32,110,111,116,32,117,115,101,100,32,102,111,114,32,80,78,71,0,0,0,0,80,78,71,32,102,105,108,101,32,105,115,32,115,109,97,108,108,101,114,32,116,104,97,110,32,97,32,80,78,71,32,104,101,97,100,101,114,0,0,0,105,110,99,111,114,114,101,99,116,32,80,78,71,32,115,105,103,110,97,116,117,114,101,44,32,105,116,39,115,32,110,111,32,80,78,71,32,111,114,32,99,111,114,114,117,112,116,101,100,0,0,0,0,0,0,0,102,105,114,115,116,32,99,104,117,110,107,32,105,115,32,110,111,116,32,116,104,101,32,104,101,97,100,101,114,32,99,104,117,110,107,0,0,0,0,0,99,104,117,110,107,32,108,101,110,103,116,104,32,116,111,111,32,108,97,114,103,101,44,32,99,104,117,110,107,32,98,114,111,107,101,110,32,111,102,102,32,97,116,32,101,110,100,32,111,102,32,102,105,108,101,0,105,108,108,101,103,97,108,32,80,78,71,32,99,111,108,111,114,32,116,121,112,101,32,111,114,32,98,112,112,0,0,0,105,108,108,101,103,97,108,32,80,78,71,32,99,111,109,112,114,101,115,115,105,111,110,32,109,101,116,104,111,100,0,0,105,108,108,101,103,97,108,32,80,78,71,32,102,105,108,116,101,114,32,109,101,116,104,111,100,0,0,0,0,0,0,0,105,108,108,101,103,97,108,32,80,78,71,32,105,110,116,101,114,108,97,99,101,32,109,101,116,104,111,100,0,0,0,0,99,104,117,110,107,32,108,101,110,103,116,104,32,111,102,32,97,32,99,104,117,110,107,32,105,115,32,116,111,111,32,108,97,114,103,101,32,111,114,32,116,104,101,32,99,104,117,110,107,32,116,111,111,32,115,109,97,108,108,0,0,0,0,0,105,108,108,101,103,97,108,32,80,78,71,32,102,105,108,116,101,114,32,116,121,112,101,32,101,110,99,111,117,110,116,101,114,101,100,0,0,0,0,0,105,108,108,101,103,97,108,32,98,105,116,32,100,101,112,116,104,32,102,111,114,32,116,104,105,115,32,99,111,108,111,114,32,116,121,112,101,32,103,105,118,101,110,0,0,0,0,0,116,104,101,32,112,97,108,101,116,116,101,32,105,115,32,116,111,111,32,98,105,103,0,0,109,111,114,101,32,112,97,108,101,116,116,101,32,97,108,112,104,97,32,118,97,108,117,101,115,32,103,105,118,101,110,32,105,110,32,116,82,78,83,32,99,104,117,110,107,32,116,104,97,110,32,116,104,101,114,101,32,97,114,101,32,99,111,108,111,114,115,32,105,110,32,116,104,101,32,112,97,108,101,116,116,101,0,0,0,0,0,0,116,82,78,83,32,99,104,117,110,107,32,104,97,115,32,119,114,111,110,103,32,115,105,122,101,32,102,111,114,32,103,114,101,121,115,99,97,108,101,32,105,109,97,103,101,0,0,0,116,82,78,83,32,99,104,117,110,107,32,104,97,115,32,119,114,111,110,103,32,115,105,122,101,32,102,111,114,32,82,71,66,32,105,109,97,103,101,0,116,82,78,83,32,99,104,117,110,107,32,97,112,112,101,97,114,101,100,32,119,104,105,108,101,32,105,116,32,119,97,115,32,110,111,116,32,97,108,108,111,119,101,100,32,102,111,114,32,116,104,105,115,32,99,111,108,111,114,32,116,121,112,101,0,0,0,0,0,0,0,0,98,75,71,68,32,99,104,117,110,107,32,104,97,115,32,119,114,111,110,103,32,115,105,122,101,32,102,111,114,32,112,97,108,101,116,116,101,32,105,109,97,103,101,0,0,0,0,0,98,75,71,68,32,99,104,117,110,107,32,104,97,115,32,119,114,111,110,103,32,115,105,122,101,32,102,111,114,32,103,114,101,121,115,99,97,108,101,32,105,109,97,103,101,0,0,0,98,75,71,68,32,99,104,117,110,107,32,104,97,115,32,119,114,111,110,103,32,115,105,122,101,32,102,111,114,32,82,71,66,32,105,109,97,103,101,0,97,32,118,97,108,117,101,32,105,110,32,105,110,100,101,120,101,100,32,105,109,97,103,101,32,105,115,32,108,97,114,103,101,114,32,116,104,97,110,32,116,104,101,32,112,97,108,101,116,116,101,32,115,105,122,101,32,40,98,105,116,100,101,112,116,104,32,61,32,56,41,0,97,32,118,97,108,117,101,32,105,110,32,105,110,100,101,120,101,100,32,105,109,97,103,101,32,105,115,32,108,97,114,103,101,114,32,116,104,97,110,32,116,104,101,32,112,97,108,101,116,116,101,32,115,105,122,101,32,40,98,105,116,100,101,112,116,104,32,60,32,56,41,0,101,109,112,116,121,32,105,110,112,117,116,32,111,114,32,102,105,108,101,32,100,111,101,115,110,39,116,32,101,120,105,115,116,0,0,0,0,0,0,0,106,117,109,112,101,100,32,112,97,115,116,32,109,101,109,111,114,121,32,119,104,105,108,101,32,103,101,110,101,114,97,116,105,110,103,32,100,121,110,97,109,105,99,32,104,117,102,102,109,97,110,32,116,114,101,101,0,0,0,0,0,0,0,0,106,117,109,112,101,100,32,112,97,115,116,32,109,101,109,111,114,121,32,119,104,105,108,101,32,105,110,102,108,97,116,105,110,103,32,104,117,102,102,109,97,110,32,98,108,111,99,107,0,0,0,0,0,0,0,0,106,117,109,112,101,100,32,112,97,115,116,32,109,101,109,111,114,121,32,119,104,105,108,101,32,105,110,102,108,97,116,105,110,103,0,0,0,0,0,0,115,105,122,101,32,111,102,32,122,108,105,98,32,100,97,116,97,32,116,111,111,32,115,109,97,108,108,0,0,0,0,0,114,101,112,101,97,116,32,115,121,109,98,111,108,32,105,110,32,116,114,101,101,32,119,104,105,108,101,32,116,104,101,114,101,32,119,97,115,32,110,111,32,118,97,108,117,101,32,115,121,109,98,111,108,32,121,101,116,0,0,0,0,0,0,0,106,117,109,112,101,100,32,112,97,115,116,32,116,114,101,101,32,119,104,105,108,101,32,103,101,110,101,114,97,116,105,110,103,32,104,117,102,102,109,97,110,32,116,114,101,101,0,0,103,105,118,101,110,32,111,117,116,112,117,116,32,105,109,97,103,101,32,99,111,108,111,114,116,121,112,101,32,111,114,32,98,105,116,100,101,112,116,104,32,110,111,116,32,115,117,112,112,111,114,116,101,100,32,102,111,114,32,99,111,108,111,114,32,99,111,110,118,101,114,115,105,111,110,0,0,0,0,0,105,110,118,97,108,105,100,32,67,82,67,32,101,110,99,111,117,110,116,101,114,101,100,32,40,99,104,101,99,107,105,110,103,32,67,82,67,32,99,97,110,32,98,101,32,100,105,115,97,98,108,101,100,41,0,0,105,110,118,97,108,105,100,32,65,68,76,69,82,51,50,32,101,110,99,111,117,110,116,101,114,101,100,32,40,99,104,101,99,107,105,110,103,32,65,68,76,69,82,51,50,32,99,97,110,32,98,101,32,100,105,115,97,98,108,101,100,41,0,0,114,101,113,117,101,115,116,101,100,32,99,111,108,111,114,32,99,111,110,118,101,114,115,105,111,110,32,110,111,116,32,115,117,112,112,111,114,116,101,100,0,0,0,0,0,0,0,0,105,110,118,97,108,105,100,32,119,105,110,100,111,119,32,115,105,122,101,32,103,105,118,101,110,32,105,110,32,116,104,101,32,115,101,116,116,105,110,103,115,32,111,102,32,116,104,101,32,101,110,99,111,100,101,114,32,40,109,117,115,116,32,98,101,32,48,45,51,50,55,54,56,41,0,0,0,0,0,0,105,110,118,97,108,105,100,32,66,84,89,80,69,32,103,105,118,101,110,32,105,110,32,116,104,101,32,115,101,116,116,105,110,103,115,32,111,102,32,116,104,101,32,101,110,99,111,100,101,114,32,40,111,110,108,121,32,48,44,32,49,32,97,110,100,32,50,32,97,114,101,32,97,108,108,111,119,101,100,41,0,0,0,0,0,0,0,0,99,111,110,118,101,114,115,105,111,110,32,102,114,111,109,32,99,111,108,111,114,32,116,111,32,103,114,101,121,115,99,97,108,101,32,110,111,116,32,115,117,112,112,111,114,116,101,100,0,0,0,0,0,0,0,0,108,101,110,103,116,104,32,111,102,32,97,32,99,104,117,110,107,32,116,111,111,32,108,111,110,103,44,32,109,97,120,32,97,108,108,111,119,101,100,32,102,111,114,32,80,78,71,32,105,115,32,50,49,52,55,52,56,51,54,52,55,32,98,121,116,101,115,32,112,101,114,32,99,104,117,110,107,0,0,0,116,104,101,32,108,101,110,103,116,104,32,111,102,32,116,104,101,32,69,78,68,32,115,121,109,98,111,108,32,50,53,54,32,105,110,32,116,104,101,32,72,117,102,102,109,97,110,32,116,114,101,101,32,105,115,32,48,0,0,0,0,0,0,0,116,104,101,32,108,101,110,103,116,104,32,111,102,32,97,32,116,101,120,116,32,99,104,117,110,107,32,107,101,121,119,111,114,100,32,103,105,118,101,110,32,116,111,32,116,104,101,32,101,110,99,111,100,101,114,32,105,115,32,108,111,110,103,101,114,32,116,104,97,110,32,116,104,101,32,109,97,120,105,109,117,109,32,111,102,32,55,57,32,98,121,116,101,115,0,0,116,104,101,32,108,101,110,103,116,104,32,111,102,32,97,32,116,101,120,116,32,99,104,117,110,107,32,107,101,121,119,111,114,100,32,103,105,118,101,110,32,116,111,32,116,104,101,32,101,110,99,111,100,101,114,32,105,115,32,115,109,97,108,108,101,114,32,116,104,97,110,32,116,104,101,32,109,105,110,105,109,117,109,32,111,102,32,49,32,98,121,116,101,0,0,0,116,114,105,101,100,32,116,111,32,101,110,99,111,100,101,32,97,32,80,76,84,69,32,99,104,117,110,107,32,119,105,116,104,32,97,32,112,97,108,101,116,116,101,32,116,104,97,116,32,104,97,115,32,108,101,115,115,32,116,104,97,110,32,49,32,111,114,32,109,111,114,101,32,116,104,97,110,32,50,53,54,32,99,111,108,111,114,115,0,0,0,0,0,0,0,0,117,110,107,110,111,119,110,32,99,104,117,110,107,32,116,121,112,101,32,119,105,116,104,32,39,99,114,105,116,105,99,97,108,39,32,102,108,97,103,32,101,110,99,111,117,110,116,101,114,101,100,32,98,121,32,116,104,101,32,100,101,99,111,100,101,114,0,0,0,0,0,0,117,110,101,120,105,115,116,105,110,103,32,105,110,116,101,114,108,97,99,101,32,109,111,100,101,32,103,105,118,101,110,32,116,111,32,101,110,99,111,100,101,114,32,40,109,117,115,116,32,98,101,32,48,32,111,114,32,49,41,0,0,0,0,0,119,104,105,108,101,32,100,101,99,111,100,105,110,103,44,32,117,110,101,120,105,115,116,105,110,103,32,99,111,109,112,114,101,115,115,105,111,110,32,109,101,116,104,111,100,32,101,110,99,111,117,110,116,101,114,105,110,103,32,105,110,32,122,84,88,116,32,111,114,32,105,84,88,116,32,99,104,117,110,107,32,40,105,116,32,109,117,115,116,32,98,101,32,48,41,0,105,110,118,97,108,105,100,32,116,73,77,69,32,99,104,117,110,107,32,115,105,122,101,0,105,110,118,97,108,105,100,32,112,72,89,115,32,99,104,117,110,107,32,115,105,122,101,0,110,111,32,110,117,108,108,32,116,101,114,109,105,110,97,116,105,111,110,32,99,104,97,114,32,102,111,117,110,100,32,119,104,105,108,101,32,100,101,99,111,100,105,110,103,32,116,101,120,116,32,99,104,117,110,107,0,0,0,0,0,0,0,0,105,84,88,116,32,99,104,117,110,107,32,116,111,111,32,115,104,111,114,116,32,116,111,32,99,111,110,116,97,105,110,32,114,101,113,117,105,114,101,100,32,98,121,116,101,115,0,0,105,110,116,101,103,101,114,32,111,118,101,114,102,108,111,119,32,105,110,32,98,117,102,102,101,114,32,115,105,122,101,0,102,97,105,108,101,100,32,116,111,32,111,112,101,110,32,102,105,108,101,32,102,111,114,32,114,101,97,100,105,110,103,0,102,97,105,108,101,100,32,116,111,32,111,112,101,110,32,102,105,108,101,32,102,111,114,32,119,114,105,116,105,110,103,0,116,114,105,101,100,32,99,114,101,97,116,105,110,103,32,97,32,116,114,101,101,32,111,102,32,48,32,115,121,109,98,111,108,115,0,0,0,0,0,0,108,97,122,121,32,109,97,116,99,104,105,110,103,32,97,116,32,112,111,115,32,48,32,105,115,32,105,109,112,111,115,115,105,98,108,101,0,0,0,0,99,111,108,111,114,32,99,111,110,118,101,114,115,105,111,110,32,116,111,32,112,97,108,101,116,116,101,32,114,101,113,117,101,115,116,101,100,32,119,104,105,108,101,32,97,32,99,111,108,111,114,32,105,115,110,39,116,32,105,110,32,112,97,108,101,116,116,101,0,0,0,0,109,101,109,111,114,121,32,97,108,108,111,99,97,116,105,111,110,32,102,97,105,108,101,100,0,0,0,0,0,0,0,0,103,105,118,101,110,32,105,109,97,103,101,32,116,111,111,32,115,109,97,108,108,32,116,111,32,99,111,110,116,97,105,110,32,97,108,108,32,112,105,120,101,108,115,32,116,111,32,98,101,32,101,110,99,111,100,101,100,0,0,0,0,0,0,0,105,110,116,101,114,110,97,108,32,99,111,108,111,114,32,99,111,110,118,101,114,115,105,111,110,32,98,117,103,0,0,0,105,109,112,111,115,115,105,98,108,101,32,111,102,102,115,101,116,32,105,110,32,108,122,55,55,32,101,110,99,111,100,105,110,103,32,40,105,110,116,101,114,110,97,108,32,98,117,103,41,0,0,0,0,0,0,0,109,117,115,116,32,112,114,111,118,105,100,101,32,99,117,115,116,111,109,32,122,108,105,98,32,102,117,110,99,116,105,111,110,32,112,111,105,110,116,101,114,32,105,102,32,76,79,68,69,80,78,71,95,67,79,77,80,73,76,69,95,90,76,73,66,32,105,115,32,110,111,116,32,100,101,102,105,110,101,100,0,0,0,0,0,0,0,0,105,110,118,97,108,105,100,32,102,105,108,116,101,114,32,115,116,114,97,116,101,103,121,32,103,105,118,101,110,32,102,111,114,32,76,111,100,101,80,78,71,69,110,99,111,100,101,114,83,101,116,116,105,110,103,115,46,102,105,108,116,101,114,95,115,116,114,97,116,101,103,121,0,0,0,0,0,0,0,0,116,101,120,116,32,99,104,117,110,107,32,107,101,121,119,111,114,100,32,116,111,111,32,115,104,111,114,116,32,111,114,32,108,111,110,103,58,32,109,117,115,116,32,104,97,118,101,32,115,105,122,101,32,49,45,55,57,0,0,0,0,0,0,0,119,105,110,100,111,119,115,105,122,101,32,109,117,115,116,32,98,101,32,97,32,112,111,119,101,114,32,111,102,32,116,119,111,0,0,0,0,0,0,0,117,110,107,110,111,119,110,32,101,114,114,111,114,32,99,111,100,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,130,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,86,101,110,100,111,114,58,32,37,115,10,0,0,0,0,32,82,101,110,100,101,114,101,114,58,32,37,115,10,0,0,32,86,101,114,115,105,111,110,58,32,37,115,10,0,0,0,97,116,116,114,105,98,117,116,101,32,118,101,99,52,32,97,80,111,115,105,116,105,111,110,59,32,32,32,32,32,32,10,97,116,116,114,105,98,117,116,101,32,118,101,99,50,32,97,84,101,120,67,111,111,114,100,59,32,32,32,32,32,32,10,97,116,116,114,105,98,117,116,101,32,118,101,99,52,32,97,67,111,108,111,114,59,32,32,32,32,32,32,32,32,32,10,118,97,114,121,105,110,103,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,32,32,32,32,32,32,32,32,10,118,97,114,121,105,110,103,32,118,101,99,52,32,118,67,111,108,111,114,59,32,32,32,32,32,32,32,32,32,32,32,10,117,110,105,102,111,114,109,32,109,97,116,52,32,115,80,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,59,32,10,118,111,105,100,32,109,97,105,110,40,41,32,123,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,10,32,32,32,103,108,95,80,111,115,105,116,105,111,110,32,61,32,97,80,111,115,105,116,105,111,110,32,42,32,32,32,10,32,32,32,32,32,32,32,32,32,32,32,32,115,80,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,59,32,32,10,32,32,32,118,84,101,120,67,111,111,114,100,32,61,32,97,84,101,120,67,111,111,114,100,59,32,32,32,32,32,32,10,32,32,32,118,67,111,108,111,114,32,61,32,97,67,111,108,111,114,59,32,32,32,32,32,32,32,32,32,32,32,32,10,125,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,10,0,0,0,0,0,0,112,114,101,99,105,115,105,111,110,32,109,101,100,105,117,109,112,32,102,108,111,97,116,59,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,10,118,97,114,121,105,110,103,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,10,118,97,114,121,105,110,103,32,118,101,99,52,32,118,67,111,108,111,114,59,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,115,84,101,120,116,117,114,101,59,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,10,118,111,105,100,32,109,97,105,110,40,41,32,123,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,10,32,32,103,108,95,70,114,97,103,67,111,108,111,114,32,61,32,116,101,120,116,117,114,101,50,68,40,115,84,101,120,116,117,114,101,44,32,118,84,101,120,67,111,111,114,100,41,42,118,67,111,108,111,114,59,32,10,125,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,10,0,97,80,111,115,105,116,105,111,110,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,97,84,101,120,67,111,111,114,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,97,67,111,108,111,114,0,0,0,0,0,0,0,0,0,0,115,84,101,120,116,117,114,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,115,80,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,46,112,110,103,0,0,0,0,46,80,78,71,0,0,0,0,68,114,97,119,95,76,111,97,100,73,109,97,103,101,58,32,80,78,71,32,100,101,99,111,100,101,114,32,101,114,114,111,114,32,37,117,58,32,37,115,10,0,0,0,0,0,0,0,68,114,97,119,95,76,111,97,100,73,109,97,103,101,58,32,73,109,97,103,101,32,116,121,112,101,32,110,111,116,32,115,117,112,112,111,114,116,101,100,58,32,37,115,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,254,254,254,0,0,0,0,0,0,0,0,0,0,0,16,56,124,254,0,0,0,0,254,124,56,16,0,0,32,48,56,60,56,48,32,0,4,12,28,60,28,12,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,24,24,24,24,24,0,24,0,108,108,0,0,0,0,0,0,108,108,254,108,254,108,108,0,24,62,96,60,6,124,24,0,0,198,204,24,48,102,198,0,56,108,56,118,220,204,118,0,24,24,48,0,0,0,0,0,12,24,48,48,48,24,12,0,48,24,12,12,12,24,48,0,0,108,56,254,56,108,0,0,0,24,24,126,24,24,0,0,0,0,0,0,24,24,48,0,0,0,0,126,0,0,0,0,0,0,0,0,24,24,0,0,6,12,24,48,96,192,128,0,60,102,110,118,102,60,0,0,24,56,120,24,24,24,0,0,60,102,6,28,48,126,0,0,60,102,12,6,102,60,0,0,28,60,108,204,254,12,0,0,126,96,124,6,102,60,0,0,28,48,96,124,102,60,0,0,126,6,6,12,24,24,0,0,60,102,60,102,102,60,0,0,60,102,62,6,12,56,0,0,0,24,24,0,24,24,0,0,0,24,24,0,24,24,48,0,0,6,24,96,24,6,0,0,0,0,126,0,126,0,0,0,0,96,24,6,24,96,0,0,60,102,6,12,24,0,24,0,60,102,90,90,94,96,60,0,60,102,102,126,102,102,0,0,124,102,124,102,102,124,0,0,60,96,96,96,96,60,0,0,120,108,102,102,108,120,0,0,126,96,120,96,96,126,0,0,126,96,120,96,96,96,0,0,60,102,96,110,102,62,0,0,102,102,126,102,102,102,0,0,60,24,24,24,24,60,0,0,6,6,6,6,102,60,0,0,198,204,216,248,204,198,0,0,96,96,96,96,96,124,0,0,198,238,254,214,198,198,0,0,198,230,246,222,206,198,0,0,60,102,102,102,102,60,0,0,252,198,198,252,192,192,0,0,120,204,204,204,220,126,0,0,124,102,102,124,108,102,0,0,124,198,112,28,198,124,0,0,126,24,24,24,24,24,0,0,102,102,102,102,102,60,0,0,102,102,102,102,60,24,0,0,198,198,214,254,238,198,0,0,198,108,56,56,108,198,0,0,198,108,56,48,48,48,0,0,254,12,24,48,96,254,0,0,60,48,48,48,48,48,60,0,192,96,48,24,12,6,2,0,60,12,12,12,12,12,60,0,24,60,102,0,0,0,0,0,0,0,0,0,0,0,254,0,24,24,12,0,0,0,0,0,0,60,6,62,102,62,0,0,96,96,124,102,102,124,0,0,0,60,96,96,96,60,0,0,6,6,62,102,102,62,0,0,0,60,102,126,96,60,0,0,28,48,124,48,48,48,0,0,0,62,102,102,62,6,60,0,96,96,124,102,102,102,0,0,48,0,48,48,48,24,0,0,12,0,12,12,12,12,120,0,96,102,108,120,108,102,0,0,24,24,24,24,24,12,0,0,0,236,254,214,198,198,0,0,0,124,102,102,102,102,0,0,0,60,102,102,102,60,0,0,0,124,102,102,124,96,96,0,0,62,102,102,62,6,6,0,0,124,102,96,96,96,0,0,0,60,96,60,6,124,0,0,48,48,124,48,48,28,0,0,0,102,102,102,102,62,0,0,0,102,102,102,60,24,0,0,0,198,198,214,254,108,0,0,0,204,120,48,120,204,0,0,0,102,102,102,60,24,48,0,0,126,12,24,48,126,0,0,12,24,24,48,24,24,12,0,24,24,24,24,24,24,24,0,48,24,24,12,24,24,48,0,118,220,0,0,0,0,0,0,0,16,56,108,198,198,254],"i8",ALLOC_NONE,Runtime.GLOBAL_BASE);allocate([4,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,8,0,0,0,8,0,0,0,8,0,0,0,4,0,0,0,4,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,8,0,0,0,4,0,0,0,4,0,0,0,2,0,0,0,2,0,0,0,1,0,0,0,0,0,0,0,16,0,0,0,17,0,0,0,18,0,0,0,0,0,0,0,8,0,0,0,7,0,0,0,9,0,0,0,6,0,0,0,10,0,0,0,5,0,0,0,11,0,0,0,4,0,0,0,12,0,0,0,3,0,0,0,13,0,0,0,2,0,0,0,14,0,0,0,1,0,0,0,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,3,0,0,0,3,0,0,0,3,0,0,0,3,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,5,0,0,0,5,0,0,0,5,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,2,0,0,0,2,0,0,0,3,0,0,0,3,0,0,0,4,0,0,0,4,0,0,0,5,0,0,0,5,0,0,0,6,0,0,0,6,0,0,0,7,0,0,0,7,0,0,0,8,0,0,0,8,0,0,0,9,0,0,0,9,0,0,0,10,0,0,0,10,0,0,0,11,0,0,0,11,0,0,0,12,0,0,0,12,0,0,0,13,0,0,0,13,0,0,0,3,0,0,0,4,0,0,0,5,0,0,0,6,0,0,0,7,0,0,0,8,0,0,0,9,0,0,0,10,0,0,0,11,0,0,0,13,0,0,0,15,0,0,0,17,0,0,0,19,0,0,0,23,0,0,0,27,0,0,0,31,0,0,0,35,0,0,0,43,0,0,0,51,0,0,0,59,0,0,0,67,0,0,0,83,0,0,0,99,0,0,0,115,0,0,0,131,0,0,0,163,0,0,0,195,0,0,0,227,0,0,0,2,1,0,0,0,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,4,0,0,0,5,0,0,0,7,0,0,0,9,0,0,0,13,0,0,0,17,0,0,0,25,0,0,0,33,0,0,0,49,0,0,0,65,0,0,0,97,0,0,0,129,0,0,0,193,0,0,0,1,1,0,0,129,1,0,0,1,2,0,0,1,3,0,0,1,4,0,0,1,6,0,0,1,8,0,0,1,12,0,0,1,16,0,0,1,24,0,0,1,32,0,0,1,48,0,0,1,64,0,0,1,96,0,0,10,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,0,0,0,0,0,0,42,42,42,32,68,114,97,119,32,73,110,102,111,0,0,0,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,0,0,0,0,0,0,0,68,114,97,119,95,73,110,105,116,58,32,70,97,105,108,117,114,101,32,105,110,105,116,105,97,108,105,122,105,110,103,32,118,105,100,101,111,32,109,111,100,101,46,0,0,0,0,0,68,114,97,119,95,73,110,105,116,58,32,70,97,105,108,117,114,101,32,105,110,105,116,105,97,108,105,122,105,110,103,32,83,68,76,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,83,68,76,32,69,114,114,111,114,58,32,37,115,10,0,82,73,70,70,0,0,0,0,87,65,86,69,0,0,0,0,65,117,100,105,111,95,76,111,97,100,83,111,117,110,100,58,32,70,111,114,109,97,116,32,110,111,116,32,115,117,112,112,111,114,116,101,100,58,32,115,97,109,112,108,101,82,97,116,101,58,37,100,59,32,99,104,97,110,110,101,108,115,58,37,100,59,32,66,80,66,58,37,100,10,0,0,0,0,0,0,100,97,116,97,0,0,0,0,65,117,100,105,111,95,73,110,105,116,58,32,70,97,105,108,117,114,101,32,111,112,101,110,105,110,103,32,97,117,100,105,111,46,32,40,52,52,46,49,75,104,122,47,49,54,98,47,50,99,41,46,0,0,0,0,65,117,100,105,111,95,73,110,105,116,58,32,70,97,105,108,117,114,101,32,111,112,101,110,105,110,103,32,97,117,100,105,111,46,0,0,0,0,0,0,65,117,100,105,111,95,73,110,105,116,58,32,70,97,105,108,117,114,101,32,105,110,105,116,105,97,108,105,122,105,110,103,32,83,68,76,32,65,117,100,105,111,46,0,0,0,0,0,65,117,100,105,111,95,76,111,97,100,83,111,117,110,100,58,32,70,97,105,108,117,114,101,32,111,112,101,110,105,110,103,32,102,105,108,101,46,0,0,65,117,100,105,111,95,76,111,97,100,83,111,117,110,100,58,32,68,65,84,65,32,98,108,111,99,107,32,110,111,116,32,102,111,117,110,100,0,0,0,65,117,100,105,111,95,76,111,97,100,83,111,117,110,100,58,32,78,111,116,32,80,67,77,32,102,111,114,109,97,116,46,0,0,0,0,0,0,0,0,65,117,100,105,111,95,76,111,97,100,83,111,117,110,100,58,32,70,105,108,101,32,116,111,111,32,115,104,111,114,116,46,0,0,0,0,0,0,0,0,65,117,100,105,111,95,76,111,97,100,83,111,117,110,100,58,32,70,105,108,101,32,105,115,32,110,111,116,32,87,65,86,69,46,0,0,0,0,0,0,65,117,100,105,111,95,76,111,97,100,83,111,117,110,100,58,32,70,105,108,101,32,105,115,32,110,111,116,32,82,73,70,70,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,116,95,112,114,111,99,46,46,46,46,46,58,37,54,108,108,100,10,0,0,0,0,0,0,116,95,99,111,108,46,46,46,46,46,46,58,37,54,108,108,100,10,0,0,0,0,0,0,116,95,111,118,101,114,46,46,46,46,46,58,37,54,108,108,100,10,0,0,0,0,0,0,116,95,112,111,115,116,112,114,111,99,46,58,37,54,108,108,100,10,0,0,0,0,0,0,116,95,100,114,97,119,46,46,46,46,46,58,37,54,108,108,100,10,0,0,0,0,0,0,80,114,111,102,105,108,105,110,103,58,58,58,58,58,58,58,58,58,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,97,116,97,47,98,97,114,114,101,108,46,112,110,103,0,0,0,0,0,0,0,0,0,100,97,116,97,47,98,97,114,114,101,108,50,46,112,110,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,97,116,97,47,102,108,111,111,114,46,112,110,103,0,0,0,0,0,0,0,0,0,0,100,97,116,97,47,102,108,111,111,114,95,108,101,102,116,46,112,110,103,0,0,0,0,0,0,0,0,0,0,0,0,0,100,97,116,97,47,102,108,111,111,114,95,114,105,103,104,116,46,112,110,103,0,0,0,0,0,0,0,0,0,0,0,0,100,97,116,97,47,102,108,111,111,114,95,99,101,110,116,101,114,46,112,110,103,0,0,0,0,0,0,0,0,0,0,0,100,97,116,97,47,99,111,108,117,109,110,46,112,110,103,0,0,0,0,0,0,0,0,0,100,97,116,97,47,99,111,108,117,109,110,95,102,97,100,101,100,46,112,110,103,0,0,0,0,0,0,0,0,0,0,0,100,97,116,97,47,114,111,99,107,46,112,110,103,0,0,0,0,0,0,0,0,0,0,0,100,97,116,97,47,108,97,109,112,46,112,110,103,0,0,0,0,0,0,0,0,0,0,0,100,97,116,97,47,104,111,108,101,95,115,112,105,107,101,100,46,112,110,103,0,0,0,0,0,0,0,0,0,0,0,0,100,97,116,97,47,104,111,108,101,95,108,97,118,97,46,112,110,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,97,116,97,47,112,108,97,121,101,114,95,117,112,46,112,110,103,0,0,0,0,0,0,100,97,116,97,47,112,108,97,121,101,114,95,100,111,119,110,46,112,110,103,0,0,0,0,100,97,116,97,47,112,108,97,121,101,114,95,108,101,102,116,46,112,110,103,0,0,0,0,100,97,116,97,47,112,108,97,121,101,114,95,114,105,103,104,116,46,112,110,103,0,0,0,100,97,116,97,47,115,97,118,101,95,112,111,105,110,116,46,112,110,103,0,0,0,0,0,100,97,116,97,47,115,97,118,101,95,112,111,105,110,116,95,97,99,116,105,118,101,46,112,110,103,0,0,0,0,0,0,100,97,116,97,47,101,120,105,116,95,112,111,105,110,116,46,112,110,103,0,0,0,0,0,0,0,0,0,0,0,0,0,100,97,116,97,47,101,110,100,95,112,111,105,110,116,46,112,110,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,97,116,97,47,97,114,114,111,119,115,104,111,111,116,101,114,95,117,112,46,112,110,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,97,116,97,47,97,114,114,111,119,115,104,111,111,116,101,114,95,100,111,119,110,46,112,110,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,97,116,97,47,97,114,114,111,119,115,104,111,111,116,101,114,95,108,101,102,116,46,112,110,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,97,116,97,47,97,114,114,111,119,115,104,111,111,116,101,114,95,114,105,103,104,116,46,112,110,103,0,0,0,0,0,0,0,0,0,0,0,0,0,100,97,116,97,47,97,114,114,111,119,95,117,112,46,112,110,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,97,116,97,47,97,114,114,111,119,95,100,111,119,110,46,112,110,103,0,0,0,0,0,0,0,0,0,0,0,0,0,100,97,116,97,47,97,114,114,111,119,95,108,101,102,116,46,112,110,103,0,0,0,0,0,0,0,0,0,0,0,0,0,100,97,116,97,47,97,114,114,111,119,95,114,105,103,104,116,46,112,110,103,0,0,0,0,0,0,0,0,0,0,0,0,100,97,116,97,47,102,105,114,101,46,112,110,103,0,0,0,0,0,0,0,0,0,0,0,100,97,116,97,47,112,108,97,121,101,114,95,98,114,111,107,101,110,46,112,110,103,0,0,0,0,0,0,0,0,0,0,100,97,116,97,47,72,105,116,95,72,117,114,116,49,48,46,119,97,118,0,0,0,0,0,100,97,116,97,47,80,111,119,101,114,117,112,49,48,46,119,97,118,0,0,0,0,0,0,100,97,116,97,47,80,111,119,101,114,117,112,51,48,46,119,97,118,0,0,0,0,0,0,100,97,116,97,47,76,97,115,101,114,95,83,104,111,111,116,50,46,119,97,118,0,0,0,100,97,116,97,47,69,120,112,108,111,115,105,111,110,50,46,119,97,118,0,0,0,0,0,100,97,116,97,47,72,105,116,95,72,117,114,116,49,54,46,119,97,118,0,0,0,0,0,100,97,116,97,47,69,120,112,108,111,115,105,111,110,49,54,46,119,97,118,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,97,116,97,47,108,101,118,101,108,95,37,48,50,100,46,116,120,116,0,0,0,0,0,114,0,0,0,0,0,0,0,37,100,32,37,100,0,0,0,115,97,118,101,115,47,103,97,109,101,46,115,97,118,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,80,114,101,115,115,32,91,83,112,97,99,101,93,32,116,111,32,83,116,97,114,116,46,0,80,114,101,115,115,32,91,83,112,97,99,101,93,32,116,111,32,67,111,110,116,105,110,117,101,46,0,0,0,0,0,0,80,114,101,115,115,32,91,88,93,32,116,111,32,83,116,97,114,116,46,0,0,0,0,0,66,121,32,75,97,98,108,101,97,100,111,32,40,86,65,82,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67,111,110,103,114,97,116,117,108,97,116,105,111,110,115,32,121,111,117,32,115,97,118,101,100,32,116,104,101,32,107,105,116,116,105,101,33,0,0,0,84,104,97,110,107,115,32,102,111,114,32,112,108,97,121,105,110,103,33,0,0,0,0,0,80,114,101,115,115,32,91,83,112,97,99,101,93,32,116,111,32,84,105,116,108,101,46,0,76,101,118,101,108,58,32,37,100,46,37,100,0,0,0,0,76,101,118,101,108,32,67,111,109,112,108,101,116,101,0,0,76,101,118,101,108,32,67,111,109,112,108,101,116,101,46,0,89,111,117,32,97,114,101,32,100,101,97,100,46,0,0,0,115,97,118,101,115,0,0,0,114,98,0,0,0,0,0,0,119,98,0,0,0,0,0,0,70,83,46,115,121,110,99,102,115,40,102,117,110,99,116,105,111,110,32,40,101,114,114,41,32,123,32,125,41,59,0,0,100,101,98,117,103,0,0,0,71,97,109,101,0,0,0,0,100,97,116,97,47,108,111,103,111,46,112,110,103,0,0,0,100,97,116,97,47,101,110,100,46,112,110,103,0,0,0,0,68,101,98,117,103,32,77,111,100,101,32,65,99,116,105,118,97,116,101,100,33,0,0,0,2,0,0,192,3,0,0,192,4,0,0,192,5,0,0,192,6,0,0,192,7,0,0,192,8,0,0,192,9,0,0,192,10,0,0,192,11,0,0,192,12,0,0,192,13,0,0,192,14,0,0,192,15,0,0,192,16,0,0,192,17,0,0,192,18,0,0,192,19,0,0,192,20,0,0,192,21,0,0,192,22,0,0,192,23,0,0,192,24,0,0,192,25,0,0,192,26,0,0,192,27,0,0,192,28,0,0,192,29,0,0,192,30,0,0,192,31,0,0,192,0,0,0,179,1,0,0,195,2,0,0,195,3,0,0,195,4,0,0,195,5,0,0,195,6,0,0,195,7,0,0,195,8,0,0,195,9,0,0,195,10,0,0,195,11,0,0,195,12,0,0,195,13,0,0,211,14,0,0,195,15,0,0,195,0,0,12,187,1,0,12,195,2,0,12,195,3,0,12,195,4,0,12,211,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,1,2,3,4,5,6,7,8,9,255,255,255,255,255,255,255,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,255,255,255,255,255,255,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,1,2,4,7,3,6,5,0,0,0,0,0,0,0,0,105,110,102,105,110,105,116,121,0,0,0,0,0,0,0,0,95,112,137,0,255,9,47,15,10,0,0,0,100,0,0,0,232,3,0,0,16,39,0,0,160,134,1,0,64,66,15,0,128,150,152,0,0,225,245,5,17,0,10,0,17,17,17,0,0,0,0,5,0,0,0,0,0,0,9,0,0,0,0,11,0,0,0,0,0,0,0,0,17,0,15,10,17,17,17,3,10,7,0,1,19,9,11,11,0,0,9,6,11,0,0,11,0,6,17,0,0,0,17,17,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,17,0,10,10,17,17,17,0,10,0,0,2,0,9,11,0,0,0,9,0,11,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,12,0,0,0,0,9,12,0,0,0,0,0,12,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,4,13,0,0,0,0,9,14,0,0,0,0,0,14,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,15,0,0,0,0,9,16,0,0,0,0,0,16,0,0,16,0,0,18,0,0,0,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,0,0,0,18,18,18,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,10,0,0,0,0,9,11,0,0,0,0,0,11,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,12,0,0,0,0,9,12,0,0,0,0,0,12,0,0,12,0,0,45,43,32,32,32,48,88,48,120,0,0,0,0,0,0,0,40,110,117,108,108,41,0,0,45,48,88,43,48,88,32,48,88,45,48,120,43,48,120,32,48,120,0,0,0,0,0,0,105,110,102,0,0,0,0,0,73,78,70,0,0,0,0,0,110,97,110,0,0,0,0,0,78,65,78,0,0,0,0,0,48,49,50,51,52,53,54,55,56,57,65,66,67,68,69,70,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"i8",ALLOC_NONE,Runtime.GLOBAL_BASE+8344);var tempDoublePtr=Runtime.alignMemory(allocate(12,"i8",ALLOC_STATIC),8);assert(tempDoublePtr%8==0);function copyTempFloat(ptr){HEAP8[tempDoublePtr]=HEAP8[ptr];HEAP8[tempDoublePtr+1]=HEAP8[ptr+1];HEAP8[tempDoublePtr+2]=HEAP8[ptr+2];HEAP8[tempDoublePtr+3]=HEAP8[ptr+3]}function copyTempDouble(ptr){HEAP8[tempDoublePtr]=HEAP8[ptr];HEAP8[tempDoublePtr+1]=HEAP8[ptr+1];HEAP8[tempDoublePtr+2]=HEAP8[ptr+2];HEAP8[tempDoublePtr+3]=HEAP8[ptr+3];HEAP8[tempDoublePtr+4]=HEAP8[ptr+4];HEAP8[tempDoublePtr+5]=HEAP8[ptr+5];HEAP8[tempDoublePtr+6]=HEAP8[ptr+6];HEAP8[tempDoublePtr+7]=HEAP8[ptr+7]}Module["_rand_r"]=_rand_r;var ___rand_seed=allocate([41108891,0,0,0],"i32",ALLOC_STATIC);Module["_rand"]=_rand;Module["_i64Subtract"]=_i64Subtract;function _fabsf(){return Math_abs.apply(null,arguments)}Module["_i64Add"]=_i64Add;var ERRNO_CODES={EPERM:1,ENOENT:2,ESRCH:3,EINTR:4,EIO:5,ENXIO:6,E2BIG:7,ENOEXEC:8,EBADF:9,ECHILD:10,EAGAIN:11,EWOULDBLOCK:11,ENOMEM:12,EACCES:13,EFAULT:14,ENOTBLK:15,EBUSY:16,EEXIST:17,EXDEV:18,ENODEV:19,ENOTDIR:20,EISDIR:21,EINVAL:22,ENFILE:23,EMFILE:24,ENOTTY:25,ETXTBSY:26,EFBIG:27,ENOSPC:28,ESPIPE:29,EROFS:30,EMLINK:31,EPIPE:32,EDOM:33,ERANGE:34,ENOMSG:42,EIDRM:43,ECHRNG:44,EL2NSYNC:45,EL3HLT:46,EL3RST:47,ELNRNG:48,EUNATCH:49,ENOCSI:50,EL2HLT:51,EDEADLK:35,ENOLCK:37,EBADE:52,EBADR:53,EXFULL:54,ENOANO:55,EBADRQC:56,EBADSLT:57,EDEADLOCK:35,EBFONT:59,ENOSTR:60,ENODATA:61,ETIME:62,ENOSR:63,ENONET:64,ENOPKG:65,EREMOTE:66,ENOLINK:67,EADV:68,ESRMNT:69,ECOMM:70,EPROTO:71,EMULTIHOP:72,EDOTDOT:73,EBADMSG:74,ENOTUNIQ:76,EBADFD:77,EREMCHG:78,ELIBACC:79,ELIBBAD:80,ELIBSCN:81,ELIBMAX:82,ELIBEXEC:83,ENOSYS:38,ENOTEMPTY:39,ENAMETOOLONG:36,ELOOP:40,EOPNOTSUPP:95,EPFNOSUPPORT:96,ECONNRESET:104,ENOBUFS:105,EAFNOSUPPORT:97,EPROTOTYPE:91,ENOTSOCK:88,ENOPROTOOPT:92,ESHUTDOWN:108,ECONNREFUSED:111,EADDRINUSE:98,ECONNABORTED:103,ENETUNREACH:101,ENETDOWN:100,ETIMEDOUT:110,EHOSTDOWN:112,EHOSTUNREACH:113,EINPROGRESS:115,EALREADY:114,EDESTADDRREQ:89,EMSGSIZE:90,EPROTONOSUPPORT:93,ESOCKTNOSUPPORT:94,EADDRNOTAVAIL:99,ENETRESET:102,EISCONN:106,ENOTCONN:107,ETOOMANYREFS:109,EUSERS:87,EDQUOT:122,ESTALE:116,ENOTSUP:95,ENOMEDIUM:123,EILSEQ:84,EOVERFLOW:75,ECANCELED:125,ENOTRECOVERABLE:131,EOWNERDEAD:130,ESTRPIPE:86};var ERRNO_MESSAGES={0:"Success",1:"Not super-user",2:"No such file or directory",3:"No such process",4:"Interrupted system call",5:"I/O error",6:"No such device or address",7:"Arg list too long",8:"Exec format error",9:"Bad file number",10:"No children",11:"No more processes",12:"Not enough core",13:"Permission denied",14:"Bad address",15:"Block device required",16:"Mount device busy",17:"File exists",18:"Cross-device link",19:"No such device",20:"Not a directory",21:"Is a directory",22:"Invalid argument",23:"Too many open files in system",24:"Too many open files",25:"Not a typewriter",26:"Text file busy",27:"File too large",28:"No space left on device",29:"Illegal seek",30:"Read only file system",31:"Too many links",32:"Broken pipe",33:"Math arg out of domain of func",34:"Math result not representable",35:"File locking deadlock error",36:"File or path name too long",37:"No record locks available",38:"Function not implemented",39:"Directory not empty",40:"Too many symbolic links",42:"No message of desired type",43:"Identifier removed",44:"Channel number out of range",45:"Level 2 not synchronized",46:"Level 3 halted",47:"Level 3 reset",48:"Link number out of range",49:"Protocol driver not attached",50:"No CSI structure available",51:"Level 2 halted",52:"Invalid exchange",53:"Invalid request descriptor",54:"Exchange full",55:"No anode",56:"Invalid request code",57:"Invalid slot",59:"Bad font file fmt",60:"Device not a stream",61:"No data (for no delay io)",62:"Timer expired",63:"Out of streams resources",64:"Machine is not on the network",65:"Package not installed",66:"The object is remote",67:"The link has been severed",68:"Advertise error",69:"Srmount error",70:"Communication error on send",71:"Protocol error",72:"Multihop attempted",73:"Cross mount point (not really error)",74:"Trying to read unreadable message",75:"Value too large for defined data type",76:"Given log. name not unique",77:"f.d. invalid for this operation",78:"Remote address changed",79:"Can access a needed shared lib",80:"Accessing a corrupted shared lib",81:".lib section in a.out corrupted",82:"Attempting to link in too many libs",83:"Attempting to exec a shared library",84:"Illegal byte sequence",86:"Streams pipe error",87:"Too many users",88:"Socket operation on non-socket",89:"Destination address required",90:"Message too long",91:"Protocol wrong type for socket",92:"Protocol not available",93:"Unknown protocol",94:"Socket type not supported",95:"Not supported",96:"Protocol family not supported",97:"Address family not supported by protocol family",98:"Address already in use",99:"Address not available",100:"Network interface is not configured",101:"Network is unreachable",102:"Connection reset by network",103:"Connection aborted",104:"Connection reset by peer",105:"No buffer space available",106:"Socket is already connected",107:"Socket is not connected",108:"Can't send after socket shutdown",109:"Too many references",110:"Connection timed out",111:"Connection refused",112:"Host is down",113:"Host is unreachable",114:"Socket already connected",115:"Connection already in progress",116:"Stale file handle",122:"Quota exceeded",123:"No medium (in tape drive)",125:"Operation canceled",130:"Previous owner died",131:"State not recoverable"};var ___errno_state=0;function ___setErrNo(value){HEAP32[___errno_state>>2]=value;return value}var PATH={splitPath:(function(filename){var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)}),normalizeArray:(function(parts,allowAboveRoot){var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up--;up){parts.unshift("..")}}return parts}),normalize:(function(path){var isAbsolute=path.charAt(0)==="/",trailingSlash=path.substr(-1)==="/";path=PATH.normalizeArray(path.split("/").filter((function(p){return!!p})),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path}),dirname:(function(path){var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.substr(0,dir.length-1)}return root+dir}),basename:(function(path){if(path==="/")return"/";var lastSlash=path.lastIndexOf("/");if(lastSlash===-1)return path;return path.substr(lastSlash+1)}),extname:(function(path){return PATH.splitPath(path)[3]}),join:(function(){var paths=Array.prototype.slice.call(arguments,0);return PATH.normalize(paths.join("/"))}),join2:(function(l,r){return PATH.normalize(l+"/"+r)}),resolve:(function(){var resolvedPath="",resolvedAbsolute=false;for(var i=arguments.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?arguments[i]:FS.cwd();if(typeof path!=="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){continue}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=path.charAt(0)==="/"}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter((function(p){return!!p})),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."}),relative:(function(from,to){from=PATH.resolve(from).substr(1);to=PATH.resolve(to).substr(1);function trim(arr){var start=0;for(;start=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;inode.contents.length){node.contents=MEMFS.getFileDataAsRegularArray(node);node.usedBytes=node.contents.length}if(!node.contents||node.contents.subarray){var prevCapacity=node.contents?node.contents.buffer.byteLength:0;if(prevCapacity>=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity0)node.contents.set(oldContents.subarray(0,node.usedBytes),0);return}if(!node.contents&&newCapacity>0)node.contents=[];while(node.contents.lengthnewSize)node.contents.length=newSize;else while(node.contents.length=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);assert(size>=0);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i0||position+lengthe2.timestamp){create.push(key);total++}}));var remove=[];Object.keys(dst.entries).forEach((function(key){var e=dst.entries[key];var e2=src.entries[key];if(!e2){remove.push(key);total++}}));if(!total){return callback(null)}var errored=false;var completed=0;var db=src.type==="remote"?src.db:dst.db;var transaction=db.transaction([IDBFS.DB_STORE_NAME],"readwrite");var store=transaction.objectStore(IDBFS.DB_STORE_NAME);function done(err){if(err){if(!done.errored){done.errored=true;return callback(err)}return}if(++completed>=total){return callback(null)}}transaction.onerror=(function(){done(this.error)});create.sort().forEach((function(path){if(dst.type==="local"){IDBFS.loadRemoteEntry(store,path,(function(err,entry){if(err)return done(err);IDBFS.storeLocalEntry(path,entry,done)}))}else{IDBFS.loadLocalEntry(path,(function(err,entry){if(err)return done(err);IDBFS.storeRemoteEntry(store,path,entry,done)}))}}));remove.sort().reverse().forEach((function(path){if(dst.type==="local"){IDBFS.removeLocalEntry(path,done)}else{IDBFS.removeRemoteEntry(store,path,done)}}))})};var NODEFS={isWindows:false,staticInit:(function(){NODEFS.isWindows=!!process.platform.match(/^win/)}),mount:(function(mount){assert(ENVIRONMENT_IS_NODE);return NODEFS.createNode(null,"/",NODEFS.getMode(mount.opts.root),0)}),createNode:(function(parent,name,mode,dev){if(!FS.isDir(mode)&&!FS.isFile(mode)&&!FS.isLink(mode)){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}var node=FS.createNode(parent,name,mode);node.node_ops=NODEFS.node_ops;node.stream_ops=NODEFS.stream_ops;return node}),getMode:(function(path){var stat;try{stat=fs.lstatSync(path);if(NODEFS.isWindows){stat.mode=stat.mode|(stat.mode&146)>>1}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}return stat.mode}),realPath:(function(node){var parts=[];while(node.parent!==node){parts.push(node.name);node=node.parent}parts.push(node.mount.opts.root);parts.reverse();return PATH.join.apply(null,parts)}),flagsToPermissionStringMap:{0:"r",1:"r+",2:"r+",64:"r",65:"r+",66:"r+",129:"rx+",193:"rx+",514:"w+",577:"w",578:"w+",705:"wx",706:"wx+",1024:"a",1025:"a",1026:"a+",1089:"a",1090:"a+",1153:"ax",1154:"ax+",1217:"ax",1218:"ax+",4096:"rs",4098:"rs+"},flagsToPermissionString:(function(flags){if(flags in NODEFS.flagsToPermissionStringMap){return NODEFS.flagsToPermissionStringMap[flags]}else{return flags}}),node_ops:{getattr:(function(node){var path=NODEFS.realPath(node);var stat;try{stat=fs.lstatSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}if(NODEFS.isWindows&&!stat.blksize){stat.blksize=4096}if(NODEFS.isWindows&&!stat.blocks){stat.blocks=(stat.size+stat.blksize-1)/stat.blksize|0}return{dev:stat.dev,ino:stat.ino,mode:stat.mode,nlink:stat.nlink,uid:stat.uid,gid:stat.gid,rdev:stat.rdev,size:stat.size,atime:stat.atime,mtime:stat.mtime,ctime:stat.ctime,blksize:stat.blksize,blocks:stat.blocks}}),setattr:(function(node,attr){var path=NODEFS.realPath(node);try{if(attr.mode!==undefined){fs.chmodSync(path,attr.mode);node.mode=attr.mode}if(attr.timestamp!==undefined){var date=new Date(attr.timestamp);fs.utimesSync(path,date,date)}if(attr.size!==undefined){fs.truncateSync(path,attr.size)}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}}),lookup:(function(parent,name){var path=PATH.join2(NODEFS.realPath(parent),name);var mode=NODEFS.getMode(path);return NODEFS.createNode(parent,name,mode)}),mknod:(function(parent,name,mode,dev){var node=NODEFS.createNode(parent,name,mode,dev);var path=NODEFS.realPath(node);try{if(FS.isDir(node.mode)){fs.mkdirSync(path,node.mode)}else{fs.writeFileSync(path,"",{mode:node.mode})}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}return node}),rename:(function(oldNode,newDir,newName){var oldPath=NODEFS.realPath(oldNode);var newPath=PATH.join2(NODEFS.realPath(newDir),newName);try{fs.renameSync(oldPath,newPath)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}}),unlink:(function(parent,name){var path=PATH.join2(NODEFS.realPath(parent),name);try{fs.unlinkSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}}),rmdir:(function(parent,name){var path=PATH.join2(NODEFS.realPath(parent),name);try{fs.rmdirSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}}),readdir:(function(node){var path=NODEFS.realPath(node);try{return fs.readdirSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}}),symlink:(function(parent,newName,oldPath){var newPath=PATH.join2(NODEFS.realPath(parent),newName);try{fs.symlinkSync(oldPath,newPath)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}}),readlink:(function(node){var path=NODEFS.realPath(node);try{return fs.readlinkSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}})},stream_ops:{open:(function(stream){var path=NODEFS.realPath(stream.node);try{if(FS.isFile(stream.node.mode)){stream.nfd=fs.openSync(path,NODEFS.flagsToPermissionString(stream.flags))}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}}),close:(function(stream){try{if(FS.isFile(stream.node.mode)&&stream.nfd){fs.closeSync(stream.nfd)}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}}),read:(function(stream,buffer,offset,length,position){var nbuffer=new Buffer(length);var res;try{res=fs.readSync(stream.nfd,nbuffer,0,length,position)}catch(e){throw new FS.ErrnoError(ERRNO_CODES[e.code])}if(res>0){for(var i=0;i8){throw new FS.ErrnoError(ERRNO_CODES.ELOOP)}var parts=PATH.normalizeArray(path.split("/").filter((function(p){return!!p})),false);var current=FS.root;var current_path="/";for(var i=0;i40){throw new FS.ErrnoError(ERRNO_CODES.ELOOP)}}}}return{path:current_path,node:current}}),getPath:(function(node){var path;while(true){if(FS.isRoot(node)){var mount=node.mount.mountpoint;if(!path)return mount;return mount[mount.length-1]!=="/"?mount+"/"+path:mount+path}path=path?node.name+"/"+path:node.name;node=node.parent}}),hashName:(function(parentid,name){var hash=0;for(var i=0;i>>0)%FS.nameTable.length}),hashAddNode:(function(node){var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node}),hashRemoveNode:(function(node){var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}}),lookupNode:(function(parent,name){var err=FS.mayLookup(parent);if(err){throw new FS.ErrnoError(err)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)}),createNode:(function(parent,name,mode,rdev){if(!FS.FSNode){FS.FSNode=(function(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.mounted=null;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.node_ops={};this.stream_ops={};this.rdev=rdev});FS.FSNode.prototype={};var readMode=292|73;var writeMode=146;Object.defineProperties(FS.FSNode.prototype,{read:{get:(function(){return(this.mode&readMode)===readMode}),set:(function(val){val?this.mode|=readMode:this.mode&=~readMode})},write:{get:(function(){return(this.mode&writeMode)===writeMode}),set:(function(val){val?this.mode|=writeMode:this.mode&=~writeMode})},isFolder:{get:(function(){return FS.isDir(this.mode)})},isDevice:{get:(function(){return FS.isChrdev(this.mode)})}})}var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node}),destroyNode:(function(node){FS.hashRemoveNode(node)}),isRoot:(function(node){return node===node.parent}),isMountpoint:(function(node){return!!node.mounted}),isFile:(function(mode){return(mode&61440)===32768}),isDir:(function(mode){return(mode&61440)===16384}),isLink:(function(mode){return(mode&61440)===40960}),isChrdev:(function(mode){return(mode&61440)===8192}),isBlkdev:(function(mode){return(mode&61440)===24576}),isFIFO:(function(mode){return(mode&61440)===4096}),isSocket:(function(mode){return(mode&49152)===49152}),flagModes:{"r":0,"rs":1052672,"r+":2,"w":577,"wx":705,"xw":705,"w+":578,"wx+":706,"xw+":706,"a":1089,"ax":1217,"xa":1217,"a+":1090,"ax+":1218,"xa+":1218},modeStringToFlags:(function(str){var flags=FS.flagModes[str];if(typeof flags==="undefined"){throw new Error("Unknown file open mode: "+str)}return flags}),flagsToPermissionString:(function(flag){var accmode=flag&2097155;var perms=["r","w","rw"][accmode];if(flag&512){perms+="w"}return perms}),nodePermissions:(function(node,perms){if(FS.ignorePermissions){return 0}if(perms.indexOf("r")!==-1&&!(node.mode&292)){return ERRNO_CODES.EACCES}else if(perms.indexOf("w")!==-1&&!(node.mode&146)){return ERRNO_CODES.EACCES}else if(perms.indexOf("x")!==-1&&!(node.mode&73)){return ERRNO_CODES.EACCES}return 0}),mayLookup:(function(dir){return FS.nodePermissions(dir,"x")}),mayCreate:(function(dir,name){try{var node=FS.lookupNode(dir,name);return ERRNO_CODES.EEXIST}catch(e){}return FS.nodePermissions(dir,"wx")}),mayDelete:(function(dir,name,isdir){var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var err=FS.nodePermissions(dir,"wx");if(err){return err}if(isdir){if(!FS.isDir(node.mode)){return ERRNO_CODES.ENOTDIR}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return ERRNO_CODES.EBUSY}}else{if(FS.isDir(node.mode)){return ERRNO_CODES.EISDIR}}return 0}),mayOpen:(function(node,flags){if(!node){return ERRNO_CODES.ENOENT}if(FS.isLink(node.mode)){return ERRNO_CODES.ELOOP}else if(FS.isDir(node.mode)){if((flags&2097155)!==0||flags&512){return ERRNO_CODES.EISDIR}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))}),MAX_OPEN_FDS:4096,nextfd:(function(fd_start,fd_end){fd_start=fd_start||0;fd_end=fd_end||FS.MAX_OPEN_FDS;for(var fd=fd_start;fd<=fd_end;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(ERRNO_CODES.EMFILE)}),getStream:(function(fd){return FS.streams[fd]}),createStream:(function(stream,fd_start,fd_end){if(!FS.FSStream){FS.FSStream=(function(){});FS.FSStream.prototype={};Object.defineProperties(FS.FSStream.prototype,{object:{get:(function(){return this.node}),set:(function(val){this.node=val})},isRead:{get:(function(){return(this.flags&2097155)!==1})},isWrite:{get:(function(){return(this.flags&2097155)!==0})},isAppend:{get:(function(){return this.flags&1024})}})}var newStream=new FS.FSStream;for(var p in stream){newStream[p]=stream[p]}stream=newStream;var fd=FS.nextfd(fd_start,fd_end);stream.fd=fd;FS.streams[fd]=stream;return stream}),closeStream:(function(fd){FS.streams[fd]=null}),getStreamFromPtr:(function(ptr){return FS.streams[ptr-1]}),getPtrForStream:(function(stream){return stream?stream.fd+1:0}),chrdev_stream_ops:{open:(function(stream){var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;if(stream.stream_ops.open){stream.stream_ops.open(stream)}}),llseek:(function(){throw new FS.ErrnoError(ERRNO_CODES.ESPIPE)})},major:(function(dev){return dev>>8}),minor:(function(dev){return dev&255}),makedev:(function(ma,mi){return ma<<8|mi}),registerDevice:(function(dev,ops){FS.devices[dev]={stream_ops:ops}}),getDevice:(function(dev){return FS.devices[dev]}),getMounts:(function(mount){var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push.apply(check,m.mounts)}return mounts}),syncfs:(function(populate,callback){if(typeof populate==="function"){callback=populate;populate=false}var mounts=FS.getMounts(FS.root.mount);var completed=0;function done(err){if(err){if(!done.errored){done.errored=true;return callback(err)}return}if(++completed>=mounts.length){callback(null)}}mounts.forEach((function(mount){if(!mount.type.syncfs){return done(null)}mount.type.syncfs(mount,populate,done)}))}),mount:(function(type,opts,mountpoint){var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(ERRNO_CODES.EBUSY)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(ERRNO_CODES.EBUSY)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR)}}var mount={type:type,opts:opts,mountpoint:mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot}),unmount:(function(mountpoint){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);Object.keys(FS.nameTable).forEach((function(hash){var current=FS.nameTable[hash];while(current){var next=current.name_next;if(mounts.indexOf(current.mount)!==-1){FS.destroyNode(current)}current=next}}));node.mounted=null;var idx=node.mount.mounts.indexOf(mount);assert(idx!==-1);node.mount.mounts.splice(idx,1)}),lookup:(function(parent,name){return parent.node_ops.lookup(parent,name)}),mknod:(function(path,mode,dev){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);var err=FS.mayCreate(parent,name);if(err){throw new FS.ErrnoError(err)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}return parent.node_ops.mknod(parent,name,mode,dev)}),create:(function(path,mode){mode=mode!==undefined?mode:438;mode&=4095;mode|=32768;return FS.mknod(path,mode,0)}),mkdir:(function(path,mode){mode=mode!==undefined?mode:511;mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)}),mkdev:(function(path,mode,dev){if(typeof dev==="undefined"){dev=mode;mode=438}mode|=8192;return FS.mknod(path,mode,dev)}),symlink:(function(oldpath,newpath){var lookup=FS.lookupPath(newpath,{parent:true});var parent=lookup.node;var newname=PATH.basename(newpath);var err=FS.mayCreate(parent,newname);if(err){throw new FS.ErrnoError(err)}if(!parent.node_ops.symlink){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}return parent.node_ops.symlink(parent,newname,oldpath)}),rename:(function(old_path,new_path){var old_dirname=PATH.dirname(old_path);var new_dirname=PATH.dirname(new_path);var old_name=PATH.basename(old_path);var new_name=PATH.basename(new_path);var lookup,old_dir,new_dir;try{lookup=FS.lookupPath(old_path,{parent:true});old_dir=lookup.node;lookup=FS.lookupPath(new_path,{parent:true});new_dir=lookup.node}catch(e){throw new FS.ErrnoError(ERRNO_CODES.EBUSY)}if(old_dir.mount!==new_dir.mount){throw new FS.ErrnoError(ERRNO_CODES.EXDEV)}var old_node=FS.lookupNode(old_dir,old_name);var relative=PATH.relative(old_path,new_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}relative=PATH.relative(new_path,old_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY)}var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(old_node===new_node){return}var isdir=FS.isDir(old_node.mode);var err=FS.mayDelete(old_dir,old_name,isdir);if(err){throw new FS.ErrnoError(err)}err=new_node?FS.mayDelete(new_dir,new_name,isdir):FS.mayCreate(new_dir,new_name);if(err){throw new FS.ErrnoError(err)}if(!old_dir.node_ops.rename){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}if(FS.isMountpoint(old_node)||new_node&&FS.isMountpoint(new_node)){throw new FS.ErrnoError(ERRNO_CODES.EBUSY)}if(new_dir!==old_dir){err=FS.nodePermissions(old_dir,"w");if(err){throw new FS.ErrnoError(err)}}try{if(FS.trackingDelegate["willMovePath"]){FS.trackingDelegate["willMovePath"](old_path,new_path)}}catch(e){console.log("FS.trackingDelegate['willMovePath']('"+old_path+"', '"+new_path+"') threw an exception: "+e.message)}FS.hashRemoveNode(old_node);try{old_dir.node_ops.rename(old_node,new_dir,new_name)}catch(e){throw e}finally{FS.hashAddNode(old_node)}try{if(FS.trackingDelegate["onMovePath"])FS.trackingDelegate["onMovePath"](old_path,new_path)}catch(e){console.log("FS.trackingDelegate['onMovePath']('"+old_path+"', '"+new_path+"') threw an exception: "+e.message)}}),rmdir:(function(path){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var err=FS.mayDelete(parent,name,true);if(err){throw new FS.ErrnoError(err)}if(!parent.node_ops.rmdir){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(ERRNO_CODES.EBUSY)}try{if(FS.trackingDelegate["willDeletePath"]){FS.trackingDelegate["willDeletePath"](path)}}catch(e){console.log("FS.trackingDelegate['willDeletePath']('"+path+"') threw an exception: "+e.message)}parent.node_ops.rmdir(parent,name);FS.destroyNode(node);try{if(FS.trackingDelegate["onDeletePath"])FS.trackingDelegate["onDeletePath"](path)}catch(e){console.log("FS.trackingDelegate['onDeletePath']('"+path+"') threw an exception: "+e.message)}}),readdir:(function(path){var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;if(!node.node_ops.readdir){throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR)}return node.node_ops.readdir(node)}),unlink:(function(path){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var err=FS.mayDelete(parent,name,false);if(err){if(err===ERRNO_CODES.EISDIR)err=ERRNO_CODES.EPERM;throw new FS.ErrnoError(err)}if(!parent.node_ops.unlink){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(ERRNO_CODES.EBUSY)}try{if(FS.trackingDelegate["willDeletePath"]){FS.trackingDelegate["willDeletePath"](path)}}catch(e){console.log("FS.trackingDelegate['willDeletePath']('"+path+"') threw an exception: "+e.message)}parent.node_ops.unlink(parent,name);FS.destroyNode(node);try{if(FS.trackingDelegate["onDeletePath"])FS.trackingDelegate["onDeletePath"](path)}catch(e){console.log("FS.trackingDelegate['onDeletePath']('"+path+"') threw an exception: "+e.message)}}),readlink:(function(path){var lookup=FS.lookupPath(path);var link=lookup.node;if(!link.node_ops.readlink){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}return link.node_ops.readlink(link)}),stat:(function(path,dontFollow){var lookup=FS.lookupPath(path,{follow:!dontFollow});var node=lookup.node;if(!node.node_ops.getattr){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}return node.node_ops.getattr(node)}),lstat:(function(path){return FS.stat(path,true)}),chmod:(function(path,mode,dontFollow){var node;if(typeof path==="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}node.node_ops.setattr(node,{mode:mode&4095|node.mode&~4095,timestamp:Date.now()})}),lchmod:(function(path,mode){FS.chmod(path,mode,true)}),fchmod:(function(fd,mode){var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(ERRNO_CODES.EBADF)}FS.chmod(stream.node,mode)}),chown:(function(path,uid,gid,dontFollow){var node;if(typeof path==="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}node.node_ops.setattr(node,{timestamp:Date.now()})}),lchown:(function(path,uid,gid){FS.chown(path,uid,gid,true)}),fchown:(function(fd,uid,gid){var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(ERRNO_CODES.EBADF)}FS.chown(stream.node,uid,gid)}),truncate:(function(path,len){if(len<0){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}var node;if(typeof path==="string"){var lookup=FS.lookupPath(path,{follow:true});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}if(FS.isDir(node.mode)){throw new FS.ErrnoError(ERRNO_CODES.EISDIR)}if(!FS.isFile(node.mode)){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}var err=FS.nodePermissions(node,"w");if(err){throw new FS.ErrnoError(err)}node.node_ops.setattr(node,{size:len,timestamp:Date.now()})}),ftruncate:(function(fd,len){var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(ERRNO_CODES.EBADF)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}FS.truncate(stream.node,len)}),utime:(function(path,atime,mtime){var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;node.node_ops.setattr(node,{timestamp:Math.max(atime,mtime)})}),open:(function(path,flags,mode,fd_start,fd_end){if(path===""){throw new FS.ErrnoError(ERRNO_CODES.ENOENT)}flags=typeof flags==="string"?FS.modeStringToFlags(flags):flags;mode=typeof mode==="undefined"?438:mode;if(flags&64){mode=mode&4095|32768}else{mode=0}var node;if(typeof path==="object"){node=path}else{path=PATH.normalize(path);try{var lookup=FS.lookupPath(path,{follow:!(flags&131072)});node=lookup.node}catch(e){}}if(flags&64){if(node){if(flags&128){throw new FS.ErrnoError(ERRNO_CODES.EEXIST)}}else{node=FS.mknod(path,mode,0)}}if(!node){throw new FS.ErrnoError(ERRNO_CODES.ENOENT)}if(FS.isChrdev(node.mode)){flags&=~512}var err=FS.mayOpen(node,flags);if(err){throw new FS.ErrnoError(err)}if(flags&512){FS.truncate(node,0)}flags&=~(128|512);var stream=FS.createStream({node:node,path:FS.getPath(node),flags:flags,seekable:true,position:0,stream_ops:node.stream_ops,ungotten:[],error:false},fd_start,fd_end);if(stream.stream_ops.open){stream.stream_ops.open(stream)}if(Module["logReadFiles"]&&!(flags&1)){if(!FS.readFiles)FS.readFiles={};if(!(path in FS.readFiles)){FS.readFiles[path]=1;Module["printErr"]("read file: "+path)}}try{if(FS.trackingDelegate["onOpenFile"]){var trackingFlags=0;if((flags&2097155)!==1){trackingFlags|=FS.tracking.openFlags.READ}if((flags&2097155)!==0){trackingFlags|=FS.tracking.openFlags.WRITE}FS.trackingDelegate["onOpenFile"](path,trackingFlags)}}catch(e){console.log("FS.trackingDelegate['onOpenFile']('"+path+"', flags) threw an exception: "+e.message)}return stream}),close:(function(stream){try{if(stream.stream_ops.close){stream.stream_ops.close(stream)}}catch(e){throw e}finally{FS.closeStream(stream.fd)}}),llseek:(function(stream,offset,whence){if(!stream.seekable||!stream.stream_ops.llseek){throw new FS.ErrnoError(ERRNO_CODES.ESPIPE)}return stream.stream_ops.llseek(stream,offset,whence)}),read:(function(stream,buffer,offset,length,position){if(length<0||position<0){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(ERRNO_CODES.EBADF)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(ERRNO_CODES.EISDIR)}if(!stream.stream_ops.read){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}var seeking=true;if(typeof position==="undefined"){position=stream.position;seeking=false}else if(!stream.seekable){throw new FS.ErrnoError(ERRNO_CODES.ESPIPE)}var bytesRead=stream.stream_ops.read(stream,buffer,offset,length,position);if(!seeking)stream.position+=bytesRead;return bytesRead}),write:(function(stream,buffer,offset,length,position,canOwn){if(length<0||position<0){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(ERRNO_CODES.EBADF)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(ERRNO_CODES.EISDIR)}if(!stream.stream_ops.write){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}if(stream.flags&1024){FS.llseek(stream,0,2)}var seeking=true;if(typeof position==="undefined"){position=stream.position;seeking=false}else if(!stream.seekable){throw new FS.ErrnoError(ERRNO_CODES.ESPIPE)}var bytesWritten=stream.stream_ops.write(stream,buffer,offset,length,position,canOwn);if(!seeking)stream.position+=bytesWritten;try{if(stream.path&&FS.trackingDelegate["onWriteToFile"])FS.trackingDelegate["onWriteToFile"](stream.path)}catch(e){console.log("FS.trackingDelegate['onWriteToFile']('"+path+"') threw an exception: "+e.message)}return bytesWritten}),allocate:(function(stream,offset,length){if(offset<0||length<=0){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(ERRNO_CODES.EBADF)}if(!FS.isFile(stream.node.mode)&&!FS.isDir(node.mode)){throw new FS.ErrnoError(ERRNO_CODES.ENODEV)}if(!stream.stream_ops.allocate){throw new FS.ErrnoError(ERRNO_CODES.EOPNOTSUPP)}stream.stream_ops.allocate(stream,offset,length)}),mmap:(function(stream,buffer,offset,length,position,prot,flags){if((stream.flags&2097155)===1){throw new FS.ErrnoError(ERRNO_CODES.EACCES)}if(!stream.stream_ops.mmap){throw new FS.ErrnoError(ERRNO_CODES.ENODEV)}return stream.stream_ops.mmap(stream,buffer,offset,length,position,prot,flags)}),ioctl:(function(stream,cmd,arg){if(!stream.stream_ops.ioctl){throw new FS.ErrnoError(ERRNO_CODES.ENOTTY)}return stream.stream_ops.ioctl(stream,cmd,arg)}),readFile:(function(path,opts){opts=opts||{};opts.flags=opts.flags||"r";opts.encoding=opts.encoding||"binary";if(opts.encoding!=="utf8"&&opts.encoding!=="binary"){throw new Error('Invalid encoding type "'+opts.encoding+'"')}var ret;var stream=FS.open(path,opts.flags);var stat=FS.stat(path);var length=stat.size;var buf=new Uint8Array(length);FS.read(stream,buf,0,length,0);if(opts.encoding==="utf8"){ret="";var utf8=new Runtime.UTF8Processor;for(var i=0;i>2]=FS.getPtrForStream(stdin);assert(stdin.fd===0,"invalid handle for stdin ("+stdin.fd+")");var stdout=FS.open("/dev/stdout","w");HEAP32[_stdout>>2]=FS.getPtrForStream(stdout);assert(stdout.fd===1,"invalid handle for stdout ("+stdout.fd+")");var stderr=FS.open("/dev/stderr","w");HEAP32[_stderr>>2]=FS.getPtrForStream(stderr);assert(stderr.fd===2,"invalid handle for stderr ("+stderr.fd+")")}),ensureErrnoError:(function(){if(FS.ErrnoError)return;FS.ErrnoError=function ErrnoError(errno){this.errno=errno;for(var key in ERRNO_CODES){if(ERRNO_CODES[key]===errno){this.code=key;break}}this.message=ERRNO_MESSAGES[errno]};FS.ErrnoError.prototype=new Error;FS.ErrnoError.prototype.constructor=FS.ErrnoError;[ERRNO_CODES.ENOENT].forEach((function(code){FS.genericErrors[code]=new FS.ErrnoError(code);FS.genericErrors[code].stack=""}))}),staticInit:(function(){FS.ensureErrnoError();FS.nameTable=new Array(4096);FS.mount(MEMFS,{},"/");FS.createDefaultDirectories();FS.createDefaultDevices()}),init:(function(input,output,error){assert(!FS.init.initialized,"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)");FS.init.initialized=true;FS.ensureErrnoError();Module["stdin"]=input||Module["stdin"];Module["stdout"]=output||Module["stdout"];Module["stderr"]=error||Module["stderr"];FS.createStandardStreams()}),quit:(function(){FS.init.initialized=false;for(var i=0;ithis.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=Math.floor(idx/this.chunkSize);return this.getter(chunkNum)[chunkOffset]};LazyUint8Array.prototype.setDataGetter=function LazyUint8Array_setDataGetter(getter){this.getter=getter};LazyUint8Array.prototype.cacheLength=function LazyUint8Array_cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=(function(from,to){if(from>to)throw new Error("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)throw new Error("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);if(typeof Uint8Array!="undefined")xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}else{return intArrayFromString(xhr.responseText||"",true)}});var lazyArray=this;lazyArray.setDataGetter((function(chunkNum){var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]==="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]==="undefined")throw new Error("doXHR failed!");return lazyArray.chunks[chunkNum]}));this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true};if(typeof XMLHttpRequest!=="undefined"){if(!ENVIRONMENT_IS_WORKER)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var lazyArray=new LazyUint8Array;Object.defineProperty(lazyArray,"length",{get:(function(){if(!this.lengthKnown){this.cacheLength()}return this._length})});Object.defineProperty(lazyArray,"chunkSize",{get:(function(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize})});var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url:url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperty(node,"usedBytes",{get:(function(){return this.contents.length})});var stream_ops={};var keys=Object.keys(node.stream_ops);keys.forEach((function(key){var fn=node.stream_ops[key];stream_ops[key]=function forceLoadLazyFile(){if(!FS.forceLoadFile(node)){throw new FS.ErrnoError(ERRNO_CODES.EIO)}return fn.apply(null,arguments)}}));stream_ops.read=function stream_ops_read(stream,buffer,offset,length,position){if(!FS.forceLoadFile(node)){throw new FS.ErrnoError(ERRNO_CODES.EIO)}var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);assert(size>=0);if(contents.slice){for(var i=0;ipow2){pow2<<=1;++log2}GL.log2ceilLookup[i]=log2}}),generateTempBuffers:(function(quads){var largestIndex=GL.log2ceilLookup[GL.MAX_TEMP_BUFFER_SIZE];GL.tempVertexBufferCounters1.length=GL.tempVertexBufferCounters2.length=largestIndex+1;GL.tempVertexBuffers1.length=GL.tempVertexBuffers2.length=largestIndex+1;GL.tempIndexBuffers.length=largestIndex+1;for(var i=0;i<=largestIndex;++i){GL.tempIndexBuffers[i]=null;GL.tempVertexBufferCounters1[i]=GL.tempVertexBufferCounters2[i]=0;var ringbufferLength=GL.numTempVertexBuffersPerSize;GL.tempVertexBuffers1[i]=[];GL.tempVertexBuffers2[i]=[];var ringbuffer1=GL.tempVertexBuffers1[i];var ringbuffer2=GL.tempVertexBuffers2[i];ringbuffer1.length=ringbuffer2.length=ringbufferLength;for(var j=0;j>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}GLctx.bufferData(GLctx.ELEMENT_ARRAY_BUFFER,quadIndexes,GLctx.STATIC_DRAW);GLctx.bindBuffer(GLctx.ELEMENT_ARRAY_BUFFER,null)}}),getTempVertexBuffer:function getTempVertexBuffer(sizeBytes){var idx=GL.log2ceilLookup[sizeBytes];var ringbuffer=GL.tempVertexBuffers1[idx];var nextFreeBufferIndex=GL.tempVertexBufferCounters1[idx];GL.tempVertexBufferCounters1[idx]=GL.tempVertexBufferCounters1[idx]+1&GL.numTempVertexBuffersPerSize-1;var vbo=ringbuffer[nextFreeBufferIndex];if(vbo){return vbo}var prevVBO=GLctx.getParameter(GLctx.ARRAY_BUFFER_BINDING);ringbuffer[nextFreeBufferIndex]=GLctx.createBuffer();GLctx.bindBuffer(GLctx.ARRAY_BUFFER,ringbuffer[nextFreeBufferIndex]);GLctx.bufferData(GLctx.ARRAY_BUFFER,1<>2];if(len<0){frag=Pointer_stringify(HEAP32[string+i*4>>2])}else{frag=Pointer_stringify(HEAP32[string+i*4>>2],len)}}else{frag=Pointer_stringify(HEAP32[string+i*4>>2])}source+=frag}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}),get:(function(name_,p,type){if(!p){GL.recordError(1281);return}var ret=undefined;switch(name_){case 36346:ret=1;break;case 36344:if(type!=="Integer"){GL.recordError(1280)}return;case 36345:ret=0;break;case 34466:var formats=GLctx.getParameter(34467);ret=formats.length;break;case 35738:ret=5121;break;case 35739:ret=6408;break}if(ret===undefined){var result=GLctx.getParameter(name_);switch(typeof result){case"number":ret=result;break;case"boolean":ret=result?1:0;break;case"string":GL.recordError(1280);return;case"object":if(result===null){switch(name_){case 34964:case 35725:case 34965:case 36006:case 36007:case 32873:case 34068:{ret=0;break};default:{GL.recordError(1280);return}}}else if(result instanceof Float32Array||result instanceof Uint32Array||result instanceof Int32Array||result instanceof Array){for(var i=0;i>2]=result[i];break;case"Float":HEAPF32[p+i*4>>2]=result[i];break;case"Boolean":HEAP8[p+i>>0]=result[i]?1:0;break;default:throw"internal glGet error, bad type: "+type}}return}else if(result instanceof WebGLBuffer||result instanceof WebGLProgram||result instanceof WebGLFramebuffer||result instanceof WebGLRenderbuffer||result instanceof WebGLTexture){ret=result.name|0}else{GL.recordError(1280);return}break;default:GL.recordError(1280);return}}switch(type){case"Integer":HEAP32[p>>2]=ret;break;case"Float":HEAPF32[p>>2]=ret;break;case"Boolean":HEAP8[p>>0]=ret?1:0;break;default:throw"internal glGet error, bad type: "+type}}),getTexPixelData:(function(type,format,width,height,pixels,internalFormat){var sizePerPixel;switch(type){case 5121:switch(format){case 6406:case 6409:sizePerPixel=1;break;case 6407:sizePerPixel=3;break;case 6408:sizePerPixel=4;break;case 6410:sizePerPixel=2;break;default:GL.recordError(1280);return{pixels:null,internalFormat:0}}break;case 5123:if(format==6402){sizePerPixel=2}else{GL.recordError(1280);return{pixels:null,internalFormat:0}}break;case 5125:if(format==6402){sizePerPixel=4}else{GL.recordError(1280);return{pixels:null,internalFormat:0}}break;case 34042:sizePerPixel=4;break;case 33635:case 32819:case 32820:sizePerPixel=2;break;case 5126:switch(format){case 6407:sizePerPixel=3*4;break;case 6408:sizePerPixel=4*4;break;default:GL.recordError(1280);return{pixels:null,internalFormat:0}}internalFormat=GLctx.RGBA;break;default:GL.recordError(1280);return{pixels:null,internalFormat:0}}var bytes=GL.computeImageSize(width,height,sizePerPixel,GL.unpackAlignment);if(type==5121){pixels=HEAPU8.subarray(pixels,pixels+bytes)}else if(type==5126){pixels=HEAPF32.subarray(pixels>>2,pixels+bytes>>2)}else if(type==5125||type==34042){pixels=HEAPU32.subarray(pixels>>2,pixels+bytes>>2)}else{pixels=HEAPU16.subarray(pixels>>1,pixels+bytes>>1)}return{pixels:pixels,internalFormat:internalFormat}}),calcBufLength:function calcBufLength(size,type,stride,count){if(stride>0){return count*stride}var typeSize=GL.byteSizeByType[type-GL.byteSizeByTypeRoot];return size*typeSize*count},usedTempBuffers:[],preDrawHandleClientVertexAttribBindings:function preDrawHandleClientVertexAttribBindings(count){GL.resetBufferBinding=false;for(var i=0;i>8,sock.sport&255]))}return peer}),getPeer:(function(sock,addr,port){return sock.peers[addr+":"+port]}),addPeer:(function(sock,peer){sock.peers[peer.addr+":"+peer.port]=peer}),removePeer:(function(sock,peer){delete sock.peers[peer.addr+":"+peer.port]}),handlePeerEvents:(function(sock,peer){var first=true;var handleOpen=(function(){try{var queued=peer.dgram_send_queue.shift();while(queued){peer.socket.send(queued);queued=peer.dgram_send_queue.shift()}}catch(e){peer.socket.close()}});function handleMessage(data){assert(typeof data!=="string"&&data.byteLength!==undefined);data=new Uint8Array(data);var wasfirst=first;first=false;if(wasfirst&&data.length===10&&data[0]===255&&data[1]===255&&data[2]===255&&data[3]===255&&data[4]==="p".charCodeAt(0)&&data[5]==="o".charCodeAt(0)&&data[6]==="r".charCodeAt(0)&&data[7]==="t".charCodeAt(0)){var newport=data[8]<<8|data[9];SOCKFS.websocket_sock_ops.removePeer(sock,peer);peer.port=newport;SOCKFS.websocket_sock_ops.addPeer(sock,peer);return}sock.recv_queue.push({addr:peer.addr,port:peer.port,data:data})}if(ENVIRONMENT_IS_NODE){peer.socket.on("open",handleOpen);peer.socket.on("message",(function(data,flags){if(!flags.binary){return}handleMessage((new Uint8Array(data)).buffer)}));peer.socket.on("error",(function(){}))}else{peer.socket.onopen=handleOpen;peer.socket.onmessage=function peer_socket_onmessage(event){handleMessage(event.data)}}}),poll:(function(sock){if(sock.type===1&&sock.server){return sock.pending.length?64|1:0}var mask=0;var dest=sock.type===1?SOCKFS.websocket_sock_ops.getPeer(sock,sock.daddr,sock.dport):null;if(sock.recv_queue.length||!dest||dest&&dest.socket.readyState===dest.socket.CLOSING||dest&&dest.socket.readyState===dest.socket.CLOSED){mask|=64|1}if(!dest||dest&&dest.socket.readyState===dest.socket.OPEN){mask|=4}if(dest&&dest.socket.readyState===dest.socket.CLOSING||dest&&dest.socket.readyState===dest.socket.CLOSED){mask|=16}return mask}),ioctl:(function(sock,request,arg){switch(request){case 21531:var bytes=0;if(sock.recv_queue.length){bytes=sock.recv_queue[0].data.length}HEAP32[arg>>2]=bytes;return 0;default:return ERRNO_CODES.EINVAL}}),close:(function(sock){if(sock.server){try{sock.server.close()}catch(e){}sock.server=null}var peers=Object.keys(sock.peers);for(var i=0;i0){HEAP8[ptr++>>0]=streamObj.ungotten.pop();bytesToRead--;bytesRead++}var err=_read(streamObj.fd,ptr,bytesToRead);if(err==-1){if(streamObj)streamObj.error=true;return 0}bytesRead+=err;if(bytesRead=6){var curr=leftchar>>leftbits-6&63;leftbits-=6;ret+=BASE[curr]}}if(leftbits==2){ret+=BASE[(leftchar&3)<<4];ret+=PAD+PAD}else if(leftbits==4){ret+=BASE[(leftchar&15)<<2];ret+=PAD}return ret}audio.src="data:audio/x-"+name.substr(-3)+";base64,"+encode64(byteArray);finish(audio)};audio.src=url;Browser.safeSetTimeout((function(){finish(audio)}),1e4)}else{return fail()}};Module["preloadPlugins"].push(audioPlugin);var canvas=Module["canvas"];function pointerLockChange(){Browser.pointerLock=document["pointerLockElement"]===canvas||document["mozPointerLockElement"]===canvas||document["webkitPointerLockElement"]===canvas||document["msPointerLockElement"]===canvas}if(canvas){canvas.requestPointerLock=canvas["requestPointerLock"]||canvas["mozRequestPointerLock"]||canvas["webkitRequestPointerLock"]||canvas["msRequestPointerLock"]||(function(){});canvas.exitPointerLock=document["exitPointerLock"]||document["mozExitPointerLock"]||document["webkitExitPointerLock"]||document["msExitPointerLock"]||(function(){});canvas.exitPointerLock=canvas.exitPointerLock.bind(document);document.addEventListener("pointerlockchange",pointerLockChange,false);document.addEventListener("mozpointerlockchange",pointerLockChange,false);document.addEventListener("webkitpointerlockchange",pointerLockChange,false);document.addEventListener("mspointerlockchange",pointerLockChange,false);if(Module["elementPointerLock"]){canvas.addEventListener("click",(function(ev){if(!Browser.pointerLock&&canvas.requestPointerLock){canvas.requestPointerLock();ev.preventDefault()}}),false)}}}),createContext:(function(canvas,useWebGL,setInModule,webGLContextAttributes){if(useWebGL&&Module.ctx)return Module.ctx;var ctx;var errorInfo="?";function onContextCreationError(event){errorInfo=event.statusMessage||errorInfo}try{if(useWebGL){var contextAttributes={antialias:false,alpha:false};if(webGLContextAttributes){for(var attribute in webGLContextAttributes){contextAttributes[attribute]=webGLContextAttributes[attribute]}}canvas.addEventListener("webglcontextcreationerror",onContextCreationError,false);try{["experimental-webgl","webgl"].some((function(webglId){return ctx=canvas.getContext(webglId,contextAttributes)}))}finally{canvas.removeEventListener("webglcontextcreationerror",onContextCreationError,false)}}else{ctx=canvas.getContext("2d")}if(!ctx)throw":("}catch(e){Module.print("Could not create canvas: "+[errorInfo,e]);return null}if(useWebGL){canvas.style.backgroundColor="black"}if(setInModule){if(!useWebGL)assert(typeof GLctx==="undefined","cannot set in module if GLctx is used, but we are a non-GL context that would replace it");Module.ctx=ctx;if(useWebGL)GLctx=ctx;Module.useWebGL=useWebGL;Browser.moduleContextCreatedCallbacks.forEach((function(callback){callback()}));Browser.init()}return ctx}),destroyContext:(function(canvas,useWebGL,setInModule){}),fullScreenHandlersInstalled:false,lockPointer:undefined,resizeCanvas:undefined,requestFullScreen:(function(lockPointer,resizeCanvas){Browser.lockPointer=lockPointer;Browser.resizeCanvas=resizeCanvas;if(typeof Browser.lockPointer==="undefined")Browser.lockPointer=true;if(typeof Browser.resizeCanvas==="undefined")Browser.resizeCanvas=false;var canvas=Module["canvas"];function fullScreenChange(){Browser.isFullScreen=false;var canvasContainer=canvas.parentNode;if((document["webkitFullScreenElement"]||document["webkitFullscreenElement"]||document["mozFullScreenElement"]||document["mozFullscreenElement"]||document["fullScreenElement"]||document["fullscreenElement"]||document["msFullScreenElement"]||document["msFullscreenElement"]||document["webkitCurrentFullScreenElement"])===canvasContainer){canvas.cancelFullScreen=document["cancelFullScreen"]||document["mozCancelFullScreen"]||document["webkitCancelFullScreen"]||document["msExitFullscreen"]||document["exitFullscreen"]||(function(){});canvas.cancelFullScreen=canvas.cancelFullScreen.bind(document);if(Browser.lockPointer)canvas.requestPointerLock();Browser.isFullScreen=true;if(Browser.resizeCanvas)Browser.setFullScreenCanvasSize()}else{canvasContainer.parentNode.insertBefore(canvas,canvasContainer);canvasContainer.parentNode.removeChild(canvasContainer);if(Browser.resizeCanvas)Browser.setWindowedCanvasSize()}if(Module["onFullScreen"])Module["onFullScreen"](Browser.isFullScreen);Browser.updateCanvasDimensions(canvas)}if(!Browser.fullScreenHandlersInstalled){Browser.fullScreenHandlersInstalled=true;document.addEventListener("fullscreenchange",fullScreenChange,false);document.addEventListener("mozfullscreenchange",fullScreenChange,false);document.addEventListener("webkitfullscreenchange",fullScreenChange,false);document.addEventListener("MSFullscreenChange",fullScreenChange,false)}var canvasContainer=document.createElement("div");canvas.parentNode.insertBefore(canvasContainer,canvas);canvasContainer.appendChild(canvas);canvasContainer.requestFullScreen=canvasContainer["requestFullScreen"]||canvasContainer["mozRequestFullScreen"]||canvasContainer["msRequestFullscreen"]||(canvasContainer["webkitRequestFullScreen"]?(function(){canvasContainer["webkitRequestFullScreen"](Element["ALLOW_KEYBOARD_INPUT"])}):null);canvasContainer.requestFullScreen()}),nextRAF:0,fakeRequestAnimationFrame:(function(func){var now=Date.now();if(Browser.nextRAF===0){Browser.nextRAF=now+1e3/60}else{while(now+2>=Browser.nextRAF){Browser.nextRAF+=1e3/60}}var delay=Math.max(Browser.nextRAF-now,0);setTimeout(func,delay)}),requestAnimationFrame:function requestAnimationFrame(func){if(typeof window==="undefined"){Browser.fakeRequestAnimationFrame(func)}else{if(!window.requestAnimationFrame){window.requestAnimationFrame=window["requestAnimationFrame"]||window["mozRequestAnimationFrame"]||window["webkitRequestAnimationFrame"]||window["msRequestAnimationFrame"]||window["oRequestAnimationFrame"]||Browser.fakeRequestAnimationFrame}window.requestAnimationFrame(func)}},safeCallback:(function(func){return(function(){if(!ABORT)return func.apply(null,arguments)})}),safeRequestAnimationFrame:(function(func){return Browser.requestAnimationFrame((function(){if(!ABORT)func()}))}),safeSetTimeout:(function(func,timeout){Module["noExitRuntime"]=true;return setTimeout((function(){if(!ABORT)func()}),timeout)}),safeSetInterval:(function(func,timeout){Module["noExitRuntime"]=true;return setInterval((function(){if(!ABORT)func()}),timeout)}),getMimetype:(function(name){return{"jpg":"image/jpeg","jpeg":"image/jpeg","png":"image/png","bmp":"image/bmp","ogg":"audio/ogg","wav":"audio/wav","mp3":"audio/mpeg"}[name.substr(name.lastIndexOf(".")+1)]}),getUserMedia:(function(func){if(!window.getUserMedia){window.getUserMedia=navigator["getUserMedia"]||navigator["mozGetUserMedia"]}window.getUserMedia(func)}),getMovementX:(function(event){return event["movementX"]||event["mozMovementX"]||event["webkitMovementX"]||0}),getMovementY:(function(event){return event["movementY"]||event["mozMovementY"]||event["webkitMovementY"]||0}),getMouseWheelDelta:(function(event){var delta=0;switch(event.type){case"DOMMouseScroll":delta=event.detail;break;case"mousewheel":delta=-event.wheelDelta;break;case"wheel":delta=event.deltaY;break;default:throw"unrecognized mouse wheel event: "+event.type}return Math.max(-1,Math.min(1,delta))}),mouseX:0,mouseY:0,mouseMovementX:0,mouseMovementY:0,touches:{},lastTouches:{},calculateMouseEvent:(function(event){if(Browser.pointerLock){if(event.type!="mousemove"&&"mozMovementX"in event){Browser.mouseMovementX=Browser.mouseMovementY=0}else{Browser.mouseMovementX=Browser.getMovementX(event);Browser.mouseMovementY=Browser.getMovementY(event)}if(typeof SDL!="undefined"){Browser.mouseX=SDL.mouseX+Browser.mouseMovementX;Browser.mouseY=SDL.mouseY+Browser.mouseMovementY}else{Browser.mouseX+=Browser.mouseMovementX;Browser.mouseY+=Browser.mouseMovementY}}else{var rect=Module["canvas"].getBoundingClientRect();var cw=Module["canvas"].width;var ch=Module["canvas"].height;var scrollX=typeof window.scrollX!=="undefined"?window.scrollX:window.pageXOffset;var scrollY=typeof window.scrollY!=="undefined"?window.scrollY:window.pageYOffset;if(event.type==="touchstart"||event.type==="touchend"||event.type==="touchmove"){var touch=event.touch;if(touch===undefined){return}var adjustedX=touch.pageX-(scrollX+rect.left);var adjustedY=touch.pageY-(scrollY+rect.top);adjustedX=adjustedX*(cw/rect.width);adjustedY=adjustedY*(ch/rect.height);var coords={x:adjustedX,y:adjustedY};if(event.type==="touchstart"){Browser.lastTouches[touch.identifier]=coords;Browser.touches[touch.identifier]=coords}else if(event.type==="touchend"||event.type==="touchmove"){Browser.lastTouches[touch.identifier]=Browser.touches[touch.identifier];Browser.touches[touch.identifier]={x:adjustedX,y:adjustedY}}return}var x=event.pageX-(scrollX+rect.left);var y=event.pageY-(scrollY+rect.top);x=x*(cw/rect.width);y=y*(ch/rect.height);Browser.mouseMovementX=x-Browser.mouseX;Browser.mouseMovementY=y-Browser.mouseY;Browser.mouseX=x;Browser.mouseY=y}}),xhrLoad:(function(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function xhr_onload(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response)}else{onerror()}};xhr.onerror=onerror;xhr.send(null)}),asyncLoad:(function(url,onload,onerror,noRunDep){Browser.xhrLoad(url,(function(arrayBuffer){assert(arrayBuffer,'Loading data file "'+url+'" failed (no arrayBuffer).');onload(new Uint8Array(arrayBuffer));if(!noRunDep)removeRunDependency("al "+url)}),(function(event){if(onerror){onerror()}else{throw'Loading data file "'+url+'" failed.'}}));if(!noRunDep)addRunDependency("al "+url)}),resizeListeners:[],updateResizeListeners:(function(){var canvas=Module["canvas"];Browser.resizeListeners.forEach((function(listener){listener(canvas.width,canvas.height)}))}),setCanvasSize:(function(width,height,noUpdates){var canvas=Module["canvas"];Browser.updateCanvasDimensions(canvas,width,height);if(!noUpdates)Browser.updateResizeListeners()}),windowedWidth:0,windowedHeight:0,setFullScreenCanvasSize:(function(){if(typeof SDL!="undefined"){var flags=HEAPU32[SDL.screen+Runtime.QUANTUM_SIZE*0>>2];flags=flags|8388608;HEAP32[SDL.screen+Runtime.QUANTUM_SIZE*0>>2]=flags}Browser.updateResizeListeners()}),setWindowedCanvasSize:(function(){if(typeof SDL!="undefined"){var flags=HEAPU32[SDL.screen+Runtime.QUANTUM_SIZE*0>>2];flags=flags&~8388608;HEAP32[SDL.screen+Runtime.QUANTUM_SIZE*0>>2]=flags}Browser.updateResizeListeners()}),updateCanvasDimensions:(function(canvas,wNative,hNative){if(wNative&&hNative){canvas.widthNative=wNative;canvas.heightNative=hNative}else{wNative=canvas.widthNative;hNative=canvas.heightNative}var w=wNative;var h=hNative;if(Module["forcedAspectRatio"]&&Module["forcedAspectRatio"]>0){if(w/h>2]=poolPtr;HEAP32[_environ>>2]=envPtr}else{envPtr=HEAP32[_environ>>2];poolPtr=HEAP32[envPtr>>2]}var strings=[];var totalSize=0;for(var key in env){if(typeof env[key]==="string"){var line=key+"="+env[key];strings.push(line);totalSize+=line.length}}if(totalSize>TOTAL_ENV_SIZE){throw new Error("Environment size exceeded TOTAL_ENV_SIZE!")}var ptrSize=4;for(var i=0;i>2]=poolPtr;poolPtr+=line.length+1}HEAP32[envPtr+strings.length*ptrSize>>2]=0}var ENV={};function _getenv(name){if(name===0)return 0;name=Pointer_stringify(name);if(!ENV.hasOwnProperty(name))return 0;if(_getenv.ret)_free(_getenv.ret);_getenv.ret=allocate(intArrayFromString(ENV[name]),"i8",ALLOC_NORMAL);return _getenv.ret}function _putenv(string){if(string===0){___setErrNo(ERRNO_CODES.EINVAL);return-1}string=Pointer_stringify(string);var splitPoint=string.indexOf("=");if(string===""||string.indexOf("=")===-1){___setErrNo(ERRNO_CODES.EINVAL);return-1}var name=string.slice(0,splitPoint);var value=string.slice(splitPoint+1);if(!(name in ENV)||ENV[name]!==value){ENV[name]=value;___buildEnvironment(ENV)}return 0}function _SDL_RWFromConstMem(mem,size){var id=SDL.rwops.length;SDL.rwops.push({bytes:mem,count:size});return id}function _TTF_RenderText_Solid(font,text,color){text=Pointer_stringify(text)||" ";var fontData=SDL.fonts[font];var w=SDL.estimateTextWidth(fontData,text);var h=fontData.size;var color=SDL.loadColorToCSSRGB(color);var fontString=h+"px "+fontData.name;var surf=SDL.makeSurface(w,h,0,false,"text:"+text);var surfData=SDL.surfaces[surf];surfData.ctx.save();surfData.ctx.fillStyle=color;surfData.ctx.font=fontString;surfData.ctx.textBaseline="top";surfData.ctx.fillText(text,0,0);surfData.ctx.restore();return surf}function _Mix_HaltMusic(){var audio=SDL.music.audio;if(audio){audio.src=audio.src;audio.currentPosition=0;audio.pause()}SDL.music.audio=null;if(SDL.hookMusicFinished){Runtime.dynCall("v",SDL.hookMusicFinished)}return 0}function _Mix_PlayMusic(id,loops){if(SDL.music.audio){if(!SDL.music.audio.paused)Module.printErr("Music is already playing. "+SDL.music.source);SDL.music.audio.pause()}var info=SDL.audios[id];var audio;if(info.webAudio){audio={};audio.resource=info;audio.paused=false;audio.currentPosition=0;audio.play=(function(){SDL.playWebAudio(this)});audio.pause=(function(){SDL.pauseWebAudio(this)})}else if(info.audio){audio=info.audio}audio["onended"]=(function(){if(SDL.music.audio==this)_Mix_HaltMusic()});audio.loop=loops!=0;audio.volume=SDL.music.volume;SDL.music.audio=audio;audio.play();return 0}function _Mix_FreeChunk(id){SDL.audios[id]=null}function _Mix_LoadWAV_RW(rwopsID,freesrc){var rwops=SDL.rwops[rwopsID];if(rwops===undefined)return 0;var filename="";var audio;var webAudio;var bytes;if(rwops.filename!==undefined){filename=PATH.resolve(rwops.filename);var raw=Module["preloadedAudios"][filename];if(!raw){if(raw===null)Module.printErr("Trying to reuse preloaded audio, but freePreloadedMediaOnUse is set!");if(!Module.noAudioDecoding)Runtime.warnOnce("Cannot find preloaded audio "+filename);try{bytes=FS.readFile(filename)}catch(e){Module.printErr("Couldn't find file for: "+filename);return 0}}if(Module["freePreloadedMediaOnUse"]){Module["preloadedAudios"][filename]=null}audio=raw}else if(rwops.bytes!==undefined){if(SDL.webAudioAvailable())bytes=HEAPU8.buffer.slice(rwops.bytes,rwops.bytes+rwops.count);else bytes=HEAPU8.subarray(rwops.bytes,rwops.bytes+rwops.count)}else{return 0}var arrayBuffer=bytes?bytes.buffer||bytes:bytes;var canPlayWithWebAudio=Module["SDL_canPlayWithWebAudio"]===undefined||Module["SDL_canPlayWithWebAudio"](filename,arrayBuffer);if(bytes!==undefined&&SDL.webAudioAvailable()&&canPlayWithWebAudio){audio=undefined;webAudio={};webAudio.onDecodeComplete=[];function onDecodeComplete(data){webAudio.decodedBuffer=data;webAudio.onDecodeComplete.forEach((function(e){e()}));webAudio.onDecodeComplete=undefined}SDL.audioContext["decodeAudioData"](arrayBuffer,onDecodeComplete)}else if(audio===undefined&&bytes){var blob=new Blob([bytes],{type:rwops.mimetype});var url=URL.createObjectURL(blob);audio=new Audio;audio.src=url;audio.mozAudioChannelType="content"}var id=SDL.audios.length;SDL.audios.push({source:filename,audio:audio,webAudio:webAudio});return id}function _Mix_PlayChannel(channel,id,loops){var info=SDL.audios[id];if(!info)return-1;if(!info.audio&&!info.webAudio)return-1;if(channel==-1){for(var i=SDL.channelMinimumNumber;i0&&SDL.rwops[SDL.rwops.length-1]===null){SDL.rwops.pop()}}function _IMG_Load_RW(rwopsID,freeSrc){try{function cleanup(){if(rwops&&freeSrc)_SDL_FreeRW(rwopsID)}function addCleanup(func){var old=cleanup;cleanup=function added_cleanup(){old();func()}}function callStbImage(func,params){var x=Module["_malloc"](4);var y=Module["_malloc"](4);var comp=Module["_malloc"](4);addCleanup((function(){Module["_free"](x);Module["_free"](y);Module["_free"](comp);if(data)Module["_stbi_image_free"](data)}));var data=Module["_"+func].apply(null,params.concat([x,y,comp,0]));if(!data)return null;return{rawData:true,data:data,width:HEAP32[x>>2],height:HEAP32[y>>2],size:HEAP32[x>>2]*HEAP32[y>>2]*HEAP32[comp>>2],bpp:HEAP32[comp>>2]}}var rwops=SDL.rwops[rwopsID];if(rwops===undefined){return 0}var filename=rwops.filename;if(filename===undefined){Runtime.warnOnce("Only file names that have been preloaded are supported for IMG_Load_RW. Consider using STB_IMAGE=1 if you want synchronous image decoding (see settings.js)");return 0}if(!raw){filename=PATH.resolve(filename);var raw=Module["preloadedImages"][filename];if(!raw){if(raw===null)Module.printErr("Trying to reuse preloaded image, but freePreloadedMediaOnUse is set!");Runtime.warnOnce("Cannot find preloaded image "+filename);Runtime.warnOnce("Cannot find preloaded image "+filename+". Consider using STB_IMAGE=1 if you want synchronous image decoding (see settings.js)");return 0}else if(Module["freePreloadedMediaOnUse"]){Module["preloadedImages"][filename]=null}}var surf=SDL.makeSurface(raw.width,raw.height,0,false,"load:"+filename);var surfData=SDL.surfaces[surf];surfData.ctx.globalCompositeOperation="copy";if(!raw.rawData){surfData.ctx.drawImage(raw,0,0,raw.width,raw.height,0,0,raw.width,raw.height)}else{var imageData=surfData.ctx.getImageData(0,0,surfData.width,surfData.height);if(raw.bpp==4){imageData.data.set(HEAPU8.subarray(raw.data,raw.data+raw.size))}else if(raw.bpp==3){var pixels=raw.size/3;var data=imageData.data;var sourcePtr=raw.data;var destPtr=0;for(var i=0;i>0];data[destPtr++]=HEAPU8[sourcePtr++>>0];data[destPtr++]=HEAPU8[sourcePtr++>>0];data[destPtr++]=255}}else if(raw.bpp==1){var pixels=raw.size;var data=imageData.data;var sourcePtr=raw.data;var destPtr=0;for(var i=0;i>0];data[destPtr++]=value;data[destPtr++]=value;data[destPtr++]=value;data[destPtr++]=255}}else{Module.printErr("cannot handle bpp "+raw.bpp);return 0}surfData.ctx.putImageData(imageData,0,0)}surfData.ctx.globalCompositeOperation="source-over";_SDL_LockSurface(surf);surfData.locked--;if(SDL.GL){surfData.canvas=surfData.ctx=null}return surf}finally{cleanup()}}function _SDL_RWFromFile(_name,mode){var id=SDL.rwops.length;var name=Pointer_stringify(_name);SDL.rwops.push({filename:name,mimetype:Browser.getMimetype(name)});return id}function _IMG_Load(filename){var rwops=_SDL_RWFromFile(filename);var result=_IMG_Load_RW(rwops,1);return result}function _SDL_LockSurface(surf){var surfData=SDL.surfaces[surf];surfData.locked++;if(surfData.locked>1)return 0;if(!surfData.buffer){surfData.buffer=_malloc(surfData.width*surfData.height*4);HEAP32[surf+20>>2]=surfData.buffer}HEAP32[surf+20>>2]=surfData.buffer;if(surf==SDL.screen&&Module.screenIsReadOnly&&surfData.image)return 0;surfData.image=surfData.ctx.getImageData(0,0,surfData.width,surfData.height);if(surf==SDL.screen){var data=surfData.image.data;var num=data.length;for(var i=0;i>2],y:HEAP32[rect+4>>2],w:HEAP32[rect+8>>2],h:HEAP32[rect+12>>2]}}),loadColorToCSSRGB:(function(color){var rgba=HEAP32[color>>2];return"rgb("+(rgba&255)+","+(rgba>>8&255)+","+(rgba>>16&255)+")"}),loadColorToCSSRGBA:(function(color){var rgba=HEAP32[color>>2];return"rgba("+(rgba&255)+","+(rgba>>8&255)+","+(rgba>>16&255)+","+(rgba>>24&255)/255+")"}),translateColorToCSSRGBA:(function(rgba){return"rgba("+(rgba&255)+","+(rgba>>8&255)+","+(rgba>>16&255)+","+(rgba>>>24)/255+")"}),translateRGBAToCSSRGBA:(function(r,g,b,a){return"rgba("+(r&255)+","+(g&255)+","+(b&255)+","+(a&255)/255+")"}),translateRGBAToColor:(function(r,g,b,a){return r|g<<8|b<<16|a<<24}),makeSurface:(function(width,height,flags,usePageCanvas,source,rmask,gmask,bmask,amask){flags=flags||0;var is_SDL_HWSURFACE=flags&1;var is_SDL_HWPALETTE=flags&2097152;var is_SDL_OPENGL=flags&67108864;var surf=_malloc(60);var pixelFormat=_malloc(44);var bpp=is_SDL_HWPALETTE?1:4;var buffer=0;if(!is_SDL_HWSURFACE&&!is_SDL_OPENGL){buffer=_malloc(width*height*4)}HEAP32[surf>>2]=flags;HEAP32[surf+4>>2]=pixelFormat;HEAP32[surf+8>>2]=width;HEAP32[surf+12>>2]=height;HEAP32[surf+16>>2]=width*bpp;HEAP32[surf+20>>2]=buffer;HEAP32[surf+36>>2]=0;HEAP32[surf+40>>2]=0;HEAP32[surf+44>>2]=Module["canvas"].width;HEAP32[surf+48>>2]=Module["canvas"].height;HEAP32[surf+56>>2]=1;HEAP32[pixelFormat>>2]=0;HEAP32[pixelFormat+4>>2]=0;HEAP8[pixelFormat+8>>0]=bpp*8;HEAP8[pixelFormat+9>>0]=bpp;HEAP32[pixelFormat+12>>2]=rmask||255;HEAP32[pixelFormat+16>>2]=gmask||65280;HEAP32[pixelFormat+20>>2]=bmask||16711680;HEAP32[pixelFormat+24>>2]=amask||4278190080;SDL.GL=SDL.GL||is_SDL_OPENGL;var canvas;if(!usePageCanvas){if(SDL.canvasPool.length>0){canvas=SDL.canvasPool.pop()}else{canvas=document.createElement("canvas")}canvas.width=width;canvas.height=height}else{canvas=Module["canvas"]}var webGLContextAttributes={antialias:SDL.glAttributes[13]!=0&&SDL.glAttributes[14]>1,depth:SDL.glAttributes[6]>0,stencil:SDL.glAttributes[7]>0};var ctx=Browser.createContext(canvas,is_SDL_OPENGL,usePageCanvas,webGLContextAttributes);SDL.surfaces[surf]={width:width,height:height,canvas:canvas,ctx:ctx,surf:surf,buffer:buffer,pixelFormat:pixelFormat,alpha:255,flags:flags,locked:0,usePageCanvas:usePageCanvas,source:source,isFlagSet:(function(flag){return flags&flag})};return surf}),copyIndexedColorData:(function(surfData,rX,rY,rW,rH){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>0]*3;var colorOffset=colorBase+x*4;data[colorOffset]=colors[index];data[colorOffset+1]=colors[index+1];data[colorOffset+2]=colors[index+2]}}}),freeSurface:(function(surf){var refcountPointer=surf+56;var refcount=HEAP32[refcountPointer>>2];if(refcount>1){HEAP32[refcountPointer>>2]=refcount-1;return}var info=SDL.surfaces[surf];if(!info.usePageCanvas&&info.canvas)SDL.canvasPool.push(info.canvas);if(info.buffer)_free(info.buffer);_free(info.pixelFormat);_free(surf);SDL.surfaces[surf]=null;if(surf===SDL.screen){SDL.screen=null}}),downFingers:{},savedKeydown:null,receiveEvent:(function(event){function unpressAllPressedKeys(){for(var code in SDL.keyboardMap){SDL.events.push({type:"keyup",keyCode:SDL.keyboardMap[code]})}}switch(event.type){case"touchstart":case"touchmove":{event.preventDefault();var touches=[];if(event.type==="touchstart"){for(var i=0;i0?4:3;var event1={type:"mousedown",button:button,pageX:event.pageX,pageY:event.pageY};SDL.events.push(event1);var event2={type:"mouseup",button:button,pageX:event.pageX,pageY:event.pageY};SDL.events.push(event2);if(event.type=="DOMMouseScroll"){SDL.events.push({type:"wheel",deltaX:0,deltaY:-event.detail});break}else if(event.type=="mousewheel"){SDL.events.push({type:"wheel",deltaX:0,deltaY:event.wheelDelta});break}}else if(event.type=="mousedown"){SDL.DOMButtons[event.button]=1;SDL.events.push({type:"touchstart",touch:{identifier:0,deviceID:-1,pageX:event.pageX,pageY:event.pageY}})}else if(event.type=="mouseup"){if(!SDL.DOMButtons[event.button]){return}SDL.events.push({type:"touchend",touch:{identifier:0,deviceID:-1,pageX:event.pageX,pageY:event.pageY}});SDL.DOMButtons[event.button]=0}if(event.type==="keydown"||event.type==="mousedown"){SDL.canRequestFullscreen=true}else if(event.type==="keyup"||event.type==="mouseup"){if(SDL.isRequestingFullscreen){Module["requestFullScreen"](true,true);SDL.isRequestingFullscreen=false}SDL.canRequestFullscreen=false}if(event.type==="keypress"&&SDL.savedKeydown){SDL.savedKeydown.keypressCharCode=event.charCode;SDL.savedKeydown=null}else if(event.type==="keydown"){SDL.savedKeydown=event}if(event.type!=="keypress"||SDL.textInput){SDL.events.push(event)}break;case"mouseout":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}}event.preventDefault();break;case"focus":SDL.events.push(event);event.preventDefault();break;case"blur":SDL.events.push(event);unpressAllPressedKeys();event.preventDefault();break;case"visibilitychange":SDL.events.push({type:"visibilitychange",visible:!document.hidden});unpressAllPressedKeys();event.preventDefault();break;case"unload":if(Browser.mainLoop.runner){SDL.events.push(event);Browser.mainLoop.runner()}return;case"resize":SDL.events.push(event);if(event.preventDefault){event.preventDefault()}break}if(SDL.events.length>=1e4){Module.printErr("SDL event queue full, dropping events");SDL.events=SDL.events.slice(0,1e4)}SDL.flushEventsToHandler();return}),handleEvent:(function(event){if(event.handled)return;event.handled=true;switch(event.type){case"touchstart":case"touchend":case"touchmove":{Browser.calculateMouseEvent(event);break};case"keydown":case"keyup":{var down=event.type==="keydown";var code=event.keyCode;if(code>=65&&code<=90){code+=32}else{code=SDL.keyCodes[event.keyCode]||event.keyCode}HEAP8[SDL.keyboardState+code>>0]=down;SDL.modState=(HEAP8[SDL.keyboardState+1248>>0]?64|128:0)|(HEAP8[SDL.keyboardState+1249>>0]?1|2:0)|(HEAP8[SDL.keyboardState+1250>>0]?256|512:0);if(down){SDL.keyboardMap[code]=event.keyCode}else{delete SDL.keyboardMap[code]}break};case"mousedown":case"mouseup":if(event.type=="mousedown"){SDL.buttonState|=1<0){if(SDL.makeCEvent(SDL.events.shift(),ptr)!==false)return 1}return 0}else{return SDL.events.length>0}}),makeCEvent:(function(event,ptr){if(typeof event==="number"){_memcpy(ptr,event,28);return}SDL.handleEvent(event);switch(event.type){case"keydown":case"keyup":{var down=event.type==="keydown";var key=event.keyCode;if(key>=65&&key<=90){key+=32}else{key=SDL.keyCodes[event.keyCode]||event.keyCode}var scan;if(key>=1024){scan=key-1024}else{scan=SDL.scanCodes[key]||key}HEAP32[ptr>>2]=SDL.DOMEventToSDLEvent[event.type];HEAP8[ptr+8>>0]=down?1:0;HEAP8[ptr+9>>0]=0;HEAP32[ptr+12>>2]=scan;HEAP32[ptr+16>>2]=key;HEAP16[ptr+20>>1]=SDL.modState;HEAP32[ptr+24>>2]=event.keypressCharCode||key;break};case"keypress":{HEAP32[ptr>>2]=SDL.DOMEventToSDLEvent[event.type];var cStr=intArrayFromString(String.fromCharCode(event.charCode));for(var i=0;i>0]=cStr[i]}break};case"mousedown":case"mouseup":case"mousemove":{if(event.type!="mousemove"){var down=event.type==="mousedown";HEAP32[ptr>>2]=SDL.DOMEventToSDLEvent[event.type];HEAP32[ptr+4>>2]=0;HEAP32[ptr+8>>2]=0;HEAP32[ptr+12>>2]=0;HEAP8[ptr+16>>0]=event.button+1;HEAP8[ptr+17>>0]=down?1:0;HEAP32[ptr+20>>2]=Browser.mouseX;HEAP32[ptr+24>>2]=Browser.mouseY}else{HEAP32[ptr>>2]=SDL.DOMEventToSDLEvent[event.type];HEAP32[ptr+4>>2]=0;HEAP32[ptr+8>>2]=0;HEAP32[ptr+12>>2]=0;HEAP32[ptr+16>>2]=SDL.buttonState;HEAP32[ptr+20>>2]=Browser.mouseX;HEAP32[ptr+24>>2]=Browser.mouseY;HEAP32[ptr+28>>2]=Browser.mouseMovementX;HEAP32[ptr+32>>2]=Browser.mouseMovementY}break};case"wheel":{HEAP32[ptr>>2]=SDL.DOMEventToSDLEvent[event.type];HEAP32[ptr+16>>2]=event.deltaX;HEAP32[ptr+20>>2]=event.deltaY;break};case"touchstart":case"touchend":case"touchmove":{var touch=event.touch;if(!Browser.touches[touch.identifier])break;var w=Module["canvas"].width;var h=Module["canvas"].height;var x=Browser.touches[touch.identifier].x/w;var y=Browser.touches[touch.identifier].y/h;var lx=Browser.lastTouches[touch.identifier].x/w;var ly=Browser.lastTouches[touch.identifier].y/h;var dx=x-lx;var dy=y-ly;if(touch["deviceID"]===undefined)touch.deviceID=SDL.TOUCH_DEFAULT_ID;if(dx===0&&dy===0&&event.type==="touchmove")return false;HEAP32[ptr>>2]=SDL.DOMEventToSDLEvent[event.type];HEAP32[ptr+4>>2]=_SDL_GetTicks();tempI64=[touch.deviceID>>>0,(tempDouble=touch.deviceID,+Math_abs(tempDouble)>=+1?tempDouble>+0?(Math_min(+Math_floor(tempDouble/+4294967296),+4294967295)|0)>>>0:~~+Math_ceil((tempDouble- +(~~tempDouble>>>0))/+4294967296)>>>0:0)],HEAP32[ptr+8>>2]=tempI64[0],HEAP32[ptr+12>>2]=tempI64[1];tempI64=[touch.identifier>>>0,(tempDouble=touch.identifier,+Math_abs(tempDouble)>=+1?tempDouble>+0?(Math_min(+Math_floor(tempDouble/+4294967296),+4294967295)|0)>>>0:~~+Math_ceil((tempDouble- +(~~tempDouble>>>0))/+4294967296)>>>0:0)],HEAP32[ptr+16>>2]=tempI64[0],HEAP32[ptr+20>>2]=tempI64[1];HEAPF32[ptr+24>>2]=x;HEAPF32[ptr+28>>2]=y;HEAPF32[ptr+32>>2]=dx;HEAPF32[ptr+36>>2]=dy;if(touch.force!==undefined){HEAPF32[ptr+40>>2]=touch.force}else{HEAPF32[ptr+40>>2]=event.type=="touchend"?0:1}break};case"unload":{HEAP32[ptr>>2]=SDL.DOMEventToSDLEvent[event.type];break};case"resize":{HEAP32[ptr>>2]=SDL.DOMEventToSDLEvent[event.type];HEAP32[ptr+4>>2]=event.w;HEAP32[ptr+8>>2]=event.h;break};case"joystick_button_up":case"joystick_button_down":{var state=event.type==="joystick_button_up"?0:1;HEAP32[ptr>>2]=SDL.DOMEventToSDLEvent[event.type];HEAP8[ptr+4>>0]=event.index;HEAP8[ptr+5>>0]=event.button;HEAP8[ptr+6>>0]=state;break};case"joystick_axis_motion":{HEAP32[ptr>>2]=SDL.DOMEventToSDLEvent[event.type];HEAP8[ptr+4>>0]=event.index;HEAP8[ptr+5>>0]=event.axis;HEAP32[ptr+8>>2]=SDL.joystickAxisValueConversion(event.value);break};case"focus":{var SDL_WINDOWEVENT_FOCUS_GAINED=12;HEAP32[ptr>>2]=SDL.DOMEventToSDLEvent[event.type];HEAP32[ptr+4>>2]=0;HEAP8[ptr+8>>0]=SDL_WINDOWEVENT_FOCUS_GAINED;break};case"blur":{var SDL_WINDOWEVENT_FOCUS_LOST=13;HEAP32[ptr>>2]=SDL.DOMEventToSDLEvent[event.type];HEAP32[ptr+4>>2]=0;HEAP8[ptr+8>>0]=SDL_WINDOWEVENT_FOCUS_LOST;break};case"visibilitychange":{var SDL_WINDOWEVENT_SHOWN=1;var SDL_WINDOWEVENT_HIDDEN=2;var visibilityEventID=event.visible?SDL_WINDOWEVENT_SHOWN:SDL_WINDOWEVENT_HIDDEN;HEAP32[ptr>>2]=SDL.DOMEventToSDLEvent[event.type];HEAP32[ptr+4>>2]=0;HEAP8[ptr+8>>0]=visibilityEventID;break};default:throw"Unhandled SDL event: "+event.type}}),estimateTextWidth:(function(fontData,text){var h=fontData.size;var fontString=h+"px "+fontData.name;var tempCtx=SDL.ttfContext;tempCtx.save();tempCtx.font=fontString;var ret=tempCtx.measureText(text).width|0;tempCtx.restore();return ret}),allocateChannels:(function(num){if(SDL.numChannels&&SDL.numChannels>=num&&num!=0)return;SDL.numChannels=num;SDL.channels=[];for(var i=0;i>1]/32768}}else if(SDL.audio.format==8){for(var j=0;j>0];channelData[j]=(v>=0?v-128:v+128)/128}}}}),debugSurface:(function(surfData){console.log("dumping surface "+[surfData.surf,surfData.source,surfData.width,surfData.height]);var image=surfData.ctx.getImageData(0,0,surfData.width,surfData.height);var data=image.data;var num=Math.min(surfData.width,surfData.height);for(var i=0;i0}}),queryJoysticks:(function(){for(var joystick in SDL.lastJoystickState){var state=SDL.getGamepad(joystick-1);var prevState=SDL.lastJoystickState[joystick];if(typeof state.timestamp!=="number"||state.timestamp!==prevState.timestamp){var i;for(i=0;ideviceIndex&&deviceIndex>=0){return gamepads[deviceIndex]}return null})};function _SDL_SetVideoMode(width,height,depth,flags){["touchstart","touchend","touchmove","mousedown","mouseup","mousemove","DOMMouseScroll","mousewheel","wheel","mouseout"].forEach((function(event){Module["canvas"].addEventListener(event,SDL.receiveEvent,true)}));var canvas=Module["canvas"];if(width==0&&height==0){width=canvas.width;height=canvas.height}if(!SDL.addedResizeListener){SDL.addedResizeListener=true;Browser.resizeListeners.push((function(w,h){if(!SDL.settingVideoMode){SDL.receiveEvent({type:"resize",w:w,h:h})}}))}if(width!==canvas.width||height!==canvas.height){SDL.settingVideoMode=true;Browser.setCanvasSize(width,height);SDL.settingVideoMode=false}if(SDL.screen){SDL.freeSurface(SDL.screen);assert(!SDL.screen)}if(SDL.GL)flags=flags|67108864;SDL.screen=SDL.makeSurface(width,height,flags,true,"screen");return SDL.screen}function _open(path,oflag,varargs){var mode=HEAP32[varargs>>2];path=Pointer_stringify(path);try{var stream=FS.open(path,oflag,mode);return stream.fd}catch(e){FS.handleFSError(e);return-1}}function _fopen(filename,mode){var flags;mode=Pointer_stringify(mode);if(mode[0]=="r"){if(mode.indexOf("+")!=-1){flags=2}else{flags=0}}else if(mode[0]=="w"){if(mode.indexOf("+")!=-1){flags=2}else{flags=1}flags|=64;flags|=512}else if(mode[0]=="a"){if(mode.indexOf("+")!=-1){flags=2}else{flags=1}flags|=64;flags|=1024}else{___setErrNo(ERRNO_CODES.EINVAL);return 0}var fd=_open(filename,flags,allocate([511,0,0,0],"i32",ALLOC_STACK));return fd===-1?0:FS.getPtrForStream(FS.getStream(fd))}function _sqrtf(){return Math_sqrt.apply(null,arguments)}function _glGetString(name_){if(GL.stringCache[name_])return GL.stringCache[name_];var ret;switch(name_){case 7936:case 7937:case 7938:ret=allocate(intArrayFromString(GLctx.getParameter(name_)),"i8",ALLOC_NORMAL);break;case 7939:var exts=GLctx.getSupportedExtensions();var gl_exts=[];for(i in exts){gl_exts.push(exts[i]);gl_exts.push("GL_"+exts[i])}ret=allocate(intArrayFromString(gl_exts.join(" ")),"i8",ALLOC_NORMAL);break;case 35724:ret=allocate(intArrayFromString("OpenGL ES GLSL 1.00 (WebGL)"),"i8",ALLOC_NORMAL);break;default:GL.recordError(1280);return 0}GL.stringCache[name_]=ret;return ret}function _send(fd,buf,len,flags){var sock=SOCKFS.getSocket(fd);if(!sock){___setErrNo(ERRNO_CODES.EBADF);return-1}return _write(fd,buf,len)}function _pwrite(fildes,buf,nbyte,offset){var stream=FS.getStream(fildes);if(!stream){___setErrNo(ERRNO_CODES.EBADF);return-1}try{var slab=HEAP8;return FS.write(stream,slab,buf,nbyte,offset)}catch(e){FS.handleFSError(e);return-1}}function _write(fildes,buf,nbyte){var stream=FS.getStream(fildes);if(!stream){___setErrNo(ERRNO_CODES.EBADF);return-1}try{var slab=HEAP8;return FS.write(stream,slab,buf,nbyte)}catch(e){FS.handleFSError(e);return-1}}Module["_strlen"]=_strlen;function _fputs(s,stream){var fd=_fileno(stream);return _write(fd,s,_strlen(s))}function _fputc(c,stream){var chr=unSign(c&255);HEAP8[_fputc.ret>>0]=chr;var fd=_fileno(stream);var ret=_write(fd,_fputc.ret,1);if(ret==-1){var streamObj=FS.getStreamFromPtr(stream);if(streamObj)streamObj.error=true;return-1}else{return chr}}function _puts(s){var stdout=HEAP32[_stdout>>2];var ret=_fputs(s,stdout);if(ret<0){return ret}else{var newlineRet=_fputc(10,stdout);return newlineRet<0?-1:ret+1}}function _fwrite(ptr,size,nitems,stream){var bytesToWrite=nitems*size;if(bytesToWrite==0)return 0;var fd=_fileno(stream);var bytesWritten=_write(fd,ptr,bytesToWrite);if(bytesWritten==-1){var streamObj=FS.getStreamFromPtr(stream);if(streamObj)streamObj.error=true;return 0}else{return Math.floor(bytesWritten/size)}}function _mknod(path,mode,dev){path=Pointer_stringify(path);switch(mode&61440){case 32768:case 8192:case 24576:case 4096:case 49152:break;default:___setErrNo(ERRNO_CODES.EINVAL);return-1}try{FS.mknod(path,mode,dev);return 0}catch(e){FS.handleFSError(e);return-1}}function _mkdir(path,mode){path=Pointer_stringify(path);if(path[path.length-1]==="/")path=path.substr(0,path.length-1);try{FS.mkdir(path,mode,0);return 0}catch(e){FS.handleFSError(e);return-1}}function _ftell(stream){stream=FS.getStreamFromPtr(stream);if(!stream){___setErrNo(ERRNO_CODES.EBADF);return-1}if(FS.isChrdev(stream.node.mode)){___setErrNo(ERRNO_CODES.ESPIPE);return-1}else{return stream.position}}function _glEnableVertexAttribArray(index){var cb=GL.clientBuffers[index];cb.enabled=true;GLctx.enableVertexAttribArray(index)}function _glBindBuffer(target,buffer){var bufferObj=buffer?GL.buffers[buffer]:null;if(target==GLctx.ARRAY_BUFFER){GL.currArrayBuffer=buffer}else if(target==GLctx.ELEMENT_ARRAY_BUFFER){GL.currElementArrayBuffer=buffer}GLctx.bindBuffer(target,bufferObj)}function _SDL_InitSubSystem(flags){return 0}function _glCompileShader(shader){GLctx.compileShader(GL.shaders[shader])}Module["_bitshift64Lshr"]=_bitshift64Lshr;Module["_memset"]=_memset;function _glBufferData(target,size,data,usage){switch(usage){case 35041:case 35042:usage=35040;break;case 35045:case 35046:usage=35044;break;case 35049:case 35050:usage=35048;break}if(!data){GLctx.bufferData(target,size,usage)}else{GLctx.bufferData(target,HEAPU8.subarray(data,data+size),usage)}}var _BDtoIHigh=true;function _gettimeofday(ptr){var now=Date.now();HEAP32[ptr>>2]=Math.floor(now/1e3);HEAP32[ptr+4>>2]=Math.floor((now-1e3*Math.floor(now/1e3))*1e3);return 0}function _SDL_WM_SetCaption(title,icon){title=title&&Pointer_stringify(title);icon=icon&&Pointer_stringify(icon)}function _emscripten_memcpy_big(dest,src,num){HEAPU8.set(HEAPU8.subarray(src,src+num),dest);return dest}Module["_memcpy"]=_memcpy;function _sbrk(bytes){var self=_sbrk;if(!self.called){DYNAMICTOP=alignMemoryPage(DYNAMICTOP);self.called=true;assert(Runtime.dynamicAlloc);self.alloc=Runtime.dynamicAlloc;Runtime.dynamicAlloc=(function(){abort("cannot dynamically allocate, sbrk now has control")})}var ret=DYNAMICTOP;if(bytes!=0)self.alloc(bytes);return ret}Module["_bitshift64Shl"]=_bitshift64Shl;function _glGenTextures(n,textures){for(var i=0;i>2]=id}}function _SDL_GetError(){if(!SDL.errorMessage){SDL.errorMessage=allocate(intArrayFromString("unknown SDL-emscripten error"),"i8",ALLOC_NORMAL)}return SDL.errorMessage}function ___errno_location(){return ___errno_state}var _BItoD=true;function _SDL_OpenAudio(desired,obtained){try{SDL.audio={freq:HEAPU32[desired>>2],format:HEAPU16[desired+4>>1],channels:HEAPU8[desired+6>>0],samples:HEAPU16[desired+8>>1],callback:HEAPU32[desired+16>>2],userdata:HEAPU32[desired+20>>2],paused:true,timer:null};if(SDL.audio.format==8){SDL.audio.silence=128}else if(SDL.audio.format==32784){SDL.audio.silence=0}else{throw"Invalid SDL audio format "+SDL.audio.format+"!"}if(SDL.audio.freq<=0){throw"Unsupported sound frequency "+SDL.audio.freq+"!"}else if(SDL.audio.freq<=22050){SDL.audio.freq=22050}else if(SDL.audio.freq<=32e3){SDL.audio.freq=32e3}else if(SDL.audio.freq<=44100){SDL.audio.freq=44100}else if(SDL.audio.freq<=48e3){SDL.audio.freq=48e3}else if(SDL.audio.freq<=96e3){SDL.audio.freq=96e3}else{throw"Unsupported sound frequency "+SDL.audio.freq+"!"}if(SDL.audio.channels==0){SDL.audio.channels=1}else if(SDL.audio.channels<0||SDL.audio.channels>32){throw"Unsupported number of audio channels for SDL audio: "+SDL.audio.channels+"!"}else if(SDL.audio.channels!=1&&SDL.audio.channels!=2){console.log("Warning: Using untested number of audio channels "+SDL.audio.channels)}if(SDL.audio.samples<128||SDL.audio.samples>524288){throw"Unsupported audio callback buffer size "+SDL.audio.samples+"!"}else if((SDL.audio.samples&SDL.audio.samples-1)!=0){throw"Audio callback buffer size "+SDL.audio.samples+" must be a power-of-two!"}var totalSamples=SDL.audio.samples*SDL.audio.channels;SDL.audio.bytesPerSample=SDL.audio.format==8||SDL.audio.format==32776?1:2;SDL.audio.bufferSize=totalSamples*SDL.audio.bytesPerSample;SDL.audio.buffer=_malloc(SDL.audio.bufferSize);SDL.audio.numSimultaneouslyQueuedBuffers=Module["SDL_numSimultaneouslyQueuedBuffers"]||3;SDL.audio.caller=function SDL_audio_caller(){if(!SDL.audio){return}Runtime.dynCall("viii",SDL.audio.callback,[SDL.audio.userdata,SDL.audio.buffer,SDL.audio.bufferSize]);SDL.audio.pushAudio(SDL.audio.buffer,SDL.audio.bufferSize)};SDL.audio.audioOutput=new Audio;if(typeof SDL.audio.audioOutput["mozSetup"]==="function"){SDL.audio.audioOutput["mozSetup"](SDL.audio.channels,SDL.audio.freq);SDL.audio.mozBuffer=new Float32Array(totalSamples);SDL.audio.nextPlayTime=0;SDL.audio.pushAudio=function SDL_audio_pushAudio(ptr,size){--SDL.audio.numAudioTimersPending;var mozBuffer=SDL.audio.mozBuffer;if(SDL.audio.format==32784){for(var i=0;i>1]/32768}}else if(SDL.audio.format==8){for(var i=0;i>0];mozBuffer[i]=(v>=0?v-128:v+128)/128}}SDL.audio.audioOutput["mozWriteAudio"](mozBuffer);var curtime=Date.now()/1e3-SDL.audio.startTime;var playtime=Math.max(curtime,SDL.audio.nextPlayTime);var buffer_duration=SDL.audio.samples/SDL.audio.freq;SDL.audio.nextPlayTime=playtime+buffer_duration;SDL.audio.timer=Browser.safeSetTimeout(SDL.audio.caller,1e3*(playtime-curtime));++SDL.audio.numAudioTimersPending;if(SDL.audio.numAudioTimersPending>2]=SDL.audio.freq;HEAP16[obtained+4>>1]=SDL.audio.format;HEAP8[obtained+6>>0]=SDL.audio.channels;HEAP8[obtained+7>>0]=SDL.audio.silence;HEAP16[obtained+8>>1]=SDL.audio.samples;HEAP32[obtained+16>>2]=SDL.audio.callback;HEAP32[obtained+20>>2]=SDL.audio.userdata}SDL.allocateChannels(32)}catch(e){console.log('Initializing SDL audio threw an exception: "'+e.toString()+'"! Continuing without audio.');SDL.audio=null;SDL.allocateChannels(0);if(obtained){HEAP32[obtained>>2]=0;HEAP16[obtained+4>>1]=0;HEAP8[obtained+6>>0]=0;HEAP8[obtained+7>>0]=0;HEAP16[obtained+8>>1]=0;HEAP32[obtained+16>>2]=0;HEAP32[obtained+20>>2]=0}}if(!SDL.audio){return-1}return 0}function _fmod(x,y){return x%y}function _fmodl(){return _fmod.apply(null,arguments)}function _glCreateShader(shaderType){var id=GL.getNewId(GL.shaders);GL.shaders[id]=GLctx.createShader(shaderType);return id}function _glUniform1i(location,v0){location=GL.uniforms[location];GLctx.uniform1i(location,v0)}function _glTexImage2D(target,level,internalFormat,width,height,border,format,type,pixels){if(pixels){var data=GL.getTexPixelData(type,format,width,height,pixels,internalFormat);pixels=data.pixels;internalFormat=data.internalFormat}else{pixels=null}GLctx.texImage2D(target,level,internalFormat,width,height,border,format,type,pixels)}function _sysconf(name){switch(name){case 30:return PAGE_SIZE;case 132:case 133:case 12:case 137:case 138:case 15:case 235:case 16:case 17:case 18:case 19:case 20:case 149:case 13:case 10:case 236:case 153:case 9:case 21:case 22:case 159:case 154:case 14:case 77:case 78:case 139:case 80:case 81:case 79:case 82:case 68:case 67:case 164:case 11:case 29:case 47:case 48:case 95:case 52:case 51:case 46:return 200809;case 27:case 246:case 127:case 128:case 23:case 24:case 160:case 161:case 181:case 182:case 242:case 183:case 184:case 243:case 244:case 245:case 165:case 178:case 179:case 49:case 50:case 168:case 169:case 175:case 170:case 171:case 172:case 97:case 76:case 32:case 173:case 35:return-1;case 176:case 177:case 7:case 155:case 8:case 157:case 125:case 126:case 92:case 93:case 129:case 130:case 131:case 94:case 91:return 1;case 74:case 60:case 69:case 70:case 4:return 1024;case 31:case 42:case 72:return 32;case 87:case 26:case 33:return 2147483647;case 34:case 1:return 47839;case 38:case 36:return 99;case 43:case 37:return 2048;case 0:return 2097152;case 3:return 65536;case 28:return 32768;case 44:return 32767;case 75:return 16384;case 39:return 1e3;case 89:return 700;case 71:return 256;case 40:return 255;case 2:return 100;case 180:return 64;case 25:return 20;case 5:return 16;case 6:return 6;case 73:return 4;case 84:{if(typeof navigator==="object")return navigator["hardwareConcurrency"]||1;return 1}}___setErrNo(ERRNO_CODES.EINVAL);return-1}function _fgetc(stream){var streamObj=FS.getStreamFromPtr(stream);if(!streamObj)return-1;if(streamObj.eof||streamObj.error)return-1;var ret=_fread(_fgetc.ret,1,1,stream);if(ret==0){return-1}else if(ret==-1){streamObj.error=true;return-1}else{return HEAPU8[_fgetc.ret>>0]}}var _SItoF=true;function _srand(seed){HEAP32[___rand_seed>>2]=seed}var _BDtoILow=true;function _glGetProgramiv(program,pname,p){if(pname==35716){HEAP32[p>>2]=GLctx.getProgramInfoLog(GL.programs[program]).length+1}else if(pname==35719){var ptable=GL.programInfos[program];if(ptable){HEAP32[p>>2]=ptable.maxUniformLength;return}else if(program>2]=ptable.maxAttributeLength;return}else if(program>2]=GLctx.getProgramParameter(GL.programs[program],pname)}}function _glVertexAttribPointer(index,size,type,normalized,stride,ptr){var cb=GL.clientBuffers[index];if(!GL.currArrayBuffer){cb.size=size;cb.type=type;cb.normalized=normalized;cb.stride=stride;cb.ptr=ptr;cb.clientside=true;return}cb.clientside=false;GLctx.vertexAttribPointer(index,size,type,normalized,stride,ptr)}function _SDL_GetKeyboardState(numKeys){if(numKeys){HEAP32[numKeys>>2]=65536}return SDL.keyboardState}function _abort(){Module["abort"]()}function _glGetUniformLocation(program,name){name=Pointer_stringify(name);var arrayOffset=0;if(name.indexOf("]",name.length-1)!==-1){var ls=name.lastIndexOf("[");var arrayIndex=name.slice(ls+1,-1);if(arrayIndex.length>0){arrayOffset=parseInt(arrayIndex);if(arrayOffset<0){return-1}}name=name.slice(0,ls)}var ptable=GL.programInfos[program];if(!ptable){return-1}var utable=ptable.uniforms;var uniformInfo=utable[name];if(uniformInfo&&arrayOffset>2]=Browser.mouseX;if(y)HEAP32[y>>2]=Browser.mouseY;return SDL.buttonState}function _glEnable(x0){GLctx.enable(x0)}function _fabs(){return Math_abs.apply(null,arguments)}function _lseek(fildes,offset,whence){var stream=FS.getStream(fildes);if(!stream){___setErrNo(ERRNO_CODES.EBADF);return-1}try{return FS.llseek(stream,offset,whence)}catch(e){FS.handleFSError(e);return-1}}function _fseek(stream,offset,whence){var fd=_fileno(stream);var ret=_lseek(fd,offset,whence);if(ret==-1){return-1}stream=FS.getStreamFromPtr(stream);stream.eof=false;return 0}function _glDrawArrays(mode,first,count){GL.preDrawHandleClientVertexAttribBindings(first+count);GLctx.drawArrays(mode,first,count);GL.postDrawHandleClientVertexAttribBindings()}function _glGenBuffers(n,buffers){for(var i=0;i>2]=id}}function _glDeleteProgram(program){var program=GL.programs[program];GLctx.deleteProgram(program);program.name=0;GL.programs[program]=null;GL.programInfos[program]=null}function _glGetAttribLocation(program,name){program=GL.programs[program];name=Pointer_stringify(name);return GLctx.getAttribLocation(program,name)}function _rewind(stream){_fseek(stream,0,0);var streamObj=FS.getStreamFromPtr(stream);if(streamObj)streamObj.error=false}function _glAttachShader(program,shader){GLctx.attachShader(GL.programs[program],GL.shaders[shader])}function _glDeleteShader(shader){GLctx.deleteShader(GL.shaders[shader]);GL.shaders[shader]=null}function _glBlendFunc(x0,x1){GLctx.blendFunc(x0,x1)}function _glCreateProgram(){var id=GL.getNewId(GL.programs);var program=GLctx.createProgram();program.name=id;GL.programs[id]=program;return id}function _glPixelStorei(pname,param){if(pname==3333){GL.packAlignment=param}else if(pname==3317){GL.unpackAlignment=param}GLctx.pixelStorei(pname,param)}function _emscripten_set_main_loop(func,fps,simulateInfiniteLoop,arg){Module["noExitRuntime"]=true;assert(!Browser.mainLoop.scheduler,"there can only be one main loop function at once: call emscripten_cancel_main_loop to cancel the previous one, if you want to");Browser.mainLoop.runner=function Browser_mainLoop_runner(){if(ABORT)return;if(Browser.mainLoop.queue.length>0){var start=Date.now();var blocker=Browser.mainLoop.queue.shift();blocker.func(blocker.arg);if(Browser.mainLoop.remainingBlockers){var remaining=Browser.mainLoop.remainingBlockers;var next=remaining%1==0?remaining-1:Math.floor(remaining);if(blocker.counted){Browser.mainLoop.remainingBlockers=next}else{next=next+.5;Browser.mainLoop.remainingBlockers=(8*remaining+next)/9}}console.log('main loop blocker "'+blocker.name+'" took '+(Date.now()-start)+" ms");Browser.mainLoop.updateStatus();setTimeout(Browser.mainLoop.runner,0);return}if(Browser.mainLoop.shouldPause){Browser.mainLoop.paused=true;Browser.mainLoop.shouldPause=false;return}GL.newRenderingFrameStarted();if(Browser.mainLoop.method==="timeout"&&Module.ctx){Module.printErr("Looks like you are rendering without using requestAnimationFrame for the main loop. You should use 0 for the frame rate in emscripten_set_main_loop in order to use requestAnimationFrame, as that can greatly improve your frame rates!");Browser.mainLoop.method=""}Browser.mainLoop.runIter((function(){if(typeof arg!=="undefined"){Runtime.dynCall("vi",func,[arg])}else{Runtime.dynCall("v",func)}}));if(Browser.mainLoop.shouldPause){Browser.mainLoop.paused=true;Browser.mainLoop.shouldPause=false;return}Browser.mainLoop.scheduler()};if(fps&&fps>0){Browser.mainLoop.scheduler=function Browser_mainLoop_scheduler(){setTimeout(Browser.mainLoop.runner,1e3/fps)};Browser.mainLoop.method="timeout"}else{Browser.mainLoop.scheduler=function Browser_mainLoop_scheduler(){Browser.requestAnimationFrame(Browser.mainLoop.runner)};Browser.mainLoop.method="rAF"}Browser.mainLoop.scheduler();if(simulateInfiniteLoop){throw"SimulateInfiniteLoop"}}function _time(ptr){var ret=Math.floor(Date.now()/1e3);if(ptr){HEAP32[ptr>>2]=ret}return ret}function _stime(when){___setErrNo(ERRNO_CODES.EPERM);return-1}function _strerror_r(errnum,strerrbuf,buflen){if(errnum in ERRNO_MESSAGES){if(ERRNO_MESSAGES[errnum].length>buflen-1){return ___setErrNo(ERRNO_CODES.ERANGE)}else{var msg=ERRNO_MESSAGES[errnum];writeAsciiToMemory(msg,strerrbuf);return 0}}else{return ___setErrNo(ERRNO_CODES.EINVAL)}}function _strerror(errnum){if(!_strerror.buffer)_strerror.buffer=_malloc(256);_strerror_r(errnum,_strerror.buffer,256);return _strerror.buffer}function __reallyNegative(x){return x<0||x===0&&1/x===-Infinity}function __formatString(format,varargs){var textIndex=format;var argIndex=0;function getNextArg(type){var ret;if(type==="double"){ret=(HEAP32[tempDoublePtr>>2]=HEAP32[varargs+argIndex>>2],HEAP32[tempDoublePtr+4>>2]=HEAP32[varargs+(argIndex+4)>>2],+HEAPF64[tempDoublePtr>>3])}else if(type=="i64"){ret=[HEAP32[varargs+argIndex>>2],HEAP32[varargs+(argIndex+4)>>2]]}else{type="i32";ret=HEAP32[varargs+argIndex>>2]}argIndex+=Runtime.getNativeFieldSize(type);return ret}var ret=[];var curr,next,currArg;while(1){var startTextIndex=textIndex;curr=HEAP8[textIndex>>0];if(curr===0)break;next=HEAP8[textIndex+1>>0];if(curr==37){var flagAlwaysSigned=false;var flagLeftAlign=false;var flagAlternative=false;var flagZeroPad=false;var flagPadSign=false;flagsLoop:while(1){switch(next){case 43:flagAlwaysSigned=true;break;case 45:flagLeftAlign=true;break;case 35:flagAlternative=true;break;case 48:if(flagZeroPad){break flagsLoop}else{flagZeroPad=true;break};case 32:flagPadSign=true;break;default:break flagsLoop}textIndex++;next=HEAP8[textIndex+1>>0]}var width=0;if(next==42){width=getNextArg("i32");textIndex++;next=HEAP8[textIndex+1>>0]}else{while(next>=48&&next<=57){width=width*10+(next-48);textIndex++;next=HEAP8[textIndex+1>>0]}}var precisionSet=false,precision=-1;if(next==46){precision=0;precisionSet=true;textIndex++;next=HEAP8[textIndex+1>>0];if(next==42){precision=getNextArg("i32");textIndex++}else{while(1){var precisionChr=HEAP8[textIndex+1>>0];if(precisionChr<48||precisionChr>57)break;precision=precision*10+(precisionChr-48);textIndex++}}next=HEAP8[textIndex+1>>0]}if(precision<0){precision=6;precisionSet=false}var argSize;switch(String.fromCharCode(next)){case"h":var nextNext=HEAP8[textIndex+2>>0];if(nextNext==104){textIndex++;argSize=1}else{argSize=2}break;case"l":var nextNext=HEAP8[textIndex+2>>0];if(nextNext==108){textIndex++;argSize=8}else{argSize=4}break;case"L":case"q":case"j":argSize=8;break;case"z":case"t":case"I":argSize=4;break;default:argSize=null}if(argSize)textIndex++;next=HEAP8[textIndex+1>>0];switch(String.fromCharCode(next)){case"d":case"i":case"u":case"o":case"x":case"X":case"p":{var signed=next==100||next==105;argSize=argSize||4;var currArg=getNextArg("i"+argSize*8);var origArg=currArg;var argText;if(argSize==8){currArg=Runtime.makeBigInt(currArg[0],currArg[1],next==117)}if(argSize<=4){var limit=Math.pow(256,argSize)-1;currArg=(signed?reSign:unSign)(currArg&limit,argSize*8)}var currAbsArg=Math.abs(currArg);var prefix="";if(next==100||next==105){if(argSize==8&&i64Math)argText=i64Math.stringify(origArg[0],origArg[1],null);else argText=reSign(currArg,8*argSize,1).toString(10)}else if(next==117){if(argSize==8&&i64Math)argText=i64Math.stringify(origArg[0],origArg[1],true);else argText=unSign(currArg,8*argSize,1).toString(10);currArg=Math.abs(currArg)}else if(next==111){argText=(flagAlternative?"0":"")+currAbsArg.toString(8)}else if(next==120||next==88){prefix=flagAlternative&&currArg!=0?"0x":"";if(argSize==8&&i64Math){if(origArg[1]){argText=(origArg[1]>>>0).toString(16);var lower=(origArg[0]>>>0).toString(16);while(lower.length<8)lower="0"+lower;argText+=lower}else{argText=(origArg[0]>>>0).toString(16)}}else if(currArg<0){currArg=-currArg;argText=(currAbsArg-1).toString(16);var buffer=[];for(var i=0;i=0){if(flagAlwaysSigned){prefix="+"+prefix}else if(flagPadSign){prefix=" "+prefix}}if(argText.charAt(0)=="-"){prefix="-"+prefix;argText=argText.substr(1)}while(prefix.length+argText.lengthexponent&&exponent>=-4){next=(next==103?"f":"F").charCodeAt(0);precision-=exponent+1}else{next=(next==103?"e":"E").charCodeAt(0);precision--}effectivePrecision=Math.min(precision,20)}if(next==101||next==69){argText=currArg.toExponential(effectivePrecision);if(/[eE][-+]\d$/.test(argText)){argText=argText.slice(0,-1)+"0"+argText.slice(-1)}}else if(next==102||next==70){argText=currArg.toFixed(effectivePrecision);if(currArg===0&&__reallyNegative(currArg)){argText="-"+argText}}var parts=argText.split("e");if(isGeneral&&!flagAlternative){while(parts[0].length>1&&parts[0].indexOf(".")!=-1&&(parts[0].slice(-1)=="0"||parts[0].slice(-1)==".")){parts[0]=parts[0].slice(0,-1)}}else{if(flagAlternative&&argText.indexOf(".")==-1)parts[0]+=".";while(precision>effectivePrecision++)parts[0]+="0"}argText=parts[0]+(parts.length>1?"e"+parts[1]:"");if(next==69)argText=argText.toUpperCase();if(currArg>=0){if(flagAlwaysSigned){argText="+"+argText}else if(flagPadSign){argText=" "+argText}}}while(argText.length>0])}}else{ret=ret.concat(intArrayFromString("(null)".substr(0,argLength),true))}if(flagLeftAlign){while(argLength0){ret.push(32)}if(!flagLeftAlign)ret.push(getNextArg("i8"));break};case"n":{var ptr=getNextArg("i32*");HEAP32[ptr>>2]=ret.length;break};case"%":{ret.push(curr);break};default:{for(var i=startTextIndex;i>0])}}}textIndex+=2}else{ret.push(curr);textIndex+=1}}return ret}function _fprintf(stream,format,varargs){var result=__formatString(format,varargs);var stack=Runtime.stackSave();var ret=_fwrite(allocate(result,"i8",ALLOC_STACK),1,result.length,stream);Runtime.stackRestore(stack);return ret}function _printf(format,varargs){var stdout=HEAP32[_stdout>>2];return _fprintf(stdout,format,varargs)}function _glUniformMatrix4fv(location,count,transpose,value){location=GL.uniforms[location];var view;if(count===1){view=GL.miniTempBufferViews[15];for(var i=0;i<16;i++){view[i]=HEAPF32[value+i*4>>2]}}else{view=HEAPF32.subarray(value>>2,value+count*64>>2)}GLctx.uniformMatrix4fv(location,transpose,view)}function _SDL_GL_SwapBuffers(){if(Browser.doSwapBuffers)Browser.doSwapBuffers()}function _glBufferSubData(target,offset,size,data){GLctx.bufferSubData(target,offset,HEAPU8.subarray(data,data+size))}function _SDL_PollEvent(ptr){return SDL.pollEvent(ptr)}function _SDL_Init(initFlags){SDL.startTime=Date.now();SDL.initFlags=initFlags;if(!Module["doNotCaptureKeyboard"]){document.addEventListener("keydown",SDL.receiveEvent);document.addEventListener("keyup",SDL.receiveEvent);document.addEventListener("keypress",SDL.receiveEvent);window.addEventListener("focus",SDL.receiveEvent);window.addEventListener("blur",SDL.receiveEvent);document.addEventListener("visibilitychange",SDL.receiveEvent)}if(initFlags&512){addEventListener("gamepadconnected",(function(){}))}window.addEventListener("unload",SDL.receiveEvent);SDL.keyboardState=_malloc(65536);_memset(SDL.keyboardState,0,65536);SDL.DOMEventToSDLEvent["keydown"]=768;SDL.DOMEventToSDLEvent["keyup"]=769;SDL.DOMEventToSDLEvent["keypress"]=771;SDL.DOMEventToSDLEvent["mousedown"]=1025;SDL.DOMEventToSDLEvent["mouseup"]=1026;SDL.DOMEventToSDLEvent["mousemove"]=1024;SDL.DOMEventToSDLEvent["wheel"]=1027;SDL.DOMEventToSDLEvent["touchstart"]=1792;SDL.DOMEventToSDLEvent["touchend"]=1793;SDL.DOMEventToSDLEvent["touchmove"]=1794;SDL.DOMEventToSDLEvent["unload"]=256;SDL.DOMEventToSDLEvent["resize"]=28673;SDL.DOMEventToSDLEvent["visibilitychange"]=512;SDL.DOMEventToSDLEvent["focus"]=512;SDL.DOMEventToSDLEvent["blur"]=512;SDL.DOMEventToSDLEvent["joystick_axis_motion"]=1536;SDL.DOMEventToSDLEvent["joystick_button_down"]=1539;SDL.DOMEventToSDLEvent["joystick_button_up"]=1540;return 0}function _glTexParameteri(x0,x1,x2){GLctx.texParameteri(x0,x1,x2)}function _llvm_trap(){abort("trap!")}function _copysign(a,b){return __reallyNegative(a)===__reallyNegative(b)?a:-a}function _copysignl(){return _copysign.apply(null,arguments)}function _glGetShaderiv(shader,pname,p){if(pname==35716){var log=GLctx.getShaderInfoLog(GL.shaders[shader]);if(!log)log="(unknown error)";HEAP32[p>>2]=log.length+1}else{HEAP32[p>>2]=GLctx.getShaderParameter(GL.shaders[shader],pname)}}FS.staticInit();__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()})});Module["FS_createFolder"]=FS.createFolder;Module["FS_createPath"]=FS.createPath;Module["FS_createDataFile"]=FS.createDataFile;Module["FS_createPreloadedFile"]=FS.createPreloadedFile;Module["FS_createLazyFile"]=FS.createLazyFile;Module["FS_createLink"]=FS.createLink;Module["FS_createDevice"]=FS.createDevice;___errno_state=Runtime.staticAlloc(4);HEAP32[___errno_state>>2]=0;__ATINIT__.unshift({func:(function(){TTY.init()})});__ATEXIT__.push({func:(function(){TTY.shutdown()})});TTY.utf8=new Runtime.UTF8Processor;if(ENVIRONMENT_IS_NODE){var fs=require("fs");NODEFS.staticInit()}var GLctx;GL.init();__ATINIT__.push({func:(function(){SOCKFS.root=FS.mount(SOCKFS,{},null)})});Module["requestFullScreen"]=function Module_requestFullScreen(lockPointer,resizeCanvas){Browser.requestFullScreen(lockPointer,resizeCanvas)};Module["requestAnimationFrame"]=function Module_requestAnimationFrame(func){Browser.requestAnimationFrame(func)};Module["setCanvasSize"]=function Module_setCanvasSize(width,height,noUpdates){Browser.setCanvasSize(width,height,noUpdates)};Module["pauseMainLoop"]=function Module_pauseMainLoop(){Browser.mainLoop.pause()};Module["resumeMainLoop"]=function Module_resumeMainLoop(){Browser.mainLoop.resume()};Module["getUserMedia"]=function Module_getUserMedia(){Browser.getUserMedia()};___buildEnvironment(ENV);_fputc.ret=allocate([0],"i8",ALLOC_STATIC);_fgetc.ret=allocate([0],"i8",ALLOC_STATIC);STACK_BASE=STACKTOP=Runtime.alignMemory(STATICTOP);staticSealed=true;STACK_MAX=STACK_BASE+5242880;DYNAMIC_BASE=DYNAMICTOP=Runtime.alignMemory(STACK_MAX);assert(DYNAMIC_BASE>2]=b;Zd(h,11560,f);b=Pb(h|0,11584)|0;if((b|0)==0){m=0;i=e;return m|0}h=c[2456]|0;if((h|0)>0){n=h;h=0;while(1){o=c[(c[2452]|0)+(h<<2)>>2]|0;if((o|0)==0){p=n}else{q=c[o+156>>2]|0;if((q|0)==0){r=n}else{xc[q&7](o);r=c[2456]|0}c[o+212>>2]=c[2448];c[2448]=o;p=r}h=h+1|0;if((h|0)>=(p|0)){break}else{n=p}}}c[2456]=0;he(j|0,0,1024)|0;p=0;a:while(1){while(1){s=Jb(b|0)|0;if((s|0)==-1){t=11;break a}else if((s|0)==10){t=12;break a}else if((s|0)!=13){break}}a[j+p>>0]=s;n=p+1|0;if((n|0)<1024){p=n}else{break}}if((t|0)==11){a[j+p>>0]=0}else if((t|0)==12){a[j+p>>0]=0}c[f>>2]=k;c[f+4>>2]=l;Nd(j,11592,f);if((c[l>>2]|0)>0){f=0;do{he(j|0,0,1024)|0;p=0;b:while(1){while(1){u=Jb(b|0)|0;if((u|0)==-1){t=18;break b}else if((u|0)==10){t=19;break b}else if((u|0)!=13){break}}a[j+p>>0]=u;s=p+1|0;if((s|0)<1024){p=s}else{break}}if((t|0)==18){t=0;a[j+p>>0]=0}else if((t|0)==19){t=0;a[j+p>>0]=0}s=c[k>>2]|0;c:do{if((s|0)>0){v=+(f<<5|16|0);n=s;h=0;while(1){r=h<<1;d:do{if((h|0)>0){switch(a[j+(r+ -2)>>0]|0){case 108:case 68:case 84:case 114:case 62:case 60:case 86:case 65:case 70:case 69:case 83:case 66:case 109:case 35:case 46:{w=4;break d;break};default:{}}w=0}else{w=0}}while(0);if((h|0)<(n+ -1|0)){switch(a[j+(r+2)>>0]|0){case 108:case 68:case 84:case 114:case 62:case 60:case 86:case 65:case 70:case 69:case 83:case 66:case 109:case 35:case 46:{x=0;break};default:{x=1}}y=(x|w)^1}else{y=w}o=a[j+r>>0]|0;switch(o<<24>>24){case 108:case 68:case 84:case 114:case 62:case 60:case 86:case 65:case 70:case 69:case 83:case 66:case 109:case 35:case 46:{z=0;break};default:{z=1}}q=z?y:y|2;if((q|0)==6){A=bd(c[2854]|0)|0;B=+(h<<5|16|0);g[A+24>>2]=B;g[A+28>>2]=v;C=+g[A+76>>2];D=+g[A+68>>2];E=(C>D?C:D)*.5+10.0;C=+g[A+72>>2];F=(C>D?C:D)*.5+10.0;D=+g[A+52>>2];C=D+B;if(D>0.0){g[A+196>>2]=C+F;g[A+200>>2]=B-F}else{g[A+200>>2]=C-F;g[A+196>>2]=F+B}B=+g[A+56>>2];F=B+v;if(B>0.0){g[A+204>>2]=E+F;g[A+208>>2]=v-E}else{g[A+208>>2]=F-E;g[A+204>>2]=E+v}fd(A)}else if((q|0)==7){A=bd(c[2850]|0)|0;E=+(h<<5|16|0);g[A+24>>2]=E;g[A+28>>2]=v;F=+g[A+76>>2];B=+g[A+68>>2];C=(F>B?F:B)*.5+10.0;F=+g[A+72>>2];D=(F>B?F:B)*.5+10.0;B=+g[A+52>>2];F=B+E;if(B>0.0){g[A+196>>2]=F+D;g[A+200>>2]=E-D}else{g[A+200>>2]=F-D;g[A+196>>2]=D+E}E=+g[A+56>>2];D=E+v;if(E>0.0){g[A+204>>2]=C+D;g[A+208>>2]=v-C}else{g[A+208>>2]=D-C;g[A+204>>2]=C+v}fd(A)}else if((q|0)==3){A=bd(c[2852]|0)|0;C=+(h<<5|16|0);g[A+24>>2]=C;g[A+28>>2]=v;D=+g[A+76>>2];E=+g[A+68>>2];F=(D>E?D:E)*.5+10.0;D=+g[A+72>>2];B=(D>E?D:E)*.5+10.0;E=+g[A+52>>2];D=E+C;if(E>0.0){g[A+196>>2]=D+B;g[A+200>>2]=C-B}else{g[A+200>>2]=D-B;g[A+196>>2]=B+C}C=+g[A+56>>2];B=C+v;if(C>0.0){g[A+204>>2]=F+B;g[A+208>>2]=v-F}else{g[A+208>>2]=B-F;g[A+204>>2]=F+v}fd(A)}else if((q|0)==2){q=bd(c[2856]|0)|0;F=+(h<<5|16|0);g[q+24>>2]=F;g[q+28>>2]=v;B=+g[q+76>>2];C=+g[q+68>>2];D=(B>C?B:C)*.5+10.0;B=+g[q+72>>2];E=(B>C?B:C)*.5+10.0;C=+g[q+52>>2];B=C+F;if(C>0.0){g[q+196>>2]=B+E;g[q+200>>2]=F-E}else{g[q+200>>2]=B-E;g[q+196>>2]=E+F}F=+g[q+56>>2];E=F+v;if(F>0.0){g[q+204>>2]=D+E;g[q+208>>2]=v-D}else{g[q+208>>2]=E-D;g[q+204>>2]=D+v}fd(q)}do{switch(o<<24>>24){case 66:{q=bd(c[2840]|0)|0;D=+(h<<5|16|0);g[q+24>>2]=D;g[q+28>>2]=v;E=+g[q+76>>2];F=+g[q+68>>2];B=(E>F?E:F)*.5+10.0;E=+g[q+72>>2];C=(E>F?E:F)*.5+10.0;F=+g[q+52>>2];E=F+D;if(F>0.0){g[q+196>>2]=E+C;g[q+200>>2]=D-C}else{g[q+200>>2]=E-C;g[q+196>>2]=C+D}D=+g[q+56>>2];C=D+v;if(D>0.0){g[q+204>>2]=B+C;g[q+208>>2]=v-B}else{g[q+208>>2]=C-B;g[q+204>>2]=B+v}fd(q);break};case 109:{q=bd(c[2844]|0)|0;B=+(h<<5|16|0);g[q+24>>2]=B;g[q+28>>2]=v;C=+g[q+76>>2];D=+g[q+68>>2];E=(C>D?C:D)*.5+10.0;C=+g[q+72>>2];F=(C>D?C:D)*.5+10.0;D=+g[q+52>>2];C=D+B;if(D>0.0){g[q+196>>2]=C+F;g[q+200>>2]=B-F}else{g[q+200>>2]=C-F;g[q+196>>2]=F+B}B=+g[q+56>>2];F=B+v;if(B>0.0){g[q+204>>2]=E+F;g[q+208>>2]=v-E}else{g[q+208>>2]=F-E;g[q+204>>2]=E+v}fd(q);break};case 76:{q=bd(c[2860]|0)|0;E=+(h<<5|16|0);g[q+24>>2]=E;g[q+28>>2]=v;F=+g[q+76>>2];B=+g[q+68>>2];C=(F>B?F:B)*.5+10.0;F=+g[q+72>>2];D=(F>B?F:B)*.5+10.0;B=+g[q+52>>2];F=B+E;if(B>0.0){g[q+196>>2]=F+D;g[q+200>>2]=E-D}else{g[q+200>>2]=F-D;g[q+196>>2]=D+E}E=+g[q+56>>2];D=E+v;if(E>0.0){g[q+204>>2]=C+D;g[q+208>>2]=v-C}else{g[q+208>>2]=D-C;g[q+204>>2]=C+v}fd(q);break};case 108:{q=bd(c[2848]|0)|0;C=+(h<<5|16|0);g[q+24>>2]=C;g[q+28>>2]=v;D=+g[q+76>>2];E=+g[q+68>>2];F=(D>E?D:E)*.5+10.0;D=+g[q+72>>2];B=(D>E?D:E)*.5+10.0;E=+g[q+52>>2];D=E+C;if(E>0.0){g[q+196>>2]=D+B;g[q+200>>2]=C-B}else{g[q+200>>2]=D-B;g[q+196>>2]=B+C}C=+g[q+56>>2];B=C+v;if(C>0.0){g[q+204>>2]=F+B;g[q+208>>2]=v-F}else{g[q+208>>2]=B-F;g[q+204>>2]=F+v}fd(q);break};case 124:{q=bd(c[2858]|0)|0;F=+(h<<5|16|0);g[q+24>>2]=F;g[q+28>>2]=v;B=+g[q+76>>2];C=+g[q+68>>2];D=(B>C?B:C)*.5+10.0;B=+g[q+72>>2];E=(B>C?B:C)*.5+10.0;C=+g[q+52>>2];B=C+F;if(C>0.0){g[q+196>>2]=B+E;g[q+200>>2]=F-E}else{g[q+200>>2]=B-E;g[q+196>>2]=E+F}F=+g[q+56>>2];E=F+v;if(F>0.0){g[q+204>>2]=D+E;g[q+208>>2]=v-D}else{g[q+208>>2]=E-D;g[q+204>>2]=D+v}fd(q);break};case 83:{q=bd(c[2878]|0)|0;D=+(h<<5|16|0);g[q+24>>2]=D;g[q+28>>2]=v;E=+g[q+76>>2];F=+g[q+68>>2];B=(E>F?E:F)*.5+10.0;E=+g[q+72>>2];C=(E>F?E:F)*.5+10.0;F=+g[q+52>>2];E=F+D;if(F>0.0){g[q+196>>2]=E+C;g[q+200>>2]=D-C}else{g[q+200>>2]=E-C;g[q+196>>2]=C+D}D=+g[q+56>>2];C=D+v;if(D>0.0){g[q+204>>2]=B+C;g[q+208>>2]=v-B}else{g[q+208>>2]=C-B;g[q+204>>2]=B+v}fd(q);c[q+176>>2]=(a[j+(r|1)>>0]|0)+ -48;break};case 114:{q=bd(c[2846]|0)|0;B=+(h<<5|16|0);g[q+24>>2]=B;g[q+28>>2]=v;C=+g[q+76>>2];D=+g[q+68>>2];E=(C>D?C:D)*.5+10.0;C=+g[q+72>>2];F=(C>D?C:D)*.5+10.0;D=+g[q+52>>2];C=D+B;if(D>0.0){g[q+196>>2]=C+F;g[q+200>>2]=B-F}else{g[q+200>>2]=C-F;g[q+196>>2]=F+B}B=+g[q+56>>2];F=B+v;if(B>0.0){g[q+204>>2]=E+F;g[q+208>>2]=v-E}else{g[q+208>>2]=F-E;g[q+204>>2]=E+v}fd(q);break};case 86:{q=bd(c[2872]|0)|0;E=+(h<<5|16|0);g[q+24>>2]=E;g[q+28>>2]=v;F=+g[q+76>>2];B=+g[q+68>>2];C=(F>B?F:B)*.5+10.0;F=+g[q+72>>2];D=(F>B?F:B)*.5+10.0;B=+g[q+52>>2];F=B+E;if(B>0.0){g[q+196>>2]=F+D;g[q+200>>2]=E-D}else{g[q+200>>2]=F-D;g[q+196>>2]=D+E}E=+g[q+56>>2];D=E+v;if(E>0.0){g[q+204>>2]=C+D;g[q+208>>2]=v-C}else{g[q+208>>2]=D-C;g[q+204>>2]=C+v}fd(q);break};case 60:{q=bd(c[2874]|0)|0;C=+(h<<5|16|0);g[q+24>>2]=C;g[q+28>>2]=v;D=+g[q+76>>2];E=+g[q+68>>2];F=(D>E?D:E)*.5+10.0;D=+g[q+72>>2];B=(D>E?D:E)*.5+10.0;E=+g[q+52>>2];D=E+C;if(E>0.0){g[q+196>>2]=D+B;g[q+200>>2]=C-B}else{g[q+200>>2]=D-B;g[q+196>>2]=B+C}C=+g[q+56>>2];B=C+v;if(C>0.0){g[q+204>>2]=F+B;g[q+208>>2]=v-F}else{g[q+208>>2]=B-F;g[q+204>>2]=F+v}fd(q);break};case 70:{q=bd(c[2882]|0)|0;F=+(h<<5|16|0);g[q+24>>2]=F;g[q+28>>2]=v;B=+g[q+76>>2];C=+g[q+68>>2];D=(B>C?B:C)*.5+10.0;B=+g[q+72>>2];E=(B>C?B:C)*.5+10.0;C=+g[q+52>>2];B=C+F;if(C>0.0){g[q+196>>2]=B+E;g[q+200>>2]=F-E}else{g[q+200>>2]=B-E;g[q+196>>2]=E+F}F=+g[q+56>>2];E=F+v;if(F>0.0){g[q+204>>2]=D+E;g[q+208>>2]=v-D}else{g[q+208>>2]=E-D;g[q+204>>2]=D+v}fd(q);break};case 65:{q=bd(c[2870]|0)|0;D=+(h<<5|16|0);g[q+24>>2]=D;g[q+28>>2]=v;E=+g[q+76>>2];F=+g[q+68>>2];B=(E>F?E:F)*.5+10.0;E=+g[q+72>>2];C=(E>F?E:F)*.5+10.0;F=+g[q+52>>2];E=F+D;if(F>0.0){g[q+196>>2]=E+C;g[q+200>>2]=D-C}else{g[q+200>>2]=E-C;g[q+196>>2]=C+D}D=+g[q+56>>2];C=D+v;if(D>0.0){g[q+204>>2]=B+C;g[q+208>>2]=v-B}else{g[q+208>>2]=C-B;g[q+204>>2]=B+v}fd(q);break};case 62:{q=bd(c[2876]|0)|0;B=+(h<<5|16|0);g[q+24>>2]=B;g[q+28>>2]=v;C=+g[q+76>>2];D=+g[q+68>>2];E=(C>D?C:D)*.5+10.0;C=+g[q+72>>2];F=(C>D?C:D)*.5+10.0;D=+g[q+52>>2];C=D+B;if(D>0.0){g[q+196>>2]=C+F;g[q+200>>2]=B-F}else{g[q+200>>2]=C-F;g[q+196>>2]=F+B}B=+g[q+56>>2];F=B+v;if(B>0.0){g[q+204>>2]=E+F;g[q+208>>2]=v-E}else{g[q+208>>2]=F-E;g[q+204>>2]=E+v}fd(q);break};case 69:{q=bd(c[2880]|0)|0;E=+(h<<5|16|0);g[q+24>>2]=E;g[q+28>>2]=v;F=+g[q+76>>2];B=+g[q+68>>2];C=(F>B?F:B)*.5+10.0;F=+g[q+72>>2];D=(F>B?F:B)*.5+10.0;B=+g[q+52>>2];F=B+E;if(B>0.0){g[q+196>>2]=F+D;g[q+200>>2]=E-D}else{g[q+200>>2]=F-D;g[q+196>>2]=D+E}E=+g[q+56>>2];D=E+v;if(E>0.0){g[q+204>>2]=C+D;g[q+208>>2]=v-C}else{g[q+208>>2]=D-C;g[q+204>>2]=C+v}fd(q);break};case 35:{q=bd(c[2842]|0)|0;C=+(h<<5|16|0);g[q+24>>2]=C;g[q+28>>2]=v;D=+g[q+76>>2];E=+g[q+68>>2];F=(D>E?D:E)*.5+10.0;D=+g[q+72>>2];B=(D>E?D:E)*.5+10.0;E=+g[q+52>>2];D=E+C;if(E>0.0){g[q+196>>2]=D+B;g[q+200>>2]=C-B}else{g[q+200>>2]=D-B;g[q+196>>2]=B+C}C=+g[q+56>>2];B=C+v;if(C>0.0){g[q+204>>2]=F+B;g[q+208>>2]=v-F}else{g[q+208>>2]=B-F;g[q+204>>2]=F+v}fd(q);break};default:{}}}while(0);h=h+1|0;n=c[k>>2]|0;if((h|0)>=(n|0)){break c}}}}while(0);f=f+1|0}while((f|0)<(c[l>>2]|0))}Fb(b|0)|0;c[2888]=d;b=c[2456]|0;if((b|0)<=0){m=1;i=e;return m|0}l=c[2452]|0;f=0;while(1){G=c[l+(f<<2)>>2]|0;if(((G|0)!=0?(c[G+4>>2]|0)==9:0)?(c[G+176>>2]|0)==(d|0):0){break}f=f+1|0;if((f|0)>=(b|0)){m=1;t=169;break}}if((t|0)==169){i=e;return m|0}t=bd(c[2838]|0)|0;g[t+24>>2]=+g[G+24>>2];g[t+28>>2]=+g[G+28>>2];fd(t);m=1;i=e;return m|0}function Cd(a){a=a|0;var b=0,d=0,e=0,f=0,g=0;a=i;i=i+16|0;b=a;d=(c[9248>>2]|0)==1|(c[9252>>2]|0)==1?1:0;if((c[2306]|0)==1){if((c[2904]|0)==0){e=0;f=5}else{f=4}}else{g=c[2904]|0;if((c[9228>>2]|0)==1&(g|0)!=0){f=4}else{e=g;f=5}}do{if((f|0)==4){c[2904]=0;f=7}else if((f|0)==5){if((d|0)!=0){if((e|0)==0){f=7;break}else{break}}else{i=a;return}}}while(0);if((f|0)==7){c[2476]=0;c[2478]=0;c[2480]=0;c[2482]=0;c[2906]=0;c[2908]=1;c[2910]=0;Bd(0,1)|0;c[2904]=1}c[2464]=1;c[2466]=2;c[2468]=1;f=9944;c[f>>2]=0;c[f+4>>2]=0;f=9952;c[f>>2]=0;c[f+4>>2]=0;f=9960;c[f>>2]=0;c[f+4>>2]=0;f=9968;c[f>>2]=0;c[f+4>>2]=0;f=9984;c[f>>2]=0;c[f+4>>2]=0;c[2494]=0;c[2498]=0;c[1528]=1;c[1530]=1;if((c[1532]|0)!=0){i=a;return}c[1532]=1;f=5104;e=c[f+4>>2]|0;d=6136;c[d>>2]=c[f>>2];c[d+4>>2]=e;nb(b|0,0)|0;e=c[b>>2]|0;d=qe(e|0,((e|0)<0)<<31>>31|0,1e6,0)|0;e=c[b+4>>2]|0;b=ee(d|0,E|0,e|0,((e|0)<0)<<31>>31|0)|0;e=6144;c[e>>2]=b;c[e+4>>2]=E;hc(3,0,1);i=a;return}function Dd(a){a=+a;var b=0,d=0,e=0,f=0,h=0,j=0;b=i;i=i+1040|0;d=b;e=b+8|0;g[1566]=1.0;g[1568]=1.0;g[1570]=1.0;g[1572]=1.0;f=c[2908]|0;c[d>>2]=(c[2906]|0)+1;c[d+4>>2]=f;Zd(e,11864,d);g[1566]=0.0;g[1568]=0.0;g[1570]=0.0;g[1572]=.5;Wc(c[2914]|0,e,17,17);g[1566]=1.0;g[1568]=1.0;g[1570]=1.0;g[1572]=1.0;Wc(c[2914]|0,e,16,16);e=c[2910]|0;if((e|0)==1){g[1566]=0.0;g[1568]=0.0;g[1570]=0.0;g[1572]=.5;Wc(c[2914]|0,11912,301,301);g[1566]=1.0;g[1568]=0.0;g[1570]=0.0;g[1572]=1.0;Wc(c[2914]|0,11912,300,300);i=b;return}else if((e|0)==3){c[1528]=2;c[1530]=2;if((c[1532]|0)!=0){i=b;return}c[1532]=1;f=5104;h=c[f+4>>2]|0;j=6136;c[j>>2]=c[f>>2];c[j+4>>2]=h;nb(d|0,0)|0;h=c[d>>2]|0;j=qe(h|0,((h|0)<0)<<31>>31|0,1e6,0)|0;h=c[d+4>>2]|0;d=ee(j|0,E|0,h|0,((h|0)<0)<<31>>31|0)|0;h=6144;c[h>>2]=d;c[h+4>>2]=E;hc(3,0,1);i=b;return}else if((e|0)==2){g[1566]=0.0;g[1568]=0.0;g[1570]=0.0;g[1572]=.5;Wc(c[2914]|0,11880,301,301);g[1566]=1.0;g[1568]=1.0;g[1570]=0.0;g[1572]=1.0;Wc(c[2914]|0,11896,300,300);i=b;return}else{i=b;return}}function Ed(a,b){a=a|0;b=+b;var d=0,e=0,f=0,h=0.0,j=0;a=i;Tc();g[1566]=1.0;g[1568]=1.0;g[1570]=1.0;g[1572]=1.0;d=c[2912]|0;e=(c[d+4>>2]|0)+320|0;f=(c[1284]|0)-((c[d+8>>2]|0)+150)|0;b=+((c[d+12>>2]|0)+e|0);h=+(f-(c[d+16>>2]|0)|0);if((c[1280]|0)!=(d|0)){Sc();c[1280]=d}Lc(c[1278]|0,+(e|0),+(f|0),0.0,b,h,1.0);f=c[2914]|0;if((c[2904]|0)==0){Wc(f,11664,300,300);j=c[2914]|0;Wc(j,11744,200,440);i=a;return}else{Wc(f,11688,300,300);Wc(c[2914]|0,11720,300,316);j=c[2914]|0;Wc(j,11744,200,440);i=a;return}}function Fd(a){a=a|0;var b=0,d=0,e=0,f=0;a=i;i=i+16|0;b=a;if(!((c[9248>>2]|0)==1|(c[9252>>2]|0)==1|(c[9256>>2]|0)==1)){i=a;return}c[2904]=0;c[2906]=0;c[2908]=1;c[2910]=0;c[1528]=3;c[1530]=3;if((c[1532]|0)!=0){i=a;return}c[1532]=1;d=5104;e=c[d+4>>2]|0;f=6136;c[f>>2]=c[d>>2];c[f+4>>2]=e;nb(b|0,0)|0;e=c[b>>2]|0;f=qe(e|0,((e|0)<0)<<31>>31|0,1e6,0)|0;e=c[b+4>>2]|0;b=ee(f|0,E|0,e|0,((e|0)<0)<<31>>31|0)|0;e=6144;c[e>>2]=b;c[e+4>>2]=E;hc(3,0,1);i=a;return}function Gd(a,b){a=a|0;b=+b;var d=0,e=0,f=0,h=0.0;a=i;Tc();g[1566]=1.0;g[1568]=1.0;g[1570]=1.0;g[1572]=1.0;d=c[2942]|0;e=(c[d+4>>2]|0)+320|0;f=(c[1284]|0)-((c[d+8>>2]|0)+150)|0;b=+((c[d+12>>2]|0)+e|0);h=+(f-(c[d+16>>2]|0)|0);if((c[1280]|0)!=(d|0)){Sc();c[1280]=d}Lc(c[1278]|0,+(e|0),+(f|0),0.0,b,h,1.0);Wc(c[2914]|0,11776,250,320);Wc(c[2914]|0,11816,250,350);Wc(c[2914]|0,11840,300,400);i=a;return}function Hd(){return}function Id(){var a=0,b=0,d=0,e=0,f=0;a=i;i=i+16|0;b=a;a:do{if((c[2910]|0)!=0){d=0;while(1){if((c[9224+(d<<2)>>2]|0)==1){break}d=d+1|0;if((d|0)>=10){break a}}if((Bd(c[2906]|0,c[2908]|0)|0)==0){c[1528]=2;c[1530]=2;if((c[1532]|0)!=0){break}c[1532]=1;d=5104;e=c[d+4>>2]|0;f=6136;c[f>>2]=c[d>>2];c[f+4>>2]=e;nb(b|0,0)|0;e=c[b>>2]|0;f=qe(e|0,((e|0)<0)<<31>>31|0,1e6,0)|0;e=c[b+4>>2]|0;d=ee(f|0,E|0,e|0,((e|0)<0)<<31>>31|0)|0;e=6144;c[e>>2]=d;c[e+4>>2]=E;hc(3,0,1);break}if((c[2910]|0)==2){c[2476]=0;c[2478]=0;c[2480]=0;c[2482]=0}c[2910]=0}}while(0);if((c[9256>>2]|0)!=1){i=a;return}c[1528]=3;c[1530]=3;if((c[1532]|0)!=0){i=a;return}c[1532]=1;e=5104;d=c[e+4>>2]|0;f=6136;c[f>>2]=c[e>>2];c[f+4>>2]=d;nb(b|0,0)|0;d=c[b>>2]|0;f=qe(d|0,((d|0)<0)<<31>>31|0,1e6,0)|0;d=c[b+4>>2]|0;b=ee(f|0,E|0,d|0,((d|0)<0)<<31>>31|0)|0;d=6144;c[d>>2]=b;c[d+4>>2]=E;hc(3,0,1);i=a;return}function Jd(){var a=0,b=0;a=i;Ra(11928,511)|0;b=Pb(11600,11944)|0;if((b|0)==0){i=a;return}kb(11624,1,4,b|0)|0;kb(11632,1,4,b|0)|0;Fb(b|0)|0;xb(11952);i=a;return}function Kd(e,f){e=e|0;f=f|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;h=i;i=i+112|0;j=h;k=h+88|0;l=h+64|0;cb(Hb(0)|0);if((e|0)>1?(e=c[f+4>>2]|0,(a[e>>0]|0)==100):0){f=e;e=11984;do{f=f+1|0;e=e+1|0;m=a[f>>0]|0;n=a[e>>0]|0}while(!((m<<24>>24==0?1:m<<24>>24!=n<<24>>24)|n<<24>>24==0));if(m<<24>>24==n<<24>>24){c[2470]=1;Ja(12032)|0}}n=5104;c[n>>2]=66666;c[n+4>>2]=0;c[1282]=640;c[1284]=480;do{if((yb(32)|0)<0){Ja(9176)|0;c[j>>2]=ya()|0;eb(9288,j|0)|0}else{n=jb(640,480,32,201326593)|0;c[1274]=n;if((n|0)==0){Ja(9128)|0;c[j>>2]=ya()|0;eb(9288,j|0)|0;break}$b(11992,0);Ja(9032)|0;Ja(9072)|0;c[j>>2]=gb(7936)|0;eb(5144,j|0)|0;c[j>>2]=gb(7937)|0;eb(5160,j|0)|0;c[j>>2]=gb(7938)|0;eb(5176,j|0)|0;Ja(9088)|0;c[j>>2]=5192;n=Da(35633)|0;if((n|0)!=0){Oa(n|0,1,j|0,0);Kb(n|0);cc(n|0,35713,k|0);if((c[k>>2]|0)==0){Qb(n|0);o=0}else{o=n}}else{o=0}c[j>>2]=5584;n=Da(35632)|0;if((n|0)!=0){Oa(n|0,1,j|0,0);Kb(n|0);cc(n|0,35713,k|0);if((c[k>>2]|0)==0){Qb(n|0);p=0}else{p=n}}else{p=0}if(!((o|0)==0|(p|0)==0)){n=wa()|0;hb(n|0,o|0);hb(n|0,p|0);fc(n|0);Rb(n|0,35714,l|0);if((c[l>>2]|0)==0){ua(n|0);q=0}else{q=n}}else{q=0}pa(q|0);c[1500]=Ba(q|0,5984)|0;c[1506]=Ba(q|0,6008)|0;c[1510]=Ba(q|0,6032)|0;c[1516]=Xb(q|0,6048)|0;c[1524]=Xb(q|0,6072)|0;Na(1,6104);va(34962,c[1526]|0);Nb(34962,192e3,0,35048);va(34962,c[1526]|0);Ua(c[1500]|0,2,5126,0,32,0);Ua(c[1506]|0,2,5126,0,32,8);Ua(c[1510]|0,4,5126,0,32,16);Lb(c[1500]|0);Lb(c[1506]|0);Lb(c[1510]|0);zb(c[1516]|0,0);g[j>>2]=2.0/+(c[1282]|0);g[j+4>>2]=0.0;g[j+8>>2]=0.0;g[j+12>>2]=-1.0;g[j+16>>2]=0.0;g[j+20>>2]=2.0/+(c[1284]|0);g[j+24>>2]=0.0;g[j+28>>2]=-1.0;g[j+32>>2]=0.0;g[j+36>>2]=0.0;g[j+40>>2]=1.0;n=j+44|0;m=j+60|0;c[n+0>>2]=0;c[n+4>>2]=0;c[n+8>>2]=0;c[n+12>>2]=0;g[m>>2]=1.0;sa(c[1524]|0,1,0,j|0);db(3042);Aa(770,771);m=Pd(12)|0;c[m>>2]=Pd(12800)|0;c[m+4>>2]=0;c[m+8>>2]=400;c[1278]=m;g[1566]=1.0;g[1568]=1.0;g[1570]=1.0;g[1572]=1.0;Ga(512)|0;r=9224|0;s=r+40|0;do{c[r>>2]=0;r=r+4|0}while((r|0)<(s|0));do{if((Ga(16)|0)<0){Ja(9504)|0;c[j>>2]=ya()|0;eb(9288,j|0)|0}else{c[k>>2]=44100;b[k+4>>1]=-32752;a[k+6>>0]=2;b[k+8>>1]=2048;c[k+16>>2]=1;if((bb(k|0,l|0)|0)<0){Ja(9464)|0;c[j>>2]=ya()|0;eb(9288,j|0)|0;break}m=c[l+4>>2]|0;if(((m&65535)<<16>>16==-32752?(c[l>>2]|0)==44100:0)?(m&16711680|0)==131072:0){Vb(0);break}Ja(9408)|0;Sb()}}while(0);c[2472]=640;c[2474]=480;c[2476]=0;c[2478]=0;c[2480]=0;c[2482]=0;c[2484]=66}}while(0);c[2912]=Vc(12e3)|0;c[2942]=Vc(12016)|0;l=Pd(20)|0;k=Pd(24)|0;q=Pd(65536)|0;c[k>>2]=q;c[k+4>>2]=0;c[k+8>>2]=0;c[k+12>>2]=2048;c[k+16>>2]=8;c[k+20>>2]=-1;p=0;do{o=p<<3;m=0;do{n=(m<<11)+o|0;e=d[6296+(m+o)>>0]|0;f=0;do{t=n+f<<2;a[q+t>>0]=-1;a[q+(t|1)>>0]=-1;a[q+(t|2)>>0]=-1;a[q+(t|3)>>0]=((1<<7-f&e|0)!=0)<<31>>31;f=f+1|0}while((f|0)!=8);m=m+1|0}while((m|0)!=8);p=p+1|0}while((p|0)!=256);c[l>>2]=k;c[l+4>>2]=8;c[l+8>>2]=8;c[l+12>>2]=0;c[l+16>>2]=256;c[2914]=l;l=Vc(10280)|0;c[2574]=l;c[l+4>>2]=-16;c[l+8>>2]=-32;l=Vc(10304)|0;c[2582]=l;c[l+4>>2]=-16;c[l+8>>2]=-16;l=Vc(10336)|0;c[2588]=l;c[l+4>>2]=-16;c[l+8>>2]=-16;l=Vc(10360)|0;c[2596]=l;c[l+4>>2]=-16;c[l+8>>2]=-16;l=Vc(10392)|0;c[2604]=l;c[l+4>>2]=-16;c[l+8>>2]=-16;l=Vc(10424)|0;c[2612]=l;c[l+4>>2]=-16;c[l+8>>2]=-16;l=Vc(10456)|0;c[2618]=l;c[l+4>>2]=-16;c[l+8>>2]=-80;l=Vc(10480)|0;c[2626]=l;c[l+4>>2]=-16;c[l+8>>2]=-80;l=Vc(10512)|0;c[2632]=l;c[l+4>>2]=-16;c[l+8>>2]=-32;l=Vc(10536)|0;c[2638]=l;c[l+4>>2]=-16;c[l+8>>2]=-48;l=Vc(10560)|0;c[2646]=l;c[l+4>>2]=-16;c[l+8>>2]=-16;l=Vc(10592)|0;if((l|0)==0){Sa()}k=Pd(24)|0;c[k>>2]=l;c[k+4>>2]=32;g[k+8>>2]=5.0;c[k+12>>2]=2;c[k+16>>2]=200;c[k+20>>2]=400;c[2654]=k;c[l+4>>2]=-16;c[l+8>>2]=-16;l=Vc(10624)|0;c[2536]=l;c[l+4>>2]=-16;c[l+8>>2]=-48;l=Vc(10648)|0;c[2538]=l;c[l+4>>2]=-16;c[l+8>>2]=-48;l=Vc(10672)|0;c[2542]=l;c[l+4>>2]=-16;c[l+8>>2]=-48;l=Vc(10696)|0;c[2540]=l;c[l+4>>2]=-16;c[l+8>>2]=-48;l=Vc(10720)|0;c[2566]=l;c[l+4>>2]=-16;c[l+8>>2]=-16;l=Vc(10744)|0;if((l|0)==0){Sa()}k=Pd(24)|0;c[k>>2]=l;c[k+4>>2]=32;g[k+8>>2]=5.0;c[k+12>>2]=2;c[k+16>>2]=200;c[k+20>>2]=400;c[2564]=k;c[l+4>>2]=-16;c[l+8>>2]=-16;l=Vc(10776)|0;if((l|0)==0){Sa()}k=Pd(24)|0;c[k>>2]=l;c[k+4>>2]=32;g[k+8>>2]=10.0;c[k+12>>2]=2;c[k+16>>2]=100;c[k+20>>2]=200;c[2700]=k;c[l+4>>2]=-16;c[l+8>>2]=-48;l=Vc(10808)|0;c[2708]=l;c[l+4>>2]=-16;c[l+8>>2]=-32;l=Vc(10840)|0;c[2718]=l;c[l+4>>2]=-16;c[l+8>>2]=-16;l=Vc(10880)|0;c[2728]=l;c[l+4>>2]=-16;c[l+8>>2]=-16;l=Vc(10920)|0;c[2738]=l;c[l+4>>2]=-16;c[l+8>>2]=-16;l=Vc(10960)|0;c[2748]=l;c[l+4>>2]=-16;c[l+8>>2]=-16;l=Vc(11e3)|0;c[2756]=l;c[l+4>>2]=-16;c[l+8>>2]=-16;l=Vc(11032)|0;c[2764]=l;c[l+4>>2]=-16;c[l+8>>2]=-16;l=Vc(11064)|0;c[2772]=l;c[l+4>>2]=-16;c[l+8>>2]=-16;l=Vc(11096)|0;c[2780]=l;c[l+4>>2]=-16;c[l+8>>2]=-16;l=Vc(11128)|0;if((l|0)==0){Sa()}k=Pd(24)|0;c[k>>2]=l;c[k+4>>2]=32;g[k+8>>2]=5.0;c[k+12>>2]=3;c[k+16>>2]=200;c[k+20>>2]=600;c[2786]=k;c[l+4>>2]=-16;c[l+8>>2]=-48;l=Vc(11152)|0;c[2794]=l;c[l+4>>2]=-16;c[l+8>>2]=-48;c[2556]=$c(11184)|0;c[2568]=$c(11208)|0;c[2562]=$c(11232)|0;c[2558]=$c(11256)|0;c[2552]=$c(11280)|0;c[2548]=$c(11304)|0;c[2544]=$c(11328)|0;l=c[2448]|0;if((l|0)==0){u=Pd(216)|0}else{c[2448]=c[l+212>>2];u=l}c[u>>2]=0;c[u+4>>2]=0;l=u+16|0;k=u+32|0;c[l+0>>2]=0;c[l+4>>2]=0;c[l+8>>2]=0;c[l+12>>2]=0;c[u+36>>2]=1;l=u+40|0;p=u+68|0;c[l+0>>2]=0;c[l+4>>2]=0;c[l+8>>2]=0;c[l+12>>2]=0;c[l+16>>2]=0;g[p>>2]=1.0;g[u+72>>2]=1.0;g[u+76>>2]=1.0;p=u+80|0;l=u+84|0;c[u+116>>2]=0;q=u+132|0;c[l+0>>2]=0;c[l+4>>2]=0;c[l+8>>2]=0;c[l+12>>2]=0;c[l+16>>2]=0;c[l+20>>2]=0;c[l+24>>2]=0;g[q>>2]=1.0;g[u+128>>2]=1.0;g[u+124>>2]=1.0;g[u+120>>2]=1.0;q=u+148|0;l=u+144|0;m=u+140|0;o=u+136|0;c[u+212>>2]=0;r=u+152|0;s=r+44|0;do{c[r>>2]=0;r=r+4|0}while((r|0)<(s|0));g[p>>2]=-1.0;c[k>>2]=0;g[o>>2]=0.0;g[m>>2]=0.0;g[l>>2]=0.0;g[q>>2]=1.0;q=bd(u)|0;c[2838]=q;c[q+4>>2]=0;g[q+68>>2]=16.0;g[q+72>>2]=24.0;g[q+76>>2]=24.0;g[q+80>>2]=30.0;g[q+88>>2]=2.5;g[q+92>>2]=.30000001192092896;c[q+32>>2]=25;g[q+136>>2]=.4000000059604645;g[q+140>>2]=.4000000059604645;g[q+144>>2]=.4000000059604645;g[q+148>>2]=96.0;l=c[2538]|0;c[q+104>>2]=0;c[q+108>>2]=l;c[q+116>>2]=0;c[q+160>>2]=1;c[q+168>>2]=1;q=bd(u)|0;c[2840]=q;c[q+4>>2]=1;c[q+32>>2]=9;g[q+68>>2]=16.0;g[q+72>>2]=24.0;g[q+76>>2]=24.0;g[q+80>>2]=25.0;g[q+88>>2]=2.0;g[q+92>>2]=.5;c[q+160>>2]=2;l=c[2574]|0;c[q+104>>2]=0;c[q+108>>2]=l;c[q+116>>2]=0;q=bd(u)|0;c[2842]=q;c[q+4>>2]=2;c[q+32>>2]=1;g[q+68>>2]=12.0;g[q+72>>2]=24.0;g[q+76>>2]=24.0;l=c[2618]|0;c[q+104>>2]=0;c[q+108>>2]=l;c[q+116>>2]=0;l=bd(q)|0;c[2844]=l;q=c[2626]|0;c[l+104>>2]=0;c[l+108>>2]=q;c[l+116>>2]=0;l=bd(c[2842]|0)|0;c[2846]=l;q=c[2632]|0;c[l+104>>2]=0;c[l+108>>2]=q;c[l+116>>2]=0;c[l+32>>2]=1;q=bd(l)|0;c[2848]=q;l=c[2638]|0;c[q+104>>2]=0;c[q+108>>2]=l;c[q+116>>2]=0;c[q+32>>2]=17;g[q+136>>2]=.4000000059604645;g[q+140>>2]=.4000000059604645;g[q+144>>2]=.4000000059604645;g[q+148>>2]=160.0;q=bd(u)|0;c[2850]=q;c[q+4>>2]=3;c[q+36>>2]=-1;c[q+32>>2]=0;l=c[2588]|0;c[q+104>>2]=0;c[q+108>>2]=l;c[q+116>>2]=0;l=bd(q)|0;c[2852]=l;q=c[2596]|0;c[l+104>>2]=0;c[l+108>>2]=q;c[l+116>>2]=0;l=bd(c[2850]|0)|0;c[2854]=l;q=c[2604]|0;c[l+104>>2]=0;c[l+108>>2]=q;c[l+116>>2]=0;l=bd(c[2850]|0)|0;c[2856]=l;q=c[2612]|0;c[l+104>>2]=0;c[l+108>>2]=q;c[l+116>>2]=0;l=bd(u)|0;c[2858]=l;c[l+4>>2]=4;c[l+36>>2]=-1;c[l+32>>2]=8;g[l+68>>2]=18.0;q=c[2646]|0;c[l+104>>2]=0;c[l+108>>2]=q;c[l+116>>2]=0;c[l+172>>2]=3;l=bd(u)|0;c[2546]=l;c[l+4>>2]=5;c[l+36>>2]=-1;c[l+32>>2]=0;q=c[2582]|0;c[l+104>>2]=0;c[l+108>>2]=q;c[l+116>>2]=0;l=bd(u)|0;c[2860]=l;c[l+4>>2]=6;c[l+36>>2]=-1;c[l+32>>2]=24;g[l+68>>2]=18.0;q=c[2654]|0;c[l+112>>2]=0;m=l+104|0;if((c[m>>2]|0)!=(q|0)){c[m>>2]=q;c[l+108>>2]=0;c[l+116>>2]=0}g[l+136>>2]=1.0;g[l+140>>2]=0.0;g[l+144>>2]=0.0;g[l+148>>2]=128.0;c[l+152>>2]=4;c[l+172>>2]=4;l=bd(u)|0;c[2862]=l;c[l+4>>2]=8;c[l+32>>2]=17;g[l+136>>2]=.20000000298023224;g[l+140>>2]=.20000000298023224;g[l+144>>2]=.20000000298023224;g[l+148>>2]=64.0;g[l+68>>2]=4.0;g[l+80>>2]=.10000000149011612;c[l+168>>2]=2;c[l+160>>2]=5;c[l+176>>2]=120;q=c[2756]|0;c[l+104>>2]=0;c[l+108>>2]=q;c[l+116>>2]=0;g[l+52>>2]=0.0;g[l+56>>2]=-16.0;q=bd(l)|0;c[2864]=q;l=c[2764]|0;c[q+104>>2]=0;c[q+108>>2]=l;c[q+116>>2]=0;g[q+52>>2]=0.0;g[q+56>>2]=16.0;q=bd(c[2862]|0)|0;c[2866]=q;l=c[2772]|0;c[q+104>>2]=0;c[q+108>>2]=l;c[q+116>>2]=0;g[q+52>>2]=-16.0;g[q+56>>2]=0.0;q=bd(c[2862]|0)|0;c[2868]=q;l=c[2780]|0;c[q+104>>2]=0;c[q+108>>2]=l;c[q+116>>2]=0;g[q+52>>2]=16.0;g[q+56>>2]=0.0;q=bd(u)|0;c[2870]=q;c[q+4>>2]=7;c[q+32>>2]=1;g[q+68>>2]=15.0;c[q+152>>2]=5;c[q+160>>2]=6;l=c[2718]|0;c[q+104>>2]=0;c[q+108>>2]=l;c[q+116>>2]=0;c[q+192>>2]=c[2862];l=bd(q)|0;c[2872]=l;q=c[2728]|0;c[l+104>>2]=0;c[l+108>>2]=q;c[l+116>>2]=0;c[l+192>>2]=c[2864];l=bd(c[2870]|0)|0;c[2874]=l;q=c[2738]|0;c[l+104>>2]=0;c[l+108>>2]=q;c[l+116>>2]=0;c[l+192>>2]=c[2866];l=bd(c[2870]|0)|0;c[2876]=l;q=c[2748]|0;c[l+104>>2]=0;c[l+108>>2]=q;c[l+116>>2]=0;c[l+192>>2]=c[2868];l=bd(u)|0;c[2878]=l;c[l+4>>2]=9;g[l+40>>2]=-5.0;c[l+32>>2]=24;g[l+68>>2]=20.0;g[l+136>>2]=0.0;g[l+140>>2]=0.0;g[l+144>>2]=.5;g[l+148>>2]=64.0;q=c[2566]|0;c[l+104>>2]=0;c[l+108>>2]=q;c[l+116>>2]=0;c[l+172>>2]=7;c[l+156>>2]=6;l=bd(u)|0;c[2880]=l;c[l+4>>2]=10;c[l+32>>2]=24;g[l+136>>2]=.5;g[l+140>>2]=.5;g[l+144>>2]=.5;g[l+148>>2]=160.0;g[l+68>>2]=20.0;q=c[2700]|0;c[l+112>>2]=0;m=l+104|0;if((c[m>>2]|0)!=(q|0)){c[m>>2]=q;c[l+108>>2]=0;c[l+116>>2]=0}c[l+172>>2]=8;q=bd(l)|0;c[2882]=q;l=c[2708]|0;c[q+104>>2]=0;c[q+108>>2]=l;c[q+116>>2]=0;c[q+172>>2]=9;q=bd(u)|0;c[2884]=q;c[q+36>>2]=0;c[q+4>>2]=11;c[q+32>>2]=24;g[q+136>>2]=.5;g[q+140>>2]=.5;g[q+144>>2]=.5;g[q+148>>2]=160.0;g[q+68>>2]=20.0;l=c[2566]|0;c[q+104>>2]=0;c[q+108>>2]=l;c[q+116>>2]=0;c[q+172>>2]=10;q=bd(u)|0;c[2886]=q;c[q+36>>2]=0;c[q+4>>2]=12;c[q+32>>2]=0;l=c[2566]|0;c[q+104>>2]=0;c[q+108>>2]=l;c[q+116>>2]=0;q=bd(u)|0;c[2554]=q;c[q+4>>2]=13;c[q+32>>2]=16;g[q+136>>2]=1.0;g[q+140>>2]=0.0;g[q+144>>2]=0.0;g[q+148>>2]=96.0;l=c[2786]|0;c[q+112>>2]=0;m=q+104|0;if((c[m>>2]|0)!=(l|0)){c[m>>2]=l;c[q+108>>2]=0;c[q+116>>2]=0}c[q+160>>2]=5;c[q+176>>2]=15;g[q+40>>2]=1.0;q=bd(u)|0;c[2550]=q;c[q+4>>2]=13;c[q+32>>2]=0;u=c[2794]|0;c[q+104>>2]=0;c[q+108>>2]=u;c[q+116>>2]=0;Ra(11928,511)|0;q=Pb(11600,11936)|0;do{if((q|0)!=0){ra(11624,1,4,q|0)|0;ra(11632,1,4,q|0)|0;u=c[2906]|0;l=c[2908]|0;if((u|0)==0&(l|0)==1){c[2904]=0;break}else{Bd(u,l)|0;c[2904]=1;Fb(q|0)|0;break}}}while(0);c[1528]=3;c[1530]=3;if((c[1532]|0)!=0){i=h;return 0}c[1532]=1;q=5104;l=c[q+4>>2]|0;u=6136;c[u>>2]=c[q>>2];c[u+4>>2]=l;nb(j|0,0)|0;l=c[j>>2]|0;u=qe(l|0,((l|0)<0)<<31>>31|0,1e6,0)|0;l=c[j+4>>2]|0;j=ee(u|0,E|0,l|0,((l|0)<0)<<31>>31|0)|0;l=6144;c[l>>2]=j;c[l+4>>2]=E;hc(3,0,1);i=h;return 0}function Ld(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;f=i;i=i+16|0;g=f;c[g>>2]=b;h=(e|0)==0?12264:e;e=c[h>>2]|0;a:do{if((d|0)==0){if((e|0)==0){j=0;i=f;return j|0}}else{if((b|0)==0){c[g>>2]=g;k=g}else{k=b}l=a[d>>0]|0;m=l&255;b:do{if((e|0)==0){if(l<<24>>24>-1){c[k>>2]=m;j=l<<24>>24!=0&1;i=f;return j|0}else{n=m+ -194|0;if(n>>>0>50){break a}o=c[12056+(n<<2)>>2]|0;break}}else{n=m>>>3;if((n+ -16|n+(e>>26))>>>0>7){break a}else{p=1;q=l;r=e;s=d}while(1){s=s+1|0;r=(q&255)+ -128|r<<6;n=p+ -1|0;if((r|0)>=0){break}if((n|0)==0){o=r;break b}q=a[s>>0]|0;if(((q&255)+ -128|0)>>>0>63){break a}else{p=n}}c[h>>2]=0;c[k>>2]=r;j=2-p|0;i=f;return j|0}}while(0);c[h>>2]=o;j=-2;i=f;return j|0}}while(0);c[h>>2]=0;c[(ic()|0)>>2]=84;j=-1;i=f;return j|0}function Md(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0;f=i;g=b+84|0;h=c[g>>2]|0;j=e+256|0;k=h;l=(j|0)==0;a:do{if((k&3|0)==0|l){m=j;n=l;o=h;p=4}else{q=j;r=h;while(1){if((a[r>>0]|0)==0){s=q;t=r;break a}u=r+1|0;v=q+ -1|0;w=(v|0)==0;if((u&3|0)==0|w){m=v;n=w;o=u;p=4;break}else{q=v;r=u}}}}while(0);b:do{if((p|0)==4){if(!n){if((a[o>>0]|0)!=0){c:do{if(m>>>0>3){l=m;r=o;while(1){q=c[r>>2]|0;if(((q&-2139062144^-2139062144)&q+ -16843009|0)!=0){x=l;y=r;break c}q=r+4|0;u=l+ -4|0;if(u>>>0>3){l=u;r=q}else{x=u;y=q;break}}}else{x=m;y=o}}while(0);if((x|0)==0){s=0;t=y}else{r=x;l=y;while(1){if((a[l>>0]|0)==0){s=r;t=l;break b}q=l+1|0;r=r+ -1|0;if((r|0)==0){s=0;t=q;break}else{l=q}}}}else{s=m;t=o}}else{s=0;t=o}}}while(0);o=(s|0)!=0?t:0;if((o|0)==0){z=j}else{z=o-k|0}k=z>>>0>>0?z:e;ie(d|0,h|0,k|0)|0;c[b+4>>2]=h+k;d=h+z|0;c[b+8>>2]=d;c[g>>2]=d;i=f;return k|0}function Nd(e,f,j){e=e|0;f=f|0;j=j|0;var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Fa=0,Ga=0,Ha=0,Ia=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ua=0,Va=0,Wa=0,Xa=0,Ya=0,Za=0,_a=0,$a=0,ab=0,bb=0,cb=0.0,db=0,eb=0,fb=0,gb=0,hb=0,ib=0,jb=0,kb=0,lb=0,mb=0,nb=0,ob=0,pb=0,qb=0,rb=0,sb=0,tb=0,ub=0,vb=0,wb=0,xb=0,yb=0.0,zb=0,Ab=0.0,Bb=0,Cb=0,Db=0,Eb=0,Fb=0,Gb=0,Hb=0,Ib=0,Jb=0,Kb=0,Lb=0,Mb=0,Nb=0.0,Ob=0,Pb=0.0,Qb=0,Rb=0,Sb=0.0,Tb=0,Ub=0.0,Vb=0.0,Wb=0,Xb=0,Yb=0,Zb=0,_b=0.0,$b=0,ac=0.0,bc=0,cc=0,dc=0,ec=0.0,fc=0,gc=0,hc=0.0,jc=0.0,kc=0.0,mc=0,nc=0.0,oc=0,pc=0.0,qc=0,rc=0,sc=0,tc=0,uc=0,vc=0,wc=0,xc=0,yc=0,zc=0,Ac=0,Bc=0,Cc=0,Dc=0,Ec=0,Fc=0,Gc=0,Hc=0,Ic=0,Jc=0,Kc=0,Lc=0,Mc=0,Nc=0,Oc=0,Pc=0,Qc=0,Rc=0,Sc=0,Tc=0,Uc=0,Vc=0,Wc=0,Xc=0,Yc=0,Zc=0,_c=0,$c=0,ad=0,bd=0,cd=0,dd=0,ed=0,fd=0,gd=0,hd=0,id=0,jd=0,kd=0,ld=0,md=0,nd=0,od=0,pd=0,qd=0,rd=0,sd=0,td=0,ud=0,vd=0,wd=0,xd=0,yd=0,zd=0,Ad=0,Bd=0,Cd=0,Dd=0,Ed=0,Fd=0,Gd=0,Hd=0,Id=0,Jd=0,Kd=0,Md=0,Nd=0,Od=0,Sd=0,Vd=0,Wd=0,Xd=0,Yd=0,Zd=0,_d=0,$d=0.0,ae=0,be=0,ce=0,fe=0.0,ie=0,ke=0.0,le=0.0,me=0.0,ne=0.0,oe=0.0,pe=0.0,te=0.0,ue=0,ve=0,we=0.0,xe=0,ye=0.0,ze=0,Ae=0.0,Be=0,Ce=0,De=0,Ee=0,Fe=0,Ge=0,He=0,Ie=0,Je=0,Ke=0,Le=0,Me=0,Ne=0,Oe=0,Pe=0,Qe=0,Re=0,Se=0,Te=0,Ue=0,Ve=0,We=0,Xe=0,Ye=0,Ze=0,_e=0,$e=0,af=0,bf=0,cf=0,df=0,ef=0,ff=0,gf=0,hf=0,jf=0,kf=0,lf=0,mf=0,nf=0,of=0,pf=0,qf=0,rf=0,sf=0,tf=0,uf=0,vf=0,wf=0,xf=0,yf=0,zf=0,Af=0,Bf=0,Cf=0,Df=0,Ef=0,Ff=0;l=i;i=i+944|0;m=l+160|0;n=l;o=l+16|0;p=l+673|0;q=l+40|0;r=l+672|0;s=l+48|0;v=l+24|0;c[v>>2]=j;j=s+0|0;w=j+112|0;do{c[j>>2]=0;j=j+4|0}while((j|0)<(w|0));c[s+32>>2]=2;c[s+44>>2]=e;c[s+76>>2]=-1;c[s+84>>2]=e;e=a[f>>0]|0;if(e<<24>>24==0){i=l;return}j=s+4|0;w=s+100|0;x=s+108|0;y=s+8|0;z=p+10|0;A=p+33|0;B=o+4|0;C=p+46|0;D=p+94|0;F=s+104|0;G=m+496|0;H=e;e=0;I=f;f=0;J=0;K=0;a:while(1){b:do{if(!(H<<24>>24==32)?!(((H&255)+ -9|0)>>>0<5):0){L=H<<24>>24==37;c:do{if(L){M=I+1|0;N=a[M>>0]|0;do{if(N<<24>>24==42){O=0;Q=I+2|0}else if(N<<24>>24==37){break c}else{R=(N&255)+ -48|0;if(R>>>0<10?(a[I+2>>0]|0)==36:0){c[n>>2]=c[v>>2];S=R;while(1){R=c[n>>2]|0;T=c[R>>2]|0;c[n>>2]=R+4;if(S>>>0>1){S=S+ -1|0}else{break}}O=T;Q=I+3|0;break}S=c[v>>2]|0;R=c[S>>2]|0;c[v>>2]=S+4;O=R;Q=M}}while(0);M=a[Q>>0]|0;N=M&255;if((N+ -48|0)>>>0<10){R=N;N=Q;S=0;while(1){U=(S*10|0)+ -48+R|0;V=N+1|0;W=a[V>>0]|0;R=W&255;if(!((R+ -48|0)>>>0<10)){X=W;Y=V;Z=U;break}else{N=V;S=U}}}else{X=M;Y=Q;Z=0}if(X<<24>>24==109){S=Y+1|0;_=a[S>>0]|0;$=(O|0)!=0&1;ba=S}else{_=X;$=0;ba=Y}S=ba+1|0;switch(_&255|0){case 104:{N=(a[S>>0]|0)==104;ca=N?ba+2|0:S;da=N?-2:-1;break};case 76:{ca=S;da=2;break};case 116:case 122:{ca=S;da=1;break};case 106:{ca=S;da=3;break};case 108:{N=(a[S>>0]|0)==108;ca=N?ba+2|0:S;da=N?3:1;break};case 110:case 112:case 67:case 83:case 91:case 99:case 115:case 88:case 71:case 70:case 69:case 65:case 103:case 102:case 101:case 97:case 120:case 117:case 111:case 105:case 100:{ca=ba;da=0;break};default:{ea=J;fa=K;ga=527;break a}}N=d[ca>>0]|0;S=(N&47|0)==3;R=S?N|32:N;N=S?1:da;if((R|0)==110){if((O|0)==0){ha=e;ia=ca;ja=f;ka=J;la=K;break b}switch(N|0){case-2:{a[O>>0]=f;ha=e;ia=ca;ja=f;ka=J;la=K;break b;break};case-1:{b[O>>1]=f;ha=e;ia=ca;ja=f;ka=J;la=K;break b;break};case 0:{c[O>>2]=f;ha=e;ia=ca;ja=f;ka=J;la=K;break b;break};case 1:{c[O>>2]=f;ha=e;ia=ca;ja=f;ka=J;la=K;break b;break};case 3:{S=O;c[S>>2]=f;c[S+4>>2]=((f|0)<0)<<31>>31;ha=e;ia=ca;ja=f;ka=J;la=K;break b;break};default:{ha=e;ia=ca;ja=f;ka=J;la=K;break b}}}else if((R|0)==99){ma=f;na=(Z|0)<1?1:Z}else if((R|0)==91){ma=f;na=Z}else{c[F>>2]=0;S=c[y>>2]|0;U=c[j>>2]|0;c[x>>2]=S-U;c[w>>2]=S;V=U;U=S;while(1){if(V>>>0>>0){c[j>>2]=V+1;oa=d[V>>0]|0}else{oa=Ud(s)|0}if(!((oa|0)==32|(oa+ -9|0)>>>0<5)){break}V=c[j>>2]|0;U=c[w>>2]|0}U=c[j>>2]|0;if((c[w>>2]|0)==0){pa=U}else{V=U+ -1|0;c[j>>2]=V;pa=V}ma=(c[x>>2]|0)+f+pa-(c[y>>2]|0)|0;na=Z}c[F>>2]=na;V=c[y>>2]|0;U=c[j>>2]|0;M=V-U|0;c[x>>2]=M;if((na|0)!=0&(M|0)>(na|0)){qa=U+na|0}else{qa=V}c[w>>2]=qa;if(U>>>0>>0){c[j>>2]=U+1;ra=qa}else{if((Ud(s)|0)<0){ea=J;fa=K;ga=527;break a}ra=c[w>>2]|0}if((ra|0)!=0){c[j>>2]=(c[j>>2]|0)+ -1}d:do{switch(R|0){case 91:case 99:case 115:{U=(R|0)==99;e:do{if((R&239|0)==99){he(p|0,-1,257)|0;a[p>>0]=0;if((R|0)==115){a[A>>0]=0;a[z+0>>0]=0;a[z+1>>0]=0;a[z+2>>0]=0;a[z+3>>0]=0;a[z+4>>0]=0;sa=ca}else{sa=ca}}else{V=ca+1|0;M=(a[V>>0]|0)==94;S=M&1;W=M?ca+2|0:V;he(p|0,M&1|0,257)|0;a[p>>0]=0;M=a[W>>0]|0;if(M<<24>>24==93){V=(S^1)&255;a[D>>0]=V;ta=V;ua=W+1|0}else if(M<<24>>24==45){M=(S^1)&255;a[C>>0]=M;ta=M;ua=W+1|0}else{ta=(S^1)&255;ua=W}W=ua;while(1){S=a[W>>0]|0;if(S<<24>>24==93){sa=W;break e}else if(S<<24>>24==45){M=W+1|0;V=a[M>>0]|0;if(!(V<<24>>24==93|V<<24>>24==0)){va=a[W+ -1>>0]|0;if((va&255)<(V&255)){wa=va&255;do{wa=wa+1|0;a[p+wa>>0]=ta;va=a[M>>0]|0}while((wa|0)<(va&255|0));xa=va;ya=M}else{xa=V;ya=M}}else{xa=45;ya=W}}else if(S<<24>>24==0){ea=J;fa=K;ga=527;break a}else{xa=S;ya=W}a[p+((xa&255)+1)>>0]=ta;W=ya+1|0}}}while(0);W=U?na+1|0:31;wa=(N|0)==1;va=($|0)!=0;f:do{if(wa){if(va){za=Pd(W<<2)|0;if((za|0)==0){ea=0;fa=za;ga=527;break a}else{Aa=za}}else{Aa=O}c[o>>2]=0;c[B>>2]=0;za=0;Ba=W;Ca=Aa;g:while(1){if((Ca|0)==0){Da=va&(za|0)==(Ba|0);while(1){Ea=c[j>>2]|0;if(Ea>>>0<(c[w>>2]|0)>>>0){c[j>>2]=Ea+1;Fa=d[Ea>>0]|0}else{Fa=Ud(s)|0}if((a[p+(Fa+1)>>0]|0)==0){Ga=za;Ha=0;break g}a[r>>0]=Fa;Ea=Ld(q,r,o)|0;if((Ea|0)==-2){continue}else if((Ea|0)==-1){ea=0;fa=0;ga=527;break a}if(Da){Ia=za;break}}}else{if(va){Ja=za}else{Ka=za;ga=104;break}while(1){while(1){Da=c[j>>2]|0;if(Da>>>0<(c[w>>2]|0)>>>0){c[j>>2]=Da+1;La=d[Da>>0]|0}else{La=Ud(s)|0}if((a[p+(La+1)>>0]|0)==0){Ga=Ja;Ha=Ca;break g}a[r>>0]=La;Da=Ld(q,r,o)|0;if((Da|0)==-1){ea=0;fa=Ca;ga=527;break a}else if(!((Da|0)==-2)){break}}c[Ca+(Ja<<2)>>2]=c[q>>2];Ja=Ja+1|0;if((Ja|0)==(Ba|0)){Ia=Ba;break}}}Da=Ba<<1|1;S=Rd(Ca,Da<<2)|0;if((S|0)==0){ea=0;fa=Ca;ga=527;break a}za=Ia;Ba=Da;Ca=S}h:do{if((ga|0)==104){while(1){ga=0;while(1){Ba=c[j>>2]|0;if(Ba>>>0<(c[w>>2]|0)>>>0){c[j>>2]=Ba+1;Ma=d[Ba>>0]|0}else{Ma=Ud(s)|0}if((a[p+(Ma+1)>>0]|0)==0){Ga=Ka;Ha=Ca;break h}a[r>>0]=Ma;Ba=Ld(q,r,o)|0;if((Ba|0)==-1){ga=529;break a}else if(!((Ba|0)==-2)){break}}c[Ca+(Ka<<2)>>2]=c[q>>2];Ka=Ka+1|0;ga=104}}}while(0);if((c[o>>2]|0)==0){Na=Ga;Oa=0;Pa=Ha}else{ea=0;fa=Ha;ga=527;break a}}else{if(va){Ca=Pd(W)|0;if((Ca|0)==0){ea=0;fa=0;ga=527;break a}else{Qa=0;Ra=W;Sa=Ca}while(1){Ca=Qa;do{Ba=c[j>>2]|0;if(Ba>>>0<(c[w>>2]|0)>>>0){c[j>>2]=Ba+1;Ua=d[Ba>>0]|0}else{Ua=Ud(s)|0}if((a[p+(Ua+1)>>0]|0)==0){Na=Ca;Oa=Sa;Pa=0;break f}a[Sa+Ca>>0]=Ua;Ca=Ca+1|0}while((Ca|0)!=(Ra|0));Ca=Ra<<1|1;Ba=Rd(Sa,Ca)|0;if((Ba|0)==0){ea=Sa;fa=0;ga=527;break a}else{za=Ra;Ra=Ca;Sa=Ba;Qa=za}}}if((O|0)==0){za=ra;while(1){Ba=c[j>>2]|0;if(Ba>>>0>>0){c[j>>2]=Ba+1;Va=d[Ba>>0]|0}else{Va=Ud(s)|0}if((a[p+(Va+1)>>0]|0)==0){Na=0;Oa=0;Pa=0;break f}za=c[w>>2]|0}}else{za=ra;Ba=0;while(1){Ca=c[j>>2]|0;if(Ca>>>0>>0){c[j>>2]=Ca+1;Wa=d[Ca>>0]|0}else{Wa=Ud(s)|0}if((a[p+(Wa+1)>>0]|0)==0){Na=Ba;Oa=O;Pa=0;break f}a[O+Ba>>0]=Wa;za=c[w>>2]|0;Ba=Ba+1|0}}}}while(0);W=c[j>>2]|0;if((c[w>>2]|0)==0){Xa=W}else{Ba=W+ -1|0;c[j>>2]=Ba;Xa=Ba}Ba=Xa-(c[y>>2]|0)+(c[x>>2]|0)|0;if((Ba|0)==0){ea=Oa;fa=Pa;ga=527;break a}if(!((Ba|0)==(na|0)|U^1)){ea=Oa;fa=Pa;ga=527;break a}do{if(va){if(wa){c[O>>2]=Pa;break}else{c[O>>2]=Oa;break}}}while(0);if(U){Ya=sa;Za=Oa;_a=Pa}else{if((Pa|0)!=0){c[Pa+(Na<<2)>>2]=0}if((Oa|0)==0){Ya=sa;Za=0;_a=Pa;break d}a[Oa+Na>>0]=0;Ya=sa;Za=Oa;_a=Pa}break};case 120:case 88:case 112:{$a=16;ga=150;break};case 117:case 100:{$a=10;ga=150;break};case 111:{$a=8;ga=150;break};case 105:{$a=0;ga=150;break};case 71:case 103:case 70:case 102:case 69:case 101:case 65:case 97:{if((N|0)==1){ab=53;bb=-1074;ga=240}else if((N|0)==2){ab=53;bb=-1074;ga=240}else if((N|0)==0){ab=24;bb=-149;ga=240}else{cb=0.0}i:do{if((ga|0)==240){ga=0;wa=ra;while(1){va=c[j>>2]|0;if(va>>>0>>0){c[j>>2]=va+1;db=d[va>>0]|0}else{db=Ud(s)|0}if(!((db|0)==32|(db+ -9|0)>>>0<5)){break}wa=c[w>>2]|0}do{if((db|0)==43|(db|0)==45){wa=1-(((db|0)==45&1)<<1)|0;va=c[j>>2]|0;if(va>>>0<(c[w>>2]|0)>>>0){c[j>>2]=va+1;eb=d[va>>0]|0;fb=wa;break}else{eb=Ud(s)|0;fb=wa;break}}else{eb=db;fb=1}}while(0);wa=eb;va=0;while(1){if((wa|32|0)!=(a[13048+va>>0]|0)){gb=wa;hb=va;break}do{if(va>>>0<7){Ba=c[j>>2]|0;if(Ba>>>0<(c[w>>2]|0)>>>0){c[j>>2]=Ba+1;ib=d[Ba>>0]|0;break}else{ib=Ud(s)|0;break}}else{ib=wa}}while(0);Ba=va+1|0;if(Ba>>>0<8){wa=ib;va=Ba}else{gb=ib;hb=Ba;break}}j:do{if((hb|0)==0){va=gb;wa=0;while(1){if((va|32|0)!=(a[13632+wa>>0]|0)){jb=va;kb=wa;break j}do{if(wa>>>0<2){Ba=c[j>>2]|0;if(Ba>>>0<(c[w>>2]|0)>>>0){c[j>>2]=Ba+1;lb=d[Ba>>0]|0;break}else{lb=Ud(s)|0;break}}else{lb=va}}while(0);Ba=wa+1|0;if(Ba>>>0<3){va=lb;wa=Ba}else{jb=lb;kb=Ba;break}}}else if((hb|0)==3){if((c[w>>2]|0)==0){ga=260}else{c[j>>2]=(c[j>>2]|0)+ -1;ga=260}}else if((hb|0)==8){ga=260}else{jb=gb;kb=hb}}while(0);if((ga|0)==260){ga=0;cb=+(fb|0)*u;break}if((kb|0)==0){do{if((jb|0)==48){wa=c[j>>2]|0;if(wa>>>0<(c[w>>2]|0)>>>0){c[j>>2]=wa+1;mb=d[wa>>0]|0}else{mb=Ud(s)|0}if((mb|32|0)!=120){if((c[w>>2]|0)==0){nb=48;break}c[j>>2]=(c[j>>2]|0)+ -1;nb=48;break}wa=c[j>>2]|0;if(wa>>>0<(c[w>>2]|0)>>>0){c[j>>2]=wa+1;ob=d[wa>>0]|0;pb=0}else{ob=Ud(s)|0;pb=0}while(1){if((ob|0)==46){ga=298;break}else if((ob|0)!=48){qb=0;rb=0;sb=0;tb=0;ub=ob;vb=pb;wb=0;xb=0;yb=1.0;zb=0;Ab=0.0;break}wa=c[j>>2]|0;if(wa>>>0<(c[w>>2]|0)>>>0){c[j>>2]=wa+1;ob=d[wa>>0]|0;pb=1;continue}else{ob=Ud(s)|0;pb=1;continue}}k:do{if((ga|0)==298){ga=0;wa=c[j>>2]|0;if(wa>>>0<(c[w>>2]|0)>>>0){c[j>>2]=wa+1;Bb=d[wa>>0]|0}else{Bb=Ud(s)|0}if((Bb|0)==48){Cb=-1;Db=-1}else{qb=0;rb=0;sb=0;tb=0;ub=Bb;vb=pb;wb=1;xb=0;yb=1.0;zb=0;Ab=0.0;break}while(1){wa=c[j>>2]|0;if(wa>>>0<(c[w>>2]|0)>>>0){c[j>>2]=wa+1;Eb=d[wa>>0]|0}else{Eb=Ud(s)|0}if((Eb|0)!=48){qb=0;rb=0;sb=Cb;tb=Db;ub=Eb;vb=1;wb=1;xb=0;yb=1.0;zb=0;Ab=0.0;break k}wa=ee(Cb|0,Db|0,-1,-1)|0;Cb=wa;Db=E}}}while(0);l:while(1){wa=ub+ -48|0;do{if(!(wa>>>0<10)){va=ub|32;Ba=(ub|0)==46;if(!((va+ -97|0)>>>0<6|Ba)){Fb=ub;break l}if(Ba){if((wb|0)==0){Gb=rb;Hb=qb;Ib=rb;Jb=qb;Kb=vb;Lb=1;Mb=xb;Nb=yb;Ob=zb;Pb=Ab;break}else{Fb=46;break l}}else{Qb=(ub|0)>57?va+ -87|0:wa;ga=312;break}}else{Qb=wa;ga=312}}while(0);if((ga|0)==312){ga=0;do{if((qb|0)<0|(qb|0)==0&rb>>>0<8){Rb=xb;Sb=yb;Tb=Qb+(zb<<4)|0;Ub=Ab}else{if((qb|0)<0|(qb|0)==0&rb>>>0<14){Vb=yb*.0625;Rb=xb;Sb=Vb;Tb=zb;Ub=Ab+Vb*+(Qb|0);break}if(!((Qb|0)!=0&(xb|0)==0)){Rb=xb;Sb=yb;Tb=zb;Ub=Ab;break}Rb=1;Sb=yb;Tb=zb;Ub=Ab+yb*.5}}while(0);wa=ee(rb|0,qb|0,1,0)|0;Gb=sb;Hb=tb;Ib=wa;Jb=E;Kb=1;Lb=wb;Mb=Rb;Nb=Sb;Ob=Tb;Pb=Ub}wa=c[j>>2]|0;if(wa>>>0<(c[w>>2]|0)>>>0){c[j>>2]=wa+1;qb=Jb;rb=Ib;sb=Gb;tb=Hb;ub=d[wa>>0]|0;vb=Kb;wb=Lb;xb=Mb;yb=Nb;zb=Ob;Ab=Pb;continue}else{qb=Jb;rb=Ib;sb=Gb;tb=Hb;ub=Ud(s)|0;vb=Kb;wb=Lb;xb=Mb;yb=Nb;zb=Ob;Ab=Pb;continue}}if((vb|0)==0){wa=c[j>>2]|0;if((c[w>>2]|0)==0){Wb=wa}else{va=wa+ -1|0;c[j>>2]=va;Wb=va}c[F>>2]=0;va=c[y>>2]|0;c[x>>2]=va-Wb;c[w>>2]=va;cb=+(fb|0)*0.0;break i}va=(wb|0)==0;wa=va?rb:sb;Ba=va?qb:tb;if((qb|0)<0|(qb|0)==0&rb>>>0<8){va=rb;W=qb;za=zb;while(1){Ca=za<<4;va=ee(va|0,W|0,1,0)|0;W=E;if(!((W|0)<0|(W|0)==0&va>>>0<8)){Xb=Ca;break}else{za=Ca}}}else{Xb=zb}do{if((Fb|32|0)==112){za=Td(s,0)|0;va=E;if(!((za|0)==0&(va|0)==-2147483648)){Yb=za;Zb=va;break}c[F>>2]=0;va=c[y>>2]|0;c[x>>2]=va-(c[j>>2]|0);c[w>>2]=va;cb=0.0;break i}else{if((c[w>>2]|0)==0){Yb=0;Zb=0;break}c[j>>2]=(c[j>>2]|0)+ -1;Yb=0;Zb=0}}while(0);va=je(wa|0,Ba|0,2)|0;za=ee(va|0,E|0,-32,-1)|0;va=ee(za|0,E|0,Yb|0,Zb|0)|0;za=E;if((Xb|0)==0){cb=+(fb|0)*0.0;break i}if((za|0)>0|(za|0)==0&va>>>0>(0-bb|0)>>>0){c[(ic()|0)>>2]=34;cb=+(fb|0)*1.7976931348623157e+308*1.7976931348623157e+308;break i}W=bb+ -106|0;Ca=((W|0)<0)<<31>>31;if((za|0)<(Ca|0)|(za|0)==(Ca|0)&va>>>0>>0){c[(ic()|0)>>2]=34;cb=+(fb|0)*2.2250738585072014e-308*2.2250738585072014e-308;break i}if((Xb|0)>-1){W=va;Ca=za;S=Xb;Vb=Ab;while(1){Da=S<<1;if(!(Vb>=.5)){_b=Vb;$b=Da}else{_b=Vb+-1.0;$b=Da|1}ac=Vb+_b;Da=ee(W|0,Ca|0,-1,-1)|0;M=E;if(($b|0)>-1){W=Da;Ca=M;S=$b;Vb=ac}else{bc=Da;cc=M;dc=$b;ec=ac;break}}}else{bc=va;cc=za;dc=Xb;ec=Ab}S=de(32,0,bb|0,((bb|0)<0)<<31>>31|0)|0;Ca=ee(bc|0,cc|0,S|0,E|0)|0;S=E;if(0>(S|0)|0==(S|0)&ab>>>0>Ca>>>0){fc=(Ca|0)<0?0:Ca}else{fc=ab}do{if((fc|0)<53){Ca=84-fc|0;do{if((Ca|0)>1023){S=Ca+ -1023|0;if((S|0)<=1023){gc=S;hc=8.98846567431158e+307;break}S=Ca+ -2046|0;gc=(S|0)>1023?1023:S;hc=u}else{if(!((Ca|0)<-1022)){gc=Ca;hc=1.0;break}S=Ca+1022|0;if(!((S|0)<-1022)){gc=S;hc=2.2250738585072014e-308;break}S=Ca+2044|0;gc=(S|0)<-1022?-1022:S;hc=0.0}}while(0);Ca=je(gc+1023|0,0,52)|0;S=E;c[k>>2]=Ca;c[k+4>>2]=S;Vb=+(fb|0);ac=+lc(+(hc*+h[k>>3]),+Vb);if(!((fc|0)<32&ec!=0.0)){jc=Vb;kc=ac;mc=dc;nc=ec;break}S=dc&1;jc=Vb;kc=ac;mc=(S^1)+dc|0;nc=(S|0)==0?0.0:ec}else{jc=+(fb|0);kc=0.0;mc=dc;nc=ec}}while(0);ac=jc*nc+(kc+jc*+(mc>>>0))-kc;if(!(ac!=0.0)){c[(ic()|0)>>2]=34}do{if((bc|0)>1023){Vb=ac*8.98846567431158e+307;za=bc+ -1023|0;if((za|0)<=1023){oc=za;pc=Vb;break}za=bc+ -2046|0;oc=(za|0)>1023?1023:za;pc=Vb*8.98846567431158e+307}else{if(!((bc|0)<-1022)){oc=bc;pc=ac;break}Vb=ac*2.2250738585072014e-308;za=bc+1022|0;if(!((za|0)<-1022)){oc=za;pc=Vb;break}za=bc+2044|0;oc=(za|0)<-1022?-1022:za;pc=Vb*2.2250738585072014e-308}}while(0);za=je(oc+1023|0,0,52)|0;va=E;c[k>>2]=za;c[k+4>>2]=va;cb=pc*+h[k>>3];break i}else{nb=jb}}while(0);va=bb+ab|0;za=0-va|0;S=nb;Ca=0;while(1){if((S|0)==46){ga=371;break}else if((S|0)!=48){qc=S;rc=0;sc=0;tc=Ca;uc=0;break}W=c[j>>2]|0;if(W>>>0<(c[w>>2]|0)>>>0){c[j>>2]=W+1;S=d[W>>0]|0;Ca=1;continue}else{S=Ud(s)|0;Ca=1;continue}}m:do{if((ga|0)==371){ga=0;S=c[j>>2]|0;if(S>>>0<(c[w>>2]|0)>>>0){c[j>>2]=S+1;vc=d[S>>0]|0}else{vc=Ud(s)|0}if((vc|0)==48){S=-1;W=-1;while(1){Ba=c[j>>2]|0;if(Ba>>>0<(c[w>>2]|0)>>>0){c[j>>2]=Ba+1;wc=d[Ba>>0]|0}else{wc=Ud(s)|0}if((wc|0)!=48){qc=wc;rc=S;sc=W;tc=1;uc=1;break m}Ba=ee(S|0,W|0,-1,-1)|0;S=Ba;W=E}}else{qc=vc;rc=0;sc=0;tc=Ca;uc=1}}}while(0);c[m>>2]=0;Ca=qc+ -48|0;W=(qc|0)==46;n:do{if(Ca>>>0<10|W){S=qc;Ba=W;wa=Ca;M=rc;Da=sc;V=0;Ea=0;xc=tc;yc=uc;zc=0;Ac=0;Bc=0;while(1){do{if(Ba){if((yc|0)==0){Cc=V;Dc=Ea;Ec=V;Fc=Ea;Gc=xc;Hc=1;Ic=zc;Jc=Ac;Kc=Bc}else{Lc=S;Mc=M;Nc=Da;Oc=V;Pc=Ea;Qc=xc;Rc=zc;Sc=Ac;Tc=Bc;break n}}else{Uc=ee(V|0,Ea|0,1,0)|0;Vc=E;Wc=(S|0)!=48;if((Ac|0)>=125){if(!Wc){Cc=M;Dc=Da;Ec=Uc;Fc=Vc;Gc=xc;Hc=yc;Ic=zc;Jc=Ac;Kc=Bc;break}c[G>>2]=c[G>>2]|1;Cc=M;Dc=Da;Ec=Uc;Fc=Vc;Gc=xc;Hc=yc;Ic=zc;Jc=Ac;Kc=Bc;break}Xc=m+(Ac<<2)|0;if((zc|0)==0){Yc=wa}else{Yc=S+ -48+((c[Xc>>2]|0)*10|0)|0}c[Xc>>2]=Yc;Xc=zc+1|0;Zc=(Xc|0)==9;Cc=M;Dc=Da;Ec=Uc;Fc=Vc;Gc=1;Hc=yc;Ic=Zc?0:Xc;Jc=(Zc&1)+Ac|0;Kc=Wc?Uc:Bc}}while(0);Uc=c[j>>2]|0;if(Uc>>>0<(c[w>>2]|0)>>>0){c[j>>2]=Uc+1;_c=d[Uc>>0]|0}else{_c=Ud(s)|0}wa=_c+ -48|0;Ba=(_c|0)==46;if(!(wa>>>0<10|Ba)){$c=_c;ad=Ec;bd=Cc;cd=Fc;dd=Dc;ed=Gc;fd=Hc;gd=Ic;hd=Jc;id=Kc;ga=393;break}else{S=_c;M=Cc;Da=Dc;V=Ec;Ea=Fc;xc=Gc;yc=Hc;zc=Ic;Ac=Jc;Bc=Kc}}}else{$c=qc;ad=0;bd=rc;cd=0;dd=sc;ed=tc;fd=uc;gd=0;hd=0;id=0;ga=393}}while(0);if((ga|0)==393){ga=0;Ca=(fd|0)==0;Lc=$c;Mc=Ca?ad:bd;Nc=Ca?cd:dd;Oc=ad;Pc=cd;Qc=ed;Rc=gd;Sc=hd;Tc=id}Ca=(Qc|0)!=0;do{if(Ca){if((Lc|32|0)!=101){ga=399;break}W=Td(s,0)|0;Bc=E;if((W|0)==0&(Bc|0)==-2147483648){c[F>>2]=0;Ac=c[y>>2]|0;c[x>>2]=Ac-(c[j>>2]|0);c[w>>2]=Ac;cb=0.0;break i}else{Ac=ee(W|0,Bc|0,Mc|0,Nc|0)|0;jd=Ac;kd=E;break}}else{ga=399}}while(0);do{if((ga|0)==399){ga=0;if(!((Lc|0)>-1)){jd=Mc;kd=Nc;break}if((c[w>>2]|0)==0){jd=Mc;kd=Nc;break}c[j>>2]=(c[j>>2]|0)+ -1;jd=Mc;kd=Nc}}while(0);if(!Ca){c[(ic()|0)>>2]=22;c[F>>2]=0;Ac=c[y>>2]|0;c[x>>2]=Ac-(c[j>>2]|0);c[w>>2]=Ac;cb=0.0;break}Ac=c[m>>2]|0;if((Ac|0)==0){cb=+(fb|0)*0.0;break}do{if((jd|0)==(Oc|0)&(kd|0)==(Pc|0)&((Pc|0)<0|(Pc|0)==0&Oc>>>0<10)){if(!(ab>>>0>30)?(Ac>>>ab|0)!=0:0){break}cb=+(fb|0)*+(Ac>>>0);break i}}while(0);Ac=(bb|0)/-2|0;Ca=((Ac|0)<0)<<31>>31;if((kd|0)>(Ca|0)|(kd|0)==(Ca|0)&jd>>>0>Ac>>>0){c[(ic()|0)>>2]=34;cb=+(fb|0)*1.7976931348623157e+308*1.7976931348623157e+308;break}Ac=bb+ -106|0;Ca=((Ac|0)<0)<<31>>31;if((kd|0)<(Ca|0)|(kd|0)==(Ca|0)&jd>>>0>>0){c[(ic()|0)>>2]=34;cb=+(fb|0)*2.2250738585072014e-308*2.2250738585072014e-308;break}if((Rc|0)==0){ld=Sc}else{if((Rc|0)<9){Ac=m+(Sc<<2)|0;Ca=c[Ac>>2]|0;Bc=Rc;do{Ca=Ca*10|0;Bc=Bc+1|0}while((Bc|0)!=9);c[Ac>>2]=Ca}ld=Sc+1|0}do{if((Tc|0)<9){if(!((Tc|0)<=(jd|0)&(jd|0)<18)){break}if((jd|0)==9){cb=+(fb|0)*+((c[m>>2]|0)>>>0);break i}if((jd|0)<9){cb=+(fb|0)*+((c[m>>2]|0)>>>0)/+(c[13072+(8-jd<<2)>>2]|0);break i}Bc=ab+27+(aa(jd,-3)|0)|0;W=c[m>>2]|0;if((Bc|0)<=30?(W>>>Bc|0)!=0:0){break}cb=+(fb|0)*+(W>>>0)*+(c[13072+(jd+ -10<<2)>>2]|0);break i}}while(0);Ca=(jd|0)%9|0;if((Ca|0)==0){md=0;nd=0;od=jd;pd=ld}else{Ac=(jd|0)>-1?Ca:Ca+9|0;Ca=c[13072+(8-Ac<<2)>>2]|0;do{if((ld|0)==0){qd=0;rd=jd;sd=0}else{W=1e9/(Ca|0)|0;Bc=0;zc=0;yc=0;xc=jd;while(1){Ea=m+(yc<<2)|0;V=c[Ea>>2]|0;Da=((V>>>0)/(Ca>>>0)|0)+zc|0;c[Ea>>2]=Da;zc=aa((V>>>0)%(Ca>>>0)|0,W)|0;V=yc;yc=yc+1|0;if((V|0)==(Bc|0)&(Da|0)==0){td=yc&127;ud=xc+ -9|0}else{td=Bc;ud=xc}if((yc|0)==(ld|0)){break}else{Bc=td;xc=ud}}if((zc|0)==0){qd=td;rd=ud;sd=ld;break}c[m+(ld<<2)>>2]=zc;qd=td;rd=ud;sd=ld+1|0}}while(0);md=qd;nd=0;od=9-Ac+rd|0;pd=sd}o:while(1){Ca=m+(md<<2)|0;if((od|0)<18){xc=nd;Bc=pd;while(1){yc=0;W=Bc+127|0;Da=Bc;while(1){V=W&127;Ea=m+(V<<2)|0;M=je(c[Ea>>2]|0,0,29)|0;S=ee(M|0,E|0,yc|0,0)|0;M=E;if(M>>>0>0|(M|0)==0&S>>>0>1e9){Ba=re(S|0,M|0,1e9,0)|0;wa=se(S|0,M|0,1e9,0)|0;vd=wa;wd=Ba}else{vd=S;wd=0}c[Ea>>2]=vd;Ea=(V|0)==(md|0);if((V|0)!=(Da+127&127|0)|Ea){xd=Da}else{xd=(vd|0)==0?V:Da}if(Ea){break}else{yc=wd;W=V+ -1|0;Da=xd}}Da=xc+ -29|0;if((wd|0)==0){xc=Da;Bc=xd}else{yd=Da;zd=wd;Ad=xd;break}}}else{if((od|0)==18){Bd=nd;Cd=pd}else{Dd=md;Ed=nd;Fd=od;Gd=pd;break}while(1){if(!((c[Ca>>2]|0)>>>0<9007199)){Dd=md;Ed=Bd;Fd=18;Gd=Cd;break o}Bc=0;xc=Cd+127|0;zc=Cd;while(1){Da=xc&127;W=m+(Da<<2)|0;yc=je(c[W>>2]|0,0,29)|0;V=ee(yc|0,E|0,Bc|0,0)|0;yc=E;if(yc>>>0>0|(yc|0)==0&V>>>0>1e9){Ea=re(V|0,yc|0,1e9,0)|0;S=se(V|0,yc|0,1e9,0)|0;Hd=S;Id=Ea}else{Hd=V;Id=0}c[W>>2]=Hd;W=(Da|0)==(md|0);if((Da|0)!=(zc+127&127|0)|W){Jd=zc}else{Jd=(Hd|0)==0?Da:zc}if(W){break}else{Bc=Id;xc=Da+ -1|0;zc=Jd}}zc=Bd+ -29|0;if((Id|0)==0){Bd=zc;Cd=Jd}else{yd=zc;zd=Id;Ad=Jd;break}}}Ca=md+127&127;if((Ca|0)==(Ad|0)){zc=Ad+127&127;xc=m+((Ad+126&127)<<2)|0;c[xc>>2]=c[xc>>2]|c[m+(zc<<2)>>2];Kd=zc}else{Kd=Ad}c[m+(Ca<<2)>>2]=zd;md=Ca;nd=yd;od=od+9|0;pd=Kd}p:while(1){Md=Gd+1&127;Ac=m+((Gd+127&127)<<2)|0;Ca=Dd;zc=Ed;xc=Fd;while(1){Bc=(xc|0)==18;Da=(xc|0)>27?9:1;Nd=Ca;Od=zc;while(1){W=0;while(1){V=W+Nd&127;if((V|0)==(Gd|0)){Sd=2;break}Ea=c[m+(V<<2)>>2]|0;V=c[13064+(W<<2)>>2]|0;if(Ea>>>0>>0){Sd=2;break}S=W+1|0;if(Ea>>>0>V>>>0){Sd=W;break}if((S|0)<2){W=S}else{Sd=S;break}}if((Sd|0)==2&Bc){break p}Vd=Da+Od|0;if((Nd|0)==(Gd|0)){Nd=Gd;Od=Vd}else{break}}Bc=(1<>>Da;Wd=Nd;Xd=0;S=Nd;Yd=xc;do{V=m+(S<<2)|0;Ea=c[V>>2]|0;yc=(Ea>>>Da)+Xd|0;c[V>>2]=yc;Xd=aa(Ea&Bc,W)|0;Ea=(S|0)==(Wd|0)&(yc|0)==0;S=S+1&127;Yd=Ea?Yd+ -9|0:Yd;Wd=Ea?S:Wd}while((S|0)!=(Gd|0));if((Xd|0)==0){Ca=Wd;zc=Vd;xc=Yd;continue}if((Md|0)!=(Wd|0)){break}c[Ac>>2]=c[Ac>>2]|1;Ca=Wd;zc=Vd;xc=Yd}c[m+(Gd<<2)>>2]=Xd;Dd=Wd;Ed=Vd;Fd=Yd;Gd=Md}xc=Nd&127;if((xc|0)==(Gd|0)){c[m+(Md+ -1<<2)>>2]=0;Zd=Md}else{Zd=Gd}ac=+((c[m+(xc<<2)>>2]|0)>>>0);xc=Nd+1&127;if((xc|0)==(Zd|0)){zc=Zd+1&127;c[m+(zc+ -1<<2)>>2]=0;_d=zc}else{_d=Zd}Vb=+(fb|0);$d=Vb*(ac*1.0e9+ +((c[m+(xc<<2)>>2]|0)>>>0));xc=Od+53|0;zc=xc-bb|0;if((zc|0)<(ab|0)){ae=(zc|0)<0?0:zc;be=1}else{ae=ab;be=0}if((ae|0)<53){Ca=105-ae|0;do{if((Ca|0)>1023){Ac=Ca+ -1023|0;if((Ac|0)<=1023){ce=Ac;fe=8.98846567431158e+307;break}Ac=Ca+ -2046|0;ce=(Ac|0)>1023?1023:Ac;fe=u}else{if(!((Ca|0)<-1022)){ce=Ca;fe=1.0;break}Ac=Ca+1022|0;if(!((Ac|0)<-1022)){ce=Ac;fe=2.2250738585072014e-308;break}Ac=Ca+2044|0;ce=(Ac|0)<-1022?-1022:Ac;fe=0.0}}while(0);Ca=je(ce+1023|0,0,52)|0;Ac=E;c[k>>2]=Ca;c[k+4>>2]=Ac;ac=+lc(+(fe*+h[k>>3]),+$d);Ac=53-ae|0;do{if((Ac|0)>1023){Ca=Ac+ -1023|0;if((Ca|0)<=1023){ie=Ca;ke=8.98846567431158e+307;break}Ca=Ac+ -2046|0;ie=(Ca|0)>1023?1023:Ca;ke=u}else{if(!((Ac|0)<-1022)){ie=Ac;ke=1.0;break}Ca=Ac+1022|0;if(!((Ca|0)<-1022)){ie=Ca;ke=2.2250738585072014e-308;break}Ca=Ac+2044|0;ie=(Ca|0)<-1022?-1022:Ca;ke=0.0}}while(0);Ac=je(ie+1023|0,0,52)|0;Ca=E;c[k>>2]=Ac;c[k+4>>2]=Ca;le=+Ta(+$d,+(ke*+h[k>>3]));me=ac;ne=le;oe=ac+($d-le)}else{me=0.0;ne=0.0;oe=$d}Ca=Nd+2&127;do{if((Ca|0)==(_d|0)){pe=ne}else{Ac=c[m+(Ca<<2)>>2]|0;do{if(!(Ac>>>0<5e8)){if(Ac>>>0>5e8){te=Vb*.75+ne;break}if((Nd+3&127|0)==(_d|0)){te=Vb*.5+ne;break}else{te=Vb*.75+ne;break}}else{if((Ac|0)==0?(Nd+3&127|0)==(_d|0):0){te=ne;break}te=Vb*.25+ne}}while(0);if((53-ae|0)<=1){pe=te;break}if(+Ta(+te,1.0)!=0.0){pe=te;break}pe=te+1.0}}while(0);Vb=oe+pe-me;do{if((xc&2147483647|0)>(-2-va|0)){if(!(+P(+Vb)>=9007199254740992.0)){ue=be;ve=Od;we=Vb}else{ue=(be|0)!=0&(ae|0)==(zc|0)?0:be;ve=Od+1|0;we=Vb*.5}if((ve+50|0)<=(za|0)?!((ue|0)!=0&pe!=0.0):0){xe=ve;ye=we;break}c[(ic()|0)>>2]=34;xe=ve;ye=we}else{xe=Od;ye=Vb}}while(0);do{if((xe|0)>1023){Vb=ye*8.98846567431158e+307;za=xe+ -1023|0;if((za|0)<=1023){ze=za;Ae=Vb;break}za=xe+ -2046|0;ze=(za|0)>1023?1023:za;Ae=Vb*8.98846567431158e+307}else{if(!((xe|0)<-1022)){ze=xe;Ae=ye;break}Vb=ye*2.2250738585072014e-308;za=xe+1022|0;if(!((za|0)<-1022)){ze=za;Ae=Vb;break}za=xe+2044|0;ze=(za|0)<-1022?-1022:za;Ae=Vb*2.2250738585072014e-308}}while(0);za=je(ze+1023|0,0,52)|0;zc=E;c[k>>2]=za;c[k+4>>2]=zc;cb=Ae*+h[k>>3];break}else if((kb|0)==3){zc=c[j>>2]|0;if(zc>>>0<(c[w>>2]|0)>>>0){c[j>>2]=zc+1;Be=d[zc>>0]|0}else{Be=Ud(s)|0}if((Be|0)!=40){if((c[w>>2]|0)==0){cb=t;break}c[j>>2]=(c[j>>2]|0)+ -1;cb=t;break}while(1){zc=c[j>>2]|0;if(zc>>>0<(c[w>>2]|0)>>>0){c[j>>2]=zc+1;Ce=d[zc>>0]|0}else{Ce=Ud(s)|0}if((Ce+ -48|0)>>>0<10|(Ce+ -65|0)>>>0<26){continue}if(!((Ce+ -97|0)>>>0<26|(Ce|0)==95)){break}}if((Ce|0)==41){cb=t;break}zc=c[j>>2]|0;if((c[w>>2]|0)==0){De=zc}else{za=zc+ -1|0;c[j>>2]=za;De=za}c[(ic()|0)>>2]=22;c[F>>2]=0;za=c[y>>2]|0;c[x>>2]=za-De;c[w>>2]=za;cb=0.0;break}else{za=c[j>>2]|0;if((c[w>>2]|0)==0){Ee=za}else{zc=za+ -1|0;c[j>>2]=zc;Ee=zc}c[(ic()|0)>>2]=22;c[F>>2]=0;zc=c[y>>2]|0;c[x>>2]=zc-Ee;c[w>>2]=zc;cb=0.0;break}}}while(0);if((c[x>>2]|0)==((c[y>>2]|0)-(c[j>>2]|0)|0)){ea=J;fa=K;ga=527;break a}if((O|0)!=0){if((N|0)==1){h[O>>3]=cb;Ya=ca;Za=J;_a=K;break d}else if((N|0)==0){g[O>>2]=cb;Ya=ca;Za=J;_a=K;break d}else if((N|0)==2){h[O>>3]=cb;Ya=ca;Za=J;_a=K;break d}else{Ya=ca;Za=J;_a=K;break d}}else{Ya=ca;Za=J;_a=K}break};default:{Ya=ca;Za=J;_a=K}}}while(0);q:do{if((ga|0)==150){ga=0;U=ra;while(1){zc=c[j>>2]|0;if(zc>>>0>>0){c[j>>2]=zc+1;Fe=d[zc>>0]|0}else{Fe=Ud(s)|0}if(!((Fe|0)==32|(Fe+ -9|0)>>>0<5)){break}U=c[w>>2]|0}do{if((Fe|0)==43|(Fe|0)==45){U=((Fe|0)==45)<<31>>31;zc=c[j>>2]|0;if(zc>>>0<(c[w>>2]|0)>>>0){c[j>>2]=zc+1;Ge=d[zc>>0]|0;He=U;break}else{Ge=Ud(s)|0;He=U;break}}else{Ge=Fe;He=0}}while(0);U=($a|0)==0;do{if(($a&10|0)==0&(Ge|0)==48){zc=c[j>>2]|0;if(zc>>>0<(c[w>>2]|0)>>>0){c[j>>2]=zc+1;Ie=d[zc>>0]|0}else{Ie=Ud(s)|0}if((Ie|32|0)!=120){Je=U?8:$a;Ke=Ie;ga=177;break}zc=c[j>>2]|0;if(zc>>>0<(c[w>>2]|0)>>>0){c[j>>2]=zc+1;Le=d[zc>>0]|0}else{Le=Ud(s)|0}if((d[Le+12769>>0]|0)>15){zc=c[j>>2]|0;if((c[w>>2]|0)==0){Me=zc}else{za=zc+ -1|0;c[j>>2]=za;Me=za}c[F>>2]=0;za=c[y>>2]|0;c[x>>2]=za-Me;c[w>>2]=za;Ne=Me;Oe=za;Pe=0;Qe=0}else{Re=16;Se=Le;ga=192}}else{za=U?10:$a;if((d[Ge+12769>>0]|0)>>>0>>0){Je=za;Ke=Ge;ga=177}else{za=c[j>>2]|0;if((c[w>>2]|0)==0){Te=za}else{zc=za+ -1|0;c[j>>2]=zc;Te=zc}c[F>>2]=0;zc=c[y>>2]|0;c[x>>2]=zc-Te;c[w>>2]=zc;c[(ic()|0)>>2]=22;Ne=Te;Oe=zc;Pe=0;Qe=0}}}while(0);if((ga|0)==177){ga=0;if((Je|0)==10){U=Ke+ -48|0;if(U>>>0<10){zc=U;U=0;while(1){Ue=U+zc|0;za=c[j>>2]|0;if(za>>>0<(c[w>>2]|0)>>>0){c[j>>2]=za+1;Ve=d[za>>0]|0}else{Ve=Ud(s)|0}za=Ve+ -48|0;if(!(za>>>0<10&Ue>>>0<429496729)){break}zc=za;U=Ue*10|0}We=Ue;Xe=0;Ye=Ve}else{We=0;Xe=0;Ye=Ke}U=Ye+ -48|0;if(U>>>0<10){zc=We;za=Xe;va=U;U=Ye;while(1){xc=qe(zc|0,za|0,10,0)|0;Ca=E;Ac=((va|0)<0)<<31>>31;S=~Ac;if(Ca>>>0>S>>>0|(Ca|0)==(S|0)&xc>>>0>~va>>>0){Ze=va;_e=zc;$e=za;af=U;break}S=ee(xc|0,Ca|0,va|0,Ac|0)|0;Ac=E;Ca=c[j>>2]|0;if(Ca>>>0<(c[w>>2]|0)>>>0){c[j>>2]=Ca+1;bf=d[Ca>>0]|0}else{bf=Ud(s)|0}Ca=bf+ -48|0;if(Ca>>>0<10&(Ac>>>0<429496729|(Ac|0)==429496729&S>>>0<2576980378)){zc=S;za=Ac;va=Ca;U=bf}else{Ze=Ca;_e=S;$e=Ac;af=bf;break}}if(Ze>>>0>9){cf=_e;df=$e;ga=224}else{ef=10;ff=_e;gf=$e;hf=af;ga=218}}else{cf=We;df=Xe;ga=224}}else{Re=Je;Se=Ke;ga=192}}r:do{if((ga|0)==192){ga=0;if((Re+ -1&Re|0)==0){U=a[13032+((Re*23|0)>>>5&7)>>0]|0;va=a[Se+12769>>0]|0;za=va&255;if(za>>>0>>0){zc=za;za=0;do{za=zc|za<>2]|0;if(Ac>>>0<(c[w>>2]|0)>>>0){c[j>>2]=Ac+1;jf=d[Ac>>0]|0}else{jf=Ud(s)|0}kf=a[jf+12769>>0]|0;zc=kf&255}while(zc>>>0>>0&za>>>0<134217728);lf=kf;mf=0;nf=za;of=jf}else{lf=va;mf=0;nf=0;of=Se}zc=ge(-1,-1,U|0)|0;Ac=E;if((lf&255)>>>0>=Re>>>0|(mf>>>0>Ac>>>0|(mf|0)==(Ac|0)&nf>>>0>zc>>>0)){ef=Re;ff=nf;gf=mf;hf=of;ga=218;break}else{pf=nf;qf=mf;rf=lf}while(1){S=je(pf|0,qf|0,U|0)|0;Ca=E;xc=rf&255|S;S=c[j>>2]|0;if(S>>>0<(c[w>>2]|0)>>>0){c[j>>2]=S+1;sf=d[S>>0]|0}else{sf=Ud(s)|0}rf=a[sf+12769>>0]|0;if((rf&255)>>>0>=Re>>>0|(Ca>>>0>Ac>>>0|(Ca|0)==(Ac|0)&xc>>>0>zc>>>0)){ef=Re;ff=xc;gf=Ca;hf=sf;ga=218;break r}else{pf=xc;qf=Ca}}}zc=a[Se+12769>>0]|0;Ac=zc&255;if(Ac>>>0>>0){U=Ac;Ac=0;do{Ac=U+(aa(Ac,Re)|0)|0;va=c[j>>2]|0;if(va>>>0<(c[w>>2]|0)>>>0){c[j>>2]=va+1;tf=d[va>>0]|0}else{tf=Ud(s)|0}uf=a[tf+12769>>0]|0;U=uf&255}while(U>>>0>>0&Ac>>>0<119304647);vf=Ac;wf=0;xf=uf;yf=tf}else{vf=0;wf=0;xf=zc;yf=Se}if((xf&255)>>>0>>0){U=re(-1,-1,Re|0,0)|0;va=E;za=wf;Ca=vf;xc=xf;S=yf;while(1){if(za>>>0>va>>>0|(za|0)==(va|0)&Ca>>>0>U>>>0){ef=Re;ff=Ca;gf=za;hf=S;ga=218;break r}W=qe(Ca|0,za|0,Re|0,0)|0;Bc=E;Da=xc&255;if(Bc>>>0>4294967295|(Bc|0)==-1&W>>>0>~Da>>>0){ef=Re;ff=Ca;gf=za;hf=S;ga=218;break r}Ea=ee(Da|0,0,W|0,Bc|0)|0;Bc=E;W=c[j>>2]|0;if(W>>>0<(c[w>>2]|0)>>>0){c[j>>2]=W+1;zf=d[W>>0]|0}else{zf=Ud(s)|0}xc=a[zf+12769>>0]|0;if(!((xc&255)>>>0>>0)){ef=Re;ff=Ea;gf=Bc;hf=zf;ga=218;break}else{za=Bc;Ca=Ea;S=zf}}}else{ef=Re;ff=vf;gf=wf;hf=yf;ga=218}}}while(0);if((ga|0)==218){ga=0;if((d[hf+12769>>0]|0)>>>0>>0){do{S=c[j>>2]|0;if(S>>>0<(c[w>>2]|0)>>>0){c[j>>2]=S+1;Af=d[S>>0]|0}else{Af=Ud(s)|0}}while((d[Af+12769>>0]|0)>>>0>>0);c[(ic()|0)>>2]=34;cf=-1;df=-1;ga=224}else{cf=ff;df=gf;ga=224}}if((ga|0)==224){ga=0;S=c[j>>2]|0;if((c[w>>2]|0)==0){Bf=S}else{Ca=S+ -1|0;c[j>>2]=Ca;Bf=Ca}Ca=((He|0)<0)<<31>>31;S=de(cf^He|0,df^Ca|0,He|0,Ca|0)|0;Ne=Bf;Oe=c[y>>2]|0;Pe=S;Qe=E}if((c[x>>2]|0)==(Oe-Ne|0)){ea=J;fa=K;ga=527;break a}S=(O|0)==0;if(!((R|0)!=112|S)){c[O>>2]=Pe;Ya=ca;Za=J;_a=K;break}if(S){Ya=ca;Za=J;_a=K}else{switch(N|0){case-2:{a[O>>0]=Pe;Ya=ca;Za=J;_a=K;break q;break};case-1:{b[O>>1]=Pe;Ya=ca;Za=J;_a=K;break q;break};case 3:{S=O;c[S>>2]=Pe;c[S+4>>2]=Qe;Ya=ca;Za=J;_a=K;break q;break};case 1:{c[O>>2]=Pe;Ya=ca;Za=J;_a=K;break q;break};case 0:{c[O>>2]=Pe;Ya=ca;Za=J;_a=K;break q;break};default:{Ya=ca;Za=J;_a=K;break q}}}}}while(0);ha=((O|0)!=0&1)+e|0;ia=Ya;ja=(c[x>>2]|0)+ma+(c[j>>2]|0)-(c[y>>2]|0)|0;ka=Za;la=_a;break b}}while(0);N=I+(L&1)|0;c[F>>2]=0;R=c[y>>2]|0;S=c[j>>2]|0;c[x>>2]=R-S;c[w>>2]=R;if(S>>>0>>0){c[j>>2]=S+1;Cf=d[S>>0]|0}else{Cf=Ud(s)|0}if((Cf|0)!=(d[N>>0]|0)){ga=22;break a}ha=e;ia=N;ja=f+1|0;ka=J;la=K}else{Df=I;ga=5}}while(0);if((ga|0)==5){while(1){ga=0;N=Df+1|0;S=a[N>>0]|0;if(S<<24>>24==32){Df=N;ga=5;continue}if(((S&255)+ -9|0)>>>0<5){Df=N;ga=5}else{break}}c[F>>2]=0;N=c[y>>2]|0;S=c[j>>2]|0;c[x>>2]=N-S;c[w>>2]=N;R=S;S=N;while(1){if(R>>>0>>0){c[j>>2]=R+1;Ef=d[R>>0]|0}else{Ef=Ud(s)|0}if(!((Ef|0)==32|(Ef+ -9|0)>>>0<5)){break}R=c[j>>2]|0;S=c[w>>2]|0}S=c[j>>2]|0;if((c[w>>2]|0)==0){Ff=S}else{R=S+ -1|0;c[j>>2]=R;Ff=R}ha=e;ia=Df;ja=(c[x>>2]|0)+f+Ff-(c[y>>2]|0)|0;ka=J;la=K}I=ia+1|0;H=a[I>>0]|0;if(H<<24>>24==0){ga=529;break}else{e=ha;f=ja;J=ka;K=la}}if((ga|0)==22){if((c[w>>2]|0)==0){i=l;return}c[j>>2]=(c[j>>2]|0)+ -1;i=l;return}else if((ga|0)==527){if(($|0)==0){i=l;return}Qd(ea);Qd(fa);i=l;return}else if((ga|0)==529){i=l;return}}function Od(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;d=i;e=Md(a,b,c)|0;i=d;return e|0}function Pd(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,Aa=0,Ba=0,Ca=0,Da=0,Fa=0,Ga=0,Ha=0,Ia=0,Ja=0,Ka=0,La=0;b=i;do{if(a>>>0<245){if(a>>>0<11){d=16}else{d=a+11&-8}e=d>>>3;f=c[3068]|0;g=f>>>e;if((g&3|0)!=0){h=(g&1^1)+e|0;j=h<<1;k=12312+(j<<2)|0;l=12312+(j+2<<2)|0;j=c[l>>2]|0;m=j+8|0;n=c[m>>2]|0;do{if((k|0)!=(n|0)){if(n>>>0<(c[12288>>2]|0)>>>0){Mb()}o=n+12|0;if((c[o>>2]|0)==(j|0)){c[o>>2]=k;c[l>>2]=n;break}else{Mb()}}else{c[3068]=f&~(1<>2]=n|3;l=j+(n|4)|0;c[l>>2]=c[l>>2]|1;p=m;i=b;return p|0}if(d>>>0>(c[12280>>2]|0)>>>0){if((g|0)!=0){l=2<>>12&16;k=l>>>n;l=k>>>5&8;o=k>>>l;k=o>>>2&4;q=o>>>k;o=q>>>1&2;r=q>>>o;q=r>>>1&1;s=(l|n|k|o|q)+(r>>>q)|0;q=s<<1;r=12312+(q<<2)|0;o=12312+(q+2<<2)|0;q=c[o>>2]|0;k=q+8|0;n=c[k>>2]|0;do{if((r|0)!=(n|0)){if(n>>>0<(c[12288>>2]|0)>>>0){Mb()}l=n+12|0;if((c[l>>2]|0)==(q|0)){c[l>>2]=r;c[o>>2]=n;break}else{Mb()}}else{c[3068]=f&~(1<>2]=d|3;o=q+d|0;c[q+(d|4)>>2]=n|1;c[q+f>>2]=n;f=c[12280>>2]|0;if((f|0)!=0){r=c[12292>>2]|0;e=f>>>3;f=e<<1;g=12312+(f<<2)|0;m=c[3068]|0;j=1<>2]|0;if(h>>>0<(c[12288>>2]|0)>>>0){Mb()}else{t=e;u=h}}else{c[3068]=m|j;t=12312+(f+2<<2)|0;u=g}c[t>>2]=r;c[u+12>>2]=r;c[r+8>>2]=u;c[r+12>>2]=g}c[12280>>2]=n;c[12292>>2]=o;p=k;i=b;return p|0}o=c[12276>>2]|0;if((o|0)!=0){n=(o&0-o)+ -1|0;o=n>>>12&16;g=n>>>o;n=g>>>5&8;r=g>>>n;g=r>>>2&4;f=r>>>g;r=f>>>1&2;j=f>>>r;f=j>>>1&1;m=c[12576+((n|o|g|r|f)+(j>>>f)<<2)>>2]|0;f=(c[m+4>>2]&-8)-d|0;j=m;r=m;while(1){m=c[j+16>>2]|0;if((m|0)==0){g=c[j+20>>2]|0;if((g|0)==0){break}else{v=g}}else{v=m}m=(c[v+4>>2]&-8)-d|0;g=m>>>0>>0;f=g?m:f;j=v;r=g?v:r}j=c[12288>>2]|0;if(r>>>0>>0){Mb()}k=r+d|0;if(!(r>>>0>>0)){Mb()}q=c[r+24>>2]|0;s=c[r+12>>2]|0;do{if((s|0)==(r|0)){g=r+20|0;m=c[g>>2]|0;if((m|0)==0){o=r+16|0;n=c[o>>2]|0;if((n|0)==0){w=0;break}else{x=n;y=o}}else{x=m;y=g}while(1){g=x+20|0;m=c[g>>2]|0;if((m|0)!=0){x=m;y=g;continue}g=x+16|0;m=c[g>>2]|0;if((m|0)==0){break}else{x=m;y=g}}if(y>>>0>>0){Mb()}else{c[y>>2]=0;w=x;break}}else{g=c[r+8>>2]|0;if(g>>>0>>0){Mb()}m=g+12|0;if((c[m>>2]|0)!=(r|0)){Mb()}o=s+8|0;if((c[o>>2]|0)==(r|0)){c[m>>2]=s;c[o>>2]=g;w=s;break}else{Mb()}}}while(0);do{if((q|0)!=0){s=c[r+28>>2]|0;j=12576+(s<<2)|0;if((r|0)==(c[j>>2]|0)){c[j>>2]=w;if((w|0)==0){c[12276>>2]=c[12276>>2]&~(1<>>0<(c[12288>>2]|0)>>>0){Mb()}s=q+16|0;if((c[s>>2]|0)==(r|0)){c[s>>2]=w}else{c[q+20>>2]=w}if((w|0)==0){break}}if(w>>>0<(c[12288>>2]|0)>>>0){Mb()}c[w+24>>2]=q;s=c[r+16>>2]|0;do{if((s|0)!=0){if(s>>>0<(c[12288>>2]|0)>>>0){Mb()}else{c[w+16>>2]=s;c[s+24>>2]=w;break}}}while(0);s=c[r+20>>2]|0;if((s|0)!=0){if(s>>>0<(c[12288>>2]|0)>>>0){Mb()}else{c[w+20>>2]=s;c[s+24>>2]=w;break}}}}while(0);if(f>>>0<16){q=f+d|0;c[r+4>>2]=q|3;s=r+(q+4)|0;c[s>>2]=c[s>>2]|1}else{c[r+4>>2]=d|3;c[r+(d|4)>>2]=f|1;c[r+(f+d)>>2]=f;s=c[12280>>2]|0;if((s|0)!=0){q=c[12292>>2]|0;j=s>>>3;s=j<<1;g=12312+(s<<2)|0;o=c[3068]|0;m=1<>2]|0;if(n>>>0<(c[12288>>2]|0)>>>0){Mb()}else{z=j;A=n}}else{c[3068]=o|m;z=12312+(s+2<<2)|0;A=g}c[z>>2]=q;c[A+12>>2]=q;c[q+8>>2]=A;c[q+12>>2]=g}c[12280>>2]=f;c[12292>>2]=k}p=r+8|0;i=b;return p|0}else{B=d}}else{B=d}}else{if(!(a>>>0>4294967231)){g=a+11|0;q=g&-8;s=c[12276>>2]|0;if((s|0)!=0){m=0-q|0;o=g>>>8;if((o|0)!=0){if(q>>>0>16777215){C=31}else{g=(o+1048320|0)>>>16&8;n=o<>>16&4;j=n<>>16&2;h=14-(o|g|n)+(j<>>15)|0;C=q>>>(h+7|0)&1|h<<1}}else{C=0}h=c[12576+(C<<2)>>2]|0;a:do{if((h|0)==0){D=m;E=0;F=0}else{if((C|0)==31){G=0}else{G=25-(C>>>1)|0}n=m;j=0;g=q<>2]&-8;H=l-q|0;if(H>>>0>>0){if((l|0)==(q|0)){D=H;E=o;F=o;break a}else{I=H;J=o}}else{I=n;J=e}H=c[o+20>>2]|0;o=c[o+(g>>>31<<2)+16>>2]|0;l=(H|0)==0|(H|0)==(o|0)?j:H;if((o|0)==0){D=I;E=l;F=J;break}else{n=I;j=l;g=g<<1;e=J}}}}while(0);if((E|0)==0&(F|0)==0){h=2<>>12&16;r=h>>>m;h=r>>>5&8;k=r>>>h;r=k>>>2&4;f=k>>>r;k=f>>>1&2;e=f>>>k;f=e>>>1&1;K=c[12576+((h|m|r|k|f)+(e>>>f)<<2)>>2]|0}else{K=E}if((K|0)==0){L=D;M=F}else{f=D;e=K;k=F;while(1){r=(c[e+4>>2]&-8)-q|0;m=r>>>0>>0;h=m?r:f;r=m?e:k;m=c[e+16>>2]|0;if((m|0)!=0){f=h;e=m;k=r;continue}e=c[e+20>>2]|0;if((e|0)==0){L=h;M=r;break}else{f=h;k=r}}}if((M|0)!=0?L>>>0<((c[12280>>2]|0)-q|0)>>>0:0){k=c[12288>>2]|0;if(M>>>0>>0){Mb()}f=M+q|0;if(!(M>>>0>>0)){Mb()}e=c[M+24>>2]|0;s=c[M+12>>2]|0;do{if((s|0)==(M|0)){r=M+20|0;h=c[r>>2]|0;if((h|0)==0){m=M+16|0;g=c[m>>2]|0;if((g|0)==0){N=0;break}else{O=g;P=m}}else{O=h;P=r}while(1){r=O+20|0;h=c[r>>2]|0;if((h|0)!=0){O=h;P=r;continue}r=O+16|0;h=c[r>>2]|0;if((h|0)==0){break}else{O=h;P=r}}if(P>>>0>>0){Mb()}else{c[P>>2]=0;N=O;break}}else{r=c[M+8>>2]|0;if(r>>>0>>0){Mb()}h=r+12|0;if((c[h>>2]|0)!=(M|0)){Mb()}m=s+8|0;if((c[m>>2]|0)==(M|0)){c[h>>2]=s;c[m>>2]=r;N=s;break}else{Mb()}}}while(0);do{if((e|0)!=0){s=c[M+28>>2]|0;k=12576+(s<<2)|0;if((M|0)==(c[k>>2]|0)){c[k>>2]=N;if((N|0)==0){c[12276>>2]=c[12276>>2]&~(1<>>0<(c[12288>>2]|0)>>>0){Mb()}s=e+16|0;if((c[s>>2]|0)==(M|0)){c[s>>2]=N}else{c[e+20>>2]=N}if((N|0)==0){break}}if(N>>>0<(c[12288>>2]|0)>>>0){Mb()}c[N+24>>2]=e;s=c[M+16>>2]|0;do{if((s|0)!=0){if(s>>>0<(c[12288>>2]|0)>>>0){Mb()}else{c[N+16>>2]=s;c[s+24>>2]=N;break}}}while(0);s=c[M+20>>2]|0;if((s|0)!=0){if(s>>>0<(c[12288>>2]|0)>>>0){Mb()}else{c[N+20>>2]=s;c[s+24>>2]=N;break}}}}while(0);b:do{if(!(L>>>0<16)){c[M+4>>2]=q|3;c[M+(q|4)>>2]=L|1;c[M+(L+q)>>2]=L;e=L>>>3;if(L>>>0<256){s=e<<1;k=12312+(s<<2)|0;r=c[3068]|0;m=1<>2]|0;if(!(h>>>0<(c[12288>>2]|0)>>>0)){Q=e;R=h;break}Mb()}}while(0);c[Q>>2]=f;c[R+12>>2]=f;c[M+(q+8)>>2]=R;c[M+(q+12)>>2]=k;break}s=L>>>8;if((s|0)!=0){if(L>>>0>16777215){S=31}else{m=(s+1048320|0)>>>16&8;r=s<>>16&4;h=r<>>16&2;e=14-(s|m|r)+(h<>>15)|0;S=L>>>(e+7|0)&1|e<<1}}else{S=0}e=12576+(S<<2)|0;c[M+(q+28)>>2]=S;c[M+(q+20)>>2]=0;c[M+(q+16)>>2]=0;r=c[12276>>2]|0;h=1<>2]=r|h;c[e>>2]=f;c[M+(q+24)>>2]=e;c[M+(q+12)>>2]=f;c[M+(q+8)>>2]=f;break}h=c[e>>2]|0;if((S|0)==31){T=0}else{T=25-(S>>>1)|0}c:do{if((c[h+4>>2]&-8|0)!=(L|0)){e=L<>>31<<2)+16|0;m=c[U>>2]|0;if((m|0)==0){break}if((c[m+4>>2]&-8|0)==(L|0)){V=m;break c}else{e=e<<1;r=m}}if(U>>>0<(c[12288>>2]|0)>>>0){Mb()}else{c[U>>2]=f;c[M+(q+24)>>2]=r;c[M+(q+12)>>2]=f;c[M+(q+8)>>2]=f;break b}}else{V=h}}while(0);h=V+8|0;k=c[h>>2]|0;e=c[12288>>2]|0;if(V>>>0>>0){Mb()}if(k>>>0>>0){Mb()}else{c[k+12>>2]=f;c[h>>2]=f;c[M+(q+8)>>2]=k;c[M+(q+12)>>2]=V;c[M+(q+24)>>2]=0;break}}else{k=L+q|0;c[M+4>>2]=k|3;h=M+(k+4)|0;c[h>>2]=c[h>>2]|1}}while(0);p=M+8|0;i=b;return p|0}else{B=q}}else{B=q}}else{B=-1}}}while(0);M=c[12280>>2]|0;if(!(B>>>0>M>>>0)){L=M-B|0;V=c[12292>>2]|0;if(L>>>0>15){c[12292>>2]=V+B;c[12280>>2]=L;c[V+(B+4)>>2]=L|1;c[V+M>>2]=L;c[V+4>>2]=B|3}else{c[12280>>2]=0;c[12292>>2]=0;c[V+4>>2]=M|3;L=V+(M+4)|0;c[L>>2]=c[L>>2]|1}p=V+8|0;i=b;return p|0}V=c[12284>>2]|0;if(B>>>0>>0){L=V-B|0;c[12284>>2]=L;V=c[12296>>2]|0;c[12296>>2]=V+B;c[V+(B+4)>>2]=L|1;c[V+4>>2]=B|3;p=V+8|0;i=b;return p|0}do{if((c[3186]|0)==0){V=Ea(30)|0;if((V+ -1&V|0)==0){c[12752>>2]=V;c[12748>>2]=V;c[12756>>2]=-1;c[12760>>2]=-1;c[12764>>2]=0;c[12716>>2]=0;c[3186]=(lb(0)|0)&-16^1431655768;break}else{Mb()}}}while(0);V=B+48|0;L=c[12752>>2]|0;M=B+47|0;U=L+M|0;T=0-L|0;L=U&T;if(!(L>>>0>B>>>0)){p=0;i=b;return p|0}S=c[12712>>2]|0;if((S|0)!=0?(R=c[12704>>2]|0,Q=R+L|0,Q>>>0<=R>>>0|Q>>>0>S>>>0):0){p=0;i=b;return p|0}d:do{if((c[12716>>2]&4|0)==0){S=c[12296>>2]|0;e:do{if((S|0)!=0){Q=12720|0;while(1){R=c[Q>>2]|0;if(!(R>>>0>S>>>0)?(W=Q+4|0,(R+(c[W>>2]|0)|0)>>>0>S>>>0):0){break}R=c[Q+8>>2]|0;if((R|0)==0){X=182;break e}else{Q=R}}if((Q|0)!=0){R=U-(c[12284>>2]|0)&T;if(R>>>0<2147483647){N=za(R|0)|0;O=(N|0)==((c[Q>>2]|0)+(c[W>>2]|0)|0);Y=N;Z=R;_=O?N:-1;$=O?R:0;X=191}else{aa=0}}else{X=182}}else{X=182}}while(0);do{if((X|0)==182){S=za(0)|0;if((S|0)!=(-1|0)){q=S;R=c[12748>>2]|0;O=R+ -1|0;if((O&q|0)==0){ba=L}else{ba=L-q+(O+q&0-R)|0}R=c[12704>>2]|0;q=R+ba|0;if(ba>>>0>B>>>0&ba>>>0<2147483647){O=c[12712>>2]|0;if((O|0)!=0?q>>>0<=R>>>0|q>>>0>O>>>0:0){aa=0;break}O=za(ba|0)|0;q=(O|0)==(S|0);Y=O;Z=ba;_=q?S:-1;$=q?ba:0;X=191}else{aa=0}}else{aa=0}}}while(0);f:do{if((X|0)==191){q=0-Z|0;if((_|0)!=(-1|0)){ca=_;da=$;X=202;break d}do{if((Y|0)!=(-1|0)&Z>>>0<2147483647&Z>>>0>>0?(S=c[12752>>2]|0,O=M-Z+S&0-S,O>>>0<2147483647):0){if((za(O|0)|0)==(-1|0)){za(q|0)|0;aa=$;break f}else{ea=O+Z|0;break}}else{ea=Z}}while(0);if((Y|0)==(-1|0)){aa=$}else{ca=Y;da=ea;X=202;break d}}}while(0);c[12716>>2]=c[12716>>2]|4;fa=aa;X=199}else{fa=0;X=199}}while(0);if((((X|0)==199?L>>>0<2147483647:0)?(aa=za(L|0)|0,L=za(0)|0,(L|0)!=(-1|0)&(aa|0)!=(-1|0)&aa>>>0>>0):0)?(ea=L-aa|0,L=ea>>>0>(B+40|0)>>>0,L):0){ca=aa;da=L?ea:fa;X=202}if((X|0)==202){fa=(c[12704>>2]|0)+da|0;c[12704>>2]=fa;if(fa>>>0>(c[12708>>2]|0)>>>0){c[12708>>2]=fa}fa=c[12296>>2]|0;g:do{if((fa|0)!=0){ea=12720|0;while(1){ga=c[ea>>2]|0;ha=ea+4|0;ia=c[ha>>2]|0;if((ca|0)==(ga+ia|0)){X=214;break}L=c[ea+8>>2]|0;if((L|0)==0){break}else{ea=L}}if(((X|0)==214?(c[ea+12>>2]&8|0)==0:0)?fa>>>0>=ga>>>0&fa>>>0>>0:0){c[ha>>2]=ia+da;L=(c[12284>>2]|0)+da|0;aa=fa+8|0;if((aa&7|0)==0){ja=0}else{ja=0-aa&7}aa=L-ja|0;c[12296>>2]=fa+ja;c[12284>>2]=aa;c[fa+(ja+4)>>2]=aa|1;c[fa+(L+4)>>2]=40;c[12300>>2]=c[12760>>2];break}if(ca>>>0<(c[12288>>2]|0)>>>0){c[12288>>2]=ca}L=ca+da|0;aa=12720|0;while(1){if((c[aa>>2]|0)==(L|0)){X=224;break}Y=c[aa+8>>2]|0;if((Y|0)==0){break}else{aa=Y}}if((X|0)==224?(c[aa+12>>2]&8|0)==0:0){c[aa>>2]=ca;L=aa+4|0;c[L>>2]=(c[L>>2]|0)+da;L=ca+8|0;if((L&7|0)==0){ka=0}else{ka=0-L&7}L=ca+(da+8)|0;if((L&7|0)==0){la=0}else{la=0-L&7}L=ca+(la+da)|0;ea=ka+B|0;Y=ca+ea|0;$=L-(ca+ka)-B|0;c[ca+(ka+4)>>2]=B|3;h:do{if((L|0)!=(c[12296>>2]|0)){if((L|0)==(c[12292>>2]|0)){Z=(c[12280>>2]|0)+$|0;c[12280>>2]=Z;c[12292>>2]=Y;c[ca+(ea+4)>>2]=Z|1;c[ca+(Z+ea)>>2]=Z;break}Z=da+4|0;M=c[ca+(Z+la)>>2]|0;if((M&3|0)==1){V=M&-8;_=M>>>3;i:do{if(!(M>>>0<256)){ba=c[ca+((la|24)+da)>>2]|0;W=c[ca+(da+12+la)>>2]|0;do{if((W|0)==(L|0)){T=la|16;U=ca+(Z+T)|0;q=c[U>>2]|0;if((q|0)==0){Q=ca+(T+da)|0;T=c[Q>>2]|0;if((T|0)==0){ma=0;break}else{na=T;oa=Q}}else{na=q;oa=U}while(1){U=na+20|0;q=c[U>>2]|0;if((q|0)!=0){na=q;oa=U;continue}U=na+16|0;q=c[U>>2]|0;if((q|0)==0){break}else{na=q;oa=U}}if(oa>>>0<(c[12288>>2]|0)>>>0){Mb()}else{c[oa>>2]=0;ma=na;break}}else{U=c[ca+((la|8)+da)>>2]|0;if(U>>>0<(c[12288>>2]|0)>>>0){Mb()}q=U+12|0;if((c[q>>2]|0)!=(L|0)){Mb()}Q=W+8|0;if((c[Q>>2]|0)==(L|0)){c[q>>2]=W;c[Q>>2]=U;ma=W;break}else{Mb()}}}while(0);if((ba|0)==0){break}W=c[ca+(da+28+la)>>2]|0;r=12576+(W<<2)|0;do{if((L|0)!=(c[r>>2]|0)){if(ba>>>0<(c[12288>>2]|0)>>>0){Mb()}U=ba+16|0;if((c[U>>2]|0)==(L|0)){c[U>>2]=ma}else{c[ba+20>>2]=ma}if((ma|0)==0){break i}}else{c[r>>2]=ma;if((ma|0)!=0){break}c[12276>>2]=c[12276>>2]&~(1<>>0<(c[12288>>2]|0)>>>0){Mb()}c[ma+24>>2]=ba;W=la|16;r=c[ca+(W+da)>>2]|0;do{if((r|0)!=0){if(r>>>0<(c[12288>>2]|0)>>>0){Mb()}else{c[ma+16>>2]=r;c[r+24>>2]=ma;break}}}while(0);r=c[ca+(Z+W)>>2]|0;if((r|0)==0){break}if(r>>>0<(c[12288>>2]|0)>>>0){Mb()}else{c[ma+20>>2]=r;c[r+24>>2]=ma;break}}else{r=c[ca+((la|8)+da)>>2]|0;ba=c[ca+(da+12+la)>>2]|0;U=12312+(_<<1<<2)|0;do{if((r|0)!=(U|0)){if(r>>>0<(c[12288>>2]|0)>>>0){Mb()}if((c[r+12>>2]|0)==(L|0)){break}Mb()}}while(0);if((ba|0)==(r|0)){c[3068]=c[3068]&~(1<<_);break}do{if((ba|0)==(U|0)){pa=ba+8|0}else{if(ba>>>0<(c[12288>>2]|0)>>>0){Mb()}W=ba+8|0;if((c[W>>2]|0)==(L|0)){pa=W;break}Mb()}}while(0);c[r+12>>2]=ba;c[pa>>2]=r}}while(0);qa=ca+((V|la)+da)|0;ra=V+$|0}else{qa=L;ra=$}_=qa+4|0;c[_>>2]=c[_>>2]&-2;c[ca+(ea+4)>>2]=ra|1;c[ca+(ra+ea)>>2]=ra;_=ra>>>3;if(ra>>>0<256){Z=_<<1;M=12312+(Z<<2)|0;U=c[3068]|0;W=1<<_;do{if((U&W|0)==0){c[3068]=U|W;sa=12312+(Z+2<<2)|0;ta=M}else{_=12312+(Z+2<<2)|0;Q=c[_>>2]|0;if(!(Q>>>0<(c[12288>>2]|0)>>>0)){sa=_;ta=Q;break}Mb()}}while(0);c[sa>>2]=Y;c[ta+12>>2]=Y;c[ca+(ea+8)>>2]=ta;c[ca+(ea+12)>>2]=M;break}Z=ra>>>8;do{if((Z|0)==0){ua=0}else{if(ra>>>0>16777215){ua=31;break}W=(Z+1048320|0)>>>16&8;U=Z<>>16&4;Q=U<>>16&2;_=14-(V|W|U)+(Q<>>15)|0;ua=ra>>>(_+7|0)&1|_<<1}}while(0);Z=12576+(ua<<2)|0;c[ca+(ea+28)>>2]=ua;c[ca+(ea+20)>>2]=0;c[ca+(ea+16)>>2]=0;M=c[12276>>2]|0;_=1<>2]=M|_;c[Z>>2]=Y;c[ca+(ea+24)>>2]=Z;c[ca+(ea+12)>>2]=Y;c[ca+(ea+8)>>2]=Y;break}_=c[Z>>2]|0;if((ua|0)==31){va=0}else{va=25-(ua>>>1)|0}j:do{if((c[_+4>>2]&-8|0)!=(ra|0)){Z=ra<>>31<<2)+16|0;U=c[wa>>2]|0;if((U|0)==0){break}if((c[U+4>>2]&-8|0)==(ra|0)){xa=U;break j}else{Z=Z<<1;M=U}}if(wa>>>0<(c[12288>>2]|0)>>>0){Mb()}else{c[wa>>2]=Y;c[ca+(ea+24)>>2]=M;c[ca+(ea+12)>>2]=Y;c[ca+(ea+8)>>2]=Y;break h}}else{xa=_}}while(0);_=xa+8|0;Z=c[_>>2]|0;r=c[12288>>2]|0;if(xa>>>0>>0){Mb()}if(Z>>>0>>0){Mb()}else{c[Z+12>>2]=Y;c[_>>2]=Y;c[ca+(ea+8)>>2]=Z;c[ca+(ea+12)>>2]=xa;c[ca+(ea+24)>>2]=0;break}}else{Z=(c[12284>>2]|0)+$|0;c[12284>>2]=Z;c[12296>>2]=Y;c[ca+(ea+4)>>2]=Z|1}}while(0);p=ca+(ka|8)|0;i=b;return p|0}ea=12720|0;while(1){ya=c[ea>>2]|0;if(!(ya>>>0>fa>>>0)?(Aa=c[ea+4>>2]|0,Ba=ya+Aa|0,Ba>>>0>fa>>>0):0){break}ea=c[ea+8>>2]|0}ea=ya+(Aa+ -39)|0;if((ea&7|0)==0){Ca=0}else{Ca=0-ea&7}ea=ya+(Aa+ -47+Ca)|0;Y=ea>>>0<(fa+16|0)>>>0?fa:ea;ea=Y+8|0;$=ca+8|0;if(($&7|0)==0){Da=0}else{Da=0-$&7}$=da+ -40-Da|0;c[12296>>2]=ca+Da;c[12284>>2]=$;c[ca+(Da+4)>>2]=$|1;c[ca+(da+ -36)>>2]=40;c[12300>>2]=c[12760>>2];c[Y+4>>2]=27;c[ea+0>>2]=c[12720>>2];c[ea+4>>2]=c[12724>>2];c[ea+8>>2]=c[12728>>2];c[ea+12>>2]=c[12732>>2];c[12720>>2]=ca;c[12724>>2]=da;c[12732>>2]=0;c[12728>>2]=ea;ea=Y+28|0;c[ea>>2]=7;if((Y+32|0)>>>0>>0){$=ea;do{ea=$;$=$+4|0;c[$>>2]=7}while((ea+8|0)>>>0>>0)}if((Y|0)!=(fa|0)){$=Y-fa|0;ea=fa+($+4)|0;c[ea>>2]=c[ea>>2]&-2;c[fa+4>>2]=$|1;c[fa+$>>2]=$;ea=$>>>3;if($>>>0<256){L=ea<<1;aa=12312+(L<<2)|0;Z=c[3068]|0;_=1<>2]|0;if(!(r>>>0<(c[12288>>2]|0)>>>0)){Fa=ea;Ga=r;break}Mb()}}while(0);c[Fa>>2]=fa;c[Ga+12>>2]=fa;c[fa+8>>2]=Ga;c[fa+12>>2]=aa;break}L=$>>>8;if((L|0)!=0){if($>>>0>16777215){Ha=31}else{_=(L+1048320|0)>>>16&8;Z=L<<_;L=(Z+520192|0)>>>16&4;Y=Z<>>16&2;r=14-(L|_|Z)+(Y<>>15)|0;Ha=$>>>(r+7|0)&1|r<<1}}else{Ha=0}r=12576+(Ha<<2)|0;c[fa+28>>2]=Ha;c[fa+20>>2]=0;c[fa+16>>2]=0;Z=c[12276>>2]|0;Y=1<>2]=Z|Y;c[r>>2]=fa;c[fa+24>>2]=r;c[fa+12>>2]=fa;c[fa+8>>2]=fa;break}Y=c[r>>2]|0;if((Ha|0)==31){Ia=0}else{Ia=25-(Ha>>>1)|0}k:do{if((c[Y+4>>2]&-8|0)!=($|0)){r=$<>>31<<2)+16|0;_=c[Ja>>2]|0;if((_|0)==0){break}if((c[_+4>>2]&-8|0)==($|0)){Ka=_;break k}else{r=r<<1;Z=_}}if(Ja>>>0<(c[12288>>2]|0)>>>0){Mb()}else{c[Ja>>2]=fa;c[fa+24>>2]=Z;c[fa+12>>2]=fa;c[fa+8>>2]=fa;break g}}else{Ka=Y}}while(0);Y=Ka+8|0;$=c[Y>>2]|0;aa=c[12288>>2]|0;if(Ka>>>0>>0){Mb()}if($>>>0>>0){Mb()}else{c[$+12>>2]=fa;c[Y>>2]=fa;c[fa+8>>2]=$;c[fa+12>>2]=Ka;c[fa+24>>2]=0;break}}}else{$=c[12288>>2]|0;if(($|0)==0|ca>>>0<$>>>0){c[12288>>2]=ca}c[12720>>2]=ca;c[12724>>2]=da;c[12732>>2]=0;c[12308>>2]=c[3186];c[12304>>2]=-1;$=0;do{Y=$<<1;aa=12312+(Y<<2)|0;c[12312+(Y+3<<2)>>2]=aa;c[12312+(Y+2<<2)>>2]=aa;$=$+1|0}while(($|0)!=32);$=ca+8|0;if(($&7|0)==0){La=0}else{La=0-$&7}$=da+ -40-La|0;c[12296>>2]=ca+La;c[12284>>2]=$;c[ca+(La+4)>>2]=$|1;c[ca+(da+ -36)>>2]=40;c[12300>>2]=c[12760>>2]}}while(0);da=c[12284>>2]|0;if(da>>>0>B>>>0){ca=da-B|0;c[12284>>2]=ca;da=c[12296>>2]|0;c[12296>>2]=da+B;c[da+(B+4)>>2]=ca|1;c[da+4>>2]=B|3;p=da+8|0;i=b;return p|0}}c[(ic()|0)>>2]=12;p=0;i=b;return p|0}function Qd(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0;b=i;if((a|0)==0){i=b;return}d=a+ -8|0;e=c[12288>>2]|0;if(d>>>0>>0){Mb()}f=c[a+ -4>>2]|0;g=f&3;if((g|0)==1){Mb()}h=f&-8;j=a+(h+ -8)|0;do{if((f&1|0)==0){k=c[d>>2]|0;if((g|0)==0){i=b;return}l=-8-k|0;m=a+l|0;n=k+h|0;if(m>>>0>>0){Mb()}if((m|0)==(c[12292>>2]|0)){o=a+(h+ -4)|0;if((c[o>>2]&3|0)!=3){p=m;q=n;break}c[12280>>2]=n;c[o>>2]=c[o>>2]&-2;c[a+(l+4)>>2]=n|1;c[j>>2]=n;i=b;return}o=k>>>3;if(k>>>0<256){k=c[a+(l+8)>>2]|0;r=c[a+(l+12)>>2]|0;s=12312+(o<<1<<2)|0;if((k|0)!=(s|0)){if(k>>>0>>0){Mb()}if((c[k+12>>2]|0)!=(m|0)){Mb()}}if((r|0)==(k|0)){c[3068]=c[3068]&~(1<>>0>>0){Mb()}s=r+8|0;if((c[s>>2]|0)==(m|0)){t=s}else{Mb()}}else{t=r+8|0}c[k+12>>2]=r;c[t>>2]=k;p=m;q=n;break}k=c[a+(l+24)>>2]|0;r=c[a+(l+12)>>2]|0;do{if((r|0)==(m|0)){s=a+(l+20)|0;o=c[s>>2]|0;if((o|0)==0){u=a+(l+16)|0;v=c[u>>2]|0;if((v|0)==0){w=0;break}else{x=v;y=u}}else{x=o;y=s}while(1){s=x+20|0;o=c[s>>2]|0;if((o|0)!=0){x=o;y=s;continue}s=x+16|0;o=c[s>>2]|0;if((o|0)==0){break}else{x=o;y=s}}if(y>>>0>>0){Mb()}else{c[y>>2]=0;w=x;break}}else{s=c[a+(l+8)>>2]|0;if(s>>>0>>0){Mb()}o=s+12|0;if((c[o>>2]|0)!=(m|0)){Mb()}u=r+8|0;if((c[u>>2]|0)==(m|0)){c[o>>2]=r;c[u>>2]=s;w=r;break}else{Mb()}}}while(0);if((k|0)!=0){r=c[a+(l+28)>>2]|0;s=12576+(r<<2)|0;if((m|0)==(c[s>>2]|0)){c[s>>2]=w;if((w|0)==0){c[12276>>2]=c[12276>>2]&~(1<>>0<(c[12288>>2]|0)>>>0){Mb()}r=k+16|0;if((c[r>>2]|0)==(m|0)){c[r>>2]=w}else{c[k+20>>2]=w}if((w|0)==0){p=m;q=n;break}}if(w>>>0<(c[12288>>2]|0)>>>0){Mb()}c[w+24>>2]=k;r=c[a+(l+16)>>2]|0;do{if((r|0)!=0){if(r>>>0<(c[12288>>2]|0)>>>0){Mb()}else{c[w+16>>2]=r;c[r+24>>2]=w;break}}}while(0);r=c[a+(l+20)>>2]|0;if((r|0)!=0){if(r>>>0<(c[12288>>2]|0)>>>0){Mb()}else{c[w+20>>2]=r;c[r+24>>2]=w;p=m;q=n;break}}else{p=m;q=n}}else{p=m;q=n}}else{p=d;q=h}}while(0);if(!(p>>>0>>0)){Mb()}d=a+(h+ -4)|0;w=c[d>>2]|0;if((w&1|0)==0){Mb()}if((w&2|0)==0){if((j|0)==(c[12296>>2]|0)){e=(c[12284>>2]|0)+q|0;c[12284>>2]=e;c[12296>>2]=p;c[p+4>>2]=e|1;if((p|0)!=(c[12292>>2]|0)){i=b;return}c[12292>>2]=0;c[12280>>2]=0;i=b;return}if((j|0)==(c[12292>>2]|0)){e=(c[12280>>2]|0)+q|0;c[12280>>2]=e;c[12292>>2]=p;c[p+4>>2]=e|1;c[p+e>>2]=e;i=b;return}e=(w&-8)+q|0;x=w>>>3;do{if(!(w>>>0<256)){y=c[a+(h+16)>>2]|0;t=c[a+(h|4)>>2]|0;do{if((t|0)==(j|0)){g=a+(h+12)|0;f=c[g>>2]|0;if((f|0)==0){r=a+(h+8)|0;k=c[r>>2]|0;if((k|0)==0){z=0;break}else{A=k;B=r}}else{A=f;B=g}while(1){g=A+20|0;f=c[g>>2]|0;if((f|0)!=0){A=f;B=g;continue}g=A+16|0;f=c[g>>2]|0;if((f|0)==0){break}else{A=f;B=g}}if(B>>>0<(c[12288>>2]|0)>>>0){Mb()}else{c[B>>2]=0;z=A;break}}else{g=c[a+h>>2]|0;if(g>>>0<(c[12288>>2]|0)>>>0){Mb()}f=g+12|0;if((c[f>>2]|0)!=(j|0)){Mb()}r=t+8|0;if((c[r>>2]|0)==(j|0)){c[f>>2]=t;c[r>>2]=g;z=t;break}else{Mb()}}}while(0);if((y|0)!=0){t=c[a+(h+20)>>2]|0;n=12576+(t<<2)|0;if((j|0)==(c[n>>2]|0)){c[n>>2]=z;if((z|0)==0){c[12276>>2]=c[12276>>2]&~(1<>>0<(c[12288>>2]|0)>>>0){Mb()}t=y+16|0;if((c[t>>2]|0)==(j|0)){c[t>>2]=z}else{c[y+20>>2]=z}if((z|0)==0){break}}if(z>>>0<(c[12288>>2]|0)>>>0){Mb()}c[z+24>>2]=y;t=c[a+(h+8)>>2]|0;do{if((t|0)!=0){if(t>>>0<(c[12288>>2]|0)>>>0){Mb()}else{c[z+16>>2]=t;c[t+24>>2]=z;break}}}while(0);t=c[a+(h+12)>>2]|0;if((t|0)!=0){if(t>>>0<(c[12288>>2]|0)>>>0){Mb()}else{c[z+20>>2]=t;c[t+24>>2]=z;break}}}}else{t=c[a+h>>2]|0;y=c[a+(h|4)>>2]|0;n=12312+(x<<1<<2)|0;if((t|0)!=(n|0)){if(t>>>0<(c[12288>>2]|0)>>>0){Mb()}if((c[t+12>>2]|0)!=(j|0)){Mb()}}if((y|0)==(t|0)){c[3068]=c[3068]&~(1<>>0<(c[12288>>2]|0)>>>0){Mb()}n=y+8|0;if((c[n>>2]|0)==(j|0)){C=n}else{Mb()}}else{C=y+8|0}c[t+12>>2]=y;c[C>>2]=t}}while(0);c[p+4>>2]=e|1;c[p+e>>2]=e;if((p|0)==(c[12292>>2]|0)){c[12280>>2]=e;i=b;return}else{D=e}}else{c[d>>2]=w&-2;c[p+4>>2]=q|1;c[p+q>>2]=q;D=q}q=D>>>3;if(D>>>0<256){w=q<<1;d=12312+(w<<2)|0;e=c[3068]|0;C=1<>2]|0;if(j>>>0<(c[12288>>2]|0)>>>0){Mb()}else{E=q;F=j}}else{c[3068]=e|C;E=12312+(w+2<<2)|0;F=d}c[E>>2]=p;c[F+12>>2]=p;c[p+8>>2]=F;c[p+12>>2]=d;i=b;return}d=D>>>8;if((d|0)!=0){if(D>>>0>16777215){G=31}else{F=(d+1048320|0)>>>16&8;E=d<>>16&4;w=E<>>16&2;C=14-(d|F|E)+(w<>>15)|0;G=D>>>(C+7|0)&1|C<<1}}else{G=0}C=12576+(G<<2)|0;c[p+28>>2]=G;c[p+20>>2]=0;c[p+16>>2]=0;E=c[12276>>2]|0;w=1<>2]|0;if((G|0)==31){H=0}else{H=25-(G>>>1)|0}b:do{if((c[F+4>>2]&-8|0)!=(D|0)){d=D<>>31<<2)+16|0;j=c[I>>2]|0;if((j|0)==0){break}if((c[j+4>>2]&-8|0)==(D|0)){J=j;break b}else{d=d<<1;e=j}}if(I>>>0<(c[12288>>2]|0)>>>0){Mb()}else{c[I>>2]=p;c[p+24>>2]=e;c[p+12>>2]=p;c[p+8>>2]=p;break a}}else{J=F}}while(0);F=J+8|0;d=c[F>>2]|0;j=c[12288>>2]|0;if(J>>>0>>0){Mb()}if(d>>>0>>0){Mb()}else{c[d+12>>2]=p;c[F>>2]=p;c[p+8>>2]=d;c[p+12>>2]=J;c[p+24>>2]=0;break}}else{c[12276>>2]=E|w;c[C>>2]=p;c[p+24>>2]=C;c[p+12>>2]=p;c[p+8>>2]=p}}while(0);p=(c[12304>>2]|0)+ -1|0;c[12304>>2]=p;if((p|0)==0){K=12728|0}else{i=b;return}while(1){p=c[K>>2]|0;if((p|0)==0){break}else{K=p+8|0}}c[12304>>2]=-1;i=b;return}function Rd(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0;d=i;if((a|0)==0){e=Pd(b)|0;i=d;return e|0}if(b>>>0>4294967231){c[(ic()|0)>>2]=12;e=0;i=d;return e|0}if(b>>>0<11){f=16}else{f=b+11&-8}g=a+ -4|0;h=c[g>>2]|0;j=h&-8;k=j+ -8|0;l=a+k|0;m=c[12288>>2]|0;if((a+ -8|0)>>>0>>0){Mb()}n=h&3;if(!((n|0)!=1&(k|0)>-8)){Mb()}k=j|4;o=a+(k+ -8)|0;p=c[o>>2]|0;if((p&1|0)==0){Mb()}do{if((n|0)==0){if(!(f>>>0<256|j>>>0<(f|4)>>>0)?!((j-f|0)>>>0>c[12752>>2]<<1>>>0):0){e=a;i=d;return e|0}}else{if(!(j>>>0>>0)){q=j-f|0;if(!(q>>>0>15)){e=a;i=d;return e|0}c[g>>2]=h&1|f|2;c[a+((f|4)+ -8)>>2]=q|3;c[o>>2]=c[o>>2]|1;Sd(a+(f+ -8)|0,q);e=a;i=d;return e|0}if((l|0)==(c[12296>>2]|0)){q=(c[12284>>2]|0)+j|0;if(!(q>>>0>f>>>0)){break}r=q-f|0;c[g>>2]=h&1|f|2;c[a+((f|4)+ -8)>>2]=r|1;c[12296>>2]=a+(f+ -8);c[12284>>2]=r;e=a;i=d;return e|0}if((l|0)==(c[12292>>2]|0)){r=(c[12280>>2]|0)+j|0;if(r>>>0>>0){break}q=r-f|0;if(q>>>0>15){c[g>>2]=h&1|f|2;c[a+((f|4)+ -8)>>2]=q|1;c[a+(r+ -8)>>2]=q;s=a+(r+ -4)|0;c[s>>2]=c[s>>2]&-2;t=a+(f+ -8)|0;u=q}else{c[g>>2]=h&1|r|2;q=a+(r+ -4)|0;c[q>>2]=c[q>>2]|1;t=0;u=0}c[12280>>2]=u;c[12292>>2]=t;e=a;i=d;return e|0}if((p&2|0)==0?(q=(p&-8)+j|0,!(q>>>0>>0)):0){r=q-f|0;s=p>>>3;do{if(!(p>>>0<256)){v=c[a+(j+16)>>2]|0;w=c[a+k>>2]|0;do{if((w|0)==(l|0)){x=a+(j+12)|0;y=c[x>>2]|0;if((y|0)==0){z=a+(j+8)|0;A=c[z>>2]|0;if((A|0)==0){B=0;break}else{C=A;D=z}}else{C=y;D=x}while(1){x=C+20|0;y=c[x>>2]|0;if((y|0)!=0){C=y;D=x;continue}x=C+16|0;y=c[x>>2]|0;if((y|0)==0){break}else{C=y;D=x}}if(D>>>0>>0){Mb()}else{c[D>>2]=0;B=C;break}}else{x=c[a+j>>2]|0;if(x>>>0>>0){Mb()}y=x+12|0;if((c[y>>2]|0)!=(l|0)){Mb()}z=w+8|0;if((c[z>>2]|0)==(l|0)){c[y>>2]=w;c[z>>2]=x;B=w;break}else{Mb()}}}while(0);if((v|0)!=0){w=c[a+(j+20)>>2]|0;x=12576+(w<<2)|0;if((l|0)==(c[x>>2]|0)){c[x>>2]=B;if((B|0)==0){c[12276>>2]=c[12276>>2]&~(1<>>0<(c[12288>>2]|0)>>>0){Mb()}w=v+16|0;if((c[w>>2]|0)==(l|0)){c[w>>2]=B}else{c[v+20>>2]=B}if((B|0)==0){break}}if(B>>>0<(c[12288>>2]|0)>>>0){Mb()}c[B+24>>2]=v;w=c[a+(j+8)>>2]|0;do{if((w|0)!=0){if(w>>>0<(c[12288>>2]|0)>>>0){Mb()}else{c[B+16>>2]=w;c[w+24>>2]=B;break}}}while(0);w=c[a+(j+12)>>2]|0;if((w|0)==0){break}if(w>>>0<(c[12288>>2]|0)>>>0){Mb()}else{c[B+20>>2]=w;c[w+24>>2]=B;break}}}else{w=c[a+j>>2]|0;v=c[a+k>>2]|0;x=12312+(s<<1<<2)|0;if((w|0)!=(x|0)){if(w>>>0>>0){Mb()}if((c[w+12>>2]|0)!=(l|0)){Mb()}}if((v|0)==(w|0)){c[3068]=c[3068]&~(1<>>0>>0){Mb()}z=v+8|0;if((c[z>>2]|0)==(l|0)){E=z;break}Mb()}}while(0);c[w+12>>2]=v;c[E>>2]=w}}while(0);if(r>>>0<16){c[g>>2]=q|c[g>>2]&1|2;s=a+((q|4)+ -8)|0;c[s>>2]=c[s>>2]|1;e=a;i=d;return e|0}else{c[g>>2]=c[g>>2]&1|f|2;c[a+((f|4)+ -8)>>2]=r|3;s=a+((q|4)+ -8)|0;c[s>>2]=c[s>>2]|1;Sd(a+(f+ -8)|0,r);e=a;i=d;return e|0}}}}while(0);f=Pd(b)|0;if((f|0)==0){e=0;i=d;return e|0}E=c[g>>2]|0;g=(E&-8)-((E&3|0)==0?8:4)|0;ie(f|0,a|0,(g>>>0>>0?g:b)|0)|0;Qd(a);e=f;i=d;return e|0}function Sd(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0;d=i;e=a+b|0;f=c[a+4>>2]|0;do{if((f&1|0)==0){g=c[a>>2]|0;if((f&3|0)==0){i=d;return}h=a+(0-g)|0;j=g+b|0;k=c[12288>>2]|0;if(h>>>0>>0){Mb()}if((h|0)==(c[12292>>2]|0)){l=a+(b+4)|0;if((c[l>>2]&3|0)!=3){m=h;n=j;break}c[12280>>2]=j;c[l>>2]=c[l>>2]&-2;c[a+(4-g)>>2]=j|1;c[e>>2]=j;i=d;return}l=g>>>3;if(g>>>0<256){o=c[a+(8-g)>>2]|0;p=c[a+(12-g)>>2]|0;q=12312+(l<<1<<2)|0;if((o|0)!=(q|0)){if(o>>>0>>0){Mb()}if((c[o+12>>2]|0)!=(h|0)){Mb()}}if((p|0)==(o|0)){c[3068]=c[3068]&~(1<>>0>>0){Mb()}q=p+8|0;if((c[q>>2]|0)==(h|0)){r=q}else{Mb()}}else{r=p+8|0}c[o+12>>2]=p;c[r>>2]=o;m=h;n=j;break}o=c[a+(24-g)>>2]|0;p=c[a+(12-g)>>2]|0;do{if((p|0)==(h|0)){q=16-g|0;l=a+(q+4)|0;s=c[l>>2]|0;if((s|0)==0){t=a+q|0;q=c[t>>2]|0;if((q|0)==0){u=0;break}else{v=q;w=t}}else{v=s;w=l}while(1){l=v+20|0;s=c[l>>2]|0;if((s|0)!=0){v=s;w=l;continue}l=v+16|0;s=c[l>>2]|0;if((s|0)==0){break}else{v=s;w=l}}if(w>>>0>>0){Mb()}else{c[w>>2]=0;u=v;break}}else{l=c[a+(8-g)>>2]|0;if(l>>>0>>0){Mb()}s=l+12|0;if((c[s>>2]|0)!=(h|0)){Mb()}t=p+8|0;if((c[t>>2]|0)==(h|0)){c[s>>2]=p;c[t>>2]=l;u=p;break}else{Mb()}}}while(0);if((o|0)!=0){p=c[a+(28-g)>>2]|0;k=12576+(p<<2)|0;if((h|0)==(c[k>>2]|0)){c[k>>2]=u;if((u|0)==0){c[12276>>2]=c[12276>>2]&~(1<>>0<(c[12288>>2]|0)>>>0){Mb()}p=o+16|0;if((c[p>>2]|0)==(h|0)){c[p>>2]=u}else{c[o+20>>2]=u}if((u|0)==0){m=h;n=j;break}}if(u>>>0<(c[12288>>2]|0)>>>0){Mb()}c[u+24>>2]=o;p=16-g|0;k=c[a+p>>2]|0;do{if((k|0)!=0){if(k>>>0<(c[12288>>2]|0)>>>0){Mb()}else{c[u+16>>2]=k;c[k+24>>2]=u;break}}}while(0);k=c[a+(p+4)>>2]|0;if((k|0)!=0){if(k>>>0<(c[12288>>2]|0)>>>0){Mb()}else{c[u+20>>2]=k;c[k+24>>2]=u;m=h;n=j;break}}else{m=h;n=j}}else{m=h;n=j}}else{m=a;n=b}}while(0);u=c[12288>>2]|0;if(e>>>0>>0){Mb()}v=a+(b+4)|0;w=c[v>>2]|0;if((w&2|0)==0){if((e|0)==(c[12296>>2]|0)){r=(c[12284>>2]|0)+n|0;c[12284>>2]=r;c[12296>>2]=m;c[m+4>>2]=r|1;if((m|0)!=(c[12292>>2]|0)){i=d;return}c[12292>>2]=0;c[12280>>2]=0;i=d;return}if((e|0)==(c[12292>>2]|0)){r=(c[12280>>2]|0)+n|0;c[12280>>2]=r;c[12292>>2]=m;c[m+4>>2]=r|1;c[m+r>>2]=r;i=d;return}r=(w&-8)+n|0;f=w>>>3;do{if(!(w>>>0<256)){k=c[a+(b+24)>>2]|0;g=c[a+(b+12)>>2]|0;do{if((g|0)==(e|0)){o=a+(b+20)|0;l=c[o>>2]|0;if((l|0)==0){t=a+(b+16)|0;s=c[t>>2]|0;if((s|0)==0){x=0;break}else{y=s;z=t}}else{y=l;z=o}while(1){o=y+20|0;l=c[o>>2]|0;if((l|0)!=0){y=l;z=o;continue}o=y+16|0;l=c[o>>2]|0;if((l|0)==0){break}else{y=l;z=o}}if(z>>>0>>0){Mb()}else{c[z>>2]=0;x=y;break}}else{o=c[a+(b+8)>>2]|0;if(o>>>0>>0){Mb()}l=o+12|0;if((c[l>>2]|0)!=(e|0)){Mb()}t=g+8|0;if((c[t>>2]|0)==(e|0)){c[l>>2]=g;c[t>>2]=o;x=g;break}else{Mb()}}}while(0);if((k|0)!=0){g=c[a+(b+28)>>2]|0;j=12576+(g<<2)|0;if((e|0)==(c[j>>2]|0)){c[j>>2]=x;if((x|0)==0){c[12276>>2]=c[12276>>2]&~(1<>>0<(c[12288>>2]|0)>>>0){Mb()}g=k+16|0;if((c[g>>2]|0)==(e|0)){c[g>>2]=x}else{c[k+20>>2]=x}if((x|0)==0){break}}if(x>>>0<(c[12288>>2]|0)>>>0){Mb()}c[x+24>>2]=k;g=c[a+(b+16)>>2]|0;do{if((g|0)!=0){if(g>>>0<(c[12288>>2]|0)>>>0){Mb()}else{c[x+16>>2]=g;c[g+24>>2]=x;break}}}while(0);g=c[a+(b+20)>>2]|0;if((g|0)!=0){if(g>>>0<(c[12288>>2]|0)>>>0){Mb()}else{c[x+20>>2]=g;c[g+24>>2]=x;break}}}}else{g=c[a+(b+8)>>2]|0;k=c[a+(b+12)>>2]|0;j=12312+(f<<1<<2)|0;if((g|0)!=(j|0)){if(g>>>0>>0){Mb()}if((c[g+12>>2]|0)!=(e|0)){Mb()}}if((k|0)==(g|0)){c[3068]=c[3068]&~(1<>>0>>0){Mb()}j=k+8|0;if((c[j>>2]|0)==(e|0)){A=j}else{Mb()}}else{A=k+8|0}c[g+12>>2]=k;c[A>>2]=g}}while(0);c[m+4>>2]=r|1;c[m+r>>2]=r;if((m|0)==(c[12292>>2]|0)){c[12280>>2]=r;i=d;return}else{B=r}}else{c[v>>2]=w&-2;c[m+4>>2]=n|1;c[m+n>>2]=n;B=n}n=B>>>3;if(B>>>0<256){w=n<<1;v=12312+(w<<2)|0;r=c[3068]|0;A=1<>2]|0;if(e>>>0<(c[12288>>2]|0)>>>0){Mb()}else{C=n;D=e}}else{c[3068]=r|A;C=12312+(w+2<<2)|0;D=v}c[C>>2]=m;c[D+12>>2]=m;c[m+8>>2]=D;c[m+12>>2]=v;i=d;return}v=B>>>8;if((v|0)!=0){if(B>>>0>16777215){E=31}else{D=(v+1048320|0)>>>16&8;C=v<>>16&4;w=C<>>16&2;A=14-(v|D|C)+(w<>>15)|0;E=B>>>(A+7|0)&1|A<<1}}else{E=0}A=12576+(E<<2)|0;c[m+28>>2]=E;c[m+20>>2]=0;c[m+16>>2]=0;C=c[12276>>2]|0;w=1<>2]=C|w;c[A>>2]=m;c[m+24>>2]=A;c[m+12>>2]=m;c[m+8>>2]=m;i=d;return}w=c[A>>2]|0;if((E|0)==31){F=0}else{F=25-(E>>>1)|0}a:do{if((c[w+4>>2]&-8|0)==(B|0)){G=w}else{E=B<>>31<<2)+16|0;C=c[H>>2]|0;if((C|0)==0){break}if((c[C+4>>2]&-8|0)==(B|0)){G=C;break a}else{E=E<<1;A=C}}if(H>>>0<(c[12288>>2]|0)>>>0){Mb()}c[H>>2]=m;c[m+24>>2]=A;c[m+12>>2]=m;c[m+8>>2]=m;i=d;return}}while(0);H=G+8|0;B=c[H>>2]|0;w=c[12288>>2]|0;if(G>>>0>>0){Mb()}if(B>>>0>>0){Mb()}c[B+12>>2]=m;c[H>>2]=m;c[m+8>>2]=B;c[m+12>>2]=G;c[m+24>>2]=0;i=d;return}function Td(a,b){a=a|0;b=b|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0;e=i;f=a+4|0;g=c[f>>2]|0;h=a+100|0;if(g>>>0<(c[h>>2]|0)>>>0){c[f>>2]=g+1;j=d[g>>0]|0}else{j=Ud(a)|0}if((j|0)==43|(j|0)==45){g=(j|0)==45&1;k=c[f>>2]|0;if(k>>>0<(c[h>>2]|0)>>>0){c[f>>2]=k+1;l=d[k>>0]|0}else{l=Ud(a)|0}if(!((l+ -48|0)>>>0<10|(b|0)==0)?(c[h>>2]|0)!=0:0){c[f>>2]=(c[f>>2]|0)+ -1;m=l;n=g}else{m=l;n=g}}else{m=j;n=0}if((m+ -48|0)>>>0>9){if((c[h>>2]|0)==0){o=-2147483648;p=0;E=o;i=e;return p|0}c[f>>2]=(c[f>>2]|0)+ -1;o=-2147483648;p=0;E=o;i=e;return p|0}else{q=m;r=0}while(1){s=q+ -48+r|0;m=c[f>>2]|0;if(m>>>0<(c[h>>2]|0)>>>0){c[f>>2]=m+1;t=d[m>>0]|0}else{t=Ud(a)|0}u=(t+ -48|0)>>>0<10;if(!(u&(s|0)<214748364)){break}q=t;r=s*10|0}r=((s|0)<0)<<31>>31;if(u){u=s;q=r;m=t;while(1){j=qe(u|0,q|0,10,0)|0;g=E;l=ee(m|0,((m|0)<0)<<31>>31|0,-48,-1)|0;b=ee(l|0,E|0,j|0,g|0)|0;g=E;j=c[f>>2]|0;if(j>>>0<(c[h>>2]|0)>>>0){c[f>>2]=j+1;v=d[j>>0]|0}else{v=Ud(a)|0}if((v+ -48|0)>>>0<10&((g|0)<21474836|(g|0)==21474836&b>>>0<2061584302)){u=b;q=g;m=v}else{w=b;x=g;y=v;break}}}else{w=s;x=r;y=t}if((y+ -48|0)>>>0<10){do{y=c[f>>2]|0;if(y>>>0<(c[h>>2]|0)>>>0){c[f>>2]=y+1;z=d[y>>0]|0}else{z=Ud(a)|0}}while((z+ -48|0)>>>0<10)}if((c[h>>2]|0)!=0){c[f>>2]=(c[f>>2]|0)+ -1}f=(n|0)!=0;n=de(0,0,w|0,x|0)|0;o=f?E:x;p=f?n:w;E=o;i=e;return p|0}function Ud(b){b=b|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0;e=i;f=b+104|0;g=c[f>>2]|0;if(!((g|0)!=0?(c[b+108>>2]|0)>=(g|0):0)){h=3}if((h|0)==3?(g=Xd(b)|0,(g|0)>=0):0){j=c[f>>2]|0;f=c[b+8>>2]|0;k=c[b+4>>2]|0;if((j|0)!=0?(l=j-(c[b+108>>2]|0)+ -1|0,(f-k|0)>(l|0)):0){c[b+100>>2]=k+l;m=k}else{n=k;h=8}if((h|0)==8){c[b+100>>2]=f;m=n}if((f|0)!=0){n=b+108|0;c[n>>2]=f+1-m+(c[n>>2]|0)}n=m+ -1|0;if((d[n>>0]|0|0)==(g|0)){o=g;i=e;return o|0}a[n>>0]=g;o=g;i=e;return o|0}c[b+100>>2]=0;o=-1;i=e;return o|0}function Vd(a,b){a=+a;b=b|0;var d=0,e=0,f=0,g=0,j=0,l=0.0,m=0.0,n=0.0,o=0;d=i;h[k>>3]=a;e=c[k>>2]|0;f=c[k+4>>2]|0;g=ge(e|0,f|0,52)|0;j=g&2047;if((j|0)==2047){l=a;i=d;return+l}else if((j|0)==0){if(a!=0.0){m=+Vd(a*18446744073709552000.0,b);n=m;o=(c[b>>2]|0)+ -64|0}else{n=a;o=0}c[b>>2]=o;l=n;i=d;return+l}else{c[b>>2]=j+ -1022;c[k>>2]=e;c[k+4>>2]=f&-2146435073|1071644672;l=+h[k>>3];i=d;return+l}return 0.0}function Wd(b,d){b=b|0;d=d|0;var e=0,f=0;e=i;if((b|0)==0){f=0;i=e;return f|0}if(d>>>0<128){a[b>>0]=d;f=1;i=e;return f|0}if(d>>>0<2048){a[b>>0]=d>>>6|192;a[b+1>>0]=d&63|128;f=2;i=e;return f|0}if(d>>>0<55296|(d+ -57344|0)>>>0<8192){a[b>>0]=d>>>12|224;a[b+1>>0]=d>>>6&63|128;a[b+2>>0]=d&63|128;f=3;i=e;return f|0}if((d+ -65536|0)>>>0<1048576){a[b>>0]=d>>>18|240;a[b+1>>0]=d>>>12&63|128;a[b+2>>0]=d>>>6&63|128;a[b+3>>0]=d&63|128;f=4;i=e;return f|0}else{c[(ic()|0)>>2]=84;f=-1;i=e;return f|0}return 0}function Xd(b){b=b|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0;e=i;i=i+16|0;f=e;g=b+8|0;do{if((c[g>>2]|0)==0){h=b+74|0;j=a[h>>0]|0;a[h>>0]=j+255|j;j=b+20|0;h=b+44|0;if((c[j>>2]|0)>>>0>(c[h>>2]|0)>>>0){zc[c[b+36>>2]&3](b,0,0)|0}c[b+16>>2]=0;c[b+28>>2]=0;c[j>>2]=0;j=c[b>>2]|0;if((j&20|0)==0){k=c[h>>2]|0;c[g>>2]=k;c[b+4>>2]=k;break}if((j&4|0)==0){l=-1;i=e;return l|0}c[b>>2]=j|32;l=-1;i=e;return l|0}}while(0);if((zc[c[b+32>>2]&3](b,f,1)|0)!=1){l=-1;i=e;return l|0}l=d[f>>0]|0;i=e;return l|0}function Yd(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;f=i;g=e+16|0;h=c[g>>2]|0;do{if((h|0)==0){j=e+74|0;k=a[j>>0]|0;a[j>>0]=k+255|k;k=c[e>>2]|0;if((k&8|0)==0){c[e+8>>2]=0;c[e+4>>2]=0;j=c[e+44>>2]|0;c[e+28>>2]=j;c[e+20>>2]=j;l=j+(c[e+48>>2]|0)|0;c[g>>2]=l;m=l;n=j;break}c[e>>2]=k|32;i=f;return}else{m=h;n=c[e+20>>2]|0}}while(0);h=e+20|0;if((m-n|0)>>>0>>0){zc[c[e+36>>2]&3](e,b,d)|0;i=f;return}a:do{if((a[e+75>>0]|0)>-1){m=d;while(1){if((m|0)==0){o=d;p=b;q=n;break a}g=m+ -1|0;if((a[b+g>>0]|0)==10){break}else{m=g}}if((zc[c[e+36>>2]&3](e,b,m)|0)>>>0>>0){i=f;return}else{o=d-m|0;p=b+m|0;q=c[h>>2]|0;break}}else{o=d;p=b;q=n}}while(0);ie(q|0,p|0,o|0)|0;c[h>>2]=(c[h>>2]|0)+o;i=f;return}function Zd(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;f=i;i=i+352|0;g=f+248|0;h=f+80|0;j=f;k=f+264|0;l=f+136|0;m=f+120|0;c[m>>2]=e;e=l+0|0;n=13672|0;o=e+112|0;do{c[e>>2]=c[n>>2];e=e+4|0;n=n+4|0}while((e|0)<(o|0));n=-2-b|0;p=n>>>0<2147483647?n:2147483647;n=l+48|0;c[n>>2]=p;q=l+20|0;c[q>>2]=b;r=l+44|0;c[r>>2]=b;s=b+p|0;b=l+16|0;c[b>>2]=s;t=l+28|0;c[t>>2]=s;e=h+0|0;o=e+40|0;do{c[e>>2]=0;e=e+4|0}while((e|0)<(o|0));c[g>>2]=c[m>>2];if((_d(0,d,g,j,h)|0)>=0){if((c[n>>2]|0)==0){m=c[r>>2]|0;c[r>>2]=k;c[t>>2]=k;c[q>>2]=k;c[n>>2]=80;c[b>>2]=k+80;_d(l,d,g,j,h)|0;if((m|0)!=0){zc[c[l+36>>2]&3](l,0,0)|0;c[r>>2]=m;c[n>>2]=0;c[b>>2]=0;c[t>>2]=0;c[q>>2]=0}}else{_d(l,d,g,j,h)|0}}if((p|0)==0){i=f;return}p=c[q>>2]|0;a[p+(((p|0)==(c[b>>2]|0))<<31>>31)>>0]=0;i=f;return}function _d(e,f,g,j,l){e=e|0;f=f|0;g=g|0;j=j|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Fa=0,Ga=0,Ha=0,Ia=0,Ja=0,Ka=0.0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Ua=0,Va=0,Wa=0,Xa=0,Ya=0,Za=0,_a=0,$a=0,ab=0,bb=0,cb=0,db=0,eb=0,fb=0,gb=0,hb=0,ib=0,jb=0,kb=0,lb=0,mb=0,nb=0,ob=0.0,pb=0,qb=0,rb=0,sb=0,tb=0,ub=0,vb=0,wb=0,xb=0,yb=0,zb=0,Ab=0.0,Bb=0.0,Cb=0,Db=0,Eb=0,Fb=0,Gb=0,Hb=0.0,Ib=0,Jb=0,Kb=0,Lb=0,Mb=0,Nb=0,Ob=0,Pb=0,Qb=0,Rb=0,Sb=0,Tb=0,Ub=0.0,Vb=0,Wb=0,Xb=0,Yb=0,Zb=0,_b=0,$b=0,ac=0,bc=0,cc=0,dc=0,ec=0,fc=0,gc=0,hc=0,jc=0,kc=0,lc=0,mc=0,oc=0,pc=0,qc=0,rc=0,sc=0,tc=0,uc=0,vc=0,wc=0,xc=0,yc=0.0,zc=0.0,Ac=0.0,Bc=0,Cc=0,Dc=0,Ec=0,Fc=0,Gc=0,Hc=0,Ic=0,Jc=0,Kc=0,Lc=0,Mc=0,Nc=0,Oc=0,Pc=0,Qc=0,Rc=0,Sc=0,Tc=0,Uc=0,Vc=0,Wc=0,Xc=0,Yc=0,Zc=0,_c=0,$c=0,ad=0,bd=0,cd=0,dd=0,ed=0,fd=0,gd=0,hd=0,id=0,jd=0,kd=0,ld=0,md=0,nd=0,od=0,pd=0,qd=0,rd=0,sd=0,td=0,ud=0,vd=0,wd=0,xd=0,yd=0,zd=0,Ad=0;m=i;i=i+832|0;n=m+16|0;o=m;p=m+808|0;q=p;r=m+792|0;s=m+496|0;t=m+752|0;u=m+8|0;v=m+804|0;w=(e|0)!=0;x=t+40|0;y=x;z=t+39|0;t=u+4|0;A=r+12|0;B=r+11|0;r=A;C=r-q|0;D=-2-q|0;F=r+2|0;G=n+264|0;H=p+9|0;I=H;J=p+8|0;K=0;L=0;M=f;f=0;N=0;O=0;a:while(1){do{if((f|0)>-1){if((N|0)>(2147483647-f|0)){c[(ic()|0)>>2]=75;P=-1;break}else{P=N+f|0;break}}else{P=f}}while(0);Q=a[M>>0]|0;if(Q<<24>>24==0){R=351;break}else{S=Q;T=M}while(1){if(S<<24>>24==0){U=T;V=T;break}else if(S<<24>>24==37){W=T;X=T;R=9;break}Q=T+1|0;S=a[Q>>0]|0;T=Q}b:do{if((R|0)==9){while(1){R=0;if((a[W+1>>0]|0)!=37){U=W;V=X;break b}Q=X+1|0;Y=W+2|0;if((a[Y>>0]|0)==37){W=Y;X=Q;R=9}else{U=Y;V=Q;break}}}}while(0);Q=V-M|0;if(w){Yd(M,Q,e)}if((V|0)!=(M|0)){Z=L;_=K;M=U;f=P;N=Q;L=Z;K=_;continue}Y=U+1|0;$=a[Y>>0]|0;ba=($<<24>>24)+ -48|0;if(ba>>>0<10?(a[U+2>>0]|0)==36:0){ca=U+3|0;da=a[ca>>0]|0;ea=ba;fa=1;ga=ca}else{da=$;ea=-1;fa=O;ga=Y}Y=da<<24>>24;c:do{if((Y+ -32|0)>>>0<32){$=Y;ca=da;ba=0;ha=ga;while(1){if((1<<$+ -32&75913|0)==0){ia=ca;ja=ba;ka=ha;break c}la=1<<(ca<<24>>24)+ -32|ba;ma=ha+1|0;na=a[ma>>0]|0;$=na<<24>>24;if(!(($+ -32|0)>>>0<32)){ia=na;ja=la;ka=ma;break}else{ca=na;ba=la;ha=ma}}}else{ia=da;ja=0;ka=ga}}while(0);do{if(ia<<24>>24==42){Y=ka+1|0;ha=(a[Y>>0]|0)+ -48|0;if(ha>>>0<10?(a[ka+2>>0]|0)==36:0){c[l+(ha<<2)>>2]=10;oa=1;pa=ka+3|0;qa=c[j+((a[Y>>0]|0)+ -48<<3)>>2]|0}else{if((fa|0)!=0){ra=-1;R=370;break a}if(!w){sa=Y;ta=ja;ua=0;va=0;break}ha=c[g>>2]|0;ba=c[ha>>2]|0;c[g>>2]=ha+4;oa=0;pa=Y;qa=ba}if((qa|0)<0){sa=pa;ta=ja|8192;ua=oa;va=0-qa|0}else{sa=pa;ta=ja;ua=oa;va=qa}}else{ba=ia<<24>>24;if((ba+ -48|0)>>>0<10){Y=ba;ba=ka;ha=0;do{ha=Y+ -48+(ha*10|0)|0;ba=ba+1|0;Y=a[ba>>0]|0}while((Y+ -48|0)>>>0<10);if((ha|0)<0){ra=-1;R=370;break a}else{sa=ba;ta=ja;ua=fa;va=ha}}else{sa=ka;ta=ja;ua=fa;va=0}}}while(0);d:do{if((a[sa>>0]|0)==46){Y=sa+1|0;ca=a[Y>>0]|0;if(!(ca<<24>>24==42)){$=ca<<24>>24;if(($+ -48|0)>>>0<10){wa=$;xa=Y;ya=0}else{za=Y;Aa=0;break}while(1){Y=wa+ -48+(ya*10|0)|0;$=xa+1|0;wa=a[$>>0]|0;if(!((wa+ -48|0)>>>0<10)){za=$;Aa=Y;break d}else{xa=$;ya=Y}}}ha=sa+2|0;ba=(a[ha>>0]|0)+ -48|0;if(ba>>>0<10?(a[sa+3>>0]|0)==36:0){c[l+(ba<<2)>>2]=10;za=sa+4|0;Aa=c[j+((a[ha>>0]|0)+ -48<<3)>>2]|0;break}if((ua|0)!=0){ra=-1;R=370;break a}if(w){ba=c[g>>2]|0;Y=c[ba>>2]|0;c[g>>2]=ba+4;za=ha;Aa=Y}else{za=ha;Aa=0}}else{za=sa;Aa=-1}}while(0);ha=za;Y=0;while(1){Ba=a[ha>>0]|0;ba=(Ba<<24>>24)+ -65|0;if(ba>>>0>57){ra=-1;R=370;break a}Ca=ha+1|0;Da=a[13104+(Y*58|0)+ba>>0]|0;Ea=Da&255;if((Ea+ -1|0)>>>0<8){ha=Ca;Y=Ea}else{break}}if(Da<<24>>24==0){ra=-1;R=370;break}ba=(ea|0)>-1;e:do{if(Da<<24>>24==19){if(ba){ra=-1;R=370;break a}if(w){Fa=Ba;Ga=L;Ha=K}else{Z=L;_=K;M=Ca;f=P;N=Q;O=ua;L=Z;K=_;continue a}}else{f:do{if(ba){c[l+(ea<<2)>>2]=Ea;$=j+(ea<<3)|0;ca=c[$+4>>2]|0;ma=c[$>>2]|0;if(w){Ia=ma;Ja=ca}else{K=ca;L=ma;M=Ca;f=P;N=Q;O=ua;continue a}}else{if(!w){ra=0;R=370;break a}if((Da&255)>20){Fa=Ba;Ga=L;Ha=K;break e}do{switch(Ea|0){case 10:{ma=c[g>>2]|0;ca=c[ma>>2]|0;c[g>>2]=ma+4;Ia=ca;Ja=((ca|0)<0)<<31>>31;break f;break};case 12:{ca=c[g>>2]|0;ma=ca;$=c[ma>>2]|0;la=c[ma+4>>2]|0;c[g>>2]=ca+8;Ia=$;Ja=la;break f;break};case 9:{la=c[g>>2]|0;$=c[la>>2]|0;c[g>>2]=la+4;Ia=$;Ja=K;break f;break};case 14:{$=c[g>>2]|0;la=c[$>>2]|0;c[g>>2]=$+4;Ia=la&65535;Ja=0;break f;break};case 15:{la=c[g>>2]|0;$=c[la>>2]|0;c[g>>2]=la+4;Ia=$<<24>>24;Ja=((($&255)<<24>>24|0)<0)<<31>>31;break f;break};case 11:{$=c[g>>2]|0;la=c[$>>2]|0;c[g>>2]=$+4;Ia=la;Ja=0;break f;break};case 13:{la=c[g>>2]|0;$=c[la>>2]|0;c[g>>2]=la+4;Ia=$<<16>>16;Ja=((($&65535)<<16>>16|0)<0)<<31>>31;break f;break};case 18:{$=c[g>>2]|0;c[k>>2]=c[$>>2];c[k+4>>2]=c[$+4>>2];Ka=+h[k>>3];c[g>>2]=$+8;h[k>>3]=Ka;Ia=c[k>>2]|0;Ja=c[k+4>>2]|0;break f;break};case 16:{$=c[g>>2]|0;la=c[$>>2]|0;c[g>>2]=$+4;Ia=la&255;Ja=0;break f;break};case 17:{la=c[g>>2]|0;c[k>>2]=c[la>>2];c[k+4>>2]=c[la+4>>2];Ka=+h[k>>3];c[g>>2]=la+8;h[k>>3]=Ka;Ia=c[k>>2]|0;Ja=c[k+4>>2]|0;break f;break};default:{Ia=L;Ja=K;break f}}}while(0)}}while(0);Fa=a[ha>>0]|0;Ga=Ia;Ha=Ja}}while(0);ha=Fa<<24>>24;if((Y|0)==0){La=ha}else{La=(ha&15|0)==3?ha&-33:ha}ha=ta&-65537;ba=(ta&8192|0)==0?ta:ha;g:do{switch(La|0){case 99:{a[z>>0]=Ga;Ma=Ha;Na=Ga;Oa=z;Pa=ha;Qa=1;Ra=0;Sa=13568;Ta=x;break};case 88:case 120:{Ua=ba;Va=Aa;Wa=La;R=77;break};case 109:{Xa=nc(c[(ic()|0)>>2]|0)|0;R=99;break};case 115:{Xa=(Ga|0)==0?13584:Ga;R=99;break};case 110:{switch(Y|0){case 0:{c[Ga>>2]=P;K=Ha;L=Ga;M=Ca;f=P;N=Q;O=ua;continue a;break};case 2:{la=Ga;c[la>>2]=P;c[la+4>>2]=((P|0)<0)<<31>>31;K=Ha;L=Ga;M=Ca;f=P;N=Q;O=ua;continue a;break};case 1:{c[Ga>>2]=P;K=Ha;L=Ga;M=Ca;f=P;N=Q;O=ua;continue a;break};case 4:{a[Ga>>0]=P;K=Ha;L=Ga;M=Ca;f=P;N=Q;O=ua;continue a;break};case 6:{c[Ga>>2]=P;K=Ha;L=Ga;M=Ca;f=P;N=Q;O=ua;continue a;break};case 3:{b[Ga>>1]=P;K=Ha;L=Ga;M=Ca;f=P;N=Q;O=ua;continue a;break};case 7:{la=Ga;c[la>>2]=P;c[la+4>>2]=((P|0)<0)<<31>>31;K=Ha;L=Ga;M=Ca;f=P;N=Q;O=ua;continue a;break};default:{K=Ha;L=Ga;M=Ca;f=P;N=Q;O=ua;continue a}}break};case 112:{Ua=ba|8;Va=Aa>>>0>8?Aa:8;Wa=120;R=77;break};case 67:{c[u>>2]=Ga;c[t>>2]=0;Ya=u;Za=u;_a=-1;R=115;break};case 83:{if((Aa|0)==0){$a=Ga;ab=Ga;bb=0;R=122}else{Ya=Ga;Za=Ga;_a=Aa;R=115}break};case 111:{la=Ga;$=(la|0)==0&(Ha|0)==0;if($){cb=x}else{ca=x;ma=la;la=Ha;while(1){na=ca+ -1|0;a[na>>0]=ma&7|48;ma=ge(ma|0,la|0,3)|0;la=E;if((ma|0)==0&(la|0)==0){cb=na;break}else{ca=na}}}if((ba&8|0)==0){db=Ga;eb=Ha;fb=cb;gb=ba;hb=Aa;ib=0;jb=13568;R=94}else{db=Ga;eb=Ha;fb=cb;gb=ba;hb=Aa;ib=$&1^1;jb=$?13568:13573|0;R=94}break};case 105:case 100:{if((Ha|0)<0){ca=de(0,0,Ga|0,Ha|0)|0;kb=ca;lb=E;mb=1;nb=13568;R=89;break g}if((ba&2048|0)==0){ca=ba&1;kb=Ga;lb=Ha;mb=ca;nb=(ca|0)==0?13568:13570|0;R=89}else{kb=Ga;lb=Ha;mb=1;nb=13569|0;R=89}break};case 117:{kb=Ga;lb=Ha;mb=0;nb=13568;R=89;break};case 65:case 71:case 70:case 69:case 97:case 103:case 102:case 101:{c[k>>2]=Ga;c[k+4>>2]=Ha;Ka=+h[k>>3];c[o>>2]=0;if((Ha|0)>=0){if((ba&2048|0)==0){ca=ba&1;ob=Ka;pb=ca;qb=(ca|0)==0?13593|0:13598|0}else{ob=Ka;pb=1;qb=13595|0}}else{ob=-Ka;pb=1;qb=13592}h[k>>3]=ob;ca=c[k+4>>2]&2146435072;if(!(ca>>>0<2146435072|(ca|0)==2146435072&0<0)){ca=(La&32|0)!=0;if(ob!=ob|0.0!=0.0){rb=0;sb=ca?13632:13640}else{rb=pb;sb=ca?13616:13624}ca=rb+3|0;la=(ca|0)<(va|0);if((ba&8192|0)==0&la){ma=va-ca|0;he(s|0,32,(ma>>>0>256?256:ma)|0)|0;if(ma>>>0>255){na=ma;while(1){Yd(s,256,e);tb=na+ -256|0;if(tb>>>0>255){na=tb}else{ub=tb;break}}}else{ub=ma}Yd(s,ub,e)}Yd(qb,rb,e);Yd(sb,3,e);if((ba&73728|0)==8192&la){na=va-ca|0;he(s|0,32,(na>>>0>256?256:na)|0)|0;if(na>>>0>255){$=na;while(1){Yd(s,256,e);tb=$+ -256|0;if(tb>>>0>255){$=tb}else{vb=tb;break}}}else{vb=na}Yd(s,vb,e)}K=Ha;L=Ga;M=Ca;f=P;N=la?va:ca;O=ua;continue a}Ka=+Vd(ob,o)*2.0;$=Ka!=0.0;if($){c[o>>2]=(c[o>>2]|0)+ -1}ma=La|32;if((ma|0)==97){tb=La&32;wb=(tb|0)==0?qb:qb+9|0;xb=pb|2;yb=Aa>>>0>11?0:12-Aa|0;do{if((yb|0)!=0){zb=yb;Ab=8.0;do{zb=zb+ -1|0;Ab=Ab*16.0}while((zb|0)!=0);if((a[wb>>0]|0)==45){Bb=-(Ab+(-Ka-Ab));break}else{Bb=Ka+Ab-Ab;break}}else{Bb=Ka}}while(0);yb=c[o>>2]|0;ca=(yb|0)<0?0-yb|0:yb;if((ca|0)<0){yb=A;la=ca;na=((ca|0)<0)<<31>>31;while(1){zb=se(la|0,na|0,10,0)|0;yb=yb+ -1|0;a[yb>>0]=zb|48;zb=la;la=re(la|0,na|0,10,0)|0;if(!(na>>>0>9|(na|0)==9&zb>>>0>4294967295)){break}else{na=E}}Cb=yb;Db=la}else{Cb=A;Db=ca}if((Db|0)==0){Eb=Cb}else{na=Cb;zb=Db;while(1){Fb=na+ -1|0;a[Fb>>0]=(zb>>>0)%10|0|48;if(zb>>>0<10){Eb=Fb;break}else{na=Fb;zb=(zb>>>0)/10|0}}}if((Eb|0)==(A|0)){a[B>>0]=48;Gb=B}else{Gb=Eb}a[Gb+ -1>>0]=(c[o>>2]>>31&2)+43;zb=Gb+ -2|0;a[zb>>0]=La+15;na=(ba&8|0)==0;if((Aa|0)>0){if(na){Hb=Bb;ca=p;while(1){la=~~Hb;yb=ca+1|0;a[ca>>0]=d[13648+la>>0]|tb;Hb=(Hb- +(la|0))*16.0;if((yb-q|0)==1){a[yb>>0]=46;Ib=ca+2|0}else{Ib=yb}if(!(Hb!=0.0)){Jb=Ib;break}else{ca=Ib}}}else{Hb=Bb;ca=p;while(1){yb=~~Hb;la=ca+1|0;a[ca>>0]=d[13648+yb>>0]|tb;Hb=(Hb- +(yb|0))*16.0;if((la-q|0)==1){a[la>>0]=46;Kb=ca+2|0}else{Kb=la}if(!(Hb!=0.0)){Jb=Kb;break}else{ca=Kb}}}}else{if(na){Hb=Bb;ca=p;while(1){la=~~Hb;yb=ca+1|0;a[ca>>0]=d[13648+la>>0]|tb;Hb=(Hb- +(la|0))*16.0;la=Hb!=0.0;if((yb-q|0)==1&la){a[yb>>0]=46;Lb=ca+2|0}else{Lb=yb}if(!la){Jb=Lb;break}else{ca=Lb}}}else{Hb=Bb;ca=p;while(1){na=~~Hb;la=ca+1|0;a[ca>>0]=d[13648+na>>0]|tb;Hb=(Hb- +(na|0))*16.0;if((la-q|0)==1){a[la>>0]=46;Mb=ca+2|0}else{Mb=la}if(!(Hb!=0.0)){Jb=Mb;break}else{ca=Mb}}}}ca=Jb;do{if((Aa|0)==0){R=186}else{if((D+ca|0)>=(Aa|0)){R=186;break}Nb=F+Aa-zb|0}}while(0);if((R|0)==186){R=0;Nb=C-zb+ca|0}tb=Nb+xb|0;la=ba&73728;na=(tb|0)<(va|0);if((la|0)==0&na){yb=va-tb|0;he(s|0,32,(yb>>>0>256?256:yb)|0)|0;if(yb>>>0>255){Fb=yb;while(1){Yd(s,256,e);Ob=Fb+ -256|0;if(Ob>>>0>255){Fb=Ob}else{Pb=Ob;break}}}else{Pb=yb}Yd(s,Pb,e)}Yd(wb,xb,e);if((la|0)==65536&na){Fb=va-tb|0;he(s|0,48,(Fb>>>0>256?256:Fb)|0)|0;if(Fb>>>0>255){Ob=Fb;while(1){Yd(s,256,e);Qb=Ob+ -256|0;if(Qb>>>0>255){Ob=Qb}else{Rb=Qb;break}}}else{Rb=Fb}Yd(s,Rb,e)}Ob=ca-q|0;Yd(p,Ob,e);xb=r-zb|0;wb=Nb-xb-Ob|0;if((wb|0)>0){he(s|0,48,(wb>>>0>256?256:wb)|0)|0;if(wb>>>0>255){Ob=wb;while(1){Yd(s,256,e);yb=Ob+ -256|0;if(yb>>>0>255){Ob=yb}else{Sb=yb;break}}}else{Sb=wb}Yd(s,Sb,e)}Yd(zb,xb,e);if((la|0)==8192&na){Ob=va-tb|0;he(s|0,32,(Ob>>>0>256?256:Ob)|0)|0;if(Ob>>>0>255){ca=Ob;while(1){Yd(s,256,e);Fb=ca+ -256|0;if(Fb>>>0>255){ca=Fb}else{Tb=Fb;break}}}else{Tb=Ob}Yd(s,Tb,e)}K=Ha;L=Ga;M=Ca;f=P;N=na?va:tb;O=ua;continue a}ca=(Aa|0)<0?6:Aa;if($){la=(c[o>>2]|0)+ -28|0;c[o>>2]=la;Ub=Ka*268435456.0;Vb=la}else{Ub=Ka;Vb=c[o>>2]|0}la=(Vb|0)<0?n:G;Hb=Ub;xb=la;do{zb=~~Hb>>>0;c[xb>>2]=zb;xb=xb+4|0;Hb=(Hb- +(zb>>>0))*1.0e9}while(Hb!=0.0);$=c[o>>2]|0;if(($|0)>0){tb=$;na=la;Ob=xb;while(1){zb=(tb|0)>29?29:tb;wb=Ob+ -4|0;do{if(wb>>>0>>0){Wb=na;Xb=(c[wb>>2]|0)==0&Ob>>>0>na>>>0?wb:Ob}else{Fb=0;yb=wb;do{Qb=je(c[yb>>2]|0,0,zb|0)|0;Yb=ee(Qb|0,E|0,Fb|0,0)|0;Qb=E;Zb=se(Yb|0,Qb|0,1e9,0)|0;c[yb>>2]=Zb;Fb=re(Yb|0,Qb|0,1e9,0)|0;yb=yb+ -4|0}while(!(yb>>>0>>0));yb=(c[wb>>2]|0)==0&Ob>>>0>na>>>0?wb:Ob;if((Fb|0)==0){Wb=na;Xb=yb;break}Qb=na+ -4|0;c[Qb>>2]=Fb;Wb=Qb;Xb=yb}}while(0);wb=(c[o>>2]|0)-zb|0;c[o>>2]=wb;if((wb|0)>0){tb=wb;na=Wb;Ob=Xb}else{_b=wb;$b=Wb;ac=Xb;break}}}else{_b=$;$b=la;ac=xb}h:do{if((_b|0)<0){Ob=((ca|0)/9|0)+2|0;if((ma|0)==102){na=la;tb=la+(Ob<<2)|0;wb=_b;yb=$b;Qb=ac;while(1){Yb=0-wb|0;Zb=(Yb|0)>9?9:Yb;do{if(yb>>>0>>0){Yb=(1<>>Zb;cc=0;dc=yb;do{ec=c[dc>>2]|0;c[dc>>2]=(ec>>>Zb)+cc;cc=aa(ec&Yb,bc)|0;dc=dc+4|0}while(dc>>>0>>0);dc=(c[yb>>2]|0)==0?yb+4|0:yb;if((cc|0)==0){fc=dc;gc=Qb;break}c[Qb>>2]=cc;fc=dc;gc=Qb+4|0}else{fc=(c[yb>>2]|0)==0?yb+4|0:yb;gc=Qb}}while(0);Fb=(gc-na>>2|0)>(Ob|0)?tb:gc;wb=(c[o>>2]|0)+Zb|0;c[o>>2]=wb;if((wb|0)>=0){hc=fc;jc=Fb;break h}else{yb=fc;Qb=Fb}}}else{kc=_b;lc=$b;mc=ac}while(1){Qb=0-kc|0;yb=(Qb|0)>9?9:Qb;do{if(lc>>>0>>0){Qb=(1<>>yb;tb=0;na=lc;do{zb=c[na>>2]|0;c[na>>2]=(zb>>>yb)+tb;tb=aa(zb&Qb,wb)|0;na=na+4|0}while(na>>>0>>0);na=(c[lc>>2]|0)==0?lc+4|0:lc;if((tb|0)==0){oc=na;pc=mc;break}c[mc>>2]=tb;oc=na;pc=mc+4|0}else{oc=(c[lc>>2]|0)==0?lc+4|0:lc;pc=mc}}while(0);if((pc-oc>>2|0)>(Ob|0)){qc=oc+(Ob<<2)|0}else{qc=pc}kc=(c[o>>2]|0)+yb|0;c[o>>2]=kc;if((kc|0)>=0){hc=oc;jc=qc;break}else{lc=oc;mc=qc}}}else{hc=$b;jc=ac}}while(0);xb=la;do{if(hc>>>0>>0){$=(xb-hc>>2)*9|0;Ob=c[hc>>2]|0;if(Ob>>>0<10){rc=$;break}else{sc=$;tc=10}while(1){tc=tc*10|0;$=sc+1|0;if(Ob>>>0>>0){rc=$;break}else{sc=$}}}else{rc=0}}while(0);Ob=(ma|0)==103;$=ca-((ma|0)!=102?rc:0)+((Ob&(ca|0)!=0)<<31>>31)|0;if(($|0)<(((jc-xb>>2)*9|0)+ -9|0)){Zb=$+9216|0;$=(Zb|0)/9|0;na=la+($+ -1023<<2)|0;wb=((Zb|0)%9|0)+1|0;if((wb|0)<9){Zb=10;Qb=wb;while(1){wb=Zb*10|0;Qb=Qb+1|0;if((Qb|0)==9){uc=wb;break}else{Zb=wb}}}else{uc=10}Zb=c[na>>2]|0;Qb=(Zb>>>0)%(uc>>>0)|0;if((Qb|0)==0?(la+($+ -1022<<2)|0)==(jc|0):0){vc=hc;wc=na;xc=rc}else{R=244}do{if((R|0)==244){R=0;Ab=(((Zb>>>0)/(uc>>>0)|0)&1|0)==0?9007199254740992.0:9007199254740994.0;ma=(uc|0)/2|0;do{if(Qb>>>0>>0){yc=.5}else{if((Qb|0)==(ma|0)?(la+($+ -1022<<2)|0)==(jc|0):0){yc=1.0;break}yc=1.5}}while(0);do{if((pb|0)==0){zc=Ab;Ac=yc}else{if((a[qb>>0]|0)!=45){zc=Ab;Ac=yc;break}zc=Ab*-1.0;Ac=yc*-1.0}}while(0);ma=Zb-Qb|0;c[na>>2]=ma;if(!(zc+Ac!=zc)){vc=hc;wc=na;xc=rc;break}wb=ma+uc|0;c[na>>2]=wb;if(wb>>>0>999999999){wb=na;while(1){ma=wb+ -4|0;c[wb>>2]=0;cc=(c[ma>>2]|0)+1|0;c[ma>>2]=cc;if(cc>>>0>999999999){wb=ma}else{Bc=ma;break}}}else{Bc=na}wb=Bc>>>0>>0?Bc:hc;ma=(xb-wb>>2)*9|0;cc=c[wb>>2]|0;if(cc>>>0<10){vc=wb;wc=Bc;xc=ma;break}else{Cc=ma;Dc=10}while(1){Dc=Dc*10|0;ma=Cc+1|0;if(cc>>>0>>0){vc=wb;wc=Bc;xc=ma;break}else{Cc=ma}}}}while(0);na=wc+4|0;Qb=jc>>>0>na>>>0?na:jc;while(1){na=Qb+ -4|0;if((c[na>>2]|0)==0&Qb>>>0>vc>>>0){Qb=na}else{Ec=vc;Fc=xc;Gc=Qb;break}}}else{Ec=hc;Fc=rc;Gc=jc}Qb=0-Fc|0;do{if(Ob){na=((ca|0)==0&1)+ca|0;if((na|0)>(Fc|0)&(Fc|0)>-5){Hc=La+ -1|0;Ic=na+ -1-Fc|0}else{Hc=La+ -2|0;Ic=na+ -1|0}if((ba&8|0)!=0){Jc=Hc;Kc=Ic;break}do{if(Gc>>>0>Ec>>>0){na=c[Gc+ -4>>2]|0;if((na|0)==0){Lc=9;break}if(((na>>>0)%10|0|0)==0){Mc=10;Nc=0}else{Lc=0;break}while(1){Mc=Mc*10|0;Zb=Nc+1|0;if(((na>>>0)%(Mc>>>0)|0|0)!=0){Lc=Zb;break}else{Nc=Zb}}}else{Lc=9}}while(0);na=((Gc-xb>>2)*9|0)+ -9|0;if((Hc|32|0)==102){yb=na-Lc|0;Zb=(yb|0)<0?0:yb;Jc=Hc;Kc=(Ic|0)<(Zb|0)?Ic:Zb;break}else{Zb=na+Fc-Lc|0;na=(Zb|0)<0?0:Zb;Jc=Hc;Kc=(Ic|0)<(na|0)?Ic:na;break}}else{Jc=La;Kc=ca}}while(0);ca=(Kc|0)!=0;if(ca){Oc=1}else{Oc=(ba&8|0)!=0}xb=Oc&1;Ob=(Jc|32|0)==102;if(Ob){Pc=(Fc|0)>0?Fc:0;Qc=0}else{na=(Fc|0)<0?Qb:Fc;if((na|0)<0){Zb=A;yb=na;$=((na|0)<0)<<31>>31;while(1){wb=se(yb|0,$|0,10,0)|0;Zb=Zb+ -1|0;a[Zb>>0]=wb|48;wb=yb;yb=re(yb|0,$|0,10,0)|0;if(!($>>>0>9|($|0)==9&wb>>>0>4294967295)){break}else{$=E}}Rc=Zb;Sc=yb}else{Rc=A;Sc=na}if((Sc|0)==0){Tc=Rc}else{$=Rc;Qb=Sc;while(1){wb=$+ -1|0;a[wb>>0]=(Qb>>>0)%10|0|48;if(Qb>>>0<10){Tc=wb;break}else{$=wb;Qb=(Qb>>>0)/10|0}}}if((r-Tc|0)<2){Qb=Tc;while(1){$=Qb+ -1|0;a[$>>0]=48;if((r-$|0)<2){Qb=$}else{Uc=$;break}}}else{Uc=Tc}a[Uc+ -1>>0]=(Fc>>31&2)+43;Qb=Uc+ -2|0;a[Qb>>0]=Jc;Pc=r-Qb|0;Qc=Qb}Qb=pb+1+Kc+xb+Pc|0;$=ba&73728;na=(Qb|0)<(va|0);if(($|0)==0&na){yb=va-Qb|0;he(s|0,32,(yb>>>0>256?256:yb)|0)|0;if(yb>>>0>255){Zb=yb;while(1){Yd(s,256,e);wb=Zb+ -256|0;if(wb>>>0>255){Zb=wb}else{Vc=wb;break}}}else{Vc=yb}Yd(s,Vc,e)}Yd(qb,pb,e);if(($|0)==65536&na){Zb=va-Qb|0;he(s|0,48,(Zb>>>0>256?256:Zb)|0)|0;if(Zb>>>0>255){xb=Zb;while(1){Yd(s,256,e);wb=xb+ -256|0;if(wb>>>0>255){xb=wb}else{Wc=wb;break}}}else{Wc=Zb}Yd(s,Wc,e)}do{if(Ob){xb=Ec>>>0>la>>>0?la:Ec;yb=xb;do{wb=c[yb>>2]|0;if((wb|0)==0){Xc=H}else{cc=H;ma=wb;while(1){wb=cc+ -1|0;a[wb>>0]=(ma>>>0)%10|0|48;if(ma>>>0<10){Xc=wb;break}else{cc=wb;ma=(ma>>>0)/10|0}}}do{if((yb|0)==(xb|0)){if((Xc|0)!=(H|0)){Yc=Xc;break}a[J>>0]=48;Yc=J}else{if(Xc>>>0>p>>>0){Zc=Xc}else{Yc=Xc;break}while(1){ma=Zc+ -1|0;a[ma>>0]=48;if(ma>>>0>p>>>0){Zc=ma}else{Yc=ma;break}}}}while(0);Yd(Yc,I-Yc|0,e);yb=yb+4|0}while(!(yb>>>0>la>>>0));if(!ca?(ba&8|0)==0:0){break}Yd(13664,1,e);if(yb>>>0>>0&(Kc|0)>0){xb=Kc;tb=yb;while(1){ma=c[tb>>2]|0;if((ma|0)!=0){cc=H;wb=ma;while(1){cc=cc+ -1|0;a[cc>>0]=(wb>>>0)%10|0|48;if(wb>>>0<10){break}else{wb=(wb>>>0)/10|0}}if(cc>>>0>p>>>0){_c=cc;R=307}else{$c=cc}}else{_c=H;R=307}if((R|0)==307){while(1){R=0;wb=_c+ -1|0;a[wb>>0]=48;if(wb>>>0>p>>>0){_c=wb;R=307}else{$c=wb;break}}}Yd($c,(xb|0)>9?9:xb,e);tb=tb+4|0;cc=xb+ -9|0;if(!(tb>>>0>>0&(cc|0)>0)){ad=cc;break}else{xb=cc}}}else{ad=Kc}if((ad|0)<=0){break}he(s|0,48,(ad>>>0>256?256:ad)|0)|0;if(ad>>>0>255){xb=ad;while(1){Yd(s,256,e);tb=xb+ -256|0;if(tb>>>0>255){xb=tb}else{bd=tb;break}}}else{bd=ad}Yd(s,bd,e)}else{xb=Gc>>>0>Ec>>>0?Gc:Ec+4|0;do{if((Kc|0)>-1){tb=(ba&8|0)!=0;yb=Kc;cc=Ec;do{wb=c[cc>>2]|0;if((wb|0)!=0){ma=H;zb=wb;while(1){ma=ma+ -1|0;a[ma>>0]=(zb>>>0)%10|0|48;if(zb>>>0<10){break}else{zb=(zb>>>0)/10|0}}if((ma|0)!=(H|0)){cd=ma}else{R=318}}else{R=318}if((R|0)==318){R=0;a[J>>0]=48;cd=J}do{if((cc|0)==(Ec|0)){zb=cd+1|0;Yd(cd,1,e);if(!((yb|0)>0|tb)){dd=zb;break}Yd(13664,1,e);dd=zb}else{if(cd>>>0>p>>>0){ed=cd}else{dd=cd;break}while(1){zb=ed+ -1|0;a[zb>>0]=48;if(zb>>>0>p>>>0){ed=zb}else{dd=zb;break}}}}while(0);ma=I-dd|0;Yd(dd,(ma|0)<(yb|0)?ma:yb,e);yb=yb-ma|0;cc=cc+4|0}while(cc>>>0>>0&(yb|0)>-1);if((yb|0)<=0){break}he(s|0,48,(yb>>>0>256?256:yb)|0)|0;if(yb>>>0>255){cc=yb;while(1){Yd(s,256,e);tb=cc+ -256|0;if(tb>>>0>255){cc=tb}else{fd=tb;break}}}else{fd=yb}Yd(s,fd,e)}}while(0);Yd(Qc,r-Qc|0,e)}}while(0);if(($|0)==8192&na){ca=va-Qb|0;he(s|0,32,(ca>>>0>256?256:ca)|0)|0;if(ca>>>0>255){la=ca;while(1){Yd(s,256,e);Ob=la+ -256|0;if(Ob>>>0>255){la=Ob}else{gd=Ob;break}}}else{gd=ca}Yd(s,gd,e)}K=Ha;L=Ga;M=Ca;f=P;N=na?va:Qb;O=ua;continue a;break};default:{Ma=Ha;Na=Ga;Oa=M;Pa=ba;Qa=Aa;Ra=0;Sa=13568;Ta=x}}}while(0);i:do{if((R|0)==77){R=0;Q=Ga;Y=Wa&32;if(!((Q|0)==0&(Ha|0)==0)){la=x;$=Q;Q=Ha;do{la=la+ -1|0;a[la>>0]=d[13648+($&15)>>0]|Y;$=ge($|0,Q|0,4)|0;Q=E}while(!(($|0)==0&(Q|0)==0));if((Ua&8|0)==0){db=Ga;eb=Ha;fb=la;gb=Ua;hb=Va;ib=0;jb=13568;R=94}else{db=Ga;eb=Ha;fb=la;gb=Ua;hb=Va;ib=2;jb=13568+(Wa>>4)|0;R=94}}else{db=Ga;eb=Ha;fb=x;gb=Ua;hb=Va;ib=0;jb=13568;R=94}}else if((R|0)==89){R=0;Q=kb;if(lb>>>0>0|(lb|0)==0&Q>>>0>4294967295){$=x;Y=Q;Qb=lb;while(1){na=se(Y|0,Qb|0,10,0)|0;$=$+ -1|0;a[$>>0]=na|48;na=Y;Y=re(Y|0,Qb|0,10,0)|0;if(!(Qb>>>0>9|(Qb|0)==9&na>>>0>4294967295)){break}else{Qb=E}}hd=$;id=Y}else{hd=x;id=Q}if((id|0)==0){db=kb;eb=lb;fb=hd;gb=ba;hb=Aa;ib=mb;jb=nb;R=94}else{Qb=hd;la=id;while(1){na=Qb+ -1|0;a[na>>0]=(la>>>0)%10|0|48;if(la>>>0<10){db=kb;eb=lb;fb=na;gb=ba;hb=Aa;ib=mb;jb=nb;R=94;break}else{Qb=na;la=(la>>>0)/10|0}}}}else if((R|0)==99){R=0;la=Xa;Qb=(Aa|0)==0;j:do{if((la&3|0)==0|Qb){jd=Aa;kd=Qb;ld=Xa;R=102}else{Q=Aa;Y=Xa;while(1){if((a[Y>>0]|0)==0){md=Q;nd=Y;break j}$=Y+1|0;na=Q+ -1|0;ca=(na|0)==0;if(($&3|0)==0|ca){jd=na;kd=ca;ld=$;R=102;break}else{Q=na;Y=$}}}}while(0);k:do{if((R|0)==102){R=0;if(!kd){if((a[ld>>0]|0)!=0){l:do{if(jd>>>0>3){Qb=jd;Y=ld;while(1){Q=c[Y>>2]|0;if(((Q&-2139062144^-2139062144)&Q+ -16843009|0)!=0){od=Qb;pd=Y;break l}Q=Y+4|0;$=Qb+ -4|0;if($>>>0>3){Qb=$;Y=Q}else{od=$;pd=Q;break}}}else{od=jd;pd=ld}}while(0);if((od|0)==0){md=0;nd=pd}else{Y=od;Qb=pd;while(1){if((a[Qb>>0]|0)==0){md=Y;nd=Qb;break k}yb=Qb+1|0;Y=Y+ -1|0;if((Y|0)==0){md=0;nd=yb;break}else{Qb=yb}}}}else{md=jd;nd=ld}}else{md=0;nd=ld}}}while(0);Qb=(md|0)!=0?nd:0;if((Qb|0)==0){Ma=Ha;Na=Ga;Oa=Xa;Pa=ha;Qa=Aa;Ra=0;Sa=13568;Ta=Xa+Aa|0;break}else{Ma=Ha;Na=Ga;Oa=Xa;Pa=ha;Qa=Qb-la|0;Ra=0;Sa=13568;Ta=Qb;break}}else if((R|0)==115){R=0;Qb=0;Y=0;yb=Ya;while(1){Q=c[yb>>2]|0;if((Q|0)==0){qd=Qb;rd=Y;break}$=Wd(v,Q)|0;if(!(($|0)>-1)){ra=-1;R=370;break a}Q=$+Qb|0;if($>>>0>(_a-Qb|0)>>>0){$a=Ya;ab=Za;bb=Qb;R=122;break i}if(!(Q>>>0<_a>>>0)){qd=Q;rd=$;break}Qb=Q;Y=$;yb=yb+4|0}if((rd|0)<0){ra=-1;R=370;break a}else{$a=Ya;ab=Za;bb=qd;R=122}}}while(0);if((R|0)==94){R=0;ha=(hb|0)>-1?gb&-65537:gb;yb=(db|0)==0&(eb|0)==0;if(yb&(hb|0)==0){Ma=eb;Na=db;Oa=x;Pa=ha;Qa=0;Ra=ib;Sa=jb;Ta=x}else{Y=(yb&1)+(y-fb)|0;Ma=eb;Na=db;Oa=fb;Pa=ha;Qa=(hb|0)>(Y|0)?hb:Y;Ra=ib;Sa=jb;Ta=x}}else if((R|0)==122){R=0;Y=ba&73728;ha=(bb|0)<(va|0);if((Y|0)==0&ha){yb=va-bb|0;he(s|0,32,(yb>>>0>256?256:yb)|0)|0;if(yb>>>0>255){Qb=yb;while(1){Yd(s,256,e);la=Qb+ -256|0;if(la>>>0>255){Qb=la}else{sd=la;break}}}else{sd=yb}Yd(s,sd,e)}m:do{if((bb|0)!=0){Qb=0;ba=$a;while(1){la=c[ba>>2]|0;if((la|0)==0){break m}$=Wd(v,la)|0;la=$+Qb|0;if((la|0)>(bb|0)){break m}Yd(v,$,e);if(!(la>>>0>>0)){break m}Qb=la;ba=ba+4|0}}}while(0);if((Y|0)==8192&ha){yb=va-bb|0;he(s|0,32,(yb>>>0>256?256:yb)|0)|0;if(yb>>>0>255){ba=yb;while(1){Yd(s,256,e);Qb=ba+ -256|0;if(Qb>>>0>255){ba=Qb}else{td=Qb;break}}}else{td=yb}Yd(s,td,e)}K=Ha;L=ab;M=Ca;f=P;N=ha?va:bb;O=ua;continue}ba=Ta-Oa|0;Y=(Qa|0)<(ba|0)?ba:Qa;Qb=Ra+Y|0;la=(va|0)<(Qb|0)?Qb:va;$=Pa&73728;Q=(Qb|0)<(la|0);if(($|0)==0&Q){na=la-Qb|0;he(s|0,32,(na>>>0>256?256:na)|0)|0;if(na>>>0>255){ca=na;while(1){Yd(s,256,e);Ob=ca+ -256|0;if(Ob>>>0>255){ca=Ob}else{ud=Ob;break}}}else{ud=na}Yd(s,ud,e)}Yd(Sa,Ra,e);if(($|0)==65536&Q){ca=la-Qb|0;he(s|0,48,(ca>>>0>256?256:ca)|0)|0;if(ca>>>0>255){ha=ca;while(1){Yd(s,256,e);yb=ha+ -256|0;if(yb>>>0>255){ha=yb}else{vd=yb;break}}}else{vd=ca}Yd(s,vd,e)}if((ba|0)<(Y|0)){ha=Y-ba|0;he(s|0,48,(ha>>>0>256?256:ha)|0)|0;if(ha>>>0>255){na=ha;while(1){Yd(s,256,e);yb=na+ -256|0;if(yb>>>0>255){na=yb}else{wd=yb;break}}}else{wd=ha}Yd(s,wd,e)}Yd(Oa,ba,e);if(!(($|0)==8192&Q)){K=Ma;L=Na;M=Ca;f=P;N=la;O=ua;continue}na=la-Qb|0;he(s|0,32,(na>>>0>256?256:na)|0)|0;if(na>>>0>255){Y=na;while(1){Yd(s,256,e);ca=Y+ -256|0;if(ca>>>0>255){Y=ca}else{xd=ca;break}}}else{xd=na}Yd(s,xd,e);K=Ma;L=Na;M=Ca;f=P;N=la;O=ua}if((R|0)==351){if((e|0)!=0){ra=P;i=m;return ra|0}if((O|0)==0){ra=0;i=m;return ra|0}else{yd=1}while(1){O=c[l+(yd<<2)>>2]|0;if((O|0)==0){zd=1;Ad=yd;break}P=j+(yd<<3)|0;n:do{if(!(O>>>0>20)){do{switch(O|0){case 16:{e=c[g>>2]|0;ua=c[e>>2]|0;c[g>>2]=e+4;e=P;c[e>>2]=ua&255;c[e+4>>2]=0;break n;break};case 14:{e=c[g>>2]|0;ua=c[e>>2]|0;c[g>>2]=e+4;e=P;c[e>>2]=ua&65535;c[e+4>>2]=0;break n;break};case 15:{e=c[g>>2]|0;ua=c[e>>2]|0;c[g>>2]=e+4;e=(ua&255)<<24>>24;ua=P;c[ua>>2]=e;c[ua+4>>2]=((e|0)<0)<<31>>31;break n;break};case 12:{e=c[g>>2]|0;ua=e;N=c[ua>>2]|0;f=c[ua+4>>2]|0;c[g>>2]=e+8;e=P;c[e>>2]=N;c[e+4>>2]=f;break n;break};case 9:{f=c[g>>2]|0;e=c[f>>2]|0;c[g>>2]=f+4;c[P>>2]=e;break n;break};case 17:{e=c[g>>2]|0;c[k>>2]=c[e>>2];c[k+4>>2]=c[e+4>>2];zc=+h[k>>3];c[g>>2]=e+8;h[P>>3]=zc;break n;break};case 18:{e=c[g>>2]|0;c[k>>2]=c[e>>2];c[k+4>>2]=c[e+4>>2];zc=+h[k>>3];c[g>>2]=e+8;h[P>>3]=zc;break n;break};case 10:{e=c[g>>2]|0;f=c[e>>2]|0;c[g>>2]=e+4;e=P;c[e>>2]=f;c[e+4>>2]=((f|0)<0)<<31>>31;break n;break};case 13:{f=c[g>>2]|0;e=c[f>>2]|0;c[g>>2]=f+4;f=(e&65535)<<16>>16;e=P;c[e>>2]=f;c[e+4>>2]=((f|0)<0)<<31>>31;break n;break};case 11:{f=c[g>>2]|0;e=c[f>>2]|0;c[g>>2]=f+4;f=P;c[f>>2]=e;c[f+4>>2]=0;break n;break};default:{break n}}}while(0)}}while(0);yd=yd+1|0;if((yd|0)>=10){ra=1;R=370;break}}if((R|0)==370){i=m;return ra|0}while(1){yd=Ad+1|0;if(!zd){ra=-1;R=370;break}if((yd|0)>=10){ra=1;R=370;break}zd=(c[l+(yd<<2)>>2]|0)==0;Ad=yd}if((R|0)==370){i=m;return ra|0}}else if((R|0)==370){i=m;return ra|0}return 0}function $d(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;e=i;f=a+20|0;g=c[f>>2]|0;h=(c[a+16>>2]|0)-g|0;a=h>>>0>d>>>0?d:h;ie(g|0,b|0,a|0)|0;c[f>>2]=(c[f>>2]|0)+a;i=e;return d|0}function ae(){}function be(a){a=a|0;var b=0;b=(aa(c[a>>2]|0,31010991)|0)+1735287159&2147483647;c[a>>2]=b;return b|0}function ce(){return be(o)|0}function de(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0;e=b-d>>>0;e=b-d-(c>>>0>a>>>0|0)>>>0;return(E=e,a-c>>>0|0)|0}function ee(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0;e=a+c>>>0;return(E=b+d+(e>>>0>>0|0)>>>0,e|0)|0}function fe(b){b=b|0;var c=0;c=b;while(a[c>>0]|0){c=c+1|0}return c-b|0}function ge(a,b,c){a=a|0;b=b|0;c=c|0;if((c|0)<32){E=b>>>c;return a>>>c|(b&(1<>>c-32|0}function he(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;f=b+e|0;if((e|0)>=20){d=d&255;g=b&3;h=d|d<<8|d<<16|d<<24;i=f&~3;if(g){g=b+4-g|0;while((b|0)<(g|0)){a[b>>0]=d;b=b+1|0}}while((b|0)<(i|0)){c[b>>2]=h;b=b+4|0}}while((b|0)<(f|0)){a[b>>0]=d;b=b+1|0}return b-e|0}function ie(b,d,e){b=b|0;d=d|0;e=e|0;var f=0;if((e|0)>=4096)return gc(b|0,d|0,e|0)|0;f=b|0;if((b&3)==(d&3)){while(b&3){if((e|0)==0)return f|0;a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0;e=e-1|0}while((e|0)>=4){c[b>>2]=c[d>>2];b=b+4|0;d=d+4|0;e=e-4|0}}while((e|0)>0){a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0;e=e-1|0}return f|0}function je(a,b,c){a=a|0;b=b|0;c=c|0;if((c|0)<32){E=b<>>32-c;return a<>c;return a>>>c|(b&(1<>c-32|0}function le(b){b=b|0;var c=0;c=a[n+(b>>>24)>>0]|0;if((c|0)<8)return c|0;c=a[n+(b>>16&255)>>0]|0;if((c|0)<8)return c+8|0;c=a[n+(b>>8&255)>>0]|0;if((c|0)<8)return c+16|0;return(a[n+(b&255)>>0]|0)+24|0}function me(b){b=b|0;var c=0;c=a[m+(b&255)>>0]|0;if((c|0)<8)return c|0;c=a[m+(b>>8&255)>>0]|0;if((c|0)<8)return c+8|0;c=a[m+(b>>16&255)>>0]|0;if((c|0)<8)return c+16|0;return(a[m+(b>>>24)>>0]|0)+24|0}function ne(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0;c=a&65535;d=b&65535;e=aa(d,c)|0;f=a>>>16;a=(e>>>16)+(aa(d,f)|0)|0;d=b>>>16;b=aa(d,c)|0;return(E=(a>>>16)+(aa(d,f)|0)+(((a&65535)+b|0)>>>16)|0,a+b<<16|e&65535|0)|0}function oe(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0,i=0;e=b>>31|((b|0)<0?-1:0)<<1;f=((b|0)<0?-1:0)>>31|((b|0)<0?-1:0)<<1;g=d>>31|((d|0)<0?-1:0)<<1;h=((d|0)<0?-1:0)>>31|((d|0)<0?-1:0)<<1;i=de(e^a,f^b,e,f)|0;b=E;a=g^e;e=h^f;f=de((te(i,b,de(g^c,h^d,g,h)|0,E,0)|0)^a,E^e,a,e)|0;return f|0}function pe(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0;f=i;i=i+8|0;g=f|0;h=b>>31|((b|0)<0?-1:0)<<1;j=((b|0)<0?-1:0)>>31|((b|0)<0?-1:0)<<1;k=e>>31|((e|0)<0?-1:0)<<1;l=((e|0)<0?-1:0)>>31|((e|0)<0?-1:0)<<1;m=de(h^a,j^b,h,j)|0;b=E;te(m,b,de(k^d,l^e,k,l)|0,E,g)|0;l=de(c[g>>2]^h,c[g+4>>2]^j,h,j)|0;j=E;i=f;return(E=j,l)|0}function qe(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0;e=a;a=c;c=ne(e,a)|0;f=E;return(E=(aa(b,a)|0)+(aa(d,e)|0)+f|f&0,c|0|0)|0}function re(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0;e=te(a,b,c,d,0)|0;return e|0}function se(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0;f=i;i=i+8|0;g=f|0;te(a,b,d,e,g)|0;i=f;return(E=c[g+4>>2]|0,c[g>>2]|0)|0} - - - -function Cc(a){a=a|0;var b=0;b=i;i=i+a|0;i=i+7&-8;return b|0}function Dc(){return i|0}function Ec(a){a=a|0;i=a}function Fc(a,b){a=a|0;b=b|0;if((p|0)==0){p=a;q=b}}function Gc(b){b=b|0;a[k>>0]=a[b>>0];a[k+1>>0]=a[b+1>>0];a[k+2>>0]=a[b+2>>0];a[k+3>>0]=a[b+3>>0]}function Hc(b){b=b|0;a[k>>0]=a[b>>0];a[k+1>>0]=a[b+1>>0];a[k+2>>0]=a[b+2>>0];a[k+3>>0]=a[b+3>>0];a[k+4>>0]=a[b+4>>0];a[k+5>>0]=a[b+5>>0];a[k+6>>0]=a[b+6>>0];a[k+7>>0]=a[b+7>>0]}function Ic(a){a=a|0;E=a}function Jc(){return E|0}function Kc(a,b,c,d,e,f){a=a|0;b=b|0;c=c|0;d=d|0;e=+e;f=f|0;var h=0,j=0.0,k=0,l=0.0,m=0,n=0.0,o=0,p=0.0,q=0,r=0.0,s=0.0,t=0.0,u=0.0,v=0;h=i;j=+g[a>>2];k=a+4|0;l=+g[k>>2];m=b+4|0;n=e*.5;e=+g[c>>2];o=c+4|0;p=+g[o>>2];q=d+4|0;r=e*+g[d>>2]+p*+g[q>>2];s=j*e+l*p-r;t=(j+ +g[b>>2])*e+(l+ +g[m>>2])*p-r;if((!(!(s>=-9999999747378752.0e-20)|!(t<=9999999747378752.0e-20))?(r=s/(s-t),g[f>>2]=r,t=+g[o>>2],s=-t,p=+g[c>>2],l=+g[d>>2],e=n*p,j=+g[q>>2],u=(r*+g[b>>2]+ +g[a>>2])*s+(r*+g[m>>2]+ +g[k>>2])*p,(n*t+l)*s+p*(j-e)-u<=0.0):0)?u-((n*s+l)*s+p*(e+j))<=0.0:0){v=1;i=h;return v|0}v=0;i=h;return v|0}function Lc(a,b,d,e,f,h,j){a=a|0;b=+b;d=+d;e=+e;f=+f;h=+h;j=+j;var k=0,l=0.0,m=0.0,n=0.0,o=0.0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0;k=i;l=+g[1566];m=+g[1568];n=+g[1570];o=+g[1572];p=a+8|0;q=c[p>>2]|0;r=a+4|0;s=c[r>>2]|0;if((q|0)>(s|0)){t=s;u=c[a>>2]|0}else{c[p>>2]=q<<1;v=Pd(q<<6)|0;q=c[a>>2]|0;ie(v|0,q|0,s<<5|0)|0;Qd(q);c[a>>2]=v;t=c[r>>2]|0;u=v}v=t<<3;g[u+(v<<2)>>2]=b;g[u+((v|1)<<2)>>2]=d;g[u+((v|2)<<2)>>2]=e;g[u+((v|3)<<2)>>2]=0.0;g[u+((v|4)<<2)>>2]=l;g[u+((v|5)<<2)>>2]=m;g[u+((v|6)<<2)>>2]=n;g[u+((v|7)<<2)>>2]=o;v=(c[r>>2]|0)+1|0;c[r>>2]=v;u=c[p>>2]|0;if((u|0)>(v|0)){w=v;x=c[a>>2]|0}else{c[p>>2]=u<<1;t=Pd(u<<6)|0;u=c[a>>2]|0;ie(t|0,u|0,v<<5|0)|0;Qd(u);c[a>>2]=t;w=c[r>>2]|0;x=t}t=w<<3;g[x+(t<<2)>>2]=f;g[x+((t|1)<<2)>>2]=d;g[x+((t|2)<<2)>>2]=j;g[x+((t|3)<<2)>>2]=0.0;g[x+((t|4)<<2)>>2]=l;g[x+((t|5)<<2)>>2]=m;g[x+((t|6)<<2)>>2]=n;g[x+((t|7)<<2)>>2]=o;t=(c[r>>2]|0)+1|0;c[r>>2]=t;x=c[p>>2]|0;if((x|0)>(t|0)){y=t;z=c[a>>2]|0}else{c[p>>2]=x<<1;w=Pd(x<<6)|0;x=c[a>>2]|0;ie(w|0,x|0,t<<5|0)|0;Qd(x);c[a>>2]=w;y=c[r>>2]|0;z=w}w=y<<3;g[z+(w<<2)>>2]=f;g[z+((w|1)<<2)>>2]=h;g[z+((w|2)<<2)>>2]=j;g[z+((w|3)<<2)>>2]=1.0;g[z+((w|4)<<2)>>2]=l;g[z+((w|5)<<2)>>2]=m;g[z+((w|6)<<2)>>2]=n;g[z+((w|7)<<2)>>2]=o;w=(c[r>>2]|0)+1|0;c[r>>2]=w;z=c[p>>2]|0;if((z|0)>(w|0)){A=w;B=c[a>>2]|0}else{c[p>>2]=z<<1;y=Pd(z<<6)|0;z=c[a>>2]|0;ie(y|0,z|0,w<<5|0)|0;Qd(z);c[a>>2]=y;A=c[r>>2]|0;B=y}y=A<<3;g[B+(y<<2)>>2]=f;g[B+((y|1)<<2)>>2]=h;g[B+((y|2)<<2)>>2]=j;g[B+((y|3)<<2)>>2]=1.0;g[B+((y|4)<<2)>>2]=l;g[B+((y|5)<<2)>>2]=m;g[B+((y|6)<<2)>>2]=n;g[B+((y|7)<<2)>>2]=o;y=(c[r>>2]|0)+1|0;c[r>>2]=y;B=c[p>>2]|0;if((B|0)>(y|0)){C=y;D=c[a>>2]|0}else{c[p>>2]=B<<1;A=Pd(B<<6)|0;B=c[a>>2]|0;ie(A|0,B|0,y<<5|0)|0;Qd(B);c[a>>2]=A;C=c[r>>2]|0;D=A}A=C<<3;g[D+(A<<2)>>2]=b;g[D+((A|1)<<2)>>2]=h;g[D+((A|2)<<2)>>2]=e;g[D+((A|3)<<2)>>2]=1.0;g[D+((A|4)<<2)>>2]=l;g[D+((A|5)<<2)>>2]=m;g[D+((A|6)<<2)>>2]=n;g[D+((A|7)<<2)>>2]=o;A=(c[r>>2]|0)+1|0;c[r>>2]=A;D=c[p>>2]|0;if((D|0)>(A|0)){E=A;F=c[a>>2]|0;G=E<<3;H=F+(G<<2)|0;g[H>>2]=b;I=G|1;J=F+(I<<2)|0;g[J>>2]=d;K=G|2;L=F+(K<<2)|0;g[L>>2]=e;M=G|3;N=F+(M<<2)|0;g[N>>2]=0.0;O=G|4;P=F+(O<<2)|0;g[P>>2]=l;Q=G|5;R=F+(Q<<2)|0;g[R>>2]=m;S=G|6;T=F+(S<<2)|0;g[T>>2]=n;U=G|7;V=F+(U<<2)|0;g[V>>2]=o;W=c[r>>2]|0;X=W+1|0;c[r>>2]=X;i=k;return}else{c[p>>2]=D<<1;p=Pd(D<<6)|0;D=c[a>>2]|0;ie(p|0,D|0,A<<5|0)|0;Qd(D);c[a>>2]=p;E=c[r>>2]|0;F=p;G=E<<3;H=F+(G<<2)|0;g[H>>2]=b;I=G|1;J=F+(I<<2)|0;g[J>>2]=d;K=G|2;L=F+(K<<2)|0;g[L>>2]=e;M=G|3;N=F+(M<<2)|0;g[N>>2]=0.0;O=G|4;P=F+(O<<2)|0;g[P>>2]=l;Q=G|5;R=F+(Q<<2)|0;g[R>>2]=m;S=G|6;T=F+(S<<2)|0;g[T>>2]=n;U=G|7;V=F+(U<<2)|0;g[V>>2]=o;W=c[r>>2]|0;X=W+1|0;c[r>>2]=X;i=k;return}}function Mc(b,e,f,g,h){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Fa=0,Ga=0,Ha=0,Ia=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Ua=0,Va=0,Wa=0,Xa=0,Ya=0,Za=0,_a=0,$a=0,ab=0,bb=0,cb=0,db=0,eb=0,fb=0,gb=0,hb=0,ib=0,jb=0,kb=0,lb=0,mb=0,nb=0,ob=0,pb=0,qb=0,rb=0,sb=0,tb=0,ub=0,vb=0,wb=0,xb=0,yb=0,zb=0,Ab=0,Bb=0,Cb=0,Db=0,Eb=0,Fb=0,Gb=0,Hb=0,Ib=0;j=i;i=i+64|0;k=j+40|0;l=j;m=j+20|0;if(g>>>0<2){n=53;i=j;return n|0}o=a[f>>0]|0;p=o&255;q=d[f+1>>0]|0;if((((p<<8|q)>>>0)%31|0|0)!=0){n=24;i=j;return n|0}if((p&15|0)!=8|o<<24>>24<0){n=25;i=j;return n|0}if((q&32|0)!=0){n=26;i=j;return n|0}q=g+ -2|0;o=c[h+8>>2]|0;if((o|0)==0){p=c[e>>2]|0;r=q<<3;s=l+4|0;t=l+8|0;u=m+4|0;v=m+8|0;w=l+16|0;x=m+16|0;y=m+12|0;z=g+ -4|0;A=k+4|0;B=k+8|0;C=k+16|0;D=k+12|0;E=l+12|0;F=g+ -6|0;G=0;H=0;I=p;J=p;p=c[b>>2]|0;while(1){K=G+2|0;if(!(K>>>0>>0)){L=52;M=p;N=I;break}O=d[f+((G>>>3)+2)>>0]|0;P=G&7;Q=G+1|0;R=G+3|0;S=(d[f+((K>>>3)+2)>>0]|0)>>>(K&7)<<1&2|(d[f+((Q>>>3)+2)>>0]|0)>>>(Q&7)&1;if((S|0)==0){if((R&7|0)==0){T=R}else{Q=R;while(1){K=Q+1|0;if((K&7|0)==0){T=K;break}else{Q=K}}}Q=T>>>3;if(!(Q>>>0>>0)){L=52;M=p;N=I;break}K=(d[f+(Q+3)>>0]|0)<<8|(d[f+(Q+2)>>0]|0);U=Q+4|0;if((((d[f+(Q+5)>>0]|0)<<8|(d[f+U>>0]|0))+K|0)!=65535){L=21;M=p;N=I;break}V=K+H|0;if(!(V>>>0>>0)){if(J>>>0>>0){W=V<<1;X=Rd(p,W)|0;if((X|0)==0){L=83;M=p;N=I;break}else{Y=X;Z=W;_=V}}else{Y=p;Z=J;_=V}}else{Y=p;Z=J;_=I}W=K+U|0;if(W>>>0>q>>>0){L=23;M=Y;N=_;break}if((K|0)!=0){X=H+1|0;a[Y+H>>0]=a[f+(Q+6)>>0]|0;if((K|0)==1){$=X;aa=W}else{Q=X;X=1;ba=U;while(1){X=X+1|0;a[Y+Q>>0]=a[f+(ba+3)>>0]|0;if((X|0)==(K|0)){$=V;aa=W;break}else{Q=Q+1|0;ba=ba+1|0}}}}else{$=H;aa=U}ca=aa<<3;da=$;ea=Z;fa=Y;ga=_}else if((S|0)!=3){c[l>>2]=0;c[s>>2]=0;c[t>>2]=0;c[m>>2]=0;c[u>>2]=0;c[v>>2]=0;if((S|0)==2){ba=R>>>3;if(ba>>>0>>0){Q=G+4|0;W=G+5|0;V=G+6|0;K=G+7|0;X=(d[f+((Q>>>3)+2)>>0]|0)>>>(Q&7)<<1&2|(d[f+(ba+2)>>0]|0)>>>(R&7)&1|(d[f+((W>>>3)+2)>>0]|0)>>>(W&7)<<2&4|(d[f+((V>>>3)+2)>>0]|0)>>>(V&7)<<3&8|(d[f+((K>>>3)+2)>>0]|0)>>>(K&7)<<4&16;K=G+8|0;V=X+257|0;W=G+9|0;ba=G+10|0;Q=G+11|0;ha=G+12|0;ia=(d[f+((W>>>3)+2)>>0]|0)>>>(W&7)<<1&2|(d[f+((K>>>3)+2)>>0]|0)>>>(K&7)&1|(d[f+((ba>>>3)+2)>>0]|0)>>>(ba&7)<<2&4|(d[f+((Q>>>3)+2)>>0]|0)>>>(Q&7)<<3&8|(d[f+((ha>>>3)+2)>>0]|0)>>>(ha&7)<<4&16;ha=G+13|0;Q=G+14|0;ba=G+15|0;K=G+16|0;W=G+17|0;ja=((d[f+((Q>>>3)+2)>>0]|0)>>>(Q&7)<<1&2|(d[f+((ha>>>3)+2)>>0]|0)>>>(ha&7)&1|(d[f+((ba>>>3)+2)>>0]|0)>>>(ba&7)<<2&4|(d[f+((K>>>3)+2)>>0]|0)>>>(K&7)<<3&8)+4|0;c[k>>2]=0;c[A>>2]=0;c[B>>2]=0;K=Pd(76)|0;a:do{if((K|0)!=0){ba=W;ha=0;while(1){if(ha>>>0>>0){Q=ba+1|0;ka=ba+2|0;c[K+(c[8472+(ha<<2)>>2]<<2)>>2]=(d[f+((Q>>>3)+2)>>0]|0)>>>(Q&7)<<1&2|(d[f+((ba>>>3)+2)>>0]|0)>>>(ba&7)&1|(d[f+((ka>>>3)+2)>>0]|0)>>>(ka&7)<<2&4;la=ba+3|0}else{c[K+(c[8472+(ha<<2)>>2]<<2)>>2]=0;la=ba}ha=ha+1|0;if((ha|0)==19){break}else{ba=la}}ba=Pd(76)|0;c[B>>2]=ba;if((ba|0)!=0){ma=ba+0|0;na=K+0|0;oa=ma+76|0;do{c[ma>>2]=c[na>>2];ma=ma+4|0;na=na+4|0}while((ma|0)<(oa|0));c[C>>2]=19;c[D>>2]=7;ba=Zc(k)|0;if((ba|0)==0){ha=Pd(1152)|0;ka=Pd(128)|0;if(!((ha|0)==0|(ka|0)==0)){he(ha|0,0,1152)|0;ma=ka+0|0;oa=ma+128|0;do{c[ma>>2]=0;ma=ma+4|0}while((ma|0)<(oa|0));Q=X+258|0;pa=ia+Q|0;if((pa|0)!=0){qa=c[k>>2]|0;ra=c[C>>2]|0;sa=-258-X|0;ta=la;ua=0;va=0;b:while(1){wa=ta;xa=va;while(1){ya=wa;za=0;while(1){if(!(ya>>>0>>0)){Aa=ya;Ba=83;break b}Ca=c[qa+(((d[f+((ya>>>3)+2)>>0]|0)>>>(ya&7)&1|za<<1)<<2)>>2]|0;Da=ya+1|0;if(Ca>>>0>>0){break}za=Ca-ra|0;if(!(za>>>0>>0)){Aa=Da;Ba=83;break b}else{ya=Da}}if(!(Ca>>>0<16)){break}if(xa>>>0>>0){c[ha+(xa<<2)>>2]=Ca}else{c[ka+(xa-V<<2)>>2]=Ca}za=xa+1|0;if(za>>>0>>0){wa=Da;xa=za}else{Ea=Da;Fa=ua;break b}}c:do{if((Ca|0)==18){if(!(Da>>>0>>0)){Ga=Da;Ha=ka;Ia=ha;Ja=50;break a}wa=ya+2|0;za=ya+3|0;Ka=ya+4|0;La=ya+5|0;Ma=ya+6|0;Na=ya+7|0;Oa=ya+8|0;Pa=((d[f+((wa>>>3)+2)>>0]|0)>>>(wa&7)<<1&2|(d[f+((Da>>>3)+2)>>0]|0)>>>(Da&7)&1|(d[f+((za>>>3)+2)>>0]|0)>>>(za&7)<<2&4|(d[f+((Ka>>>3)+2)>>0]|0)>>>(Ka&7)<<3&8|(d[f+((La>>>3)+2)>>0]|0)>>>(La&7)<<4&16|(d[f+((Ma>>>3)+2)>>0]|0)>>>(Ma&7)<<5&32|(d[f+((Na>>>3)+2)>>0]|0)>>>(Na&7)<<6&64)+11|0;if((Pa|0)==0){Qa=Oa;Ra=ua;Sa=xa;break}else{Ta=xa;Ua=0}while(1){if(!(Ta>>>0>>0)){Qa=Oa;Ra=15;Sa=Ta;break c}if(Ta>>>0>>0){c[ha+(Ta<<2)>>2]=0}else{c[ka+(Ta-V<<2)>>2]=0}Na=Ta+1|0;Ua=Ua+1|0;if(!(Ua>>>0>>0)){Qa=Oa;Ra=ua;Sa=Na;break}else{Ta=Na}}}else if((Ca|0)==17){if(!(Da>>>0>>0)){Ga=Da;Ha=ka;Ia=ha;Ja=50;break a}Oa=ya+2|0;Pa=ya+3|0;Na=ya+4|0;Ma=((d[f+((Oa>>>3)+2)>>0]|0)>>>(Oa&7)<<1&2|(d[f+((Da>>>3)+2)>>0]|0)>>>(Da&7)&1|(d[f+((Pa>>>3)+2)>>0]|0)>>>(Pa&7)<<2&4)+3|0;Pa=xa;Oa=0;while(1){if(!(Pa>>>0>>0)){Qa=Na;Ra=14;Sa=Pa;break c}if(Pa>>>0>>0){c[ha+(Pa<<2)>>2]=0}else{c[ka+(Pa-V<<2)>>2]=0}La=Pa+1|0;Oa=Oa+1|0;if(!(Oa>>>0>>0)){Qa=Na;Ra=ua;Sa=La;break}else{Pa=La}}}else if((Ca|0)==16){if(!(Da>>>0>>0)){Ga=Da;Ha=ka;Ia=ha;Ja=50;break a}if((xa|0)==0){Ga=Da;Ha=ka;Ia=ha;Ja=54;break a}Pa=ya+2|0;Na=ya+3|0;Ma=((d[f+((Pa>>>3)+2)>>0]|0)>>>(Pa&7)<<1&2|(d[f+((Da>>>3)+2)>>0]|0)>>>(Da&7)&1)+3|0;if(xa>>>0>>0){Va=ha+(xa+ -1<<2)|0}else{Va=ka+(sa+xa<<2)|0}Pa=c[Va>>2]|0;Oa=xa;La=0;while(1){if(!(Oa>>>0>>0)){Qa=Na;Ra=13;Sa=Oa;break c}if(Oa>>>0>>0){c[ha+(Oa<<2)>>2]=Pa}else{c[ka+(Oa-V<<2)>>2]=Pa}Ka=Oa+1|0;La=La+1|0;if(!(La>>>0>>0)){Qa=Na;Ra=ua;Sa=Ka;break}else{Oa=Ka}}}else if((Ca|0)==-1){Aa=Da;Ba=83;break b}else{Ga=Da;Ha=ka;Ia=ha;Ja=16;break a}}while(0);if(Sa>>>0>>0){ta=Qa;ua=Ra;va=Sa}else{Ea=Qa;Fa=Ra;break}}if((Ba|0)==83){Ba=0;Ga=Aa;Ha=ka;Ia=ha;Ja=Aa>>>0>r>>>0?10:11;break}if((Fa|0)==0){if((c[ha+1024>>2]|0)!=0){va=Pd(1152)|0;c[t>>2]=va;if((va|0)==0){Ga=Ea;Ha=ka;Ia=ha;Ja=83}else{ie(va|0,ha|0,1152)|0;c[w>>2]=288;c[E>>2]=15;va=Zc(l)|0;if((va|0)!=0){Ga=Ea;Ha=ka;Ia=ha;Ja=va;break}va=Pd(128)|0;c[v>>2]=va;if((va|0)==0){Ga=Ea;Ha=ka;Ia=ha;Ja=83;break}ma=va+0|0;na=ka+0|0;oa=ma+128|0;do{c[ma>>2]=c[na>>2];ma=ma+4|0;na=na+4|0}while((ma|0)<(oa|0));c[x>>2]=32;c[y>>2]=15;Ga=Ea;Ha=ka;Ia=ha;Ja=Zc(m)|0}}else{Ga=Ea;Ha=ka;Ia=ha;Ja=64}}else{Ga=Ea;Ha=ka;Ia=ha;Ja=Fa}}else{Ga=la;Ha=ka;Ia=ha;Ja=64}}else{Ga=la;Ha=ka;Ia=ha;Ja=83}}else{Ga=la;Ha=0;Ia=0;Ja=ba}}else{Ga=la;Ha=0;Ia=0;Ja=83}}else{Ga=W;Ha=0;Ia=0;Ja=83}}while(0);Qd(K);Qd(Ia);Qd(Ha);Qd(c[k>>2]|0);Qd(c[A>>2]|0);Qd(c[B>>2]|0);if((Ja|0)==0){Wa=Ga;Ba=92}else{Xa=c[l>>2]|0;Ya=c[m>>2]|0;Za=J;_a=I;$a=p;ab=Ga;bb=H;cb=Ja}}else{Xa=0;Ya=0;Za=J;_a=I;$a=p;ab=R;bb=H;cb=49}}else if((S|0)==1){W=Pd(1152)|0;if((W|0)!=0){V=0;do{c[W+(V<<2)>>2]=8;V=V+1|0}while((V|0)!=144);db=144;do{c[W+(db<<2)>>2]=9;db=db+1|0}while((db|0)!=256);c[W+1024>>2]=7;c[W+1028>>2]=7;c[W+1032>>2]=7;c[W+1036>>2]=7;c[W+1040>>2]=7;c[W+1044>>2]=7;c[W+1048>>2]=7;c[W+1052>>2]=7;c[W+1056>>2]=7;c[W+1060>>2]=7;c[W+1064>>2]=7;c[W+1068>>2]=7;c[W+1072>>2]=7;c[W+1076>>2]=7;c[W+1080>>2]=7;c[W+1084>>2]=7;c[W+1088>>2]=7;c[W+1092>>2]=7;c[W+1096>>2]=7;c[W+1100>>2]=7;c[W+1104>>2]=7;c[W+1108>>2]=7;c[W+1112>>2]=7;c[W+1116>>2]=7;c[W+1120>>2]=8;c[W+1124>>2]=8;c[W+1128>>2]=8;c[W+1132>>2]=8;c[W+1136>>2]=8;c[W+1140>>2]=8;c[W+1144>>2]=8;c[W+1148>>2]=8;V=Pd(1152)|0;c[t>>2]=V;if((V|0)!=0){S=0;do{c[V+(S<<2)>>2]=c[W+(S<<2)>>2];S=S+1|0}while((S|0)!=288);c[w>>2]=288;c[E>>2]=15;Zc(l)|0}Qd(W)}S=Pd(128)|0;if((S|0)!=0){V=0;do{c[S+(V<<2)>>2]=5;V=V+1|0}while((V|0)!=32);V=Pd(128)|0;c[v>>2]=V;if((V|0)!=0){ma=V+0|0;na=S+0|0;oa=ma+128|0;do{c[ma>>2]=c[na>>2];ma=ma+4|0;na=na+4|0}while((ma|0)<(oa|0));c[x>>2]=32;c[y>>2]=15;Zc(m)|0}Qd(S);Wa=R;Ba=92}else{Wa=R;Ba=92}}else{Wa=R;Ba=92}d:do{if((Ba|0)==92){Ba=0;V=c[l>>2]|0;W=c[w>>2]|0;K=c[m>>2]|0;X=c[x>>2]|0;ia=Wa;ja=H;U=J;va=I;ua=p;e:while(1){eb=U;fb=va;gb=ua;ta=ia;while(1){pa=ta;sa=0;while(1){if(!(pa>>>0>>0)){hb=pa;break e}ib=c[V+(((d[f+((pa>>>3)+2)>>0]|0)>>>(pa&7)&1|sa<<1)<<2)>>2]|0;jb=pa+1|0;if(ib>>>0>>0){break}sa=ib-W|0;if(!(sa>>>0>>0)){hb=jb;break e}else{pa=jb}}if(ib>>>0<256){break}pa=ib+ -257|0;if(!(pa>>>0<29)){Ba=126;break e}if(!(jb>>>0>>0)){Xa=V;Ya=K;Za=eb;_a=fb;$a=gb;ab=jb;bb=ja;cb=51;break d}sa=c[8552+(pa<<2)>>2]|0;Q=c[8792+(pa<<2)>>2]|0;if((ib+ -265|0)>>>0>19){kb=jb;lb=0}else{pa=jb;ra=0;qa=0;while(1){qa=(((d[f+((pa>>>3)+2)>>0]|0)>>>(pa&7)&1)<>>0>>0)){nb=pa;Ba=113;break e}ob=c[K+(((d[f+((pa>>>3)+2)>>0]|0)>>>(pa&7)&1|ra<<1)<<2)>>2]|0;pb=pa+1|0;if(ob>>>0>>0){break}ra=ob-X|0;if(!(ra>>>0>>0)){nb=pb;Ba=113;break e}else{pa=pb}}if(ob>>>0>29){nb=pb;Ba=113;break e}if(!(pb>>>0>>0)){Xa=V;Ya=K;Za=eb;_a=fb;$a=gb;ab=pb;bb=ja;cb=51;break d}pa=c[8672+(ob<<2)>>2]|0;ra=c[8912+(ob<<2)>>2]|0;if(ob>>>0<4){qb=pb;rb=0}else{Q=pb;qa=0;sa=0;while(1){sa=(((d[f+((Q>>>3)+2)>>0]|0)>>>(Q&7)&1)<>>0>ja>>>0){Xa=V;Ya=K;Za=eb;_a=fb;$a=gb;ab=qb;bb=ja;cb=52;break d}tb=mb+ja|0;do{if(!(tb>>>0>>0)){Q=tb<<1;if(!(eb>>>0>>0)){ub=gb;vb=eb;wb=Q;break}qa=tb<<2;xa=Rd(gb,qa)|0;if((xa|0)==0){Xa=V;Ya=K;Za=eb;_a=fb;$a=gb;ab=qb;bb=ja;cb=83;break d}else{ub=xa;vb=qa;wb=Q}}else{ub=gb;vb=eb;wb=fb}}while(0);if((mb|0)==0){eb=vb;fb=wb;gb=ub;ta=qb}else{Ba=124;break}}if((Ba|0)==124){Ba=0;ta=ja-sb|0;a[ub+ja>>0]=a[ub+ta>>0]|0;ra=ja+1|0;if((mb|0)==1){ia=qb;ja=ra;U=vb;va=wb;ua=ub;continue}else{xb=ta;yb=ra;zb=1}while(1){ra=xb+1|0;sa=ra>>>0>>0?ra:ta;ra=zb+1|0;a[ub+yb>>0]=a[ub+sa>>0]|0;if((ra|0)==(mb|0)){ia=qb;ja=tb;U=vb;va=wb;ua=ub;continue e}else{xb=sa;yb=yb+1|0;zb=ra}}}if(!(ja>>>0>>0)){ta=(ja<<1)+2|0;if(eb>>>0>>0){ra=ta<<1;sa=Rd(gb,ra)|0;if((sa|0)==0){Xa=V;Ya=K;Za=eb;_a=fb;$a=gb;ab=jb;bb=ja;cb=83;break d}else{Ab=sa;Bb=ra;Cb=ta}}else{Ab=gb;Bb=eb;Cb=ta}}else{Ab=gb;Bb=eb;Cb=fb}a[Ab+ja>>0]=ib;ia=jb;ja=ja+1|0;U=Bb;va=Cb;ua=Ab}if((Ba|0)==113){Ba=0;if(!((ib|0)==-1)){Xa=V;Ya=K;Za=eb;_a=fb;$a=gb;ab=nb;bb=ja;cb=18;break}Xa=V;Ya=K;Za=eb;_a=fb;$a=gb;ab=nb;bb=ja;cb=nb>>>0>r>>>0?10:11;break}else if((Ba|0)==126){Ba=0;if((ib|0)==256){Xa=V;Ya=K;Za=eb;_a=fb;$a=gb;ab=jb;bb=ja;cb=0;break}else{hb=jb}}Xa=V;Ya=K;Za=eb;_a=fb;$a=gb;ab=hb;bb=ja;cb=hb>>>0>r>>>0?10:11}}while(0);Qd(Xa);Qd(c[s>>2]|0);Qd(c[t>>2]|0);Qd(Ya);Qd(c[u>>2]|0);Qd(c[v>>2]|0);if((cb|0)==0){ca=ab;da=bb;ea=Za;fa=$a;ga=_a}else{L=cb;M=$a;N=_a;break}}else{L=20;M=p;N=I;break}if((O&1<>>0>>0){ea=Rd(fa,da<<1)|0;Ba=(ea|0)==0;L=Ba?83:0;M=Ba?fa:ea;N=Ba?ga:da}else{L=0;M=fa;N=da}}c[b>>2]=M;c[e>>2]=N;Db=L}else{Db=tc[o&0](b,e,f+2|0,q,h)|0}if((Db|0)!=0){n=Db;i=j;return n|0}if((c[h>>2]|0)==0){h=(d[f+(g+ -3)>>0]|0)<<16|(d[f+(g+ -4)>>0]|0)<<24|(d[f+q>>0]|0)<<8|(d[f+(g+ -1)>>0]|0);g=c[e>>2]|0;if((g|0)==0){Eb=1;Fb=0}else{e=c[b>>2]|0;b=g;g=1;f=0;while(1){q=b>>>0>5550?5550:b;Db=b;b=b-q|0;if((q|0)==0){Gb=e;Hb=g;Ib=f}else{o=e;L=q;N=g;M=f;while(1){N=(d[o>>0]|0)+N|0;M=N+M|0;L=L+ -1|0;if((L|0)==0){break}else{o=o+1|0}}Gb=e+(Db>>>0<5550?Db:5550)|0;Hb=N;Ib=M}g=(Hb>>>0)%65521|0;f=(Ib>>>0)%65521|0;if((Db|0)==(q|0)){break}else{e=Gb}}Eb=g;Fb=f<<16}if((Eb|Fb|0)!=(h|0)){n=58;i=j;return n|0}}n=0;i=j;return n|0}function Nc(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0;f=i;g=b+64|0;h=b+60|0;j=Rd(c[g>>2]|0,(c[h>>2]<<2)+4|0)|0;k=b+68|0;b=Rd(c[k>>2]|0,(c[h>>2]<<2)+4|0)|0;if((j|0)==0|(b|0)==0){Qd(j);Qd(b);l=83;i=f;return l|0}m=c[h>>2]|0;c[h>>2]=m+1;c[g>>2]=j;c[k>>2]=b;b=j+(m<<2)|0;c[b>>2]=0;m=Pd(1)|0;if((m|0)!=0){a[m>>0]=0;c[b>>2]=m}m=(c[g>>2]|0)+((c[h>>2]|0)+ -1<<2)|0;g=fe(d|0)|0;b=Rd(c[m>>2]|0,g+1|0)|0;if(((b|0)!=0?(a[b+g>>0]=0,c[m>>2]=b,(g|0)!=0):0)?(a[b>>0]=a[d>>0]|0,(g|0)!=1):0){b=1;do{a[(c[m>>2]|0)+b>>0]=a[d+b>>0]|0;b=b+1|0}while((b|0)!=(g|0))}g=(c[k>>2]|0)+((c[h>>2]|0)+ -1<<2)|0;c[g>>2]=0;b=Pd(1)|0;if((b|0)!=0){a[b>>0]=0;c[g>>2]=b}b=(c[k>>2]|0)+((c[h>>2]|0)+ -1<<2)|0;h=fe(e|0)|0;k=Rd(c[b>>2]|0,h+1|0)|0;if((k|0)==0){l=0;i=f;return l|0}a[k+h>>0]=0;c[b>>2]=k;if((h|0)==0){l=0;i=f;return l|0}a[k>>0]=a[e>>0]|0;if((h|0)==1){l=0;i=f;return l|0}else{n=1}do{a[(c[b>>2]|0)+n>>0]=a[e+n>>0]|0;n=n+1|0}while((n|0)!=(h|0));l=0;i=f;return l|0}function Oc(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0;b=i;d=a+20|0;e=c[d>>2]|0;if((e|0)!=0){Qd(e)}c[d>>2]=0;c[a+24>>2]=0;d=a+60|0;e=a+64|0;f=c[e>>2]|0;g=a+68|0;if((c[d>>2]|0)==0){h=f}else{j=f;f=0;while(1){k=j+(f<<2)|0;Qd(c[k>>2]|0);c[k>>2]=0;k=(c[g>>2]|0)+(f<<2)|0;Qd(c[k>>2]|0);c[k>>2]=0;f=f+1|0;k=c[e>>2]|0;if(!(f>>>0<(c[d>>2]|0)>>>0)){h=k;break}else{j=k}}}Qd(h);Qd(c[g>>2]|0);g=a+72|0;h=a+76|0;j=c[h>>2]|0;d=a+80|0;f=a+84|0;e=a+88|0;if((c[g>>2]|0)==0){l=j}else{k=j;j=0;while(1){m=k+(j<<2)|0;Qd(c[m>>2]|0);c[m>>2]=0;m=(c[d>>2]|0)+(j<<2)|0;Qd(c[m>>2]|0);c[m>>2]=0;m=(c[f>>2]|0)+(j<<2)|0;Qd(c[m>>2]|0);c[m>>2]=0;m=(c[e>>2]|0)+(j<<2)|0;Qd(c[m>>2]|0);c[m>>2]=0;j=j+1|0;m=c[h>>2]|0;if(!(j>>>0<(c[g>>2]|0)>>>0)){l=m;break}else{k=m}}}Qd(l);Qd(c[d>>2]|0);Qd(c[f>>2]|0);Qd(c[e>>2]|0);Qd(c[a+136>>2]|0);Qd(c[a+140>>2]|0);Qd(c[a+144>>2]|0);i=b;return}function Pc(b,e,f,g,h,j){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0;k=i;l=(f|0)!=0;f=l?4:3;switch(c[h>>2]|0){case 3:{if((e|0)==0){m=0;i=k;return m|0}n=h+4|0;o=h+12|0;p=h+8|0;q=(j|0)==0;j=b;r=0;s=0;while(1){t=c[n>>2]|0;if((t|0)==8){u=r;v=d[g+s>>0]|0}else if((t|0)==0){u=r;v=0}else{w=r;x=t+ -1|0;y=0;while(1){z=w+1|0;A=(((d[g+(w>>>3)>>0]|0)>>>(w&7^7)&1)<>>0>>0)){u=z;v=A;break}else{w=z;y=A}}}if(v>>>0<(c[o>>2]|0)>>>0){y=v<<2;a[j>>0]=a[(c[p>>2]|0)+y>>0]|0;a[j+1>>0]=a[(c[p>>2]|0)+(y|1)>>0]|0;a[j+2>>0]=a[(c[p>>2]|0)+(y|2)>>0]|0;if(l){a[j+3>>0]=a[(c[p>>2]|0)+(y|3)>>0]|0}}else{if(q){break}a[j+2>>0]=0;a[j+1>>0]=0;a[j>>0]=0;if(l){a[j+3>>0]=-1}}s=s+1|0;if(!(s>>>0>>0)){m=0;B=78;break}else{j=j+f|0;r=u}}if((B|0)==78){i=k;return m|0}m=(t|0)==8?46:47;i=k;return m|0};case 0:{t=h+4|0;B=c[t>>2]|0;if((B|0)==16){if((e|0)==0){m=0;i=k;return m|0}u=h+16|0;r=h+20|0;j=b;s=0;while(1){q=s<<1;p=g+q|0;v=a[p>>0]|0;a[j+2>>0]=v;a[j+1>>0]=v;a[j>>0]=v;if(l){if((c[u>>2]|0)==0){C=-1}else{C=(((d[p>>0]|0)<<8|(d[g+(q|1)>>0]|0)|0)!=(c[r>>2]|0))<<31>>31}a[j+3>>0]=C}s=s+1|0;if((s|0)==(e|0)){m=0;break}else{j=j+f|0}}i=k;return m|0}else if((B|0)==8){if((e|0)==0){m=0;i=k;return m|0}j=h+16|0;s=h+20|0;if(l){D=b;E=0}else{C=b;r=0;while(1){u=a[g+r>>0]|0;a[C+2>>0]=u;a[C+1>>0]=u;a[C>>0]=u;r=r+1|0;if((r|0)==(e|0)){m=0;break}else{C=C+f|0}}i=k;return m|0}while(1){C=g+E|0;r=a[C>>0]|0;a[D+2>>0]=r;a[D+1>>0]=r;a[D>>0]=r;if((c[j>>2]|0)==0){F=-1}else{F=((d[C>>0]|0|0)!=(c[s>>2]|0))<<31>>31}a[D+3>>0]=F;E=E+1|0;if((E|0)==(e|0)){m=0;break}else{D=D+f|0}}i=k;return m|0}else{D=(1<>>3)>>0]|0)>>>(r&7^7)&1)<>>0>>0)){G=p;H=v;break}else{r=p;q=v}}}q=(((H*255|0)>>>0)/(D>>>0)|0)&255;a[s+2>>0]=q;a[s+1>>0]=q;a[s>>0]=q;if(l){if((c[E>>2]|0)==0){I=-1}else{I=((H|0)!=(c[F>>2]|0))<<31>>31}a[s+3>>0]=I}if((B|0)==(e|0)){m=0;break}s=s+f|0;j=G;C=c[t>>2]|0;B=B+1|0}i=k;return m|0}break};case 4:{B=(e|0)==0;if((c[h+4>>2]|0)!=8){if(B){m=0;i=k;return m|0}else{J=b;K=0}while(1){t=K<<2;C=a[g+t>>0]|0;a[J+2>>0]=C;a[J+1>>0]=C;a[J>>0]=C;if(l){a[J+3>>0]=a[g+(t|2)>>0]|0}K=K+1|0;if((K|0)==(e|0)){m=0;break}else{J=J+f|0}}i=k;return m|0}if(B){m=0;i=k;return m|0}if(l){B=b;J=0;while(1){K=J<<1;t=a[g+K>>0]|0;a[B+2>>0]=t;a[B+1>>0]=t;a[B>>0]=t;a[B+3>>0]=a[g+(K|1)>>0]|0;J=J+1|0;if((J|0)==(e|0)){m=0;break}else{B=B+f|0}}i=k;return m|0}else{B=b;J=0;while(1){K=a[g+(J<<1)>>0]|0;a[B+2>>0]=K;a[B+1>>0]=K;a[B>>0]=K;J=J+1|0;if((J|0)==(e|0)){m=0;break}else{B=B+f|0}}i=k;return m|0}break};case 2:{B=(e|0)==0;if((c[h+4>>2]|0)==8){if(B){m=0;i=k;return m|0}J=h+16|0;K=h+20|0;t=h+24|0;C=h+28|0;G=b;j=0;while(1){s=j*3|0;I=a[g+s>>0]|0;a[G>>0]=I;F=a[g+(s+1)>>0]|0;a[G+1>>0]=F;H=a[g+(s+2)>>0]|0;a[G+2>>0]=H;if(l){if(((c[J>>2]|0)!=0?(I&255|0)==(c[K>>2]|0):0)?(F&255|0)==(c[t>>2]|0):0){L=((H&255|0)!=(c[C>>2]|0))<<31>>31}else{L=-1}a[G+3>>0]=L}j=j+1|0;if((j|0)==(e|0)){m=0;break}else{G=G+f|0}}i=k;return m|0}else{if(B){m=0;i=k;return m|0}B=h+16|0;G=h+20|0;j=h+24|0;L=h+28|0;C=b;t=0;while(1){K=t*6|0;J=g+K|0;a[C>>0]=a[J>>0]|0;H=g+(K+2)|0;a[C+1>>0]=a[H>>0]|0;F=g+(K+4)|0;a[C+2>>0]=a[F>>0]|0;if(l){if(((c[B>>2]|0)!=0?((d[J>>0]|0)<<8|(d[g+(K|1)>>0]|0)|0)==(c[G>>2]|0):0)?((d[H>>0]|0)<<8|(d[g+(K+3)>>0]|0)|0)==(c[j>>2]|0):0){M=(((d[F>>0]|0)<<8|(d[g+(K+5)>>0]|0)|0)!=(c[L>>2]|0))<<31>>31}else{M=-1}a[C+3>>0]=M}t=t+1|0;if((t|0)==(e|0)){m=0;break}else{C=C+f|0}}i=k;return m|0}break};case 6:{C=(e|0)==0;if((c[h+4>>2]|0)==8){if(C){m=0;i=k;return m|0}else{N=b;O=0}while(1){h=O<<2;a[N>>0]=a[g+h>>0]|0;a[N+1>>0]=a[g+(h|1)>>0]|0;a[N+2>>0]=a[g+(h|2)>>0]|0;if(l){a[N+3>>0]=a[g+(h|3)>>0]|0}O=O+1|0;if((O|0)==(e|0)){m=0;break}else{N=N+f|0}}i=k;return m|0}else{if(C){m=0;i=k;return m|0}else{P=b;Q=0}while(1){b=Q<<3;a[P>>0]=a[g+b>>0]|0;a[P+1>>0]=a[g+(b|2)>>0]|0;a[P+2>>0]=a[g+(b|4)>>0]|0;if(l){a[P+3>>0]=a[g+(b|6)>>0]|0}Q=Q+1|0;if((Q|0)==(e|0)){m=0;break}else{P=P+f|0}}i=k;return m|0}break};default:{m=0;i=k;return m|0}}return 0}function Qc(a){a=a|0;var b=0,d=0,e=0,f=0;b=i;d=0;do{e=a+(d<<2)|0;f=c[e>>2]|0;if((f|0)!=0){Qc(f);Qd(c[e>>2]|0)}d=d+1|0}while((d|0)!=16);i=b;return}function Rc(b,e,f,g,h,j){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Fa=0,Ga=0,Ha=0,Ia=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Ua=0,Va=0,Wa=0,Xa=0,Ya=0,Za=0,_a=0,$a=0,ab=0,bb=0,cb=0,db=0,eb=0,fb=0,gb=0,hb=0,ib=0,jb=0,kb=0,lb=0,mb=0,nb=0,ob=0,pb=0,qb=0,rb=0,sb=0,tb=0,ub=0,vb=0,wb=0,xb=0,yb=0,zb=0,Ab=0,Bb=0,Cb=0,Db=0,Eb=0,Fb=0,Gb=0,Hb=0,Ib=0,Jb=0,Kb=0,Lb=0,Mb=0,Nb=0,Ob=0,Pb=0,Qb=0,Rb=0,Sb=0,Tb=0,Ub=0,Vb=0,Wb=0,Xb=0,Yb=0,Zb=0,_b=0,$b=0,ac=0,bc=0,cc=0,dc=0,ec=0,fc=0,gc=0,hc=0,ic=0,jc=0,kc=0,lc=0,mc=0,nc=0,oc=0,pc=0,qc=0,rc=0,sc=0,uc=0,vc=0,wc=0,xc=0,yc=0,zc=0,Ac=0,Bc=0,Cc=0,Dc=0,Ec=0,Fc=0,Gc=0,Hc=0,Ic=0,Jc=0,Kc=0,Lc=0,Rc=0,Sc=0,Tc=0,Uc=0,Vc=0,Wc=0,Zc=0,_c=0,$c=0,ad=0,bd=0,cd=0,dd=0,ed=0,fd=0,gd=0,hd=0,id=0,jd=0,kd=0,ld=0,md=0,nd=0,od=0,pd=0,qd=0,rd=0,sd=0,td=0;k=i;i=i+368|0;l=k+288|0;m=k+260|0;n=k+232|0;o=k+200|0;p=k+168|0;q=k+136|0;r=k+96|0;s=k+64|0;t=k+32|0;u=k;v=k+124|0;c[b>>2]=0;w=g+132|0;do{if((j|0)==0|(h|0)==0){c[g+292>>2]=48;x=48}else{if(j>>>0<29){c[g+292>>2]=27;x=27;break}Oc(w);y=g+160|0;z=g+144|0;c[y+0>>2]=0;c[y+4>>2]=0;c[y+8>>2]=0;c[y+12>>2]=0;c[z>>2]=6;A=g+148|0;c[A>>2]=8;B=g+152|0;c[B>>2]=0;C=g+156|0;c[C>>2]=0;D=g+140|0;c[D>>2]=0;c[w>>2]=0;E=g+136|0;c[E>>2]=0;F=g+176|0;G=g+252|0;c[G>>2]=0;H=g+268|0;c[H+0>>2]=0;c[H+4>>2]=0;c[H+8>>2]=0;c[H+12>>2]=0;c[H+16>>2]=0;c[H+20>>2]=0;H=F+0|0;I=H+52|0;do{c[H>>2]=0;H=H+4|0}while((H|0)<(I|0));if((((((((a[h>>0]|0)==-119?(a[h+1>>0]|0)==80:0)?(a[h+2>>0]|0)==78:0)?(a[h+3>>0]|0)==71:0)?(a[h+4>>0]|0)==13:0)?(a[h+5>>0]|0)==10:0)?(a[h+6>>0]|0)==26:0)?(a[h+7>>0]|0)==10:0){if((((a[h+12>>0]|0)==73?(a[h+13>>0]|0)==72:0)?(a[h+14>>0]|0)==68:0)?(a[h+15>>0]|0)==82:0){c[e>>2]=d[h+17>>0]<<16|d[h+16>>0]<<24|d[h+18>>0]<<8|d[h+19>>0];c[f>>2]=d[h+21>>0]<<16|d[h+20>>0]<<24|d[h+22>>0]<<8|d[h+23>>0];J=a[h+24>>0]|0;K=J&255;c[A>>2]=K;L=d[h+25>>0]|0;c[z>>2]=L;M=a[h+26>>0]|0;c[w>>2]=M&255;N=a[h+27>>0]|0;c[E>>2]=N&255;O=a[h+28>>0]|0;c[D>>2]=O&255;P=g+16|0;if((c[P>>2]|0)==0){Q=d[h+29>>0]|0;R=d[h+30>>0]<<16;S=d[h+31>>0]<<8;T=d[h+32>>0]|0;U=-1;V=0;do{U=c[8+((d[h+(V+12)>>0]^U&255)<<2)>>2]^U>>>8;V=V+1|0}while((V|0)!=17);if((R|Q<<24|S|T|0)!=(~U|0)){c[g+292>>2]=57;x=57;break}}if(!(M<<24>>24==0)){c[g+292>>2]=32;x=32;break}if(!(N<<24>>24==0)){c[g+292>>2]=33;x=33;break}if((O&255)>1){c[g+292>>2]=34;x=34;break}switch(L|0){case 4:{if(!((K|0)==8|(K|0)==16)){W=37;X=37}break};case 2:{if(!((K|0)==8|(K|0)==16)){W=37;X=37}break};case 0:{if(!((K+ -1|0)>>>0<2|J<<24>>24==4|J<<24>>24==8|J<<24>>24==16)){W=37;X=37}break};case 3:{if(!((K+ -1|0)>>>0<2|J<<24>>24==4|J<<24>>24==8)){W=37;X=37}break};case 6:{if(!((K|0)==8|(K|0)==16)){W=37;X=37}break};default:{W=31;X=37}}if((X|0)==37){c[g+292>>2]=W;Y=W;i=k;return Y|0}V=g+292|0;c[V>>2]=0;E=h;Z=g+172|0;_=g+168|0;$=g+164|0;ba=g+188|0;ca=g+184|0;da=g+180|0;ea=g+28|0;fa=l+8|0;ga=l+4|0;ha=g+4|0;ia=l+8|0;ja=l+4|0;ka=g+224|0;la=g+228|0;ma=g+232|0;na=g+236|0;oa=g+240|0;pa=g+244|0;qa=g+248|0;ra=g+256|0;sa=g+260|0;ta=g+264|0;ua=g+32|0;va=g+208|0;wa=g+204|0;xa=g+212|0;ya=g+216|0;za=g+220|0;Aa=0;Ba=0;Ca=0;Da=h+33|0;Ea=1;Fa=0;a:while(1){Ga=Da-E+12|0;Ha=Ga>>>0>j>>>0|Da>>>0>>0;Ia=Da+1|0;Ja=Da+2|0;Ka=Da+3|0;La=Da+8|0;Ma=Da+4|0;Na=Da+5|0;Oa=Da+6|0;Pa=Da+7|0;Qa=Da+9|0;Ra=Da+10|0;Sa=Da+11|0;Ta=Da+12|0;Ua=Da+13|0;Va=Da+14|0;Wa=Da+15|0;Xa=Da+16|0;Ya=Ba;Za=Aa;_a=Ca;$a=0;ab=Ea;while(1){bb=c[V>>2]|0;if(!($a<<24>>24==0&(bb|0)==0)){cb=bb;db=_a;eb=Ya;break a}if(Ha){X=42;break a}bb=d[Ia>>0]<<16|d[Da>>0]<<24|d[Ja>>0]<<8|d[Ka>>0];if((bb|0)<0){X=44;break a}if((bb+Ga|0)>>>0>j>>>0){X=47;break a}fb=bb+12|0;if((Da+fb|0)>>>0>>0){X=47;break a}gb=a[Ma>>0]|0;b:do{if(gb<<24>>24==116){hb=a[Na>>0]|0;if(!(hb<<24>>24==82)){ib=hb;X=102;break}if((a[Oa>>0]|0)!=78){jb=1;X=87;break}if((a[Pa>>0]|0)!=83){jb=1;X=87;break}hb=c[z>>2]|0;do{if((hb|0)==2){if((bb|0)!=6){kb=41;X=86;break a}c[y>>2]=1;c[$>>2]=d[La>>0]<<8|d[Qa>>0];c[_>>2]=d[Ra>>0]<<8|d[Sa>>0];c[Z>>2]=d[Ta>>0]<<8|d[Ua>>0]}else if((hb|0)==0){if((bb|0)!=2){kb=30;X=86;break a}c[y>>2]=1;lb=d[La>>0]<<8|d[Qa>>0];c[Z>>2]=lb;c[_>>2]=lb;c[$>>2]=lb}else if((hb|0)==3){if((c[C>>2]|0)>>>0>>0){kb=38;X=86;break a}if((bb|0)==0){break}else{mb=0}do{a[(c[B>>2]|0)+(mb<<2|3)>>0]=a[Da+(mb+8)>>0]|0;mb=mb+1|0}while((mb|0)!=(bb|0))}else{kb=42;X=86;break a}}while(0);c[V>>2]=0;nb=Za;ob=Ya;pb=_a;qb=0;rb=ab}else if(gb<<24>>24==73){hb=a[Na>>0]|0;if(hb<<24>>24==69){if((a[Oa>>0]|0)!=78){jb=0;X=87;break}if((a[Pa>>0]|0)==68){nb=Za;ob=Ya;pb=_a;qb=1;rb=ab;break}else{jb=0;X=87;break}}else if(!(hb<<24>>24==68)){X=226;break a}if((a[Oa>>0]|0)!=65){X=226;break a}if((a[Pa>>0]|0)!=84){jb=0;X=87;break}hb=bb+Ya|0;if(Za>>>0>>0){lb=hb<<1;sb=Rd(_a,lb)|0;if((sb|0)==0){X=55;break a}else{tb=lb;ub=sb}}else{tb=Za;ub=_a}if((bb|0)==0){nb=tb;ob=hb;pb=ub;qb=0;rb=3;break}else{vb=0}do{a[ub+(vb+Ya)>>0]=a[Da+(vb+8)>>0]|0;vb=vb+1|0}while((vb|0)!=(bb|0));nb=tb;ob=hb;pb=ub;qb=0;rb=3}else if(gb<<24>>24==80){if((a[Na>>0]|0)!=76){X=226;break a}do{if((a[Oa>>0]|0)==84){if((a[Pa>>0]|0)!=69){break}hb=c[B>>2]|0;if((hb|0)!=0){Qd(hb)}hb=(bb>>>0)/3|0;c[C>>2]=hb;sb=Pd(hb<<2)|0;c[B>>2]=sb;c:do{if((sb|0)==0){if(!(bb>>>0<3)){X=66;break a}}else{if(bb>>>0>770){wb=38;X=72;break a}if(bb>>>0<3){break}else{xb=sb;yb=0;zb=0}while(1){hb=yb<<2;a[xb+hb>>0]=a[Da+(zb+8)>>0]|0;a[(c[B>>2]|0)+(hb|1)>>0]=a[Da+(zb+9)>>0]|0;a[(c[B>>2]|0)+(hb|2)>>0]=a[Da+(zb+10)>>0]|0;a[(c[B>>2]|0)+(hb|3)>>0]=-1;hb=yb+1|0;if(!(hb>>>0<(c[C>>2]|0)>>>0)){break c}xb=c[B>>2]|0;yb=hb;zb=zb+3|0}}}while(0);c[V>>2]=0;nb=Za;ob=Ya;pb=_a;qb=0;rb=2;break b}}while(0);if(gb<<24>>24==116){X=212}else{jb=0;X=87}}else{jb=0;X=87}}while(0);d:do{if((X|0)==87){X=0;do{if(gb<<24>>24==98){if((a[Na>>0]|0)!=75){break}if((a[Oa>>0]|0)!=71){break}if((a[Pa>>0]|0)!=68){break}switch(c[z>>2]|0){case 6:case 2:{if((bb|0)!=6){Ab=45;X=99;break a}c[F>>2]=1;c[da>>2]=d[La>>0]<<8|d[Qa>>0];c[ca>>2]=d[Ra>>0]<<8|d[Sa>>0];c[ba>>2]=d[Ta>>0]<<8|d[Ua>>0];break};case 4:case 0:{if((bb|0)!=2){Ab=44;X=99;break a}c[F>>2]=1;sb=d[La>>0]<<8|d[Qa>>0];c[ba>>2]=sb;c[ca>>2]=sb;c[da>>2]=sb;break};case 3:{if((bb|0)!=1){Ab=43;X=99;break a}c[F>>2]=1;sb=d[La>>0]|0;c[ba>>2]=sb;c[ca>>2]=sb;c[da>>2]=sb;break};default:{}}c[V>>2]=0;nb=Za;ob=Ya;pb=_a;qb=0;rb=ab;break d}}while(0);if(!jb){Bb=0;X=116;break}ib=a[Na>>0]|0;X=102}}while(0);do{if((X|0)==102){X=0;if(!(ib<<24>>24==69)){Bb=1;X=116;break}if((a[Oa>>0]|0)!=88){Bb=1;X=116;break}if((a[Pa>>0]|0)!=116){Bb=1;X=116;break}if((c[ea>>2]|0)==0){nb=Za;ob=Ya;pb=_a;qb=0;rb=ab;break}do{if((bb|0)==0){Cb=89;Db=0;Eb=0}else{sb=0;while(1){hb=sb+1|0;if((a[Da+(sb+8)>>0]|0)==0){Fb=sb;break}if(hb>>>0>>0){sb=hb}else{Fb=hb;break}}if((Fb|0)==0|Fb>>>0>79){Cb=89;Db=0;Eb=0;break}sb=Fb+1|0;hb=Pd(sb)|0;if((hb|0)==0){Cb=83;Db=0;Eb=0;break}a[hb+Fb>>0]=0;ie(hb|0,La|0,Fb|0)|0;lb=sb>>>0>bb>>>0?0:bb-sb|0;Gb=Pd(lb+1|0)|0;if((Gb|0)==0){Cb=83;Db=hb;Eb=0;break}a[Gb+lb>>0]=0;if((lb|0)!=0){ie(Gb|0,Da+(Fb+9)|0,(sb>>>0>>0?bb:sb)+~Fb|0)|0}Cb=Nc(w,hb,Gb)|0;Db=hb;Eb=Gb}}while(0);Qd(Db);Qd(Eb);c[V>>2]=Cb;if((Cb|0)==0){nb=Za;ob=Ya;pb=_a;qb=0;rb=ab}else{cb=Cb;db=_a;eb=Ya;break a}}}while(0);e:do{if((X|0)==116){X=0;do{if(gb<<24>>24==122){if((a[Na>>0]|0)!=84){Hb=Bb;break}if((a[Oa>>0]|0)!=88){Hb=Bb;break}if((a[Pa>>0]|0)!=116){Hb=Bb;break}if((c[ea>>2]|0)==0){nb=Za;ob=Ya;pb=_a;qb=0;rb=ab;break e}c[l>>2]=0;c[fa>>2]=0;c[ga>>2]=0;f:do{if((bb|0)==0){Ib=0}else{Gb=0;while(1){hb=Gb+1|0;if((a[Da+(Gb+8)>>0]|0)==0){Ib=Gb;break f}if(hb>>>0>>0){Gb=hb}else{Ib=hb;break}}}}while(0);Gb=Ib+2|0;do{if(Gb>>>0>>0){if((Ib|0)==0|Ib>>>0>79){Jb=89;Kb=0;break}hb=Pd(Ib+1|0)|0;if((hb|0)==0){Jb=83;Kb=0;break}a[hb+Ib>>0]=0;ie(hb|0,La|0,Ib|0)|0;if((a[Da+(Ib+9)>>0]|0)!=0){Jb=72;Kb=hb;break}if(Gb>>>0>bb>>>0){Jb=75;Kb=hb;break}sb=bb-Gb|0;lb=Da+(Ib+10)|0;Lb=c[ha>>2]|0;if((Lb|0)==0){Mb=Mc(l,ga,lb,sb,g)|0}else{Mb=tc[Lb&0](l,ga,lb,sb,g)|0}if((Mb|0)!=0){Jb=Mb;Kb=hb;break}sb=c[ga>>2]|0;lb=sb+1|0;do{if((c[fa>>2]|0)>>>0>>0){Lb=lb<<1;Nb=Rd(c[l>>2]|0,Lb)|0;if((Nb|0)==0){break}c[fa>>2]=Lb;c[l>>2]=Nb;Ob=Nb;X=137}else{Ob=c[l>>2]|0;X=137}}while(0);if((X|0)==137){X=0;c[ga>>2]=lb;a[Ob+sb>>0]=0}Jb=Nc(w,hb,c[l>>2]|0)|0;Kb=hb}else{Jb=75;Kb=0}}while(0);Qd(Kb);c[fa>>2]=0;c[ga>>2]=0;Qd(c[l>>2]|0);c[V>>2]=Jb;if((Jb|0)==0){nb=Za;ob=Ya;pb=_a;qb=0;rb=ab;break e}else{cb=Jb;db=_a;eb=Ya;break a}}else if(gb<<24>>24==105){if((a[Na>>0]|0)!=84){Hb=Bb;break}if((a[Oa>>0]|0)!=88){Hb=Bb;break}if((a[Pa>>0]|0)!=116){Hb=Bb;break}if((c[ea>>2]|0)==0){nb=Za;ob=Ya;pb=_a;qb=0;rb=ab;break e}c[l>>2]=0;c[ia>>2]=0;c[ja>>2]=0;g:do{if(bb>>>0<5){Pb=30;Qb=0;Rb=0;Sb=0}else{Gb=0;while(1){Nb=Gb+1|0;if((a[Da+(Gb+8)>>0]|0)==0){Tb=Gb;break}if(Nb>>>0>>0){Gb=Nb}else{Tb=Nb;break}}Gb=Tb+3|0;if(!(Gb>>>0>>0)){Pb=75;Qb=0;Rb=0;Sb=0;break}if((Tb|0)==0|Tb>>>0>79){Pb=89;Qb=0;Rb=0;Sb=0;break}hb=Pd(Tb+1|0)|0;if((hb|0)==0){Pb=83;Qb=0;Rb=0;Sb=0;break}a[hb+Tb>>0]=0;ie(hb|0,La|0,Tb|0)|0;sb=a[Da+(Tb+9)>>0]|0;if((a[Da+(Tb+10)>>0]|0)==0){Ub=Gb;Vb=0}else{Pb=72;Qb=hb;Rb=0;Sb=0;break}while(1){Wb=Vb+1|0;if((a[Da+(Ub+8)>>0]|0)==0){Xb=Wb;Yb=Vb;break}Ub=Ub+1|0;if(!(Ub>>>0>>0)){X=152;break}else{Vb=Wb}}if((X|0)==152){X=0;Xb=Vb+2|0;Yb=Wb}lb=Pd(Xb)|0;if((lb|0)==0){Pb=83;Qb=hb;Rb=0;Sb=0;break}a[lb+Yb>>0]=0;if((Yb|0)!=0){ie(lb|0,Da+(Tb+11)|0,Yb|0)|0}Nb=Xb+Gb|0;h:do{if(Nb>>>0>>0){Lb=Nb;Zb=0;while(1){_b=Zb+1|0;if((a[Da+(Lb+8)>>0]|0)==0){$b=_b;ac=Zb;break h}Lb=Lb+1|0;if(!(Lb>>>0>>0)){bc=_b;X=159;break}else{Zb=_b}}}else{bc=0;X=159}}while(0);if((X|0)==159){X=0;$b=bc+1|0;ac=bc}Gb=Pd($b)|0;if((Gb|0)==0){Pb=83;Qb=hb;Rb=lb;Sb=0;break}a[Gb+ac>>0]=0;if((ac|0)!=0){ie(Gb|0,Da+(Tb+11+Xb)|0,ac|0)|0}Zb=$b+Nb|0;Lb=Zb>>>0>bb>>>0?0:bb-Zb|0;i:do{if(sb<<24>>24==0){_b=Lb+1|0;if((_b|0)==0){cc=0}else{dc=_b<<1;ec=Pd(dc)|0;if((ec|0)==0){Pb=83;Qb=hb;Rb=lb;Sb=Gb;break g}c[ia>>2]=dc;c[l>>2]=ec;cc=ec}c[ja>>2]=_b;a[cc+Lb>>0]=0;if((Lb|0)==0){break}_b=Zb+8|0;a[cc>>0]=a[Da+_b>>0]|0;if((Lb|0)==1){break}a[cc+1>>0]=a[Da+(Zb+9)>>0]|0;if((Lb|0)==2){break}else{fc=cc;gc=2}while(1){a[fc+gc>>0]=a[Da+(gc+_b)>>0]|0;ec=gc+1|0;if((ec|0)==(Lb|0)){break i}fc=c[l>>2]|0;gc=ec}}else{_b=Da+(Zb+8)|0;ec=c[ha>>2]|0;if((ec|0)==0){hc=Mc(l,ja,_b,Lb,g)|0}else{hc=tc[ec&0](l,ja,_b,Lb,g)|0}if((hc|0)!=0){Pb=hc;Qb=hb;Rb=lb;Sb=Gb;break g}_b=c[ia>>2]|0;ec=c[ja>>2]|0;if(_b>>>0>>0){c[ia>>2]=ec;ic=ec}else{ic=_b}_b=ec+1|0;if(ic>>>0<_b>>>0){dc=_b<<1;jc=Rd(c[l>>2]|0,dc)|0;if((jc|0)==0){break}c[ia>>2]=dc;c[l>>2]=jc;kc=jc}else{kc=c[l>>2]|0}c[ja>>2]=_b;a[kc+ec>>0]=0}}while(0);Lb=c[l>>2]|0;Zb=Rd(c[va>>2]|0,(c[wa>>2]<<2)+4|0)|0;sb=Rd(c[xa>>2]|0,(c[wa>>2]<<2)+4|0)|0;Nb=Rd(c[ya>>2]|0,(c[wa>>2]<<2)+4|0)|0;ec=Rd(c[za>>2]|0,(c[wa>>2]<<2)+4|0)|0;if((Zb|0)==0|(sb|0)==0|(Nb|0)==0|(ec|0)==0){Qd(Zb);Qd(sb);Qd(Nb);Qd(ec);Pb=83;Qb=hb;Rb=lb;Sb=Gb;break}_b=c[wa>>2]|0;c[wa>>2]=_b+1;c[va>>2]=Zb;c[xa>>2]=sb;c[ya>>2]=Nb;c[za>>2]=ec;ec=Zb+(_b<<2)|0;c[ec>>2]=0;_b=Pd(1)|0;if((_b|0)!=0){a[_b>>0]=0;c[ec>>2]=_b}_b=(c[va>>2]|0)+((c[wa>>2]|0)+ -1<<2)|0;ec=fe(hb|0)|0;Zb=Rd(c[_b>>2]|0,ec+1|0)|0;do{if((Zb|0)!=0){a[Zb+ec>>0]=0;c[_b>>2]=Zb;if((ec|0)==0){break}a[Zb>>0]=a[hb>>0]|0;if((ec|0)==1){break}else{lc=1}do{a[(c[_b>>2]|0)+lc>>0]=a[hb+lc>>0]|0;lc=lc+1|0}while((lc|0)!=(ec|0))}}while(0);ec=(c[xa>>2]|0)+((c[wa>>2]|0)+ -1<<2)|0;c[ec>>2]=0;_b=Pd(1)|0;if((_b|0)!=0){a[_b>>0]=0;c[ec>>2]=_b}_b=(c[xa>>2]|0)+((c[wa>>2]|0)+ -1<<2)|0;ec=fe(lb|0)|0;Zb=Rd(c[_b>>2]|0,ec+1|0)|0;do{if((Zb|0)!=0){a[Zb+ec>>0]=0;c[_b>>2]=Zb;if((ec|0)==0){break}a[Zb>>0]=a[lb>>0]|0;if((ec|0)==1){break}else{mc=1}do{a[(c[_b>>2]|0)+mc>>0]=a[lb+mc>>0]|0;mc=mc+1|0}while((mc|0)!=(ec|0))}}while(0);ec=(c[ya>>2]|0)+((c[wa>>2]|0)+ -1<<2)|0;c[ec>>2]=0;_b=Pd(1)|0;if((_b|0)!=0){a[_b>>0]=0;c[ec>>2]=_b}_b=(c[ya>>2]|0)+((c[wa>>2]|0)+ -1<<2)|0;ec=fe(Gb|0)|0;Zb=Rd(c[_b>>2]|0,ec+1|0)|0;do{if((Zb|0)!=0){a[Zb+ec>>0]=0;c[_b>>2]=Zb;if((ec|0)==0){break}a[Zb>>0]=a[Gb>>0]|0;if((ec|0)==1){break}else{nc=1}do{a[(c[_b>>2]|0)+nc>>0]=a[Gb+nc>>0]|0;nc=nc+1|0}while((nc|0)!=(ec|0))}}while(0);ec=(c[za>>2]|0)+((c[wa>>2]|0)+ -1<<2)|0;c[ec>>2]=0;_b=Pd(1)|0;if((_b|0)!=0){a[_b>>0]=0;c[ec>>2]=_b}_b=(c[za>>2]|0)+((c[wa>>2]|0)+ -1<<2)|0;ec=fe(Lb|0)|0;Zb=Rd(c[_b>>2]|0,ec+1|0)|0;if((Zb|0)==0){Pb=0;Qb=hb;Rb=lb;Sb=Gb;break}a[Zb+ec>>0]=0;c[_b>>2]=Zb;if((ec|0)==0){Pb=0;Qb=hb;Rb=lb;Sb=Gb;break}a[Zb>>0]=a[Lb>>0]|0;if((ec|0)==1){Pb=0;Qb=hb;Rb=lb;Sb=Gb;break}else{oc=1}do{a[(c[_b>>2]|0)+oc>>0]=a[Lb+oc>>0]|0;oc=oc+1|0}while((oc|0)!=(ec|0));Pb=0;Qb=hb;Rb=lb;Sb=Gb}}while(0);Qd(Qb);Qd(Rb);Qd(Sb);c[ia>>2]=0;c[ja>>2]=0;Qd(c[l>>2]|0);c[V>>2]=Pb;if((Pb|0)==0){nb=Za;ob=Ya;pb=_a;qb=0;rb=ab;break e}else{cb=Pb;db=_a;eb=Ya;break a}}else{Hb=Bb}}while(0);if(Hb){X=212}else{X=218}}}while(0);do{if((X|0)==212){X=0;if((a[Na>>0]|0)!=73){X=218;break}if((a[Oa>>0]|0)!=77){X=218;break}if((a[Pa>>0]|0)!=69){X=218;break}if((bb|0)!=7){X=216;break a}c[ka>>2]=1;c[la>>2]=d[La>>0]<<8|d[Qa>>0];c[ma>>2]=d[Ra>>0]|0;c[na>>2]=d[Sa>>0]|0;c[oa>>2]=d[Ta>>0]|0;c[pa>>2]=d[Ua>>0]|0;c[qa>>2]=d[Va>>0]|0;c[V>>2]=0;nb=Za;ob=Ya;pb=_a;qb=0;rb=ab}}while(0);if((X|0)==218){X=0;if(!(gb<<24>>24==112)){X=225;break}if((a[Na>>0]|0)!=72){X=227;break}if((a[Oa>>0]|0)!=89){X=227;break}if((a[Pa>>0]|0)!=115){X=227;break}if((bb|0)!=9){X=223;break a}c[G>>2]=1;c[ra>>2]=d[Qa>>0]<<16|d[La>>0]<<24|d[Ra>>0]<<8|d[Sa>>0];c[sa>>2]=d[Ua>>0]<<16|d[Ta>>0]<<24|d[Va>>0]<<8|d[Wa>>0];c[ta>>2]=d[Xa>>0]|0;c[V>>2]=0;nb=Za;ob=Ya;pb=_a;qb=0;rb=ab}if((c[P>>2]|Fa|0)==0){Gb=d[Ia>>0]<<16|d[Da>>0]<<24|d[Ja>>0]<<8|d[Ka>>0];lb=d[Da+(Gb+9)>>0]<<16|d[Da+(Gb+8)>>0]<<24|d[Da+(Gb+10)>>0]<<8|d[Da+(Gb+11)>>0];hb=Gb+4|0;if((hb|0)==0){pc=0}else{Gb=-1;ec=0;do{Gb=c[8+((d[Da+(ec+4)>>0]^Gb&255)<<2)>>2]^Gb>>>8;ec=ec+1|0}while((ec|0)!=(hb|0));pc=~Gb}if((lb|0)!=(pc|0)){X=239;break a}}if(qb<<24>>24==0){qc=nb;rc=ob;sc=pb;uc=rb;vc=Fa;break}else{Ya=ob;Za=nb;_a=pb;$a=qb;ab=rb}}if((X|0)==225){X=0;if((gb&32)==0){X=226;break}else{X=227}}do{if((X|0)==227){X=0;if((c[ua>>2]|0)==0){qc=Za;rc=Ya;sc=_a;uc=ab;vc=1;break}$a=ab+ -1|0;Xa=g+($a<<2)+268|0;Wa=g+($a<<2)+280|0;$a=c[Wa>>2]|0;Va=$a+fb|0;if(Va>>>0>>0|Va>>>0<$a>>>0){wc=77;X=233;break a}Ta=Rd(c[Xa>>2]|0,Va)|0;if((Ta|0)==0){wc=83;X=233;break a}c[Xa>>2]=Ta;c[Wa>>2]=Va;if((fb|0)!=0){Va=0;do{a[Ta+(Va+$a)>>0]=a[Da+Va>>0]|0;Va=Va+1|0}while((Va|0)!=(fb|0))}c[V>>2]=0;qc=Za;rc=Ya;sc=_a;uc=ab;vc=1}}while(0);Aa=qc;Ba=rc;Ca=sc;Da=Da+((d[Ia>>0]<<16|d[Da>>0]<<24|d[Ja>>0]<<8|d[Ka>>0])+12)|0;Ea=uc;Fa=vc}switch(X|0){case 42:{c[V>>2]=30;cb=30;db=_a;eb=Ya;break};case 44:{c[V>>2]=63;cb=63;db=_a;eb=Ya;break};case 47:{c[V>>2]=64;cb=64;db=_a;eb=Ya;break};case 55:{c[V>>2]=83;cb=83;db=_a;eb=Ya;break};case 66:{c[C>>2]=0;wb=83;X=72;break};case 86:{c[V>>2]=kb;cb=kb;db=_a;eb=Ya;break};case 99:{c[V>>2]=Ab;cb=Ab;db=_a;eb=Ya;break};case 216:{c[V>>2]=73;cb=73;db=_a;eb=Ya;break};case 223:{c[V>>2]=74;cb=74;db=_a;eb=Ya;break};case 226:{c[V>>2]=69;cb=69;db=_a;eb=Ya;break};case 233:{c[V>>2]=wc;cb=wc;db=_a;eb=Ya;break};case 239:{c[V>>2]=57;cb=57;db=pb;eb=ob;break}}if((X|0)==72){c[V>>2]=wb;cb=wb;db=_a;eb=Ya}c[v>>2]=0;Fa=v+8|0;c[Fa>>2]=0;Ea=v+4|0;c[Ea>>2]=0;j:do{if((cb|0)==0){Da=c[f>>2]|0;switch(c[z>>2]|0){case 2:{xc=3;break};case 3:case 0:{xc=1;break};case 4:{xc=2;break};case 6:{xc=4;break};default:{xc=0}}Ca=(((aa(aa(aa(Da,c[e>>2]|0)|0,c[A>>2]|0)|0,xc)|0)+7|0)>>>3)+Da|0;do{if((Ca|0)!=0){Da=Ca<<1;Ba=Pd(Da)|0;if((Ba|0)!=0){c[Fa>>2]=Da;c[v>>2]=Ba;Ba=(c[V>>2]|0)==0;c[Ea>>2]=Ca;if(Ba){break}else{break j}}else{c[V>>2]=83;break j}}else{c[Ea>>2]=0}}while(0);Ca=c[ha>>2]|0;if((Ca|0)==0){yc=Mc(v,Ea,db,eb,g)|0}else{yc=tc[Ca&0](v,Ea,db,eb,g)|0}c[V>>2]=yc}}while(0);Qd(db);if((c[V>>2]|0)==0){ha=c[e>>2]|0;Ca=c[f>>2]|0;Ka=c[z>>2]|0;Ja=c[A>>2]|0;switch(Ka|0){case 4:{zc=2;break};case 3:case 0:{zc=1;break};case 6:{zc=4;break};case 2:{zc=3;break};default:{zc=0}}Ia=((aa(aa(aa(Ca,ha)|0,Ja)|0,zc)|0)+7|0)>>>3;do{if((Ia|0)==0){Ac=0;Bc=Ka;Cc=Ja;Dc=ha;Ec=Ca;X=268}else{Ba=Pd(Ia<<1)|0;if((Ba|0)==0){c[V>>2]=83;Fc=0;break}he(Ba|0,0,Ia|0)|0;if((c[V>>2]|0)!=0){Fc=Ba;break}Ac=Ba;Bc=c[z>>2]|0;Cc=c[A>>2]|0;Dc=c[e>>2]|0;Ec=c[f>>2]|0;X=268}}while(0);if((X|0)==268){z=c[v>>2]|0;switch(Bc|0){case 2:{Gc=3;break};case 4:{Gc=2;break};case 6:{Gc=4;break};case 3:case 0:{Gc=1;break};default:{Gc=0}}Ia=aa(Gc,Cc)|0;k:do{if((Ia|0)==0){Hc=31}else{l:do{if((c[D>>2]|0)==0){do{if(Ia>>>0<8){Ca=aa(Ia,Dc)|0;ha=Ca+7&-8;if((Ca|0)==(ha|0)){break}Ja=Yc(z,z,Dc,Ec,Ia)|0;if((Ja|0)!=0){Hc=Ja;break k}Ja=ha-Ca|0;if((Ec|0)==0){break l}ha=(Ca|0)==0;Ka=0;Ba=0;Da=0;while(1){if(ha){Ic=Ba;Jc=Ka}else{Aa=Ba;ua=Ka;P=0;while(1){ta=1<<(ua&7^7);if((1<<(Aa&7^7)&d[z+(Aa>>>3)>>0]|0)==0){sa=Ac+(ua>>>3)|0;a[sa>>0]=d[sa>>0]&(ta^255)}else{sa=Ac+(ua>>>3)|0;a[sa>>0]=d[sa>>0]|ta}P=P+1|0;if((P|0)==(Ca|0)){break}else{Aa=Aa+1|0;ua=ua+1|0}}Ic=Ba+Ca|0;Jc=Ka+Ca|0}Da=Da+1|0;if((Da|0)==(Ec|0)){break l}else{Ka=Jc;Ba=Ja+Ic|0}}}}while(0);Ja=Yc(Ac,z,Dc,Ec,Ia)|0;if((Ja|0)!=0){Hc=Ja;break k}}else{Xc(l,r,s,t,u,Dc,Ec,Ia);Ja=Ia>>>0<8;Ba=0;do{Ka=c[t+(Ba<<2)>>2]|0;Da=c[l+(Ba<<2)>>2]|0;Ca=c[r+(Ba<<2)>>2]|0;ha=Yc(z+Ka|0,z+(c[s+(Ba<<2)>>2]|0)|0,Da,Ca,Ia)|0;if((ha|0)!=0){Hc=ha;break k}do{if(Ja){ha=c[u+(Ba<<2)>>2]|0;ua=aa(Da,Ia)|0;Aa=(ua+7&-8)-ua|0;if((Ca|0)==0){break}P=(ua|0)==0;ta=0;sa=0;ra=0;while(1){if(P){Kc=sa;Lc=ta}else{G=sa;qa=ta;pa=0;while(1){oa=1<<(qa&7^7);if((1<<(G&7^7)&d[z+((G>>>3)+Ka)>>0]|0)==0){na=z+((qa>>>3)+ha)|0;a[na>>0]=d[na>>0]&(oa^255)}else{na=z+((qa>>>3)+ha)|0;a[na>>0]=d[na>>0]|oa}pa=pa+1|0;if((pa|0)==(ua|0)){break}else{G=G+1|0;qa=qa+1|0}}Kc=sa+ua|0;Lc=ta+ua|0}ra=ra+1|0;if((ra|0)==(Ca|0)){break}else{ta=Lc;sa=Aa+Kc|0}}}}while(0);Ba=Ba+1|0}while(Ba>>>0<7);Xc(m,n,o,p,q,Dc,Ec,Ia);if(Ia>>>0>7){Ba=Ia>>>3;Ja=(Ba|0)==0;Ca=0;while(1){Ka=c[n+(Ca<<2)>>2]|0;if((Ka|0)!=0){Da=c[m+(Ca<<2)>>2]|0;Aa=(Da|0)==0;sa=q+(Ca<<2)|0;ta=8344+(Ca<<2)|0;ra=8376+(Ca<<2)|0;ua=8408+(Ca<<2)|0;ha=8440+(Ca<<2)|0;P=0;do{if(!Aa){qa=c[sa>>2]|0;G=aa((aa(c[ra>>2]|0,P)|0)+(c[ta>>2]|0)|0,Dc)|0;pa=G+(c[ua>>2]|0)|0;G=c[ha>>2]|0;oa=aa(P,Da)|0;na=0;do{ma=(aa(na+oa|0,Ba)|0)+qa|0;la=aa(pa+(aa(na,G)|0)|0,Ba)|0;if(!Ja){ka=0;do{a[Ac+(ka+la)>>0]=a[z+(ma+ka)>>0]|0;ka=ka+1|0}while(ka>>>0>>0)}na=na+1|0}while((na|0)!=(Da|0))}P=P+1|0}while((P|0)!=(Ka|0))}Ca=Ca+1|0;if((Ca|0)==7){break l}}}else{Rc=0}do{Ca=c[m+(Rc<<2)>>2]|0;Ba=c[n+(Rc<<2)>>2]|0;if((Ba|0)!=0){Ja=(Ca|0)==0;Ka=q+(Rc<<2)|0;P=8344+(Rc<<2)|0;Da=8376+(Rc<<2)|0;ha=8408+(Rc<<2)|0;ua=8440+(Rc<<2)|0;ta=0;do{if(!Ja){ra=c[Ka>>2]<<3;sa=aa(ta,Ca)|0;Aa=aa((aa(c[Da>>2]|0,ta)|0)+(c[P>>2]|0)|0,Dc)|0;na=c[ua>>2]|0;G=Aa+(c[ha>>2]|0)|0;Aa=0;do{pa=(aa(Aa+sa|0,Ia)|0)+ra|0;qa=aa(G+(aa(Aa,na)|0)|0,Ia)|0;oa=0;while(1){ka=(d[z+(pa>>>3)>>0]|0)>>>(pa&7^7)&1;if((ka|0)!=0){ma=Ac+(qa>>>3)|0;a[ma>>0]=d[ma>>0]|ka<<(qa&7^7)}oa=oa+1|0;if((oa|0)==(Ia|0)){break}else{pa=pa+1|0;qa=qa+1|0}}Aa=Aa+1|0}while((Aa|0)!=(Ca|0))}ta=ta+1|0}while((ta|0)!=(Ba|0))}Rc=Rc+1|0}while((Rc|0)!=7)}}while(0);Hc=0}}while(0);c[V>>2]=Hc;Fc=Ac}c[b>>2]=Fc}c[Fa>>2]=0;c[Ea>>2]=0;Qd(c[v>>2]|0);Ia=c[V>>2]|0;if((Ia|0)!=0){Y=Ia;i=k;return Y|0}Ia=g+100|0;z=g+144|0;if((c[g+24>>2]|0)==0){D=g+108|0;Ba=c[D>>2]|0;if((Ba|0)!=0){Qd(Ba)}c[Ia+0>>2]=c[z+0>>2];c[Ia+4>>2]=c[z+4>>2];c[Ia+8>>2]=c[z+8>>2];c[Ia+12>>2]=c[z+12>>2];c[Ia+16>>2]=c[z+16>>2];c[Ia+20>>2]=c[z+20>>2];c[Ia+24>>2]=c[z+24>>2];c[Ia+28>>2]=c[z+28>>2];Ba=c[B>>2]|0;m:do{if((Ba|0)!=0){ta=Pd(1024)|0;c[D>>2]=ta;Ca=c[C>>2]|0;if((ta|0)==0){ha=(Ca|0)==0?0:83;c[V>>2]=ha;Y=ha;i=k;return Y|0}if((Ca&1073741823|0)==0){break}a[ta>>0]=a[Ba>>0]|0;if(Ca<<2>>>0>1){Sc=ta;Tc=Ba;Uc=1}else{break}while(1){a[Sc+Uc>>0]=a[Tc+Uc>>0]|0;ta=Uc+1|0;if(!(ta>>>0>2]<<2>>>0)){break m}Sc=c[D>>2]|0;Tc=c[B>>2]|0;Uc=ta}}}while(0);c[V>>2]=0;Y=0;i=k;return Y|0}D=c[Ia>>2]|0;n:do{if((D|0)==(c[z>>2]|0)){if((c[g+104>>2]|0)!=(c[A>>2]|0)){break}Ba=c[g+116>>2]|0;if((Ba|0)!=(c[y>>2]|0)){break}if((Ba|0)!=0){if((c[g+120>>2]|0)!=(c[$>>2]|0)){break}if((c[g+124>>2]|0)!=(c[_>>2]|0)){break}if((c[g+128>>2]|0)!=(c[Z>>2]|0)){break}}Ba=c[g+112>>2]|0;if((Ba|0)!=(c[C>>2]|0)){break}if((Ba&1073741823|0)==0){Y=0;i=k;return Y|0}Ea=c[g+108>>2]|0;Fa=c[B>>2]|0;ta=Ba<<2;Ba=0;while(1){if((a[Ea+Ba>>0]|0)!=(a[Fa+Ba>>0]|0)){break n}Ba=Ba+1|0;if(!(Ba>>>0>>0)){Y=0;break}}i=k;return Y|0}}while(0);ta=c[b>>2]|0;do{if(!((D|0)==6|(D|0)==2)){if((c[g+104>>2]|0)==8){break}else{Y=56}i=k;return Y|0}}while(0);Ba=g+104|0;switch(D|0){case 2:{Vc=3;break};case 6:{Vc=4;break};case 3:case 0:{Vc=1;break};case 4:{Vc=2;break};default:{Vc=0}}Fa=aa(c[f>>2]|0,c[e>>2]|0)|0;Ea=Pd(((aa(aa(Fa,c[Ba>>2]|0)|0,Vc)|0)+7|0)>>>3)|0;c[b>>2]=Ea;o:do{if((Ea|0)==0){Wc=83}else{Ca=c[g+20>>2]|0;ha=c[Ia>>2]|0;p:do{if((ha|0)==(c[z>>2]|0)){ua=c[Ba>>2]|0;if((ua|0)!=(c[A>>2]|0)){break}P=c[g+116>>2]|0;if((P|0)!=(c[y>>2]|0)){break}if((P|0)!=0){if((c[g+120>>2]|0)!=(c[$>>2]|0)){break}if((c[g+124>>2]|0)!=(c[_>>2]|0)){break}if((c[g+128>>2]|0)!=(c[Z>>2]|0)){break}}P=c[g+112>>2]|0;if((P|0)!=(c[C>>2]|0)){break}if((P&1073741823|0)!=0){Da=c[g+108>>2]|0;Ka=c[B>>2]|0;Ja=P<<2;P=0;do{if((a[Da+P>>0]|0)!=(a[Ka+P>>0]|0)){break p}P=P+1|0}while(P>>>0>>0)}switch(ha|0){case 4:{Zc=2;break};case 6:{Zc=4;break};case 3:case 0:{Zc=1;break};case 2:{Zc=3;break};default:{Zc=0}}Ja=((aa(aa(ua,Fa)|0,Zc)|0)+7|0)>>>3;if((Ja|0)==0){Wc=0;break o}else{_c=0}while(1){a[Ea+_c>>0]=a[ta+_c>>0]|0;_c=_c+1|0;if(!(_c>>>0>>0)){Wc=0;break o}}}}while(0);do{if((ha|0)==3){Ja=1<>2];ua=c[g+112>>2]|0;P=ua>>>0>>0?ua:Ja;H=l+0|0;I=H+64|0;do{c[H>>2]=0;H=H+4|0}while((H|0)<(I|0));c[l+64>>2]=-1;if((P|0)==0){break}Ka=g+108|0;Da=~ua;Aa=~Ja;na=~(Da>>>0>Aa>>>0?Da:Aa);Aa=0;do{Da=Aa<<2;G=c[Ka>>2]|0;ra=d[G+Da>>0]|0;sa=d[G+(Da|1)>>0]|0;qa=d[G+(Da|2)>>0]|0;pa=d[G+(Da|3)>>0]|0;Da=l;G=0;while(1){oa=Da+((sa>>>G<<2&4|pa>>>G&1|ra>>>G<<3&8|qa>>>G<<1&2)<<2)|0;ka=c[oa>>2]|0;if((ka|0)==0){ma=Pd(68)|0;c[oa>>2]=ma;H=ma+0|0;I=H+64|0;do{c[H>>2]=0;H=H+4|0}while((H|0)<(I|0));c[ma+64>>2]=-1;$c=c[oa>>2]|0}else{$c=ka}G=G+1|0;if((G|0)==8){break}else{Da=$c}}c[$c+64>>2]=Aa;Aa=Aa+1|0}while((Aa|0)!=(na|0))}}while(0);na=c[Ba>>2]|0;q:do{if((c[A>>2]|0)==16&(na|0)==16){if((Fa|0)==0){ad=0;break}else{bd=1;cd=0}while(1){if(!bd){ad=85;break q}Aa=c[z>>2]|0;r:do{if((Aa|0)==0){Ka=cd<<1;Ja=a[ta+(Ka|1)>>0]|0;ua=d[ta+Ka>>0]<<8|Ja&255;Ka=ua&65535;do{if((c[y>>2]|0)!=0){if((ua|0)!=(c[$>>2]|0)){break}dd=0;ed=0;fd=Ja;gd=(Ka&65535)>>>8&255;hd=Ja;id=(Ka&65535)>>>8&255;jd=Ja;kd=(Ka&65535)>>>8&255;break r}}while(0);dd=-1;ed=-1;fd=Ja;gd=(Ka&65535)>>>8&255;hd=Ja;id=(Ka&65535)>>>8&255;jd=Ja;kd=(Ka&65535)>>>8&255}else if((Aa|0)==6){ua=cd<<3;dd=a[ta+(ua|7)>>0]|0;ed=a[ta+(ua|6)>>0]|0;fd=a[ta+(ua|5)>>0]|0;gd=a[ta+(ua|4)>>0]|0;hd=a[ta+(ua|3)>>0]|0;id=a[ta+(ua|2)>>0]|0;jd=a[ta+(ua|1)>>0]|0;kd=a[ta+ua>>0]|0}else if((Aa|0)==4){ua=cd<<2;ka=a[ta+(ua|1)>>0]|0;oa=(d[ta+ua>>0]<<8|ka&255)&65535;dd=a[ta+(ua|3)>>0]|0;ed=a[ta+(ua|2)>>0]|0;fd=ka;gd=(oa&65535)>>>8&255;hd=ka;id=(oa&65535)>>>8&255;jd=ka;kd=(oa&65535)>>>8&255}else if((Aa|0)==2){oa=cd*6|0;ka=a[ta+(oa|1)>>0]|0;ua=d[ta+oa>>0]<<8|ka&255;ma=ua&65535;P=a[ta+(oa+3)>>0]|0;Da=d[ta+(oa+2)>>0]<<8|P&255;G=Da&65535;qa=a[ta+(oa+5)>>0]|0;ra=d[ta+(oa+4)>>0]<<8|qa&255;oa=ra&65535;do{if((c[y>>2]|0)!=0){if((ua|0)!=(c[$>>2]|0)){break}if((Da|0)!=(c[_>>2]|0)){break}if((ra|0)!=(c[Z>>2]|0)){break}dd=0;ed=0;fd=qa;gd=(oa&65535)>>>8&255;hd=P;id=(G&65535)>>>8&255;jd=ka;kd=(ma&65535)>>>8&255;break r}}while(0);dd=-1;ed=-1;fd=qa;gd=(oa&65535)>>>8&255;hd=P;id=(G&65535)>>>8&255;jd=ka;kd=(ma&65535)>>>8&255}else{ad=85;break q}}while(0);if((c[Ba>>2]|0)!=16){ad=85;break q}Aa=c[Ia>>2]|0;if((Aa|0)==2){ra=cd*6|0;a[Ea+ra>>0]=kd;a[Ea+(ra|1)>>0]=jd;a[Ea+(ra+2)>>0]=id;a[Ea+(ra+3)>>0]=hd;a[Ea+(ra+4)>>0]=gd;a[Ea+(ra+5)>>0]=fd}else if((Aa|0)==4){ra=cd<<2;a[Ea+ra>>0]=kd;a[Ea+(ra|1)>>0]=jd;a[Ea+(ra|2)>>0]=ed;a[Ea+(ra|3)>>0]=dd}else if((Aa|0)==0){ra=cd<<1;a[Ea+ra>>0]=kd;a[Ea+(ra|1)>>0]=jd}else if((Aa|0)==6){Aa=cd<<3;a[Ea+Aa>>0]=kd;a[Ea+(Aa|1)>>0]=jd;a[Ea+(Aa|2)>>0]=id;a[Ea+(Aa|3)>>0]=hd;a[Ea+(Aa|4)>>0]=gd;a[Ea+(Aa|5)>>0]=fd;a[Ea+(Aa|6)>>0]=ed;a[Ea+(Aa|7)>>0]=dd}Aa=cd+1|0;if(!(Aa>>>0>>0)){ad=0;break q}bd=(c[A>>2]|0)==16;cd=Aa}}else{do{if((na|0)==8){if((ha|0)==6){ad=Pc(Ea,Fa,1,ta,z,Ca)|0;break q}else if((ha|0)==2){ad=Pc(Ea,Fa,0,ta,z,Ca)|0;break q}else{break}}}while(0);if((Fa|0)==0){ad=0;break}Aa=(Ca|0)==0;ra=0;Da=0;ua=0;Ka=0;Ja=0;s:while(1){t:do{switch(c[z>>2]|0){case 0:{pa=c[A>>2]|0;if((pa|0)==8){sa=a[ta+Ka>>0]|0;if((c[y>>2]|0)!=0?(sa&255|0)==(c[$>>2]|0):0){ld=0;md=sa;nd=sa;od=sa;break t}ld=-1;md=sa;nd=sa;od=sa;break t}else if((pa|0)==16){sa=Ka<<1;la=a[ta+sa>>0]|0;if((c[y>>2]|0)!=0?((la&255)<<8|d[ta+(sa|1)>>0]|0)==(c[$>>2]|0):0){ld=0;md=la;nd=la;od=la;break t}ld=-1;md=la;nd=la;od=la;break t}else{la=(1<>>3)>>0]|0)>>>(sa&7^7)&1)<>>0>>0)){pd=wa;break}else{sa=sa+1|0;ia=wa}}}ia=(((pd*255|0)>>>0)/(la>>>0)|0)&255;if((c[y>>2]|0)!=0?(pd|0)==(c[$>>2]|0):0){ld=0;md=ia;nd=ia;od=ia;break t}ld=-1;md=ia;nd=ia;od=ia;break t}break};case 2:{if((c[A>>2]|0)==8){ia=Ka*3|0;sa=a[ta+ia>>0]|0;pa=a[ta+(ia+1)>>0]|0;ja=a[ta+(ia+2)>>0]|0;do{if((c[y>>2]|0)!=0){if((sa&255|0)!=(c[$>>2]|0)){break}if((pa&255|0)!=(c[_>>2]|0)){break}if((ja&255|0)==(c[Z>>2]|0)){ld=0;md=ja;nd=pa;od=sa;break t}}}while(0);ld=-1;md=ja;nd=pa;od=sa;break t}else{la=Ka*6|0;ia=a[ta+la>>0]|0;ma=a[ta+(la+2)>>0]|0;ka=a[ta+(la+4)>>0]|0;do{if((c[y>>2]|0)!=0){if(((ia&255)<<8|d[ta+(la|1)>>0]|0)!=(c[$>>2]|0)){break}if(((ma&255)<<8|d[ta+(la+3)>>0]|0)!=(c[_>>2]|0)){break}if(((ka&255)<<8|d[ta+(la+5)>>0]|0)==(c[Z>>2]|0)){ld=0;md=ka;nd=ma;od=ia;break t}}}while(0);ld=-1;md=ka;nd=ma;od=ia;break t}break};case 3:{qd=c[A>>2]|0;if((qd|0)==8){rd=d[ta+Ka>>0]|0}else if((qd|0)==0){rd=0}else{la=aa(qd,Ka)|0;sa=qd+ -1|0;pa=0;while(1){ja=(((d[ta+(la>>>3)>>0]|0)>>>(la&7^7)&1)<>>0>>0)){rd=ja;break}else{la=la+1|0;pa=ja}}}if(!(rd>>>0<(c[C>>2]|0)>>>0)){if(Aa){break s}else{ld=-1;md=0;nd=0;od=0;break t}}else{pa=rd<<2;la=c[B>>2]|0;ld=a[la+(pa|3)>>0]|0;md=a[la+(pa|2)>>0]|0;nd=a[la+(pa|1)>>0]|0;od=a[la+pa>>0]|0;break t}break};case 4:{if((c[A>>2]|0)==8){pa=Ka<<1;la=a[ta+pa>>0]|0;ld=a[ta+(pa|1)>>0]|0;md=la;nd=la;od=la;break t}else{la=Ka<<2;pa=a[ta+la>>0]|0;ld=a[ta+(la|2)>>0]|0;md=pa;nd=pa;od=pa;break t}break};case 6:{if((c[A>>2]|0)==8){pa=Ka<<2;ld=a[ta+(pa|3)>>0]|0;md=a[ta+(pa|2)>>0]|0;nd=a[ta+(pa|1)>>0]|0;od=a[ta+pa>>0]|0;break t}else{pa=Ka<<3;ld=a[ta+(pa|6)>>0]|0;md=a[ta+(pa|4)>>0]|0;nd=a[ta+(pa|2)>>0]|0;od=a[ta+pa>>0]|0;break t}break};default:{ld=ra;md=Da;nd=ua;od=Ja}}}while(0);u:do{switch(c[Ia>>2]|0){case 0:{pa=c[Ba>>2]|0;if((pa|0)==8){a[Ea+Ka>>0]=od;break u}else if((pa|0)!=16){if((pa|0)==1){sd=7}else{sd=(pa|0)==2?3:1}la=sd&Ka;sa=((1<>>(8-pa|0))<<(aa(sd-la|0,pa)|0);if((la|0)==0){a[Ea+((aa(pa,Ka)|0)>>>3)>>0]=sa;break u}else{la=Ea+((aa(pa,Ka)|0)>>>3)|0;a[la>>0]=d[la>>0]|sa;break u}}else{sa=Ka<<1;a[Ea+(sa|1)>>0]=od;a[Ea+sa>>0]=od;break u}break};case 3:{sa=od&255;la=nd&255;pa=md&255;ia=ld&255;ma=l;ka=0;do{ma=c[ma+((la>>>ka<<2&4|ia>>>ka&1|sa>>>ka<<3&8|pa>>>ka<<1&2)<<2)>>2]|0;ka=ka+1|0;if((ma|0)==0){ad=82;break q}}while((ka|0)<8);ka=c[ma+64>>2]|0;if((ka|0)<0){ad=82;break q}pa=c[Ba>>2]|0;if((pa|0)==1){td=7}else if((pa|0)==8){a[Ea+Ka>>0]=ka;break u}else{td=(pa|0)==2?3:1}sa=td&Ka;ia=((1<>>3)>>0]=ia;break u}else{sa=Ea+((aa(pa,Ka)|0)>>>3)|0;a[sa>>0]=d[sa>>0]|ia;break u}break};case 6:{if((c[Ba>>2]|0)==8){ia=Ka<<2;a[Ea+ia>>0]=od;a[Ea+(ia|1)>>0]=nd;a[Ea+(ia|2)>>0]=md;a[Ea+(ia|3)>>0]=ld;break u}else{ia=Ka<<3;a[Ea+(ia|1)>>0]=od;a[Ea+ia>>0]=od;a[Ea+(ia|3)>>0]=nd;a[Ea+(ia|2)>>0]=nd;a[Ea+(ia|5)>>0]=md;a[Ea+(ia|4)>>0]=md;a[Ea+(ia|7)>>0]=ld;a[Ea+(ia|6)>>0]=ld;break u}break};case 4:{ia=c[Ba>>2]|0;if((ia|0)==8){sa=Ka<<1;a[Ea+sa>>0]=od;a[Ea+(sa|1)>>0]=ld;break u}else if((ia|0)==16){ia=Ka<<2;a[Ea+(ia|1)>>0]=od;a[Ea+ia>>0]=od;a[Ea+(ia|3)>>0]=ld;a[Ea+(ia|2)>>0]=ld;break u}else{break u}break};case 2:{if((c[Ba>>2]|0)==8){ia=Ka*3|0;a[Ea+ia>>0]=od;a[Ea+(ia+1)>>0]=nd;a[Ea+(ia+2)>>0]=md;break u}else{ia=Ka*6|0;a[Ea+(ia|1)>>0]=od;a[Ea+ia>>0]=od;a[Ea+(ia+3)>>0]=nd;a[Ea+(ia+2)>>0]=nd;a[Ea+(ia+5)>>0]=md;a[Ea+(ia+4)>>0]=md;break u}break};default:{}}}while(0);Ka=Ka+1|0;if(!(Ka>>>0>>0)){ad=0;break q}else{ra=ld;Da=md;ua=nd;Ja=od}}ad=(qd|0)==8?46:47}}while(0);if((c[Ia>>2]|0)!=3){Wc=ad;break}Qc(l);Wc=ad}}while(0);c[V>>2]=Wc;Qd(ta);Y=c[V>>2]|0;i=k;return Y|0}c[g+292>>2]=29;x=29;break}c[g+292>>2]=28;x=28}}while(0);c[g+292>>2]=x;Y=x;i=k;return Y|0}function Sc(){var a=0,b=0,d=0,e=0,f=0,g=0,h=0,j=0;a=i;i=i+16|0;b=a;d=c[1280]|0;if((d|0)==0){i=a;return}if((c[(c[1278]|0)+4>>2]|0)<1){i=a;return}e=c[d+20>>2]|0;if((e|0)==-1){f=c[d+12>>2]|0;g=c[d+16>>2]|0;h=c[d>>2]|0;fb(1,b|0);ub(3553,c[b>>2]|0);Yb(3553,10240,9729);Yb(3553,10241,9729);Yb(3553,10242,33071);Yb(3553,10243,33071);ub(3553,c[b>>2]|0);bc(3317,1);Ob(3553,0,6408,f|0,g|0,0,6408,5121,h|0);h=c[b>>2]|0;c[(c[1280]|0)+20>>2]=h;j=h}else{j=e}ub(3553,j|0);j=c[1278]|0;Ya(34962,0,c[j+4>>2]<<5|0,c[j>>2]|0);Ab(4,0,c[(c[1278]|0)+4>>2]|0);c[(c[1278]|0)+4>>2]=0;i=a;return}function Tc(){var a=0,b=0,d=0,e=0.0,f=0.0,h=0;a=i;i=i+192|0;b=a;Sc();d=b+28|0;c[b+0>>2]=0;c[b+4>>2]=0;c[b+8>>2]=0;c[b+12>>2]=0;c[b+16>>2]=0;c[b+20>>2]=0;c[b+24>>2]=0;g[d>>2]=1.0;g[b+32>>2]=0.0;e=+(c[1284]|0);g[b+36>>2]=e;g[b+40>>2]=0.0;g[b+44>>2]=1.0;g[b+48>>2]=0.0;g[b+52>>2]=0.0;g[b+56>>2]=0.0;g[b+60>>2]=1.0;f=+(c[1282]|0);g[b+64>>2]=f;g[b+68>>2]=e;g[b+72>>2]=1.0;g[b+76>>2]=1.0;g[b+80>>2]=0.0;g[b+84>>2]=0.0;g[b+88>>2]=0.0;g[b+92>>2]=1.0;g[b+96>>2]=f;g[b+100>>2]=e;g[b+104>>2]=1.0;g[b+108>>2]=1.0;g[b+112>>2]=0.0;g[b+116>>2]=0.0;g[b+120>>2]=0.0;g[b+124>>2]=1.0;g[b+128>>2]=f;g[b+132>>2]=0.0;g[b+136>>2]=1.0;d=b+140|0;h=b+156|0;c[d+0>>2]=0;c[d+4>>2]=0;c[d+8>>2]=0;c[d+12>>2]=0;g[h>>2]=1.0;h=b+160|0;d=b+188|0;c[h+0>>2]=0;c[h+4>>2]=0;c[h+8>>2]=0;c[h+12>>2]=0;c[h+16>>2]=0;c[h+20>>2]=0;c[h+24>>2]=0;g[d>>2]=1.0;Ya(34962,0,192,b|0);Ab(4,0,6);i=a;return}function Uc(){var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0;b=i;i=i+48|0;d=b;mc();a:do{if((Wb(d|0)|0)!=0){e=d+16|0;while(1){f=c[d>>2]|0;switch(f|0){case 256:{c[9256>>2]=(c[9256>>2]|0)==0?1:2;break};case 1796:case 1793:case 1026:{g=8;break};case 1795:case 1792:case 1025:{g=7;break};case 768:{if((c[e>>2]|0)==27){c[9256>>2]=(c[9256>>2]|0)==0?1:2;switch(f|0){case 1796:case 1793:case 1026:{g=8;break};case 1795:case 1792:case 1025:{g=7;break};default:{}}}break};default:{}}if((g|0)==7?(g=0,c[2304]=1,(f|0)==1796|(f|0)==1793|(f|0)==1026):0){g=8}if((g|0)==8){g=0;c[2304]=0}if((Wb(d|0)|0)==0){break a}}}}while(0);if((c[1528]|0)!=0){g=6136;e=c[g>>2]|0;f=c[g+4>>2]|0;if((f|0)>0|(f|0)==0&e>>>0>1e5){g=6136;c[g>>2]=1e5;c[g+4>>2]=0;h=0;j=1e5}else{h=f;j=e}e=5104;f=c[e+4>>2]|0;if(((h|0)>(f|0)|((h|0)==(f|0)?j>>>0>=(c[e>>2]|0)>>>0:0))&(c[1532]|0)!=0){do{e=Xa(0)|0;do{if((a[e+122>>0]|0)!=0){if((c[2306]|0)==0){c[2306]=1;break}else{c[2306]=2;break}}else{c[2306]=0}}while(0);do{if((a[e+120>>0]|0)!=0){if((c[9228>>2]|0)==0){c[9228>>2]=1;break}else{c[9228>>2]=2;break}}else{c[9228>>2]=0}}while(0);do{if((a[e+1106>>0]|0)!=0){if((c[9232>>2]|0)==0){c[9232>>2]=1;break}else{c[9232>>2]=2;break}}else{c[9232>>2]=0}}while(0);do{if((a[e+1105>>0]|0)!=0){if((c[9236>>2]|0)==0){c[9236>>2]=1;break}else{c[9236>>2]=2;break}}else{c[9236>>2]=0}}while(0);do{if((a[e+1104>>0]|0)!=0){if((c[9240>>2]|0)==0){c[9240>>2]=1;break}else{c[9240>>2]=2;break}}else{c[9240>>2]=0}}while(0);do{if((a[e+1103>>0]|0)!=0){if((c[9244>>2]|0)==0){c[9244>>2]=1;break}else{c[9244>>2]=2;break}}else{c[9244>>2]=0}}while(0);do{if((a[e+32>>0]|0)!=0){if((c[9248>>2]|0)==0){c[9248>>2]=1;break}else{c[9248>>2]=2;break}}else{c[9248>>2]=0}}while(0);do{if(((a[e+1112>>0]|a[e+13>>0])&255|c[2304]|0)!=0){if((c[9252>>2]|0)==0){c[9252>>2]=1;break}else{c[9252>>2]=2;break}}else{c[9252>>2]=0}}while(0);do{if((a[e+112>>0]|0)!=0){if((c[9260>>2]|0)==0){c[9260>>2]=1;break}else{c[9260>>2]=2;break}}else{c[9260>>2]=0}}while(0);xc[c[1528]&7](0);e=5104;j=c[e>>2]|0;f=c[e+4>>2]|0;e=6136;h=de(c[e>>2]|0,c[e+4>>2]|0,j|0,f|0)|0;e=E;g=6136;c[g>>2]=h;c[g+4>>2]=e;c[9256>>2]=0}while(((e|0)>(f|0)|(e|0)==(f|0)&h>>>0>=j>>>0)&(c[1532]|0)!=0)}}j=c[1530]|0;if((j|0)==0){nb(d|0,0)|0;k=c[d>>2]|0;l=(k|0)<0;m=l<<31>>31;n=qe(k|0,m|0,1e6,0)|0;o=E;p=d+4|0;q=c[p>>2]|0;r=(q|0)<0;s=r<<31>>31;t=ee(n|0,o|0,q|0,s|0)|0;u=E;v=6144;w=v;x=c[w>>2]|0;y=v+4|0;z=y;A=c[z>>2]|0;B=de(t|0,u|0,x|0,A|0)|0;C=E;D=6136;F=D;G=c[F>>2]|0;H=D+4|0;I=H;J=c[I>>2]|0;K=ee(B|0,C|0,G|0,J|0)|0;L=E;M=6136;N=M;c[N>>2]=K;O=M+4|0;P=O;c[P>>2]=L;Q=6144;R=Q;c[R>>2]=t;S=Q+4|0;T=S;c[T>>2]=u;i=b;return}h=6136;f=5104;vc[j&3](0,(+((c[h>>2]|0)>>>0)+4294967296.0*+(c[h+4>>2]|0))/(+((c[f>>2]|0)>>>0)+4294967296.0*+(c[f+4>>2]|0)));Sc();nb(d|0,0)|0;k=c[d>>2]|0;l=(k|0)<0;m=l<<31>>31;n=qe(k|0,m|0,1e6,0)|0;o=E;p=d+4|0;q=c[p>>2]|0;r=(q|0)<0;s=r<<31>>31;t=ee(n|0,o|0,q|0,s|0)|0;u=E;v=6144;w=v;x=c[w>>2]|0;y=v+4|0;z=y;A=c[z>>2]|0;B=de(t|0,u|0,x|0,A|0)|0;C=E;D=6136;F=D;G=c[F>>2]|0;H=D+4|0;I=H;J=c[I>>2]|0;K=ee(B|0,C|0,G|0,J|0)|0;L=E;M=6136;N=M;c[N>>2]=K;O=M+4|0;P=O;c[P>>2]=L;Q=6144;R=Q;c[R>>2]=t;S=Q+4|0;T=S;c[T>>2]=u;i=b;return}function Vc(b){b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0;d=i;i=i+304|0;e=d;do{if((b|0)!=0){f=fe(b|0)|0;if((f|0)>=4){g=b+(f+ -4)|0;f=a[g>>0]|0;a:do{if(f<<24>>24==0){h=0;j=6152}else{k=4;l=f;m=g;n=6152;while(1){k=k+ -1|0;o=a[n>>0]|0;if(!((k|0)!=0&o<<24>>24!=0&l<<24>>24==o<<24>>24)){h=l;j=n;break a}m=m+1|0;o=n+1|0;l=a[m>>0]|0;if(l<<24>>24==0){h=0;j=o;break}else{n=o}}}}while(0);if(!(h<<24>>24==(a[j>>0]|0))){p=7}}else{p=7}if((p|0)==7){g=fe(b|0)|0;if((g|0)<4){break}f=b+(g+ -4)|0;g=a[f>>0]|0;b:do{if(g<<24>>24==0){q=0;r=6160}else{n=4;l=g;m=f;k=6160;while(1){n=n+ -1|0;o=a[k>>0]|0;if(!((n|0)!=0&o<<24>>24!=0&l<<24>>24==o<<24>>24)){q=l;r=k;break b}m=m+1|0;o=k+1|0;l=a[m>>0]|0;if(l<<24>>24==0){q=0;r=o;break}else{k=o}}}}while(0);if(!(q<<24>>24==(a[r>>0]|0))){break}}f=Pd(24)|0;g=f+12|0;k=f+16|0;l=Pb(b|0,11936)|0;c:do{if((l|0)==0){Qd(0);s=78;p=88}else{Cb(l|0,0,2)|0;m=Ma(l|0)|0;Ia(l|0);n=Pd(m)|0;o=(m|0)==0;if(o|(n|0)==0){t=0}else{t=ra(n|0,1,m|0,l|0)|0}Fb(l|0)|0;m=(n|0)!=0|o;o=m?0:83;if(m){c[e+24>>2]=1;c[e+28>>2]=1;c[e+32>>2]=0;c[e+0>>2]=0;c[e+4>>2]=0;c[e+8>>2]=0;c[e+12>>2]=0;c[e+16>>2]=0;c[e+20>>2]=0;c[e+36>>2]=2;c[e+40>>2]=1;c[e+44>>2]=2048;c[e+48>>2]=3;c[e+52>>2]=128;c[e+56>>2]=1;c[e+60>>2]=0;c[e+64>>2]=0;c[e+68>>2]=0;c[e+76>>2]=1;c[e+80>>2]=1;c[e+72>>2]=2;c[e+88>>2]=0;c[e+84>>2]=0;c[e+92>>2]=0;c[e+96>>2]=1;m=e+100|0;u=e+104|0;v=e+108|0;w=e+112|0;x=e+160|0;y=e+144|0;c[x+0>>2]=0;c[x+4>>2]=0;c[x+8>>2]=0;c[x+12>>2]=0;c[v+0>>2]=0;c[v+4>>2]=0;c[v+8>>2]=0;c[v+12>>2]=0;c[v+16>>2]=0;c[v+20>>2]=0;c[y>>2]=6;c[e+148>>2]=8;c[e+152>>2]=0;c[e+156>>2]=0;c[e+140>>2]=0;c[e+132>>2]=0;c[e+136>>2]=0;y=e+176|0;c[e+252>>2]=0;x=e+268|0;c[x+0>>2]=0;c[x+4>>2]=0;c[x+8>>2]=0;c[x+12>>2]=0;c[x+16>>2]=0;c[x+20>>2]=0;x=y+0|0;y=x+52|0;do{c[x>>2]=0;x=x+4|0}while((x|0)<(y|0));c[e+292>>2]=1;c[m>>2]=6;c[u>>2]=8;x=Rc(f,g,k,e,n,t)|0;y=c[v>>2]|0;if((y|0)!=0){Qd(y)}c[v>>2]=0;c[w>>2]=0;Oc(e+132|0);z=n;A=x}else{z=0;A=o}Qd(z);if((A|0)==0){c[f+4>>2]=(c[g>>2]|0)/-2|0;c[f+8>>2]=(c[k>>2]|0)/-2|0;c[f+20>>2]=-1;B=f;i=d;return B|0}else{C=A}do{switch(C|0){case 11:{D=1144;E=C;break c;break};case 17:{D=1304;E=C;break c;break};case 20:{D=1400;E=C;break c;break};case 1:{D=1064;E=C;break c;break};case 15:{D=1200;E=C;break c;break};case 31:{D=1896;E=C;break c;break};case 36:{D=2088;E=C;break c;break};case 14:{D=1200;E=C;break c;break};case 37:{D=2128;E=C;break c;break};case 38:{D=2176;E=C;break c;break};case 39:{D=2200;E=C;break c;break};case 34:{D=1992;E=C;break c;break};case 42:{D=2376;E=C;break c;break};case 43:{D=2448;E=C;break c;break};case 44:{D=2496;E=C;break c;break};case 26:{D=1640;E=C;break c;break};case 24:{D=1560;E=C;break c;break};case 32:{D=1928;E=C;break c;break};case 27:{D=1704;E=C;break c;break};case 30:{D=1840;E=C;break c;break};case 10:{D=1088;E=C;break c;break};case 47:{D=2656;E=C;break c;break};case 48:{D=2728;E=C;break c;break};case 21:{D=1456;E=C;break c;break};case 28:{D=1744;E=C;break c;break};case 16:{D=1248;E=C;break c;break};case 29:{D=1800;E=C;break c;break};case 25:{D=1592;E=C;break c;break};case 45:{D=2544;E=C;break c;break};case 18:{D=1360;E=C;break c;break};case 33:{D=1960;E=C;break c;break};case 35:{D=2024;E=C;break c;break};case 46:{D=2584;E=C;break c;break};case 50:{D=2768;E=C;break c;break};case 13:{D=1200;E=C;break c;break};case 22:{D=1304;E=C;break c;break};case 41:{D=2336;E=C;break c;break};case 49:{D=2768;E=C;break c;break};case 51:{D=2832;E=C;break c;break};case 40:{D=2288;E=C;break c;break};case 19:{D=1304;E=C;break c;break};case 23:{D=1512;E=C;break c;break};case 52:{D=2888;E=C;break c;break};case 60:{D=3320;E=C;break c;break};case 0:{D=1032;E=C;break c;break};case 66:{D=3688;E=C;break c;break};case 75:{D=4256;E=C;break c;break};case 76:{D=4320;E=C;break c;break};case 86:{D=4744;E=C;break c;break};case 69:{D=3976;E=C;break c;break};case 67:{D=3784;E=C;break c;break};case 87:{D=4800;E=C;break c;break};case 83:{D=4616;E=C;break c;break};case 71:{D=4048;E=C;break c;break};case 81:{D=4504;E=C;break c;break};case 74:{D=4232;E=C;break c;break};case 77:{D=4368;E=C;break c;break};case 53:{D=2928;E=C;break c;break};case 54:{D=2960;E=C;break c;break};case 58:{D=3208;E=C;break c;break};case 56:{D=3072;E=C;break c;break};case 59:{D=3272;E=C;break c;break};case 68:{D=3880;E=C;break c;break};case 62:{D=3488;E=C;break c;break};case 78:{s=C;p=88;break c;break};case 55:{D=3024;E=C;break c;break};case 79:{D=4432;E=C;break c;break};case 84:{D=4648;E=C;break c;break};case 85:{D=4712;E=C;break c;break};case 88:{D=4888;E=C;break c;break};case 90:{D=5032;E=C;break c;break};case 61:{D=3400;E=C;break c;break};case 72:{D=4112;E=C;break c;break};case 73:{D=4208;E=C;break c;break};case 89:{D=4968;E=C;break c;break};case 82:{D=4544;E=C;break c;break};case 80:{D=4464;E=C;break c;break};case 57:{D=3152;E=C;break c;break};case 64:{D=3624;E=C;break c;break};case 63:{D=3544;E=C;break c;break};default:{D=5072;E=C;break c}}}while(0)}}while(0);if((p|0)==88){D=4400;E=s}c[e>>2]=E;c[e+4>>2]=D;eb(6168,e|0)|0;B=0;i=d;return B|0}}while(0);c[e>>2]=b;eb(6216,e|0)|0;B=0;i=d;return B|0}function Wc(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0.0,u=0.0,v=0.0;g=i;h=a[d>>0]|0;if(h<<24>>24==0){i=g;return}j=b+16|0;k=b+4|0;l=b+12|0;m=e;e=h;h=d;while(1){d=e<<24>>24;if((d|0)<(c[j>>2]|0)){n=c[b>>2]|0;o=c[k>>2]|0;p=(c[n+4>>2]|0)+m|0;q=c[1284]|0;r=(c[n+8>>2]|0)+f|0;s=q-(c[n+16>>2]|0)-r|0;t=1.0/+(c[n+12>>2]|0);u=+(o|0);v=u*+(d-(c[l>>2]|0)|0)*t;if((c[1280]|0)!=(n|0)){Sc();c[1280]=n}Lc(c[1278]|0,+(p|0),+(q-r|0),v,+(p+o|0),+(s|0),u*t+v)}s=h+1|0;o=a[s>>0]|0;if(o<<24>>24==0){break}m=(c[k>>2]|0)+m|0;e=o;h=s}i=g;return}function Xc(a,b,d,e,f,g,h,j){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0;k=i;l=g+ -1|0;g=h+ -1|0;h=0;do{m=c[8440+(h<<2)>>2]|0;n=a+(h<<2)|0;c[n>>2]=((l+m-(c[8408+(h<<2)>>2]|0)|0)>>>0)/(m>>>0)|0;m=c[8376+(h<<2)>>2]|0;o=((g+m-(c[8344+(h<<2)>>2]|0)|0)>>>0)/(m>>>0)|0;m=b+(h<<2)|0;c[m>>2]=o;p=(c[n>>2]|0)==0?0:o;c[m>>2]=p;if((p|0)==0){c[n>>2]=0}h=h+1|0}while((h|0)!=7);c[f>>2]=0;c[e>>2]=0;c[d>>2]=0;h=0;g=0;while(1){l=a+(g<<2)|0;n=c[l>>2]|0;p=b+(g<<2)|0;if((n|0)!=0?(m=c[p>>2]|0,(m|0)!=0):0){q=aa(m,(((aa(n,j)|0)+7|0)>>>3)+1|0)|0}else{q=0}n=g+1|0;m=d+(n<<2)|0;c[m>>2]=q+h;c[e+(n<<2)>>2]=(aa(((aa(c[l>>2]|0,j)|0)+7|0)>>>3,c[p>>2]|0)|0)+(c[e+(g<<2)>>2]|0);c[f+(n<<2)>>2]=(((aa(aa(c[p>>2]|0,j)|0,c[l>>2]|0)|0)+7|0)>>>3)+(c[f+(g<<2)>>2]|0);if((n|0)==7){break}h=c[m>>2]|0;g=n}i=k;return}function Yc(b,c,e,f,g){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0;h=i;j=(g+7|0)>>>3;k=((aa(g,e)|0)+7|0)>>>3;if((f|0)==0){l=0;i=h;return l|0}e=k+1|0;g=(k|0)==0;m=(j|0)==0;n=j>>>0>>0;o=0;p=0;a:while(1){q=aa(p,k)|0;r=aa(p,e)|0;s=r+1|0;b:do{switch(d[c+r>>0]|0|0){case 4:{if((o|0)==0){if(!m){t=0;do{a[b+(t+q)>>0]=a[c+(t+s)>>0]|0;t=t+1|0}while((t|0)!=(j|0))}if(!n){break b}t=q-j|0;u=j;while(1){a[b+(u+q)>>0]=(d[b+(t+u)>>0]|0)+(d[c+(u+s)>>0]|0);u=u+1|0;if((u|0)==(k|0)){break b}}}if(!m){u=0;do{a[b+(u+q)>>0]=(d[o+u>>0]|0)+(d[c+(u+s)>>0]|0);u=u+1|0}while((u|0)!=(j|0))}if(n){u=j;do{t=u-j|0;v=a[b+(t+q)>>0]|0;w=a[o+u>>0]|0;x=a[o+t>>0]|0;t=w&255;y=x&255;z=t-y|0;A=(z|0)>-1?z:0-z|0;z=v&255;B=z-y|0;C=(B|0)>-1?B:0-B|0;B=t+z+(aa(y,-2)|0)|0;y=((B|0)>-1?B:0-B|0)<<16>>16;if((y|0)<(A|0)&(y|0)<(C|0)){D=x}else{D=(C|0)<(A|0)?w:v}a[b+(u+q)>>0]=(D&255)+(d[c+(u+s)>>0]|0);u=u+1|0}while((u|0)!=(k|0))}break};case 0:{if(!g){u=0;do{a[b+(u+q)>>0]=a[c+(u+s)>>0]|0;u=u+1|0}while((u|0)!=(k|0))}break};case 3:{if((o|0)==0){if(!m){u=0;do{a[b+(u+q)>>0]=a[c+(u+s)>>0]|0;u=u+1|0}while((u|0)!=(j|0))}if(!n){break b}u=q-j|0;v=j;do{a[b+(v+q)>>0]=((d[b+(u+v)>>0]|0)>>>1)+(d[c+(v+s)>>0]|0);v=v+1|0}while((v|0)!=(k|0))}else{if(!m){v=0;do{a[b+(v+q)>>0]=((d[o+v>>0]|0)>>>1)+(d[c+(v+s)>>0]|0);v=v+1|0}while((v|0)!=(j|0))}if(!n){break b}v=q-j|0;u=j;do{a[b+(u+q)>>0]=(((d[o+u>>0]|0)+(d[b+(v+u)>>0]|0)|0)>>>1)+(d[c+(u+s)>>0]|0);u=u+1|0}while((u|0)!=(k|0))}break};case 2:{if((o|0)==0){if(g){break b}else{E=0}do{a[b+(E+q)>>0]=a[c+(E+s)>>0]|0;E=E+1|0}while((E|0)!=(k|0))}else{if(g){break b}else{F=0}do{a[b+(F+q)>>0]=(d[o+F>>0]|0)+(d[c+(F+s)>>0]|0);F=F+1|0}while((F|0)!=(k|0))}break};case 1:{if(!m){u=0;do{a[b+(u+q)>>0]=a[c+(u+s)>>0]|0;u=u+1|0}while((u|0)!=(j|0))}if(n){u=q-j|0;v=j;do{a[b+(v+q)>>0]=(d[b+(u+v)>>0]|0)+(d[c+(v+s)>>0]|0);v=v+1|0}while((v|0)!=(k|0))}break};default:{l=36;G=40;break a}}}while(0);o=b+q|0;p=p+1|0;if(!(p>>>0>>0)){l=0;G=40;break}}if((G|0)==40){i=h;return l|0}return 0}function Zc(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0;b=i;d=a+16|0;e=Pd(c[d>>2]<<2)|0;f=a+4|0;c[f>>2]=e;g=(e|0)==0;e=a+12|0;h=(c[e>>2]|0)+1|0;j=h<<2;if((j|0)!=0){k=Pd(h<<3)|0;if((k|0)==0){l=0;m=0}else{n=k;o=4}}else{n=0;o=4}do{if((o|0)==4){if((h|0)!=0){he(n|0,0,j|0)|0}k=(c[e>>2]|0)+1|0;p=k<<2;if((p|0)==0){q=0}else{r=Pd(k<<3)|0;if((r|0)==0){l=n;m=0;break}q=r}if((k|0)!=0){he(q|0,0,p|0)|0}if(g){l=n;m=q}else{p=c[d>>2]|0;if((p|0)==0){s=0}else{k=c[a+8>>2]|0;r=0;do{t=n+(c[k+(r<<2)>>2]<<2)|0;c[t>>2]=(c[t>>2]|0)+1;r=r+1|0}while(r>>>0
- - -
- -
- - -
- - -
- - - - - - -

About

-You are a robot on a rescue mision.
-The rescuer and the rescued are alone
-in a strange place.
-
-Good Luck!
-

 

- - - -

Play

-
-
- ► Play -
-
- Get it on Google Play -
-
-

 

- - - - - -

Screenshots

-

- - - - - -

-

 

- - - - -

Contact

- - -

 

- -

 

- - - - -
- Copyright © 2011-2014 Valeriano Alfonso. -
- -
- -
-
- - - \ No newline at end of file diff --git a/DIST/web/join.php b/DIST/web/join.php deleted file mode 100644 index 77278ac..0000000 --- a/DIST/web/join.php +++ /dev/null @@ -1,36 +0,0 @@ - - - -

OK!

- - \ No newline at end of file diff --git a/DIST/web/lonelyruins_banner.png b/DIST/web/lonelyruins_banner.png deleted file mode 100644 index b402f7f..0000000 Binary files a/DIST/web/lonelyruins_banner.png and /dev/null differ diff --git a/DIST/web/play.html b/DIST/web/play.html deleted file mode 100644 index b6e33ba..0000000 --- a/DIST/web/play.html +++ /dev/null @@ -1,133 +0,0 @@ - - - - - - Lonely Ruins - - - -
- -
-
-
-

Loading...

- Code:
-
-
- Data:
-
-
- -
- - - - - \ No newline at end of file diff --git a/DIST/web/sshots/20120102/shot-20120102-1.png b/DIST/web/sshots/20120102/shot-20120102-1.png deleted file mode 100644 index 1a3ad41..0000000 Binary files a/DIST/web/sshots/20120102/shot-20120102-1.png and /dev/null differ diff --git a/DIST/web/sshots/20120102/shot-20120102-1.thumb.png b/DIST/web/sshots/20120102/shot-20120102-1.thumb.png deleted file mode 100644 index c10eef1..0000000 Binary files a/DIST/web/sshots/20120102/shot-20120102-1.thumb.png and /dev/null differ diff --git a/DIST/web/sshots/20120102/shot-20120102-2.png b/DIST/web/sshots/20120102/shot-20120102-2.png deleted file mode 100644 index 7f18ffb..0000000 Binary files a/DIST/web/sshots/20120102/shot-20120102-2.png and /dev/null differ diff --git a/DIST/web/sshots/20120102/shot-20120102-2.thumb.png b/DIST/web/sshots/20120102/shot-20120102-2.thumb.png deleted file mode 100644 index 6436a93..0000000 Binary files a/DIST/web/sshots/20120102/shot-20120102-2.thumb.png and /dev/null differ diff --git a/DIST/web/sshots/20120102/shot-20120102-3.png b/DIST/web/sshots/20120102/shot-20120102-3.png deleted file mode 100644 index 2ae5264..0000000 Binary files a/DIST/web/sshots/20120102/shot-20120102-3.png and /dev/null differ diff --git a/DIST/web/sshots/20120102/shot-20120102-3.thumb.png b/DIST/web/sshots/20120102/shot-20120102-3.thumb.png deleted file mode 100644 index 1f4ba64..0000000 Binary files a/DIST/web/sshots/20120102/shot-20120102-3.thumb.png and /dev/null differ diff --git a/DIST/web/style.css b/DIST/web/style.css deleted file mode 100644 index 2e48216..0000000 --- a/DIST/web/style.css +++ /dev/null @@ -1,223 +0,0 @@ -/*********************************************** - * Copyright (c) 2012 Valeriano Alfonso * - ***********************************************/ - - - -/* Elementos Base */ -html, body { - height: 100%; - margin: 0; - padding: 0; - font-family: Verdana,Arial,Helvetica,sans-serif; - background-color:#000000; - color: #777777; - font-size: 10pt; -} -h1{ - text-align: left; - margin-top: 0; - margin-bottom: 1em; - font-size: 16pt; - font-weight: bold; -} -h2{ - text-align: left; - margin-top: 0; - margin-bottom: 0.75em; - font-size: 14pt; - font-weight: bold; -} -h3{ - text-align: left; - margin-top: 0; - margin-bottom: 0.5em; - font-size: 10pt; - font-weight: bold; -} -h4{ - margin-top: 0; - margin-bottom: 0.5em; - font-size: 11pt; - font-weight: bold; -} -p,li,td{ - margin-top: 0; - margin-bottom: 0.5em; - font-size: 10pt; -} -li { - padding:2px; -} -img { - border:0; -} - - - - - - -/* Links normales */ -a { - text-decoration:none; - font-weight: bold; - display:inline; -} -a:link { - color: #7777FF; -} -a:visited { - color: #7777FF; -} -a:hover { - color: #FFFFFF; - text-decoration: underline; -} -a:active { - color: #CBB545; -} - - - - - - - - - - -/* Estilo de Lonely Ruins */ -.contenedor { - margin: 0; - padding: 0; - float: left; - width: 100%; - min-height: 100%; -} -.cabecera { - width: 700px; - height:130px; - margin: 0 auto; - position: relative; -} -.titulo { - margin:0; - padding:0; - border:0; - vertical-align:bottom; - position:absolute; -} -a.titulo:hover { - background:none; -} -a.titulo img { - border:none; -} -a.titulo:hover img{ - border:none; -} -.contenido { - width: 700px; - margin:0; - padding:0; - border:0; - position:relative; - margin: 0 auto; - vertical-align:bottom; -} -.pie { - width:700px; - height: 64px; - margin:0; - padding:0; - border:0; - position:relative; - margin: 0 auto; - font-weight: bold; -} - - - - -.navbar { - height:130px; - width:500px; - margin:0; - padding:0; - border:0; - vertical-align:bottom; - position:absolute; - bottom:0px; - right:0px; -} -.navbar ul { - list-style:none; - list-style-type:none; - list-style-position:inside; - border:0; - padding:0; - margin:0; - display:block; - position:absolute; - bottom:0; - right:0; -} -.navbar li{ - padding:0px; - float: left; - text-align: center; - vertical-align: bottom; - margin: 1px; - border-left:1px solid #777777; -} -.navbar li:first-child{ - border-left:none; -} - -/* links del navbar */ -.navbar a { - padding: 4px; - font-size:12pt; - display:block; -} - - - -.toTop{ - text-align:right; - font-size:7pt; -} - - -.columnContainer{ - white-space: nowrap; - font-size: 0; - vertical-align: top; -} -.column2{ - width:50%; - display:inline-block; - font-size: 10pt; - vertical-align:top; -} - -.playLink{ - font-size:25px; - display: inline-block; - border-radius: 10px; - border: solid 1px grey; - width:127px; - height:43px; - line-height:43px; -} -.playLink:link{ - color: #777777; -} -.playLink:hover{ - box-shadow: 0 0 5px white; - text-shadow: 0 0 2px white; - border: solid 1px white; - text-decoration:none; - color: white; -} diff --git a/DIST/web/web_thumb.png b/DIST/web/web_thumb.png deleted file mode 100644 index 18b73ba..0000000 Binary files a/DIST/web/web_thumb.png and /dev/null differ diff --git a/GameEnts.c b/GameEnts.c index ab8b25c..7c48e0e 100644 --- a/GameEnts.c +++ b/GameEnts.c @@ -1,5 +1,6 @@ -// Copyright (C) 2011 Valeriano Alfonso Rodriguez (Kableado) +// Copyright (C) 2012 Valeriano Alfonso Rodriguez (Kableado) +#include #include #include @@ -8,660 +9,746 @@ extern int gamelib_debug; #include "GameEnts.h" -DrawImg img_barrel; -DrawImg img_barrel2; -DrawImg img_column; -DrawImg img_column_faded; -DrawImg img_rock; -DrawImg img_lamp; -DrawImg img_floor; -DrawImg img_floor_left; -DrawImg img_floor_right; -DrawImg img_floor_center; -DrawImg img_hole_spiked; -Anim anim_hole_lava; -DrawImg img_player_down; -DrawImg img_player_up; -DrawImg img_player_left; -DrawImg img_player_right; -DrawImg img_savepoint; -Anim anim_savepoint_active; -DrawImg img_endpoint; -Anim anim_exitpoint; -DrawImg img_arrowshooter_up; -DrawImg img_arrowshooter_down; -DrawImg img_arrowshooter_left; -DrawImg img_arrowshooter_right; -DrawImg img_arrow_up; -DrawImg img_arrow_down; -DrawImg img_arrow_left; -DrawImg img_arrow_right; -Anim anim_fire; -DrawImg img_player_broken; +DrawImg img_player; +DrawImg img_platform; +DrawImg img_block; + +Entity *ent_Player; +Entity *ent_Platform; +Entity *ent_Block; -AudioSnd snd_arrowhit; -AudioSnd snd_savepoint; -AudioSnd snd_exitpoint; -AudioSnd snd_shootarrow; -AudioSnd snd_burn; -AudioSnd snd_fillhole; -AudioSnd snd_drag; +DrawImg img_wizard[2]; +//DrawImg img_wizardWalking[2]; +//DrawImg img_wizardShoting[2]; +//DrawImg img_wizardPain[2]; +DrawImg img_magikball; +DrawImg img_earth[16]; +//DrawImg img_earthBack[16]; +DrawImg img_stoneBrick; +//DrawImg img_stoneBrick[16]; +//DrawImg img_stoneBrickBack[16]; +DrawImg img_spikedBush; +DrawImg img_lavaPit; +DrawImg img_fireball; +DrawImg img_flower[2]; +DrawImg img_spike[2]; +DrawImg img_carnivorePlant[2]; +DrawImg img_bunny[2]; +DrawImg img_spider[2]; +DrawImg img_guard[2]; +DrawImg img_eliteGuard[2]; +DrawImg img_axe[2]; +DrawImg img_goatMan[2]; +DrawImg img_Princess[2]; -Entity ent_player; -Entity ent_barrel; -Entity ent_column; -Entity ent_column_faded; -Entity ent_rock; -Entity ent_lamp; -Entity ent_floor; -Entity ent_floor_right; -Entity ent_floor_left; -Entity ent_floor_center; -Entity ent_hole_spiked; -Entity ent_hole_filled; -Entity ent_hole_lava; -Entity ent_arrowshooter_up; -Entity ent_arrowshooter_down; -Entity ent_arrowshooter_left; -Entity ent_arrowshooter_right; -Entity ent_arrow_up; -Entity ent_arrow_down; -Entity ent_arrow_left; -Entity ent_arrow_right; -Entity ent_exitpoint; -Entity ent_endpoint; -Entity ent_savepoint; -Entity ent_teleporter; -Entity ent_teleporter_dest; +Entity *ent_Wizard; +Entity *ent_MagikBall; +Entity *ent_Earth; +Entity *ent_EarthBack; +Entity *ent_StoneBrick; +Entity *ent_StoneBrickBack; +Entity *ent_SpikedBush; +Entity *ent_Fireball; +Entity *ent_LavaPit; +Entity *ent_Spike[2]; +Entity *ent_Flower[2]; +Entity *ent_CarnivorePlant[2]; +Entity *ent_Bunny; +Entity *ent_Spider; +Entity *ent_Axe; +Entity *ent_Guard; +Entity *ent_EliteGuard; +Entity *ent_GoatMan; +Entity *ent_Princess; -Entity ent_fire; -Entity ent_player_broken; -extern int game_level; -extern int game_level_point; -extern int game_level_reset; +int EntityApplyGravity(Entity *e){ + float grav=0.5f; + float vTerminal=10.0f; + vec2 vGrav; -void LoadGame(); -void SaveGame(); - - -void player_proc(Entity e,int ft){ - vec2 vel; - int pos[2],size[2],delta[2]; - - if (gamelib_debug) { - if (Input_GetKey(InputKey_Jump)==InputKey_Pressed) { - if (!(e->flags&EntityFlag_Collision)) { - e->flags|=(EntityFlag_Collision|EntityFlag_Overlap); - GameLib_EntitySetLight(e,0.4f,0.4f,0.4f,5*32.0f); - }else { - e->flags&=~(EntityFlag_Collision|EntityFlag_Overlap); - GameLib_EntitySetLight(e,0.7f,0.7f,0.7f,20*32.0f); - } - } + // Only apply gravity to some entity types + if(!( + e->type==Ent_Player || + e->type==Ent_Wizard || + e->type==Ent_Fireball || + e->type==Ent_Bunny || + e->type==Ent_Spider || + e->type==Ent_Axe || + e->type==Ent_Guard || + e->type==Ent_EliteGuard || + e->type==Ent_GoatMan || + e->type==Ent_Princess || + 0 + )) + { + return(1); } + // Apply gravity + vec2_set(vGrav,0.0f,grav); + Entity_AddVelLimit(e,vGrav,vTerminal); - if(Input_GetDir(vel)){ - vec2 up,right; - float updown,leftright; - vec2_set(up,0,-1); - vec2_set(right,1,0); - updown=vec2_dot(up,vel); - leftright=vec2_dot(right,vel); - if(fabs(updown)>=fabs(leftright)){ - if(updown>0.0f){ - AnimPlay_SetImg(&e->anim,img_player_up); - }else{ - AnimPlay_SetImg(&e->anim,img_player_down); - } - }else{ - if(leftright>0.0f){ - AnimPlay_SetImg(&e->anim,img_player_right); - }else{ - AnimPlay_SetImg(&e->anim,img_player_left); - } - } - - vec2_scale(vel,vel,7); - Entity_AddVelLimit(e,vel,15.0f); - } - - GameLib_MoveToPos(e->pos,0.3f); -} - -int player_collision(Entity e1,Entity e2,float t,vec2 n){ - if(e2->type==Ent_Barrel){ - float vlen; - vec2 vdir; - vlen=sqrtf(vec2_dot(e1->vel,e1->vel)); - if(vlen>0.0f){ - vec2_scale(vdir,e1->vel,1.0f/vlen); - if (vec2_dot(vdir,n) < -0.9f) { - vec2_orthogonalize4(n); - Entity_CollisionResponseCircle(e2,e1,t,n); - return(2); - } - } - } return(1); } -void barrel_proc(Entity e,int ft){ - float qvel; - int tnow; - qvel=vec2_dot(e->vel,e->vel); - if(qvel>0.0f){ - tnow=Time_GetTime()/1000; - if(tnow-250>e->A){ - GameLib_PlaySound(snd_drag,(int)e->pos[0],(int)e->pos[1]); - e->A=tnow; + +void EntEarth_Init(Entity *ent,int up,int down,int left,int right){ + int val=up*8+right*4+down*2+left; + + + if(!up && !down && !left && !right){ + ent->flags=0; + }else + if(up && !down && !left && !right){ + ent->flags=EntityFlag_PlatformCollision; + }else{ + ent->flags=EntityFlag_BlockCollision; + } + + AnimPlay_SetImg(&ent->anim,img_earth[val]); +} + +void EntStoneBrick_Init(Entity *ent,int up,int down,int left,int right){ + if(!up && !down && !left && !right){ + ent->flags=0; + }else + if(up && !down && !left && !right){ + ent->flags=EntityFlag_PlatformCollision; + }else{ + ent->flags=EntityFlag_BlockCollision; + } +} + + + + + + +void player_proc(Entity *e,int ft){ + float acel=1.0f; + float maxVel=4.0f; + float jumpVel=12.0f; + + if(Input_GetKey(InputKey_Jump)==InputKey_Pressed || + Input_GetKey(InputKey_Up)==InputKey_Pressed){ + vec2 jump; + + // Apply jump + vec2_set(jump,0.0f,-jumpVel); + vec2_plus(e->vel,e->vel,jump); + + // FIXME: play sound + } + if(Input_GetKey(InputKey_Left)){ + vec2 left; + + // Apply left movement + vec2_set(left,-acel,0.0f); + Entity_AddVelLimit(e,left,maxVel); + } + if(Input_GetKey(InputKey_Right)){ + vec2 right; + + // Apply right movement + vec2_set(right,acel,0.0f) + Entity_AddVelLimit(e,right,maxVel); + } + + + // Scroll View + GameLib_MoveToPosH(e->pos,0.1f); +} + + + + + + + +void wizard_proc(Entity *e,int ft){ + float acel=1.0f; + float maxVel=6.0f; + float jumpVel=8.0f; + float shootVel=10.0f; + + if(Input_GetKey(InputKey_Jump)==InputKey_Pressed || + Input_GetKey(InputKey_Up)==InputKey_Pressed) + { + vec2 jump; + + // Apply jump + vec2_set(jump,0.0f,-(jumpVel+fabs(e->vel[0]))); + vec2_plus(e->vel,e->vel,jump); + + // FIXME: play sound + } + if(Input_GetKey(InputKey_Left)){ + vec2 left; + + // Apply left movement + vec2_set(left,-acel,0.0f); + Entity_AddVelLimit(e,left,maxVel); + + + AnimPlay_SetImg(&e->anim,img_wizard[0]); + e->A=0; + } + if(Input_GetKey(InputKey_Right)){ + vec2 right; + + // Apply right movement + vec2_set(right,acel,0.0f) + Entity_AddVelLimit(e,right,maxVel); + + AnimPlay_SetImg(&e->anim,img_wizard[1]); + + e->A=1; + } + if(Input_GetKey(InputKey_Action1)==InputKey_Pressed || + Input_GetKey(InputKey_Action2)==InputKey_Pressed) + { + Entity *e2; + + // Create child entity + e2=Entity_Copy(e->child); + vec2_plus(e2->pos,e2->pos,e->pos); + if(e->A==0){ + vec2_set(e2->vel,-shootVel,0); + }else + if(e->A==1){ + vec2_set(e2->vel,shootVel,0); } + GameLib_AddEntity(e2); + } + + + // Scroll View + GameLib_MoveToPosH(e->pos,0.1f); } -void hole_spiked_overlap(Entity e1,Entity e2){ - Entity e; - - if(e2->type==Ent_Barrel){ - Entity e; - - // Disable future overlaps - e1->overlap=NULL; - - // "Fill the hole" - e=Entity_Copy(ent_hole_filled); - vec2_copy(e->pos,e1->pos); - GameLib_AddEntity(e); - GameLib_PlaySound(snd_fillhole,(int)e2->pos[0],(int)e2->pos[1]); - - // Remove the two entities - GameLib_DelEntity(e1); - GameLib_DelEntity(e2); - - } - if(e2->type==Ent_Player){ - // "Kill the player" - - // Broken player - e=Entity_Copy(ent_player_broken); - vec2_copy(e->pos,e2->pos); - GameLib_AddEntity(e); - - GameLib_PlaySound(snd_burn,(int)e2->pos[0],(int)e2->pos[1]); - GameLib_DelEntity(e2); - - // HACK - game_level_reset=1; - } -} -void hole_lava_oncopy(Entity ent){ - AnimPlay_IncTime(&ent->anim,rand()%1000); -} -void hole_lava_overlap(Entity e1,Entity e2){ - Entity e; - - if(e2->type==Ent_Barrel){ - // "Burn the barrel" - - // Make fire - e=Entity_Copy(ent_fire); - vec2_copy(e->pos,e2->pos); - GameLib_AddEntity(e); - - GameLib_PlaySound(snd_burn,(int)e2->pos[0],(int)e2->pos[1]); - GameLib_DelEntity(e2); - } - if(e2->type==Ent_Player){ - // "Burn the player" - - // Make fire - e=Entity_Copy(ent_fire); - vec2_copy(e->pos,e2->pos); - GameLib_AddEntity(e); - - // Broken player - e=Entity_Copy(ent_player_broken); - vec2_copy(e->pos,e2->pos); - GameLib_AddEntity(e); - - GameLib_PlaySound(snd_burn,(int)e2->pos[0],(int)e2->pos[1]); - GameLib_DelEntity(e2); - game_level_reset=1; - } -} - - -int arrow_collision(Entity e1,Entity e2,float t,vec2 n){ - Entity e; - - if(e1->postproc) +int magikball_collision(Entity *ent,Entity *ent2,float t,vec2 n){ + if(ent->A==1) return(0); - if(e2->type==Ent_ArrowShooter) - return(0); - if(e2->type==Ent_Arrow) - return(0); + if(ent2->type==Ent_Flower){ + Entity *e2; + // Convert a flower - if(e2->type==Ent_Player){ - // KILL the player - e=Entity_Copy(ent_player_broken); - vec2_copy(e->pos,e2->pos); - GameLib_AddEntity(e); - GameLib_DelEntity(e2); - GameLib_PlaySound(snd_burn,(int)e2->pos[0],(int)e2->pos[1]); - game_level_reset=1; + // Create replacemente entity + e2=Entity_Copy(ent_CarnivorePlant[ent2->D]); + vec2_plus(e2->pos,e2->pos,ent2->pos); + GameLib_AddEntity(e2); + + // Delete original entity + GameLib_DelEntity(ent2); } - GameLib_DelEntity(e1); - GameLib_PlaySound(snd_arrowhit,(int)e1->pos[0],(int)e1->pos[1]); + if(ent2->type==Ent_Bunny){ + Entity *e2; + // Convert a bunny + printf("Bunny\n"); + + // Create replacemente entity + e2=Entity_Copy(ent_Spider); + vec2_plus(e2->pos,e2->pos,ent2->pos); + GameLib_AddEntity(e2); + + // Copy direction + e2->A=ent2->A; + + // Delete original entity + GameLib_DelEntity(ent2); + } + + // Selfdestroy + GameLib_DelEntity(ent); + ent->A=1; + + // FIXME: play sound return(0); } -void arrowshooter_oncopy(Entity e){ - e->A=(rand()%15); + +void spikedentity_overlap(Entity *e,Entity *e2){ + // FIXME: damage player + printf("FIXME: damage player\n"); } -void arrowshooter_proc(Entity e,int ft){ - if(e->A==0){ - Entity e2; - e2=Entity_Copy(e->child); - vec2_copy(e2->pos,e->pos); +int spike_collision(Entity *ent,Entity *ent2,float t,vec2 n){ + if(ent->A==1) + return(0); + + if(ent2->type==Ent_Player || + ent2->type==Ent_Wizard) + { + // FIXME: damage player + printf("FIXME: damage player\n"); + } + + // Selfdestroy + GameLib_DelEntity(ent); + ent->A=1; + + // FIXME: play sound + + return(0); +} + +void flower_oncopy(Entity *ent){ + ent->A=rand()%ent->C; +} + +void flower_proc(Entity *ent,int ft){ + if(ent->A==0){ + Entity *e2; + + // Create child entity + e2=Entity_Copy(ent->child); + vec2_plus(e2->pos,e2->pos,ent->pos); GameLib_AddEntity(e2); - GameLib_PlaySound(snd_shootarrow,(int)e->pos[0],(int)e->pos[1]); - e->A=15; + + // FIXME: play sound + + ent->A=ent->B; }else{ - e->A--; + ent->A--; } } -Entity _savepoint=NULL; -void savepoint_ondelete(Entity e){ - if(_savepoint==e){ - _savepoint=NULL; + + + + + +void bunny_proc(Entity *e,int ft){ + float acel=1.0f; + float maxVel=4.0f; + float jumpVel=5.0f; + + if(e->B==0){ + vec2 jump; + + // Apply jump + vec2_set(jump,0.0f,-jumpVel); + vec2_plus(e->vel,e->vel,jump); + + // FIXME: play sound + + e->B=e->C; + }else{ + e->B--; } -} -void savepoint_overlap(Entity e1,Entity e2){ - if(e2->type==Ent_Player){ - // Save the point - if(game_level_point!=e1->A){ - game_level_point=e1->A; - GameLib_PlaySound(snd_savepoint,(int)e1->pos[0],(int)e1->pos[1]); - SaveGame(); - } - if(e1!=_savepoint){ - AnimPlay_SetAnim(&e1->anim,anim_savepoint_active); - GameLib_EntitySetLight(e1,0.0f,0.0f,0.5f,4*32.0f); - if(_savepoint){ - AnimPlay_SetImg(&_savepoint->anim,img_savepoint); - GameLib_EntitySetLight(_savepoint,0.0f,0.0f,0.5f,2*32.0f); - } - _savepoint=e1; - } - } -} - -void exitpoint_overlap(Entity e1,Entity e2){ - if(e2->type==Ent_Player){ - // Exit the level - game_level++; - game_level_point=1; - game_level_reset=2; - - // HACK: Delete the player - GameLib_DelEntity(e2); - - GameLib_PlaySound(snd_exitpoint,(int)e1->pos[0],(int)e1->pos[1]); - SaveGame(); - } -} - -void endpoint_overlap(Entity e1,Entity e2){ - if(e2->type==Ent_Player){ - // Go to end - game_level_reset=3; - - // HACK: Delete the player - GameLib_DelEntity(e2); - - GameLib_PlaySound(snd_exitpoint,(int)e1->pos[0],(int)e1->pos[1]); - SaveGame(); - } -} - -void timeoutent_proc(Entity e,int ft){ if(e->A==0){ - GameLib_DelEntity(e); + vec2 left; + + // Apply left movement + vec2_set(left,-acel,0.0f); + Entity_AddVelLimit(e,left,maxVel); + + + AnimPlay_SetImg(&e->anim,img_bunny[0]); + } + if(e->A==1){ + vec2 right; + + // Apply right movement + vec2_set(right,acel,0.0f) + Entity_AddVelLimit(e,right,maxVel); + + AnimPlay_SetImg(&e->anim,img_bunny[1]); + } +} +int bunny_collision(Entity *ent,Entity *ent2,float t,vec2 n){ + if(n[0]>0.5f){ + ent->A=1; + }else + if(n[0]<-0.5f){ + ent->A=0; + } + + + if(ent2->type==Ent_Player || + ent2->type==Ent_Wizard) + { + // FIXME: damage player + printf("FIXME: damage player\n"); + } + + return(1); +} + + + +void spider_proc(Entity *e,int ft){ + float acel=1.0f; + float maxVel=4.0f; + float jumpVel=5.0f; + + if(e->B==0){ + vec2 jump; + + // Apply jump + vec2_set(jump,0.0f,-jumpVel); + vec2_plus(e->vel,e->vel,jump); + + // FIXME: play sound + + e->B=e->C; }else{ - e->A--; + e->B--; + } + if(e->A==0){ + vec2 left; + + // Apply left movement + vec2_set(left,-acel,0.0f); + Entity_AddVelLimit(e,left,maxVel); + + + AnimPlay_SetImg(&e->anim,img_spider[0]); + } + if(e->A==1){ + vec2 right; + + // Apply right movement + vec2_set(right,acel,0.0f) + Entity_AddVelLimit(e,right,maxVel); + + AnimPlay_SetImg(&e->anim,img_spider[1]); } } - -int teleporter_searchdest(Entity ent,void *d){ - int a=*(int*)d; - if(ent->type!=Ent_Teleporter_Dest){ - return 0; +int spider_collision(Entity *ent,Entity *ent2,float t,vec2 n){ + if(n[0]>0.5f){ + ent->A=1; + }else + if(n[0]<-0.5f){ + ent->A=0; } - if(ent->A==a){ - return 1; - } - return 0; + return(1); } -void teleporter_overlap(Entity e1,Entity e2){ - Entity dest=NULL; - // Search the destination - dest=GameLib_SearchEnt(teleporter_searchdest,&e1->A); - if(dest){ - vec2_copy(e2->pos,dest->pos); - } -} + void GameEnts_Init(){ - Entity ent; - - ////////////////////////////// - // Load Resources - - img_barrel=Draw_LoadImage("data/barrel.png"); - Draw_SetOffset(img_barrel,-16,-32); - - img_barrel2=Draw_LoadImage("data/barrel2.png"); - Draw_SetOffset(img_barrel2,-16,-16); - - img_floor=Draw_LoadImage("data/floor.png"); - Draw_SetOffset(img_floor,-16,-16); - img_floor_left=Draw_LoadImage("data/floor_left.png"); - Draw_SetOffset(img_floor_left,-16,-16); - img_floor_right=Draw_LoadImage("data/floor_right.png"); - Draw_SetOffset(img_floor_right,-16,-16); - img_floor_center=Draw_LoadImage("data/floor_center.png"); - Draw_SetOffset(img_floor_center,-16,-16); - - img_column=Draw_LoadImage("data/column.png"); - Draw_SetOffset(img_column,-16,-80); - img_column_faded=Draw_LoadImage("data/column_faded.png"); - Draw_SetOffset(img_column_faded,-16,-80); - img_rock=Draw_LoadImage("data/rock.png"); - Draw_SetOffset(img_rock,-16,-32); - img_lamp=Draw_LoadImage("data/lamp.png"); - Draw_SetOffset(img_lamp,-16,-48); - - img_hole_spiked=Draw_LoadImage("data/hole_spiked.png"); - Draw_SetOffset(img_hole_spiked,-16,-16); - - anim_hole_lava=Anim_LoadAnim("data/hole_lava.png",32,2,5); - Anim_SetOffset(anim_hole_lava,-16,-16); - - img_player_up=Draw_LoadImage("data/player_up.png"); - Draw_SetOffset(img_player_up,-16,-48); - img_player_down=Draw_LoadImage("data/player_down.png"); - Draw_SetOffset(img_player_down,-16,-48); - img_player_left=Draw_LoadImage("data/player_left.png"); - Draw_SetOffset(img_player_left,-16,-48); - img_player_right=Draw_LoadImage("data/player_right.png"); - Draw_SetOffset(img_player_right,-16,-48); - - img_savepoint=Draw_LoadImage("data/save_point.png"); - Draw_SetOffset(img_savepoint,-16,-16); - - anim_savepoint_active=Anim_LoadAnim("data/save_point_active.png",32,2,5); - Anim_SetOffset(anim_savepoint_active,-16,-16); - - anim_exitpoint=Anim_LoadAnim("data/exit_point.png",32,2,10); - Anim_SetOffset(anim_exitpoint,-16,-48); - - img_endpoint=Draw_LoadImage("data/end_point.png"); - Draw_SetOffset(img_endpoint,-16,-32); - - img_arrowshooter_up=Draw_LoadImage("data/arrowshooter_up.png"); - Draw_SetOffset(img_arrowshooter_up,-16,-16); - img_arrowshooter_down=Draw_LoadImage("data/arrowshooter_down.png"); - Draw_SetOffset(img_arrowshooter_down,-16,-16); - img_arrowshooter_left=Draw_LoadImage("data/arrowshooter_left.png"); - Draw_SetOffset(img_arrowshooter_left,-16,-16); - img_arrowshooter_right=Draw_LoadImage("data/arrowshooter_right.png"); - Draw_SetOffset(img_arrowshooter_right,-16,-16); - - img_arrow_up=Draw_LoadImage("data/arrow_up.png"); - Draw_SetOffset(img_arrow_up,-16,-16); - img_arrow_down=Draw_LoadImage("data/arrow_down.png"); - Draw_SetOffset(img_arrow_down,-16,-16); - img_arrow_left=Draw_LoadImage("data/arrow_left.png"); - Draw_SetOffset(img_arrow_left,-16,-16); - img_arrow_right=Draw_LoadImage("data/arrow_right.png"); - Draw_SetOffset(img_arrow_right,-16,-16); - - anim_fire=Anim_LoadAnim("data/fire.png",32,3,5); - Anim_SetOffset(anim_fire,-16,-48); - - img_player_broken=Draw_LoadImage("data/player_broken.png"); - Draw_SetOffset(img_player_broken,-16,-48); + ///////////////////////////// + // Load and initialize media. + // - snd_arrowhit=Audio_LoadSound("data/Hit_Hurt10.wav"); - snd_exitpoint=Audio_LoadSound("data/Powerup10.wav"); - snd_savepoint=Audio_LoadSound("data/Powerup30.wav"); - snd_shootarrow=Audio_LoadSound("data/Laser_Shoot2.wav"); - snd_burn=Audio_LoadSound("data/Explosion2.wav"); - snd_fillhole=Audio_LoadSound("data/Hit_Hurt16.wav"); - snd_drag=Audio_LoadSound("data/Explosion16.wav"); + img_player=Draw_LoadImage("data/player.bmp"); + img_platform=Draw_LoadImage("data/platform.bmp"); + img_block=Draw_LoadImage("data/block.bmp"); + + // Wizard + img_wizard[0]=Draw_LoadImage("data/wizard_left.bmp"); + img_wizard[1]=Draw_LoadImage("data/wizard_right.bmp"); + + // Magik Ball + img_magikball=Draw_LoadImage("data/magikball.bmp"); + + // Load the earth images + img_earth[ 0]=Draw_LoadImage("data/earth/0.bmp"); + img_earth[ 1]=Draw_LoadImage("data/earth/1.bmp"); + img_earth[ 2]=Draw_LoadImage("data/earth/2.bmp"); + img_earth[ 3]=Draw_LoadImage("data/earth/3.bmp"); + img_earth[ 4]=Draw_LoadImage("data/earth/4.bmp"); + img_earth[ 5]=Draw_LoadImage("data/earth/5.bmp"); + img_earth[ 6]=Draw_LoadImage("data/earth/6.bmp"); + img_earth[ 7]=Draw_LoadImage("data/earth/7.bmp"); + img_earth[ 8]=Draw_LoadImage("data/earth/8.bmp"); + img_earth[ 9]=Draw_LoadImage("data/earth/9.bmp"); + img_earth[10]=Draw_LoadImage("data/earth/A.bmp"); + img_earth[11]=Draw_LoadImage("data/earth/B.bmp"); + img_earth[12]=Draw_LoadImage("data/earth/C.bmp"); + img_earth[13]=Draw_LoadImage("data/earth/D.bmp"); + img_earth[14]=Draw_LoadImage("data/earth/E.bmp"); + img_earth[15]=Draw_LoadImage("data/earth/F.bmp"); + + // FIXME: Earth back + + // Stone Brick + img_stoneBrick=Draw_LoadImage("data/rock.bmp"); + + // FIXME: Stone Brick back + + // Spiked Bush + img_spikedBush=Draw_LoadImage("data/spikedbush.bmp"); + + // FIXME: Lava Pit + + // FIXME: Fireball + + // Flower + img_flower[0]=Draw_LoadImage("data/flower_left.bmp"); + img_flower[1]=Draw_LoadImage("data/flower_right.bmp"); + + // Spike + img_spike[0]=Draw_LoadImage("data/spike_left.bmp"); + img_spike[1]=Draw_LoadImage("data/spike_right.bmp"); + + // Carnivore Plant + img_carnivorePlant[0]=Draw_LoadImage("data/carnivoreplant_left.bmp"); + img_carnivorePlant[1]=Draw_LoadImage("data/carnivoreplant_right.bmp"); + + // Bunny + img_bunny[0]=Draw_LoadImage("data/bunny_left.bmp"); + img_bunny[1]=Draw_LoadImage("data/bunny_right.bmp"); + + // Spider + img_spider[0]=Draw_LoadImage("data/spider_left.bmp"); + img_spider[1]=Draw_LoadImage("data/spider_right.bmp"); + + // FIXME: Guard + + // FIXME: Elite Guard + + // FIXEM: Axe + + // FIXME: GoatMan + + // FIXME: Princess + + + ///////////////////////// + // Initialize entity types. + // + + ent_Player=Entity_New(); + ent_Player->type=Ent_Player; + //ent_Player->flags=EntityFlag_Light; + //Entity_SetLight(ent_Player,.2,.2,.2,200); + ent_Player->flags=EntityFlag_Collision|EntityFlag_Overlap; + ent_Player->zorder=0; + AnimPlay_SetImg(&ent_Player->anim,img_player); + ent_Player->proc=player_proc; + ent_Player->mass=1.0f; + ent_Player->radius=12; + ent_Player->width=24; + ent_Player->height=24; + ent_Player->fric_static=0.0f; + ent_Player->fric_dynamic=0.2f; + + ent_Platform=Entity_New(); + ent_Platform->type=Ent_Platform; + ent_Platform->flags=EntityFlag_PlatformCollision; + ent_Platform->zorder=-1; + AnimPlay_SetImg(&ent_Platform->anim,img_platform); + ent_Platform->mass=0.0f; + ent_Platform->radius=12; + ent_Platform->width=64; + ent_Platform->height=16; + ent_Platform->fric_static=0.0f; + ent_Platform->fric_dynamic=0.2f; + + ent_Block=Entity_New(); + ent_Block->type=Ent_Block; + ent_Block->flags=EntityFlag_BlockCollision; + ent_Block->zorder=-1; + AnimPlay_SetImg(&ent_Block->anim,img_block); + ent_Block->mass=0.0f; + ent_Block->radius=32; + ent_Block->width=64; + ent_Block->height=64; + ent_Block->fric_static=0.0f; + ent_Block->fric_dynamic=0.2f; + // Magik Ball + ent_MagikBall=Entity_New(); + ent_MagikBall->type=Ent_Spike; + ent_MagikBall->flags=EntityFlag_Collision; + ent_MagikBall->zorder=0; + AnimPlay_SetImg(&ent_MagikBall->anim,img_magikball); + ent_MagikBall->mass=1.0f; + ent_MagikBall->radius=5; + ent_MagikBall->width=10; + ent_MagikBall->height=10; + ent_MagikBall->collision=magikball_collision; - - /////////////////////////////////////// - // Create the entity templates - - ent=Entity_New(); - ent->mass=-1.0f; - ent->flags=0; - //Entity_SetLight(ent,0.2f,0.2f,0.2f,1.0f); - Entity_SetLight(ent,0,0,0,1); - - - ent_player=Entity_Copy(ent); - ent_player->type=Ent_Player; - ent_player->radius=16.0f; - ent_player->width=24; - ent_player->height=24; - ent_player->mass=30.0f; - ent_player->backFric_static=2.5f; - ent_player->backFric_dynamic=0.3f; - ent_player->flags= - EntityFlag_Collision|EntityFlag_Overlap|EntityFlag_Light; - Entity_SetLight(ent_player,0.4f,0.4f,0.4f,3*32.0f); - AnimPlay_SetImg(&ent_player->anim,img_player_down); - ent_player->proc=player_proc; - ent_player->collision=player_collision; - - - ent_barrel=Entity_Copy(ent); - ent_barrel->type=Ent_Barrel; - ent_barrel->flags= - EntityFlag_Collision|EntityFlag_Overlap; - ent_barrel->radius=16.0f; - ent_barrel->width=24; - ent_barrel->height=24; - ent_barrel->mass=25.0f; - ent_barrel->backFric_static=2.0f; - ent_barrel->backFric_dynamic=0.5f; - ent_barrel->proc=barrel_proc; - AnimPlay_SetImg(&ent_barrel->anim,img_barrel); - - - ent_column=Entity_Copy(ent); - ent_column->type=Ent_Column; - //ent_column->flags=EntityFlag_BlockCollision; - ent_column->flags=EntityFlag_Collision; - ent_column->radius=12; - ent_column->width=24; - ent_column->height=24; - AnimPlay_SetImg(&ent_column->anim,img_column); - ent_column_faded=Entity_Copy(ent_column); - AnimPlay_SetImg(&ent_column_faded->anim,img_column_faded); - ent_rock=Entity_Copy(ent_column); - AnimPlay_SetImg(&ent_rock->anim,img_rock); - ent_rock->flags=EntityFlag_Collision; - ent_lamp=Entity_Copy(ent_rock); - AnimPlay_SetImg(&ent_lamp->anim,img_lamp); - ent_lamp->flags= - EntityFlag_Collision|EntityFlag_Light; - Entity_SetLight(ent_lamp,0.4f,0.4f,0.4f,5*32.0f); - - - - ent_floor=Entity_Copy(ent); - ent_floor->type=Ent_Floor; - ent_floor->zorder=-1; - ent_floor->flags=0; - AnimPlay_SetImg(&ent_floor->anim,img_floor); - ent_floor_left=Entity_Copy(ent_floor); - AnimPlay_SetImg(&ent_floor_left->anim,img_floor_left); - ent_floor_right=Entity_Copy(ent_floor); - AnimPlay_SetImg(&ent_floor_right->anim,img_floor_right); - ent_floor_center=Entity_Copy(ent_floor); - AnimPlay_SetImg(&ent_floor_center->anim,img_floor_center); - - ent_hole_spiked=Entity_Copy(ent); - ent_hole_spiked->type=Ent_Hole_Spiked; - ent_hole_spiked->zorder=-1; - ent_hole_spiked->flags=EntityFlag_Overlap; - ent_hole_spiked->radius=18; - AnimPlay_SetImg(&ent_hole_spiked->anim,img_hole_spiked); - ent_hole_spiked->overlap=hole_spiked_overlap; - - ent_hole_filled=Entity_Copy(ent); - ent_hole_filled->type=Ent_Hole_Filled; - ent_hole_filled->zorder=-1; - ent_hole_filled->flags=0; - AnimPlay_SetImg(&ent_hole_filled->anim,img_barrel2); - - ent_hole_lava=Entity_Copy(ent); - ent_hole_lava->type=Ent_Hole_Lava; - ent_hole_lava->zorder=-1; - ent_hole_lava->flags=EntityFlag_Overlap|EntityFlag_Light; - ent_hole_lava->radius=18; - AnimPlay_SetAnim(&ent_hole_lava->anim,anim_hole_lava); - Entity_SetLight(ent_hole_lava,1.0f,0.0f,0.0f,4*32.0f); - ent_hole_lava->oncopy=hole_lava_oncopy; - ent_hole_lava->overlap=hole_lava_overlap; - - - ent_arrow_up=Entity_Copy(ent); - ent_arrow_up->type=Ent_Arrow; - //ent_arrow_up->flags=EntityFlag_Collision; - ent_arrow_up->flags=EntityFlag_Collision|EntityFlag_Light; - Entity_SetLight(ent_arrow_up,0.2f,0.2f,0.2f,2*32.0f); - ent_arrow_up->radius=4; - ent_arrow_up->mass=0.1f; - ent_arrow_up->collision=arrow_collision; - ent_arrow_up->proc=timeoutent_proc; - ent_arrow_up->A=120; - AnimPlay_SetImg(&ent_arrow_up->anim,img_arrow_up); - vec2_set(ent_arrow_up->vel,0,-16); - ent_arrow_down=Entity_Copy(ent_arrow_up); - AnimPlay_SetImg(&ent_arrow_down->anim,img_arrow_down); - vec2_set(ent_arrow_down->vel,0,16); - ent_arrow_left=Entity_Copy(ent_arrow_up); - AnimPlay_SetImg(&ent_arrow_left->anim,img_arrow_left); - vec2_set(ent_arrow_left->vel,-16,0); - ent_arrow_right=Entity_Copy(ent_arrow_up); - AnimPlay_SetImg(&ent_arrow_right->anim,img_arrow_right); - vec2_set(ent_arrow_right->vel,16,0); - - - ent_arrowshooter_up=Entity_Copy(ent); - ent_arrowshooter_up->type=Ent_ArrowShooter; - ent_arrowshooter_up->flags=EntityFlag_Collision; - ent_arrowshooter_up->radius=15; - ent_arrowshooter_up->oncopy=arrowshooter_oncopy; - ent_arrowshooter_up->proc=arrowshooter_proc; - AnimPlay_SetImg(&ent_arrowshooter_up->anim,img_arrowshooter_up); - ent_arrowshooter_up->child=ent_arrow_up; - ent_arrowshooter_down=Entity_Copy(ent_arrowshooter_up); - AnimPlay_SetImg(&ent_arrowshooter_down->anim,img_arrowshooter_down); - ent_arrowshooter_down->child=ent_arrow_down; - ent_arrowshooter_left=Entity_Copy(ent_arrowshooter_up); - AnimPlay_SetImg(&ent_arrowshooter_left->anim,img_arrowshooter_left); - ent_arrowshooter_left->child=ent_arrow_left; - ent_arrowshooter_right=Entity_Copy(ent_arrowshooter_up); - AnimPlay_SetImg(&ent_arrowshooter_right->anim,img_arrowshooter_right); - ent_arrowshooter_right->child=ent_arrow_right; - - - ent_savepoint=Entity_Copy(ent); - ent_savepoint->type=Ent_SavePoint; - ent_savepoint->sortYOffset=-5; - ent_savepoint->flags=EntityFlag_Overlap|EntityFlag_Light; - ent_savepoint->radius=20; - Entity_SetLight(ent_savepoint,0.0f,0.0f,0.5f,2*32.0f); - AnimPlay_SetImg(&ent_savepoint->anim,img_savepoint); - ent_savepoint->overlap=savepoint_overlap; - ent_savepoint->ondelete=savepoint_ondelete; - - - ent_exitpoint=Entity_Copy(ent); - ent_exitpoint->type=Ent_ExitPoint; - ent_exitpoint->flags=EntityFlag_Overlap|EntityFlag_Light; - Entity_SetLight(ent_exitpoint,0.5f,0.5f,0.5f,5*32.0f); - ent_exitpoint->radius=20; - AnimPlay_SetAnim(&ent_exitpoint->anim,anim_exitpoint); - ent_exitpoint->overlap=exitpoint_overlap; - ent_endpoint=Entity_Copy(ent_exitpoint); - AnimPlay_SetImg(&ent_endpoint->anim,img_endpoint); - ent_endpoint->overlap=endpoint_overlap; - - ent_teleporter=Entity_Copy(ent); - ent_teleporter->zorder=0; - ent_teleporter->type=Ent_Teleporter; - ent_teleporter->flags=EntityFlag_Overlap|EntityFlag_Light; - Entity_SetLight(ent_teleporter,0.5f,0.5f,0.5f,5*32.0f); - ent_teleporter->radius=20; - AnimPlay_SetImg(&ent_teleporter->anim,img_savepoint); - ent_teleporter->overlap=teleporter_overlap; - - ent_teleporter_dest=Entity_Copy(ent); - ent_teleporter_dest->zorder=0; - ent_teleporter_dest->type=Ent_Teleporter_Dest; - ent_teleporter_dest->flags=0; - AnimPlay_SetImg(&ent_teleporter_dest->anim,img_savepoint); + // Wizard + ent_Wizard=Entity_New(); + ent_Wizard->type=Ent_Wizard; + ent_Wizard->flags=EntityFlag_Collision|EntityFlag_Overlap; + ent_Wizard->zorder=0; + AnimPlay_SetImg(&ent_Wizard->anim,img_wizard[0]); + ent_Wizard->proc=wizard_proc; + ent_Wizard->mass=1.0f; + ent_Wizard->radius=24; + ent_Wizard->width=24; + ent_Wizard->height=58; + ent_Wizard->fric_static=0.0f; + ent_Wizard->fric_dynamic=0.2f; + ent_Wizard->child=ent_MagikBall; + // Earth + ent_Earth=Entity_New(); + ent_Earth->type=Ent_Earth; + ent_Earth->flags=EntityFlag_BlockCollision; + ent_Earth->zorder=-2; + AnimPlay_SetImg(&ent_Earth->anim,img_earth[0]); + ent_Earth->mass=0.0f; + ent_Earth->radius=16; + ent_Earth->width=32; + ent_Earth->height=32; + ent_Earth->fric_static=0.0f; + ent_Earth->fric_dynamic=0.2f; - ent_fire=Entity_Copy(ent); - ent_fire->type=Ent_Effect; - ent_fire->flags=EntityFlag_Light; - Entity_SetLight(ent_fire,1.0f,0.0f,0.0f,3*32.0f); - AnimPlay_SetAnim(&ent_fire->anim,anim_fire); - ent_fire->proc=timeoutent_proc; - ent_fire->A=15; - ent_fire->sortYOffset=1; - ent_player_broken=Entity_Copy(ent); - ent_player_broken->type=Ent_Effect; - ent_player_broken->flags=0; - AnimPlay_SetImg(&ent_player_broken->anim,img_player_broken); + // FIXME: Earth back + + // Stone Bricks + ent_StoneBrick=Entity_New(); + ent_StoneBrick->type=Ent_StoneBrick; + ent_StoneBrick->flags=EntityFlag_BlockCollision; + ent_StoneBrick->zorder=-2; + AnimPlay_SetImg(&ent_StoneBrick->anim,img_stoneBrick); + ent_StoneBrick->mass=0.0f; + ent_StoneBrick->radius=16; + ent_StoneBrick->width=32; + ent_StoneBrick->height=32; + ent_StoneBrick->fric_static=0.0f; + ent_StoneBrick->fric_dynamic=0.2f; + + // FIXME: Stone Bricks back + + // Spiked Bush + ent_SpikedBush=Entity_New(); + ent_SpikedBush->type=Ent_SpikedBush; + ent_SpikedBush->flags=EntityFlag_Overlap; + vec2_set(ent_SpikedBush->pos,0,8); + ent_SpikedBush->zorder=1; + AnimPlay_SetImg(&ent_SpikedBush->anim,img_spikedBush); + ent_SpikedBush->mass=0.0f; + ent_SpikedBush->radius=24; + ent_SpikedBush->overlap=spikedentity_overlap; + + // FIXME: Fireball + + + // FIXME: Lava Pit + + + // Spikes + ent_Spike[0]=Entity_New(); + ent_Spike[0]->type=Ent_Spike; + ent_Spike[0]->flags=EntityFlag_Collision; + ent_Spike[0]->zorder=0; + AnimPlay_SetImg(&ent_Spike[0]->anim,img_spike[0]); + vec2_set(ent_Spike[0]->pos,0,-16); + ent_Spike[0]->mass=1.0f; + ent_Spike[0]->radius=5; + ent_Spike[0]->width=10; + ent_Spike[0]->height=10; + ent_Spike[0]->collision=spike_collision; + vec2_set(ent_Spike[0]->vel,-3,2); + ent_Spike[1]=Entity_Copy(ent_Spike[0]); + AnimPlay_SetImg(&ent_Spike[1]->anim,img_spike[1]); + vec2_set(ent_Spike[1]->vel,3,2); + + + // Flower + ent_Flower[0]=Entity_New(); + ent_Flower[0]->type=Ent_Flower; + ent_Flower[0]->flags=EntityFlag_Collision|EntityFlag_Overlap; + ent_Flower[0]->zorder=1; + AnimPlay_SetImg(&ent_Flower[0]->anim,img_flower[0]); + ent_Flower[0]->mass=0.0f; + ent_Flower[0]->radius=16; + ent_Flower[0]->overlap=spikedentity_overlap; + ent_Flower[0]->oncopy=flower_oncopy; + ent_Flower[0]->proc=flower_proc; + ent_Flower[0]->B=60; + ent_Flower[0]->C=60; + ent_Flower[0]->child=ent_Spike[0]; + ent_Flower[0]->D=0; + ent_Flower[1]=Entity_Copy(ent_Flower[0]); + AnimPlay_SetImg(&ent_Flower[1]->anim,img_flower[1]); + ent_Flower[1]->child=ent_Spike[1]; + ent_Flower[1]->D=1; + + + // Carnivore Plant + ent_CarnivorePlant[0]=Entity_New(); + ent_CarnivorePlant[0]->type=Ent_CarnivorePlant; + ent_CarnivorePlant[0]->flags=0; + ent_CarnivorePlant[0]->zorder=1; + AnimPlay_SetImg(&ent_CarnivorePlant[0]->anim,img_carnivorePlant[0]); + ent_CarnivorePlant[0]->mass=0.0f; + ent_CarnivorePlant[0]->radius=16; + ent_CarnivorePlant[0]->child=ent_Spike[0]; + ent_CarnivorePlant[1]=Entity_Copy(ent_CarnivorePlant[0]); + AnimPlay_SetImg(&ent_CarnivorePlant[1]->anim,img_carnivorePlant[1]); + + + // Bunny + ent_Bunny=Entity_New(); + ent_Bunny->type=Ent_Bunny; + ent_Bunny->flags=EntityFlag_Collision; + ent_Bunny->zorder=0; + AnimPlay_SetImg(&ent_Bunny->anim,img_bunny[0]); + ent_Bunny->proc=bunny_proc; + ent_Bunny->collision=bunny_collision; + ent_Bunny->mass=1.0f; + ent_Bunny->radius=12; + ent_Bunny->width=24; + ent_Bunny->height=24; + ent_Bunny->fric_static=0.0f; + ent_Bunny->fric_dynamic=0.2f; + ent_Bunny->A=0; + ent_Bunny->B=0; + ent_Bunny->C=60; + + + // Spider + ent_Spider=Entity_New(); + ent_Spider->type=Ent_Spider; + ent_Spider->flags=EntityFlag_Collision; + ent_Spider->zorder=0; + AnimPlay_SetImg(&ent_Spider->anim,img_spider[0]); + ent_Spider->proc=spider_proc; + ent_Spider->collision=spider_collision; + ent_Spider->mass=1.0f; + ent_Spider->radius=12; + ent_Spider->width=24; + ent_Spider->height=24; + ent_Spider->fric_static=0.0f; + ent_Spider->fric_dynamic=0.2f; + ent_Spider->A=0; + ent_Spider->B=0; + ent_Spider->C=60; + + // FIXME: Guard + + // FIXME: Elite Guard + + // FIXEM: Axe + + // FIXME: GoatMan + + // FIXME: Princess + } - diff --git a/GameEnts.h b/GameEnts.h index 6f915fd..7f9b49e 100644 --- a/GameEnts.h +++ b/GameEnts.h @@ -1,51 +1,70 @@ -// Copyright (C) 2011 Valeriano Alfonso Rodriguez (Kableado) +// Copyright (C) 2012 Valeriano Alfonso Rodriguez (Kableado) #ifndef _GAMEENTS_H_ #define _GAMEENTS_H_ -void GameEnts_Init(); + enum { Ent_Player, - Ent_Barrel, - Ent_Column, - Ent_Floor, - Ent_Hole_Spiked, - Ent_Hole_Filled, - Ent_Hole_Lava, - Ent_ArrowShooter, - Ent_Arrow, - Ent_SavePoint, - Ent_ExitPoint, - Ent_Teleporter, - Ent_Teleporter_Dest, - Ent_Effect -} EntityType; -extern Entity ent_player; -extern Entity ent_barrel; -extern Entity ent_column; -extern Entity ent_column_faded; -extern Entity ent_rock; -extern Entity ent_lamp; -extern Entity ent_floor; -extern Entity ent_floor_right; -extern Entity ent_floor_left; -extern Entity ent_floor_center; -extern Entity ent_hole_spiked; -extern Entity ent_hole_filled; -extern Entity ent_hole_lava; -extern Entity ent_arrowshooter_up; -extern Entity ent_arrowshooter_down; -extern Entity ent_arrowshooter_left; -extern Entity ent_arrowshooter_right; -extern Entity ent_arrow_up; -extern Entity ent_arrow_down; -extern Entity ent_arrow_left; -extern Entity ent_arrow_right; -extern Entity ent_exitpoint; -extern Entity ent_endpoint; -extern Entity ent_savepoint; -extern Entity ent_teleporter; -extern Entity ent_teleporter_dest; + Ent_Platform, + Ent_Block, -#endif + Ent_Wizard, + Ent_MagikBall, + Ent_Earth, + Ent_EarthBack, + Ent_StoneBrick, + Ent_StoneBrickBack, + Ent_SpikedBush, + Ent_LavaPit, + Ent_Fireball, + Ent_Flower, + Ent_Spike, + Ent_CarnivorePlant, + Ent_Bunny, + Ent_Spider, + Ent_Guard, + Ent_EliteGuard, + Ent_Axe, + Ent_GoatMan, + Ent_Princess +} EntityType; + +extern Entity *ent_Player; +extern Entity *ent_Platform; +extern Entity *ent_Block; + +extern Entity *ent_Wizard; +extern Entity *ent_MagikBall; +extern Entity *ent_Earth; +extern Entity *ent_EarthBack; +extern Entity *ent_StoneBrick; +extern Entity *ent_StoneBrickBack; +extern Entity *ent_SpikedBush; +extern Entity *ent_LavaPit; +extern Entity *ent_Fireball; +extern Entity *ent_Spike[2]; +extern Entity *ent_Flower[2]; +extern Entity *ent_CarnivorePlant[2]; +extern Entity *ent_Bunny; +extern Entity *ent_Spider; +extern Entity *ent_Axe; +extern Entity *ent_Guard; +extern Entity *ent_EliteGuard; +extern Entity *ent_GoatMan; +extern Entity *ent_Princess; + + +int EntityApplyGravity(Entity *e); + +void EntEarth_Init(Entity *ent,int up,int down,int left,int right); + +void EntStoneBrick_Init(Entity *ent,int up,int down,int left,int right); + + +void GameEnts_Init(); + + + +#endif _GAMEENTS_H_ diff --git a/GameLib/Anim.c b/GameLib/Anim.c index f0a73e8..7b6b020 100644 --- a/GameLib/Anim.c +++ b/GameLib/Anim.c @@ -25,7 +25,7 @@ typedef struct { // Anim_LoadAnim // // -Anim Anim_LoadAnim(char *fichero,int width,int frames,float fps){ +Anim Anim_LoadAnim(char *fichero,int frames,float fps){ DrawImg img; Animation *anim; int w,h; @@ -39,10 +39,7 @@ Anim Anim_LoadAnim(char *fichero,int width,int frames,float fps){ // Create the animation container anim=malloc(sizeof(Animation)); anim->img=img; - anim->w=width; - if(width<=0){ - anim->w=w/frames; - } + anim->w=w/frames; anim->fps=fps; anim->frames=frames; anim->ftime=1000/fps; @@ -101,7 +98,7 @@ void Anim_Draw(Anim a,int time_ms,int x,int y){ Animation *anim=a; int frame; - frame=(time_ms/anim->ftime)%anim->frames; + frame=(time_ms%anim->time)/anim->ftime; Draw_DrawImgPart(anim->img,x,y,anim->w,frame); } diff --git a/GameLib/Anim.h b/GameLib/Anim.h index 4d873a0..862fa83 100644 --- a/GameLib/Anim.h +++ b/GameLib/Anim.h @@ -17,7 +17,7 @@ typedef void *Anim; // Anim_LoadAnim // // -Anim Anim_LoadAnim(char *fichero,int width,int frames,float fps); +Anim Anim_LoadAnim(char *fichero,int frames,float fps); ///////////////////////////// diff --git a/GameLib/Audio.c b/GameLib/Audio.c index 4506b83..abacb5d 100644 --- a/GameLib/Audio.c +++ b/GameLib/Audio.c @@ -4,9 +4,6 @@ #define _WIN32_WINNT 0x0501 #include #endif -#include -#include -#include #include #include "Audio.h" @@ -18,35 +15,30 @@ static void Audio_MixerCallback(void *ud,Uint8 *stream,int l); // AudioWave // /////////////// // Reference to a sound. -typedef struct TAudioWave TAudioWave, *AudioWave; -struct TAudioWave { - unsigned int sampleRate; - int channels; - int bpb; - int BPB; +typedef struct Tag_AudioWave { + SDL_AudioSpec spec; Uint32 len; Uint8 *buffer; - AudioWave next; -}; -AudioWave _waves=NULL; + struct Tag_AudioWave *next; +} AudioWave; +AudioWave *_waves=NULL; //////////////////////////////////////////////// // AudioChan // /////////////// // Reference to a sound. -typedef struct TAudioChan TAudioChan, *AudioChan; -struct TAudioChan { - AudioWave wave; +typedef struct Tag_AudioChan { + AudioWave *wave; Uint32 pos; unsigned char rightvol; unsigned char leftvol; - AudioChan next; -}; -AudioChan _channels=NULL; -AudioChan _free_channels=NULL; + struct Tag_AudioChan *next; +} AudioChan; +AudioChan *_channels=NULL; +AudioChan *_free_channels=NULL; ///////////////////////////// // Audio_Init @@ -63,7 +55,7 @@ int Audio_Init(){ #endif if(SDL_InitSubSystem(SDL_INIT_AUDIO) < 0){ printf("Audio_Init: Failure initializing SDL Audio.\n"); - printf("\tSDL Error: %s\n",SDL_GetError()); + printf("Audio_Init: SDL Error: %s\n",SDL_GetError()); return(0); } @@ -71,11 +63,11 @@ int Audio_Init(){ as.freq = 44100; as.format = AUDIO_S16SYS; as.channels = 2; - as.samples = 2048; + as.samples = 1024; as.callback = Audio_MixerCallback; if(SDL_OpenAudio(&as, &as2) < 0){ printf("Audio_Init: Failure opening audio.\n"); - printf("\tSDL Error: %s\n",SDL_GetError()); + printf("Audio_Init: SDL Error: %s\n",SDL_GetError()); return(0); } @@ -102,16 +94,16 @@ int Audio_Init(){ // Mixes the audio channels. static void Audio_MixerCallback(void *ud,Uint8 *stream,int l){ signed short *ptr_out,*ptr_wave; - AudioChan prevchan; - AudioChan chan; - AudioWave wave; + AudioChan *prevchan; + AudioChan *chan; + AudioWave *wave; int len=l/4; // Asume 16bpb and 2 output chan int chan_remain; int len_mix; int i; // Clean - memset(stream,0,l); + memset(stream,0,len); // Mix all the channels prevchan=NULL; @@ -119,7 +111,7 @@ static void Audio_MixerCallback(void *ud,Uint8 *stream,int l){ while(chan){ if(!chan->wave){ // Remove finished channels - AudioChan aux_chan=chan->next; + AudioChan *aux_chan=chan->next; chan->next=_free_channels; _free_channels=chan; chan=aux_chan; @@ -198,105 +190,38 @@ void Audio_Frame(){ // // Loads a sound, giving a reference. AudioSnd Audio_LoadSound(char *filename){ - int error = 0; - FILE *f; - char id[5] = { 0, 0, 0, 0, 0 }, *sndBuffer = NULL; - short formatTag, channels, bitsPerSample; - int formatLen, sampleRate, dataSize; + AudioWave *wave; - f = fopen(filename, "rb"); - if (!f) { - printf("Audio_LoadSound: Failure opening file.\n"); + // Allocate and load the sound + wave=malloc(sizeof(AudioWave)); + if( SDL_LoadWAV(filename, + &wave->spec, &wave->buffer, &wave->len) == NULL ) + { + printf("Audio_LoadSound: Failure Loading sound: %s\n",filename); + printf("Audio_LoadSound: SDL Error: %s\n",SDL_GetError()); + free(wave); return(NULL); } - // Read id "RIFF" - fread(id, 4, sizeof(char), f); - if (strcmp(id, "RIFF")) { - printf("Audio_LoadSound: File is not RIFF.\n"); - fclose(f); - return(NULL); + // Asert results + if( wave->spec.format != AUDIO_S16 || + wave->spec.freq != 44100 || + wave->spec.channels != 1 ) + { + printf("Audio_LoadSound: Failure opening sound. (44.1Khz/16b/1c).\n"); + SDL_FreeWAV(wave->buffer); + free(wave); + return(0); } - // File size (-"RIFF") - fseek(f, 4, SEEK_CUR); // size - - // Read id "WAVE" - fread(id, 4, sizeof(char), f); - if (strcmp(id, "WAVE")) { - printf("Audio_LoadSound: File is not WAVE.\n"); - fclose(f); - return(NULL); - } - - // Read the format - fread(id, 1, sizeof(char) * 4, f); // Read "fmt " - fread(&formatLen, 1, sizeof(int), f); - if (formatLen < 14) { - printf("Audio_LoadSound: File too short.\n"); - fclose(f); - return (NULL ); - } - fread(&formatTag, 1, sizeof(short), f); // 1=PCM - if (formatTag != 1) { - printf("Audio_LoadSound: Not PCM format.\n"); - fclose(f); - return (NULL ); - } - fread(&channels, 1, sizeof(short), f); - fread(&sampleRate, 1, sizeof(int), f); - fseek(f, 2, SEEK_CUR); // avgBytesSec - fseek(f, 2, SEEK_CUR); // blockAlign - fread(&bitsPerSample, 1, sizeof(short), f); - fseek(f, formatLen - 14, SEEK_CUR); // Align read - - // Assert sound format - if (sampleRate!=44100 || channels!=1 || bitsPerSample!=2) { - printf("Audio_LoadSound: Format not supported: " - "sampleRate:%d; channels:%d; BPB:%d\n", - sampleRate, channels, bitsPerSample); - fclose(f); - return(NULL); - } - - // Skip no "data" blocks - do{ - int lenRead=fread(id, 1, sizeof(char) * 4, f); - if(lenRead<4){ break; } - if (strcmp(id, "data")) { - fread(&dataSize, 1, sizeof(int), f); - fseek(f, dataSize, SEEK_CUR); - }else{ - break; - } - }while(1); - if (strcmp(id, "data")) { - printf("Audio_LoadSound: DATA block not found\n"); - fclose(f); - return (NULL ); - } - - // Read the "data" block - fread(&dataSize, 1, sizeof(int), f); - sndBuffer = malloc(sizeof(char)*dataSize); - fread(sndBuffer, dataSize, sizeof(char), f); - - fclose(f); - - // Build the wave object - AudioWave wave = malloc(sizeof(TAudioWave)); - wave->sampleRate = sampleRate; - wave->channels = channels; - wave->buffer = (Uint8 *) sndBuffer; - wave->BPB = bitsPerSample; - wave->bpb = wave->bpb * 8; - wave->len = dataSize / (wave->BPB * wave->channels); + // Correct the lenght + wave->len/=2; // Take a reference wave->next=_waves; _waves=wave; - return (wave); + return((AudioSnd)wave); } @@ -307,8 +232,8 @@ AudioSnd Audio_LoadSound(char *filename){ void Audio_PlaySound(AudioSnd snd, float leftvol, float rightvol) { - AudioChan chan; - AudioWave wave; + AudioChan *chan; + AudioWave *wave; if(!snd) return; @@ -321,7 +246,7 @@ void Audio_PlaySound(AudioSnd snd, _free_channels=chan->next; chan->next=NULL; }else{ - chan=malloc(sizeof(TAudioChan)); + chan=malloc(sizeof(AudioChan)); chan->next=NULL; } diff --git a/GameLib/Draw.c b/GameLib/Draw.c index d523b4c..fddf608 100644 --- a/GameLib/Draw.c +++ b/GameLib/Draw.c @@ -2,57 +2,31 @@ #include #include -#include #include #ifdef WIN32 - // Windows #define _WIN32_WINNT 0x0501 #include #include #include - #define USE_OpenGL 1 - #define USE_OpenGLES 0 #else -#ifdef EMSCRIPTEN - // Emscripten - #include - #define GL_GLEXT_PROTOTYPES 1 - #include - #include - #define USE_OpenGL 0 - #define USE_OpenGLES 1 - #define SDL_GetKeyState SDL_GetKeyboardState +#ifdef MACOSX + #include + #include + #include + #include + #include #else - // UNIX #include - #define USE_OpenGL 1 - #define USE_OpenGLES 0 #endif #endif -#include "lodepng.c" #include #include "Time.h" #include "Util.h" -#include "QuadArray2D.h" -#include "Audio.h" -#include "Input.h" #include "Draw.h" - - -//////////////////////////////////////////////// -// DrawImage // -/////////////// -// Image container. -typedef struct TDrawImage TDrawImage, *DrawImage; -struct TDrawImage { - unsigned char *data; - int x,y; - int w,h; - GLuint tex; -}; - +#include "Input.h" +#include "Audio.h" // Globals @@ -61,76 +35,6 @@ int _width; int _height; long long proc_t_frame=33333; long long draw_t_frame=16667; -int _fps=60; -QuadArray2D _quadArray=NULL; -DrawImage _currentImg=NULL; -float _color[4]; - -#if USE_OpenGLES - -GLuint Draw_CompileShader(GLenum type, const char *source){ - GLuint shader = glCreateShader(type); - if (shader == 0) { - return 0; - } - - //load the shader source to the shader object and compile it - glShaderSource(shader, 1, &source, NULL); - glCompileShader(shader); - - //check if the shader compiled successfully - GLint compiled; - glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); - if (!compiled) { - glDeleteShader(shader); - return 0; - } - - return shader; -} - - -GLuint Draw_BuildProgram( - const char *vertexShaderSource, - const char *fragmentShaderSource) -{ - // Compile shaders - GLuint vertexShader = Draw_CompileShader(GL_VERTEX_SHADER, vertexShaderSource); - GLuint fragmentShader = Draw_CompileShader(GL_FRAGMENT_SHADER, fragmentShaderSource); - if(vertexShader==0 || fragmentShader==0){ - return 0; - } - - //create a GL program and link it - GLuint programObject = glCreateProgram(); - glAttachShader(programObject, vertexShader); - glAttachShader(programObject, fragmentShader); - glLinkProgram(programObject); - - //check if the program linked successfully - GLint linked; - glGetProgramiv(programObject, GL_LINK_STATUS, &linked); - if (!linked) - { - glDeleteProgram(programObject); - return 0; - } - return programObject; -} - -GLuint vertPosLoc; -GLuint vertTexLoc; -GLuint vertColorLoc; - -GLuint textureLoc; -GLuint projectionMatrixLoc; - - -GLuint vertexObject; - -#define Max_Vertices 6000 - -#endif ///////////////////////////// // Draw_Init @@ -150,21 +54,14 @@ int Draw_Init(int width,int height,char *title,int pfps,int fps){ } #endif - // Set globals - proc_t_frame=1000000/pfps; - draw_t_frame=1000000/fps; - _fps=fps; - _width=width; - _height=height; - // Initialize SDL if(SDL_Init(SDL_INIT_VIDEO)<0){ printf("Draw_Init: Failure initializing SDL.\n"); - printf("\tSDL Error: %s\n",SDL_GetError()); + printf("Draw_Init: SDL Error: %s\n",SDL_GetError()); return(0); } -#if USE_OpenGL + // Prepare OpenGL inicialization SDL_GL_SetAttribute (SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 8); @@ -172,22 +69,26 @@ int Draw_Init(int width,int height,char *title,int pfps,int fps){ SDL_GL_SetAttribute (SDL_GL_ALPHA_SIZE, 8); SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute (SDL_GL_STENCIL_SIZE, 8); + SDL_GL_SetAttribute (SDL_GL_SWAP_CONTROL, 0); SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1); -#endif + // Initialize video mode _screen=SDL_SetVideoMode(width,height,32,SDL_HWSURFACE|SDL_OPENGL); if( _screen == NULL){ printf("Draw_Init: Failure initializing video mode.\n"); - printf("\tSDL Error: %s\n",SDL_GetError()); + printf("Draw_Init: SDL Error: %s\n",SDL_GetError()); return(0); } SDL_WM_SetCaption(title, NULL); + proc_t_frame=1000000/pfps; + draw_t_frame=1000000/fps; + _width=width; + _height=height; -#if USE_OpenGL // Set the desired state glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); - glDisable(GL_CULL_FACE); + glEnable(GL_CULL_FACE); glEnable(GL_TEXTURE_2D); glDisable(GL_LIGHTING); glDisable(GL_DEPTH_TEST); @@ -221,169 +122,87 @@ int Draw_Init(int width,int height,char *title,int pfps,int fps){ glMatrixMode (GL_MODELVIEW); glLoadIdentity (); - glEnableClientState(GL_COLOR_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_VERTEX_ARRAY); - -#else - - // Show device info - char *str; - printf("\n*********************************\n"); - printf("*** Draw Info\n"); - str=(char *)glGetString(GL_VENDOR); - printf(" Vendor: %s\n",str); - str=(char *)glGetString(GL_RENDERER); - printf(" Renderer: %s\n",str); - str=(char *)glGetString(GL_VERSION); - printf(" Version: %s\n",str); - printf("*********************************\n"); - - const char vertexShaderSource[] = - "attribute vec4 aPosition; \n" - "attribute vec2 aTexCoord; \n" - "attribute vec4 aColor; \n" - "varying vec2 vTexCoord; \n" - "varying vec4 vColor; \n" - "uniform mat4 sProjectionMatrix; \n" - "void main() { \n" - " gl_Position = aPosition * \n" - " sProjectionMatrix; \n" - " vTexCoord = aTexCoord; \n" - " vColor = aColor; \n" - "} \n"; - - const char fragmentShaderSource[] = - "precision mediump float; \n" - "varying vec2 vTexCoord; \n" - "varying vec4 vColor; \n" - "uniform sampler2D sTexture; \n" - "void main() { \n" - " gl_FragColor = texture2D(sTexture, vTexCoord)*vColor; \n" - "} \n"; - - GLuint programObject=Draw_BuildProgram( - vertexShaderSource, - fragmentShaderSource); - glUseProgram(programObject); - - vertPosLoc = glGetAttribLocation(programObject, "aPosition"); - vertTexLoc = glGetAttribLocation(programObject, "aTexCoord"); - vertColorLoc = glGetAttribLocation(programObject, "aColor"); - - textureLoc = glGetUniformLocation(programObject, "sTexture"); - projectionMatrixLoc = glGetUniformLocation(programObject, "sProjectionMatrix"); - - glGenBuffers(1, &vertexObject); - glBindBuffer(GL_ARRAY_BUFFER, vertexObject ); - glBufferData(GL_ARRAY_BUFFER, Vertex2D_Length*sizeof(float)*Max_Vertices, - NULL, GL_DYNAMIC_DRAW); - - glBindBuffer(GL_ARRAY_BUFFER, vertexObject ); - - glVertexAttribPointer(vertPosLoc, 2, GL_FLOAT,GL_FALSE, - Vertex2D_Length*sizeof(float), (void*)(0*sizeof(float))); - glVertexAttribPointer(vertTexLoc, 2, GL_FLOAT, GL_FALSE, - Vertex2D_Length*sizeof(float), (void*)(2*sizeof(float))); - glVertexAttribPointer(vertColorLoc, 4, GL_FLOAT, GL_FALSE, - Vertex2D_Length*sizeof(float), (void*)(4*sizeof(float))); - - glEnableVertexAttribArray(vertPosLoc); - glEnableVertexAttribArray(vertTexLoc); - glEnableVertexAttribArray(vertColorLoc); - - glUniform1i(textureLoc, 0); - - GLfloat projectionMatrix[16]={ - 2.0f/(float)_width, 0.0, 0.0, -1.0, - 0.0, 2.0/(float)_height, 0.0, -1.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0 - }; - glUniformMatrix4fv(projectionMatrixLoc, - 1, GL_FALSE, projectionMatrix); - -#endif - // Enable Alpha blending glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); - // Initialize the triangle array - _quadArray=QuadArray2D_Create(400); - - Draw_SetColor(1.0f,1.0f,1.0f,1.0f); - return(1); } - ///////////////////////////// -// Draw_UploadGLTexture +// Draw_Loop // -// Uploads a OpenGL texture. -GLuint Draw_UploadGLTexture(int w, int h, unsigned char *pixels){ - GLuint tex; +// Loops updating the game window. +void Draw_Loop(int (*proc)(),void (*draw)()){ + int done=0; + SDL_Event event; + Uint8* keys; + long long time,time2,timed; + long long t_frame=0; - // Generate OpenGL texture - glGenTextures(1, &tex); - glBindTexture(GL_TEXTURE_2D, tex); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + t_frame=proc_t_frame; + time=Time_GetTime(); + while(!done){ - // Load OpenGL texture - glBindTexture(GL_TEXTURE_2D, tex); -#if USE_OpenGL - glPixelStorei( GL_UNPACK_ROW_LENGTH, w ); -#endif - glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, - w, h, 0, - GL_RGBA, GL_UNSIGNED_BYTE, pixels); + // Update screen + SDL_GL_SwapBuffers(); - return(tex); -} + // Process Events + while(SDL_PollEvent(&event) ){ + if(event.type == SDL_QUIT ){ + done=1; + } + if(event.type == SDL_KEYDOWN ){ + if(event.key.keysym.sym == SDLK_ESCAPE ) { + done=1; + } + } + } + + // Process keys for Draw + keys=SDL_GetKeyState(NULL); + if(keys[SDLK_F12]){ + // Screenshot key + Draw_SaveScreenshoot("shot.bmp"); + } + + // Sound Frame + Audio_Frame(); -///////////////////////////// -// Draw_Flush -// -// Performs all the queued draw actions. -void Draw_Flush(){ - if(_currentImg==NULL || _quadArray->nVertex<=0){ - return; + // Process and draw + if(proc){ + while(t_frame>=proc_t_frame && !done){ + Input_Frame(); + if(!proc()){ + done=1; + } + t_frame-=proc_t_frame; + + } + } + if(draw){ + draw(); + } + + // Measure time + time2=Time_GetTime(); + timed=time2-time; + if(timed50000){ + t_frame=50000; + } } - if(_currentImg->tex==-1){ - _currentImg->tex=Draw_UploadGLTexture(_currentImg->w, _currentImg->h, _currentImg->data); - } - -#if USE_OpenGL - // Draw the quad array - glBindTexture(GL_TEXTURE_2D, _currentImg->tex); - glColorPointer( 4, GL_FLOAT, Vertex2D_Length*sizeof(float), - (GLvoid *)(_quadArray->vertexData+4) ); - glTexCoordPointer( 2, GL_FLOAT, Vertex2D_Length*sizeof(float), - (GLvoid *)(_quadArray->vertexData+2) ); - glVertexPointer( 2, GL_FLOAT, Vertex2D_Length*sizeof(float), - (GLvoid *)(_quadArray->vertexData) ); - glDrawArrays(GL_TRIANGLES,0,_quadArray->nVertex); - -#else - - // Draw the quad array - glBindTexture(GL_TEXTURE_2D, _currentImg->tex); - glBufferSubData(GL_ARRAY_BUFFER, 0, - Vertex2D_Length*sizeof(float)*_quadArray->nVertex, - _quadArray->vertexData); - glDrawArrays(GL_TRIANGLES, 0, _quadArray->nVertex); - -#endif - - // Empty it - QuadArray2D_Clean(_quadArray); } @@ -396,235 +215,93 @@ void Draw_Clean( unsigned char g, unsigned char b) { -#ifndef EMSCRIPTEN - glClearColor(r/255.0f,g/255.0f,b/255.0f,1.0f); + glClearColor(r/256.0f,g/256.0f,b/256.0f,1.0f); glClear(GL_COLOR_BUFFER_BIT); -#else - Draw_Flush(); - float fr=r/255.0f; - float fg=g/255.0f; - float fb=b/255.0f; - GLfloat vVertices[] = { - 0.0, 0.0, // Position 0 - 0.0, 0.0, // TexCoord 0 - fr, fg, fb, 1.0, // Color +} - 0.0, _height, // Position 1 - 0.0, 1.0, // TexCoord 1 - fr, fg, fb, 1.0, // Color - _width, _height, // Position 2 - 1.0, 1.0, // TexCoord 2 - fr, fg, fb, 1.0, // Color - _width, _height, // Position 2 - 1.0, 1.0, // TexCoord 2 - fr, fg, fb, 1.0, // Color +//////////////////////////////////////////////// +// DrawImage // +/////////////// +// Image container. +typedef struct Tag_DrawImage { + SDL_Surface *surf; + GLuint tex; + int x,y; +} DrawImage; - _width, 0.0, // Position 3 - 1.0, 0.0, // TexCoord 3 - fr, fg, fb, 1.0, // Color - 0.0, 0.0, // Position 0 - 0.0, 0.0, // TexCoord 0 - fr, fg, fb, 1.0, // Color - }; - glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vVertices), vVertices); - glDrawArrays(GL_TRIANGLES, 0, 6); -#endif +///////////////////////////// +// Draw_LoadSurface +// +// Loads a surface. +SDL_Surface *Draw_LoadSurface(char *filename){ + SDL_Surface *surf; + + // Load the BMP as a surface + surf=SDL_LoadBMP(filename); + if(surf == NULL){ + printf("Draw_LoadImage: Failure Loading image: %s\n",filename); + printf("Draw_LoadImage: SDL Error: %s\n",SDL_GetError()); + return(NULL); + } + + if (surf->format->BytesPerPixel==4) { + // Swap RGB to BGR + Uint32 *ptr,*ptr_end; + ptr=(Uint32 *)surf->pixels; + ptr_end=ptr+(surf->w*surf->h); + while (ptr100000){ - _accTime=100000; - } - while(_accTime>=proc_t_frame && _draw_looping){ - Input_Frame(); - _proc_func(_data); - _accTime-=proc_t_frame; - Input_SetKey(InputKey_Exit,0); - } - } - - // Draw - if(_draw_func){ - float frameFactor=0.0f; - frameFactor=(float)_accTime/(float)proc_t_frame; - _draw_func(_data,frameFactor); - Draw_Flush(); - } - - return _draw_looping; -} - -#ifdef EMSCRIPTEN -long long _procTime1; -long long _procTime2; -void Draw_LoopIterationAux(){ - Draw_LoopIteration(); - - // Update time - _procTime2=Time_GetTime(); - _accTime+=_procTime2-_procTime1; - _procTime1=_procTime2; -} -#endif - -///////////////////////////// -// Draw_Loop -// -// Loops updating the game window. -void Draw_Loop( - void (*proc)(void *data), - void (*draw)(void *data,float f), - void *data) -{ - long long newTime; - long long procTime1,procTime2,drawTime1,drawTime2,waitTime; - - _proc_func=proc; - _draw_func=draw; - _data=data; - if(_draw_looping){return;} - _draw_looping=1; -#ifndef EMSCRIPTEN - _accTime=proc_t_frame; - procTime1=drawTime1=Time_GetTime(); - while(Draw_LoopIteration()){ - - // Wait to round draw_t_frame - drawTime2=Time_GetTime(); - waitTime=draw_t_frame-(drawTime2-drawTime1); - Time_Pause(waitTime); - drawTime2=Time_GetTime(); - drawTime1=drawTime2; - - // Update time - procTime2=Time_GetTime(); - _accTime+=procTime2-procTime1; - procTime1=procTime2; - } -#else - _accTime=proc_t_frame; - _procTime1=Time_GetTime(); - if(_fps<=50){ - emscripten_set_main_loop(Draw_LoopIterationAux, _fps, 1); - }else{ - emscripten_set_main_loop(Draw_LoopIterationAux, 0, 1); - } -#endif -} + // Generate OpenGL texture + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + //glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); + //glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); -///////////////////////////// -// Draw_BreakLoop -// -// Breaks the drawing loop -void Draw_BreakLoop(){ -#ifndef EMSCRIPTEN - _draw_looping=0; -#endif -} + // Load OpenGL texture + glBindTexture(GL_TEXTURE_2D, tex); + glPixelStorei( GL_UNPACK_ROW_LENGTH, surf->w ); + glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); + //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, + // surf->w, surf->h, 0, + // GL_RGBA, GL_UNSIGNED_BYTE, surf->pixels); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, + surf->w, surf->h, 0, + GL_RGBA, GL_UNSIGNED_BYTE, surf->pixels); + //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, + // imagen->ancho, imagen->alto, 0, + // GL_RGB, GL_UNSIGNED_BYTE, imagen->data); - -///////////////////////////// -// Draw_OverrideExit -// -// Overrides the default exit mechanism -void Draw_OverrideExit(int override){ - _draw_exitoverrided=override; -} - - -///////////////////////////// -// Draw_CreateImage -// -DrawImg Draw_CreateImage(int w,int h){ - DrawImage image; - - // Create the image container - image=malloc(sizeof(TDrawImage)); - image->data=malloc(w*h*4); - image->x=0; - image->y=0; - image->w=w; - image->h=h; - image->tex=-1; - - return((DrawImg)image); + return(tex); } @@ -633,28 +310,28 @@ DrawImg Draw_CreateImage(int w,int h){ // // Loads a image, giving a reference. DrawImg Draw_LoadImage(char *filename){ - DrawImage image; + DrawImage *image; + SDL_Surface *surf; - // Try loading PNG images - if(EndsWith(filename,".png") || EndsWith(filename,".PNG")){ - image=malloc(sizeof(TDrawImage)); - unsigned error = lodepng_decode32_file( - &image->data, - (unsigned*)&image->w, - (unsigned*)&image->h, - filename); - if(error){ - printf("Draw_LoadImage: PNG decoder error %u: %s\n", error, lodepng_error_text(error)); - return(NULL); - } - image->x=-(int)(image->w/2); - image->y=-(int)(image->h/2); - image->tex=-1; - return (DrawImg)image; + + // Loads the surface + surf=Draw_LoadSurface(filename); + if(surf == NULL){ + return(NULL); } - printf("Draw_LoadImage: Image type not supported: %s\n",filename); - return(NULL); + + // Create the image container + image=malloc(sizeof(DrawImage)); + image->surf=surf; + image->tex=Draw_UploadGLTexture(surf); + //image->x=0; + //image->y=0; + image->x=-(surf->w/2); + image->y=-(surf->h/2); + + + return((DrawImg)image); } @@ -663,11 +340,11 @@ DrawImg Draw_LoadImage(char *filename){ // // Gets the image size. void Draw_GetSize(DrawImg img,int *w,int *h){ - DrawImage image=img; + DrawImage *image=img; // Gets the image size - *w=image->w; - *h=image->h; + *w=image->surf->w; + *h=image->surf->h; } @@ -677,14 +354,14 @@ void Draw_GetSize(DrawImg img,int *w,int *h){ // // Sets and Gets the image offset. void Draw_SetOffset(DrawImg img,int x,int y){ - DrawImage image=img; + DrawImage *image=img; // Sets the image offset image->x=x; image->y=y; } void Draw_GetOffset(DrawImg img,int *x,int *y){ - DrawImage image=img; + DrawImage *image=img; // Gets the image offset *x=image->x; @@ -697,24 +374,30 @@ void Draw_GetOffset(DrawImg img,int *x,int *y){ // // Draws an image. void Draw_DrawImg(DrawImg img,int x,int y){ - DrawImage image=img; - float x1,x2,y1,y2; + DrawImage *image=img; + int x1,x2,y1,y2; // Prepare x1=x+image->x; y1=_height-(y+image->y); - x2=(x+image->x)+image->w; - y2=_height-((y+image->y)+image->h); + x2=(x+image->x)+image->surf->w; + y2=_height-((y+image->y)+image->surf->h); // Draw a quad - if(_currentImg!=image){ - Draw_Flush(); - _currentImg=image; - } - QuadArray2D_AddQuad(_quadArray, - x1,y1,0.0f,0.0f, - x2,y2,1.0f,1.0f, - _color); + glBindTexture(GL_TEXTURE_2D, image->tex); + glBegin (GL_QUADS); + glTexCoord2f (1, 0); + glVertex2i (x2, y1); + + glTexCoord2f (0, 0); + glVertex2i (x1, y1); + + glTexCoord2f (0, 1); + glVertex2i (x1, y2); + + glTexCoord2f (1, 1); + glVertex2i (x2, y2); + glEnd (); } @@ -723,7 +406,7 @@ void Draw_DrawImg(DrawImg img,int x,int y){ // // Draws an image, resizing. void Draw_DrawImgResized(DrawImg img,int x,int y,float w,float h){ - DrawImage image=img; + DrawImage *image=img; int x1,x2,y1,y2; // Prepare @@ -733,14 +416,20 @@ void Draw_DrawImgResized(DrawImg img,int x,int y,float w,float h){ y2=_height-((y+image->y)+h); // Draw a quad - if(_currentImg!=image){ - Draw_Flush(); - _currentImg=image; - } - QuadArray2D_AddQuad(_quadArray, - x1,y1,0.0f,0.0f, - x2,y2,1.0f,1.0f, - _color); + glBindTexture(GL_TEXTURE_2D, image->tex); + glBegin (GL_QUADS); + glTexCoord2f (1, 0); + glVertex2i (x2, y1); + + glTexCoord2f (0, 0); + glVertex2i (x1, y1); + + glTexCoord2f (0, 1); + glVertex2i (x1, y2); + + glTexCoord2f (1, 1); + glVertex2i (x2, y2); + glEnd (); } @@ -750,7 +439,7 @@ void Draw_DrawImgResized(DrawImg img,int x,int y,float w,float h){ // // Draws an image part. void Draw_DrawImgPart(DrawImg img,int x,int y,int w,int i){ - DrawImage image=img; + DrawImage *image=img; int x1,x2,y1,y2; float us,u1,u2; @@ -758,20 +447,26 @@ void Draw_DrawImgPart(DrawImg img,int x,int y,int w,int i){ x1=x+image->x; y1=_height-(y+image->y); x2=(x+image->x)+w; - y2=_height-((y+image->y)+image->h); - us=1.0f/image->w; + y2=_height-((y+image->y)+image->surf->h); + us=1.0f/image->surf->w; u1=us*i*w; u2=u1+us*w; // Draw a quad - if(_currentImg!=image){ - Draw_Flush(); - _currentImg=image; - } - QuadArray2D_AddQuad(_quadArray, - x1,y1,u1,0.0f, - x2,y2,u2,1.0f, - _color); + glBindTexture(GL_TEXTURE_2D, image->tex); + glBegin (GL_QUADS); + glTexCoord2f (u2, 0); + glVertex2i (x2, y1); + + glTexCoord2f (u1, 0); + glVertex2i (x1, y1); + + glTexCoord2f (u1, 1); + glVertex2i (x1, y2); + + glTexCoord2f (u2, 1); + glVertex2i (x2, y2); + glEnd (); } @@ -780,10 +475,7 @@ void Draw_DrawImgPart(DrawImg img,int x,int y,int w,int i){ // // void Draw_SetColor(float r,float g,float b,float a){ - _color[0]=r; - _color[1]=g; - _color[2]=b; - _color[3]=a; + glColor4f(r,g,b,a); } @@ -799,41 +491,51 @@ typedef struct { ///////////////////////////// -// Draw_DefaultImage +// Draw_DefaultFont // -// Creates a image with the default font. +// Creates a surface with the default font. #include "FontData.h" -DrawImage Draw_DefaultFontImage( +SDL_Surface *Draw_DefaultFontSurface( unsigned char r, unsigned char g, unsigned char b, unsigned char a) { - DrawImage img; + SDL_Surface *surf; int x,y,c; Uint32 color,color2; - // Create the image and colors - img=Draw_CreateImage(8*256,8); + // Create the surface + surf = SDL_CreateRGBSurface(SDL_SWSURFACE, + 8*256, 8, 32,0,0,0,0); + surf->format->Amask=0xFF000000; + surf->format->Ashift=24; + SDL_SetAlpha(surf, SDL_SRCALPHA, 255); + + // HACK: Set the colors in BGR order + color =SDL_MapRGBA(surf->format,b,g,r,a); + color2=SDL_MapRGBA(surf->format,b,g,r,0); // Draw the font + SDL_LockSurface(surf); for(c=0;c<256;c++){ for(y=0;y<8;y++){ for(x=0;x<8;x++){ - int offset=((c*8+x)+(8*256*y))*4; - img->data[offset+0]=r; - img->data[offset+1]=g; - img->data[offset+2]=b; if(((fontdata_8x8[c*8+y]>>(7-x)) & 0x01)==1){ - img->data[offset+3]=0xFF; + //Imagen_PutPixel(dest,c*8+x,y,color); + ((Uint32 *)surf->pixels)[(c*8+x)+(8*256*y)]= + color; }else{ - img->data[offset+3]=0x00; + //Imagen_PutPixel(dest,c*8+x,y,color2); + ((Uint32 *)surf->pixels)[(c*8+x)+(8*256*y)]= + color2; } } } } + SDL_UnlockSurface(surf); - return(img); + return(surf); } @@ -851,7 +553,10 @@ DrawFnt Draw_DefaultFont( // Create the default font font=malloc(sizeof(DrawFont)); - font->img=Draw_DefaultFontImage(r,g,b,a); + font->img.surf=Draw_DefaultFontSurface(r,g,b,a); + font->img.tex=Draw_UploadGLTexture(font->img.surf); + font->img.x=0; + font->img.y=0; font->w=8; font->h=8; font->min=0; @@ -869,9 +574,12 @@ DrawFnt Draw_LoadFont(char *fichero,int min,int max){ // Create the font form the image font=malloc(sizeof(DrawFont)); - font->img=Draw_LoadImage(fichero); - font->w=font->img->w/(max-min); - font->h=font->img->h; + font->img.surf=Draw_LoadSurface(fichero); + font->img.tex=Draw_UploadGLTexture(font->img.surf); + font->img.x=0; + font->img.y=0; + font->w=font->img.surf->w/(max-min); + font->h=font->img.surf->h; font->min=min; font->max=max; @@ -891,7 +599,7 @@ void Draw_DrawText(DrawFnt f,char *text,int x,int y){ ptr=text; while(*ptr){ if((*ptr)max){ - Draw_DrawImgPart(font->img,x,y,font->w,(*ptr)-font->min); + Draw_DrawImgPart((DrawImg)&font->img,x,y,font->w,(*ptr)-font->min); } x+=font->w; ptr++; @@ -904,7 +612,6 @@ void Draw_DrawText(DrawFnt f,char *text,int x,int y){ // // void Draw_SaveScreenshoot(char *filename){ -#if USE_OpenGL SDL_Surface *surf; unsigned char *image_line; int i,half_height,line_size; @@ -952,7 +659,6 @@ void Draw_SaveScreenshoot(char *filename){ // Cleanup SDL_FreeSurface(surf); -#endif } diff --git a/GameLib/Draw.h b/GameLib/Draw.h index 03ab494..d54f141 100644 --- a/GameLib/Draw.h +++ b/GameLib/Draw.h @@ -11,6 +11,13 @@ int Draw_Init(int width,int height,char *title,int pfps,int fps); +///////////////////////////// +// Draw_Loop +// +// Loops updating the game window. +void Draw_Loop(int (*proc)(),void (*draw)()); + + ///////////////////////////// // Draw_Clean // @@ -21,37 +28,6 @@ void Draw_Clean( unsigned char b); -///////////////////////////// -// Draw_Loop -// -// Loops updating the game window. -void Draw_Loop( - void (*proc)(void *data), - void (*draw)(void *data,float f), - void *data); - - -///////////////////////////// -// Draw_BreakLoop -// -// Breaks the drawing loop -void Draw_BreakLoop(); - - -///////////////////////////// -// Draw_OverrideExit -// -// Overrides the default exit mechanism -void Draw_OverrideExit(int override); - - -///////////////////////////// -// Draw_Flush -// -// Performs all the queued draw actions. -void Draw_Flush(); - - //////////////////////////////////////////////// // DrawImg // ///////////// @@ -59,12 +35,6 @@ void Draw_Flush(); typedef void *DrawImg; -///////////////////////////// -// Draw_CreateImage -// -DrawImg Draw_CreateImage(int w,int h); - - ///////////////////////////// // Draw_LoadImage // diff --git a/GameLib/Entity.c b/GameLib/Entity.c index 930ab53..df016c3 100644 --- a/GameLib/Entity.c +++ b/GameLib/Entity.c @@ -1,4 +1,4 @@ -// Copyright (C) 2011-2014 Valeriano Alfonso Rodriguez (Kableado) +// Copyright (C) 2011 Valeriano Alfonso Rodriguez (Kableado) #include #include @@ -17,12 +17,12 @@ // Entity_New // // -Entity _free_entity=NULL; -Entity Entity_New(){ - Entity e; +Entity *_free_entity=NULL; +Entity *Entity_New(){ + Entity *e; if(!_free_entity){ - e=malloc(sizeof(TEntity)); + e=malloc(sizeof(Entity)); }else{ e=_free_entity; _free_entity=e->next; @@ -30,11 +30,9 @@ Entity Entity_New(){ e->base=NULL; e->type=0; - vec2_set(e->pos0,0.0f,0.0f); vec2_set(e->pos,0.0f,0.0f); e->flags=EntityFlag_Collision|EntityFlag_Overlap; e->zorder=1; - e->sortYOffset=0; vec2_set(e->dir,0.0f,0.0f); @@ -77,7 +75,7 @@ Entity Entity_New(){ // Entity_Destroy // // -void Entity_Destroy(Entity e){ +void Entity_Destroy(Entity *e){ if(e->ondelete){ e->ondelete(e); } @@ -90,8 +88,8 @@ void Entity_Destroy(Entity e){ // Entity_Copy // // -Entity Entity_Copy(Entity e){ - Entity n; +Entity *Entity_Copy(Entity *e){ + Entity *n; n=Entity_New(); @@ -100,7 +98,6 @@ Entity Entity_Copy(Entity e){ vec2_set(n->pos,e->pos[0],e->pos[1]); n->flags=e->flags; n->zorder=e->zorder; - n->sortYOffset=e->sortYOffset; vec2_set(n->vel,e->vel[0],e->vel[1]); n->radius=e->radius; @@ -136,8 +133,6 @@ Entity Entity_Copy(Entity e){ n->D=e->D; n->child=e->child; - Entity_CalcBBox(n); - // Call the copy event if(n->oncopy){ n->oncopy(n); @@ -147,67 +142,22 @@ Entity Entity_Copy(Entity e){ } -///////////////////////////// -// Entity_CalcBBox -// -// -#define BBox_ExtraMargin 10 -#define max(a,b) ((a)>(b)?(a):(b)) -void Entity_CalcBBox(Entity e){ - float hHeight=(max(e->height,e->radius)/2)+BBox_ExtraMargin; - float hWidth=(max(e->width,e->radius)/2)+BBox_ExtraMargin; - if(e->vel[0]>0){ - e->maxX=e->pos[0]+e->vel[0]+hWidth; - e->minX=e->pos[0]-hWidth; - }else{ - e->minX=(e->pos[0]+e->vel[0])-hWidth; - e->maxX=e->pos[0]+hWidth; - } - if(e->vel[1]>0){ - e->maxY=e->pos[1]+e->vel[1]+hHeight; - e->minY=e->pos[1]-hHeight; - }else{ - e->minY=(e->pos[1]+e->vel[1])-hHeight; - e->maxY=e->pos[1]+hHeight; - } -} - - -///////////////////////////// -// Entity_BBoxIntersect -// -// -int Entity_BBoxIntersect(Entity ent1,Entity ent2){ - if( ent1->maxX>=ent2->minX && ent1->minX<=ent2->maxX && - ent1->maxY>=ent2->minY && ent1->minY<=ent2->maxY ) - { - return(1); - } - return(0); -} - - ///////////////////////////// // Entity_Draw // // -void Entity_Draw(Entity e,int x,int y,float f){ - vec2 fPos; +void Entity_Draw(Entity *e,int x,int y){ Draw_SetColor(e->color[0],e->color[1],e->color[2],e->color[3]); - if(e->flags&EntityFlag_UpdatedPos){ - vec2_interpol(fPos,e->pos0,e->pos,f); - AnimPlay_Draw(&e->anim,fPos[0]+x,fPos[1]+y); - }else{ - AnimPlay_Draw(&e->anim,e->pos[0]+x,e->pos[1]+y); - } + AnimPlay_Draw(&e->anim,e->pos[0]+x,e->pos[1]+y); } + ///////////////////////////// // Entity_IsVisible // // -int Entity_IsVisible(Entity e,int x,int y,int w,int h){ +int Entity_IsVisible(Entity *e,int x,int y,int w,int h){ int xmax,xmin; int ymax,ymin; int ih,iw; @@ -235,7 +185,7 @@ int Entity_IsVisible(Entity e,int x,int y,int w,int h){ // Entity_Process // // -void Entity_Process(Entity b,int ft){ +void Entity_Process(Entity *b,int ft){ b->flags&=~EntityFlag_UpdatedPos; // Launch method @@ -249,11 +199,9 @@ void Entity_Process(Entity b,int ft){ // Entity_PostProcess // // -void Entity_PostProcess(Entity e,int ft){ +void Entity_PostProcess(Entity *e,int ft){ float qlen,len; - vec2_copy(e->pos0,e->pos); - // Determine if there is movement qlen=vec2_dot(e->vel,e->vel); if(qlen>0.0f){ @@ -275,8 +223,6 @@ void Entity_PostProcess(Entity e,int ft){ // Mark the update of the position. vec2_copy(e->oldpos,e->pos); e->flags|=EntityFlag_UpdatedPos; - - Entity_CalcBBox(e); } // Launch method @@ -290,123 +236,131 @@ void Entity_PostProcess(Entity e,int ft){ ///////////////////////////// -// CollisionInfo_New +// Entity_CollisionResponseClircle // -// -CollisionInfo _free_collInfo=NULL; -CollisionInfo CollisionInfo_New(int responseType,Entity ent1,Entity ent2,float t,vec2 n,int applyFriction){ - CollisionInfo collInfo; - - if(!_free_collInfo){ - collInfo=malloc(sizeof(TCollisionInfo)); - }else{ - collInfo=_free_collInfo; - _free_collInfo=collInfo->next; - } - collInfo->next=NULL; - - collInfo->responseType=responseType; - collInfo->ent1=ent1; - collInfo->ent2=ent2; - collInfo->t=t; - vec2_copy(collInfo->n,n); - collInfo->applyFriction=applyFriction; - - return collInfo; -} - - -///////////////////////////// -// CollisionInfo_Destroy -// -// -void CollisionInfo_Destroy(CollisionInfo *collInfoRef){ - if(collInfoRef==NULL || collInfoRef[0]==NULL){return;} - - CollisionInfo collInfo=collInfoRef[0]; - CollisionInfo nextCollInfo; - while(collInfo!=NULL){ - nextCollInfo=collInfo->next; - collInfo->next=_free_collInfo; - _free_collInfo=collInfo; - collInfo=nextCollInfo; - } - collInfoRef[0]=NULL; -} - - -///////////////////////////// -// CollisionInfo_Add -// -// -void CollisionInfo_Add(CollisionInfo *collInfoRef, - int responseType,Entity ent1,Entity ent2,float t,vec2 n,int applyFriction) +// Normal response to a collision between circles. +void Entity_CollisionResponseCircle( + Entity *b1,Entity *b2,float t,vec2 n) { - if(collInfoRef==NULL){return;} - CollisionInfo prevCollInfo=NULL; - CollisionInfo collInfo=collInfoRef[0]; - CollisionInfo newCollInfo=CollisionInfo_New(responseType,ent1,ent2,t,n,applyFriction); + float moment; + vec2 temp; + float elast; - while(collInfo!=NULL && collInfo->tnext; - } - if(prevCollInfo==NULL){ - collInfoRef[0]=newCollInfo; + if(b1->mass>0.0f && b2->mass>0.0f){ + // Calculate elasticity + elast=(b1->mass*b1->elast+b2->mass*b2->elast)/ + (b1->mass+b2->mass); + + // Collision between two massed balls + moment=((1.0f+elast)*b1->mass*b2->mass* + (fabs(vec2_dot(b1->vel,n))+fabs(vec2_dot(b2->vel,n)))) + /(b1->mass+b2->mass); + vec2_scale(temp,n,moment/b1->mass); + vec2_minus(b1->vel,b1->vel,temp); + vec2_scale(temp,n,moment/b2->mass); + vec2_plus(b2->vel,b2->vel,temp); + }else + if(b1->mass>0.0f && b2->mass<=0.0f){ + // Collision between a massed ball and a fixed ball + moment=(1.0f+b1->elast)* + (vec2_dot(b1->vel,n)); + vec2_scale(temp,n,moment); + vec2_minus(b1->vel,b1->vel,temp); + }else + if(b1->mass<=0.0f && b2->mass>0.0f){ + // Collision between a massed ball and a fixed ball + // (imposible, but better safe) + moment=(1.0f+b2->elast)* + (vec2_dot(b2->vel,n)); + vec2_scale(temp,n,moment); + vec2_plus(b2->vel,b2->vel,temp); }else{ - prevCollInfo->next=newCollInfo; + // Collision between 2 fixed balls + // (imposible, but better safe) + vec2_set(b1->vel,0,0); + vec2_set(b2->vel,0,0); } - newCollInfo->next=collInfo; } ///////////////////////////// -// CollisionInfo_CheckRepetition +// Entity_CollisionResponseLine // -// -int CollisionInfo_CheckRepetition(CollisionInfo collInfo,Entity ent1,Entity ent2) +// Normal response to a collision with a line. +void Entity_CollisionResponseLine( + Entity *ent,Entity *ent2,float t,vec2 norm,int applyFriction) { - while(collInfo!=NULL){ - if((collInfo->ent1==ent1 && collInfo->ent2==ent2) || - (collInfo->ent1==ent2 && collInfo->ent2==ent1)) - { - return(1); + vec2 pos2,vel2,velFric,intersection; + float dist,fric_static,fric_dynamic,fricLen; + + // Calculate friction + fric_static=(ent->fric_static+ent2->fric_static)/2; + fric_dynamic=(ent->fric_dynamic+ent2->fric_dynamic)/2; + + // Calculate end position + vec2_scale(vel2,ent->vel,1.0f-t); + dist=-vec2_dot(norm,vel2); + vec2_plus(pos2,ent->pos,ent->vel); + vec2_scaleadd(pos2,pos2,norm,dist); + + // Calculate intersection + vec2_scaleadd(intersection,ent->pos,ent->vel,t); + + if(applyFriction){ + // Apply friction + vec2_minus(velFric,pos2,intersection); + fricLen=sqrtf(vec2_dot(velFric,velFric)); + if(fricLen0.0f){ + vec2_scaleadd(pos2,intersection,velFric, + 1.0f-(fric_dynamic+(fric_static/fricLen))); + }else{ + vec2_scaleadd(pos2,intersection,velFric, + 1.0f-fric_dynamic); + } } - collInfo=collInfo->next; } - return(0); + + // Apply to velocity + vec2_scaleadd(pos2,pos2,norm,0.1f); + vec2_minus(ent->vel,pos2,ent->pos); } ///////////////////////////// -// Entity_CheckCollisions +// Entity_Collide // // -int Entity_CheckCollision(Entity ent1,Entity ent2,CollisionInfo *collInfoRef){ +int Entity_Collide(Entity *b1,Entity *b2){ float t; vec2 n,p; vec2 vel; - int flags=ent1->flags|ent2->flags; + int flags=b1->flags|b2->flags; if(flags&EntityFlag_Platform && !(flags&EntityFlag_Block)){ // One of the entities is a platform and none is a block - Entity ent,ent_plat; + Entity *ent,*ent_plat; float plat_width; vec2 p; // Decide who is the platform and who is the ent - if(ent1->mass<=0.0f && ent2->mass>0.0f){ - ent=ent2; - ent_plat=ent1; + if(b1->mass<=0.0f && b2->mass>0.0f){ + ent=b2; + ent_plat=b1; }else - if(ent2->mass<=0.0f && ent1->mass>0.0f){ - ent=ent1; - ent_plat=ent2; + if(b2->mass<=0.0f && b1->mass>0.0f){ + ent=b1; + ent_plat=b2; }else{ // Two static or two dinamic entities?!? return(0); } + // Check Top vec2_set(n,0,-1); vec2_scaleadd(p,ent_plat->pos,n,(ent->height+ent_plat->height)/2); @@ -414,10 +368,36 @@ int Entity_CheckCollision(Entity ent1,Entity ent2,CollisionInfo *collInfoRef){ if(Intersect_RayEdge(ent->pos,ent->vel, n,p,plat_width,&t)) { - // Keep colision info - CollisionInfo_Add(collInfoRef, - CollisionResponse_Line,ent,ent_plat,t,n,1); - return(1); + int response=1; + int rc; + + // Check the collision methods + if(ent->collision){ + rc=ent->collision(ent,ent_plat,t,n); + if (rc==0) + response=0; + if (rc>1) + response=2; + } + if(ent_plat->collision){ + vec2 n2; + vec2_scale(n2,n,-1.0f); + rc=ent_plat->collision(ent_plat,ent,t,n2); + if (rc==0) + response=0; + if (rc>1) + response=2; + } + + // Collision response + if(response==1){ + Entity_CollisionResponseLine(ent,ent_plat,t,n,1); + return(1); + } + if (response==2) { + return(1); + } + return(0); } return(0); @@ -425,19 +405,19 @@ int Entity_CheckCollision(Entity ent1,Entity ent2,CollisionInfo *collInfoRef){ if(flags&EntityFlag_Block && !(flags&EntityFlag_Platform)){ // One of the entities is a block and none is a platform - Entity ent,ent_block; + Entity *ent,*ent_block; float auxT,block_len; vec2 auxN,p; int applyFriction; - // Decide who is the platform and who is the ent - if(ent1->mass<=0.0f && ent2->mass>0.0f){ - ent=ent2; - ent_block=ent1; + // Decide who is the block and who is the ent + if(b1->mass<=0.0f && b2->mass>0.0f){ + ent=b2; + ent_block=b1; }else - if(ent2->mass<=0.0f && ent1->mass>0.0f){ - ent=ent1; - ent_block=ent2; + if(b2->mass<=0.0f && b1->mass>0.0f){ + ent=b1; + ent_block=b2; }else{ // Two static or two dinamic entities?!? return(0); @@ -504,155 +484,61 @@ int Entity_CheckCollision(Entity ent1,Entity ent2,CollisionInfo *collInfoRef){ } if(t<1.0f){ - // Keep colision info - CollisionInfo_Add(collInfoRef, - CollisionResponse_Line,ent,ent_block,t,n,applyFriction); - return(1); + // Handle colision + int response=1; + int rc; + + // Check the collision methods + if(ent->collision){ + rc=ent->collision(ent,ent_block,t,n); + if (rc==0) + response=0; + if (rc>1) + response=2; + } + if(ent_block->collision){ + vec2 n2; + vec2_scale(n2,n,-1.0f); + rc=ent_block->collision(ent_block,ent,t,n2); + if (rc==0) + response=0; + if (rc>1) + response=2; + } + + // Collision response + if(response==1){ + Entity_CollisionResponseLine(ent,ent_block,t,n,applyFriction); + return(1); + } + if (response==2) { + return(1); + } + return(0); } return(0); } - // Test relative to ent1 - vec2_minus(vel,ent1->vel,ent2->vel); - if(Colision_CircleCircle(ent1->pos,ent1->radius,vel,ent2->pos,ent2->radius,&t,n)){ - // Keep colision info - CollisionInfo_Add(collInfoRef, - CollisionResponse_Circle,ent1,ent2,t,n,0); - return(1); - } - return(0); -} - -///////////////////////////// -// Entity_CollisionResponseCircle -// -// Normal response to a collision between circles. -void Entity_CollisionResponseCircle( - Entity b1,Entity b2,float t,vec2 n) -{ - float moment; - vec2 temp; - float elast; - - if(b1->mass>0.0f && b2->mass>0.0f){ - // Calculate elasticity - elast=(b1->mass*b1->elast+b2->mass*b2->elast)/ - (b1->mass+b2->mass); - - // Collision between two massed balls - moment=((1.0f+elast)*b1->mass*b2->mass* - (fabs(vec2_dot(b1->vel,n))+fabs(vec2_dot(b2->vel,n)))) - /(b1->mass+b2->mass); - vec2_scale(temp,n,moment/b1->mass); - vec2_minus(b1->vel,b1->vel,temp); - Entity_CalcBBox(b1); - vec2_scale(temp,n,moment/b2->mass); - vec2_plus(b2->vel,b2->vel,temp); - Entity_CalcBBox(b2); - }else - if(b1->mass>0.0f && b2->mass<=0.0f){ - // Collision between a massed ball and a fixed ball - moment=(1.0f+b1->elast)* - (vec2_dot(b1->vel,n)); - vec2_scale(temp,n,moment); - vec2_minus(b1->vel,b1->vel,temp); - Entity_CalcBBox(b1); - }else - if(b1->mass<=0.0f && b2->mass>0.0f){ - // Collision between a massed ball and a fixed ball - // (imposible, but better safe) - moment=(1.0f+b2->elast)* - (vec2_dot(b2->vel,n)); - vec2_scale(temp,n,moment); - vec2_plus(b2->vel,b2->vel,temp); - Entity_CalcBBox(b2); - }else{ - // Collision between 2 fixed balls - // (imposible, but better safe) - vec2_set(b1->vel,0,0); - Entity_CalcBBox(b1); - vec2_set(b2->vel,0,0); - Entity_CalcBBox(b2); - } -} - - -///////////////////////////// -// Entity_CollisionResponseLine -// -// Normal response to a collision with a line. -void Entity_CollisionResponseLine( - Entity ent,Entity ent2,float t,vec2 norm,int applyFriction) -{ - vec2 pos2,vel2,velFric,intersection; - float dist,fric_static,fric_dynamic,fricLen; - - // Calculate friction - fric_static=(ent->fric_static+ent2->fric_static)/2; - fric_dynamic=(ent->fric_dynamic+ent2->fric_dynamic)/2; - - // Calculate end position - vec2_scale(vel2,ent->vel,1.0f-t); - dist=-vec2_dot(norm,vel2); - vec2_plus(pos2,ent->pos,ent->vel); - vec2_scaleadd(pos2,pos2,norm,dist); - - // Calculate intersection - vec2_scaleadd(intersection,ent->pos,ent->vel,t); - - if(applyFriction){ - // Apply friction - vec2_minus(velFric,pos2,intersection); - fricLen=sqrtf(vec2_dot(velFric,velFric)); - if(fricLen0.0f){ - vec2_scaleadd(pos2,intersection,velFric, - 1.0f-(fric_dynamic+(fric_static/fricLen))); - }else{ - vec2_scaleadd(pos2,intersection,velFric, - 1.0f-fric_dynamic); - } - } - } - - // Apply to velocity - vec2_scaleadd(pos2,pos2,norm,0.1f); - vec2_minus(ent->vel,pos2,ent->pos); - - Entity_CalcBBox(ent); -} - - -///////////////////////////// -// Entity_CollisionInfoResponse -// -// -int Entity_CollisionInfoResponse(CollisionInfo collInfo){ - while(collInfo!=NULL){ - // Handle colision + // Test relative to b1 + vec2_minus(vel,b1->vel,b2->vel); + if(Colision_CircleCircle(b1->pos,b1->radius,vel,b2->pos,b2->radius,&t,n)){ int response=1; int rc; - vec2 n1; vec2 n2; - vec2_copy(n1,collInfo->n); - vec2_scale(n2,collInfo->n,-1.0f); + vec2_scale(n2,n,-1.0f); // Check the collision methods - if(collInfo->ent1->collision){ - rc=collInfo->ent1->collision(collInfo->ent1,collInfo->ent2,collInfo->t,n1); + if(b1->collision){ + rc=b1->collision(b1,b2,t,n2); if (rc==0) response=0; if (rc>1) response=2; } - if(collInfo->ent2->collision){ - rc=collInfo->ent2->collision(collInfo->ent2,collInfo->ent1,collInfo->t,n2); + if(b2->collision){ + rc=b2->collision(b2,b1,t,n); if (rc==0) response=0; if (rc>1) @@ -661,26 +547,17 @@ int Entity_CollisionInfoResponse(CollisionInfo collInfo){ // Collision response if(response==1){ - if(collInfo->responseType==CollisionResponse_Line){ - Entity_CollisionResponseLine( - collInfo->ent1,collInfo->ent2,collInfo->t,collInfo->n,collInfo->applyFriction); - }else - if(collInfo->responseType==CollisionResponse_Circle){ - if(vec2_dot(collInfo->ent1->vel,collInfo->ent1->vel)> - vec2_dot(collInfo->ent2->vel,collInfo->ent2->vel)) - { - Entity_CollisionResponseCircle(collInfo->ent1,collInfo->ent2,collInfo->t,n2); - }else{ - Entity_CollisionResponseCircle(collInfo->ent2,collInfo->ent1,collInfo->t,n1); - } + if(vec2_dot(b1->vel,b1->vel)>vec2_dot(b2->vel,b2->vel)){ + Entity_CollisionResponseCircle(b1,b2,t,n); + }else{ + Entity_CollisionResponseCircle(b2,b1,t,n); } return(1); } if (response==2) { return(1); } - - collInfo=collInfo->next; + return(0); } return(0); } @@ -690,7 +567,7 @@ int Entity_CollisionInfoResponse(CollisionInfo collInfo){ // Entity_Overlaps // // -void Entity_Overlaps(Entity b1,Entity b2){ +void Entity_Overlaps(Entity *b1,Entity *b2){ vec2 len; vec2_minus(len,b1->pos,b2->pos); @@ -717,7 +594,7 @@ void Entity_Overlaps(Entity b1,Entity b2){ // Entity_GetPos // // -void Entity_GetPos(Entity e,vec2 pos){ +void Entity_GetPos(Entity *e,vec2 pos){ vec2_copy(pos,e->pos); } @@ -725,7 +602,7 @@ void Entity_GetPos(Entity e,vec2 pos){ // Entity_UpdatePos // // -void Entity_UpdatePos(Entity e,vec2 pos){ +void Entity_UpdatePos(Entity *e,vec2 pos){ // Mark the update of the position. vec2_copy(e->oldpos,e->pos); @@ -738,7 +615,7 @@ void Entity_UpdatePos(Entity e,vec2 pos){ // Entity_AddVelLimit // // -void Entity_AddVelLimit(Entity e,vec2 vel,float limit){ +void Entity_AddVelLimit(Entity *e,vec2 vel,float limit){ float vlen_orig,vlen; vec2 dir,vel_temp; @@ -756,7 +633,6 @@ void Entity_AddVelLimit(Entity e,vec2 vel,float limit){ vec2_scale(vel_temp,dir,vlen); vec2_plus(e->vel,e->vel,vel_temp); } - Entity_CalcBBox(e); } @@ -764,7 +640,7 @@ void Entity_AddVelLimit(Entity e,vec2 vel,float limit){ // Entity_SetColor // // -void Entity_SetColor(Entity e,float r,float g,float b,float a){ +void Entity_SetColor(Entity *e,float r,float g,float b,float a){ e->color[0]=r; e->color[1]=g; e->color[2]=b; @@ -776,7 +652,7 @@ void Entity_SetColor(Entity e,float r,float g,float b,float a){ // Entity_AddColor // // -void Entity_AddColor(Entity e,float r,float g,float b,float a){ +void Entity_AddColor(Entity *e,float r,float g,float b,float a){ e->color[0]+=r; if(e->color[0]>1.0f) e->color[0]=1.0f; @@ -796,7 +672,7 @@ void Entity_AddColor(Entity e,float r,float g,float b,float a){ // Entity_SetLight // // -void Entity_SetLight(Entity e,float r,float g,float b,float rad){ +void Entity_SetLight(Entity *e,float r,float g,float b,float rad){ e->light[0]=r; e->light[1]=g; e->light[2]=b; @@ -809,7 +685,7 @@ void Entity_SetLight(Entity e,float r,float g,float b,float rad){ // Entity_Iluminate // // -void Entity_Iluminate(Entity e,Entity *elist,int n){ +void Entity_Iluminate(Entity *e,Entity **elist,int n){ int i; vec2 vdist; float qdist,f; @@ -849,7 +725,7 @@ void Entity_Iluminate(Entity e,Entity *elist,int n){ // Entity_MarkUpdateLight // // -void Entity_MarkUpdateLight(Entity e,Entity *elist,int n){ +void Entity_MarkUpdateLight(Entity *e,Entity **elist,int n){ if(e->flags&EntityFlag_Light){ int i; vec2 max,min; diff --git a/GameLib/Entity.h b/GameLib/Entity.h index 07d417e..7a044b3 100644 --- a/GameLib/Entity.h +++ b/GameLib/Entity.h @@ -1,4 +1,4 @@ -// Copyright (C) 2011-2014 Valeriano Alfonso Rodriguez (Kableado) +// Copyright (C) 2011 Valeriano Alfonso Rodriguez (Kableado) #ifndef _ENTITY_H_ #define _ENTITY_H_ @@ -9,7 +9,8 @@ //////////////////////////////////////////////// -// Entity +// Entity // +//////////// // #define EntityFlag_Collision 1 #define EntityFlag_Platform 2 @@ -20,17 +21,14 @@ #define EntityFlag_Light 16 #define EntityFlag_UpdateLight 32 #define EntityFlag_UpdatedPos 64 -typedef struct TEntity TEntity, *Entity; -struct TEntity { - Entity base; +typedef struct Tag_Entity { + struct Tag_Entity *base; int type; vec2 oldpos; - vec2 pos0; vec2 pos; int flags; int zorder; - float sortYOffset; vec2 dir; @@ -51,134 +49,72 @@ struct TEntity { float color[4]; float light[4]; - void (*oncopy)(Entity ent); - void (*ondelete)(Entity ent); - void (*proc)(Entity ent,int ft); - void (*postproc)(Entity ent,int ft); - int (*collision)(Entity ent, Entity ent2, float t,vec2 n); - void (*overlap)(Entity ent, Entity ent2); + void (*oncopy)(struct Tag_Entity *ent); + void (*ondelete)(struct Tag_Entity *ent); + void (*proc)(struct Tag_Entity *ent,int ft); + void (*postproc)(struct Tag_Entity *ent,int ft); + int (*collision)( + struct Tag_Entity *ent, + struct Tag_Entity *ent2, + float t,vec2 n); + void (*overlap)( + struct Tag_Entity *ent, + struct Tag_Entity *ent2); int A; int B; int C; int D; - Entity child; + struct Tag_Entity *child; - float maxX,minX; - float maxY,minY; - - Entity next; -}; + void *next; +} Entity; ///////////////////////////// // Entity_New // -Entity Entity_New(); +// +Entity *Entity_New(); ///////////////////////////// // Entity_Destroy // -void Entity_Destroy(Entity e); +// +void Entity_Destroy(Entity *e); ///////////////////////////// // Entity_Copy // -Entity Entity_Copy(Entity e); - - -///////////////////////////// -// Entity_CalcBBox // -// -void Entity_CalcBBox(Entity e); - - -///////////////////////////// -// Entity_BBoxIntersect -// -// -int Entity_BBoxIntersect(Entity ent1,Entity ent2); +Entity *Entity_Copy(Entity *e); ///////////////////////////// // Entity_Draw // -void Entity_Draw(Entity e,int x,int y,float f); - +// +void Entity_Draw(Entity *e,int x,int y); ///////////////////////////// // Entity_IsVisible // -int Entity_IsVisible(Entity e,int x,int y,int w,int h); - +// +int Entity_IsVisible(Entity *e,int x,int y,int w,int h); ///////////////////////////// // Entity_Process // -void Entity_Process(Entity e,int ft); - +// +void Entity_Process(Entity *e,int ft); ///////////////////////////// // Entity_PostProcess // -void Entity_PostProcess(Entity e,int ft); - - -//////////////////////////////////////////////// -// CollisionInfo // -#define CollisionResponse_Circle 1 -#define CollisionResponse_Line 2 -typedef struct TCollisionInfo TCollisionInfo,*CollisionInfo; -struct TCollisionInfo { - int responseType; - Entity ent1; - Entity ent2; - float t; - vec2 n; - int applyFriction; - - CollisionInfo next; -}; - - -///////////////////////////// -// CollisionInfo_New -// -// -CollisionInfo CollisionInfo_New(int responseType,Entity ent1,Entity ent2,float t,vec2 n,int applyFriction); - - -///////////////////////////// -// CollisionInfo_Destroy -// -// -void CollisionInfo_Destroy(CollisionInfo *collInfoRef); - - -///////////////////////////// -// CollisionInfo_Add -// -// -void CollisionInfo_Add(CollisionInfo *collInfo, - int responseType,Entity ent1,Entity ent2,float t,vec2 n,int applyFriction); - - -///////////////////////////// -// CollisionInfo_CheckRepetition -// -// -int CollisionInfo_CheckRepetition(CollisionInfo collInfo,Entity ent1,Entity ent2); - - -///////////////////////////// -// Entity_CheckCollision -// -// -int Entity_CheckCollision(Entity ent1,Entity ent2,CollisionInfo *collInfoRef); +void Entity_PostProcess(Entity *e,int ft); ///////////////////////////// @@ -186,7 +122,7 @@ int Entity_CheckCollision(Entity ent1,Entity ent2,CollisionInfo *collInfoRef); // // Normal response to a collision of spheres. void Entity_CollisionResponseCircle( - Entity b1,Entity b2,float t,vec2 n); + Entity *b1,Entity *b2,float t,vec2 n); ///////////////////////////// @@ -194,69 +130,75 @@ void Entity_CollisionResponseCircle( // // Normal response to a collision with a line. void Entity_CollisionResponseLine( - Entity ent,Entity ent2,float t,vec2 n,int applyFriction); + Entity *ent,Entity *ent2,float t,vec2 n,int applyFriction); ///////////////////////////// -// Entity_CollisionInfoResponse +// Entity_Collide // // -int Entity_CollisionInfoResponse(CollisionInfo collInfo); +int Entity_Collide(Entity *b1,Entity *b2); ///////////////////////////// // Entity_Overlaps // -void Entity_Overlaps(Entity b1,Entity b2); +// +void Entity_Overlaps(Entity *b1,Entity *b2); ///////////////////////////// // Entity_GetPos // -void Entity_GetPos(Entity e,vec2 pos); +// +void Entity_GetPos(Entity *e,vec2 pos); ///////////////////////////// // Entity_UpdatePos // -void Entity_UpdatePos(Entity e,vec2 pos); +// +void Entity_UpdatePos(Entity *e,vec2 pos); ///////////////////////////// // Entity_AddVelLimit // -void Entity_AddVelLimit(Entity e,vec2 vel,float limit); +// +void Entity_AddVelLimit(Entity *e,vec2 vel,float limit); ///////////////////////////// // Entity_SetColor // -void Entity_SetColor(Entity e,float r,float g,float b,float a); +// +void Entity_SetColor(Entity *e,float r,float g,float b,float a); ///////////////////////////// // Entity_AddColor // -void Entity_AddColor(Entity e,float r,float g,float b,float a); +// +void Entity_AddColor(Entity *e,float r,float g,float b,float a); ///////////////////////////// // Entity_AddColor // -void Entity_SetLight(Entity e,float r,float g,float b,float rad); - +// +void Entity_SetLight(Entity *e,float r,float g,float b,float rad); ///////////////////////////// // Entity_AddColor // -void Entity_Iluminate(Entity e,Entity *elist,int n); - +// +void Entity_Iluminate(Entity *e,Entity **elist,int n); ///////////////////////////// // Entity_MarkUpdateLight // -void Entity_MarkUpdateLight(Entity e,Entity *elist,int n); - +// +void Entity_MarkUpdateLight(Entity *e,Entity **elist,int n); #endif diff --git a/GameLib/GameLib.c b/GameLib/GameLib.c index b4049d5..d5b5a86 100644 --- a/GameLib/GameLib.c +++ b/GameLib/GameLib.c @@ -1,9 +1,6 @@ // Copyright (C) 2011 Valeriano Alfonso Rodriguez (Kableado) #include -#include -#include -#include #include #include "Time.h" @@ -17,7 +14,8 @@ #include "GameLib.h" // Globals -Entity *_entity=NULL; +int _running; +Entity **_entity=NULL; int *_entity_flag=NULL; int _n_entities=0; int _n_entities_res=0; @@ -25,12 +23,11 @@ int _entities_lock=0; int _entities_compactate=0; void (*_gameproc)()=NULL; void (*_gamepostproc)()=NULL; -void (*_gamepredraw)(float f)=NULL; -void (*_gamedraw)(float f)=NULL; -int _pft; +void (*_gamepredraw)()=NULL; +void (*_gamedraw)()=NULL; +int _ft; int _game_size[2]; -int _game_pos0[2]; -int _game_pos1[2]; +int _game_pos[2]; long long t_proc; long long t_col; @@ -58,12 +55,10 @@ int GameLib_Init(int w,int h,char *title,int pfps,int fps){ _game_size[0]=w; _game_size[1]=h; - _game_pos0[0]=0; - _game_pos0[1]=0; - _game_pos1[0]=0; - _game_pos1[1]=0; + _game_pos[0]=0; + _game_pos[1]=0; - _pft=1000/pfps; + _ft=1000/fps; return(1); } @@ -73,9 +68,9 @@ int GameLib_Init(int w,int h,char *title,int pfps,int fps){ // GameLib_AddEntity // // Adds an entity to the game. -void GameLib_AddEntity(Entity e){ +void GameLib_AddEntity(Entity *e){ if(_n_entities>=_n_entities_res){ - Entity *entity_aux; + Entity **entity_aux; int *entity_flag_aux; int i; @@ -84,7 +79,7 @@ void GameLib_AddEntity(Entity e){ _n_entities_res=32; else _n_entities_res*=2; - entity_aux=malloc(sizeof(Entity)*_n_entities_res); + entity_aux=malloc(sizeof(Entity *)*_n_entities_res); entity_flag_aux=malloc(sizeof(int)*_n_entities_res); for(i=0;i<_n_entities;i++){ entity_aux[i]=_entity[i]; @@ -105,8 +100,6 @@ void GameLib_AddEntity(Entity e){ // Mark for light update Entity_MarkUpdateLight(e,_entity,_n_entities); - - Entity_CalcBBox(e); } @@ -114,7 +107,7 @@ void GameLib_AddEntity(Entity e){ // GameLib_UnrefEntity // // removes the reference to the entity. -int GameLib_UnrefEntity(Entity e){ +int GameLib_UnrefEntity(Entity *e){ int i; for(i=0;i<_n_entities;i++){ if(e==_entity[i]){ @@ -140,7 +133,7 @@ int GameLib_UnrefEntity(Entity e){ // GameLib_DelEntity // // Adds an entity to the game. -int GameLib_DelEntity(Entity e){ +int GameLib_DelEntity(Entity *e){ int i; if((i=GameLib_UnrefEntity(e))==-1){ return(0); @@ -184,19 +177,15 @@ void GameLib_Compactate(){ _entities_lock=0; } - ///////////////////////////// // GameLib_ProcLoop // // Process the loop. -void GameLib_ProcLoop(void *data){ +int GameLib_ProcLoop(){ int i,j; int repeat,count; long long time; - // Step the gamePosition - _game_pos0[0]=_game_pos1[0]; - _game_pos0[1]=_game_pos1[1]; // Process time=Time_GetTime(); @@ -207,43 +196,31 @@ void GameLib_ProcLoop(void *data){ for(i=0;i<_n_entities;i++){ if(!_entity[i]) continue; - Entity_Process(_entity[i],_pft); + Entity_Process(_entity[i],_ft); } GameLib_Compactate(); t_proc+=Time_GetTime()-time; + // Colisions between entities time=Time_GetTime(); GameLib_Compactate();_entities_lock=1; count=0; do{ repeat=0; - CollisionInfo collInfo=NULL; for(i=0;i<_n_entities;i++){ if(!(_entity[i]->flags&EntityFlag_Collision) || _entity[i]->mass<0.0f) continue; - if(_entity[i]->vel[0]<=0.0f && _entity[i]->vel[0]>=-0.0f && - _entity[i]->vel[1]<=0.0f && _entity[i]->vel[1]>=-0.0f) - { - continue; - } for(j=0;j<_n_entities;j++){ - if(!(_entity[j]->flags&EntityFlag_Collision) || - !Entity_BBoxIntersect(_entity[i],_entity[j]) || - CollisionInfo_CheckRepetition(collInfo,_entity[i],_entity[j])) - { + if(!(_entity[j]->flags&EntityFlag_Collision) || i==j) continue; + if(Entity_Collide(_entity[i],_entity[j])){ + repeat=1; } - Entity_CheckCollision(_entity[i],_entity[j],&collInfo); } } - if(Entity_CollisionInfoResponse(collInfo)){ - repeat=1; - } - CollisionInfo_Destroy(&collInfo); count++; - }while(repeat && count<50); - + }while(repeat && count<10); // Stop remaining collisions if(count==10){ for(i=0;i<_n_entities;i++){ @@ -252,11 +229,9 @@ void GameLib_ProcLoop(void *data){ for(j=0;j<_n_entities;j++){ if(!(_entity[j]->flags&EntityFlag_Collision) || i==j) continue; - if(Entity_CheckCollision(_entity[i],_entity[j],NULL)){ + if(Entity_Collide(_entity[i],_entity[j])){ vec2_set(_entity[i]->vel,0,0); - Entity_CalcBBox(_entity[i]); vec2_set(_entity[j]->vel,0,0); - Entity_CalcBBox(_entity[j]); } } } @@ -285,25 +260,21 @@ void GameLib_ProcLoop(void *data){ do{ n2=0; for(i=1;izorder > ent2->zorder){ + if(_entity[i-1]->zorder > _entity[i]->zorder){ // Lower level swap=1; }else - if(ent1->zorder < ent2->zorder){ + if(_entity[i-1]->zorder < _entity[i]->zorder){ // Upper level }else{ // Same level - float y1=ent1->pos[1]+ent1->sortYOffset; - float y2=ent2->pos[1]+ent2->sortYOffset; - if(y1 > y2){ + if(_entity[i-1]->pos[1] > _entity[i]->pos[1]){ swap=1; } } if(swap){ - Entity ent; + Entity *ent; ent=_entity[i]; _entity[i]=_entity[i-1]; _entity[i-1]=ent; @@ -313,11 +284,12 @@ void GameLib_ProcLoop(void *data){ n=n2; }while(n>0); + // PostProcess time=Time_GetTime(); GameLib_Compactate();_entities_lock=1; for(i=0;i<_n_entities;i++){ - Entity_PostProcess(_entity[i],_pft); + Entity_PostProcess(_entity[i],_ft); if(_entity[i]->flags&EntityFlag_UpdatedPos){ Entity_MarkUpdateLight(_entity[i],_entity,_n_entities); } @@ -329,6 +301,8 @@ void GameLib_ProcLoop(void *data){ t_postproc+=Time_GetTime()-time; fproc_count++; + + return(_running); } @@ -336,19 +310,20 @@ void GameLib_ProcLoop(void *data){ // GameLib_DrawLoop // // -void GameLib_DrawLoop(void *data, float f){ +void GameLib_DrawLoop(){ long long time; int i; - int game_pos[2]; - - game_pos[0]=_game_pos0[0]+f*(_game_pos1[0]-_game_pos0[0]); - game_pos[1]=_game_pos0[1]+f*(_game_pos1[1]-_game_pos0[1]); time=Time_GetTime(); + // Update Lights + //GameLib_UpdateIlumination(); + + + // Predibujado if(_gamepredraw){ - _gamepredraw(f); + _gamepredraw(); }else{ // Limpiar pantalla Draw_Clean(0,0,0); @@ -357,11 +332,11 @@ void GameLib_DrawLoop(void *data, float f){ // Draw entities GameLib_Compactate();_entities_lock=1; for(i=0;i<_n_entities;i++){ - Entity e=_entity[i]; + Entity *e=_entity[i]; // Check visivility if(!Entity_IsVisible(e, - game_pos[0],game_pos[1], + _game_pos[0],_game_pos[1], _game_size[0],_game_size[1])) { continue; @@ -373,37 +348,18 @@ void GameLib_DrawLoop(void *data, float f){ e->flags&=~EntityFlag_UpdateLight; } - Entity_Draw(e,-game_pos[0],-game_pos[1],f); + Entity_Draw(e,-_game_pos[0],-_game_pos[1]); } Draw_SetColor(1,1,1,1); if(_gamedraw){ - _gamedraw(f); + _gamedraw(); } GameLib_Compactate(); + t_draw+=Time_GetTime()-time; fdraw_count++; - - if(Input_GetKey(InputKey_DumpProfiling)==InputKey_Pressed){ - printf("Profiling:::::::::\n"); - if(fproc_count>0){ - printf("t_proc.....:%6lld\n",t_proc/fproc_count); - printf("t_col......:%6lld\n",t_col/fproc_count); - printf("t_over.....:%6lld\n",t_over/fproc_count); - printf("t_postproc.:%6lld\n",t_postproc/fproc_count); - } - if(fdraw_count>0){ - printf("t_draw.....:%6lld\n",t_draw/fdraw_count); - } - t_proc=0; - t_col=0; - t_over=0; - t_postproc=0; - t_draw=0; - fproc_count=0; - fdraw_count=0; - } } @@ -414,9 +370,11 @@ void GameLib_DrawLoop(void *data, float f){ void GameLib_Loop( void (*gameproc)(), void (*gamepostproc)(), - void (*gamepredraw)(float f), - void (*gamedraw)(float f)) + void (*gamepredraw)(), + void (*gamedraw)()) { + _running=1; + _gameproc=gameproc; _gamepostproc=gamepostproc; _gamepredraw=gamepredraw; @@ -428,30 +386,41 @@ void GameLib_Loop( t_draw=0; fproc_count=0; fdraw_count=0; - Draw_Loop(GameLib_ProcLoop,GameLib_DrawLoop,NULL); + Draw_Loop(GameLib_ProcLoop,GameLib_DrawLoop); + + if (gamelib_debug) { + printf("Profiling:::::::::\n"); + printf("t_proc.....:%6lld\n",t_proc/fproc_count); + printf("t_col......:%6lld\n",t_col/fproc_count); + printf("t_over.....:%6lld\n",t_over/fproc_count); + printf("t_postproc.:%6lld\n",t_postproc/fproc_count); + printf("t_draw.....:%6lld\n",t_draw/fdraw_count); + } +} + + +///////////////////////////// +// GameLib_BreakLoop +// +// Breaks the game loop. +void GameLib_BreakLoop(){ + _running=0; } ///////////////////////////// // GameLib_GetPos // GameLib_SetPos -// GameLib_UpdatePos // GameLib_SetPos // // void GameLib_GetPos(int pos[2]){ - pos[0]=_game_pos1[0]; - pos[1]=_game_pos1[1]; + pos[0]=_game_pos[0]; + pos[1]=_game_pos[1]; } void GameLib_SetPos(int pos[2]){ - _game_pos0[0]=pos[0]; - _game_pos0[1]=pos[1]; - _game_pos1[0]=pos[0]; - _game_pos1[1]=pos[1]; -} -void GameLib_UpdatePos(int pos[2]){ - _game_pos1[0]=pos[0]; - _game_pos1[1]=pos[1]; + _game_pos[0]=pos[0]; + _game_pos[1]=pos[1]; } void GameLib_GetSize(int size[2]){ size[0]=_game_size[0]; @@ -472,10 +441,10 @@ void GameLib_MoveToPos(vec2 pos,float f){ GameLib_MoveToPosV(pos,f); } void GameLib_MoveToPosH(vec2 pos,float f){ - _game_pos1[0]=_game_pos1[0]+(pos[0]-(_game_pos1[0]+(_game_size[0]/2.0f)))*f; + _game_pos[0]=_game_pos[0]+(pos[0]-(_game_pos[0]+(_game_size[0]/2.0f)))*f; } void GameLib_MoveToPosV(vec2 pos,float f){ - _game_pos1[1]=_game_pos1[1]+(pos[1]-(_game_pos1[1]+(_game_size[1]/2.0f)))*f; + _game_pos[1]=_game_pos[1]+(pos[1]-(_game_pos[1]+(_game_size[1]/2.0f)))*f; } @@ -501,7 +470,7 @@ void GameLib_DelEnts(){ // GameLib_ForEachEn // // Iterates every entity. -void GameLib_ForEachEnt(int (*func)(Entity ent)){ +void GameLib_ForEachEnt(int (*func)(Entity *ent)){ int i; for(i=0;i<_n_entities;i++){ if(!_entity[i]) @@ -513,25 +482,6 @@ void GameLib_ForEachEnt(int (*func)(Entity ent)){ } -///////////////////////////// -// GameLib_SearchEnt -// -// Searches throught the entities. -Entity GameLib_SearchEnt(int (*func)(Entity ent,void *d),void *d){ - int i; - Entity ent=NULL; - for(i=0;i<_n_entities;i++){ - if(!_entity[i]) - continue; - if(func(_entity[i],d)){ - ent=_entity[i]; - break; - } - } - return ent; -} - - ///////////////////////////// // GameLib_PlaySound // @@ -541,8 +491,8 @@ void GameLib_PlaySound(AudioSnd snd,int x,int y){ int r,cx,cy,off; // Get the screen context - cx=_game_pos1[0]+_game_size[0]/2; - cy=_game_pos1[1]+_game_size[1]/2; + cx=_game_pos[0]+_game_size[0]/2; + cy=_game_pos[1]+_game_size[1]/2; if(_game_size[0]>_game_size[1]){ r=_game_size[0]/2; }else{ @@ -590,7 +540,7 @@ void GameLib_Iluminate(){ // GameLib_EntitySetLight // // -void GameLib_EntitySetLight(Entity e,float r,float g,float b,float rad){ +void GameLib_EntitySetLight(Entity *e,float r,float g,float b,float rad){ if(e->flags&EntityFlag_Light){ Entity_MarkUpdateLight(e,_entity,_n_entities); Entity_SetLight(e,r,g,b,rad); diff --git a/GameLib/GameLib.h b/GameLib/GameLib.h index 49b7ca1..e44489f 100644 --- a/GameLib/GameLib.h +++ b/GameLib/GameLib.h @@ -23,21 +23,21 @@ int GameLib_Init(int w,int h,char *title,int pfps,int fps); // GameLib_AddEntity // // Adds an entity to the game. -void GameLib_AddEntity(Entity e); +void GameLib_AddEntity(Entity *e); ///////////////////////////// // GameLib_UnrefEntity // // removes the reference to the entity. -int GameLib_UnrefEntity(Entity e); +int GameLib_UnrefEntity(Entity *e); ///////////////////////////// // GameLib_DelEntity // // Adds an entity to the game. -int GameLib_DelEntity(Entity e); +int GameLib_DelEntity(Entity *e); ///////////////////////////// @@ -47,8 +47,15 @@ int GameLib_DelEntity(Entity e); void GameLib_Loop( void (*gameproc)(), void (*gamepostproc)(), - void (*gamepredraw)(float f), - void (*gamedraw)(float f)); + void (*gamepredraw)(), + void (*gamedraw)()); + + +///////////////////////////// +// GameLib_BreakLoop +// +// Breaks the game loop. +void GameLib_BreakLoop(); ///////////////////////////// @@ -81,17 +88,10 @@ void GameLib_DelEnts(); ///////////////////////////// -// GameLib_ForEachEnt +// GameLib_ForEachEn // // Iterates every entity. -void GameLib_ForEachEnt(int (*func)(Entity ent)); - - -///////////////////////////// -// GameLib_SearchEnt -// -// Searches throught the entities. -Entity GameLib_SearchEnt(int (*func)(Entity ent,void *d),void *d); +void GameLib_ForEachEnt(int (*func)(Entity *ent)); ///////////////////////////// @@ -112,7 +112,7 @@ void GameLib_Iluminate(); // GameLib_EntitySetLight // // -void GameLib_EntitySetLight(Entity e,float r,float g,float b,float rad); +void GameLib_EntitySetLight(Entity *e,float r,float g,float b,float rad); ///////////////////////////// diff --git a/GameLib/Input.c b/GameLib/Input.c index 3096542..15c4bb6 100644 --- a/GameLib/Input.c +++ b/GameLib/Input.c @@ -2,21 +2,15 @@ #include #include -#ifdef EMSCRIPTEN -#define SDL_GetKeyState SDL_GetKeyboardState -#endif #include "Util.h" #include "Input.h" - // Globals InputKeyStatus _keys[InputKey_Max]; -int _pointerDown=0; SDL_Joystick *_joy; - ///////////////////////////// // Input_Init // @@ -62,10 +56,8 @@ int Input_Init(){ void Input_Frame(){ Uint8* keys; - // Get keyboard state - keys=(Uint8 *)SDL_GetKeyState(NULL); - // Process Keys + keys=SDL_GetKeyState(NULL); Input_SetKey(InputKey_Action1,keys[SDLK_z]); Input_SetKey(InputKey_Action2,keys[SDLK_x]); Input_SetKey(InputKey_Up,keys[SDLK_UP]); @@ -73,9 +65,7 @@ void Input_Frame(){ Input_SetKey(InputKey_Left,keys[SDLK_LEFT]); Input_SetKey(InputKey_Right,keys[SDLK_RIGHT]); Input_SetKey(InputKey_Jump,keys[SDLK_SPACE]); - Input_SetKey(InputKey_Continue,keys[SDLK_RETURN]|keys[SDLK_KP_ENTER]|_pointerDown); - - Input_SetKey(InputKey_DumpProfiling,keys[SDLK_p]); + Input_SetKey(InputKey_Continue,keys[SDLK_RETURN]|keys[SDLK_KP_ENTER]); } @@ -105,14 +95,6 @@ InputKeyStatus Input_GetKey(InputKey key){ } -///////////////////////////// -// Input_SetPointerDown -// -void Input_SetPointerDown(int pointerDown){ - _pointerDown=pointerDown; -} - - ///////////////////////////// // Input_AnyKey // diff --git a/GameLib/Input.h b/GameLib/Input.h index ac9240b..dfe41fd 100644 --- a/GameLib/Input.h +++ b/GameLib/Input.h @@ -33,10 +33,6 @@ typedef enum { InputKey_Right, InputKey_Jump, InputKey_Continue, - InputKey_Exit, - - InputKey_DumpProfiling, - InputKey_Max } InputKey; @@ -66,12 +62,6 @@ typedef enum { InputKeyStatus Input_GetKey(InputKey key); -///////////////////////////// -// Input_SetPointerDown -// -void Input_SetPointerDown(int pointerDown); - - ///////////////////////////// // Input_AnyKey // diff --git a/GameLib/QuadArray2D.c b/GameLib/QuadArray2D.c deleted file mode 100644 index ff98778..0000000 --- a/GameLib/QuadArray2D.c +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (C) 2013 Valeriano Alfonso Rodriguez (Kableado) - -#include -#include -#include - -#include "QuadArray2D.h" - - -QuadArray2D QuadArray2D_Create(int resVertex){ - QuadArray2D quadArray=NULL; - - quadArray=malloc(sizeof(TQuadArray2D)); - - quadArray->vertexData=malloc(sizeof(float)*Vertex2D_Length*resVertex); - quadArray->nVertex=0; - quadArray->resVertex=resVertex; - - return quadArray; -} - -void QuadArray2D_Destroy(QuadArray2D *quadArray){ - if(!quadArray) return; - if(!quadArray[0]) return; - - free(quadArray[0]->vertexData); - free(quadArray[0]); - quadArray[0]=NULL; -} - -void QuadArray2D_Clean(QuadArray2D quadArray){ - quadArray->nVertex=0; -} - -void QuadArray2D_AddVertex(QuadArray2D quadArray,float v[]){ - if(quadArray->resVertex<=quadArray->nVertex){ - // Grow vertexData - quadArray->resVertex*=2; - float *newVertexData=malloc(sizeof(float)*Vertex2D_Length* - quadArray->resVertex); - memcpy(newVertexData,quadArray->vertexData, - sizeof(float)*Vertex2D_Length*quadArray->nVertex); - free(quadArray->vertexData); - quadArray->vertexData=newVertexData; - } - - // Add the vertex - memcpy( - quadArray->vertexData+ - (Vertex2D_Length*quadArray->nVertex), - v,sizeof(float)*Vertex2D_Length); - quadArray->nVertex++; -} - -void QuadArray2D_AddQuad(QuadArray2D quadArray, - float x0, float y0,float u0, float v0, - float x1, float y1,float u1, float v1, - float color[]) -{ - float v[Vertex2D_Length]; - int firstIndex=quadArray->nVertex; - - // Set the color - v[4]=color[0]; - v[5]=color[1]; - v[6]=color[2]; - v[7]=color[3]; - - // Add the vertexes - v[0]=x0; v[1]=y0; v[2]=u0; v[3]=v0; QuadArray2D_AddVertex(quadArray,v); - v[0]=x1; v[1]=y0; v[2]=u1; v[3]=v0; QuadArray2D_AddVertex(quadArray,v); - v[0]=x1; v[1]=y1; v[2]=u1; v[3]=v1; QuadArray2D_AddVertex(quadArray,v); - - v[0]=x1; v[1]=y1; v[2]=u1; v[3]=v1; QuadArray2D_AddVertex(quadArray,v); - v[0]=x0; v[1]=y1; v[2]=u0; v[3]=v1; QuadArray2D_AddVertex(quadArray,v); - v[0]=x0; v[1]=y0; v[2]=u0; v[3]=v0; QuadArray2D_AddVertex(quadArray,v); -} - diff --git a/GameLib/QuadArray2D.h b/GameLib/QuadArray2D.h deleted file mode 100644 index 716424b..0000000 --- a/GameLib/QuadArray2D.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2013 Valeriano Alfonso Rodriguez (Kableado) - -#ifndef _QUADARRAY2D_H_ -#define _QUADARRAY2D_H_ - -// Vertex2D -> (x,y) (u,v) (r,g,b,a) -#define Vertex2D_Length 8 - - -//////////////////////////////////////////////// -// QuadArray2D -// -typedef struct TQuadArray2D TQuadArray2D, *QuadArray2D; -struct TQuadArray2D { - float *vertexData; - int nVertex; - int resVertex; -}; - - -QuadArray2D QuadArray2D_Create(int resVertex); - -void QuadArray2D_Destroy(QuadArray2D *quadArray); - -void QuadArray2D_Clean(QuadArray2D quadArray); - -void QuadArray2D_AddVertex(QuadArray2D quadArray,float v[]); - -void QuadArray2D_AddQuad(QuadArray2D quadArray, - float x0, float y0,float u0, float v0, - float x1, float y1,float u1, float v1, - float color[]); - -#endif - diff --git a/GameLib/Time.c b/GameLib/Time.c index 7762d44..a1c9af8 100644 --- a/GameLib/Time.c +++ b/GameLib/Time.c @@ -1,10 +1,11 @@ -// Copyright (C) 2011-2014 Valeriano Alfonso Rodriguez (Kableado) +// Copyright (C) 2011 Valeriano Alfonso Rodriguez (Kableado) #include #include #include #include #include +#include #include "Time.h" @@ -37,7 +38,7 @@ void Time_Pause(int pausa){ do{ diff=tend-t; if(diff>1000){ - Sleep(diff/1000); + SDL_Delay(diff/1000); }else{ Sleep(0); } @@ -45,6 +46,25 @@ void Time_Pause(int pausa){ }while(tend>=t); } #else +#ifdef MACOSX +#include +// MacOSX +long long Time_GetTime(){ + static mach_timebase_info_data_t info = {0,0}; + uint64_t t; + if(info.denom==0){ + mach_timebase_info(&info); + } + t=mach_absolute_time()*(info.numer / info.denom); + return(t/1000); +} +void Time_Pause(int pausa){ + struct timeval tv; + tv.tv_sec=(long long)pausa/1000000; + tv.tv_usec=(long long)pausa%1000000; + select(0, NULL, NULL, NULL, &tv); +} +#else // UNIX long long Time_GetTime(){ struct timeval t; @@ -59,6 +79,7 @@ void Time_Pause(int pausa){ tv.tv_usec=(long long)pausa%1000000; select(0, NULL, NULL, NULL, &tv); } +#endif // if MACOSX #endif // if WIN32 diff --git a/GameLib/Util.c b/GameLib/Util.c index 6269994..2939389 100644 --- a/GameLib/Util.c +++ b/GameLib/Util.c @@ -1,8 +1,6 @@ // Copyright (C) 2011 Valeriano Alfonso Rodriguez (Kableado) #include -#include -#include #include "Util.h" @@ -17,60 +15,6 @@ float vec2_norm(vec2 v){ return(len); } -void vec2_orthogonalize4(vec2 v) { - if (fabs(v[0]) > fabs(v[1])) { - if (v[0] >= 0) { - v[0] = 1.0f; - v[1] = 0.0f; - } else { - v[0] = -1.0f; - v[1] = 0.0f; - } - } else { - if (v[1] >= 0) { - v[1] = 1.0f; - v[0] = 0.0f; - } else { - v[1] = -1.0f; - v[0] = 0.0f; - } - } -} - -void vec2_orthogonalize8(vec2 v) { - float diff = fabs(fabs(v[0]) - fabs(v[1])); - if (diff > 0.2f) { - if (fabs(v[0]) > fabs(v[1])) { - if (v[0] >= 0) { - v[0] = 1.0f; - v[1] = 0.0f; - } else { - v[0] = -1.0f; - v[1] = 0.0f; - } - } else { - if (v[1] >= 0) { - v[1] = 1.0f; - v[0] = 0.0f; - } else { - v[1] = -1.0f; - v[0] = 0.0f; - } - } - } else { - if (v[0] > 0.0f) { - v[0] = 0.707f; - } else { - v[0] = -0.707f; - } - if (v[1] > 0.0f) { - v[1] = 0.707f; - } else { - v[1] = -0.707f; - } - } -} - ///////////////////////////// // SolveQuadratic @@ -176,9 +120,10 @@ int Colision_CircleCircle( vec2_scale(cen_a,cir2,invrads); if(Intersec_RayUnitCircle(orig_a,vel_a,cen_a,t)){ // Calculate n - vec2_scaleadd(temp,cir1,vel,*t); - vec2_minus(n,temp,cir2); - vec2_scale(n,n,invrads); + vec2_scale(temp,vel,*t); + vec2_plus(temp,cir1,temp); + vec2_minus(temp,cir2,temp); + vec2_scale(n,temp,1.0f/rads); return(1); } return(0); @@ -243,6 +188,7 @@ int absmod(int v,int d){ return(v%d); } } + float fabsmod(float v,int d){ if(v<0){ v+=d*((((int)(v/d))*(-1))+1); @@ -254,29 +200,4 @@ float fabsmod(float v,int d){ } -///////////////////////////// -// IsBigEndian -// -int IsBigEndian(){ - union{ - unsigned int i; - char c[4]; - } bint={0x01020304}; - return bint.c[0]==1; -} - - -///////////////////////////// -// EndsWith -// -int EndsWith(char *str, char *suffix){ - if (!str || !suffix) - return 0; - int lenStr = strlen(str); - int lenSuffix = strlen(suffix); - if (lenSuffix > lenStr) - return 0; - return strncmp(str+lenStr-lenSuffix, suffix, lenSuffix)==0; -} - diff --git a/GameLib/Util.h b/GameLib/Util.h index dcc4033..1a6a74e 100644 --- a/GameLib/Util.h +++ b/GameLib/Util.h @@ -26,12 +26,6 @@ typedef float vec2[2]; #define vec2_perp(v,n) (v)[0]=-(n)[1];(v)[1]=(n)[0]; #define vec2_scaleadd(v,v1,v2,s) (v)[0]=(v2)[0]*(s)+(v1)[0];(v)[1]=(v2)[1]*(s)+(v1)[1]; float vec2_norm(vec2 v); -#define vec2_interpol(v,v1,v2,f) \ - (v)[0]=(v1)[0]-f*((v1)[0]-(v2)[0]);\ - (v)[1]=(v1)[1]-f*((v1)[1]-(v2)[1]); -void vec2_orthogonalize4(vec2 v); -void vec2_orthogonalize8(vec2 v); - ///////////////////////////// @@ -40,7 +34,6 @@ void vec2_orthogonalize8(vec2 v); // Intersection between a ray and a Unit Circle. int Intersec_RayUnitCircle(vec2 orig,vec2 vel,vec2 center,float *t); - ///////////////////////////// // Intersect_CircleCircle // @@ -50,7 +43,6 @@ int Colision_CircleCircle( vec2 cb,float rb, float *t,vec2 n); - ///////////////////////////// // Intersect_RayEdge // @@ -61,6 +53,7 @@ int Intersect_RayEdge( float *t); + ///////////////////////////// // absmod // @@ -68,16 +61,4 @@ int absmod(int v,int d); float fabsmod(float v,int d); -///////////////////////////// -// IsBigEndian -// -int IsBigEndian(); - - -///////////////////////////// -// EndsWith -// -int EndsWith(char *str, char *suffix); - - #endif diff --git a/GameLib/lodepng.c b/GameLib/lodepng.c deleted file mode 100644 index bcc009f..0000000 --- a/GameLib/lodepng.c +++ /dev/null @@ -1,6285 +0,0 @@ -/* -LodePNG version 20140624 - -Copyright (c) 2005-2014 Lode Vandevenne - -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. -*/ - -/* -The manual and changelog are in the header file "lodepng.h" -Rename this file to lodepng.cpp to use it for C++, or to lodepng.c to use it for C. -*/ - -#include "lodepng.h" - -#include -#include - -#ifdef LODEPNG_COMPILE_CPP -#include -#endif /*LODEPNG_COMPILE_CPP*/ - -#define VERSION_STRING "20140624" - -#if (_MSC_VER >= 1310) /*Visual Studio: Kept warning-free but a few warning types are not desired here.*/ -#pragma warning( disable : 4244 ) /*implicit conversions: not warned by gcc -Wall -Wextra and requires too much casts*/ -#pragma warning( disable : 4996 ) /*VS does not like fopen, but fopen_s is not standard C so unusable here*/ -#endif /*_MSC_VER >= 1310*/ - -/* -This source file is built up in the following large parts. The code sections -with the "LODEPNG_COMPILE_" #defines divide this up further in an intermixed way. --Tools for C and common code for PNG and Zlib --C Code for Zlib (huffman, deflate, ...) --C Code for PNG (file format chunks, adam7, PNG filters, color conversions, ...) --The C++ wrapper around all of the above -*/ - -/*The malloc, realloc and free functions defined here with "lodepng_" in front -of the name, so that you can easily change them to others related to your -platform if needed. Everything else in the code calls these. Pass --DLODEPNG_NO_COMPILE_ALLOCATORS to the compiler, or comment out -#define LODEPNG_COMPILE_ALLOCATORS in the header, to disable the ones here and -define them in your own project's source files without needing to change -lodepng source code. Don't forget to remove "static" if you copypaste them -from here.*/ - -#ifdef LODEPNG_COMPILE_ALLOCATORS -static void* lodepng_malloc(size_t size) -{ - return malloc(size); -} - -static void* lodepng_realloc(void* ptr, size_t new_size) -{ - return realloc(ptr, new_size); -} - -static void lodepng_free(void* ptr) -{ - free(ptr); -} -#else /*LODEPNG_COMPILE_ALLOCATORS*/ -void* lodepng_malloc(size_t size); -void* lodepng_realloc(void* ptr, size_t new_size); -void lodepng_free(void* ptr); -#endif /*LODEPNG_COMPILE_ALLOCATORS*/ - -/* ////////////////////////////////////////////////////////////////////////// */ -/* ////////////////////////////////////////////////////////////////////////// */ -/* // Tools for C, and common code for PNG and Zlib. // */ -/* ////////////////////////////////////////////////////////////////////////// */ -/* ////////////////////////////////////////////////////////////////////////// */ - -/* -Often in case of an error a value is assigned to a variable and then it breaks -out of a loop (to go to the cleanup phase of a function). This macro does that. -It makes the error handling code shorter and more readable. - -Example: if(!uivector_resizev(&frequencies_ll, 286, 0)) ERROR_BREAK(83); -*/ -#define CERROR_BREAK(errorvar, code)\ -{\ - errorvar = code;\ - break;\ -} - -/*version of CERROR_BREAK that assumes the common case where the error variable is named "error"*/ -#define ERROR_BREAK(code) CERROR_BREAK(error, code) - -/*Set error var to the error code, and return it.*/ -#define CERROR_RETURN_ERROR(errorvar, code)\ -{\ - errorvar = code;\ - return code;\ -} - -/*Try the code, if it returns error, also return the error.*/ -#define CERROR_TRY_RETURN(call)\ -{\ - unsigned error = call;\ - if(error) return error;\ -} - -/* -About uivector, ucvector and string: --All of them wrap dynamic arrays or text strings in a similar way. --LodePNG was originally written in C++. The vectors replace the std::vectors that were used in the C++ version. --The string tools are made to avoid problems with compilers that declare things like strncat as deprecated. --They're not used in the interface, only internally in this file as static functions. --As with many other structs in this file, the init and cleanup functions serve as ctor and dtor. -*/ - -#ifdef LODEPNG_COMPILE_ZLIB -/*dynamic vector of unsigned ints*/ -typedef struct uivector -{ - unsigned* data; - size_t size; /*size in number of unsigned longs*/ - size_t allocsize; /*allocated size in bytes*/ -} uivector; - -static void uivector_cleanup(void* p) -{ - ((uivector*)p)->size = ((uivector*)p)->allocsize = 0; - lodepng_free(((uivector*)p)->data); - ((uivector*)p)->data = NULL; -} - -/*returns 1 if success, 0 if failure ==> nothing done*/ -static unsigned uivector_resize(uivector* p, size_t size) -{ - if(size * sizeof(unsigned) > p->allocsize) - { - size_t newsize = size * sizeof(unsigned) * 2; - void* data = lodepng_realloc(p->data, newsize); - if(data) - { - p->allocsize = newsize; - p->data = (unsigned*)data; - p->size = size; - } - else return 0; - } - else p->size = size; - return 1; -} - -/*resize and give all new elements the value*/ -static unsigned uivector_resizev(uivector* p, size_t size, unsigned value) -{ - size_t oldsize = p->size, i; - if(!uivector_resize(p, size)) return 0; - for(i = oldsize; i < size; i++) p->data[i] = value; - return 1; -} - -static void uivector_init(uivector* p) -{ - p->data = NULL; - p->size = p->allocsize = 0; -} - -#ifdef LODEPNG_COMPILE_ENCODER -/*returns 1 if success, 0 if failure ==> nothing done*/ -static unsigned uivector_push_back(uivector* p, unsigned c) -{ - if(!uivector_resize(p, p->size + 1)) return 0; - p->data[p->size - 1] = c; - return 1; -} - -/*copy q to p, returns 1 if success, 0 if failure ==> nothing done*/ -static unsigned uivector_copy(uivector* p, const uivector* q) -{ - size_t i; - if(!uivector_resize(p, q->size)) return 0; - for(i = 0; i < q->size; i++) p->data[i] = q->data[i]; - return 1; -} -#endif /*LODEPNG_COMPILE_ENCODER*/ -#endif /*LODEPNG_COMPILE_ZLIB*/ - -/* /////////////////////////////////////////////////////////////////////////// */ - -/*dynamic vector of unsigned chars*/ -typedef struct ucvector -{ - unsigned char* data; - size_t size; /*used size*/ - size_t allocsize; /*allocated size*/ -} ucvector; - -/*returns 1 if success, 0 if failure ==> nothing done*/ -static unsigned ucvector_resize(ucvector* p, size_t size) -{ - if(size * sizeof(unsigned char) > p->allocsize) - { - size_t newsize = size * sizeof(unsigned char) * 2; - void* data = lodepng_realloc(p->data, newsize); - if(data) - { - p->allocsize = newsize; - p->data = (unsigned char*)data; - p->size = size; - } - else return 0; /*error: not enough memory*/ - } - else p->size = size; - return 1; -} - -#ifdef LODEPNG_COMPILE_PNG - -static void ucvector_cleanup(void* p) -{ - ((ucvector*)p)->size = ((ucvector*)p)->allocsize = 0; - lodepng_free(((ucvector*)p)->data); - ((ucvector*)p)->data = NULL; -} - -static void ucvector_init(ucvector* p) -{ - p->data = NULL; - p->size = p->allocsize = 0; -} - -#ifdef LODEPNG_COMPILE_DECODER -/*resize and give all new elements the value*/ -static unsigned ucvector_resizev(ucvector* p, size_t size, unsigned char value) -{ - size_t oldsize = p->size, i; - if(!ucvector_resize(p, size)) return 0; - for(i = oldsize; i < size; i++) p->data[i] = value; - return 1; -} -#endif /*LODEPNG_COMPILE_DECODER*/ -#endif /*LODEPNG_COMPILE_PNG*/ - -#ifdef LODEPNG_COMPILE_ZLIB -/*you can both convert from vector to buffer&size and vica versa. If you use -init_buffer to take over a buffer and size, it is not needed to use cleanup*/ -static void ucvector_init_buffer(ucvector* p, unsigned char* buffer, size_t size) -{ - p->data = buffer; - p->allocsize = p->size = size; -} -#endif /*LODEPNG_COMPILE_ZLIB*/ - -#if (defined(LODEPNG_COMPILE_PNG) && defined(LODEPNG_COMPILE_ANCILLARY_CHUNKS)) || defined(LODEPNG_COMPILE_ENCODER) -/*returns 1 if success, 0 if failure ==> nothing done*/ -static unsigned ucvector_push_back(ucvector* p, unsigned char c) -{ - if(!ucvector_resize(p, p->size + 1)) return 0; - p->data[p->size - 1] = c; - return 1; -} -#endif /*defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_ENCODER)*/ - - -/* ////////////////////////////////////////////////////////////////////////// */ - -#ifdef LODEPNG_COMPILE_PNG -#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS -/*returns 1 if success, 0 if failure ==> nothing done*/ -static unsigned string_resize(char** out, size_t size) -{ - char* data = (char*)lodepng_realloc(*out, size + 1); - if(data) - { - data[size] = 0; /*null termination char*/ - *out = data; - } - return data != 0; -} - -/*init a {char*, size_t} pair for use as string*/ -static void string_init(char** out) -{ - *out = NULL; - string_resize(out, 0); -} - -/*free the above pair again*/ -static void string_cleanup(char** out) -{ - lodepng_free(*out); - *out = NULL; -} - -static void string_set(char** out, const char* in) -{ - size_t insize = strlen(in), i = 0; - if(string_resize(out, insize)) - { - for(i = 0; i < insize; i++) - { - (*out)[i] = in[i]; - } - } -} -#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ -#endif /*LODEPNG_COMPILE_PNG*/ - -/* ////////////////////////////////////////////////////////////////////////// */ - -unsigned lodepng_read32bitInt(const unsigned char* buffer) -{ - return (unsigned)((buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3]); -} - -#if defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_ENCODER) -/*buffer must have at least 4 allocated bytes available*/ -static void lodepng_set32bitInt(unsigned char* buffer, unsigned value) -{ - buffer[0] = (unsigned char)((value >> 24) & 0xff); - buffer[1] = (unsigned char)((value >> 16) & 0xff); - buffer[2] = (unsigned char)((value >> 8) & 0xff); - buffer[3] = (unsigned char)((value ) & 0xff); -} -#endif /*defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_ENCODER)*/ - -#ifdef LODEPNG_COMPILE_ENCODER -static void lodepng_add32bitInt(ucvector* buffer, unsigned value) -{ - ucvector_resize(buffer, buffer->size + 4); /*todo: give error if resize failed*/ - lodepng_set32bitInt(&buffer->data[buffer->size - 4], value); -} -#endif /*LODEPNG_COMPILE_ENCODER*/ - -/* ////////////////////////////////////////////////////////////////////////// */ -/* / File IO / */ -/* ////////////////////////////////////////////////////////////////////////// */ - -#ifdef LODEPNG_COMPILE_DISK - -unsigned lodepng_load_file(unsigned char** out, size_t* outsize, const char* filename) -{ - FILE* file; - long size; - - /*provide some proper output values if error will happen*/ - *out = 0; - *outsize = 0; - - file = fopen(filename, "rb"); - if(!file) return 78; - - /*get filesize:*/ - fseek(file , 0 , SEEK_END); - size = ftell(file); - rewind(file); - - /*read contents of the file into the vector*/ - *outsize = 0; - *out = (unsigned char*)lodepng_malloc((size_t)size); - if(size && (*out)) (*outsize) = fread(*out, 1, (size_t)size, file); - - fclose(file); - if(!(*out) && size) return 83; /*the above malloc failed*/ - return 0; -} - -/*write given buffer to the file, overwriting the file, it doesn't append to it.*/ -unsigned lodepng_save_file(const unsigned char* buffer, size_t buffersize, const char* filename) -{ - FILE* file; - file = fopen(filename, "wb" ); - if(!file) return 79; - fwrite((char*)buffer , 1 , buffersize, file); - fclose(file); - return 0; -} - -#endif /*LODEPNG_COMPILE_DISK*/ - -/* ////////////////////////////////////////////////////////////////////////// */ -/* ////////////////////////////////////////////////////////////////////////// */ -/* // End of common code and tools. Begin of Zlib related code. // */ -/* ////////////////////////////////////////////////////////////////////////// */ -/* ////////////////////////////////////////////////////////////////////////// */ - -#ifdef LODEPNG_COMPILE_ZLIB -#ifdef LODEPNG_COMPILE_ENCODER -/*TODO: this ignores potential out of memory errors*/ -#define addBitToStream(/*size_t**/ bitpointer, /*ucvector**/ bitstream, /*unsigned char*/ bit)\ -{\ - /*add a new byte at the end*/\ - if(((*bitpointer) & 7) == 0) ucvector_push_back(bitstream, (unsigned char)0);\ - /*earlier bit of huffman code is in a lesser significant bit of an earlier byte*/\ - (bitstream->data[bitstream->size - 1]) |= (bit << ((*bitpointer) & 0x7));\ - (*bitpointer)++;\ -} - -static void addBitsToStream(size_t* bitpointer, ucvector* bitstream, unsigned value, size_t nbits) -{ - size_t i; - for(i = 0; i < nbits; i++) addBitToStream(bitpointer, bitstream, (unsigned char)((value >> i) & 1)); -} - -static void addBitsToStreamReversed(size_t* bitpointer, ucvector* bitstream, unsigned value, size_t nbits) -{ - size_t i; - for(i = 0; i < nbits; i++) addBitToStream(bitpointer, bitstream, (unsigned char)((value >> (nbits - 1 - i)) & 1)); -} -#endif /*LODEPNG_COMPILE_ENCODER*/ - -#ifdef LODEPNG_COMPILE_DECODER - -#define READBIT(bitpointer, bitstream) ((bitstream[bitpointer >> 3] >> (bitpointer & 0x7)) & (unsigned char)1) - -static unsigned char readBitFromStream(size_t* bitpointer, const unsigned char* bitstream) -{ - unsigned char result = (unsigned char)(READBIT(*bitpointer, bitstream)); - (*bitpointer)++; - return result; -} - -static unsigned readBitsFromStream(size_t* bitpointer, const unsigned char* bitstream, size_t nbits) -{ - unsigned result = 0, i; - for(i = 0; i < nbits; i++) - { - result += ((unsigned)READBIT(*bitpointer, bitstream)) << i; - (*bitpointer)++; - } - return result; -} -#endif /*LODEPNG_COMPILE_DECODER*/ - -/* ////////////////////////////////////////////////////////////////////////// */ -/* / Deflate - Huffman / */ -/* ////////////////////////////////////////////////////////////////////////// */ - -#define FIRST_LENGTH_CODE_INDEX 257 -#define LAST_LENGTH_CODE_INDEX 285 -/*256 literals, the end code, some length codes, and 2 unused codes*/ -#define NUM_DEFLATE_CODE_SYMBOLS 288 -/*the distance codes have their own symbols, 30 used, 2 unused*/ -#define NUM_DISTANCE_SYMBOLS 32 -/*the code length codes. 0-15: code lengths, 16: copy previous 3-6 times, 17: 3-10 zeros, 18: 11-138 zeros*/ -#define NUM_CODE_LENGTH_CODES 19 - -/*the base lengths represented by codes 257-285*/ -static const unsigned LENGTHBASE[29] - = {3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, - 67, 83, 99, 115, 131, 163, 195, 227, 258}; - -/*the extra bits used by codes 257-285 (added to base length)*/ -static const unsigned LENGTHEXTRA[29] - = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, - 4, 4, 4, 4, 5, 5, 5, 5, 0}; - -/*the base backwards distances (the bits of distance codes appear after length codes and use their own huffman tree)*/ -static const unsigned DISTANCEBASE[30] - = {1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, - 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577}; - -/*the extra bits of backwards distances (added to base)*/ -static const unsigned DISTANCEEXTRA[30] - = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, - 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; - -/*the order in which "code length alphabet code lengths" are stored, out of this -the huffman tree of the dynamic huffman tree lengths is generated*/ -static const unsigned CLCL_ORDER[NUM_CODE_LENGTH_CODES] - = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - -/* ////////////////////////////////////////////////////////////////////////// */ - -/* -Huffman tree struct, containing multiple representations of the tree -*/ -typedef struct HuffmanTree -{ - unsigned* tree2d; - unsigned* tree1d; - unsigned* lengths; /*the lengths of the codes of the 1d-tree*/ - unsigned maxbitlen; /*maximum number of bits a single code can get*/ - unsigned numcodes; /*number of symbols in the alphabet = number of codes*/ -} HuffmanTree; - -/*function used for debug purposes to draw the tree in ascii art with C++*/ -/* -static void HuffmanTree_draw(HuffmanTree* tree) -{ - std::cout << "tree. length: " << tree->numcodes << " maxbitlen: " << tree->maxbitlen << std::endl; - for(size_t i = 0; i < tree->tree1d.size; i++) - { - if(tree->lengths.data[i]) - std::cout << i << " " << tree->tree1d.data[i] << " " << tree->lengths.data[i] << std::endl; - } - std::cout << std::endl; -}*/ - -static void HuffmanTree_init(HuffmanTree* tree) -{ - tree->tree2d = 0; - tree->tree1d = 0; - tree->lengths = 0; -} - -static void HuffmanTree_cleanup(HuffmanTree* tree) -{ - lodepng_free(tree->tree2d); - lodepng_free(tree->tree1d); - lodepng_free(tree->lengths); -} - -/*the tree representation used by the decoder. return value is error*/ -static unsigned HuffmanTree_make2DTree(HuffmanTree* tree) -{ - unsigned nodefilled = 0; /*up to which node it is filled*/ - unsigned treepos = 0; /*position in the tree (1 of the numcodes columns)*/ - unsigned n, i; - - tree->tree2d = (unsigned*)lodepng_malloc(tree->numcodes * 2 * sizeof(unsigned)); - if(!tree->tree2d) return 83; /*alloc fail*/ - - /* - convert tree1d[] to tree2d[][]. In the 2D array, a value of 32767 means - uninited, a value >= numcodes is an address to another bit, a value < numcodes - is a code. The 2 rows are the 2 possible bit values (0 or 1), there are as - many columns as codes - 1. - A good huffmann tree has N * 2 - 1 nodes, of which N - 1 are internal nodes. - Here, the internal nodes are stored (what their 0 and 1 option point to). - There is only memory for such good tree currently, if there are more nodes - (due to too long length codes), error 55 will happen - */ - for(n = 0; n < tree->numcodes * 2; n++) - { - tree->tree2d[n] = 32767; /*32767 here means the tree2d isn't filled there yet*/ - } - - for(n = 0; n < tree->numcodes; n++) /*the codes*/ - { - for(i = 0; i < tree->lengths[n]; i++) /*the bits for this code*/ - { - unsigned char bit = (unsigned char)((tree->tree1d[n] >> (tree->lengths[n] - i - 1)) & 1); - if(treepos > tree->numcodes - 2) return 55; /*oversubscribed, see comment in lodepng_error_text*/ - if(tree->tree2d[2 * treepos + bit] == 32767) /*not yet filled in*/ - { - if(i + 1 == tree->lengths[n]) /*last bit*/ - { - tree->tree2d[2 * treepos + bit] = n; /*put the current code in it*/ - treepos = 0; - } - else - { - /*put address of the next step in here, first that address has to be found of course - (it's just nodefilled + 1)...*/ - nodefilled++; - /*addresses encoded with numcodes added to it*/ - tree->tree2d[2 * treepos + bit] = nodefilled + tree->numcodes; - treepos = nodefilled; - } - } - else treepos = tree->tree2d[2 * treepos + bit] - tree->numcodes; - } - } - - for(n = 0; n < tree->numcodes * 2; n++) - { - if(tree->tree2d[n] == 32767) tree->tree2d[n] = 0; /*remove possible remaining 32767's*/ - } - - return 0; -} - -/* -Second step for the ...makeFromLengths and ...makeFromFrequencies functions. -numcodes, lengths and maxbitlen must already be filled in correctly. return -value is error. -*/ -static unsigned HuffmanTree_makeFromLengths2(HuffmanTree* tree) -{ - uivector blcount; - uivector nextcode; - unsigned bits, n, error = 0; - - uivector_init(&blcount); - uivector_init(&nextcode); - - tree->tree1d = (unsigned*)lodepng_malloc(tree->numcodes * sizeof(unsigned)); - if(!tree->tree1d) error = 83; /*alloc fail*/ - - if(!uivector_resizev(&blcount, tree->maxbitlen + 1, 0) - || !uivector_resizev(&nextcode, tree->maxbitlen + 1, 0)) - error = 83; /*alloc fail*/ - - if(!error) - { - /*step 1: count number of instances of each code length*/ - for(bits = 0; bits < tree->numcodes; bits++) blcount.data[tree->lengths[bits]]++; - /*step 2: generate the nextcode values*/ - for(bits = 1; bits <= tree->maxbitlen; bits++) - { - nextcode.data[bits] = (nextcode.data[bits - 1] + blcount.data[bits - 1]) << 1; - } - /*step 3: generate all the codes*/ - for(n = 0; n < tree->numcodes; n++) - { - if(tree->lengths[n] != 0) tree->tree1d[n] = nextcode.data[tree->lengths[n]]++; - } - } - - uivector_cleanup(&blcount); - uivector_cleanup(&nextcode); - - if(!error) return HuffmanTree_make2DTree(tree); - else return error; -} - -/* -given the code lengths (as stored in the PNG file), generate the tree as defined -by Deflate. maxbitlen is the maximum bits that a code in the tree can have. -return value is error. -*/ -static unsigned HuffmanTree_makeFromLengths(HuffmanTree* tree, const unsigned* bitlen, - size_t numcodes, unsigned maxbitlen) -{ - unsigned i; - tree->lengths = (unsigned*)lodepng_malloc(numcodes * sizeof(unsigned)); - if(!tree->lengths) return 83; /*alloc fail*/ - for(i = 0; i < numcodes; i++) tree->lengths[i] = bitlen[i]; - tree->numcodes = (unsigned)numcodes; /*number of symbols*/ - tree->maxbitlen = maxbitlen; - return HuffmanTree_makeFromLengths2(tree); -} - -#ifdef LODEPNG_COMPILE_ENCODER - -/* -A coin, this is the terminology used for the package-merge algorithm and the -coin collector's problem. This is used to generate the huffman tree. -A coin can be multiple coins (when they're merged) -*/ -typedef struct Coin -{ - uivector symbols; - float weight; /*the sum of all weights in this coin*/ -} Coin; - -static void coin_init(Coin* c) -{ - uivector_init(&c->symbols); -} - -/*argument c is void* so that this dtor can be given as function pointer to the vector resize function*/ -static void coin_cleanup(void* c) -{ - uivector_cleanup(&((Coin*)c)->symbols); -} - -static void coin_copy(Coin* c1, const Coin* c2) -{ - c1->weight = c2->weight; - uivector_copy(&c1->symbols, &c2->symbols); -} - -static void add_coins(Coin* c1, const Coin* c2) -{ - size_t i; - for(i = 0; i < c2->symbols.size; i++) uivector_push_back(&c1->symbols, c2->symbols.data[i]); - c1->weight += c2->weight; -} - -static void init_coins(Coin* coins, size_t num) -{ - size_t i; - for(i = 0; i < num; i++) coin_init(&coins[i]); -} - -static void cleanup_coins(Coin* coins, size_t num) -{ - size_t i; - for(i = 0; i < num; i++) coin_cleanup(&coins[i]); -} - -static int coin_compare(const void* a, const void* b) { - float wa = ((const Coin*)a)->weight; - float wb = ((const Coin*)b)->weight; - return wa > wb ? 1 : wa < wb ? -1 : 0; -} - -static unsigned append_symbol_coins(Coin* coins, const unsigned* frequencies, unsigned numcodes, size_t sum) -{ - unsigned i; - unsigned j = 0; /*index of present symbols*/ - for(i = 0; i < numcodes; i++) - { - if(frequencies[i] != 0) /*only include symbols that are present*/ - { - coins[j].weight = frequencies[i] / (float)sum; - uivector_push_back(&coins[j].symbols, i); - j++; - } - } - return 0; -} - -unsigned lodepng_huffman_code_lengths(unsigned* lengths, const unsigned* frequencies, - size_t numcodes, unsigned maxbitlen) -{ - unsigned i, j; - size_t sum = 0, numpresent = 0; - unsigned error = 0; - Coin* coins; /*the coins of the currently calculated row*/ - Coin* prev_row; /*the previous row of coins*/ - size_t numcoins; - size_t coinmem; - - if(numcodes == 0) return 80; /*error: a tree of 0 symbols is not supposed to be made*/ - - for(i = 0; i < numcodes; i++) - { - if(frequencies[i] > 0) - { - numpresent++; - sum += frequencies[i]; - } - } - - for(i = 0; i < numcodes; i++) lengths[i] = 0; - - /*ensure at least two present symbols. There should be at least one symbol - according to RFC 1951 section 3.2.7. To decoders incorrectly require two. To - make these work as well ensure there are at least two symbols. The - Package-Merge code below also doesn't work correctly if there's only one - symbol, it'd give it the theoritical 0 bits but in practice zlib wants 1 bit*/ - if(numpresent == 0) - { - lengths[0] = lengths[1] = 1; /*note that for RFC 1951 section 3.2.7, only lengths[0] = 1 is needed*/ - } - else if(numpresent == 1) - { - for(i = 0; i < numcodes; i++) - { - if(frequencies[i]) - { - lengths[i] = 1; - lengths[i == 0 ? 1 : 0] = 1; - break; - } - } - } - else - { - /*Package-Merge algorithm represented by coin collector's problem - For every symbol, maxbitlen coins will be created*/ - - coinmem = numpresent * 2; /*max amount of coins needed with the current algo*/ - coins = (Coin*)lodepng_malloc(sizeof(Coin) * coinmem); - prev_row = (Coin*)lodepng_malloc(sizeof(Coin) * coinmem); - if(!coins || !prev_row) - { - lodepng_free(coins); - lodepng_free(prev_row); - return 83; /*alloc fail*/ - } - init_coins(coins, coinmem); - init_coins(prev_row, coinmem); - - /*first row, lowest denominator*/ - error = append_symbol_coins(coins, frequencies, numcodes, sum); - numcoins = numpresent; - qsort(coins, numcoins, sizeof(Coin), coin_compare); - if(!error) - { - unsigned numprev = 0; - for(j = 1; j <= maxbitlen && !error; j++) /*each of the remaining rows*/ - { - unsigned tempnum; - Coin* tempcoins; - /*swap prev_row and coins, and their amounts*/ - tempcoins = prev_row; prev_row = coins; coins = tempcoins; - tempnum = numprev; numprev = numcoins; numcoins = tempnum; - - cleanup_coins(coins, numcoins); - init_coins(coins, numcoins); - - numcoins = 0; - - /*fill in the merged coins of the previous row*/ - for(i = 0; i + 1 < numprev; i += 2) - { - /*merge prev_row[i] and prev_row[i + 1] into new coin*/ - Coin* coin = &coins[numcoins++]; - coin_copy(coin, &prev_row[i]); - add_coins(coin, &prev_row[i + 1]); - } - /*fill in all the original symbols again*/ - if(j < maxbitlen) - { - error = append_symbol_coins(coins + numcoins, frequencies, numcodes, sum); - numcoins += numpresent; - } - qsort(coins, numcoins, sizeof(Coin), coin_compare); - } - } - - if(!error) - { - /*calculate the lenghts of each symbol, as the amount of times a coin of each symbol is used*/ - for(i = 0; i < numpresent - 1; i++) - { - Coin* coin = &coins[i]; - for(j = 0; j < coin->symbols.size; j++) lengths[coin->symbols.data[j]]++; - } - } - - cleanup_coins(coins, coinmem); - lodepng_free(coins); - cleanup_coins(prev_row, coinmem); - lodepng_free(prev_row); - } - - return error; -} - -/*Create the Huffman tree given the symbol frequencies*/ -static unsigned HuffmanTree_makeFromFrequencies(HuffmanTree* tree, const unsigned* frequencies, - size_t mincodes, size_t numcodes, unsigned maxbitlen) -{ - unsigned error = 0; - while(!frequencies[numcodes - 1] && numcodes > mincodes) numcodes--; /*trim zeroes*/ - tree->maxbitlen = maxbitlen; - tree->numcodes = (unsigned)numcodes; /*number of symbols*/ - tree->lengths = (unsigned*)lodepng_realloc(tree->lengths, numcodes * sizeof(unsigned)); - if(!tree->lengths) return 83; /*alloc fail*/ - /*initialize all lengths to 0*/ - memset(tree->lengths, 0, numcodes * sizeof(unsigned)); - - error = lodepng_huffman_code_lengths(tree->lengths, frequencies, numcodes, maxbitlen); - if(!error) error = HuffmanTree_makeFromLengths2(tree); - return error; -} - -static unsigned HuffmanTree_getCode(const HuffmanTree* tree, unsigned index) -{ - return tree->tree1d[index]; -} - -static unsigned HuffmanTree_getLength(const HuffmanTree* tree, unsigned index) -{ - return tree->lengths[index]; -} -#endif /*LODEPNG_COMPILE_ENCODER*/ - -/*get the literal and length code tree of a deflated block with fixed tree, as per the deflate specification*/ -static unsigned generateFixedLitLenTree(HuffmanTree* tree) -{ - unsigned i, error = 0; - unsigned* bitlen = (unsigned*)lodepng_malloc(NUM_DEFLATE_CODE_SYMBOLS * sizeof(unsigned)); - if(!bitlen) return 83; /*alloc fail*/ - - /*288 possible codes: 0-255=literals, 256=endcode, 257-285=lengthcodes, 286-287=unused*/ - for(i = 0; i <= 143; i++) bitlen[i] = 8; - for(i = 144; i <= 255; i++) bitlen[i] = 9; - for(i = 256; i <= 279; i++) bitlen[i] = 7; - for(i = 280; i <= 287; i++) bitlen[i] = 8; - - error = HuffmanTree_makeFromLengths(tree, bitlen, NUM_DEFLATE_CODE_SYMBOLS, 15); - - lodepng_free(bitlen); - return error; -} - -/*get the distance code tree of a deflated block with fixed tree, as specified in the deflate specification*/ -static unsigned generateFixedDistanceTree(HuffmanTree* tree) -{ - unsigned i, error = 0; - unsigned* bitlen = (unsigned*)lodepng_malloc(NUM_DISTANCE_SYMBOLS * sizeof(unsigned)); - if(!bitlen) return 83; /*alloc fail*/ - - /*there are 32 distance codes, but 30-31 are unused*/ - for(i = 0; i < NUM_DISTANCE_SYMBOLS; i++) bitlen[i] = 5; - error = HuffmanTree_makeFromLengths(tree, bitlen, NUM_DISTANCE_SYMBOLS, 15); - - lodepng_free(bitlen); - return error; -} - -#ifdef LODEPNG_COMPILE_DECODER - -/* -returns the code, or (unsigned)(-1) if error happened -inbitlength is the length of the complete buffer, in bits (so its byte length times 8) -*/ -static unsigned huffmanDecodeSymbol(const unsigned char* in, size_t* bp, - const HuffmanTree* codetree, size_t inbitlength) -{ - unsigned treepos = 0, ct; - for(;;) - { - if(*bp >= inbitlength) return (unsigned)(-1); /*error: end of input memory reached without endcode*/ - /* - decode the symbol from the tree. The "readBitFromStream" code is inlined in - the expression below because this is the biggest bottleneck while decoding - */ - ct = codetree->tree2d[(treepos << 1) + READBIT(*bp, in)]; - (*bp)++; - if(ct < codetree->numcodes) return ct; /*the symbol is decoded, return it*/ - else treepos = ct - codetree->numcodes; /*symbol not yet decoded, instead move tree position*/ - - if(treepos >= codetree->numcodes) return (unsigned)(-1); /*error: it appeared outside the codetree*/ - } -} -#endif /*LODEPNG_COMPILE_DECODER*/ - -#ifdef LODEPNG_COMPILE_DECODER - -/* ////////////////////////////////////////////////////////////////////////// */ -/* / Inflator (Decompressor) / */ -/* ////////////////////////////////////////////////////////////////////////// */ - -/*get the tree of a deflated block with fixed tree, as specified in the deflate specification*/ -static void getTreeInflateFixed(HuffmanTree* tree_ll, HuffmanTree* tree_d) -{ - /*TODO: check for out of memory errors*/ - generateFixedLitLenTree(tree_ll); - generateFixedDistanceTree(tree_d); -} - -/*get the tree of a deflated block with dynamic tree, the tree itself is also Huffman compressed with a known tree*/ -static unsigned getTreeInflateDynamic(HuffmanTree* tree_ll, HuffmanTree* tree_d, - const unsigned char* in, size_t* bp, size_t inlength) -{ - /*make sure that length values that aren't filled in will be 0, or a wrong tree will be generated*/ - unsigned error = 0; - unsigned n, HLIT, HDIST, HCLEN, i; - size_t inbitlength = inlength * 8; - - /*see comments in deflateDynamic for explanation of the context and these variables, it is analogous*/ - unsigned* bitlen_ll = 0; /*lit,len code lengths*/ - unsigned* bitlen_d = 0; /*dist code lengths*/ - /*code length code lengths ("clcl"), the bit lengths of the huffman tree used to compress bitlen_ll and bitlen_d*/ - unsigned* bitlen_cl = 0; - HuffmanTree tree_cl; /*the code tree for code length codes (the huffman tree for compressed huffman trees)*/ - - if((*bp) >> 3 >= inlength - 2) return 49; /*error: the bit pointer is or will go past the memory*/ - - /*number of literal/length codes + 257. Unlike the spec, the value 257 is added to it here already*/ - HLIT = readBitsFromStream(bp, in, 5) + 257; - /*number of distance codes. Unlike the spec, the value 1 is added to it here already*/ - HDIST = readBitsFromStream(bp, in, 5) + 1; - /*number of code length codes. Unlike the spec, the value 4 is added to it here already*/ - HCLEN = readBitsFromStream(bp, in, 4) + 4; - - HuffmanTree_init(&tree_cl); - - while(!error) - { - /*read the code length codes out of 3 * (amount of code length codes) bits*/ - - bitlen_cl = (unsigned*)lodepng_malloc(NUM_CODE_LENGTH_CODES * sizeof(unsigned)); - if(!bitlen_cl) ERROR_BREAK(83 /*alloc fail*/); - - for(i = 0; i < NUM_CODE_LENGTH_CODES; i++) - { - if(i < HCLEN) bitlen_cl[CLCL_ORDER[i]] = readBitsFromStream(bp, in, 3); - else bitlen_cl[CLCL_ORDER[i]] = 0; /*if not, it must stay 0*/ - } - - error = HuffmanTree_makeFromLengths(&tree_cl, bitlen_cl, NUM_CODE_LENGTH_CODES, 7); - if(error) break; - - /*now we can use this tree to read the lengths for the tree that this function will return*/ - bitlen_ll = (unsigned*)lodepng_malloc(NUM_DEFLATE_CODE_SYMBOLS * sizeof(unsigned)); - bitlen_d = (unsigned*)lodepng_malloc(NUM_DISTANCE_SYMBOLS * sizeof(unsigned)); - if(!bitlen_ll || !bitlen_d) ERROR_BREAK(83 /*alloc fail*/); - for(i = 0; i < NUM_DEFLATE_CODE_SYMBOLS; i++) bitlen_ll[i] = 0; - for(i = 0; i < NUM_DISTANCE_SYMBOLS; i++) bitlen_d[i] = 0; - - /*i is the current symbol we're reading in the part that contains the code lengths of lit/len and dist codes*/ - i = 0; - while(i < HLIT + HDIST) - { - unsigned code = huffmanDecodeSymbol(in, bp, &tree_cl, inbitlength); - if(code <= 15) /*a length code*/ - { - if(i < HLIT) bitlen_ll[i] = code; - else bitlen_d[i - HLIT] = code; - i++; - } - else if(code == 16) /*repeat previous*/ - { - unsigned replength = 3; /*read in the 2 bits that indicate repeat length (3-6)*/ - unsigned value; /*set value to the previous code*/ - - if(*bp >= inbitlength) ERROR_BREAK(50); /*error, bit pointer jumps past memory*/ - if (i == 0) ERROR_BREAK(54); /*can't repeat previous if i is 0*/ - - replength += readBitsFromStream(bp, in, 2); - - if(i < HLIT + 1) value = bitlen_ll[i - 1]; - else value = bitlen_d[i - HLIT - 1]; - /*repeat this value in the next lengths*/ - for(n = 0; n < replength; n++) - { - if(i >= HLIT + HDIST) ERROR_BREAK(13); /*error: i is larger than the amount of codes*/ - if(i < HLIT) bitlen_ll[i] = value; - else bitlen_d[i - HLIT] = value; - i++; - } - } - else if(code == 17) /*repeat "0" 3-10 times*/ - { - unsigned replength = 3; /*read in the bits that indicate repeat length*/ - if(*bp >= inbitlength) ERROR_BREAK(50); /*error, bit pointer jumps past memory*/ - - replength += readBitsFromStream(bp, in, 3); - - /*repeat this value in the next lengths*/ - for(n = 0; n < replength; n++) - { - if(i >= HLIT + HDIST) ERROR_BREAK(14); /*error: i is larger than the amount of codes*/ - - if(i < HLIT) bitlen_ll[i] = 0; - else bitlen_d[i - HLIT] = 0; - i++; - } - } - else if(code == 18) /*repeat "0" 11-138 times*/ - { - unsigned replength = 11; /*read in the bits that indicate repeat length*/ - if(*bp >= inbitlength) ERROR_BREAK(50); /*error, bit pointer jumps past memory*/ - - replength += readBitsFromStream(bp, in, 7); - - /*repeat this value in the next lengths*/ - for(n = 0; n < replength; n++) - { - if(i >= HLIT + HDIST) ERROR_BREAK(15); /*error: i is larger than the amount of codes*/ - - if(i < HLIT) bitlen_ll[i] = 0; - else bitlen_d[i - HLIT] = 0; - i++; - } - } - else /*if(code == (unsigned)(-1))*/ /*huffmanDecodeSymbol returns (unsigned)(-1) in case of error*/ - { - if(code == (unsigned)(-1)) - { - /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol - (10=no endcode, 11=wrong jump outside of tree)*/ - error = (*bp) > inbitlength ? 10 : 11; - } - else error = 16; /*unexisting code, this can never happen*/ - break; - } - } - if(error) break; - - if(bitlen_ll[256] == 0) ERROR_BREAK(64); /*the length of the end code 256 must be larger than 0*/ - - /*now we've finally got HLIT and HDIST, so generate the code trees, and the function is done*/ - error = HuffmanTree_makeFromLengths(tree_ll, bitlen_ll, NUM_DEFLATE_CODE_SYMBOLS, 15); - if(error) break; - error = HuffmanTree_makeFromLengths(tree_d, bitlen_d, NUM_DISTANCE_SYMBOLS, 15); - - break; /*end of error-while*/ - } - - lodepng_free(bitlen_cl); - lodepng_free(bitlen_ll); - lodepng_free(bitlen_d); - HuffmanTree_cleanup(&tree_cl); - - return error; -} - -/*inflate a block with dynamic of fixed Huffman tree*/ -static unsigned inflateHuffmanBlock(ucvector* out, const unsigned char* in, size_t* bp, - size_t* pos, size_t inlength, unsigned btype) -{ - unsigned error = 0; - HuffmanTree tree_ll; /*the huffman tree for literal and length codes*/ - HuffmanTree tree_d; /*the huffman tree for distance codes*/ - size_t inbitlength = inlength * 8; - - HuffmanTree_init(&tree_ll); - HuffmanTree_init(&tree_d); - - if(btype == 1) getTreeInflateFixed(&tree_ll, &tree_d); - else if(btype == 2) error = getTreeInflateDynamic(&tree_ll, &tree_d, in, bp, inlength); - - while(!error) /*decode all symbols until end reached, breaks at end code*/ - { - /*code_ll is literal, length or end code*/ - unsigned code_ll = huffmanDecodeSymbol(in, bp, &tree_ll, inbitlength); - if(code_ll <= 255) /*literal symbol*/ - { - if((*pos) >= out->size) - { - /*reserve more room at once*/ - if(!ucvector_resize(out, ((*pos) + 1) * 2)) ERROR_BREAK(83 /*alloc fail*/); - } - out->data[(*pos)] = (unsigned char)(code_ll); - (*pos)++; - } - else if(code_ll >= FIRST_LENGTH_CODE_INDEX && code_ll <= LAST_LENGTH_CODE_INDEX) /*length code*/ - { - unsigned code_d, distance; - unsigned numextrabits_l, numextrabits_d; /*extra bits for length and distance*/ - size_t start, forward, backward, length; - - /*part 1: get length base*/ - length = LENGTHBASE[code_ll - FIRST_LENGTH_CODE_INDEX]; - - /*part 2: get extra bits and add the value of that to length*/ - numextrabits_l = LENGTHEXTRA[code_ll - FIRST_LENGTH_CODE_INDEX]; - if(*bp >= inbitlength) ERROR_BREAK(51); /*error, bit pointer will jump past memory*/ - length += readBitsFromStream(bp, in, numextrabits_l); - - /*part 3: get distance code*/ - code_d = huffmanDecodeSymbol(in, bp, &tree_d, inbitlength); - if(code_d > 29) - { - if(code_ll == (unsigned)(-1)) /*huffmanDecodeSymbol returns (unsigned)(-1) in case of error*/ - { - /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol - (10=no endcode, 11=wrong jump outside of tree)*/ - error = (*bp) > inlength * 8 ? 10 : 11; - } - else error = 18; /*error: invalid distance code (30-31 are never used)*/ - break; - } - distance = DISTANCEBASE[code_d]; - - /*part 4: get extra bits from distance*/ - numextrabits_d = DISTANCEEXTRA[code_d]; - if(*bp >= inbitlength) ERROR_BREAK(51); /*error, bit pointer will jump past memory*/ - - distance += readBitsFromStream(bp, in, numextrabits_d); - - /*part 5: fill in all the out[n] values based on the length and dist*/ - start = (*pos); - if(distance > start) ERROR_BREAK(52); /*too long backward distance*/ - backward = start - distance; - if((*pos) + length >= out->size) - { - /*reserve more room at once*/ - if(!ucvector_resize(out, ((*pos) + length) * 2)) ERROR_BREAK(83 /*alloc fail*/); - } - - for(forward = 0; forward < length; forward++) - { - out->data[(*pos)] = out->data[backward]; - (*pos)++; - backward++; - if(backward >= start) backward = start - distance; - } - } - else if(code_ll == 256) - { - break; /*end code, break the loop*/ - } - else /*if(code == (unsigned)(-1))*/ /*huffmanDecodeSymbol returns (unsigned)(-1) in case of error*/ - { - /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol - (10=no endcode, 11=wrong jump outside of tree)*/ - error = (*bp) > inlength * 8 ? 10 : 11; - break; - } - } - - HuffmanTree_cleanup(&tree_ll); - HuffmanTree_cleanup(&tree_d); - - return error; -} - -static unsigned inflateNoCompression(ucvector* out, const unsigned char* in, size_t* bp, size_t* pos, size_t inlength) -{ - /*go to first boundary of byte*/ - size_t p; - unsigned LEN, NLEN, n, error = 0; - while(((*bp) & 0x7) != 0) (*bp)++; - p = (*bp) / 8; /*byte position*/ - - /*read LEN (2 bytes) and NLEN (2 bytes)*/ - if(p >= inlength - 4) return 52; /*error, bit pointer will jump past memory*/ - LEN = in[p] + 256u * in[p + 1]; p += 2; - NLEN = in[p] + 256u * in[p + 1]; p += 2; - - /*check if 16-bit NLEN is really the one's complement of LEN*/ - if(LEN + NLEN != 65535) return 21; /*error: NLEN is not one's complement of LEN*/ - - if((*pos) + LEN >= out->size) - { - if(!ucvector_resize(out, (*pos) + LEN)) return 83; /*alloc fail*/ - } - - /*read the literal data: LEN bytes are now stored in the out buffer*/ - if(p + LEN > inlength) return 23; /*error: reading outside of in buffer*/ - for(n = 0; n < LEN; n++) out->data[(*pos)++] = in[p++]; - - (*bp) = p * 8; - - return error; -} - -static unsigned lodepng_inflatev(ucvector* out, - const unsigned char* in, size_t insize, - const LodePNGDecompressSettings* settings) -{ - /*bit pointer in the "in" data, current byte is bp >> 3, current bit is bp & 0x7 (from lsb to msb of the byte)*/ - size_t bp = 0; - unsigned BFINAL = 0; - size_t pos = 0; /*byte position in the out buffer*/ - - unsigned error = 0; - - (void)settings; - - while(!BFINAL) - { - unsigned BTYPE; - if(bp + 2 >= insize * 8) return 52; /*error, bit pointer will jump past memory*/ - BFINAL = readBitFromStream(&bp, in); - BTYPE = 1u * readBitFromStream(&bp, in); - BTYPE += 2u * readBitFromStream(&bp, in); - - if(BTYPE == 3) return 20; /*error: invalid BTYPE*/ - else if(BTYPE == 0) error = inflateNoCompression(out, in, &bp, &pos, insize); /*no compression*/ - else error = inflateHuffmanBlock(out, in, &bp, &pos, insize, BTYPE); /*compression, BTYPE 01 or 10*/ - - if(error) return error; - } - - /*Only now we know the true size of out, resize it to that*/ - if(!ucvector_resize(out, pos)) error = 83; /*alloc fail*/ - - return error; -} - -unsigned lodepng_inflate(unsigned char** out, size_t* outsize, - const unsigned char* in, size_t insize, - const LodePNGDecompressSettings* settings) -{ - unsigned error; - ucvector v; - ucvector_init_buffer(&v, *out, *outsize); - error = lodepng_inflatev(&v, in, insize, settings); - *out = v.data; - *outsize = v.size; - return error; -} - -static unsigned inflate(unsigned char** out, size_t* outsize, - const unsigned char* in, size_t insize, - const LodePNGDecompressSettings* settings) -{ - if(settings->custom_inflate) - { - return settings->custom_inflate(out, outsize, in, insize, settings); - } - else - { - return lodepng_inflate(out, outsize, in, insize, settings); - } -} - -#endif /*LODEPNG_COMPILE_DECODER*/ - -#ifdef LODEPNG_COMPILE_ENCODER - -/* ////////////////////////////////////////////////////////////////////////// */ -/* / Deflator (Compressor) / */ -/* ////////////////////////////////////////////////////////////////////////// */ - -static const size_t MAX_SUPPORTED_DEFLATE_LENGTH = 258; - -/*bitlen is the size in bits of the code*/ -static void addHuffmanSymbol(size_t* bp, ucvector* compressed, unsigned code, unsigned bitlen) -{ - addBitsToStreamReversed(bp, compressed, code, bitlen); -} - -/*search the index in the array, that has the largest value smaller than or equal to the given value, -given array must be sorted (if no value is smaller, it returns the size of the given array)*/ -static size_t searchCodeIndex(const unsigned* array, size_t array_size, size_t value) -{ - /*linear search implementation*/ - /*for(size_t i = 1; i < array_size; i++) if(array[i] > value) return i - 1; - return array_size - 1;*/ - - /*binary search implementation (not that much faster) (precondition: array_size > 0)*/ - size_t left = 1; - size_t right = array_size - 1; - while(left <= right) - { - size_t mid = (left + right) / 2; - if(array[mid] <= value) left = mid + 1; /*the value to find is more to the right*/ - else if(array[mid - 1] > value) right = mid - 1; /*the value to find is more to the left*/ - else return mid - 1; - } - return array_size - 1; -} - -static void addLengthDistance(uivector* values, size_t length, size_t distance) -{ - /*values in encoded vector are those used by deflate: - 0-255: literal bytes - 256: end - 257-285: length/distance pair (length code, followed by extra length bits, distance code, extra distance bits) - 286-287: invalid*/ - - unsigned length_code = (unsigned)searchCodeIndex(LENGTHBASE, 29, length); - unsigned extra_length = (unsigned)(length - LENGTHBASE[length_code]); - unsigned dist_code = (unsigned)searchCodeIndex(DISTANCEBASE, 30, distance); - unsigned extra_distance = (unsigned)(distance - DISTANCEBASE[dist_code]); - - uivector_push_back(values, length_code + FIRST_LENGTH_CODE_INDEX); - uivector_push_back(values, extra_length); - uivector_push_back(values, dist_code); - uivector_push_back(values, extra_distance); -} - -/*3 bytes of data get encoded into two bytes. The hash cannot use more than 3 -bytes as input because 3 is the minimum match length for deflate*/ -static const unsigned HASH_NUM_VALUES = 65536; -static const unsigned HASH_BIT_MASK = 65535; /*HASH_NUM_VALUES - 1, but C90 does not like that as initializer*/ - -typedef struct Hash -{ - int* head; /*hash value to head circular pos - can be outdated if went around window*/ - /*circular pos to prev circular pos*/ - unsigned short* chain; - int* val; /*circular pos to hash value*/ - - /*TODO: do this not only for zeros but for any repeated byte. However for PNG - it's always going to be the zeros that dominate, so not important for PNG*/ - int* headz; /*similar to head, but for chainz*/ - unsigned short* chainz; /*those with same amount of zeros*/ - unsigned short* zeros; /*length of zeros streak, used as a second hash chain*/ -} Hash; - -static unsigned hash_init(Hash* hash, unsigned windowsize) -{ - unsigned i; - hash->head = (int*)lodepng_malloc(sizeof(int) * HASH_NUM_VALUES); - hash->val = (int*)lodepng_malloc(sizeof(int) * windowsize); - hash->chain = (unsigned short*)lodepng_malloc(sizeof(unsigned short) * windowsize); - - hash->zeros = (unsigned short*)lodepng_malloc(sizeof(unsigned short) * windowsize); - hash->headz = (int*)lodepng_malloc(sizeof(int) * (MAX_SUPPORTED_DEFLATE_LENGTH + 1)); - hash->chainz = (unsigned short*)lodepng_malloc(sizeof(unsigned short) * windowsize); - - if(!hash->head || !hash->chain || !hash->val || !hash->headz|| !hash->chainz || !hash->zeros) - { - return 83; /*alloc fail*/ - } - - /*initialize hash table*/ - for(i = 0; i < HASH_NUM_VALUES; i++) hash->head[i] = -1; - for(i = 0; i < windowsize; i++) hash->val[i] = -1; - for(i = 0; i < windowsize; i++) hash->chain[i] = i; /*same value as index indicates uninitialized*/ - - for(i = 0; i <= MAX_SUPPORTED_DEFLATE_LENGTH; i++) hash->headz[i] = -1; - for(i = 0; i < windowsize; i++) hash->chainz[i] = i; /*same value as index indicates uninitialized*/ - - return 0; -} - -static void hash_cleanup(Hash* hash) -{ - lodepng_free(hash->head); - lodepng_free(hash->val); - lodepng_free(hash->chain); - - lodepng_free(hash->zeros); - lodepng_free(hash->headz); - lodepng_free(hash->chainz); -} - - - -static unsigned getHash(const unsigned char* data, size_t size, size_t pos) -{ - unsigned result = 0; - if (pos + 2 < size) - { - /*A simple shift and xor hash is used. Since the data of PNGs is dominated - by zeroes due to the filters, a better hash does not have a significant - effect on speed in traversing the chain, and causes more time spend on - calculating the hash.*/ - result ^= (unsigned)(data[pos + 0] << 0u); - result ^= (unsigned)(data[pos + 1] << 4u); - result ^= (unsigned)(data[pos + 2] << 8u); - } else { - size_t amount, i; - if(pos >= size) return 0; - amount = size - pos; - for(i = 0; i < amount; i++) result ^= (unsigned)(data[pos + i] << (i * 8u)); - } - return result & HASH_BIT_MASK; -} - -static unsigned countZeros(const unsigned char* data, size_t size, size_t pos) -{ - const unsigned char* start = data + pos; - const unsigned char* end = start + MAX_SUPPORTED_DEFLATE_LENGTH; - if(end > data + size) end = data + size; - data = start; - while (data != end && *data == 0) data++; - /*subtracting two addresses returned as 32-bit number (max value is MAX_SUPPORTED_DEFLATE_LENGTH)*/ - return (unsigned)(data - start); -} - -/*wpos = pos & (windowsize - 1)*/ -static void updateHashChain(Hash* hash, size_t wpos, unsigned hashval, unsigned short numzeros) -{ - hash->val[wpos] = (int)hashval; - if(hash->head[hashval] != -1) hash->chain[wpos] = hash->head[hashval]; - hash->head[hashval] = wpos; - - hash->zeros[wpos] = numzeros; - if(hash->headz[numzeros] != -1) hash->chainz[wpos] = hash->headz[numzeros]; - hash->headz[numzeros] = wpos; -} - -/* -LZ77-encode the data. Return value is error code. The input are raw bytes, the output -is in the form of unsigned integers with codes representing for example literal bytes, or -length/distance pairs. -It uses a hash table technique to let it encode faster. When doing LZ77 encoding, a -sliding window (of windowsize) is used, and all past bytes in that window can be used as -the "dictionary". A brute force search through all possible distances would be slow, and -this hash technique is one out of several ways to speed this up. -*/ -static unsigned encodeLZ77(uivector* out, Hash* hash, - const unsigned char* in, size_t inpos, size_t insize, unsigned windowsize, - unsigned minmatch, unsigned nicematch, unsigned lazymatching) -{ - size_t pos; - unsigned i, error = 0; - /*for large window lengths, assume the user wants no compression loss. Otherwise, max hash chain length speedup.*/ - unsigned maxchainlength = windowsize >= 8192 ? windowsize : windowsize / 8; - unsigned maxlazymatch = windowsize >= 8192 ? MAX_SUPPORTED_DEFLATE_LENGTH : 64; - - unsigned usezeros = 1; /*not sure if setting it to false for windowsize < 8192 is better or worse*/ - unsigned numzeros = 0; - - unsigned offset; /*the offset represents the distance in LZ77 terminology*/ - unsigned length; - unsigned lazy = 0; - unsigned lazylength = 0, lazyoffset = 0; - unsigned hashval; - unsigned current_offset, current_length; - unsigned prev_offset; - const unsigned char *lastptr, *foreptr, *backptr; - unsigned hashpos; - - if(windowsize <= 0 || windowsize > 32768) return 60; /*error: windowsize smaller/larger than allowed*/ - if((windowsize & (windowsize - 1)) != 0) return 90; /*error: must be power of two*/ - - if(nicematch > MAX_SUPPORTED_DEFLATE_LENGTH) nicematch = MAX_SUPPORTED_DEFLATE_LENGTH; - - for(pos = inpos; pos < insize; pos++) - { - size_t wpos = pos & (windowsize - 1); /*position for in 'circular' hash buffers*/ - unsigned chainlength = 0; - - hashval = getHash(in, insize, pos); - - if(usezeros && hashval == 0) - { - if (numzeros == 0) numzeros = countZeros(in, insize, pos); - else if (pos + numzeros > insize || in[pos + numzeros - 1] != 0) numzeros--; - } - else - { - numzeros = 0; - } - - updateHashChain(hash, wpos, hashval, numzeros); - - /*the length and offset found for the current position*/ - length = 0; - offset = 0; - - hashpos = hash->chain[wpos]; - - lastptr = &in[insize < pos + MAX_SUPPORTED_DEFLATE_LENGTH ? insize : pos + MAX_SUPPORTED_DEFLATE_LENGTH]; - - /*search for the longest string*/ - prev_offset = 0; - for(;;) - { - if(chainlength++ >= maxchainlength) break; - current_offset = hashpos <= wpos ? wpos - hashpos : wpos - hashpos + windowsize; - - if(current_offset < prev_offset) break; /*stop when went completely around the circular buffer*/ - prev_offset = current_offset; - if(current_offset > 0) - { - /*test the next characters*/ - foreptr = &in[pos]; - backptr = &in[pos - current_offset]; - - /*common case in PNGs is lots of zeros. Quickly skip over them as a speedup*/ - if(numzeros >= 3) - { - unsigned skip = hash->zeros[hashpos]; - if(skip > numzeros) skip = numzeros; - backptr += skip; - foreptr += skip; - } - - while(foreptr != lastptr && *backptr == *foreptr) /*maximum supported length by deflate is max length*/ - { - ++backptr; - ++foreptr; - } - current_length = (unsigned)(foreptr - &in[pos]); - - if(current_length > length) - { - length = current_length; /*the longest length*/ - offset = current_offset; /*the offset that is related to this longest length*/ - /*jump out once a length of max length is found (speed gain). This also jumps - out if length is MAX_SUPPORTED_DEFLATE_LENGTH*/ - if(current_length >= nicematch) break; - } - } - - if(hashpos == hash->chain[hashpos]) break; - - if(numzeros >= 3 && length > numzeros) { - hashpos = hash->chainz[hashpos]; - if(hash->zeros[hashpos] != numzeros) break; - } else { - hashpos = hash->chain[hashpos]; - /*outdated hash value, happens if particular value was not encountered in whole last window*/ - if(hash->val[hashpos] != (int)hashval) break; - } - } - - if(lazymatching) - { - if(!lazy && length >= 3 && length <= maxlazymatch && length < MAX_SUPPORTED_DEFLATE_LENGTH) - { - lazy = 1; - lazylength = length; - lazyoffset = offset; - continue; /*try the next byte*/ - } - if(lazy) - { - lazy = 0; - if(pos == 0) ERROR_BREAK(81); - if(length > lazylength + 1) - { - /*push the previous character as literal*/ - if(!uivector_push_back(out, in[pos - 1])) ERROR_BREAK(83 /*alloc fail*/); - } - else - { - length = lazylength; - offset = lazyoffset; - hash->head[hashval] = -1; /*the same hashchain update will be done, this ensures no wrong alteration*/ - hash->headz[numzeros] = -1; /*idem*/ - pos--; - } - } - } - if(length >= 3 && offset > windowsize) ERROR_BREAK(86 /*too big (or overflown negative) offset*/); - - /*encode it as length/distance pair or literal value*/ - if(length < 3) /*only lengths of 3 or higher are supported as length/distance pair*/ - { - if(!uivector_push_back(out, in[pos])) ERROR_BREAK(83 /*alloc fail*/); - } - else if(length < minmatch || (length == 3 && offset > 4096)) - { - /*compensate for the fact that longer offsets have more extra bits, a - length of only 3 may be not worth it then*/ - if(!uivector_push_back(out, in[pos])) ERROR_BREAK(83 /*alloc fail*/); - } - else - { - addLengthDistance(out, length, offset); - for(i = 1; i < length; i++) - { - pos++; - wpos = pos & (windowsize - 1); - hashval = getHash(in, insize, pos); - if(usezeros && hashval == 0) - { - if (numzeros == 0) numzeros = countZeros(in, insize, pos); - else if (pos + numzeros > insize || in[pos + numzeros - 1] != 0) numzeros--; - } - else - { - numzeros = 0; - } - updateHashChain(hash, wpos, hashval, numzeros); - } - } - } /*end of the loop through each character of input*/ - - return error; -} - -/* /////////////////////////////////////////////////////////////////////////// */ - -static unsigned deflateNoCompression(ucvector* out, const unsigned char* data, size_t datasize) -{ - /*non compressed deflate block data: 1 bit BFINAL,2 bits BTYPE,(5 bits): it jumps to start of next byte, - 2 bytes LEN, 2 bytes NLEN, LEN bytes literal DATA*/ - - size_t i, j, numdeflateblocks = (datasize + 65534) / 65535; - unsigned datapos = 0; - for(i = 0; i < numdeflateblocks; i++) - { - unsigned BFINAL, BTYPE, LEN, NLEN; - unsigned char firstbyte; - - BFINAL = (i == numdeflateblocks - 1); - BTYPE = 0; - - firstbyte = (unsigned char)(BFINAL + ((BTYPE & 1) << 1) + ((BTYPE & 2) << 1)); - ucvector_push_back(out, firstbyte); - - LEN = 65535; - if(datasize - datapos < 65535) LEN = (unsigned)datasize - datapos; - NLEN = 65535 - LEN; - - ucvector_push_back(out, (unsigned char)(LEN % 256)); - ucvector_push_back(out, (unsigned char)(LEN / 256)); - ucvector_push_back(out, (unsigned char)(NLEN % 256)); - ucvector_push_back(out, (unsigned char)(NLEN / 256)); - - /*Decompressed data*/ - for(j = 0; j < 65535 && datapos < datasize; j++) - { - ucvector_push_back(out, data[datapos++]); - } - } - - return 0; -} - -/* -write the lz77-encoded data, which has lit, len and dist codes, to compressed stream using huffman trees. -tree_ll: the tree for lit and len codes. -tree_d: the tree for distance codes. -*/ -static void writeLZ77data(size_t* bp, ucvector* out, const uivector* lz77_encoded, - const HuffmanTree* tree_ll, const HuffmanTree* tree_d) -{ - size_t i = 0; - for(i = 0; i < lz77_encoded->size; i++) - { - unsigned val = lz77_encoded->data[i]; - addHuffmanSymbol(bp, out, HuffmanTree_getCode(tree_ll, val), HuffmanTree_getLength(tree_ll, val)); - if(val > 256) /*for a length code, 3 more things have to be added*/ - { - unsigned length_index = val - FIRST_LENGTH_CODE_INDEX; - unsigned n_length_extra_bits = LENGTHEXTRA[length_index]; - unsigned length_extra_bits = lz77_encoded->data[++i]; - - unsigned distance_code = lz77_encoded->data[++i]; - - unsigned distance_index = distance_code; - unsigned n_distance_extra_bits = DISTANCEEXTRA[distance_index]; - unsigned distance_extra_bits = lz77_encoded->data[++i]; - - addBitsToStream(bp, out, length_extra_bits, n_length_extra_bits); - addHuffmanSymbol(bp, out, HuffmanTree_getCode(tree_d, distance_code), - HuffmanTree_getLength(tree_d, distance_code)); - addBitsToStream(bp, out, distance_extra_bits, n_distance_extra_bits); - } - } -} - -/*Deflate for a block of type "dynamic", that is, with freely, optimally, created huffman trees*/ -static unsigned deflateDynamic(ucvector* out, size_t* bp, Hash* hash, - const unsigned char* data, size_t datapos, size_t dataend, - const LodePNGCompressSettings* settings, unsigned final) -{ - unsigned error = 0; - - /* - A block is compressed as follows: The PNG data is lz77 encoded, resulting in - literal bytes and length/distance pairs. This is then huffman compressed with - two huffman trees. One huffman tree is used for the lit and len values ("ll"), - another huffman tree is used for the dist values ("d"). These two trees are - stored using their code lengths, and to compress even more these code lengths - are also run-length encoded and huffman compressed. This gives a huffman tree - of code lengths "cl". The code lenghts used to describe this third tree are - the code length code lengths ("clcl"). - */ - - /*The lz77 encoded data, represented with integers since there will also be length and distance codes in it*/ - uivector lz77_encoded; - HuffmanTree tree_ll; /*tree for lit,len values*/ - HuffmanTree tree_d; /*tree for distance codes*/ - HuffmanTree tree_cl; /*tree for encoding the code lengths representing tree_ll and tree_d*/ - uivector frequencies_ll; /*frequency of lit,len codes*/ - uivector frequencies_d; /*frequency of dist codes*/ - uivector frequencies_cl; /*frequency of code length codes*/ - uivector bitlen_lld; /*lit,len,dist code lenghts (int bits), literally (without repeat codes).*/ - uivector bitlen_lld_e; /*bitlen_lld encoded with repeat codes (this is a rudemtary run length compression)*/ - /*bitlen_cl is the code length code lengths ("clcl"). The bit lengths of codes to represent tree_cl - (these are written as is in the file, it would be crazy to compress these using yet another huffman - tree that needs to be represented by yet another set of code lengths)*/ - uivector bitlen_cl; - size_t datasize = dataend - datapos; - - /* - Due to the huffman compression of huffman tree representations ("two levels"), there are some anologies: - bitlen_lld is to tree_cl what data is to tree_ll and tree_d. - bitlen_lld_e is to bitlen_lld what lz77_encoded is to data. - bitlen_cl is to bitlen_lld_e what bitlen_lld is to lz77_encoded. - */ - - unsigned BFINAL = final; - size_t numcodes_ll, numcodes_d, i; - unsigned HLIT, HDIST, HCLEN; - - uivector_init(&lz77_encoded); - HuffmanTree_init(&tree_ll); - HuffmanTree_init(&tree_d); - HuffmanTree_init(&tree_cl); - uivector_init(&frequencies_ll); - uivector_init(&frequencies_d); - uivector_init(&frequencies_cl); - uivector_init(&bitlen_lld); - uivector_init(&bitlen_lld_e); - uivector_init(&bitlen_cl); - - /*This while loop never loops due to a break at the end, it is here to - allow breaking out of it to the cleanup phase on error conditions.*/ - while(!error) - { - if(settings->use_lz77) - { - error = encodeLZ77(&lz77_encoded, hash, data, datapos, dataend, settings->windowsize, - settings->minmatch, settings->nicematch, settings->lazymatching); - if(error) break; - } - else - { - if(!uivector_resize(&lz77_encoded, datasize)) ERROR_BREAK(83 /*alloc fail*/); - for(i = datapos; i < dataend; i++) lz77_encoded.data[i] = data[i]; /*no LZ77, but still will be Huffman compressed*/ - } - - if(!uivector_resizev(&frequencies_ll, 286, 0)) ERROR_BREAK(83 /*alloc fail*/); - if(!uivector_resizev(&frequencies_d, 30, 0)) ERROR_BREAK(83 /*alloc fail*/); - - /*Count the frequencies of lit, len and dist codes*/ - for(i = 0; i < lz77_encoded.size; i++) - { - unsigned symbol = lz77_encoded.data[i]; - frequencies_ll.data[symbol]++; - if(symbol > 256) - { - unsigned dist = lz77_encoded.data[i + 2]; - frequencies_d.data[dist]++; - i += 3; - } - } - frequencies_ll.data[256] = 1; /*there will be exactly 1 end code, at the end of the block*/ - - /*Make both huffman trees, one for the lit and len codes, one for the dist codes*/ - error = HuffmanTree_makeFromFrequencies(&tree_ll, frequencies_ll.data, 257, frequencies_ll.size, 15); - if(error) break; - /*2, not 1, is chosen for mincodes: some buggy PNG decoders require at least 2 symbols in the dist tree*/ - error = HuffmanTree_makeFromFrequencies(&tree_d, frequencies_d.data, 2, frequencies_d.size, 15); - if(error) break; - - numcodes_ll = tree_ll.numcodes; if(numcodes_ll > 286) numcodes_ll = 286; - numcodes_d = tree_d.numcodes; if(numcodes_d > 30) numcodes_d = 30; - /*store the code lengths of both generated trees in bitlen_lld*/ - for(i = 0; i < numcodes_ll; i++) uivector_push_back(&bitlen_lld, HuffmanTree_getLength(&tree_ll, (unsigned)i)); - for(i = 0; i < numcodes_d; i++) uivector_push_back(&bitlen_lld, HuffmanTree_getLength(&tree_d, (unsigned)i)); - - /*run-length compress bitlen_ldd into bitlen_lld_e by using repeat codes 16 (copy length 3-6 times), - 17 (3-10 zeroes), 18 (11-138 zeroes)*/ - for(i = 0; i < (unsigned)bitlen_lld.size; i++) - { - unsigned j = 0; /*amount of repititions*/ - while(i + j + 1 < (unsigned)bitlen_lld.size && bitlen_lld.data[i + j + 1] == bitlen_lld.data[i]) j++; - - if(bitlen_lld.data[i] == 0 && j >= 2) /*repeat code for zeroes*/ - { - j++; /*include the first zero*/ - if(j <= 10) /*repeat code 17 supports max 10 zeroes*/ - { - uivector_push_back(&bitlen_lld_e, 17); - uivector_push_back(&bitlen_lld_e, j - 3); - } - else /*repeat code 18 supports max 138 zeroes*/ - { - if(j > 138) j = 138; - uivector_push_back(&bitlen_lld_e, 18); - uivector_push_back(&bitlen_lld_e, j - 11); - } - i += (j - 1); - } - else if(j >= 3) /*repeat code for value other than zero*/ - { - size_t k; - unsigned num = j / 6, rest = j % 6; - uivector_push_back(&bitlen_lld_e, bitlen_lld.data[i]); - for(k = 0; k < num; k++) - { - uivector_push_back(&bitlen_lld_e, 16); - uivector_push_back(&bitlen_lld_e, 6 - 3); - } - if(rest >= 3) - { - uivector_push_back(&bitlen_lld_e, 16); - uivector_push_back(&bitlen_lld_e, rest - 3); - } - else j -= rest; - i += j; - } - else /*too short to benefit from repeat code*/ - { - uivector_push_back(&bitlen_lld_e, bitlen_lld.data[i]); - } - } - - /*generate tree_cl, the huffmantree of huffmantrees*/ - - if(!uivector_resizev(&frequencies_cl, NUM_CODE_LENGTH_CODES, 0)) ERROR_BREAK(83 /*alloc fail*/); - for(i = 0; i < bitlen_lld_e.size; i++) - { - frequencies_cl.data[bitlen_lld_e.data[i]]++; - /*after a repeat code come the bits that specify the number of repetitions, - those don't need to be in the frequencies_cl calculation*/ - if(bitlen_lld_e.data[i] >= 16) i++; - } - - error = HuffmanTree_makeFromFrequencies(&tree_cl, frequencies_cl.data, - frequencies_cl.size, frequencies_cl.size, 7); - if(error) break; - - if(!uivector_resize(&bitlen_cl, tree_cl.numcodes)) ERROR_BREAK(83 /*alloc fail*/); - for(i = 0; i < tree_cl.numcodes; i++) - { - /*lenghts of code length tree is in the order as specified by deflate*/ - bitlen_cl.data[i] = HuffmanTree_getLength(&tree_cl, CLCL_ORDER[i]); - } - while(bitlen_cl.data[bitlen_cl.size - 1] == 0 && bitlen_cl.size > 4) - { - /*remove zeros at the end, but minimum size must be 4*/ - if(!uivector_resize(&bitlen_cl, bitlen_cl.size - 1)) ERROR_BREAK(83 /*alloc fail*/); - } - if(error) break; - - /* - Write everything into the output - - After the BFINAL and BTYPE, the dynamic block consists out of the following: - - 5 bits HLIT, 5 bits HDIST, 4 bits HCLEN - - (HCLEN+4)*3 bits code lengths of code length alphabet - - HLIT + 257 code lenghts of lit/length alphabet (encoded using the code length - alphabet, + possible repetition codes 16, 17, 18) - - HDIST + 1 code lengths of distance alphabet (encoded using the code length - alphabet, + possible repetition codes 16, 17, 18) - - compressed data - - 256 (end code) - */ - - /*Write block type*/ - addBitToStream(bp, out, BFINAL); - addBitToStream(bp, out, 0); /*first bit of BTYPE "dynamic"*/ - addBitToStream(bp, out, 1); /*second bit of BTYPE "dynamic"*/ - - /*write the HLIT, HDIST and HCLEN values*/ - HLIT = (unsigned)(numcodes_ll - 257); - HDIST = (unsigned)(numcodes_d - 1); - HCLEN = (unsigned)bitlen_cl.size - 4; - /*trim zeroes for HCLEN. HLIT and HDIST were already trimmed at tree creation*/ - while(!bitlen_cl.data[HCLEN + 4 - 1] && HCLEN > 0) HCLEN--; - addBitsToStream(bp, out, HLIT, 5); - addBitsToStream(bp, out, HDIST, 5); - addBitsToStream(bp, out, HCLEN, 4); - - /*write the code lenghts of the code length alphabet*/ - for(i = 0; i < HCLEN + 4; i++) addBitsToStream(bp, out, bitlen_cl.data[i], 3); - - /*write the lenghts of the lit/len AND the dist alphabet*/ - for(i = 0; i < bitlen_lld_e.size; i++) - { - addHuffmanSymbol(bp, out, HuffmanTree_getCode(&tree_cl, bitlen_lld_e.data[i]), - HuffmanTree_getLength(&tree_cl, bitlen_lld_e.data[i])); - /*extra bits of repeat codes*/ - if(bitlen_lld_e.data[i] == 16) addBitsToStream(bp, out, bitlen_lld_e.data[++i], 2); - else if(bitlen_lld_e.data[i] == 17) addBitsToStream(bp, out, bitlen_lld_e.data[++i], 3); - else if(bitlen_lld_e.data[i] == 18) addBitsToStream(bp, out, bitlen_lld_e.data[++i], 7); - } - - /*write the compressed data symbols*/ - writeLZ77data(bp, out, &lz77_encoded, &tree_ll, &tree_d); - /*error: the length of the end code 256 must be larger than 0*/ - if(HuffmanTree_getLength(&tree_ll, 256) == 0) ERROR_BREAK(64); - - /*write the end code*/ - addHuffmanSymbol(bp, out, HuffmanTree_getCode(&tree_ll, 256), HuffmanTree_getLength(&tree_ll, 256)); - - break; /*end of error-while*/ - } - - /*cleanup*/ - uivector_cleanup(&lz77_encoded); - HuffmanTree_cleanup(&tree_ll); - HuffmanTree_cleanup(&tree_d); - HuffmanTree_cleanup(&tree_cl); - uivector_cleanup(&frequencies_ll); - uivector_cleanup(&frequencies_d); - uivector_cleanup(&frequencies_cl); - uivector_cleanup(&bitlen_lld_e); - uivector_cleanup(&bitlen_lld); - uivector_cleanup(&bitlen_cl); - - return error; -} - -static unsigned deflateFixed(ucvector* out, size_t* bp, Hash* hash, - const unsigned char* data, - size_t datapos, size_t dataend, - const LodePNGCompressSettings* settings, unsigned final) -{ - HuffmanTree tree_ll; /*tree for literal values and length codes*/ - HuffmanTree tree_d; /*tree for distance codes*/ - - unsigned BFINAL = final; - unsigned error = 0; - size_t i; - - HuffmanTree_init(&tree_ll); - HuffmanTree_init(&tree_d); - - generateFixedLitLenTree(&tree_ll); - generateFixedDistanceTree(&tree_d); - - addBitToStream(bp, out, BFINAL); - addBitToStream(bp, out, 1); /*first bit of BTYPE*/ - addBitToStream(bp, out, 0); /*second bit of BTYPE*/ - - if(settings->use_lz77) /*LZ77 encoded*/ - { - uivector lz77_encoded; - uivector_init(&lz77_encoded); - error = encodeLZ77(&lz77_encoded, hash, data, datapos, dataend, settings->windowsize, - settings->minmatch, settings->nicematch, settings->lazymatching); - if(!error) writeLZ77data(bp, out, &lz77_encoded, &tree_ll, &tree_d); - uivector_cleanup(&lz77_encoded); - } - else /*no LZ77, but still will be Huffman compressed*/ - { - for(i = datapos; i < dataend; i++) - { - addHuffmanSymbol(bp, out, HuffmanTree_getCode(&tree_ll, data[i]), HuffmanTree_getLength(&tree_ll, data[i])); - } - } - /*add END code*/ - if(!error) addHuffmanSymbol(bp, out, HuffmanTree_getCode(&tree_ll, 256), HuffmanTree_getLength(&tree_ll, 256)); - - /*cleanup*/ - HuffmanTree_cleanup(&tree_ll); - HuffmanTree_cleanup(&tree_d); - - return error; -} - -static unsigned lodepng_deflatev(ucvector* out, const unsigned char* in, size_t insize, - const LodePNGCompressSettings* settings) -{ - unsigned error = 0; - size_t i, blocksize, numdeflateblocks; - size_t bp = 0; /*the bit pointer*/ - Hash hash; - - if(settings->btype > 2) return 61; - else if(settings->btype == 0) return deflateNoCompression(out, in, insize); - else if(settings->btype == 1) blocksize = insize; - else /*if(settings->btype == 2)*/ - { - blocksize = insize / 8 + 8; - if(blocksize < 65535) blocksize = 65535; - } - - numdeflateblocks = (insize + blocksize - 1) / blocksize; - if(numdeflateblocks == 0) numdeflateblocks = 1; - - error = hash_init(&hash, settings->windowsize); - if(error) return error; - - for(i = 0; i < numdeflateblocks && !error; i++) - { - unsigned final = (i == numdeflateblocks - 1); - size_t start = i * blocksize; - size_t end = start + blocksize; - if(end > insize) end = insize; - - if(settings->btype == 1) error = deflateFixed(out, &bp, &hash, in, start, end, settings, final); - else if(settings->btype == 2) error = deflateDynamic(out, &bp, &hash, in, start, end, settings, final); - } - - hash_cleanup(&hash); - - return error; -} - -unsigned lodepng_deflate(unsigned char** out, size_t* outsize, - const unsigned char* in, size_t insize, - const LodePNGCompressSettings* settings) -{ - unsigned error; - ucvector v; - ucvector_init_buffer(&v, *out, *outsize); - error = lodepng_deflatev(&v, in, insize, settings); - *out = v.data; - *outsize = v.size; - return error; -} - -static unsigned deflate(unsigned char** out, size_t* outsize, - const unsigned char* in, size_t insize, - const LodePNGCompressSettings* settings) -{ - if(settings->custom_deflate) - { - return settings->custom_deflate(out, outsize, in, insize, settings); - } - else - { - return lodepng_deflate(out, outsize, in, insize, settings); - } -} - -#endif /*LODEPNG_COMPILE_DECODER*/ - -/* ////////////////////////////////////////////////////////////////////////// */ -/* / Adler32 */ -/* ////////////////////////////////////////////////////////////////////////// */ - -static unsigned update_adler32(unsigned adler, const unsigned char* data, unsigned len) -{ - unsigned s1 = adler & 0xffff; - unsigned s2 = (adler >> 16) & 0xffff; - - while(len > 0) - { - /*at least 5550 sums can be done before the sums overflow, saving a lot of module divisions*/ - unsigned amount = len > 5550 ? 5550 : len; - len -= amount; - while(amount > 0) - { - s1 += (*data++); - s2 += s1; - amount--; - } - s1 %= 65521; - s2 %= 65521; - } - - return (s2 << 16) | s1; -} - -/*Return the adler32 of the bytes data[0..len-1]*/ -static unsigned adler32(const unsigned char* data, unsigned len) -{ - return update_adler32(1L, data, len); -} - -/* ////////////////////////////////////////////////////////////////////////// */ -/* / Zlib / */ -/* ////////////////////////////////////////////////////////////////////////// */ - -#ifdef LODEPNG_COMPILE_DECODER - -unsigned lodepng_zlib_decompress(unsigned char** out, size_t* outsize, const unsigned char* in, - size_t insize, const LodePNGDecompressSettings* settings) -{ - unsigned error = 0; - unsigned CM, CINFO, FDICT; - - if(insize < 2) return 53; /*error, size of zlib data too small*/ - /*read information from zlib header*/ - if((in[0] * 256 + in[1]) % 31 != 0) - { - /*error: 256 * in[0] + in[1] must be a multiple of 31, the FCHECK value is supposed to be made that way*/ - return 24; - } - - CM = in[0] & 15; - CINFO = (in[0] >> 4) & 15; - /*FCHECK = in[1] & 31;*/ /*FCHECK is already tested above*/ - FDICT = (in[1] >> 5) & 1; - /*FLEVEL = (in[1] >> 6) & 3;*/ /*FLEVEL is not used here*/ - - if(CM != 8 || CINFO > 7) - { - /*error: only compression method 8: inflate with sliding window of 32k is supported by the PNG spec*/ - return 25; - } - if(FDICT != 0) - { - /*error: the specification of PNG says about the zlib stream: - "The additional flags shall not specify a preset dictionary."*/ - return 26; - } - - error = inflate(out, outsize, in + 2, insize - 2, settings); - if(error) return error; - - if(!settings->ignore_adler32) - { - unsigned ADLER32 = lodepng_read32bitInt(&in[insize - 4]); - unsigned checksum = adler32(*out, (unsigned)(*outsize)); - if(checksum != ADLER32) return 58; /*error, adler checksum not correct, data must be corrupted*/ - } - - return 0; /*no error*/ -} - -static unsigned zlib_decompress(unsigned char** out, size_t* outsize, const unsigned char* in, - size_t insize, const LodePNGDecompressSettings* settings) -{ - if(settings->custom_zlib) - { - return settings->custom_zlib(out, outsize, in, insize, settings); - } - else - { - return lodepng_zlib_decompress(out, outsize, in, insize, settings); - } -} - -#endif /*LODEPNG_COMPILE_DECODER*/ - -#ifdef LODEPNG_COMPILE_ENCODER - -unsigned lodepng_zlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in, - size_t insize, const LodePNGCompressSettings* settings) -{ - /*initially, *out must be NULL and outsize 0, if you just give some random *out - that's pointing to a non allocated buffer, this'll crash*/ - ucvector outv; - size_t i; - unsigned error; - unsigned char* deflatedata = 0; - size_t deflatesize = 0; - - unsigned ADLER32; - /*zlib data: 1 byte CMF (CM+CINFO), 1 byte FLG, deflate data, 4 byte ADLER32 checksum of the Decompressed data*/ - unsigned CMF = 120; /*0b01111000: CM 8, CINFO 7. With CINFO 7, any window size up to 32768 can be used.*/ - unsigned FLEVEL = 0; - unsigned FDICT = 0; - unsigned CMFFLG = 256 * CMF + FDICT * 32 + FLEVEL * 64; - unsigned FCHECK = 31 - CMFFLG % 31; - CMFFLG += FCHECK; - - /*ucvector-controlled version of the output buffer, for dynamic array*/ - ucvector_init_buffer(&outv, *out, *outsize); - - ucvector_push_back(&outv, (unsigned char)(CMFFLG / 256)); - ucvector_push_back(&outv, (unsigned char)(CMFFLG % 256)); - - error = deflate(&deflatedata, &deflatesize, in, insize, settings); - - if(!error) - { - ADLER32 = adler32(in, (unsigned)insize); - for(i = 0; i < deflatesize; i++) ucvector_push_back(&outv, deflatedata[i]); - lodepng_free(deflatedata); - lodepng_add32bitInt(&outv, ADLER32); - } - - *out = outv.data; - *outsize = outv.size; - - return error; -} - -/* compress using the default or custom zlib function */ -static unsigned zlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in, - size_t insize, const LodePNGCompressSettings* settings) -{ - if(settings->custom_zlib) - { - return settings->custom_zlib(out, outsize, in, insize, settings); - } - else - { - return lodepng_zlib_compress(out, outsize, in, insize, settings); - } -} - -#endif /*LODEPNG_COMPILE_ENCODER*/ - -#else /*no LODEPNG_COMPILE_ZLIB*/ - -#ifdef LODEPNG_COMPILE_DECODER -static unsigned zlib_decompress(unsigned char** out, size_t* outsize, const unsigned char* in, - size_t insize, const LodePNGDecompressSettings* settings) -{ - if (!settings->custom_zlib) return 87; /*no custom zlib function provided */ - return settings->custom_zlib(out, outsize, in, insize, settings); -} -#endif /*LODEPNG_COMPILE_DECODER*/ -#ifdef LODEPNG_COMPILE_ENCODER -static unsigned zlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in, - size_t insize, const LodePNGCompressSettings* settings) -{ - if (!settings->custom_zlib) return 87; /*no custom zlib function provided */ - return settings->custom_zlib(out, outsize, in, insize, settings); -} -#endif /*LODEPNG_COMPILE_ENCODER*/ - -#endif /*LODEPNG_COMPILE_ZLIB*/ - -/* ////////////////////////////////////////////////////////////////////////// */ - -#ifdef LODEPNG_COMPILE_ENCODER - -/*this is a good tradeoff between speed and compression ratio*/ -#define DEFAULT_WINDOWSIZE 2048 - -void lodepng_compress_settings_init(LodePNGCompressSettings* settings) -{ - /*compress with dynamic huffman tree (not in the mathematical sense, just not the predefined one)*/ - settings->btype = 2; - settings->use_lz77 = 1; - settings->windowsize = DEFAULT_WINDOWSIZE; - settings->minmatch = 3; - settings->nicematch = 128; - settings->lazymatching = 1; - - settings->custom_zlib = 0; - settings->custom_deflate = 0; - settings->custom_context = 0; -} - -const LodePNGCompressSettings lodepng_default_compress_settings = {2, 1, DEFAULT_WINDOWSIZE, 3, 128, 1, 0, 0, 0}; - - -#endif /*LODEPNG_COMPILE_ENCODER*/ - -#ifdef LODEPNG_COMPILE_DECODER - -void lodepng_decompress_settings_init(LodePNGDecompressSettings* settings) -{ - settings->ignore_adler32 = 0; - - settings->custom_zlib = 0; - settings->custom_inflate = 0; - settings->custom_context = 0; -} - -const LodePNGDecompressSettings lodepng_default_decompress_settings = {0, 0, 0, 0}; - -#endif /*LODEPNG_COMPILE_DECODER*/ - -/* ////////////////////////////////////////////////////////////////////////// */ -/* ////////////////////////////////////////////////////////////////////////// */ -/* // End of Zlib related code. Begin of PNG related code. // */ -/* ////////////////////////////////////////////////////////////////////////// */ -/* ////////////////////////////////////////////////////////////////////////// */ - -#ifdef LODEPNG_COMPILE_PNG - -/* ////////////////////////////////////////////////////////////////////////// */ -/* / CRC32 / */ -/* ////////////////////////////////////////////////////////////////////////// */ - -/* CRC polynomial: 0xedb88320 */ -static unsigned lodepng_crc32_table[256] = { - 0u, 1996959894u, 3993919788u, 2567524794u, 124634137u, 1886057615u, 3915621685u, 2657392035u, - 249268274u, 2044508324u, 3772115230u, 2547177864u, 162941995u, 2125561021u, 3887607047u, 2428444049u, - 498536548u, 1789927666u, 4089016648u, 2227061214u, 450548861u, 1843258603u, 4107580753u, 2211677639u, - 325883990u, 1684777152u, 4251122042u, 2321926636u, 335633487u, 1661365465u, 4195302755u, 2366115317u, - 997073096u, 1281953886u, 3579855332u, 2724688242u, 1006888145u, 1258607687u, 3524101629u, 2768942443u, - 901097722u, 1119000684u, 3686517206u, 2898065728u, 853044451u, 1172266101u, 3705015759u, 2882616665u, - 651767980u, 1373503546u, 3369554304u, 3218104598u, 565507253u, 1454621731u, 3485111705u, 3099436303u, - 671266974u, 1594198024u, 3322730930u, 2970347812u, 795835527u, 1483230225u, 3244367275u, 3060149565u, - 1994146192u, 31158534u, 2563907772u, 4023717930u, 1907459465u, 112637215u, 2680153253u, 3904427059u, - 2013776290u, 251722036u, 2517215374u, 3775830040u, 2137656763u, 141376813u, 2439277719u, 3865271297u, - 1802195444u, 476864866u, 2238001368u, 4066508878u, 1812370925u, 453092731u, 2181625025u, 4111451223u, - 1706088902u, 314042704u, 2344532202u, 4240017532u, 1658658271u, 366619977u, 2362670323u, 4224994405u, - 1303535960u, 984961486u, 2747007092u, 3569037538u, 1256170817u, 1037604311u, 2765210733u, 3554079995u, - 1131014506u, 879679996u, 2909243462u, 3663771856u, 1141124467u, 855842277u, 2852801631u, 3708648649u, - 1342533948u, 654459306u, 3188396048u, 3373015174u, 1466479909u, 544179635u, 3110523913u, 3462522015u, - 1591671054u, 702138776u, 2966460450u, 3352799412u, 1504918807u, 783551873u, 3082640443u, 3233442989u, - 3988292384u, 2596254646u, 62317068u, 1957810842u, 3939845945u, 2647816111u, 81470997u, 1943803523u, - 3814918930u, 2489596804u, 225274430u, 2053790376u, 3826175755u, 2466906013u, 167816743u, 2097651377u, - 4027552580u, 2265490386u, 503444072u, 1762050814u, 4150417245u, 2154129355u, 426522225u, 1852507879u, - 4275313526u, 2312317920u, 282753626u, 1742555852u, 4189708143u, 2394877945u, 397917763u, 1622183637u, - 3604390888u, 2714866558u, 953729732u, 1340076626u, 3518719985u, 2797360999u, 1068828381u, 1219638859u, - 3624741850u, 2936675148u, 906185462u, 1090812512u, 3747672003u, 2825379669u, 829329135u, 1181335161u, - 3412177804u, 3160834842u, 628085408u, 1382605366u, 3423369109u, 3138078467u, 570562233u, 1426400815u, - 3317316542u, 2998733608u, 733239954u, 1555261956u, 3268935591u, 3050360625u, 752459403u, 1541320221u, - 2607071920u, 3965973030u, 1969922972u, 40735498u, 2617837225u, 3943577151u, 1913087877u, 83908371u, - 2512341634u, 3803740692u, 2075208622u, 213261112u, 2463272603u, 3855990285u, 2094854071u, 198958881u, - 2262029012u, 4057260610u, 1759359992u, 534414190u, 2176718541u, 4139329115u, 1873836001u, 414664567u, - 2282248934u, 4279200368u, 1711684554u, 285281116u, 2405801727u, 4167216745u, 1634467795u, 376229701u, - 2685067896u, 3608007406u, 1308918612u, 956543938u, 2808555105u, 3495958263u, 1231636301u, 1047427035u, - 2932959818u, 3654703836u, 1088359270u, 936918000u, 2847714899u, 3736837829u, 1202900863u, 817233897u, - 3183342108u, 3401237130u, 1404277552u, 615818150u, 3134207493u, 3453421203u, 1423857449u, 601450431u, - 3009837614u, 3294710456u, 1567103746u, 711928724u, 3020668471u, 3272380065u, 1510334235u, 755167117u -}; - -/*Return the CRC of the bytes buf[0..len-1].*/ -unsigned lodepng_crc32(const unsigned char* buf, size_t len) -{ - unsigned c = 0xffffffffL; - size_t n; - - for(n = 0; n < len; n++) - { - c = lodepng_crc32_table[(c ^ buf[n]) & 0xff] ^ (c >> 8); - } - return c ^ 0xffffffffL; -} - -/* ////////////////////////////////////////////////////////////////////////// */ -/* / Reading and writing single bits and bytes from/to stream for LodePNG / */ -/* ////////////////////////////////////////////////////////////////////////// */ - -static unsigned char readBitFromReversedStream(size_t* bitpointer, const unsigned char* bitstream) -{ - unsigned char result = (unsigned char)((bitstream[(*bitpointer) >> 3] >> (7 - ((*bitpointer) & 0x7))) & 1); - (*bitpointer)++; - return result; -} - -static unsigned readBitsFromReversedStream(size_t* bitpointer, const unsigned char* bitstream, size_t nbits) -{ - unsigned result = 0; - size_t i; - for(i = nbits - 1; i < nbits; i--) - { - result += (unsigned)readBitFromReversedStream(bitpointer, bitstream) << i; - } - return result; -} - -#ifdef LODEPNG_COMPILE_DECODER -static void setBitOfReversedStream0(size_t* bitpointer, unsigned char* bitstream, unsigned char bit) -{ - /*the current bit in bitstream must be 0 for this to work*/ - if(bit) - { - /*earlier bit of huffman code is in a lesser significant bit of an earlier byte*/ - bitstream[(*bitpointer) >> 3] |= (bit << (7 - ((*bitpointer) & 0x7))); - } - (*bitpointer)++; -} -#endif /*LODEPNG_COMPILE_DECODER*/ - -static void setBitOfReversedStream(size_t* bitpointer, unsigned char* bitstream, unsigned char bit) -{ - /*the current bit in bitstream may be 0 or 1 for this to work*/ - if(bit == 0) bitstream[(*bitpointer) >> 3] &= (unsigned char)(~(1 << (7 - ((*bitpointer) & 0x7)))); - else bitstream[(*bitpointer) >> 3] |= (1 << (7 - ((*bitpointer) & 0x7))); - (*bitpointer)++; -} - -/* ////////////////////////////////////////////////////////////////////////// */ -/* / PNG chunks / */ -/* ////////////////////////////////////////////////////////////////////////// */ - -unsigned lodepng_chunk_length(const unsigned char* chunk) -{ - return lodepng_read32bitInt(&chunk[0]); -} - -void lodepng_chunk_type(char type[5], const unsigned char* chunk) -{ - unsigned i; - for(i = 0; i < 4; i++) type[i] = (char)chunk[4 + i]; - type[4] = 0; /*null termination char*/ -} - -unsigned char lodepng_chunk_type_equals(const unsigned char* chunk, const char* type) -{ - if(strlen(type) != 4) return 0; - return (chunk[4] == type[0] && chunk[5] == type[1] && chunk[6] == type[2] && chunk[7] == type[3]); -} - -unsigned char lodepng_chunk_ancillary(const unsigned char* chunk) -{ - return((chunk[4] & 32) != 0); -} - -unsigned char lodepng_chunk_private(const unsigned char* chunk) -{ - return((chunk[6] & 32) != 0); -} - -unsigned char lodepng_chunk_safetocopy(const unsigned char* chunk) -{ - return((chunk[7] & 32) != 0); -} - -unsigned char* lodepng_chunk_data(unsigned char* chunk) -{ - return &chunk[8]; -} - -const unsigned char* lodepng_chunk_data_const(const unsigned char* chunk) -{ - return &chunk[8]; -} - -unsigned lodepng_chunk_check_crc(const unsigned char* chunk) -{ - unsigned length = lodepng_chunk_length(chunk); - unsigned CRC = lodepng_read32bitInt(&chunk[length + 8]); - /*the CRC is taken of the data and the 4 chunk type letters, not the length*/ - unsigned checksum = lodepng_crc32(&chunk[4], length + 4); - if(CRC != checksum) return 1; - else return 0; -} - -void lodepng_chunk_generate_crc(unsigned char* chunk) -{ - unsigned length = lodepng_chunk_length(chunk); - unsigned CRC = lodepng_crc32(&chunk[4], length + 4); - lodepng_set32bitInt(chunk + 8 + length, CRC); -} - -unsigned char* lodepng_chunk_next(unsigned char* chunk) -{ - unsigned total_chunk_length = lodepng_chunk_length(chunk) + 12; - return &chunk[total_chunk_length]; -} - -const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk) -{ - unsigned total_chunk_length = lodepng_chunk_length(chunk) + 12; - return &chunk[total_chunk_length]; -} - -unsigned lodepng_chunk_append(unsigned char** out, size_t* outlength, const unsigned char* chunk) -{ - unsigned i; - unsigned total_chunk_length = lodepng_chunk_length(chunk) + 12; - unsigned char *chunk_start, *new_buffer; - size_t new_length = (*outlength) + total_chunk_length; - if(new_length < total_chunk_length || new_length < (*outlength)) return 77; /*integer overflow happened*/ - - new_buffer = (unsigned char*)lodepng_realloc(*out, new_length); - if(!new_buffer) return 83; /*alloc fail*/ - (*out) = new_buffer; - (*outlength) = new_length; - chunk_start = &(*out)[new_length - total_chunk_length]; - - for(i = 0; i < total_chunk_length; i++) chunk_start[i] = chunk[i]; - - return 0; -} - -unsigned lodepng_chunk_create(unsigned char** out, size_t* outlength, unsigned length, - const char* type, const unsigned char* data) -{ - unsigned i; - unsigned char *chunk, *new_buffer; - size_t new_length = (*outlength) + length + 12; - if(new_length < length + 12 || new_length < (*outlength)) return 77; /*integer overflow happened*/ - new_buffer = (unsigned char*)lodepng_realloc(*out, new_length); - if(!new_buffer) return 83; /*alloc fail*/ - (*out) = new_buffer; - (*outlength) = new_length; - chunk = &(*out)[(*outlength) - length - 12]; - - /*1: length*/ - lodepng_set32bitInt(chunk, (unsigned)length); - - /*2: chunk name (4 letters)*/ - chunk[4] = (unsigned char)type[0]; - chunk[5] = (unsigned char)type[1]; - chunk[6] = (unsigned char)type[2]; - chunk[7] = (unsigned char)type[3]; - - /*3: the data*/ - for(i = 0; i < length; i++) chunk[8 + i] = data[i]; - - /*4: CRC (of the chunkname characters and the data)*/ - lodepng_chunk_generate_crc(chunk); - - return 0; -} - -/* ////////////////////////////////////////////////////////////////////////// */ -/* / Color types and such / */ -/* ////////////////////////////////////////////////////////////////////////// */ - -/*return type is a LodePNG error code*/ -static unsigned checkColorValidity(LodePNGColorType colortype, unsigned bd) /*bd = bitdepth*/ -{ - switch(colortype) - { - case 0: if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 || bd == 16)) return 37; break; /*grey*/ - case 2: if(!( bd == 8 || bd == 16)) return 37; break; /*RGB*/ - case 3: if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 )) return 37; break; /*palette*/ - case 4: if(!( bd == 8 || bd == 16)) return 37; break; /*grey + alpha*/ - case 6: if(!( bd == 8 || bd == 16)) return 37; break; /*RGBA*/ - default: return 31; - } - return 0; /*allowed color type / bits combination*/ -} - -static unsigned getNumColorChannels(LodePNGColorType colortype) -{ - switch(colortype) - { - case 0: return 1; /*grey*/ - case 2: return 3; /*RGB*/ - case 3: return 1; /*palette*/ - case 4: return 2; /*grey + alpha*/ - case 6: return 4; /*RGBA*/ - } - return 0; /*unexisting color type*/ -} - -static unsigned lodepng_get_bpp_lct(LodePNGColorType colortype, unsigned bitdepth) -{ - /*bits per pixel is amount of channels * bits per channel*/ - return getNumColorChannels(colortype) * bitdepth; -} - -/* ////////////////////////////////////////////////////////////////////////// */ - -void lodepng_color_mode_init(LodePNGColorMode* info) -{ - info->key_defined = 0; - info->key_r = info->key_g = info->key_b = 0; - info->colortype = LCT_RGBA; - info->bitdepth = 8; - info->palette = 0; - info->palettesize = 0; -} - -void lodepng_color_mode_cleanup(LodePNGColorMode* info) -{ - lodepng_palette_clear(info); -} - -unsigned lodepng_color_mode_copy(LodePNGColorMode* dest, const LodePNGColorMode* source) -{ - size_t i; - lodepng_color_mode_cleanup(dest); - *dest = *source; - if(source->palette) - { - dest->palette = (unsigned char*)lodepng_malloc(1024); - if(!dest->palette && source->palettesize) return 83; /*alloc fail*/ - for(i = 0; i < source->palettesize * 4; i++) dest->palette[i] = source->palette[i]; - } - return 0; -} - -static int lodepng_color_mode_equal(const LodePNGColorMode* a, const LodePNGColorMode* b) -{ - size_t i; - if(a->colortype != b->colortype) return 0; - if(a->bitdepth != b->bitdepth) return 0; - if(a->key_defined != b->key_defined) return 0; - if(a->key_defined) - { - if(a->key_r != b->key_r) return 0; - if(a->key_g != b->key_g) return 0; - if(a->key_b != b->key_b) return 0; - } - if(a->palettesize != b->palettesize) return 0; - for(i = 0; i < a->palettesize * 4; i++) - { - if(a->palette[i] != b->palette[i]) return 0; - } - return 1; -} - -void lodepng_palette_clear(LodePNGColorMode* info) -{ - if(info->palette) lodepng_free(info->palette); - info->palette = 0; - info->palettesize = 0; -} - -unsigned lodepng_palette_add(LodePNGColorMode* info, - unsigned char r, unsigned char g, unsigned char b, unsigned char a) -{ - unsigned char* data; - /*the same resize technique as C++ std::vectors is used, and here it's made so that for a palette with - the max of 256 colors, it'll have the exact alloc size*/ - if(!info->palette) /*allocate palette if empty*/ - { - /*room for 256 colors with 4 bytes each*/ - data = (unsigned char*)lodepng_realloc(info->palette, 1024); - if(!data) return 83; /*alloc fail*/ - else info->palette = data; - } - info->palette[4 * info->palettesize + 0] = r; - info->palette[4 * info->palettesize + 1] = g; - info->palette[4 * info->palettesize + 2] = b; - info->palette[4 * info->palettesize + 3] = a; - info->palettesize++; - return 0; -} - -unsigned lodepng_get_bpp(const LodePNGColorMode* info) -{ - /*calculate bits per pixel out of colortype and bitdepth*/ - return lodepng_get_bpp_lct(info->colortype, info->bitdepth); -} - -unsigned lodepng_get_channels(const LodePNGColorMode* info) -{ - return getNumColorChannels(info->colortype); -} - -unsigned lodepng_is_greyscale_type(const LodePNGColorMode* info) -{ - return info->colortype == LCT_GREY || info->colortype == LCT_GREY_ALPHA; -} - -unsigned lodepng_is_alpha_type(const LodePNGColorMode* info) -{ - return (info->colortype & 4) != 0; /*4 or 6*/ -} - -unsigned lodepng_is_palette_type(const LodePNGColorMode* info) -{ - return info->colortype == LCT_PALETTE; -} - -unsigned lodepng_has_palette_alpha(const LodePNGColorMode* info) -{ - size_t i; - for(i = 0; i < info->palettesize; i++) - { - if(info->palette[i * 4 + 3] < 255) return 1; - } - return 0; -} - -unsigned lodepng_can_have_alpha(const LodePNGColorMode* info) -{ - return info->key_defined - || lodepng_is_alpha_type(info) - || lodepng_has_palette_alpha(info); -} - -size_t lodepng_get_raw_size(unsigned w, unsigned h, const LodePNGColorMode* color) -{ - return (w * h * lodepng_get_bpp(color) + 7) / 8; -} - -size_t lodepng_get_raw_size_lct(unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth) -{ - return (w * h * lodepng_get_bpp_lct(colortype, bitdepth) + 7) / 8; -} - -#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - -static void LodePNGUnknownChunks_init(LodePNGInfo* info) -{ - unsigned i; - for(i = 0; i < 3; i++) info->unknown_chunks_data[i] = 0; - for(i = 0; i < 3; i++) info->unknown_chunks_size[i] = 0; -} - -static void LodePNGUnknownChunks_cleanup(LodePNGInfo* info) -{ - unsigned i; - for(i = 0; i < 3; i++) lodepng_free(info->unknown_chunks_data[i]); -} - -static unsigned LodePNGUnknownChunks_copy(LodePNGInfo* dest, const LodePNGInfo* src) -{ - unsigned i; - - LodePNGUnknownChunks_cleanup(dest); - - for(i = 0; i < 3; i++) - { - size_t j; - dest->unknown_chunks_size[i] = src->unknown_chunks_size[i]; - dest->unknown_chunks_data[i] = (unsigned char*)lodepng_malloc(src->unknown_chunks_size[i]); - if(!dest->unknown_chunks_data[i] && dest->unknown_chunks_size[i]) return 83; /*alloc fail*/ - for(j = 0; j < src->unknown_chunks_size[i]; j++) - { - dest->unknown_chunks_data[i][j] = src->unknown_chunks_data[i][j]; - } - } - - return 0; -} - -/******************************************************************************/ - -static void LodePNGText_init(LodePNGInfo* info) -{ - info->text_num = 0; - info->text_keys = NULL; - info->text_strings = NULL; -} - -static void LodePNGText_cleanup(LodePNGInfo* info) -{ - size_t i; - for(i = 0; i < info->text_num; i++) - { - string_cleanup(&info->text_keys[i]); - string_cleanup(&info->text_strings[i]); - } - lodepng_free(info->text_keys); - lodepng_free(info->text_strings); -} - -static unsigned LodePNGText_copy(LodePNGInfo* dest, const LodePNGInfo* source) -{ - size_t i = 0; - dest->text_keys = 0; - dest->text_strings = 0; - dest->text_num = 0; - for(i = 0; i < source->text_num; i++) - { - CERROR_TRY_RETURN(lodepng_add_text(dest, source->text_keys[i], source->text_strings[i])); - } - return 0; -} - -void lodepng_clear_text(LodePNGInfo* info) -{ - LodePNGText_cleanup(info); -} - -unsigned lodepng_add_text(LodePNGInfo* info, const char* key, const char* str) -{ - char** new_keys = (char**)(lodepng_realloc(info->text_keys, sizeof(char*) * (info->text_num + 1))); - char** new_strings = (char**)(lodepng_realloc(info->text_strings, sizeof(char*) * (info->text_num + 1))); - if(!new_keys || !new_strings) - { - lodepng_free(new_keys); - lodepng_free(new_strings); - return 83; /*alloc fail*/ - } - - info->text_num++; - info->text_keys = new_keys; - info->text_strings = new_strings; - - string_init(&info->text_keys[info->text_num - 1]); - string_set(&info->text_keys[info->text_num - 1], key); - - string_init(&info->text_strings[info->text_num - 1]); - string_set(&info->text_strings[info->text_num - 1], str); - - return 0; -} - -/******************************************************************************/ - -static void LodePNGIText_init(LodePNGInfo* info) -{ - info->itext_num = 0; - info->itext_keys = NULL; - info->itext_langtags = NULL; - info->itext_transkeys = NULL; - info->itext_strings = NULL; -} - -static void LodePNGIText_cleanup(LodePNGInfo* info) -{ - size_t i; - for(i = 0; i < info->itext_num; i++) - { - string_cleanup(&info->itext_keys[i]); - string_cleanup(&info->itext_langtags[i]); - string_cleanup(&info->itext_transkeys[i]); - string_cleanup(&info->itext_strings[i]); - } - lodepng_free(info->itext_keys); - lodepng_free(info->itext_langtags); - lodepng_free(info->itext_transkeys); - lodepng_free(info->itext_strings); -} - -static unsigned LodePNGIText_copy(LodePNGInfo* dest, const LodePNGInfo* source) -{ - size_t i = 0; - dest->itext_keys = 0; - dest->itext_langtags = 0; - dest->itext_transkeys = 0; - dest->itext_strings = 0; - dest->itext_num = 0; - for(i = 0; i < source->itext_num; i++) - { - CERROR_TRY_RETURN(lodepng_add_itext(dest, source->itext_keys[i], source->itext_langtags[i], - source->itext_transkeys[i], source->itext_strings[i])); - } - return 0; -} - -void lodepng_clear_itext(LodePNGInfo* info) -{ - LodePNGIText_cleanup(info); -} - -unsigned lodepng_add_itext(LodePNGInfo* info, const char* key, const char* langtag, - const char* transkey, const char* str) -{ - char** new_keys = (char**)(lodepng_realloc(info->itext_keys, sizeof(char*) * (info->itext_num + 1))); - char** new_langtags = (char**)(lodepng_realloc(info->itext_langtags, sizeof(char*) * (info->itext_num + 1))); - char** new_transkeys = (char**)(lodepng_realloc(info->itext_transkeys, sizeof(char*) * (info->itext_num + 1))); - char** new_strings = (char**)(lodepng_realloc(info->itext_strings, sizeof(char*) * (info->itext_num + 1))); - if(!new_keys || !new_langtags || !new_transkeys || !new_strings) - { - lodepng_free(new_keys); - lodepng_free(new_langtags); - lodepng_free(new_transkeys); - lodepng_free(new_strings); - return 83; /*alloc fail*/ - } - - info->itext_num++; - info->itext_keys = new_keys; - info->itext_langtags = new_langtags; - info->itext_transkeys = new_transkeys; - info->itext_strings = new_strings; - - string_init(&info->itext_keys[info->itext_num - 1]); - string_set(&info->itext_keys[info->itext_num - 1], key); - - string_init(&info->itext_langtags[info->itext_num - 1]); - string_set(&info->itext_langtags[info->itext_num - 1], langtag); - - string_init(&info->itext_transkeys[info->itext_num - 1]); - string_set(&info->itext_transkeys[info->itext_num - 1], transkey); - - string_init(&info->itext_strings[info->itext_num - 1]); - string_set(&info->itext_strings[info->itext_num - 1], str); - - return 0; -} -#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ - -void lodepng_info_init(LodePNGInfo* info) -{ - lodepng_color_mode_init(&info->color); - info->interlace_method = 0; - info->compression_method = 0; - info->filter_method = 0; -#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - info->background_defined = 0; - info->background_r = info->background_g = info->background_b = 0; - - LodePNGText_init(info); - LodePNGIText_init(info); - - info->time_defined = 0; - info->phys_defined = 0; - - LodePNGUnknownChunks_init(info); -#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ -} - -void lodepng_info_cleanup(LodePNGInfo* info) -{ - lodepng_color_mode_cleanup(&info->color); -#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - LodePNGText_cleanup(info); - LodePNGIText_cleanup(info); - - LodePNGUnknownChunks_cleanup(info); -#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ -} - -unsigned lodepng_info_copy(LodePNGInfo* dest, const LodePNGInfo* source) -{ - lodepng_info_cleanup(dest); - *dest = *source; - lodepng_color_mode_init(&dest->color); - CERROR_TRY_RETURN(lodepng_color_mode_copy(&dest->color, &source->color)); - -#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - CERROR_TRY_RETURN(LodePNGText_copy(dest, source)); - CERROR_TRY_RETURN(LodePNGIText_copy(dest, source)); - - LodePNGUnknownChunks_init(dest); - CERROR_TRY_RETURN(LodePNGUnknownChunks_copy(dest, source)); -#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ - return 0; -} - -void lodepng_info_swap(LodePNGInfo* a, LodePNGInfo* b) -{ - LodePNGInfo temp = *a; - *a = *b; - *b = temp; -} - -/* ////////////////////////////////////////////////////////////////////////// */ - -/*index: bitgroup index, bits: bitgroup size(1, 2 or 4), in: bitgroup value, out: octet array to add bits to*/ -static void addColorBits(unsigned char* out, size_t index, unsigned bits, unsigned in) -{ - unsigned m = bits == 1 ? 7 : bits == 2 ? 3 : 1; /*8 / bits - 1*/ - /*p = the partial index in the byte, e.g. with 4 palettebits it is 0 for first half or 1 for second half*/ - unsigned p = index & m; - in &= (1u << bits) - 1u; /*filter out any other bits of the input value*/ - in = in << (bits * (m - p)); - if(p == 0) out[index * bits / 8] = in; - else out[index * bits / 8] |= in; -} - -typedef struct ColorTree ColorTree; - -/* -One node of a color tree -This is the data structure used to count the number of unique colors and to get a palette -index for a color. It's like an octree, but because the alpha channel is used too, each -node has 16 instead of 8 children. -*/ -struct ColorTree -{ - ColorTree* children[16]; /*up to 16 pointers to ColorTree of next level*/ - int index; /*the payload. Only has a meaningful value if this is in the last level*/ -}; - -static void color_tree_init(ColorTree* tree) -{ - int i; - for(i = 0; i < 16; i++) tree->children[i] = 0; - tree->index = -1; -} - -static void color_tree_cleanup(ColorTree* tree) -{ - int i; - for(i = 0; i < 16; i++) - { - if(tree->children[i]) - { - color_tree_cleanup(tree->children[i]); - lodepng_free(tree->children[i]); - } - } -} - -/*returns -1 if color not present, its index otherwise*/ -static int color_tree_get(ColorTree* tree, unsigned char r, unsigned char g, unsigned char b, unsigned char a) -{ - int bit = 0; - for(bit = 0; bit < 8; bit++) - { - int i = 8 * ((r >> bit) & 1) + 4 * ((g >> bit) & 1) + 2 * ((b >> bit) & 1) + 1 * ((a >> bit) & 1); - if(!tree->children[i]) return -1; - else tree = tree->children[i]; - } - return tree ? tree->index : -1; -} - -#ifdef LODEPNG_COMPILE_ENCODER -static int color_tree_has(ColorTree* tree, unsigned char r, unsigned char g, unsigned char b, unsigned char a) -{ - return color_tree_get(tree, r, g, b, a) >= 0; -} -#endif /*LODEPNG_COMPILE_ENCODER*/ - -/*color is not allowed to already exist. -Index should be >= 0 (it's signed to be compatible with using -1 for "doesn't exist")*/ -static void color_tree_add(ColorTree* tree, - unsigned char r, unsigned char g, unsigned char b, unsigned char a, unsigned index) -{ - int bit; - for(bit = 0; bit < 8; bit++) - { - int i = 8 * ((r >> bit) & 1) + 4 * ((g >> bit) & 1) + 2 * ((b >> bit) & 1) + 1 * ((a >> bit) & 1); - if(!tree->children[i]) - { - tree->children[i] = (ColorTree*)lodepng_malloc(sizeof(ColorTree)); - color_tree_init(tree->children[i]); - } - tree = tree->children[i]; - } - tree->index = (int)index; -} - -/*put a pixel, given its RGBA color, into image of any color type*/ -static unsigned rgba8ToPixel(unsigned char* out, size_t i, - const LodePNGColorMode* mode, ColorTree* tree /*for palette*/, - unsigned char r, unsigned char g, unsigned char b, unsigned char a) -{ - if(mode->colortype == LCT_GREY) - { - unsigned char grey = r; /*((unsigned short)r + g + b) / 3*/; - if(mode->bitdepth == 8) out[i] = grey; - else if(mode->bitdepth == 16) out[i * 2 + 0] = out[i * 2 + 1] = grey; - else - { - /*take the most significant bits of grey*/ - grey = (grey >> (8 - mode->bitdepth)) & ((1 << mode->bitdepth) - 1); - addColorBits(out, i, mode->bitdepth, grey); - } - } - else if(mode->colortype == LCT_RGB) - { - if(mode->bitdepth == 8) - { - out[i * 3 + 0] = r; - out[i * 3 + 1] = g; - out[i * 3 + 2] = b; - } - else - { - out[i * 6 + 0] = out[i * 6 + 1] = r; - out[i * 6 + 2] = out[i * 6 + 3] = g; - out[i * 6 + 4] = out[i * 6 + 5] = b; - } - } - else if(mode->colortype == LCT_PALETTE) - { - int index = color_tree_get(tree, r, g, b, a); - if(index < 0) return 82; /*color not in palette*/ - if(mode->bitdepth == 8) out[i] = index; - else addColorBits(out, i, mode->bitdepth, (unsigned)index); - } - else if(mode->colortype == LCT_GREY_ALPHA) - { - unsigned char grey = r; /*((unsigned short)r + g + b) / 3*/; - if(mode->bitdepth == 8) - { - out[i * 2 + 0] = grey; - out[i * 2 + 1] = a; - } - else if(mode->bitdepth == 16) - { - out[i * 4 + 0] = out[i * 4 + 1] = grey; - out[i * 4 + 2] = out[i * 4 + 3] = a; - } - } - else if(mode->colortype == LCT_RGBA) - { - if(mode->bitdepth == 8) - { - out[i * 4 + 0] = r; - out[i * 4 + 1] = g; - out[i * 4 + 2] = b; - out[i * 4 + 3] = a; - } - else - { - out[i * 8 + 0] = out[i * 8 + 1] = r; - out[i * 8 + 2] = out[i * 8 + 3] = g; - out[i * 8 + 4] = out[i * 8 + 5] = b; - out[i * 8 + 6] = out[i * 8 + 7] = a; - } - } - - return 0; /*no error*/ -} - -/*put a pixel, given its RGBA16 color, into image of any color 16-bitdepth type*/ -static unsigned rgba16ToPixel(unsigned char* out, size_t i, - const LodePNGColorMode* mode, - unsigned short r, unsigned short g, unsigned short b, unsigned short a) -{ - if(mode->bitdepth != 16) return 85; /*must be 16 for this function*/ - if(mode->colortype == LCT_GREY) - { - unsigned short grey = r; /*((unsigned)r + g + b) / 3*/; - out[i * 2 + 0] = (grey >> 8) & 255; - out[i * 2 + 1] = grey & 255; - } - else if(mode->colortype == LCT_RGB) - { - out[i * 6 + 0] = (r >> 8) & 255; - out[i * 6 + 1] = r & 255; - out[i * 6 + 2] = (g >> 8) & 255; - out[i * 6 + 3] = g & 255; - out[i * 6 + 4] = (b >> 8) & 255; - out[i * 6 + 5] = b & 255; - } - else if(mode->colortype == LCT_GREY_ALPHA) - { - unsigned short grey = r; /*((unsigned)r + g + b) / 3*/; - out[i * 4 + 0] = (grey >> 8) & 255; - out[i * 4 + 1] = grey & 255; - out[i * 4 + 2] = (a >> 8) & 255; - out[i * 4 + 3] = a & 255; - } - else if(mode->colortype == LCT_RGBA) - { - out[i * 8 + 0] = (r >> 8) & 255; - out[i * 8 + 1] = r & 255; - out[i * 8 + 2] = (g >> 8) & 255; - out[i * 8 + 3] = g & 255; - out[i * 8 + 4] = (b >> 8) & 255; - out[i * 8 + 5] = b & 255; - out[i * 8 + 6] = (a >> 8) & 255; - out[i * 8 + 7] = a & 255; - } - - return 0; /*no error*/ -} - -/*Get RGBA8 color of pixel with index i (y * width + x) from the raw image with given color type.*/ -static unsigned getPixelColorRGBA8(unsigned char* r, unsigned char* g, - unsigned char* b, unsigned char* a, - const unsigned char* in, size_t i, - const LodePNGColorMode* mode, - unsigned fix_png) -{ - if(mode->colortype == LCT_GREY) - { - if(mode->bitdepth == 8) - { - *r = *g = *b = in[i]; - if(mode->key_defined && *r == mode->key_r) *a = 0; - else *a = 255; - } - else if(mode->bitdepth == 16) - { - *r = *g = *b = in[i * 2 + 0]; - if(mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r) *a = 0; - else *a = 255; - } - else - { - unsigned highest = ((1U << mode->bitdepth) - 1U); /*highest possible value for this bit depth*/ - size_t j = i * mode->bitdepth; - unsigned value = readBitsFromReversedStream(&j, in, mode->bitdepth); - *r = *g = *b = (value * 255) / highest; - if(mode->key_defined && value == mode->key_r) *a = 0; - else *a = 255; - } - } - else if(mode->colortype == LCT_RGB) - { - if(mode->bitdepth == 8) - { - *r = in[i * 3 + 0]; *g = in[i * 3 + 1]; *b = in[i * 3 + 2]; - if(mode->key_defined && *r == mode->key_r && *g == mode->key_g && *b == mode->key_b) *a = 0; - else *a = 255; - } - else - { - *r = in[i * 6 + 0]; - *g = in[i * 6 + 2]; - *b = in[i * 6 + 4]; - if(mode->key_defined && 256U * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r - && 256U * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g - && 256U * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b) *a = 0; - else *a = 255; - } - } - else if(mode->colortype == LCT_PALETTE) - { - unsigned index; - if(mode->bitdepth == 8) index = in[i]; - else - { - size_t j = i * mode->bitdepth; - index = readBitsFromReversedStream(&j, in, mode->bitdepth); - } - - if(index >= mode->palettesize) - { - /*This is an error according to the PNG spec, but fix_png can ignore it*/ - if(!fix_png) return (mode->bitdepth == 8 ? 46 : 47); /*index out of palette*/ - *r = *g = *b = 0; - *a = 255; - } - else - { - *r = mode->palette[index * 4 + 0]; - *g = mode->palette[index * 4 + 1]; - *b = mode->palette[index * 4 + 2]; - *a = mode->palette[index * 4 + 3]; - } - } - else if(mode->colortype == LCT_GREY_ALPHA) - { - if(mode->bitdepth == 8) - { - *r = *g = *b = in[i * 2 + 0]; - *a = in[i * 2 + 1]; - } - else - { - *r = *g = *b = in[i * 4 + 0]; - *a = in[i * 4 + 2]; - } - } - else if(mode->colortype == LCT_RGBA) - { - if(mode->bitdepth == 8) - { - *r = in[i * 4 + 0]; - *g = in[i * 4 + 1]; - *b = in[i * 4 + 2]; - *a = in[i * 4 + 3]; - } - else - { - *r = in[i * 8 + 0]; - *g = in[i * 8 + 2]; - *b = in[i * 8 + 4]; - *a = in[i * 8 + 6]; - } - } - - return 0; /*no error*/ -} - -/*Similar to getPixelColorRGBA8, but with all the for loops inside of the color -mode test cases, optimized to convert the colors much faster, when converting -to RGBA or RGB with 8 bit per cannel. buffer must be RGBA or RGB output with -enough memory, if has_alpha is true the output is RGBA. mode has the color mode -of the input buffer.*/ -static unsigned getPixelColorsRGBA8(unsigned char* buffer, size_t numpixels, - unsigned has_alpha, const unsigned char* in, - const LodePNGColorMode* mode, - unsigned fix_png) -{ - unsigned num_channels = has_alpha ? 4 : 3; - size_t i; - if(mode->colortype == LCT_GREY) - { - if(mode->bitdepth == 8) - { - for(i = 0; i < numpixels; i++, buffer += num_channels) - { - buffer[0] = buffer[1] = buffer[2] = in[i]; - if(has_alpha) buffer[3] = mode->key_defined && in[i] == mode->key_r ? 0 : 255; - } - } - else if(mode->bitdepth == 16) - { - for(i = 0; i < numpixels; i++, buffer += num_channels) - { - buffer[0] = buffer[1] = buffer[2] = in[i * 2]; - if(has_alpha) buffer[3] = mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r ? 0 : 255; - } - } - else - { - unsigned highest = ((1U << mode->bitdepth) - 1U); /*highest possible value for this bit depth*/ - size_t j = 0; - for(i = 0; i < numpixels; i++, buffer += num_channels) - { - unsigned value = readBitsFromReversedStream(&j, in, mode->bitdepth); - buffer[0] = buffer[1] = buffer[2] = (value * 255) / highest; - if(has_alpha) buffer[3] = mode->key_defined && value == mode->key_r ? 0 : 255; - } - } - } - else if(mode->colortype == LCT_RGB) - { - if(mode->bitdepth == 8) - { - for(i = 0; i < numpixels; i++, buffer += num_channels) - { - buffer[0] = in[i * 3 + 0]; - buffer[1] = in[i * 3 + 1]; - buffer[2] = in[i * 3 + 2]; - if(has_alpha) buffer[3] = mode->key_defined && buffer[0] == mode->key_r - && buffer[1]== mode->key_g && buffer[2] == mode->key_b ? 0 : 255; - } - } - else - { - for(i = 0; i < numpixels; i++, buffer += num_channels) - { - buffer[0] = in[i * 6 + 0]; - buffer[1] = in[i * 6 + 2]; - buffer[2] = in[i * 6 + 4]; - if(has_alpha) buffer[3] = mode->key_defined - && 256U * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r - && 256U * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g - && 256U * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b ? 0 : 255; - } - } - } - else if(mode->colortype == LCT_PALETTE) - { - unsigned index; - size_t j = 0; - for(i = 0; i < numpixels; i++, buffer += num_channels) - { - if(mode->bitdepth == 8) index = in[i]; - else index = readBitsFromReversedStream(&j, in, mode->bitdepth); - - if(index >= mode->palettesize) - { - /*This is an error according to the PNG spec, but fix_png can ignore it*/ - if(!fix_png) return (mode->bitdepth == 8 ? 46 : 47); /*index out of palette*/ - buffer[0] = buffer[1] = buffer[2] = 0; - if(has_alpha) buffer[3] = 255; - } - else - { - buffer[0] = mode->palette[index * 4 + 0]; - buffer[1] = mode->palette[index * 4 + 1]; - buffer[2] = mode->palette[index * 4 + 2]; - if(has_alpha) buffer[3] = mode->palette[index * 4 + 3]; - } - } - } - else if(mode->colortype == LCT_GREY_ALPHA) - { - if(mode->bitdepth == 8) - { - for(i = 0; i < numpixels; i++, buffer += num_channels) - { - buffer[0] = buffer[1] = buffer[2] = in[i * 2 + 0]; - if(has_alpha) buffer[3] = in[i * 2 + 1]; - } - } - else - { - for(i = 0; i < numpixels; i++, buffer += num_channels) - { - buffer[0] = buffer[1] = buffer[2] = in[i * 4 + 0]; - if(has_alpha) buffer[3] = in[i * 4 + 2]; - } - } - } - else if(mode->colortype == LCT_RGBA) - { - if(mode->bitdepth == 8) - { - for(i = 0; i < numpixels; i++, buffer += num_channels) - { - buffer[0] = in[i * 4 + 0]; - buffer[1] = in[i * 4 + 1]; - buffer[2] = in[i * 4 + 2]; - if(has_alpha) buffer[3] = in[i * 4 + 3]; - } - } - else - { - for(i = 0; i < numpixels; i++, buffer += num_channels) - { - buffer[0] = in[i * 8 + 0]; - buffer[1] = in[i * 8 + 2]; - buffer[2] = in[i * 8 + 4]; - if(has_alpha) buffer[3] = in[i * 8 + 6]; - } - } - } - - return 0; /*no error*/ -} - -/*Get RGBA16 color of pixel with index i (y * width + x) from the raw image with -given color type, but the given color type must be 16-bit itself.*/ -static unsigned getPixelColorRGBA16(unsigned short* r, unsigned short* g, unsigned short* b, unsigned short* a, - const unsigned char* in, size_t i, const LodePNGColorMode* mode) -{ - if(mode->bitdepth != 16) return 85; /*error: this function only supports 16-bit input*/ - - if(mode->colortype == LCT_GREY) - { - *r = *g = *b = 256 * in[i * 2 + 0] + in[i * 2 + 1]; - if(mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r) *a = 0; - else *a = 65535; - } - else if(mode->colortype == LCT_RGB) - { - *r = 256 * in[i * 6 + 0] + in[i * 6 + 1]; - *g = 256 * in[i * 6 + 2] + in[i * 6 + 3]; - *b = 256 * in[i * 6 + 4] + in[i * 6 + 5]; - if(mode->key_defined && 256U * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r - && 256U * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g - && 256U * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b) *a = 0; - else *a = 65535; - } - else if(mode->colortype == LCT_GREY_ALPHA) - { - *r = *g = *b = 256 * in[i * 4 + 0] + in[i * 4 + 1]; - *a = 256 * in[i * 4 + 2] + in[i * 4 + 3]; - } - else if(mode->colortype == LCT_RGBA) - { - *r = 256 * in[i * 8 + 0] + in[i * 8 + 1]; - *g = 256 * in[i * 8 + 2] + in[i * 8 + 3]; - *b = 256 * in[i * 8 + 4] + in[i * 8 + 5]; - *a = 256 * in[i * 8 + 6] + in[i * 8 + 7]; - } - else return 85; /*error: this function only supports 16-bit input, not palettes*/ - - return 0; /*no error*/ -} - -/* -converts from any color type to 24-bit or 32-bit (later maybe more supported). return value = LodePNG error code -the out buffer must have (w * h * bpp + 7) / 8 bytes, where bpp is the bits per pixel of the output color type -(lodepng_get_bpp) for < 8 bpp images, there may _not_ be padding bits at the end of scanlines. -*/ -unsigned lodepng_convert(unsigned char* out, const unsigned char* in, - LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in, - unsigned w, unsigned h, unsigned fix_png) -{ - unsigned error = 0; - size_t i; - ColorTree tree; - size_t numpixels = w * h; - - if(lodepng_color_mode_equal(mode_out, mode_in)) - { - size_t numbytes = lodepng_get_raw_size(w, h, mode_in); - for(i = 0; i < numbytes; i++) out[i] = in[i]; - return error; - } - - if(mode_out->colortype == LCT_PALETTE) - { - size_t palsize = 1u << mode_out->bitdepth; - if(mode_out->palettesize < palsize) palsize = mode_out->palettesize; - color_tree_init(&tree); - for(i = 0; i < palsize; i++) - { - unsigned char* p = &mode_out->palette[i * 4]; - color_tree_add(&tree, p[0], p[1], p[2], p[3], i); - } - } - - if(mode_in->bitdepth == 16 && mode_out->bitdepth == 16) - { - for(i = 0; i < numpixels; i++) - { - unsigned short r = 0, g = 0, b = 0, a = 0; - error = getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode_in); - if(error) break; - error = rgba16ToPixel(out, i, mode_out, r, g, b, a); - if(error) break; - } - } - else if(mode_out->bitdepth == 8 && mode_out->colortype == LCT_RGBA) - { - error = getPixelColorsRGBA8(out, numpixels, 1, in, mode_in, fix_png); - } - else if(mode_out->bitdepth == 8 && mode_out->colortype == LCT_RGB) - { - error = getPixelColorsRGBA8(out, numpixels, 0, in, mode_in, fix_png); - } - else - { - unsigned char r = 0, g = 0, b = 0, a = 0; - for(i = 0; i < numpixels; i++) - { - error = getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode_in, fix_png); - if(error) break; - error = rgba8ToPixel(out, i, mode_out, &tree, r, g, b, a); - if(error) break; - } - } - - if(mode_out->colortype == LCT_PALETTE) - { - color_tree_cleanup(&tree); - } - - return error; -} - -#ifdef LODEPNG_COMPILE_ENCODER - -typedef struct ColorProfile -{ - unsigned char sixteenbit; /*needs more than 8 bits per channel*/ - unsigned char sixteenbit_done; - - - unsigned char colored; /*not greyscale*/ - unsigned char colored_done; - - unsigned char key; /*a color key is required, or more*/ - unsigned short key_r; /*these values are always in 16-bit bitdepth in the profile*/ - unsigned short key_g; - unsigned short key_b; - unsigned char alpha; /*alpha channel, or alpha palette, required*/ - unsigned char alpha_done; - - unsigned numcolors; - ColorTree tree; /*for listing the counted colors, up to 256*/ - unsigned char* palette; /*size 1024. Remember up to the first 256 RGBA colors*/ - unsigned maxnumcolors; /*if more than that amount counted*/ - unsigned char numcolors_done; - - unsigned greybits; /*amount of bits required for greyscale (1, 2, 4, 8). Does not take 16 bit into account.*/ - unsigned char greybits_done; - -} ColorProfile; - -static void color_profile_init(ColorProfile* profile, const LodePNGColorMode* mode) -{ - profile->sixteenbit = 0; - profile->sixteenbit_done = mode->bitdepth == 16 ? 0 : 1; - - profile->colored = 0; - profile->colored_done = lodepng_is_greyscale_type(mode) ? 1 : 0; - - profile->key = 0; - profile->alpha = 0; - profile->alpha_done = lodepng_can_have_alpha(mode) ? 0 : 1; - - profile->numcolors = 0; - color_tree_init(&profile->tree); - profile->palette = (unsigned char*)lodepng_malloc(1024); - profile->maxnumcolors = 257; - if(lodepng_get_bpp(mode) <= 8) - { - unsigned bpp = lodepng_get_bpp(mode); - profile->maxnumcolors = bpp == 1 ? 2 : (bpp == 2 ? 4 : (bpp == 4 ? 16 : 256)); - } - profile->numcolors_done = 0; - - profile->greybits = 1; - profile->greybits_done = lodepng_get_bpp(mode) == 1 ? 1 : 0; -} - -static void color_profile_cleanup(ColorProfile* profile) -{ - color_tree_cleanup(&profile->tree); - lodepng_free(profile->palette); -} - -/*function used for debug purposes with C++*/ -/*void printColorProfile(ColorProfile* p) -{ - std::cout << "sixteenbit: " << (int)p->sixteenbit << std::endl; - std::cout << "sixteenbit_done: " << (int)p->sixteenbit_done << std::endl; - std::cout << "colored: " << (int)p->colored << std::endl; - std::cout << "colored_done: " << (int)p->colored_done << std::endl; - std::cout << "key: " << (int)p->key << std::endl; - std::cout << "key_r: " << (int)p->key_r << std::endl; - std::cout << "key_g: " << (int)p->key_g << std::endl; - std::cout << "key_b: " << (int)p->key_b << std::endl; - std::cout << "alpha: " << (int)p->alpha << std::endl; - std::cout << "alpha_done: " << (int)p->alpha_done << std::endl; - std::cout << "numcolors: " << (int)p->numcolors << std::endl; - std::cout << "maxnumcolors: " << (int)p->maxnumcolors << std::endl; - std::cout << "numcolors_done: " << (int)p->numcolors_done << std::endl; - std::cout << "greybits: " << (int)p->greybits << std::endl; - std::cout << "greybits_done: " << (int)p->greybits_done << std::endl; -}*/ - -/*Returns how many bits needed to represent given value (max 8 bit)*/ -unsigned getValueRequiredBits(unsigned short value) -{ - if(value == 0 || value == 255) return 1; - /*The scaling of 2-bit and 4-bit values uses multiples of 85 and 17*/ - if(value % 17 == 0) return value % 85 == 0 ? 2 : 4; - return 8; -} - -/*profile must already have been inited with mode. -It's ok to set some parameters of profile to done already.*/ -static unsigned get_color_profile(ColorProfile* profile, - const unsigned char* in, - size_t numpixels /*must be full image size, for certain filesize based choices*/, - const LodePNGColorMode* mode, - unsigned fix_png) -{ - unsigned error = 0; - size_t i; - - if(mode->bitdepth == 16) - { - for(i = 0; i < numpixels; i++) - { - unsigned short r, g, b, a; - error = getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode); - if(error) break; - - /*a color is considered good for 8-bit if the first byte and the second byte are equal, - (so if it's divisible through 257), NOT necessarily if the second byte is 0*/ - if(!profile->sixteenbit_done - && (((r & 255) != ((r >> 8) & 255)) - || ((g & 255) != ((g >> 8) & 255)) - || ((b & 255) != ((b >> 8) & 255)))) - { - profile->sixteenbit = 1; - profile->sixteenbit_done = 1; - profile->greybits_done = 1; /*greybits is not applicable anymore at 16-bit*/ - profile->numcolors_done = 1; /*counting colors no longer useful, palette doesn't support 16-bit*/ - } - - if(!profile->colored_done && (r != g || r != b)) - { - profile->colored = 1; - profile->colored_done = 1; - profile->greybits_done = 1; /*greybits is not applicable anymore*/ - } - - if(!profile->alpha_done && a != 65535) - { - /*only use color key if numpixels large enough to justify tRNS chunk size*/ - if(a == 0 && numpixels > 16 && !(profile->key && (r != profile->key_r || g != profile->key_g || b != profile->key_b))) - { - if(!profile->alpha && !profile->key) - { - profile->key = 1; - profile->key_r = r; - profile->key_g = g; - profile->key_b = b; - } - } - else - { - profile->alpha = 1; - profile->alpha_done = 1; - profile->greybits_done = 1; /*greybits is not applicable anymore*/ - } - } - - /* Color key cannot be used if an opaque pixel also has that RGB color. */ - if(!profile->alpha_done && a == 65535 && profile->key - && r == profile->key_r && g == profile->key_g && b == profile->key_b) - { - profile->alpha = 1; - profile->alpha_done = 1; - profile->greybits_done = 1; /*greybits is not applicable anymore*/ - } - - if(!profile->greybits_done) - { - /*assuming 8-bit r, this test does not care about 16-bit*/ - unsigned bits = getValueRequiredBits(r); - if(bits > profile->greybits) profile->greybits = bits; - if(profile->greybits >= 8) profile->greybits_done = 1; - } - - if(!profile->numcolors_done) - { - /*assuming 8-bit rgba, this test does not care about 16-bit*/ - if(!color_tree_has(&profile->tree, (unsigned char)r, (unsigned char)g, (unsigned char)b, (unsigned char)a)) - { - color_tree_add(&profile->tree, (unsigned char)r, (unsigned char)g, (unsigned char)b, (unsigned char)a, - profile->numcolors); - if(profile->numcolors < 256) - { - unsigned char* p = profile->palette; - unsigned i = profile->numcolors; - p[i * 4 + 0] = (unsigned char)r; - p[i * 4 + 1] = (unsigned char)g; - p[i * 4 + 2] = (unsigned char)b; - p[i * 4 + 3] = (unsigned char)a; - } - profile->numcolors++; - if(profile->numcolors >= profile->maxnumcolors) profile->numcolors_done = 1; - } - } - - if(profile->alpha_done && profile->numcolors_done - && profile->colored_done && profile->sixteenbit_done && profile->greybits_done) - { - break; - } - }; - } - else /* < 16-bit */ - { - for(i = 0; i < numpixels; i++) - { - unsigned char r = 0, g = 0, b = 0, a = 0; - error = getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode, fix_png); - if(error) break; - - if(!profile->colored_done && (r != g || r != b)) - { - profile->colored = 1; - profile->colored_done = 1; - profile->greybits_done = 1; /*greybits is not applicable anymore*/ - } - - if(!profile->alpha_done && a != 255) - { - if(a == 0 && !(profile->key && (r != profile->key_r || g != profile->key_g || b != profile->key_b))) - { - if(!profile->key) - { - profile->key = 1; - profile->key_r = r; - profile->key_g = g; - profile->key_b = b; - } - } - else - { - profile->alpha = 1; - profile->alpha_done = 1; - profile->greybits_done = 1; /*greybits is not applicable anymore*/ - } - } - - /* Color key cannot be used if an opaque pixel also has that RGB color. */ - if(!profile->alpha_done && a == 255 && profile->key - && r == profile->key_r && g == profile->key_g && b == profile->key_b) - { - profile->alpha = 1; - profile->alpha_done = 1; - profile->greybits_done = 1; /*greybits is not applicable anymore*/ - } - - if(!profile->greybits_done) - { - unsigned bits = getValueRequiredBits(r); - if(bits > profile->greybits) profile->greybits = bits; - if(profile->greybits >= 8) profile->greybits_done = 1; - } - - if(!profile->numcolors_done) - { - if(!color_tree_has(&profile->tree, r, g, b, a)) - { - color_tree_add(&profile->tree, r, g, b, a, profile->numcolors); - if(profile->numcolors < 256) - { - unsigned char* p = profile->palette; - unsigned i = profile->numcolors; - p[i * 4 + 0] = r; - p[i * 4 + 1] = g; - p[i * 4 + 2] = b; - p[i * 4 + 3] = a; - } - profile->numcolors++; - if(profile->numcolors >= profile->maxnumcolors) profile->numcolors_done = 1; - } - } - - if(profile->alpha_done && profile->numcolors_done && profile->colored_done && profile->greybits_done) - { - break; - } - }; - } - - /*make the profile's key always 16-bit for consistency*/ - if(mode->bitdepth < 16) - { - /*repeat each byte twice*/ - profile->key_r *= 257; - profile->key_g *= 257; - profile->key_b *= 257; - } - - return error; -} - -static void setColorKeyFrom16bit(LodePNGColorMode* mode_out, unsigned r, unsigned g, unsigned b, unsigned bitdepth) -{ - unsigned mask = (1u << bitdepth) - 1u; - mode_out->key_defined = 1; - mode_out->key_r = r & mask; - mode_out->key_g = g & mask; - mode_out->key_b = b & mask; -} - -/*updates values of mode with a potentially smaller color model. mode_out should -contain the user chosen color model, but will be overwritten with the new chosen one.*/ -unsigned lodepng_auto_choose_color(LodePNGColorMode* mode_out, - const unsigned char* image, unsigned w, unsigned h, - const LodePNGColorMode* mode_in, - LodePNGAutoConvert auto_convert) -{ - ColorProfile profile; - unsigned error = 0; - int no_nibbles = auto_convert == LAC_AUTO_NO_NIBBLES || auto_convert == LAC_AUTO_NO_NIBBLES_NO_PALETTE; - int no_palette = auto_convert == LAC_AUTO_NO_PALETTE || auto_convert == LAC_AUTO_NO_NIBBLES_NO_PALETTE; - - if(auto_convert == LAC_ALPHA) - { - if(mode_out->colortype != LCT_RGBA && mode_out->colortype != LCT_GREY_ALPHA) return 0; - } - - color_profile_init(&profile, mode_in); - if(auto_convert == LAC_ALPHA) - { - profile.colored_done = 1; - profile.greybits_done = 1; - profile.numcolors_done = 1; - profile.sixteenbit_done = 1; - } - error = get_color_profile(&profile, image, w * h, mode_in, 0 /*fix_png*/); - if(!error && auto_convert == LAC_ALPHA) - { - if(!profile.alpha) - { - mode_out->colortype = (mode_out->colortype == LCT_RGBA ? LCT_RGB : LCT_GREY); - if(profile.key) setColorKeyFrom16bit(mode_out, profile.key_r, profile.key_g, profile.key_b, mode_out->bitdepth); - } - } - else if(!error && auto_convert != LAC_ALPHA) - { - mode_out->key_defined = 0; - - if(profile.sixteenbit) - { - mode_out->bitdepth = 16; - if(profile.alpha) - { - mode_out->colortype = profile.colored ? LCT_RGBA : LCT_GREY_ALPHA; - } - else - { - mode_out->colortype = profile.colored ? LCT_RGB : LCT_GREY; - if(profile.key) setColorKeyFrom16bit(mode_out, profile.key_r, profile.key_g, profile.key_b, mode_out->bitdepth); - } - } - else /*less than 16 bits per channel*/ - { - /*don't add palette overhead if image hasn't got a lot of pixels*/ - unsigned n = profile.numcolors; - int palette_ok = !no_palette && n <= 256 && (n * 2 < w * h); - unsigned palettebits = n <= 2 ? 1 : (n <= 4 ? 2 : (n <= 16 ? 4 : 8)); - int grey_ok = !profile.colored && !profile.alpha; /*grey without alpha, with potentially low bits*/ - if(palette_ok || grey_ok) - { - if(!palette_ok || (grey_ok && profile.greybits <= palettebits)) - { - unsigned grey = profile.key_r; - mode_out->colortype = LCT_GREY; - mode_out->bitdepth = profile.greybits; - if(profile.key) setColorKeyFrom16bit(mode_out, grey, grey, grey, mode_out->bitdepth); - } - else - { - /*fill in the palette*/ - unsigned i; - unsigned char* p = profile.palette; - /*remove potential earlier palette*/ - lodepng_palette_clear(mode_out); - for(i = 0; i < profile.numcolors; i++) - { - error = lodepng_palette_add(mode_out, p[i * 4 + 0], p[i * 4 + 1], p[i * 4 + 2], p[i * 4 + 3]); - if(error) break; - } - - mode_out->colortype = LCT_PALETTE; - mode_out->bitdepth = palettebits; - } - } - else /*8-bit per channel*/ - { - mode_out->bitdepth = 8; - if(profile.alpha) - { - mode_out->colortype = profile.colored ? LCT_RGBA : LCT_GREY_ALPHA; - } - else - { - mode_out->colortype = profile.colored ? LCT_RGB : LCT_GREY /*LCT_GREY normally won't occur, already done earlier*/; - if(profile.key) setColorKeyFrom16bit(mode_out, profile.key_r, profile.key_g, profile.key_b, mode_out->bitdepth); - } - } - } - } - - color_profile_cleanup(&profile); - - if(mode_out->colortype == LCT_PALETTE && mode_in->palettesize == mode_out->palettesize) - { - /*In this case keep the palette order of the input, so that the user can choose an optimal one*/ - size_t i; - for(i = 0; i < mode_in->palettesize * 4; i++) - { - mode_out->palette[i] = mode_in->palette[i]; - } - } - - if(no_nibbles && mode_out->bitdepth < 8) - { - /*palette can keep its small amount of colors, as long as no indices use it*/ - mode_out->bitdepth = 8; - } - - return error; -} - -#endif /* #ifdef LODEPNG_COMPILE_ENCODER */ - -/* -Paeth predicter, used by PNG filter type 4 -The parameters are of type short, but should come from unsigned chars, the shorts -are only needed to make the paeth calculation correct. -*/ -static unsigned char paethPredictor(short a, short b, short c) -{ - short pa = abs(b - c); - short pb = abs(a - c); - short pc = abs(a + b - c - c); - - if(pc < pa && pc < pb) return (unsigned char)c; - else if(pb < pa) return (unsigned char)b; - else return (unsigned char)a; -} - -/*shared values used by multiple Adam7 related functions*/ - -static const unsigned ADAM7_IX[7] = { 0, 4, 0, 2, 0, 1, 0 }; /*x start values*/ -static const unsigned ADAM7_IY[7] = { 0, 0, 4, 0, 2, 0, 1 }; /*y start values*/ -static const unsigned ADAM7_DX[7] = { 8, 8, 4, 4, 2, 2, 1 }; /*x delta values*/ -static const unsigned ADAM7_DY[7] = { 8, 8, 8, 4, 4, 2, 2 }; /*y delta values*/ - -/* -Outputs various dimensions and positions in the image related to the Adam7 reduced images. -passw: output containing the width of the 7 passes -passh: output containing the height of the 7 passes -filter_passstart: output containing the index of the start and end of each - reduced image with filter bytes -padded_passstart output containing the index of the start and end of each - reduced image when without filter bytes but with padded scanlines -passstart: output containing the index of the start and end of each reduced - image without padding between scanlines, but still padding between the images -w, h: width and height of non-interlaced image -bpp: bits per pixel -"padded" is only relevant if bpp is less than 8 and a scanline or image does not - end at a full byte -*/ -static void Adam7_getpassvalues(unsigned passw[7], unsigned passh[7], size_t filter_passstart[8], - size_t padded_passstart[8], size_t passstart[8], unsigned w, unsigned h, unsigned bpp) -{ - /*the passstart values have 8 values: the 8th one indicates the byte after the end of the 7th (= last) pass*/ - unsigned i; - - /*calculate width and height in pixels of each pass*/ - for(i = 0; i < 7; i++) - { - passw[i] = (w + ADAM7_DX[i] - ADAM7_IX[i] - 1) / ADAM7_DX[i]; - passh[i] = (h + ADAM7_DY[i] - ADAM7_IY[i] - 1) / ADAM7_DY[i]; - if(passw[i] == 0) passh[i] = 0; - if(passh[i] == 0) passw[i] = 0; - } - - filter_passstart[0] = padded_passstart[0] = passstart[0] = 0; - for(i = 0; i < 7; i++) - { - /*if passw[i] is 0, it's 0 bytes, not 1 (no filtertype-byte)*/ - filter_passstart[i + 1] = filter_passstart[i] - + ((passw[i] && passh[i]) ? passh[i] * (1 + (passw[i] * bpp + 7) / 8) : 0); - /*bits padded if needed to fill full byte at end of each scanline*/ - padded_passstart[i + 1] = padded_passstart[i] + passh[i] * ((passw[i] * bpp + 7) / 8); - /*only padded at end of reduced image*/ - passstart[i + 1] = passstart[i] + (passh[i] * passw[i] * bpp + 7) / 8; - } -} - -#ifdef LODEPNG_COMPILE_DECODER - -/* ////////////////////////////////////////////////////////////////////////// */ -/* / PNG Decoder / */ -/* ////////////////////////////////////////////////////////////////////////// */ - -/*read the information from the header and store it in the LodePNGInfo. return value is error*/ -unsigned lodepng_inspect(unsigned* w, unsigned* h, LodePNGState* state, - const unsigned char* in, size_t insize) -{ - LodePNGInfo* info = &state->info_png; - if(insize == 0 || in == 0) - { - CERROR_RETURN_ERROR(state->error, 48); /*error: the given data is empty*/ - } - if(insize < 29) - { - CERROR_RETURN_ERROR(state->error, 27); /*error: the data length is smaller than the length of a PNG header*/ - } - - /*when decoding a new PNG image, make sure all parameters created after previous decoding are reset*/ - lodepng_info_cleanup(info); - lodepng_info_init(info); - - if(in[0] != 137 || in[1] != 80 || in[2] != 78 || in[3] != 71 - || in[4] != 13 || in[5] != 10 || in[6] != 26 || in[7] != 10) - { - CERROR_RETURN_ERROR(state->error, 28); /*error: the first 8 bytes are not the correct PNG signature*/ - } - if(in[12] != 'I' || in[13] != 'H' || in[14] != 'D' || in[15] != 'R') - { - CERROR_RETURN_ERROR(state->error, 29); /*error: it doesn't start with a IHDR chunk!*/ - } - - /*read the values given in the header*/ - *w = lodepng_read32bitInt(&in[16]); - *h = lodepng_read32bitInt(&in[20]); - info->color.bitdepth = in[24]; - info->color.colortype = (LodePNGColorType)in[25]; - info->compression_method = in[26]; - info->filter_method = in[27]; - info->interlace_method = in[28]; - - if(!state->decoder.ignore_crc) - { - unsigned CRC = lodepng_read32bitInt(&in[29]); - unsigned checksum = lodepng_crc32(&in[12], 17); - if(CRC != checksum) - { - CERROR_RETURN_ERROR(state->error, 57); /*invalid CRC*/ - } - } - - /*error: only compression method 0 is allowed in the specification*/ - if(info->compression_method != 0) CERROR_RETURN_ERROR(state->error, 32); - /*error: only filter method 0 is allowed in the specification*/ - if(info->filter_method != 0) CERROR_RETURN_ERROR(state->error, 33); - /*error: only interlace methods 0 and 1 exist in the specification*/ - if(info->interlace_method > 1) CERROR_RETURN_ERROR(state->error, 34); - - state->error = checkColorValidity(info->color.colortype, info->color.bitdepth); - return state->error; -} - -static unsigned unfilterScanline(unsigned char* recon, const unsigned char* scanline, const unsigned char* precon, - size_t bytewidth, unsigned char filterType, size_t length) -{ - /* - For PNG filter method 0 - unfilter a PNG image scanline by scanline. when the pixels are smaller than 1 byte, - the filter works byte per byte (bytewidth = 1) - precon is the previous unfiltered scanline, recon the result, scanline the current one - the incoming scanlines do NOT include the filtertype byte, that one is given in the parameter filterType instead - recon and scanline MAY be the same memory address! precon must be disjoint. - */ - - size_t i; - switch(filterType) - { - case 0: - for(i = 0; i < length; i++) recon[i] = scanline[i]; - break; - case 1: - for(i = 0; i < bytewidth; i++) recon[i] = scanline[i]; - for(i = bytewidth; i < length; i++) recon[i] = scanline[i] + recon[i - bytewidth]; - break; - case 2: - if(precon) - { - for(i = 0; i < length; i++) recon[i] = scanline[i] + precon[i]; - } - else - { - for(i = 0; i < length; i++) recon[i] = scanline[i]; - } - break; - case 3: - if(precon) - { - for(i = 0; i < bytewidth; i++) recon[i] = scanline[i] + precon[i] / 2; - for(i = bytewidth; i < length; i++) recon[i] = scanline[i] + ((recon[i - bytewidth] + precon[i]) / 2); - } - else - { - for(i = 0; i < bytewidth; i++) recon[i] = scanline[i]; - for(i = bytewidth; i < length; i++) recon[i] = scanline[i] + recon[i - bytewidth] / 2; - } - break; - case 4: - if(precon) - { - for(i = 0; i < bytewidth; i++) - { - recon[i] = (scanline[i] + precon[i]); /*paethPredictor(0, precon[i], 0) is always precon[i]*/ - } - for(i = bytewidth; i < length; i++) - { - recon[i] = (scanline[i] + paethPredictor(recon[i - bytewidth], precon[i], precon[i - bytewidth])); - } - } - else - { - for(i = 0; i < bytewidth; i++) - { - recon[i] = scanline[i]; - } - for(i = bytewidth; i < length; i++) - { - /*paethPredictor(recon[i - bytewidth], 0, 0) is always recon[i - bytewidth]*/ - recon[i] = (scanline[i] + recon[i - bytewidth]); - } - } - break; - default: return 36; /*error: unexisting filter type given*/ - } - return 0; -} - -static unsigned unfilter(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp) -{ - /* - For PNG filter method 0 - this function unfilters a single image (e.g. without interlacing this is called once, with Adam7 seven times) - out must have enough bytes allocated already, in must have the scanlines + 1 filtertype byte per scanline - w and h are image dimensions or dimensions of reduced image, bpp is bits per pixel - in and out are allowed to be the same memory address (but aren't the same size since in has the extra filter bytes) - */ - - unsigned y; - unsigned char* prevline = 0; - - /*bytewidth is used for filtering, is 1 when bpp < 8, number of bytes per pixel otherwise*/ - size_t bytewidth = (bpp + 7) / 8; - size_t linebytes = (w * bpp + 7) / 8; - - for(y = 0; y < h; y++) - { - size_t outindex = linebytes * y; - size_t inindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/ - unsigned char filterType = in[inindex]; - - CERROR_TRY_RETURN(unfilterScanline(&out[outindex], &in[inindex + 1], prevline, bytewidth, filterType, linebytes)); - - prevline = &out[outindex]; - } - - return 0; -} - -/* -in: Adam7 interlaced image, with no padding bits between scanlines, but between - reduced images so that each reduced image starts at a byte. -out: the same pixels, but re-ordered so that they're now a non-interlaced image with size w*h -bpp: bits per pixel -out has the following size in bits: w * h * bpp. -in is possibly bigger due to padding bits between reduced images. -out must be big enough AND must be 0 everywhere if bpp < 8 in the current implementation -(because that's likely a little bit faster) -NOTE: comments about padding bits are only relevant if bpp < 8 -*/ -static void Adam7_deinterlace(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp) -{ - unsigned passw[7], passh[7]; - size_t filter_passstart[8], padded_passstart[8], passstart[8]; - unsigned i; - - Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); - - if(bpp >= 8) - { - for(i = 0; i < 7; i++) - { - unsigned x, y, b; - size_t bytewidth = bpp / 8; - for(y = 0; y < passh[i]; y++) - for(x = 0; x < passw[i]; x++) - { - size_t pixelinstart = passstart[i] + (y * passw[i] + x) * bytewidth; - size_t pixeloutstart = ((ADAM7_IY[i] + y * ADAM7_DY[i]) * w + ADAM7_IX[i] + x * ADAM7_DX[i]) * bytewidth; - for(b = 0; b < bytewidth; b++) - { - out[pixeloutstart + b] = in[pixelinstart + b]; - } - } - } - } - else /*bpp < 8: Adam7 with pixels < 8 bit is a bit trickier: with bit pointers*/ - { - for(i = 0; i < 7; i++) - { - unsigned x, y, b; - unsigned ilinebits = bpp * passw[i]; - unsigned olinebits = bpp * w; - size_t obp, ibp; /*bit pointers (for out and in buffer)*/ - for(y = 0; y < passh[i]; y++) - for(x = 0; x < passw[i]; x++) - { - ibp = (8 * passstart[i]) + (y * ilinebits + x * bpp); - obp = (ADAM7_IY[i] + y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + x * ADAM7_DX[i]) * bpp; - for(b = 0; b < bpp; b++) - { - unsigned char bit = readBitFromReversedStream(&ibp, in); - /*note that this function assumes the out buffer is completely 0, use setBitOfReversedStream otherwise*/ - setBitOfReversedStream0(&obp, out, bit); - } - } - } - } -} - -static void removePaddingBits(unsigned char* out, const unsigned char* in, - size_t olinebits, size_t ilinebits, unsigned h) -{ - /* - After filtering there are still padding bits if scanlines have non multiple of 8 bit amounts. They need - to be removed (except at last scanline of (Adam7-reduced) image) before working with pure image buffers - for the Adam7 code, the color convert code and the output to the user. - in and out are allowed to be the same buffer, in may also be higher but still overlapping; in must - have >= ilinebits*h bits, out must have >= olinebits*h bits, olinebits must be <= ilinebits - also used to move bits after earlier such operations happened, e.g. in a sequence of reduced images from Adam7 - only useful if (ilinebits - olinebits) is a value in the range 1..7 - */ - unsigned y; - size_t diff = ilinebits - olinebits; - size_t ibp = 0, obp = 0; /*input and output bit pointers*/ - for(y = 0; y < h; y++) - { - size_t x; - for(x = 0; x < olinebits; x++) - { - unsigned char bit = readBitFromReversedStream(&ibp, in); - setBitOfReversedStream(&obp, out, bit); - } - ibp += diff; - } -} - -/*out must be buffer big enough to contain full image, and in must contain the full decompressed data from -the IDAT chunks (with filter index bytes and possible padding bits) -return value is error*/ -static unsigned postProcessScanlines(unsigned char* out, unsigned char* in, - unsigned w, unsigned h, const LodePNGInfo* info_png) -{ - /* - This function converts the filtered-padded-interlaced data into pure 2D image buffer with the PNG's colortype. - Steps: - *) if no Adam7: 1) unfilter 2) remove padding bits (= posible extra bits per scanline if bpp < 8) - *) if adam7: 1) 7x unfilter 2) 7x remove padding bits 3) Adam7_deinterlace - NOTE: the in buffer will be overwritten with intermediate data! - */ - unsigned bpp = lodepng_get_bpp(&info_png->color); - if(bpp == 0) return 31; /*error: invalid colortype*/ - - if(info_png->interlace_method == 0) - { - if(bpp < 8 && w * bpp != ((w * bpp + 7) / 8) * 8) - { - CERROR_TRY_RETURN(unfilter(in, in, w, h, bpp)); - removePaddingBits(out, in, w * bpp, ((w * bpp + 7) / 8) * 8, h); - } - /*we can immediatly filter into the out buffer, no other steps needed*/ - else CERROR_TRY_RETURN(unfilter(out, in, w, h, bpp)); - } - else /*interlace_method is 1 (Adam7)*/ - { - unsigned passw[7], passh[7]; size_t filter_passstart[8], padded_passstart[8], passstart[8]; - unsigned i; - - Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); - - for(i = 0; i < 7; i++) - { - CERROR_TRY_RETURN(unfilter(&in[padded_passstart[i]], &in[filter_passstart[i]], passw[i], passh[i], bpp)); - /*TODO: possible efficiency improvement: if in this reduced image the bits fit nicely in 1 scanline, - move bytes instead of bits or move not at all*/ - if(bpp < 8) - { - /*remove padding bits in scanlines; after this there still may be padding - bits between the different reduced images: each reduced image still starts nicely at a byte*/ - removePaddingBits(&in[passstart[i]], &in[padded_passstart[i]], passw[i] * bpp, - ((passw[i] * bpp + 7) / 8) * 8, passh[i]); - } - } - - Adam7_deinterlace(out, in, w, h, bpp); - } - - return 0; -} - -static unsigned readChunk_PLTE(LodePNGColorMode* color, const unsigned char* data, size_t chunkLength) -{ - unsigned pos = 0, i; - if(color->palette) lodepng_free(color->palette); - color->palettesize = chunkLength / 3; - color->palette = (unsigned char*)lodepng_malloc(4 * color->palettesize); - if(!color->palette && color->palettesize) - { - color->palettesize = 0; - return 83; /*alloc fail*/ - } - if(color->palettesize > 256) return 38; /*error: palette too big*/ - - for(i = 0; i < color->palettesize; i++) - { - color->palette[4 * i + 0] = data[pos++]; /*R*/ - color->palette[4 * i + 1] = data[pos++]; /*G*/ - color->palette[4 * i + 2] = data[pos++]; /*B*/ - color->palette[4 * i + 3] = 255; /*alpha*/ - } - - return 0; /* OK */ -} - -static unsigned readChunk_tRNS(LodePNGColorMode* color, const unsigned char* data, size_t chunkLength) -{ - unsigned i; - if(color->colortype == LCT_PALETTE) - { - /*error: more alpha values given than there are palette entries*/ - if(chunkLength > color->palettesize) return 38; - - for(i = 0; i < chunkLength; i++) color->palette[4 * i + 3] = data[i]; - } - else if(color->colortype == LCT_GREY) - { - /*error: this chunk must be 2 bytes for greyscale image*/ - if(chunkLength != 2) return 30; - - color->key_defined = 1; - color->key_r = color->key_g = color->key_b = 256u * data[0] + data[1]; - } - else if(color->colortype == LCT_RGB) - { - /*error: this chunk must be 6 bytes for RGB image*/ - if(chunkLength != 6) return 41; - - color->key_defined = 1; - color->key_r = 256u * data[0] + data[1]; - color->key_g = 256u * data[2] + data[3]; - color->key_b = 256u * data[4] + data[5]; - } - else return 42; /*error: tRNS chunk not allowed for other color models*/ - - return 0; /* OK */ -} - - -#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS -/*background color chunk (bKGD)*/ -static unsigned readChunk_bKGD(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) -{ - if(info->color.colortype == LCT_PALETTE) - { - /*error: this chunk must be 1 byte for indexed color image*/ - if(chunkLength != 1) return 43; - - info->background_defined = 1; - info->background_r = info->background_g = info->background_b = data[0]; - } - else if(info->color.colortype == LCT_GREY || info->color.colortype == LCT_GREY_ALPHA) - { - /*error: this chunk must be 2 bytes for greyscale image*/ - if(chunkLength != 2) return 44; - - info->background_defined = 1; - info->background_r = info->background_g = info->background_b = 256u * data[0] + data[1]; - } - else if(info->color.colortype == LCT_RGB || info->color.colortype == LCT_RGBA) - { - /*error: this chunk must be 6 bytes for greyscale image*/ - if(chunkLength != 6) return 45; - - info->background_defined = 1; - info->background_r = 256u * data[0] + data[1]; - info->background_g = 256u * data[2] + data[3]; - info->background_b = 256u * data[4] + data[5]; - } - - return 0; /* OK */ -} - -/*text chunk (tEXt)*/ -static unsigned readChunk_tEXt(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) -{ - unsigned error = 0; - char *key = 0, *str = 0; - unsigned i; - - while(!error) /*not really a while loop, only used to break on error*/ - { - unsigned length, string2_begin; - - length = 0; - while(length < chunkLength && data[length] != 0) length++; - /*even though it's not allowed by the standard, no error is thrown if - there's no null termination char, if the text is empty*/ - if(length < 1 || length > 79) CERROR_BREAK(error, 89); /*keyword too short or long*/ - - key = (char*)lodepng_malloc(length + 1); - if(!key) CERROR_BREAK(error, 83); /*alloc fail*/ - - key[length] = 0; - for(i = 0; i < length; i++) key[i] = (char)data[i]; - - string2_begin = length + 1; /*skip keyword null terminator*/ - - length = chunkLength < string2_begin ? 0 : chunkLength - string2_begin; - str = (char*)lodepng_malloc(length + 1); - if(!str) CERROR_BREAK(error, 83); /*alloc fail*/ - - str[length] = 0; - for(i = 0; i < length; i++) str[i] = (char)data[string2_begin + i]; - - error = lodepng_add_text(info, key, str); - - break; - } - - lodepng_free(key); - lodepng_free(str); - - return error; -} - -/*compressed text chunk (zTXt)*/ -static unsigned readChunk_zTXt(LodePNGInfo* info, const LodePNGDecompressSettings* zlibsettings, - const unsigned char* data, size_t chunkLength) -{ - unsigned error = 0; - unsigned i; - - unsigned length, string2_begin; - char *key = 0; - ucvector decoded; - - ucvector_init(&decoded); - - while(!error) /*not really a while loop, only used to break on error*/ - { - for(length = 0; length < chunkLength && data[length] != 0; length++) ; - if(length + 2 >= chunkLength) CERROR_BREAK(error, 75); /*no null termination, corrupt?*/ - if(length < 1 || length > 79) CERROR_BREAK(error, 89); /*keyword too short or long*/ - - key = (char*)lodepng_malloc(length + 1); - if(!key) CERROR_BREAK(error, 83); /*alloc fail*/ - - key[length] = 0; - for(i = 0; i < length; i++) key[i] = (char)data[i]; - - if(data[length + 1] != 0) CERROR_BREAK(error, 72); /*the 0 byte indicating compression must be 0*/ - - string2_begin = length + 2; - if(string2_begin > chunkLength) CERROR_BREAK(error, 75); /*no null termination, corrupt?*/ - - length = chunkLength - string2_begin; - /*will fail if zlib error, e.g. if length is too small*/ - error = zlib_decompress(&decoded.data, &decoded.size, - (unsigned char*)(&data[string2_begin]), - length, zlibsettings); - if(error) break; - ucvector_push_back(&decoded, 0); - - error = lodepng_add_text(info, key, (char*)decoded.data); - - break; - } - - lodepng_free(key); - ucvector_cleanup(&decoded); - - return error; -} - -/*international text chunk (iTXt)*/ -static unsigned readChunk_iTXt(LodePNGInfo* info, const LodePNGDecompressSettings* zlibsettings, - const unsigned char* data, size_t chunkLength) -{ - unsigned error = 0; - unsigned i; - - unsigned length, begin, compressed; - char *key = 0, *langtag = 0, *transkey = 0; - ucvector decoded; - ucvector_init(&decoded); - - while(!error) /*not really a while loop, only used to break on error*/ - { - /*Quick check if the chunk length isn't too small. Even without check - it'd still fail with other error checks below if it's too short. This just gives a different error code.*/ - if(chunkLength < 5) CERROR_BREAK(error, 30); /*iTXt chunk too short*/ - - /*read the key*/ - for(length = 0; length < chunkLength && data[length] != 0; length++) ; - if(length + 3 >= chunkLength) CERROR_BREAK(error, 75); /*no null termination char, corrupt?*/ - if(length < 1 || length > 79) CERROR_BREAK(error, 89); /*keyword too short or long*/ - - key = (char*)lodepng_malloc(length + 1); - if(!key) CERROR_BREAK(error, 83); /*alloc fail*/ - - key[length] = 0; - for(i = 0; i < length; i++) key[i] = (char)data[i]; - - /*read the compression method*/ - compressed = data[length + 1]; - if(data[length + 2] != 0) CERROR_BREAK(error, 72); /*the 0 byte indicating compression must be 0*/ - - /*even though it's not allowed by the standard, no error is thrown if - there's no null termination char, if the text is empty for the next 3 texts*/ - - /*read the langtag*/ - begin = length + 3; - length = 0; - for(i = begin; i < chunkLength && data[i] != 0; i++) length++; - - langtag = (char*)lodepng_malloc(length + 1); - if(!langtag) CERROR_BREAK(error, 83); /*alloc fail*/ - - langtag[length] = 0; - for(i = 0; i < length; i++) langtag[i] = (char)data[begin + i]; - - /*read the transkey*/ - begin += length + 1; - length = 0; - for(i = begin; i < chunkLength && data[i] != 0; i++) length++; - - transkey = (char*)lodepng_malloc(length + 1); - if(!transkey) CERROR_BREAK(error, 83); /*alloc fail*/ - - transkey[length] = 0; - for(i = 0; i < length; i++) transkey[i] = (char)data[begin + i]; - - /*read the actual text*/ - begin += length + 1; - - length = chunkLength < begin ? 0 : chunkLength - begin; - - if(compressed) - { - /*will fail if zlib error, e.g. if length is too small*/ - error = zlib_decompress(&decoded.data, &decoded.size, - (unsigned char*)(&data[begin]), - length, zlibsettings); - if(error) break; - if(decoded.allocsize < decoded.size) decoded.allocsize = decoded.size; - ucvector_push_back(&decoded, 0); - } - else - { - if(!ucvector_resize(&decoded, length + 1)) CERROR_BREAK(error, 83 /*alloc fail*/); - - decoded.data[length] = 0; - for(i = 0; i < length; i++) decoded.data[i] = data[begin + i]; - } - - error = lodepng_add_itext(info, key, langtag, transkey, (char*)decoded.data); - - break; - } - - lodepng_free(key); - lodepng_free(langtag); - lodepng_free(transkey); - ucvector_cleanup(&decoded); - - return error; -} - -static unsigned readChunk_tIME(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) -{ - if(chunkLength != 7) return 73; /*invalid tIME chunk size*/ - - info->time_defined = 1; - info->time.year = 256u * data[0] + data[1]; - info->time.month = data[2]; - info->time.day = data[3]; - info->time.hour = data[4]; - info->time.minute = data[5]; - info->time.second = data[6]; - - return 0; /* OK */ -} - -static unsigned readChunk_pHYs(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) -{ - if(chunkLength != 9) return 74; /*invalid pHYs chunk size*/ - - info->phys_defined = 1; - info->phys_x = 16777216u * data[0] + 65536u * data[1] + 256u * data[2] + data[3]; - info->phys_y = 16777216u * data[4] + 65536u * data[5] + 256u * data[6] + data[7]; - info->phys_unit = data[8]; - - return 0; /* OK */ -} -#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ - -/*read a PNG, the result will be in the same color type as the PNG (hence "generic")*/ -static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h, - LodePNGState* state, - const unsigned char* in, size_t insize) -{ - unsigned char IEND = 0; - const unsigned char* chunk; - size_t i; - ucvector idat; /*the data from idat chunks*/ - ucvector scanlines; - - /*for unknown chunk order*/ - unsigned unknown = 0; -#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - unsigned critical_pos = 1; /*1 = after IHDR, 2 = after PLTE, 3 = after IDAT*/ -#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ - - /*provide some proper output values if error will happen*/ - *out = 0; - - state->error = lodepng_inspect(w, h, state, in, insize); /*reads header and resets other parameters in state->info_png*/ - if(state->error) return; - - ucvector_init(&idat); - chunk = &in[33]; /*first byte of the first chunk after the header*/ - - /*loop through the chunks, ignoring unknown chunks and stopping at IEND chunk. - IDAT data is put at the start of the in buffer*/ - while(!IEND && !state->error) - { - unsigned chunkLength; - const unsigned char* data; /*the data in the chunk*/ - - /*error: size of the in buffer too small to contain next chunk*/ - if((size_t)((chunk - in) + 12) > insize || chunk < in) CERROR_BREAK(state->error, 30); - - /*length of the data of the chunk, excluding the length bytes, chunk type and CRC bytes*/ - chunkLength = lodepng_chunk_length(chunk); - /*error: chunk length larger than the max PNG chunk size*/ - if(chunkLength > 2147483647) CERROR_BREAK(state->error, 63); - - if((size_t)((chunk - in) + chunkLength + 12) > insize || (chunk + chunkLength + 12) < in) - { - CERROR_BREAK(state->error, 64); /*error: size of the in buffer too small to contain next chunk*/ - } - - data = lodepng_chunk_data_const(chunk); - - /*IDAT chunk, containing compressed image data*/ - if(lodepng_chunk_type_equals(chunk, "IDAT")) - { - size_t oldsize = idat.size; - if(!ucvector_resize(&idat, oldsize + chunkLength)) CERROR_BREAK(state->error, 83 /*alloc fail*/); - for(i = 0; i < chunkLength; i++) idat.data[oldsize + i] = data[i]; -#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - critical_pos = 3; -#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ - } - /*IEND chunk*/ - else if(lodepng_chunk_type_equals(chunk, "IEND")) - { - IEND = 1; - } - /*palette chunk (PLTE)*/ - else if(lodepng_chunk_type_equals(chunk, "PLTE")) - { - state->error = readChunk_PLTE(&state->info_png.color, data, chunkLength); - if(state->error) break; -#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - critical_pos = 2; -#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ - } - /*palette transparency chunk (tRNS)*/ - else if(lodepng_chunk_type_equals(chunk, "tRNS")) - { - state->error = readChunk_tRNS(&state->info_png.color, data, chunkLength); - if(state->error) break; - } -#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - /*background color chunk (bKGD)*/ - else if(lodepng_chunk_type_equals(chunk, "bKGD")) - { - state->error = readChunk_bKGD(&state->info_png, data, chunkLength); - if(state->error) break; - } - /*text chunk (tEXt)*/ - else if(lodepng_chunk_type_equals(chunk, "tEXt")) - { - if(state->decoder.read_text_chunks) - { - state->error = readChunk_tEXt(&state->info_png, data, chunkLength); - if(state->error) break; - } - } - /*compressed text chunk (zTXt)*/ - else if(lodepng_chunk_type_equals(chunk, "zTXt")) - { - if(state->decoder.read_text_chunks) - { - state->error = readChunk_zTXt(&state->info_png, &state->decoder.zlibsettings, data, chunkLength); - if(state->error) break; - } - } - /*international text chunk (iTXt)*/ - else if(lodepng_chunk_type_equals(chunk, "iTXt")) - { - if(state->decoder.read_text_chunks) - { - state->error = readChunk_iTXt(&state->info_png, &state->decoder.zlibsettings, data, chunkLength); - if(state->error) break; - } - } - else if(lodepng_chunk_type_equals(chunk, "tIME")) - { - state->error = readChunk_tIME(&state->info_png, data, chunkLength); - if(state->error) break; - } - else if(lodepng_chunk_type_equals(chunk, "pHYs")) - { - state->error = readChunk_pHYs(&state->info_png, data, chunkLength); - if(state->error) break; - } -#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ - else /*it's not an implemented chunk type, so ignore it: skip over the data*/ - { - /*error: unknown critical chunk (5th bit of first byte of chunk type is 0)*/ - if(!lodepng_chunk_ancillary(chunk)) CERROR_BREAK(state->error, 69); - - unknown = 1; -#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - if(state->decoder.remember_unknown_chunks) - { - state->error = lodepng_chunk_append(&state->info_png.unknown_chunks_data[critical_pos - 1], - &state->info_png.unknown_chunks_size[critical_pos - 1], chunk); - if(state->error) break; - } -#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ - } - - if(!state->decoder.ignore_crc && !unknown) /*check CRC if wanted, only on known chunk types*/ - { - if(lodepng_chunk_check_crc(chunk)) CERROR_BREAK(state->error, 57); /*invalid CRC*/ - } - - if(!IEND) chunk = lodepng_chunk_next_const(chunk); - } - - ucvector_init(&scanlines); - if(!state->error) - { - /*maximum final image length is already reserved in the vector's length - this is not really necessary*/ - if(!ucvector_resize(&scanlines, lodepng_get_raw_size(*w, *h, &state->info_png.color) + *h)) - { - state->error = 83; /*alloc fail*/ - } - } - if(!state->error) - { - /*decompress with the Zlib decompressor*/ - state->error = zlib_decompress(&scanlines.data, &scanlines.size, idat.data, - idat.size, &state->decoder.zlibsettings); - } - ucvector_cleanup(&idat); - - if(!state->error) - { - ucvector outv; - ucvector_init(&outv); - if(!ucvector_resizev(&outv, - lodepng_get_raw_size(*w, *h, &state->info_png.color), 0)) state->error = 83; /*alloc fail*/ - if(!state->error) state->error = postProcessScanlines(outv.data, scanlines.data, *w, *h, &state->info_png); - *out = outv.data; - } - ucvector_cleanup(&scanlines); -} - -unsigned lodepng_decode(unsigned char** out, unsigned* w, unsigned* h, - LodePNGState* state, - const unsigned char* in, size_t insize) -{ - *out = 0; - decodeGeneric(out, w, h, state, in, insize); - if(state->error) return state->error; - if(!state->decoder.color_convert || lodepng_color_mode_equal(&state->info_raw, &state->info_png.color)) - { - /*same color type, no copying or converting of data needed*/ - /*store the info_png color settings on the info_raw so that the info_raw still reflects what colortype - the raw image has to the end user*/ - if(!state->decoder.color_convert) - { - state->error = lodepng_color_mode_copy(&state->info_raw, &state->info_png.color); - if(state->error) return state->error; - } - } - else - { - /*color conversion needed; sort of copy of the data*/ - unsigned char* data = *out; - size_t outsize; - - /*TODO: check if this works according to the statement in the documentation: "The converter can convert - from greyscale input color type, to 8-bit greyscale or greyscale with alpha"*/ - if(!(state->info_raw.colortype == LCT_RGB || state->info_raw.colortype == LCT_RGBA) - && !(state->info_raw.bitdepth == 8)) - { - return 56; /*unsupported color mode conversion*/ - } - - outsize = lodepng_get_raw_size(*w, *h, &state->info_raw); - *out = (unsigned char*)lodepng_malloc(outsize); - if(!(*out)) - { - state->error = 83; /*alloc fail*/ - } - else state->error = lodepng_convert(*out, data, &state->info_raw, &state->info_png.color, *w, *h, state->decoder.fix_png); - lodepng_free(data); - } - return state->error; -} - -unsigned lodepng_decode_memory(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, - size_t insize, LodePNGColorType colortype, unsigned bitdepth) -{ - unsigned error; - LodePNGState state; - lodepng_state_init(&state); - state.info_raw.colortype = colortype; - state.info_raw.bitdepth = bitdepth; - error = lodepng_decode(out, w, h, &state, in, insize); - lodepng_state_cleanup(&state); - return error; -} - -unsigned lodepng_decode32(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, size_t insize) -{ - return lodepng_decode_memory(out, w, h, in, insize, LCT_RGBA, 8); -} - -unsigned lodepng_decode24(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, size_t insize) -{ - return lodepng_decode_memory(out, w, h, in, insize, LCT_RGB, 8); -} - -#ifdef LODEPNG_COMPILE_DISK -unsigned lodepng_decode_file(unsigned char** out, unsigned* w, unsigned* h, const char* filename, - LodePNGColorType colortype, unsigned bitdepth) -{ - unsigned char* buffer; - size_t buffersize; - unsigned error; - error = lodepng_load_file(&buffer, &buffersize, filename); - if(!error) error = lodepng_decode_memory(out, w, h, buffer, buffersize, colortype, bitdepth); - lodepng_free(buffer); - return error; -} - -unsigned lodepng_decode32_file(unsigned char** out, unsigned* w, unsigned* h, const char* filename) -{ - return lodepng_decode_file(out, w, h, filename, LCT_RGBA, 8); -} - -unsigned lodepng_decode24_file(unsigned char** out, unsigned* w, unsigned* h, const char* filename) -{ - return lodepng_decode_file(out, w, h, filename, LCT_RGB, 8); -} -#endif /*LODEPNG_COMPILE_DISK*/ - -void lodepng_decoder_settings_init(LodePNGDecoderSettings* settings) -{ - settings->color_convert = 1; -#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - settings->read_text_chunks = 1; - settings->remember_unknown_chunks = 0; -#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ - settings->ignore_crc = 0; - settings->fix_png = 0; - lodepng_decompress_settings_init(&settings->zlibsettings); -} - -#endif /*LODEPNG_COMPILE_DECODER*/ - -#if defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) - -void lodepng_state_init(LodePNGState* state) -{ -#ifdef LODEPNG_COMPILE_DECODER - lodepng_decoder_settings_init(&state->decoder); -#endif /*LODEPNG_COMPILE_DECODER*/ -#ifdef LODEPNG_COMPILE_ENCODER - lodepng_encoder_settings_init(&state->encoder); -#endif /*LODEPNG_COMPILE_ENCODER*/ - lodepng_color_mode_init(&state->info_raw); - lodepng_info_init(&state->info_png); - state->error = 1; -} - -void lodepng_state_cleanup(LodePNGState* state) -{ - lodepng_color_mode_cleanup(&state->info_raw); - lodepng_info_cleanup(&state->info_png); -} - -void lodepng_state_copy(LodePNGState* dest, const LodePNGState* source) -{ - lodepng_state_cleanup(dest); - *dest = *source; - lodepng_color_mode_init(&dest->info_raw); - lodepng_info_init(&dest->info_png); - dest->error = lodepng_color_mode_copy(&dest->info_raw, &source->info_raw); if(dest->error) return; - dest->error = lodepng_info_copy(&dest->info_png, &source->info_png); if(dest->error) return; -} - -#endif /* defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) */ - -#ifdef LODEPNG_COMPILE_ENCODER - -/* ////////////////////////////////////////////////////////////////////////// */ -/* / PNG Encoder / */ -/* ////////////////////////////////////////////////////////////////////////// */ - -/*chunkName must be string of 4 characters*/ -static unsigned addChunk(ucvector* out, const char* chunkName, const unsigned char* data, size_t length) -{ - CERROR_TRY_RETURN(lodepng_chunk_create(&out->data, &out->size, (unsigned)length, chunkName, data)); - out->allocsize = out->size; /*fix the allocsize again*/ - return 0; -} - -static void writeSignature(ucvector* out) -{ - /*8 bytes PNG signature, aka the magic bytes*/ - ucvector_push_back(out, 137); - ucvector_push_back(out, 80); - ucvector_push_back(out, 78); - ucvector_push_back(out, 71); - ucvector_push_back(out, 13); - ucvector_push_back(out, 10); - ucvector_push_back(out, 26); - ucvector_push_back(out, 10); -} - -static unsigned addChunk_IHDR(ucvector* out, unsigned w, unsigned h, - LodePNGColorType colortype, unsigned bitdepth, unsigned interlace_method) -{ - unsigned error = 0; - ucvector header; - ucvector_init(&header); - - lodepng_add32bitInt(&header, w); /*width*/ - lodepng_add32bitInt(&header, h); /*height*/ - ucvector_push_back(&header, (unsigned char)bitdepth); /*bit depth*/ - ucvector_push_back(&header, (unsigned char)colortype); /*color type*/ - ucvector_push_back(&header, 0); /*compression method*/ - ucvector_push_back(&header, 0); /*filter method*/ - ucvector_push_back(&header, interlace_method); /*interlace method*/ - - error = addChunk(out, "IHDR", header.data, header.size); - ucvector_cleanup(&header); - - return error; -} - -static unsigned addChunk_PLTE(ucvector* out, const LodePNGColorMode* info) -{ - unsigned error = 0; - size_t i; - ucvector PLTE; - ucvector_init(&PLTE); - for(i = 0; i < info->palettesize * 4; i++) - { - /*add all channels except alpha channel*/ - if(i % 4 != 3) ucvector_push_back(&PLTE, info->palette[i]); - } - error = addChunk(out, "PLTE", PLTE.data, PLTE.size); - ucvector_cleanup(&PLTE); - - return error; -} - -static unsigned addChunk_tRNS(ucvector* out, const LodePNGColorMode* info) -{ - unsigned error = 0; - size_t i; - ucvector tRNS; - ucvector_init(&tRNS); - if(info->colortype == LCT_PALETTE) - { - size_t amount = info->palettesize; - /*the tail of palette values that all have 255 as alpha, does not have to be encoded*/ - for(i = info->palettesize; i > 0; i--) - { - if(info->palette[4 * (i - 1) + 3] == 255) amount--; - else break; - } - /*add only alpha channel*/ - for(i = 0; i < amount; i++) ucvector_push_back(&tRNS, info->palette[4 * i + 3]); - } - else if(info->colortype == LCT_GREY) - { - if(info->key_defined) - { - ucvector_push_back(&tRNS, (unsigned char)(info->key_r / 256)); - ucvector_push_back(&tRNS, (unsigned char)(info->key_r % 256)); - } - } - else if(info->colortype == LCT_RGB) - { - if(info->key_defined) - { - ucvector_push_back(&tRNS, (unsigned char)(info->key_r / 256)); - ucvector_push_back(&tRNS, (unsigned char)(info->key_r % 256)); - ucvector_push_back(&tRNS, (unsigned char)(info->key_g / 256)); - ucvector_push_back(&tRNS, (unsigned char)(info->key_g % 256)); - ucvector_push_back(&tRNS, (unsigned char)(info->key_b / 256)); - ucvector_push_back(&tRNS, (unsigned char)(info->key_b % 256)); - } - } - - error = addChunk(out, "tRNS", tRNS.data, tRNS.size); - ucvector_cleanup(&tRNS); - - return error; -} - -static unsigned addChunk_IDAT(ucvector* out, const unsigned char* data, size_t datasize, - LodePNGCompressSettings* zlibsettings) -{ - ucvector zlibdata; - unsigned error = 0; - - /*compress with the Zlib compressor*/ - ucvector_init(&zlibdata); - error = zlib_compress(&zlibdata.data, &zlibdata.size, data, datasize, zlibsettings); - if(!error) error = addChunk(out, "IDAT", zlibdata.data, zlibdata.size); - ucvector_cleanup(&zlibdata); - - return error; -} - -static unsigned addChunk_IEND(ucvector* out) -{ - unsigned error = 0; - error = addChunk(out, "IEND", 0, 0); - return error; -} - -#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - -static unsigned addChunk_tEXt(ucvector* out, const char* keyword, const char* textstring) -{ - unsigned error = 0; - size_t i; - ucvector text; - ucvector_init(&text); - for(i = 0; keyword[i] != 0; i++) ucvector_push_back(&text, (unsigned char)keyword[i]); - if(i < 1 || i > 79) return 89; /*error: invalid keyword size*/ - ucvector_push_back(&text, 0); /*0 termination char*/ - for(i = 0; textstring[i] != 0; i++) ucvector_push_back(&text, (unsigned char)textstring[i]); - error = addChunk(out, "tEXt", text.data, text.size); - ucvector_cleanup(&text); - - return error; -} - -static unsigned addChunk_zTXt(ucvector* out, const char* keyword, const char* textstring, - LodePNGCompressSettings* zlibsettings) -{ - unsigned error = 0; - ucvector data, compressed; - size_t i, textsize = strlen(textstring); - - ucvector_init(&data); - ucvector_init(&compressed); - for(i = 0; keyword[i] != 0; i++) ucvector_push_back(&data, (unsigned char)keyword[i]); - if(i < 1 || i > 79) return 89; /*error: invalid keyword size*/ - ucvector_push_back(&data, 0); /*0 termination char*/ - ucvector_push_back(&data, 0); /*compression method: 0*/ - - error = zlib_compress(&compressed.data, &compressed.size, - (unsigned char*)textstring, textsize, zlibsettings); - if(!error) - { - for(i = 0; i < compressed.size; i++) ucvector_push_back(&data, compressed.data[i]); - error = addChunk(out, "zTXt", data.data, data.size); - } - - ucvector_cleanup(&compressed); - ucvector_cleanup(&data); - return error; -} - -static unsigned addChunk_iTXt(ucvector* out, unsigned compressed, const char* keyword, const char* langtag, - const char* transkey, const char* textstring, LodePNGCompressSettings* zlibsettings) -{ - unsigned error = 0; - ucvector data; - size_t i, textsize = strlen(textstring); - - ucvector_init(&data); - - for(i = 0; keyword[i] != 0; i++) ucvector_push_back(&data, (unsigned char)keyword[i]); - if(i < 1 || i > 79) return 89; /*error: invalid keyword size*/ - ucvector_push_back(&data, 0); /*null termination char*/ - ucvector_push_back(&data, compressed ? 1 : 0); /*compression flag*/ - ucvector_push_back(&data, 0); /*compression method*/ - for(i = 0; langtag[i] != 0; i++) ucvector_push_back(&data, (unsigned char)langtag[i]); - ucvector_push_back(&data, 0); /*null termination char*/ - for(i = 0; transkey[i] != 0; i++) ucvector_push_back(&data, (unsigned char)transkey[i]); - ucvector_push_back(&data, 0); /*null termination char*/ - - if(compressed) - { - ucvector compressed_data; - ucvector_init(&compressed_data); - error = zlib_compress(&compressed_data.data, &compressed_data.size, - (unsigned char*)textstring, textsize, zlibsettings); - if(!error) - { - for(i = 0; i < compressed_data.size; i++) ucvector_push_back(&data, compressed_data.data[i]); - } - ucvector_cleanup(&compressed_data); - } - else /*not compressed*/ - { - for(i = 0; textstring[i] != 0; i++) ucvector_push_back(&data, (unsigned char)textstring[i]); - } - - if(!error) error = addChunk(out, "iTXt", data.data, data.size); - ucvector_cleanup(&data); - return error; -} - -static unsigned addChunk_bKGD(ucvector* out, const LodePNGInfo* info) -{ - unsigned error = 0; - ucvector bKGD; - ucvector_init(&bKGD); - if(info->color.colortype == LCT_GREY || info->color.colortype == LCT_GREY_ALPHA) - { - ucvector_push_back(&bKGD, (unsigned char)(info->background_r / 256)); - ucvector_push_back(&bKGD, (unsigned char)(info->background_r % 256)); - } - else if(info->color.colortype == LCT_RGB || info->color.colortype == LCT_RGBA) - { - ucvector_push_back(&bKGD, (unsigned char)(info->background_r / 256)); - ucvector_push_back(&bKGD, (unsigned char)(info->background_r % 256)); - ucvector_push_back(&bKGD, (unsigned char)(info->background_g / 256)); - ucvector_push_back(&bKGD, (unsigned char)(info->background_g % 256)); - ucvector_push_back(&bKGD, (unsigned char)(info->background_b / 256)); - ucvector_push_back(&bKGD, (unsigned char)(info->background_b % 256)); - } - else if(info->color.colortype == LCT_PALETTE) - { - ucvector_push_back(&bKGD, (unsigned char)(info->background_r % 256)); /*palette index*/ - } - - error = addChunk(out, "bKGD", bKGD.data, bKGD.size); - ucvector_cleanup(&bKGD); - - return error; -} - -static unsigned addChunk_tIME(ucvector* out, const LodePNGTime* time) -{ - unsigned error = 0; - unsigned char* data = (unsigned char*)lodepng_malloc(7); - if(!data) return 83; /*alloc fail*/ - data[0] = (unsigned char)(time->year / 256); - data[1] = (unsigned char)(time->year % 256); - data[2] = (unsigned char)time->month; - data[3] = (unsigned char)time->day; - data[4] = (unsigned char)time->hour; - data[5] = (unsigned char)time->minute; - data[6] = (unsigned char)time->second; - error = addChunk(out, "tIME", data, 7); - lodepng_free(data); - return error; -} - -static unsigned addChunk_pHYs(ucvector* out, const LodePNGInfo* info) -{ - unsigned error = 0; - ucvector data; - ucvector_init(&data); - - lodepng_add32bitInt(&data, info->phys_x); - lodepng_add32bitInt(&data, info->phys_y); - ucvector_push_back(&data, info->phys_unit); - - error = addChunk(out, "pHYs", data.data, data.size); - ucvector_cleanup(&data); - - return error; -} - -#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ - -static void filterScanline(unsigned char* out, const unsigned char* scanline, const unsigned char* prevline, - size_t length, size_t bytewidth, unsigned char filterType) -{ - size_t i; - switch(filterType) - { - case 0: /*None*/ - for(i = 0; i < length; i++) out[i] = scanline[i]; - break; - case 1: /*Sub*/ - if(prevline) - { - for(i = 0; i < bytewidth; i++) out[i] = scanline[i]; - for(i = bytewidth; i < length; i++) out[i] = scanline[i] - scanline[i - bytewidth]; - } - else - { - for(i = 0; i < bytewidth; i++) out[i] = scanline[i]; - for(i = bytewidth; i < length; i++) out[i] = scanline[i] - scanline[i - bytewidth]; - } - break; - case 2: /*Up*/ - if(prevline) - { - for(i = 0; i < length; i++) out[i] = scanline[i] - prevline[i]; - } - else - { - for(i = 0; i < length; i++) out[i] = scanline[i]; - } - break; - case 3: /*Average*/ - if(prevline) - { - for(i = 0; i < bytewidth; i++) out[i] = scanline[i] - prevline[i] / 2; - for(i = bytewidth; i < length; i++) out[i] = scanline[i] - ((scanline[i - bytewidth] + prevline[i]) / 2); - } - else - { - for(i = 0; i < bytewidth; i++) out[i] = scanline[i]; - for(i = bytewidth; i < length; i++) out[i] = scanline[i] - scanline[i - bytewidth] / 2; - } - break; - case 4: /*Paeth*/ - if(prevline) - { - /*paethPredictor(0, prevline[i], 0) is always prevline[i]*/ - for(i = 0; i < bytewidth; i++) out[i] = (scanline[i] - prevline[i]); - for(i = bytewidth; i < length; i++) - { - out[i] = (scanline[i] - paethPredictor(scanline[i - bytewidth], prevline[i], prevline[i - bytewidth])); - } - } - else - { - for(i = 0; i < bytewidth; i++) out[i] = scanline[i]; - /*paethPredictor(scanline[i - bytewidth], 0, 0) is always scanline[i - bytewidth]*/ - for(i = bytewidth; i < length; i++) out[i] = (scanline[i] - scanline[i - bytewidth]); - } - break; - default: return; /*unexisting filter type given*/ - } -} - -/* log2 approximation. A slight bit faster than std::log. */ -static float flog2(float f) -{ - float result = 0; - while(f > 32) { result += 4; f /= 16; } - while(f > 2) { result++; f /= 2; } - return result + 1.442695f * (f * f * f / 3 - 3 * f * f / 2 + 3 * f - 1.83333f); -} - -static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, - const LodePNGColorMode* info, const LodePNGEncoderSettings* settings) -{ - /* - For PNG filter method 0 - out must be a buffer with as size: h + (w * h * bpp + 7) / 8, because there are - the scanlines with 1 extra byte per scanline - */ - - unsigned bpp = lodepng_get_bpp(info); - /*the width of a scanline in bytes, not including the filter type*/ - size_t linebytes = (w * bpp + 7) / 8; - /*bytewidth is used for filtering, is 1 when bpp < 8, number of bytes per pixel otherwise*/ - size_t bytewidth = (bpp + 7) / 8; - const unsigned char* prevline = 0; - unsigned x, y; - unsigned error = 0; - LodePNGFilterStrategy strategy = settings->filter_strategy; - - /* - There is a heuristic called the minimum sum of absolute differences heuristic, suggested by the PNG standard: - * If the image type is Palette, or the bit depth is smaller than 8, then do not filter the image (i.e. - use fixed filtering, with the filter None). - * (The other case) If the image type is Grayscale or RGB (with or without Alpha), and the bit depth is - not smaller than 8, then use adaptive filtering heuristic as follows: independently for each row, apply - all five filters and select the filter that produces the smallest sum of absolute values per row. - This heuristic is used if filter strategy is LFS_MINSUM and filter_palette_zero is true. - - If filter_palette_zero is true and filter_strategy is not LFS_MINSUM, the above heuristic is followed, - but for "the other case", whatever strategy filter_strategy is set to instead of the minimum sum - heuristic is used. - */ - if(settings->filter_palette_zero && - (info->colortype == LCT_PALETTE || info->bitdepth < 8)) strategy = LFS_ZERO; - - if(bpp == 0) return 31; /*error: invalid color type*/ - - if(strategy == LFS_ZERO) - { - for(y = 0; y < h; y++) - { - size_t outindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/ - size_t inindex = linebytes * y; - out[outindex] = 0; /*filter type byte*/ - filterScanline(&out[outindex + 1], &in[inindex], prevline, linebytes, bytewidth, 0); - prevline = &in[inindex]; - } - } - else if(strategy == LFS_MINSUM) - { - /*adaptive filtering*/ - size_t sum[5]; - ucvector attempt[5]; /*five filtering attempts, one for each filter type*/ - size_t smallest = 0; - unsigned char type, bestType = 0; - - for(type = 0; type < 5; type++) - { - ucvector_init(&attempt[type]); - if(!ucvector_resize(&attempt[type], linebytes)) return 83; /*alloc fail*/ - } - - if(!error) - { - for(y = 0; y < h; y++) - { - /*try the 5 filter types*/ - for(type = 0; type < 5; type++) - { - filterScanline(attempt[type].data, &in[y * linebytes], prevline, linebytes, bytewidth, type); - - /*calculate the sum of the result*/ - sum[type] = 0; - if(type == 0) - { - for(x = 0; x < linebytes; x++) sum[type] += (unsigned char)(attempt[type].data[x]); - } - else - { - for(x = 0; x < linebytes; x++) - { - /*For differences, each byte should be treated as signed, values above 127 are negative - (converted to signed char). Filtertype 0 isn't a difference though, so use unsigned there. - This means filtertype 0 is almost never chosen, but that is justified.*/ - unsigned char s = attempt[type].data[x]; - sum[type] += s < 128 ? s : (255U - s); - } - } - - /*check if this is smallest sum (or if type == 0 it's the first case so always store the values)*/ - if(type == 0 || sum[type] < smallest) - { - bestType = type; - smallest = sum[type]; - } - } - - prevline = &in[y * linebytes]; - - /*now fill the out values*/ - out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/ - for(x = 0; x < linebytes; x++) out[y * (linebytes + 1) + 1 + x] = attempt[bestType].data[x]; - } - } - - for(type = 0; type < 5; type++) ucvector_cleanup(&attempt[type]); - } - else if(strategy == LFS_ENTROPY) - { - float sum[5]; - ucvector attempt[5]; /*five filtering attempts, one for each filter type*/ - float smallest = 0; - unsigned type, bestType = 0; - unsigned count[256]; - - for(type = 0; type < 5; type++) - { - ucvector_init(&attempt[type]); - if(!ucvector_resize(&attempt[type], linebytes)) return 83; /*alloc fail*/ - } - - for(y = 0; y < h; y++) - { - /*try the 5 filter types*/ - for(type = 0; type < 5; type++) - { - filterScanline(attempt[type].data, &in[y * linebytes], prevline, linebytes, bytewidth, type); - for(x = 0; x < 256; x++) count[x] = 0; - for(x = 0; x < linebytes; x++) count[attempt[type].data[x]]++; - count[type]++; /*the filter type itself is part of the scanline*/ - sum[type] = 0; - for(x = 0; x < 256; x++) - { - float p = count[x] / (float)(linebytes + 1); - sum[type] += count[x] == 0 ? 0 : flog2(1 / p) * p; - } - /*check if this is smallest sum (or if type == 0 it's the first case so always store the values)*/ - if(type == 0 || sum[type] < smallest) - { - bestType = type; - smallest = sum[type]; - } - } - - prevline = &in[y * linebytes]; - - /*now fill the out values*/ - out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/ - for(x = 0; x < linebytes; x++) out[y * (linebytes + 1) + 1 + x] = attempt[bestType].data[x]; - } - - for(type = 0; type < 5; type++) ucvector_cleanup(&attempt[type]); - } - else if(strategy == LFS_PREDEFINED) - { - for(y = 0; y < h; y++) - { - size_t outindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/ - size_t inindex = linebytes * y; - unsigned char type = settings->predefined_filters[y]; - out[outindex] = type; /*filter type byte*/ - filterScanline(&out[outindex + 1], &in[inindex], prevline, linebytes, bytewidth, type); - prevline = &in[inindex]; - } - } - else if(strategy == LFS_BRUTE_FORCE) - { - /*brute force filter chooser. - deflate the scanline after every filter attempt to see which one deflates best. - This is very slow and gives only slightly smaller, sometimes even larger, result*/ - size_t size[5]; - ucvector attempt[5]; /*five filtering attempts, one for each filter type*/ - size_t smallest = 0; - unsigned type = 0, bestType = 0; - unsigned char* dummy; - LodePNGCompressSettings zlibsettings = settings->zlibsettings; - /*use fixed tree on the attempts so that the tree is not adapted to the filtertype on purpose, - to simulate the true case where the tree is the same for the whole image. Sometimes it gives - better result with dynamic tree anyway. Using the fixed tree sometimes gives worse, but in rare - cases better compression. It does make this a bit less slow, so it's worth doing this.*/ - zlibsettings.btype = 1; - /*a custom encoder likely doesn't read the btype setting and is optimized for complete PNG - images only, so disable it*/ - zlibsettings.custom_zlib = 0; - zlibsettings.custom_deflate = 0; - for(type = 0; type < 5; type++) - { - ucvector_init(&attempt[type]); - ucvector_resize(&attempt[type], linebytes); /*todo: give error if resize failed*/ - } - for(y = 0; y < h; y++) /*try the 5 filter types*/ - { - for(type = 0; type < 5; type++) - { - unsigned testsize = attempt[type].size; - /*if(testsize > 8) testsize /= 8;*/ /*it already works good enough by testing a part of the row*/ - - filterScanline(attempt[type].data, &in[y * linebytes], prevline, linebytes, bytewidth, type); - size[type] = 0; - dummy = 0; - zlib_compress(&dummy, &size[type], attempt[type].data, testsize, &zlibsettings); - lodepng_free(dummy); - /*check if this is smallest size (or if type == 0 it's the first case so always store the values)*/ - if(type == 0 || size[type] < smallest) - { - bestType = type; - smallest = size[type]; - } - } - prevline = &in[y * linebytes]; - out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/ - for(x = 0; x < linebytes; x++) out[y * (linebytes + 1) + 1 + x] = attempt[bestType].data[x]; - } - for(type = 0; type < 5; type++) ucvector_cleanup(&attempt[type]); - } - else return 88; /* unknown filter strategy */ - - return error; -} - -static void addPaddingBits(unsigned char* out, const unsigned char* in, - size_t olinebits, size_t ilinebits, unsigned h) -{ - /*The opposite of the removePaddingBits function - olinebits must be >= ilinebits*/ - unsigned y; - size_t diff = olinebits - ilinebits; - size_t obp = 0, ibp = 0; /*bit pointers*/ - for(y = 0; y < h; y++) - { - size_t x; - for(x = 0; x < ilinebits; x++) - { - unsigned char bit = readBitFromReversedStream(&ibp, in); - setBitOfReversedStream(&obp, out, bit); - } - /*obp += diff; --> no, fill in some value in the padding bits too, to avoid - "Use of uninitialised value of size ###" warning from valgrind*/ - for(x = 0; x < diff; x++) setBitOfReversedStream(&obp, out, 0); - } -} - -/* -in: non-interlaced image with size w*h -out: the same pixels, but re-ordered according to PNG's Adam7 interlacing, with - no padding bits between scanlines, but between reduced images so that each - reduced image starts at a byte. -bpp: bits per pixel -there are no padding bits, not between scanlines, not between reduced images -in has the following size in bits: w * h * bpp. -out is possibly bigger due to padding bits between reduced images -NOTE: comments about padding bits are only relevant if bpp < 8 -*/ -static void Adam7_interlace(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp) -{ - unsigned passw[7], passh[7]; - size_t filter_passstart[8], padded_passstart[8], passstart[8]; - unsigned i; - - Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); - - if(bpp >= 8) - { - for(i = 0; i < 7; i++) - { - unsigned x, y, b; - size_t bytewidth = bpp / 8; - for(y = 0; y < passh[i]; y++) - for(x = 0; x < passw[i]; x++) - { - size_t pixelinstart = ((ADAM7_IY[i] + y * ADAM7_DY[i]) * w + ADAM7_IX[i] + x * ADAM7_DX[i]) * bytewidth; - size_t pixeloutstart = passstart[i] + (y * passw[i] + x) * bytewidth; - for(b = 0; b < bytewidth; b++) - { - out[pixeloutstart + b] = in[pixelinstart + b]; - } - } - } - } - else /*bpp < 8: Adam7 with pixels < 8 bit is a bit trickier: with bit pointers*/ - { - for(i = 0; i < 7; i++) - { - unsigned x, y, b; - unsigned ilinebits = bpp * passw[i]; - unsigned olinebits = bpp * w; - size_t obp, ibp; /*bit pointers (for out and in buffer)*/ - for(y = 0; y < passh[i]; y++) - for(x = 0; x < passw[i]; x++) - { - ibp = (ADAM7_IY[i] + y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + x * ADAM7_DX[i]) * bpp; - obp = (8 * passstart[i]) + (y * ilinebits + x * bpp); - for(b = 0; b < bpp; b++) - { - unsigned char bit = readBitFromReversedStream(&ibp, in); - setBitOfReversedStream(&obp, out, bit); - } - } - } - } -} - -/*out must be buffer big enough to contain uncompressed IDAT chunk data, and in must contain the full image. -return value is error**/ -static unsigned preProcessScanlines(unsigned char** out, size_t* outsize, const unsigned char* in, - unsigned w, unsigned h, - const LodePNGInfo* info_png, const LodePNGEncoderSettings* settings) -{ - /* - This function converts the pure 2D image with the PNG's colortype, into filtered-padded-interlaced data. Steps: - *) if no Adam7: 1) add padding bits (= posible extra bits per scanline if bpp < 8) 2) filter - *) if adam7: 1) Adam7_interlace 2) 7x add padding bits 3) 7x filter - */ - unsigned bpp = lodepng_get_bpp(&info_png->color); - unsigned error = 0; - - if(info_png->interlace_method == 0) - { - *outsize = h + (h * ((w * bpp + 7) / 8)); /*image size plus an extra byte per scanline + possible padding bits*/ - *out = (unsigned char*)lodepng_malloc(*outsize); - if(!(*out) && (*outsize)) error = 83; /*alloc fail*/ - - if(!error) - { - /*non multiple of 8 bits per scanline, padding bits needed per scanline*/ - if(bpp < 8 && w * bpp != ((w * bpp + 7) / 8) * 8) - { - unsigned char* padded = (unsigned char*)lodepng_malloc(h * ((w * bpp + 7) / 8)); - if(!padded) error = 83; /*alloc fail*/ - if(!error) - { - addPaddingBits(padded, in, ((w * bpp + 7) / 8) * 8, w * bpp, h); - error = filter(*out, padded, w, h, &info_png->color, settings); - } - lodepng_free(padded); - } - else - { - /*we can immediatly filter into the out buffer, no other steps needed*/ - error = filter(*out, in, w, h, &info_png->color, settings); - } - } - } - else /*interlace_method is 1 (Adam7)*/ - { - unsigned passw[7], passh[7]; - size_t filter_passstart[8], padded_passstart[8], passstart[8]; - unsigned char* adam7; - - Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); - - *outsize = filter_passstart[7]; /*image size plus an extra byte per scanline + possible padding bits*/ - *out = (unsigned char*)lodepng_malloc(*outsize); - if(!(*out)) error = 83; /*alloc fail*/ - - adam7 = (unsigned char*)lodepng_malloc(passstart[7]); - if(!adam7 && passstart[7]) error = 83; /*alloc fail*/ - - if(!error) - { - unsigned i; - - Adam7_interlace(adam7, in, w, h, bpp); - for(i = 0; i < 7; i++) - { - if(bpp < 8) - { - unsigned char* padded = (unsigned char*)lodepng_malloc(padded_passstart[i + 1] - padded_passstart[i]); - if(!padded) ERROR_BREAK(83); /*alloc fail*/ - addPaddingBits(padded, &adam7[passstart[i]], - ((passw[i] * bpp + 7) / 8) * 8, passw[i] * bpp, passh[i]); - error = filter(&(*out)[filter_passstart[i]], padded, - passw[i], passh[i], &info_png->color, settings); - lodepng_free(padded); - } - else - { - error = filter(&(*out)[filter_passstart[i]], &adam7[padded_passstart[i]], - passw[i], passh[i], &info_png->color, settings); - } - - if(error) break; - } - } - - lodepng_free(adam7); - } - - return error; -} - -/* -palette must have 4 * palettesize bytes allocated, and given in format RGBARGBARGBARGBA... -returns 0 if the palette is opaque, -returns 1 if the palette has a single color with alpha 0 ==> color key -returns 2 if the palette is semi-translucent. -*/ -static unsigned getPaletteTranslucency(const unsigned char* palette, size_t palettesize) -{ - size_t i; - unsigned key = 0; - unsigned r = 0, g = 0, b = 0; /*the value of the color with alpha 0, so long as color keying is possible*/ - for(i = 0; i < palettesize; i++) - { - if(!key && palette[4 * i + 3] == 0) - { - r = palette[4 * i + 0]; g = palette[4 * i + 1]; b = palette[4 * i + 2]; - key = 1; - i = (size_t)(-1); /*restart from beginning, to detect earlier opaque colors with key's value*/ - } - else if(palette[4 * i + 3] != 255) return 2; - /*when key, no opaque RGB may have key's RGB*/ - else if(key && r == palette[i * 4 + 0] && g == palette[i * 4 + 1] && b == palette[i * 4 + 2]) return 2; - } - return key; -} - -#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS -static unsigned addUnknownChunks(ucvector* out, unsigned char* data, size_t datasize) -{ - unsigned char* inchunk = data; - while((size_t)(inchunk - data) < datasize) - { - CERROR_TRY_RETURN(lodepng_chunk_append(&out->data, &out->size, inchunk)); - out->allocsize = out->size; /*fix the allocsize again*/ - inchunk = lodepng_chunk_next(inchunk); - } - return 0; -} -#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ - -unsigned lodepng_encode(unsigned char** out, size_t* outsize, - const unsigned char* image, unsigned w, unsigned h, - LodePNGState* state) -{ - LodePNGInfo info; - ucvector outv; - unsigned char* data = 0; /*uncompressed version of the IDAT chunk data*/ - size_t datasize = 0; - - /*provide some proper output values if error will happen*/ - *out = 0; - *outsize = 0; - state->error = 0; - - lodepng_info_init(&info); - lodepng_info_copy(&info, &state->info_png); - - if((info.color.colortype == LCT_PALETTE || state->encoder.force_palette) - && (info.color.palettesize == 0 || info.color.palettesize > 256)) - { - state->error = 68; /*invalid palette size, it is only allowed to be 1-256*/ - return state->error; - } - - if(state->encoder.auto_convert != LAC_NO) - { - state->error = lodepng_auto_choose_color(&info.color, image, w, h, &state->info_raw, - state->encoder.auto_convert); - } - if(state->error) return state->error; - - if(state->encoder.zlibsettings.btype > 2) - { - CERROR_RETURN_ERROR(state->error, 61); /*error: unexisting btype*/ - } - if(state->info_png.interlace_method > 1) - { - CERROR_RETURN_ERROR(state->error, 71); /*error: unexisting interlace mode*/ - } - - state->error = checkColorValidity(info.color.colortype, info.color.bitdepth); - if(state->error) return state->error; /*error: unexisting color type given*/ - state->error = checkColorValidity(state->info_raw.colortype, state->info_raw.bitdepth); - if(state->error) return state->error; /*error: unexisting color type given*/ - - if(!lodepng_color_mode_equal(&state->info_raw, &info.color)) - { - unsigned char* converted; - size_t size = (w * h * lodepng_get_bpp(&info.color) + 7) / 8; - - converted = (unsigned char*)lodepng_malloc(size); - if(!converted && size) state->error = 83; /*alloc fail*/ - if(!state->error) - { - state->error = lodepng_convert(converted, image, &info.color, &state->info_raw, w, h, 0 /*fix_png*/); - } - if(!state->error) preProcessScanlines(&data, &datasize, converted, w, h, &info, &state->encoder); - lodepng_free(converted); - } - else preProcessScanlines(&data, &datasize, image, w, h, &info, &state->encoder); - - ucvector_init(&outv); - while(!state->error) /*while only executed once, to break on error*/ - { -#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - size_t i; -#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ - /*write signature and chunks*/ - writeSignature(&outv); - /*IHDR*/ - addChunk_IHDR(&outv, w, h, info.color.colortype, info.color.bitdepth, info.interlace_method); -#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - /*unknown chunks between IHDR and PLTE*/ - if(info.unknown_chunks_data[0]) - { - state->error = addUnknownChunks(&outv, info.unknown_chunks_data[0], info.unknown_chunks_size[0]); - if(state->error) break; - } -#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ - /*PLTE*/ - if(info.color.colortype == LCT_PALETTE) - { - addChunk_PLTE(&outv, &info.color); - } - if(state->encoder.force_palette && (info.color.colortype == LCT_RGB || info.color.colortype == LCT_RGBA)) - { - addChunk_PLTE(&outv, &info.color); - } - /*tRNS*/ - if(info.color.colortype == LCT_PALETTE && getPaletteTranslucency(info.color.palette, info.color.palettesize) != 0) - { - addChunk_tRNS(&outv, &info.color); - } - if((info.color.colortype == LCT_GREY || info.color.colortype == LCT_RGB) && info.color.key_defined) - { - addChunk_tRNS(&outv, &info.color); - } -#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - /*bKGD (must come between PLTE and the IDAt chunks*/ - if(info.background_defined) addChunk_bKGD(&outv, &info); - /*pHYs (must come before the IDAT chunks)*/ - if(info.phys_defined) addChunk_pHYs(&outv, &info); - - /*unknown chunks between PLTE and IDAT*/ - if(info.unknown_chunks_data[1]) - { - state->error = addUnknownChunks(&outv, info.unknown_chunks_data[1], info.unknown_chunks_size[1]); - if(state->error) break; - } -#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ - /*IDAT (multiple IDAT chunks must be consecutive)*/ - state->error = addChunk_IDAT(&outv, data, datasize, &state->encoder.zlibsettings); - if(state->error) break; -#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - /*tIME*/ - if(info.time_defined) addChunk_tIME(&outv, &info.time); - /*tEXt and/or zTXt*/ - for(i = 0; i < info.text_num; i++) - { - if(strlen(info.text_keys[i]) > 79) - { - state->error = 66; /*text chunk too large*/ - break; - } - if(strlen(info.text_keys[i]) < 1) - { - state->error = 67; /*text chunk too small*/ - break; - } - if(state->encoder.text_compression) - { - addChunk_zTXt(&outv, info.text_keys[i], info.text_strings[i], &state->encoder.zlibsettings); - } - else - { - addChunk_tEXt(&outv, info.text_keys[i], info.text_strings[i]); - } - } - /*LodePNG version id in text chunk*/ - if(state->encoder.add_id) - { - unsigned alread_added_id_text = 0; - for(i = 0; i < info.text_num; i++) - { - if(!strcmp(info.text_keys[i], "LodePNG")) - { - alread_added_id_text = 1; - break; - } - } - if(alread_added_id_text == 0) - { - addChunk_tEXt(&outv, "LodePNG", VERSION_STRING); /*it's shorter as tEXt than as zTXt chunk*/ - } - } - /*iTXt*/ - for(i = 0; i < info.itext_num; i++) - { - if(strlen(info.itext_keys[i]) > 79) - { - state->error = 66; /*text chunk too large*/ - break; - } - if(strlen(info.itext_keys[i]) < 1) - { - state->error = 67; /*text chunk too small*/ - break; - } - addChunk_iTXt(&outv, state->encoder.text_compression, - info.itext_keys[i], info.itext_langtags[i], info.itext_transkeys[i], info.itext_strings[i], - &state->encoder.zlibsettings); - } - - /*unknown chunks between IDAT and IEND*/ - if(info.unknown_chunks_data[2]) - { - state->error = addUnknownChunks(&outv, info.unknown_chunks_data[2], info.unknown_chunks_size[2]); - if(state->error) break; - } -#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ - addChunk_IEND(&outv); - - break; /*this isn't really a while loop; no error happened so break out now!*/ - } - - lodepng_info_cleanup(&info); - lodepng_free(data); - /*instead of cleaning the vector up, give it to the output*/ - *out = outv.data; - *outsize = outv.size; - - return state->error; -} - -unsigned lodepng_encode_memory(unsigned char** out, size_t* outsize, const unsigned char* image, - unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth) -{ - unsigned error; - LodePNGState state; - lodepng_state_init(&state); - state.info_raw.colortype = colortype; - state.info_raw.bitdepth = bitdepth; - state.info_png.color.colortype = colortype; - state.info_png.color.bitdepth = bitdepth; - lodepng_encode(out, outsize, image, w, h, &state); - error = state.error; - lodepng_state_cleanup(&state); - return error; -} - -unsigned lodepng_encode32(unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h) -{ - return lodepng_encode_memory(out, outsize, image, w, h, LCT_RGBA, 8); -} - -unsigned lodepng_encode24(unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h) -{ - return lodepng_encode_memory(out, outsize, image, w, h, LCT_RGB, 8); -} - -#ifdef LODEPNG_COMPILE_DISK -unsigned lodepng_encode_file(const char* filename, const unsigned char* image, unsigned w, unsigned h, - LodePNGColorType colortype, unsigned bitdepth) -{ - unsigned char* buffer; - size_t buffersize; - unsigned error = lodepng_encode_memory(&buffer, &buffersize, image, w, h, colortype, bitdepth); - if(!error) error = lodepng_save_file(buffer, buffersize, filename); - lodepng_free(buffer); - return error; -} - -unsigned lodepng_encode32_file(const char* filename, const unsigned char* image, unsigned w, unsigned h) -{ - return lodepng_encode_file(filename, image, w, h, LCT_RGBA, 8); -} - -unsigned lodepng_encode24_file(const char* filename, const unsigned char* image, unsigned w, unsigned h) -{ - return lodepng_encode_file(filename, image, w, h, LCT_RGB, 8); -} -#endif /*LODEPNG_COMPILE_DISK*/ - -void lodepng_encoder_settings_init(LodePNGEncoderSettings* settings) -{ - lodepng_compress_settings_init(&settings->zlibsettings); - settings->filter_palette_zero = 1; - settings->filter_strategy = LFS_MINSUM; - settings->auto_convert = LAC_AUTO; - settings->force_palette = 0; - settings->predefined_filters = 0; -#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - settings->add_id = 0; - settings->text_compression = 1; -#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ -} - -#endif /*LODEPNG_COMPILE_ENCODER*/ -#endif /*LODEPNG_COMPILE_PNG*/ - -#ifdef LODEPNG_COMPILE_ERROR_TEXT -/* -This returns the description of a numerical error code in English. This is also -the documentation of all the error codes. -*/ -const char* lodepng_error_text(unsigned code) -{ - switch(code) - { - case 0: return "no error, everything went ok"; - case 1: return "nothing done yet"; /*the Encoder/Decoder has done nothing yet, error checking makes no sense yet*/ - case 10: return "end of input memory reached without huffman end code"; /*while huffman decoding*/ - case 11: return "error in code tree made it jump outside of huffman tree"; /*while huffman decoding*/ - case 13: return "problem while processing dynamic deflate block"; - case 14: return "problem while processing dynamic deflate block"; - case 15: return "problem while processing dynamic deflate block"; - case 16: return "unexisting code while processing dynamic deflate block"; - case 17: return "end of out buffer memory reached while inflating"; - case 18: return "invalid distance code while inflating"; - case 19: return "end of out buffer memory reached while inflating"; - case 20: return "invalid deflate block BTYPE encountered while decoding"; - case 21: return "NLEN is not ones complement of LEN in a deflate block"; - /*end of out buffer memory reached while inflating: - This can happen if the inflated deflate data is longer than the amount of bytes required to fill up - all the pixels of the image, given the color depth and image dimensions. Something that doesn't - happen in a normal, well encoded, PNG image.*/ - case 22: return "end of out buffer memory reached while inflating"; - case 23: return "end of in buffer memory reached while inflating"; - case 24: return "invalid FCHECK in zlib header"; - case 25: return "invalid compression method in zlib header"; - case 26: return "FDICT encountered in zlib header while it's not used for PNG"; - case 27: return "PNG file is smaller than a PNG header"; - /*Checks the magic file header, the first 8 bytes of the PNG file*/ - case 28: return "incorrect PNG signature, it's no PNG or corrupted"; - case 29: return "first chunk is not the header chunk"; - case 30: return "chunk length too large, chunk broken off at end of file"; - case 31: return "illegal PNG color type or bpp"; - case 32: return "illegal PNG compression method"; - case 33: return "illegal PNG filter method"; - case 34: return "illegal PNG interlace method"; - case 35: return "chunk length of a chunk is too large or the chunk too small"; - case 36: return "illegal PNG filter type encountered"; - case 37: return "illegal bit depth for this color type given"; - case 38: return "the palette is too big"; /*more than 256 colors*/ - case 39: return "more palette alpha values given in tRNS chunk than there are colors in the palette"; - case 40: return "tRNS chunk has wrong size for greyscale image"; - case 41: return "tRNS chunk has wrong size for RGB image"; - case 42: return "tRNS chunk appeared while it was not allowed for this color type"; - case 43: return "bKGD chunk has wrong size for palette image"; - case 44: return "bKGD chunk has wrong size for greyscale image"; - case 45: return "bKGD chunk has wrong size for RGB image"; - /*Is the palette too small?*/ - case 46: return "a value in indexed image is larger than the palette size (bitdepth = 8)"; - /*Is the palette too small?*/ - case 47: return "a value in indexed image is larger than the palette size (bitdepth < 8)"; - /*the input data is empty, maybe a PNG file doesn't exist or is in the wrong path*/ - case 48: return "empty input or file doesn't exist"; - case 49: return "jumped past memory while generating dynamic huffman tree"; - case 50: return "jumped past memory while generating dynamic huffman tree"; - case 51: return "jumped past memory while inflating huffman block"; - case 52: return "jumped past memory while inflating"; - case 53: return "size of zlib data too small"; - case 54: return "repeat symbol in tree while there was no value symbol yet"; - /*jumped past tree while generating huffman tree, this could be when the - tree will have more leaves than symbols after generating it out of the - given lenghts. They call this an oversubscribed dynamic bit lengths tree in zlib.*/ - case 55: return "jumped past tree while generating huffman tree"; - case 56: return "given output image colortype or bitdepth not supported for color conversion"; - case 57: return "invalid CRC encountered (checking CRC can be disabled)"; - case 58: return "invalid ADLER32 encountered (checking ADLER32 can be disabled)"; - case 59: return "requested color conversion not supported"; - case 60: return "invalid window size given in the settings of the encoder (must be 0-32768)"; - case 61: return "invalid BTYPE given in the settings of the encoder (only 0, 1 and 2 are allowed)"; - /*LodePNG leaves the choice of RGB to greyscale conversion formula to the user.*/ - case 62: return "conversion from color to greyscale not supported"; - case 63: return "length of a chunk too long, max allowed for PNG is 2147483647 bytes per chunk"; /*(2^31-1)*/ - /*this would result in the inability of a deflated block to ever contain an end code. It must be at least 1.*/ - case 64: return "the length of the END symbol 256 in the Huffman tree is 0"; - case 66: return "the length of a text chunk keyword given to the encoder is longer than the maximum of 79 bytes"; - case 67: return "the length of a text chunk keyword given to the encoder is smaller than the minimum of 1 byte"; - case 68: return "tried to encode a PLTE chunk with a palette that has less than 1 or more than 256 colors"; - case 69: return "unknown chunk type with 'critical' flag encountered by the decoder"; - case 71: return "unexisting interlace mode given to encoder (must be 0 or 1)"; - case 72: return "while decoding, unexisting compression method encountering in zTXt or iTXt chunk (it must be 0)"; - case 73: return "invalid tIME chunk size"; - case 74: return "invalid pHYs chunk size"; - /*length could be wrong, or data chopped off*/ - case 75: return "no null termination char found while decoding text chunk"; - case 76: return "iTXt chunk too short to contain required bytes"; - case 77: return "integer overflow in buffer size"; - case 78: return "failed to open file for reading"; /*file doesn't exist or couldn't be opened for reading*/ - case 79: return "failed to open file for writing"; - case 80: return "tried creating a tree of 0 symbols"; - case 81: return "lazy matching at pos 0 is impossible"; - case 82: return "color conversion to palette requested while a color isn't in palette"; - case 83: return "memory allocation failed"; - case 84: return "given image too small to contain all pixels to be encoded"; - case 85: return "internal color conversion bug"; - case 86: return "impossible offset in lz77 encoding (internal bug)"; - case 87: return "must provide custom zlib function pointer if LODEPNG_COMPILE_ZLIB is not defined"; - case 88: return "invalid filter strategy given for LodePNGEncoderSettings.filter_strategy"; - case 89: return "text chunk keyword too short or long: must have size 1-79"; - /*the windowsize in the LodePNGCompressSettings. Requiring POT(==> & instead of %) makes encoding 12% faster.*/ - case 90: return "windowsize must be a power of two"; - } - return "unknown error code"; -} -#endif /*LODEPNG_COMPILE_ERROR_TEXT*/ - -/* ////////////////////////////////////////////////////////////////////////// */ -/* ////////////////////////////////////////////////////////////////////////// */ -/* // C++ Wrapper // */ -/* ////////////////////////////////////////////////////////////////////////// */ -/* ////////////////////////////////////////////////////////////////////////// */ - -#ifdef LODEPNG_COMPILE_CPP -namespace lodepng -{ - -#ifdef LODEPNG_COMPILE_DISK -void load_file(std::vector& buffer, const std::string& filename) -{ - std::ifstream file(filename.c_str(), std::ios::in|std::ios::binary|std::ios::ate); - - /*get filesize*/ - std::streamsize size = 0; - if(file.seekg(0, std::ios::end).good()) size = file.tellg(); - if(file.seekg(0, std::ios::beg).good()) size -= file.tellg(); - - /*read contents of the file into the vector*/ - buffer.resize(size_t(size)); - if(size > 0) file.read((char*)(&buffer[0]), size); -} - -/*write given buffer to the file, overwriting the file, it doesn't append to it.*/ -void save_file(const std::vector& buffer, const std::string& filename) -{ - std::ofstream file(filename.c_str(), std::ios::out|std::ios::binary); - file.write(buffer.empty() ? 0 : (char*)&buffer[0], std::streamsize(buffer.size())); -} -#endif //LODEPNG_COMPILE_DISK - -#ifdef LODEPNG_COMPILE_ZLIB -#ifdef LODEPNG_COMPILE_DECODER -unsigned decompress(std::vector& out, const unsigned char* in, size_t insize, - const LodePNGDecompressSettings& settings) -{ - unsigned char* buffer = 0; - size_t buffersize = 0; - unsigned error = zlib_decompress(&buffer, &buffersize, in, insize, &settings); - if(buffer) - { - out.insert(out.end(), &buffer[0], &buffer[buffersize]); - lodepng_free(buffer); - } - return error; -} - -unsigned decompress(std::vector& out, const std::vector& in, - const LodePNGDecompressSettings& settings) -{ - return decompress(out, in.empty() ? 0 : &in[0], in.size(), settings); -} -#endif //LODEPNG_COMPILE_DECODER - -#ifdef LODEPNG_COMPILE_ENCODER -unsigned compress(std::vector& out, const unsigned char* in, size_t insize, - const LodePNGCompressSettings& settings) -{ - unsigned char* buffer = 0; - size_t buffersize = 0; - unsigned error = zlib_compress(&buffer, &buffersize, in, insize, &settings); - if(buffer) - { - out.insert(out.end(), &buffer[0], &buffer[buffersize]); - lodepng_free(buffer); - } - return error; -} - -unsigned compress(std::vector& out, const std::vector& in, - const LodePNGCompressSettings& settings) -{ - return compress(out, in.empty() ? 0 : &in[0], in.size(), settings); -} -#endif //LODEPNG_COMPILE_ENCODER -#endif //LODEPNG_COMPILE_ZLIB - - -#ifdef LODEPNG_COMPILE_PNG - -State::State() -{ - lodepng_state_init(this); -} - -State::State(const State& other) -{ - lodepng_state_init(this); - lodepng_state_copy(this, &other); -} - -State::~State() -{ - lodepng_state_cleanup(this); -} - -State& State::operator=(const State& other) -{ - lodepng_state_copy(this, &other); - return *this; -} - -#ifdef LODEPNG_COMPILE_DECODER - -unsigned decode(std::vector& out, unsigned& w, unsigned& h, const unsigned char* in, - size_t insize, LodePNGColorType colortype, unsigned bitdepth) -{ - unsigned char* buffer; - unsigned error = lodepng_decode_memory(&buffer, &w, &h, in, insize, colortype, bitdepth); - if(buffer && !error) - { - State state; - state.info_raw.colortype = colortype; - state.info_raw.bitdepth = bitdepth; - size_t buffersize = lodepng_get_raw_size(w, h, &state.info_raw); - out.insert(out.end(), &buffer[0], &buffer[buffersize]); - lodepng_free(buffer); - } - return error; -} - -unsigned decode(std::vector& out, unsigned& w, unsigned& h, - const std::vector& in, LodePNGColorType colortype, unsigned bitdepth) -{ - return decode(out, w, h, in.empty() ? 0 : &in[0], (unsigned)in.size(), colortype, bitdepth); -} - -unsigned decode(std::vector& out, unsigned& w, unsigned& h, - State& state, - const unsigned char* in, size_t insize) -{ - unsigned char* buffer = NULL; - unsigned error = lodepng_decode(&buffer, &w, &h, &state, in, insize); - if(buffer && !error) - { - size_t buffersize = lodepng_get_raw_size(w, h, &state.info_raw); - out.insert(out.end(), &buffer[0], &buffer[buffersize]); - } - lodepng_free(buffer); - return error; -} - -unsigned decode(std::vector& out, unsigned& w, unsigned& h, - State& state, - const std::vector& in) -{ - return decode(out, w, h, state, in.empty() ? 0 : &in[0], in.size()); -} - -#ifdef LODEPNG_COMPILE_DISK -unsigned decode(std::vector& out, unsigned& w, unsigned& h, const std::string& filename, - LodePNGColorType colortype, unsigned bitdepth) -{ - std::vector buffer; - load_file(buffer, filename); - return decode(out, w, h, buffer, colortype, bitdepth); -} -#endif //LODEPNG_COMPILE_DECODER -#endif //LODEPNG_COMPILE_DISK - -#ifdef LODEPNG_COMPILE_ENCODER -unsigned encode(std::vector& out, const unsigned char* in, unsigned w, unsigned h, - LodePNGColorType colortype, unsigned bitdepth) -{ - unsigned char* buffer; - size_t buffersize; - unsigned error = lodepng_encode_memory(&buffer, &buffersize, in, w, h, colortype, bitdepth); - if(buffer) - { - out.insert(out.end(), &buffer[0], &buffer[buffersize]); - lodepng_free(buffer); - } - return error; -} - -unsigned encode(std::vector& out, - const std::vector& in, unsigned w, unsigned h, - LodePNGColorType colortype, unsigned bitdepth) -{ - if(lodepng_get_raw_size_lct(w, h, colortype, bitdepth) > in.size()) return 84; - return encode(out, in.empty() ? 0 : &in[0], w, h, colortype, bitdepth); -} - -unsigned encode(std::vector& out, - const unsigned char* in, unsigned w, unsigned h, - State& state) -{ - unsigned char* buffer; - size_t buffersize; - unsigned error = lodepng_encode(&buffer, &buffersize, in, w, h, &state); - if(buffer) - { - out.insert(out.end(), &buffer[0], &buffer[buffersize]); - lodepng_free(buffer); - } - return error; -} - -unsigned encode(std::vector& out, - const std::vector& in, unsigned w, unsigned h, - State& state) -{ - if(lodepng_get_raw_size(w, h, &state.info_raw) > in.size()) return 84; - return encode(out, in.empty() ? 0 : &in[0], w, h, state); -} - -#ifdef LODEPNG_COMPILE_DISK -unsigned encode(const std::string& filename, - const unsigned char* in, unsigned w, unsigned h, - LodePNGColorType colortype, unsigned bitdepth) -{ - std::vector buffer; - unsigned error = encode(buffer, in, w, h, colortype, bitdepth); - if(!error) save_file(buffer, filename); - return error; -} - -unsigned encode(const std::string& filename, - const std::vector& in, unsigned w, unsigned h, - LodePNGColorType colortype, unsigned bitdepth) -{ - if(lodepng_get_raw_size_lct(w, h, colortype, bitdepth) > in.size()) return 84; - return encode(filename, in.empty() ? 0 : &in[0], w, h, colortype, bitdepth); -} -#endif //LODEPNG_COMPILE_DISK -#endif //LODEPNG_COMPILE_ENCODER -#endif //LODEPNG_COMPILE_PNG -} //namespace lodepng -#endif /*LODEPNG_COMPILE_CPP*/ diff --git a/GameLib/lodepng.h b/GameLib/lodepng.h deleted file mode 100644 index a4f5bd2..0000000 --- a/GameLib/lodepng.h +++ /dev/null @@ -1,1710 +0,0 @@ -/* -LodePNG version 20140624 - -Copyright (c) 2005-2014 Lode Vandevenne - -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. -*/ - -#ifndef LODEPNG_H -#define LODEPNG_H - -#include /*for size_t*/ - -#ifdef __cplusplus -#include -#include -#endif /*__cplusplus*/ - -/* -The following #defines are used to create code sections. They can be disabled -to disable code sections, which can give faster compile time and smaller binary. -The "NO_COMPILE" defines are designed to be used to pass as defines to the -compiler command to disable them without modifying this header, e.g. --DLODEPNG_NO_COMPILE_ZLIB for gcc. -*/ -/*deflate & zlib. If disabled, you must specify alternative zlib functions in -the custom_zlib field of the compress and decompress settings*/ -#ifndef LODEPNG_NO_COMPILE_ZLIB -#define LODEPNG_COMPILE_ZLIB -#endif -/*png encoder and png decoder*/ -#ifndef LODEPNG_NO_COMPILE_PNG -#define LODEPNG_COMPILE_PNG -#endif -/*deflate&zlib decoder and png decoder*/ -#ifndef LODEPNG_NO_COMPILE_DECODER -#define LODEPNG_COMPILE_DECODER -#endif -/*deflate&zlib encoder and png encoder*/ -#ifndef LODEPNG_NO_COMPILE_ENCODER -#define LODEPNG_COMPILE_ENCODER -#endif -/*the optional built in harddisk file loading and saving functions*/ -#ifndef LODEPNG_NO_COMPILE_DISK -#define LODEPNG_COMPILE_DISK -#endif -/*support for chunks other than IHDR, IDAT, PLTE, tRNS, IEND: ancillary and unknown chunks*/ -#ifndef LODEPNG_NO_COMPILE_ANCILLARY_CHUNKS -#define LODEPNG_COMPILE_ANCILLARY_CHUNKS -#endif -/*ability to convert error numerical codes to English text string*/ -#ifndef LODEPNG_NO_COMPILE_ERROR_TEXT -#define LODEPNG_COMPILE_ERROR_TEXT -#endif -/*Compile the default allocators (C's free, malloc and realloc). If you disable this, -you can define the functions lodepng_free, lodepng_malloc and lodepng_realloc in your -source files with custom allocators.*/ -#ifndef LODEPNG_NO_COMPILE_ALLOCATORS -#define LODEPNG_COMPILE_ALLOCATORS -#endif -/*compile the C++ version (you can disable the C++ wrapper here even when compiling for C++)*/ -#ifdef __cplusplus -#ifndef LODEPNG_NO_COMPILE_CPP -#define LODEPNG_COMPILE_CPP -#endif -#endif - -#ifdef LODEPNG_COMPILE_PNG -/*The PNG color types (also used for raw).*/ -typedef enum LodePNGColorType -{ - LCT_GREY = 0, /*greyscale: 1,2,4,8,16 bit*/ - LCT_RGB = 2, /*RGB: 8,16 bit*/ - LCT_PALETTE = 3, /*palette: 1,2,4,8 bit*/ - LCT_GREY_ALPHA = 4, /*greyscale with alpha: 8,16 bit*/ - LCT_RGBA = 6 /*RGB with alpha: 8,16 bit*/ -} LodePNGColorType; - -#ifdef LODEPNG_COMPILE_DECODER -/* -Converts PNG data in memory to raw pixel data. -out: Output parameter. Pointer to buffer that will contain the raw pixel data. - After decoding, its size is w * h * (bytes per pixel) bytes larger than - initially. Bytes per pixel depends on colortype and bitdepth. - Must be freed after usage with free(*out). - Note: for 16-bit per channel colors, uses big endian format like PNG does. -w: Output parameter. Pointer to width of pixel data. -h: Output parameter. Pointer to height of pixel data. -in: Memory buffer with the PNG file. -insize: size of the in buffer. -colortype: the desired color type for the raw output image. See explanation on PNG color types. -bitdepth: the desired bit depth for the raw output image. See explanation on PNG color types. -Return value: LodePNG error code (0 means no error). -*/ -unsigned lodepng_decode_memory(unsigned char** out, unsigned* w, unsigned* h, - const unsigned char* in, size_t insize, - LodePNGColorType colortype, unsigned bitdepth); - -/*Same as lodepng_decode_memory, but always decodes to 32-bit RGBA raw image*/ -unsigned lodepng_decode32(unsigned char** out, unsigned* w, unsigned* h, - const unsigned char* in, size_t insize); - -/*Same as lodepng_decode_memory, but always decodes to 24-bit RGB raw image*/ -unsigned lodepng_decode24(unsigned char** out, unsigned* w, unsigned* h, - const unsigned char* in, size_t insize); - -#ifdef LODEPNG_COMPILE_DISK -/* -Load PNG from disk, from file with given name. -Same as the other decode functions, but instead takes a filename as input. -*/ -unsigned lodepng_decode_file(unsigned char** out, unsigned* w, unsigned* h, - const char* filename, - LodePNGColorType colortype, unsigned bitdepth); - -/*Same as lodepng_decode_file, but always decodes to 32-bit RGBA raw image.*/ -unsigned lodepng_decode32_file(unsigned char** out, unsigned* w, unsigned* h, - const char* filename); - -/*Same as lodepng_decode_file, but always decodes to 24-bit RGB raw image.*/ -unsigned lodepng_decode24_file(unsigned char** out, unsigned* w, unsigned* h, - const char* filename); -#endif /*LODEPNG_COMPILE_DISK*/ -#endif /*LODEPNG_COMPILE_DECODER*/ - - -#ifdef LODEPNG_COMPILE_ENCODER -/* -Converts raw pixel data into a PNG image in memory. The colortype and bitdepth - of the output PNG image cannot be chosen, they are automatically determined - by the colortype, bitdepth and content of the input pixel data. - Note: for 16-bit per channel colors, needs big endian format like PNG does. -out: Output parameter. Pointer to buffer that will contain the PNG image data. - Must be freed after usage with free(*out). -outsize: Output parameter. Pointer to the size in bytes of the out buffer. -image: The raw pixel data to encode. The size of this buffer should be - w * h * (bytes per pixel), bytes per pixel depends on colortype and bitdepth. -w: width of the raw pixel data in pixels. -h: height of the raw pixel data in pixels. -colortype: the color type of the raw input image. See explanation on PNG color types. -bitdepth: the bit depth of the raw input image. See explanation on PNG color types. -Return value: LodePNG error code (0 means no error). -*/ -unsigned lodepng_encode_memory(unsigned char** out, size_t* outsize, - const unsigned char* image, unsigned w, unsigned h, - LodePNGColorType colortype, unsigned bitdepth); - -/*Same as lodepng_encode_memory, but always encodes from 32-bit RGBA raw image.*/ -unsigned lodepng_encode32(unsigned char** out, size_t* outsize, - const unsigned char* image, unsigned w, unsigned h); - -/*Same as lodepng_encode_memory, but always encodes from 24-bit RGB raw image.*/ -unsigned lodepng_encode24(unsigned char** out, size_t* outsize, - const unsigned char* image, unsigned w, unsigned h); - -#ifdef LODEPNG_COMPILE_DISK -/* -Converts raw pixel data into a PNG file on disk. -Same as the other encode functions, but instead takes a filename as output. -NOTE: This overwrites existing files without warning! -*/ -unsigned lodepng_encode_file(const char* filename, - const unsigned char* image, unsigned w, unsigned h, - LodePNGColorType colortype, unsigned bitdepth); - -/*Same as lodepng_encode_file, but always encodes from 32-bit RGBA raw image.*/ -unsigned lodepng_encode32_file(const char* filename, - const unsigned char* image, unsigned w, unsigned h); - -/*Same as lodepng_encode_file, but always encodes from 24-bit RGB raw image.*/ -unsigned lodepng_encode24_file(const char* filename, - const unsigned char* image, unsigned w, unsigned h); -#endif /*LODEPNG_COMPILE_DISK*/ -#endif /*LODEPNG_COMPILE_ENCODER*/ - - -#ifdef LODEPNG_COMPILE_CPP -namespace lodepng -{ -#ifdef LODEPNG_COMPILE_DECODER -/*Same as lodepng_decode_memory, but decodes to an std::vector.*/ -unsigned decode(std::vector& out, unsigned& w, unsigned& h, - const unsigned char* in, size_t insize, - LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); -unsigned decode(std::vector& out, unsigned& w, unsigned& h, - const std::vector& in, - LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); -#ifdef LODEPNG_COMPILE_DISK -/* -Converts PNG file from disk to raw pixel data in memory. -Same as the other decode functions, but instead takes a filename as input. -*/ -unsigned decode(std::vector& out, unsigned& w, unsigned& h, - const std::string& filename, - LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); -#endif //LODEPNG_COMPILE_DISK -#endif //LODEPNG_COMPILE_DECODER - -#ifdef LODEPNG_COMPILE_ENCODER -/*Same as lodepng_encode_memory, but encodes to an std::vector.*/ -unsigned encode(std::vector& out, - const unsigned char* in, unsigned w, unsigned h, - LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); -unsigned encode(std::vector& out, - const std::vector& in, unsigned w, unsigned h, - LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); -#ifdef LODEPNG_COMPILE_DISK -/* -Converts 32-bit RGBA raw pixel data into a PNG file on disk. -Same as the other encode functions, but instead takes a filename as output. -NOTE: This overwrites existing files without warning! -*/ -unsigned encode(const std::string& filename, - const unsigned char* in, unsigned w, unsigned h, - LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); -unsigned encode(const std::string& filename, - const std::vector& in, unsigned w, unsigned h, - LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); -#endif //LODEPNG_COMPILE_DISK -#endif //LODEPNG_COMPILE_ENCODER -} //namespace lodepng -#endif /*LODEPNG_COMPILE_CPP*/ -#endif /*LODEPNG_COMPILE_PNG*/ - -#ifdef LODEPNG_COMPILE_ERROR_TEXT -/*Returns an English description of the numerical error code.*/ -const char* lodepng_error_text(unsigned code); -#endif /*LODEPNG_COMPILE_ERROR_TEXT*/ - -#ifdef LODEPNG_COMPILE_DECODER -/*Settings for zlib decompression*/ -typedef struct LodePNGDecompressSettings LodePNGDecompressSettings; -struct LodePNGDecompressSettings -{ - unsigned ignore_adler32; /*if 1, continue and don't give an error message if the Adler32 checksum is corrupted*/ - - /*use custom zlib decoder instead of built in one (default: null)*/ - unsigned (*custom_zlib)(unsigned char**, size_t*, - const unsigned char*, size_t, - const LodePNGDecompressSettings*); - /*use custom deflate decoder instead of built in one (default: null) - if custom_zlib is used, custom_deflate is ignored since only the built in - zlib function will call custom_deflate*/ - unsigned (*custom_inflate)(unsigned char**, size_t*, - const unsigned char*, size_t, - const LodePNGDecompressSettings*); - - const void* custom_context; /*optional custom settings for custom functions*/ -}; - -extern const LodePNGDecompressSettings lodepng_default_decompress_settings; -void lodepng_decompress_settings_init(LodePNGDecompressSettings* settings); -#endif /*LODEPNG_COMPILE_DECODER*/ - -#ifdef LODEPNG_COMPILE_ENCODER -/* -Settings for zlib compression. Tweaking these settings tweaks the balance -between speed and compression ratio. -*/ -typedef struct LodePNGCompressSettings LodePNGCompressSettings; -struct LodePNGCompressSettings /*deflate = compress*/ -{ - /*LZ77 related settings*/ - unsigned btype; /*the block type for LZ (0, 1, 2 or 3, see zlib standard). Should be 2 for proper compression.*/ - unsigned use_lz77; /*whether or not to use LZ77. Should be 1 for proper compression.*/ - unsigned windowsize; /*must be a power of two <= 32768. higher compresses more but is slower. Default value: 2048.*/ - unsigned minmatch; /*mininum lz77 length. 3 is normally best, 6 can be better for some PNGs. Default: 0*/ - unsigned nicematch; /*stop searching if >= this length found. Set to 258 for best compression. Default: 128*/ - unsigned lazymatching; /*use lazy matching: better compression but a bit slower. Default: true*/ - - /*use custom zlib encoder instead of built in one (default: null)*/ - unsigned (*custom_zlib)(unsigned char**, size_t*, - const unsigned char*, size_t, - const LodePNGCompressSettings*); - /*use custom deflate encoder instead of built in one (default: null) - if custom_zlib is used, custom_deflate is ignored since only the built in - zlib function will call custom_deflate*/ - unsigned (*custom_deflate)(unsigned char**, size_t*, - const unsigned char*, size_t, - const LodePNGCompressSettings*); - - const void* custom_context; /*optional custom settings for custom functions*/ -}; - -extern const LodePNGCompressSettings lodepng_default_compress_settings; -void lodepng_compress_settings_init(LodePNGCompressSettings* settings); -#endif /*LODEPNG_COMPILE_ENCODER*/ - -#ifdef LODEPNG_COMPILE_PNG -/* -Color mode of an image. Contains all information required to decode the pixel -bits to RGBA colors. This information is the same as used in the PNG file -format, and is used both for PNG and raw image data in LodePNG. -*/ -typedef struct LodePNGColorMode -{ - /*header (IHDR)*/ - LodePNGColorType colortype; /*color type, see PNG standard or documentation further in this header file*/ - unsigned bitdepth; /*bits per sample, see PNG standard or documentation further in this header file*/ - - /* - palette (PLTE and tRNS) - - Dynamically allocated with the colors of the palette, including alpha. - When encoding a PNG, to store your colors in the palette of the LodePNGColorMode, first use - lodepng_palette_clear, then for each color use lodepng_palette_add. - If you encode an image without alpha with palette, don't forget to put value 255 in each A byte of the palette. - - When decoding, by default you can ignore this palette, since LodePNG already - fills the palette colors in the pixels of the raw RGBA output. - - The palette is only supported for color type 3. - */ - unsigned char* palette; /*palette in RGBARGBA... order. When allocated, must be either 0, or have size 1024*/ - size_t palettesize; /*palette size in number of colors (amount of bytes is 4 * palettesize)*/ - - /* - transparent color key (tRNS) - - This color uses the same bit depth as the bitdepth value in this struct, which can be 1-bit to 16-bit. - For greyscale PNGs, r, g and b will all 3 be set to the same. - - When decoding, by default you can ignore this information, since LodePNG sets - pixels with this key to transparent already in the raw RGBA output. - - The color key is only supported for color types 0 and 2. - */ - unsigned key_defined; /*is a transparent color key given? 0 = false, 1 = true*/ - unsigned key_r; /*red/greyscale component of color key*/ - unsigned key_g; /*green component of color key*/ - unsigned key_b; /*blue component of color key*/ -} LodePNGColorMode; - -/*init, cleanup and copy functions to use with this struct*/ -void lodepng_color_mode_init(LodePNGColorMode* info); -void lodepng_color_mode_cleanup(LodePNGColorMode* info); -/*return value is error code (0 means no error)*/ -unsigned lodepng_color_mode_copy(LodePNGColorMode* dest, const LodePNGColorMode* source); - -void lodepng_palette_clear(LodePNGColorMode* info); -/*add 1 color to the palette*/ -unsigned lodepng_palette_add(LodePNGColorMode* info, - unsigned char r, unsigned char g, unsigned char b, unsigned char a); - -/*get the total amount of bits per pixel, based on colortype and bitdepth in the struct*/ -unsigned lodepng_get_bpp(const LodePNGColorMode* info); -/*get the amount of color channels used, based on colortype in the struct. -If a palette is used, it counts as 1 channel.*/ -unsigned lodepng_get_channels(const LodePNGColorMode* info); -/*is it a greyscale type? (only colortype 0 or 4)*/ -unsigned lodepng_is_greyscale_type(const LodePNGColorMode* info); -/*has it got an alpha channel? (only colortype 2 or 6)*/ -unsigned lodepng_is_alpha_type(const LodePNGColorMode* info); -/*has it got a palette? (only colortype 3)*/ -unsigned lodepng_is_palette_type(const LodePNGColorMode* info); -/*only returns true if there is a palette and there is a value in the palette with alpha < 255. -Loops through the palette to check this.*/ -unsigned lodepng_has_palette_alpha(const LodePNGColorMode* info); -/* -Check if the given color info indicates the possibility of having non-opaque pixels in the PNG image. -Returns true if the image can have translucent or invisible pixels (it still be opaque if it doesn't use such pixels). -Returns false if the image can only have opaque pixels. -In detail, it returns true only if it's a color type with alpha, or has a palette with non-opaque values, -or if "key_defined" is true. -*/ -unsigned lodepng_can_have_alpha(const LodePNGColorMode* info); -/*Returns the byte size of a raw image buffer with given width, height and color mode*/ -size_t lodepng_get_raw_size(unsigned w, unsigned h, const LodePNGColorMode* color); - -#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS -/*The information of a Time chunk in PNG.*/ -typedef struct LodePNGTime -{ - unsigned year; /*2 bytes used (0-65535)*/ - unsigned month; /*1-12*/ - unsigned day; /*1-31*/ - unsigned hour; /*0-23*/ - unsigned minute; /*0-59*/ - unsigned second; /*0-60 (to allow for leap seconds)*/ -} LodePNGTime; -#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ - -/*Information about the PNG image, except pixels, width and height.*/ -typedef struct LodePNGInfo -{ - /*header (IHDR), palette (PLTE) and transparency (tRNS) chunks*/ - unsigned compression_method;/*compression method of the original file. Always 0.*/ - unsigned filter_method; /*filter method of the original file*/ - unsigned interlace_method; /*interlace method of the original file*/ - LodePNGColorMode color; /*color type and bits, palette and transparency of the PNG file*/ - -#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - /* - suggested background color chunk (bKGD) - This color uses the same color mode as the PNG (except alpha channel), which can be 1-bit to 16-bit. - - For greyscale PNGs, r, g and b will all 3 be set to the same. When encoding - the encoder writes the red one. For palette PNGs: When decoding, the RGB value - will be stored, not a palette index. But when encoding, specify the index of - the palette in background_r, the other two are then ignored. - - The decoder does not use this background color to edit the color of pixels. - */ - unsigned background_defined; /*is a suggested background color given?*/ - unsigned background_r; /*red component of suggested background color*/ - unsigned background_g; /*green component of suggested background color*/ - unsigned background_b; /*blue component of suggested background color*/ - - /* - non-international text chunks (tEXt and zTXt) - - The char** arrays each contain num strings. The actual messages are in - text_strings, while text_keys are keywords that give a short description what - the actual text represents, e.g. Title, Author, Description, or anything else. - - A keyword is minimum 1 character and maximum 79 characters long. It's - discouraged to use a single line length longer than 79 characters for texts. - - Don't allocate these text buffers yourself. Use the init/cleanup functions - correctly and use lodepng_add_text and lodepng_clear_text. - */ - size_t text_num; /*the amount of texts in these char** buffers (there may be more texts in itext)*/ - char** text_keys; /*the keyword of a text chunk (e.g. "Comment")*/ - char** text_strings; /*the actual text*/ - - /* - international text chunks (iTXt) - Similar to the non-international text chunks, but with additional strings - "langtags" and "transkeys". - */ - size_t itext_num; /*the amount of international texts in this PNG*/ - char** itext_keys; /*the English keyword of the text chunk (e.g. "Comment")*/ - char** itext_langtags; /*language tag for this text's language, ISO/IEC 646 string, e.g. ISO 639 language tag*/ - char** itext_transkeys; /*keyword translated to the international language - UTF-8 string*/ - char** itext_strings; /*the actual international text - UTF-8 string*/ - - /*time chunk (tIME)*/ - unsigned time_defined; /*set to 1 to make the encoder generate a tIME chunk*/ - LodePNGTime time; - - /*phys chunk (pHYs)*/ - unsigned phys_defined; /*if 0, there is no pHYs chunk and the values below are undefined, if 1 else there is one*/ - unsigned phys_x; /*pixels per unit in x direction*/ - unsigned phys_y; /*pixels per unit in y direction*/ - unsigned phys_unit; /*may be 0 (unknown unit) or 1 (metre)*/ - - /* - unknown chunks - There are 3 buffers, one for each position in the PNG where unknown chunks can appear - each buffer contains all unknown chunks for that position consecutively - The 3 buffers are the unknown chunks between certain critical chunks: - 0: IHDR-PLTE, 1: PLTE-IDAT, 2: IDAT-IEND - Do not allocate or traverse this data yourself. Use the chunk traversing functions declared - later, such as lodepng_chunk_next and lodepng_chunk_append, to read/write this struct. - */ - unsigned char* unknown_chunks_data[3]; - size_t unknown_chunks_size[3]; /*size in bytes of the unknown chunks, given for protection*/ -#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ -} LodePNGInfo; - -/*init, cleanup and copy functions to use with this struct*/ -void lodepng_info_init(LodePNGInfo* info); -void lodepng_info_cleanup(LodePNGInfo* info); -/*return value is error code (0 means no error)*/ -unsigned lodepng_info_copy(LodePNGInfo* dest, const LodePNGInfo* source); - -#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS -void lodepng_clear_text(LodePNGInfo* info); /*use this to clear the texts again after you filled them in*/ -unsigned lodepng_add_text(LodePNGInfo* info, const char* key, const char* str); /*push back both texts at once*/ - -void lodepng_clear_itext(LodePNGInfo* info); /*use this to clear the itexts again after you filled them in*/ -unsigned lodepng_add_itext(LodePNGInfo* info, const char* key, const char* langtag, - const char* transkey, const char* str); /*push back the 4 texts of 1 chunk at once*/ -#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ - -/* -Converts raw buffer from one color type to another color type, based on -LodePNGColorMode structs to describe the input and output color type. -See the reference manual at the end of this header file to see which color conversions are supported. -return value = LodePNG error code (0 if all went ok, an error if the conversion isn't supported) -The out buffer must have size (w * h * bpp + 7) / 8, where bpp is the bits per pixel -of the output color type (lodepng_get_bpp) -The fix_png value works as described in struct LodePNGDecoderSettings. -Note: for 16-bit per channel colors, uses big endian format like PNG does. -*/ -unsigned lodepng_convert(unsigned char* out, const unsigned char* in, - LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in, - unsigned w, unsigned h, unsigned fix_png); - -#ifdef LODEPNG_COMPILE_DECODER -/* -Settings for the decoder. This contains settings for the PNG and the Zlib -decoder, but not the Info settings from the Info structs. -*/ -typedef struct LodePNGDecoderSettings -{ - LodePNGDecompressSettings zlibsettings; /*in here is the setting to ignore Adler32 checksums*/ - - unsigned ignore_crc; /*ignore CRC checksums*/ - /* - The fix_png setting, if 1, makes the decoder tolerant towards some PNG images - that do not correctly follow the PNG specification. This only supports errors - that are fixable, were found in images that are actually used on the web, and - are silently tolerated by other decoders as well. Currently only one such fix - is implemented: if a palette index is out of bounds given the palette size, - interpret it as opaque black. - By default this value is 0, which makes it stop with an error on such images. - */ - unsigned fix_png; - unsigned color_convert; /*whether to convert the PNG to the color type you want. Default: yes*/ - -#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - unsigned read_text_chunks; /*if false but remember_unknown_chunks is true, they're stored in the unknown chunks*/ - /*store all bytes from unknown chunks in the LodePNGInfo (off by default, useful for a png editor)*/ - unsigned remember_unknown_chunks; -#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ -} LodePNGDecoderSettings; - -void lodepng_decoder_settings_init(LodePNGDecoderSettings* settings); -#endif /*LODEPNG_COMPILE_DECODER*/ - -#ifdef LODEPNG_COMPILE_ENCODER -/*automatically use color type with less bits per pixel if losslessly possible. Default: AUTO*/ -typedef enum LodePNGFilterStrategy -{ - /*every filter at zero*/ - LFS_ZERO, - /*Use filter that gives minumum sum, as described in the official PNG filter heuristic.*/ - LFS_MINSUM, - /*Use the filter type that gives smallest Shannon entropy for this scanline. Depending - on the image, this is better or worse than minsum.*/ - LFS_ENTROPY, - /* - Brute-force-search PNG filters by compressing each filter for each scanline. - Experimental, very slow, and only rarely gives better compression than MINSUM. - */ - LFS_BRUTE_FORCE, - /*use predefined_filters buffer: you specify the filter type for each scanline*/ - LFS_PREDEFINED -} LodePNGFilterStrategy; - -/*automatically use color type with less bits per pixel if losslessly possible. Default: LAC_AUTO*/ -typedef enum LodePNGAutoConvert -{ - LAC_NO, /*use color type user requested*/ - LAC_ALPHA, /*use color type user requested, but if only opaque pixels and RGBA or grey+alpha, use RGB or grey*/ - LAC_AUTO, /*use PNG color type that can losslessly represent the uncompressed image the smallest possible*/ - /* - like AUTO, but do not choose 1, 2 or 4 bit per pixel types. - sometimes a PNG image compresses worse if less than 8 bits per pixels. - */ - LAC_AUTO_NO_NIBBLES, - /* - like AUTO, but never choose palette color type. For small images, encoding - the palette may take more bytes than what is gained. Note that AUTO also - already prevents encoding the palette for extremely small images, but that may - not be sufficient because due to the compression it cannot predict when to - switch. - */ - LAC_AUTO_NO_PALETTE, - LAC_AUTO_NO_NIBBLES_NO_PALETTE -} LodePNGAutoConvert; - - -/* -Automatically chooses color type that gives smallest amount of bits in the -output image, e.g. grey if there are only greyscale pixels, palette if there -are less than 256 colors, ... -The auto_convert parameter allows limiting it to not use palette, ... -*/ -unsigned lodepng_auto_choose_color(LodePNGColorMode* mode_out, - const unsigned char* image, unsigned w, unsigned h, - const LodePNGColorMode* mode_in, - LodePNGAutoConvert auto_convert); - -/*Settings for the encoder.*/ -typedef struct LodePNGEncoderSettings -{ - LodePNGCompressSettings zlibsettings; /*settings for the zlib encoder, such as window size, ...*/ - - LodePNGAutoConvert auto_convert; /*how to automatically choose output PNG color type, if at all*/ - - /*If true, follows the official PNG heuristic: if the PNG uses a palette or lower than - 8 bit depth, set all filters to zero. Otherwise use the filter_strategy. Note that to - completely follow the official PNG heuristic, filter_palette_zero must be true and - filter_strategy must be LFS_MINSUM*/ - unsigned filter_palette_zero; - /*Which filter strategy to use when not using zeroes due to filter_palette_zero. - Set filter_palette_zero to 0 to ensure always using your chosen strategy. Default: LFS_MINSUM*/ - LodePNGFilterStrategy filter_strategy; - /*used if filter_strategy is LFS_PREDEFINED. In that case, this must point to a buffer with - the same length as the amount of scanlines in the image, and each value must <= 5. You - have to cleanup this buffer, LodePNG will never free it. Don't forget that filter_palette_zero - must be set to 0 to ensure this is also used on palette or low bitdepth images.*/ - const unsigned char* predefined_filters; - - /*force creating a PLTE chunk if colortype is 2 or 6 (= a suggested palette). - If colortype is 3, PLTE is _always_ created.*/ - unsigned force_palette; -#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - /*add LodePNG identifier and version as a text chunk, for debugging*/ - unsigned add_id; - /*encode text chunks as zTXt chunks instead of tEXt chunks, and use compression in iTXt chunks*/ - unsigned text_compression; -#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ -} LodePNGEncoderSettings; - -void lodepng_encoder_settings_init(LodePNGEncoderSettings* settings); -#endif /*LODEPNG_COMPILE_ENCODER*/ - - -#if defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) -/*The settings, state and information for extended encoding and decoding.*/ -typedef struct LodePNGState -{ -#ifdef LODEPNG_COMPILE_DECODER - LodePNGDecoderSettings decoder; /*the decoding settings*/ -#endif /*LODEPNG_COMPILE_DECODER*/ -#ifdef LODEPNG_COMPILE_ENCODER - LodePNGEncoderSettings encoder; /*the encoding settings*/ -#endif /*LODEPNG_COMPILE_ENCODER*/ - LodePNGColorMode info_raw; /*specifies the format in which you would like to get the raw pixel buffer*/ - LodePNGInfo info_png; /*info of the PNG image obtained after decoding*/ - unsigned error; -#ifdef LODEPNG_COMPILE_CPP - //For the lodepng::State subclass. - virtual ~LodePNGState(){} -#endif -} LodePNGState; - -/*init, cleanup and copy functions to use with this struct*/ -void lodepng_state_init(LodePNGState* state); -void lodepng_state_cleanup(LodePNGState* state); -void lodepng_state_copy(LodePNGState* dest, const LodePNGState* source); -#endif /* defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) */ - -#ifdef LODEPNG_COMPILE_DECODER -/* -Same as lodepng_decode_memory, but uses a LodePNGState to allow custom settings and -getting much more information about the PNG image and color mode. -*/ -unsigned lodepng_decode(unsigned char** out, unsigned* w, unsigned* h, - LodePNGState* state, - const unsigned char* in, size_t insize); - -/* -Read the PNG header, but not the actual data. This returns only the information -that is in the header chunk of the PNG, such as width, height and color type. The -information is placed in the info_png field of the LodePNGState. -*/ -unsigned lodepng_inspect(unsigned* w, unsigned* h, - LodePNGState* state, - const unsigned char* in, size_t insize); -#endif /*LODEPNG_COMPILE_DECODER*/ - - -#ifdef LODEPNG_COMPILE_ENCODER -/*This function allocates the out buffer with standard malloc and stores the size in *outsize.*/ -unsigned lodepng_encode(unsigned char** out, size_t* outsize, - const unsigned char* image, unsigned w, unsigned h, - LodePNGState* state); -#endif /*LODEPNG_COMPILE_ENCODER*/ - -/* -The lodepng_chunk functions are normally not needed, except to traverse the -unknown chunks stored in the LodePNGInfo struct, or add new ones to it. -It also allows traversing the chunks of an encoded PNG file yourself. - -PNG standard chunk naming conventions: -First byte: uppercase = critical, lowercase = ancillary -Second byte: uppercase = public, lowercase = private -Third byte: must be uppercase -Fourth byte: uppercase = unsafe to copy, lowercase = safe to copy -*/ - -/*get the length of the data of the chunk. Total chunk length has 12 bytes more.*/ -unsigned lodepng_chunk_length(const unsigned char* chunk); - -/*puts the 4-byte type in null terminated string*/ -void lodepng_chunk_type(char type[5], const unsigned char* chunk); - -/*check if the type is the given type*/ -unsigned char lodepng_chunk_type_equals(const unsigned char* chunk, const char* type); - -/*0: it's one of the critical chunk types, 1: it's an ancillary chunk (see PNG standard)*/ -unsigned char lodepng_chunk_ancillary(const unsigned char* chunk); - -/*0: public, 1: private (see PNG standard)*/ -unsigned char lodepng_chunk_private(const unsigned char* chunk); - -/*0: the chunk is unsafe to copy, 1: the chunk is safe to copy (see PNG standard)*/ -unsigned char lodepng_chunk_safetocopy(const unsigned char* chunk); - -/*get pointer to the data of the chunk, where the input points to the header of the chunk*/ -unsigned char* lodepng_chunk_data(unsigned char* chunk); -const unsigned char* lodepng_chunk_data_const(const unsigned char* chunk); - -/*returns 0 if the crc is correct, 1 if it's incorrect (0 for OK as usual!)*/ -unsigned lodepng_chunk_check_crc(const unsigned char* chunk); - -/*generates the correct CRC from the data and puts it in the last 4 bytes of the chunk*/ -void lodepng_chunk_generate_crc(unsigned char* chunk); - -/*iterate to next chunks. don't use on IEND chunk, as there is no next chunk then*/ -unsigned char* lodepng_chunk_next(unsigned char* chunk); -const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk); - -/* -Appends chunk to the data in out. The given chunk should already have its chunk header. -The out variable and outlength are updated to reflect the new reallocated buffer. -Returns error code (0 if it went ok) -*/ -unsigned lodepng_chunk_append(unsigned char** out, size_t* outlength, const unsigned char* chunk); - -/* -Appends new chunk to out. The chunk to append is given by giving its length, type -and data separately. The type is a 4-letter string. -The out variable and outlength are updated to reflect the new reallocated buffer. -Returne error code (0 if it went ok) -*/ -unsigned lodepng_chunk_create(unsigned char** out, size_t* outlength, unsigned length, - const char* type, const unsigned char* data); - - -/*Calculate CRC32 of buffer*/ -unsigned lodepng_crc32(const unsigned char* buf, size_t len); -#endif /*LODEPNG_COMPILE_PNG*/ - - -#ifdef LODEPNG_COMPILE_ZLIB -/* -This zlib part can be used independently to zlib compress and decompress a -buffer. It cannot be used to create gzip files however, and it only supports the -part of zlib that is required for PNG, it does not support dictionaries. -*/ - -#ifdef LODEPNG_COMPILE_DECODER -/*Inflate a buffer. Inflate is the decompression step of deflate. Out buffer must be freed after use.*/ -unsigned lodepng_inflate(unsigned char** out, size_t* outsize, - const unsigned char* in, size_t insize, - const LodePNGDecompressSettings* settings); - -/* -Decompresses Zlib data. Reallocates the out buffer and appends the data. The -data must be according to the zlib specification. -Either, *out must be NULL and *outsize must be 0, or, *out must be a valid -buffer and *outsize its size in bytes. out must be freed by user after usage. -*/ -unsigned lodepng_zlib_decompress(unsigned char** out, size_t* outsize, - const unsigned char* in, size_t insize, - const LodePNGDecompressSettings* settings); -#endif /*LODEPNG_COMPILE_DECODER*/ - -#ifdef LODEPNG_COMPILE_ENCODER -/* -Compresses data with Zlib. Reallocates the out buffer and appends the data. -Zlib adds a small header and trailer around the deflate data. -The data is output in the format of the zlib specification. -Either, *out must be NULL and *outsize must be 0, or, *out must be a valid -buffer and *outsize its size in bytes. out must be freed by user after usage. -*/ -unsigned lodepng_zlib_compress(unsigned char** out, size_t* outsize, - const unsigned char* in, size_t insize, - const LodePNGCompressSettings* settings); - -/* -Find length-limited Huffman code for given frequencies. This function is in the -public interface only for tests, it's used internally by lodepng_deflate. -*/ -unsigned lodepng_huffman_code_lengths(unsigned* lengths, const unsigned* frequencies, - size_t numcodes, unsigned maxbitlen); - -/*Compress a buffer with deflate. See RFC 1951. Out buffer must be freed after use.*/ -unsigned lodepng_deflate(unsigned char** out, size_t* outsize, - const unsigned char* in, size_t insize, - const LodePNGCompressSettings* settings); - -#endif /*LODEPNG_COMPILE_ENCODER*/ -#endif /*LODEPNG_COMPILE_ZLIB*/ - -#ifdef LODEPNG_COMPILE_DISK -/* -Load a file from disk into buffer. The function allocates the out buffer, and -after usage you should free it. -out: output parameter, contains pointer to loaded buffer. -outsize: output parameter, size of the allocated out buffer -filename: the path to the file to load -return value: error code (0 means ok) -*/ -unsigned lodepng_load_file(unsigned char** out, size_t* outsize, const char* filename); - -/* -Save a file from buffer to disk. Warning, if it exists, this function overwrites -the file without warning! -buffer: the buffer to write -buffersize: size of the buffer to write -filename: the path to the file to save to -return value: error code (0 means ok) -*/ -unsigned lodepng_save_file(const unsigned char* buffer, size_t buffersize, const char* filename); -#endif /*LODEPNG_COMPILE_DISK*/ - -#ifdef LODEPNG_COMPILE_CPP -//The LodePNG C++ wrapper uses std::vectors instead of manually allocated memory buffers. -namespace lodepng -{ -#ifdef LODEPNG_COMPILE_PNG -class State : public LodePNGState -{ - public: - State(); - State(const State& other); - virtual ~State(); - State& operator=(const State& other); -}; - -#ifdef LODEPNG_COMPILE_DECODER -//Same as other lodepng::decode, but using a State for more settings and information. -unsigned decode(std::vector& out, unsigned& w, unsigned& h, - State& state, - const unsigned char* in, size_t insize); -unsigned decode(std::vector& out, unsigned& w, unsigned& h, - State& state, - const std::vector& in); -#endif /*LODEPNG_COMPILE_DECODER*/ - -#ifdef LODEPNG_COMPILE_ENCODER -//Same as other lodepng::encode, but using a State for more settings and information. -unsigned encode(std::vector& out, - const unsigned char* in, unsigned w, unsigned h, - State& state); -unsigned encode(std::vector& out, - const std::vector& in, unsigned w, unsigned h, - State& state); -#endif /*LODEPNG_COMPILE_ENCODER*/ - -#ifdef LODEPNG_COMPILE_DISK -/* -Load a file from disk into an std::vector. If the vector is empty, then either -the file doesn't exist or is an empty file. -*/ -void load_file(std::vector& buffer, const std::string& filename); - -/* -Save the binary data in an std::vector to a file on disk. The file is overwritten -without warning. -*/ -void save_file(const std::vector& buffer, const std::string& filename); -#endif //LODEPNG_COMPILE_DISK -#endif //LODEPNG_COMPILE_PNG - -#ifdef LODEPNG_COMPILE_ZLIB -#ifdef LODEPNG_COMPILE_DECODER -//Zlib-decompress an unsigned char buffer -unsigned decompress(std::vector& out, const unsigned char* in, size_t insize, - const LodePNGDecompressSettings& settings = lodepng_default_decompress_settings); - -//Zlib-decompress an std::vector -unsigned decompress(std::vector& out, const std::vector& in, - const LodePNGDecompressSettings& settings = lodepng_default_decompress_settings); -#endif //LODEPNG_COMPILE_DECODER - -#ifdef LODEPNG_COMPILE_ENCODER -//Zlib-compress an unsigned char buffer -unsigned compress(std::vector& out, const unsigned char* in, size_t insize, - const LodePNGCompressSettings& settings = lodepng_default_compress_settings); - -//Zlib-compress an std::vector -unsigned compress(std::vector& out, const std::vector& in, - const LodePNGCompressSettings& settings = lodepng_default_compress_settings); -#endif //LODEPNG_COMPILE_ENCODER -#endif //LODEPNG_COMPILE_ZLIB -} //namespace lodepng -#endif /*LODEPNG_COMPILE_CPP*/ - -/* -TODO: -[.] test if there are no memory leaks or security exploits - done a lot but needs to be checked often -[.] check compatibility with vareous compilers - done but needs to be redone for every newer version -[X] converting color to 16-bit per channel types -[ ] read all public PNG chunk types (but never let the color profile and gamma ones touch RGB values) -[ ] make sure encoder generates no chunks with size > (2^31)-1 -[ ] partial decoding (stream processing) -[X] let the "isFullyOpaque" function check color keys and transparent palettes too -[X] better name for the variables "codes", "codesD", "codelengthcodes", "clcl" and "lldl" -[ ] don't stop decoding on errors like 69, 57, 58 (make warnings) -[ ] make option to choose if the raw image with non multiple of 8 bits per scanline should have padding bits or not -[ ] let the C++ wrapper catch exceptions coming from the standard library and return LodePNG error codes -*/ - -#endif /*LODEPNG_H inclusion guard*/ - -/* -LodePNG Documentation ---------------------- - -0. table of contents --------------------- - - 1. about - 1.1. supported features - 1.2. features not supported - 2. C and C++ version - 3. security - 4. decoding - 5. encoding - 6. color conversions - 6.1. PNG color types - 6.2. color conversions - 6.3. padding bits - 6.4. A note about 16-bits per channel and endianness - 7. error values - 8. chunks and PNG editing - 9. compiler support - 10. examples - 10.1. decoder C++ example - 10.2. decoder C example - 11. changes - 12. contact information - - -1. about --------- - -PNG is a file format to store raster images losslessly with good compression, -supporting different color types and alpha channel. - -LodePNG is a PNG codec according to the Portable Network Graphics (PNG) -Specification (Second Edition) - W3C Recommendation 10 November 2003. - -The specifications used are: - -*) Portable Network Graphics (PNG) Specification (Second Edition): - http://www.w3.org/TR/2003/REC-PNG-20031110 -*) RFC 1950 ZLIB Compressed Data Format version 3.3: - http://www.gzip.org/zlib/rfc-zlib.html -*) RFC 1951 DEFLATE Compressed Data Format Specification ver 1.3: - http://www.gzip.org/zlib/rfc-deflate.html - -The most recent version of LodePNG can currently be found at -http://lodev.org/lodepng/ - -LodePNG works both in C (ISO C90) and C++, with a C++ wrapper that adds -extra functionality. - -LodePNG exists out of two files: --lodepng.h: the header file for both C and C++ --lodepng.c(pp): give it the name lodepng.c or lodepng.cpp (or .cc) depending on your usage - -If you want to start using LodePNG right away without reading this doc, get the -examples from the LodePNG website to see how to use it in code, or check the -smaller examples in chapter 13 here. - -LodePNG is simple but only supports the basic requirements. To achieve -simplicity, the following design choices were made: There are no dependencies -on any external library. There are functions to decode and encode a PNG with -a single function call, and extended versions of these functions taking a -LodePNGState struct allowing to specify or get more information. By default -the colors of the raw image are always RGB or RGBA, no matter what color type -the PNG file uses. To read and write files, there are simple functions to -convert the files to/from buffers in memory. - -This all makes LodePNG suitable for loading textures in games, demos and small -programs, ... It's less suitable for full fledged image editors, loading PNGs -over network (it requires all the image data to be available before decoding can -begin), life-critical systems, ... - -1.1. supported features ------------------------ - -The following features are supported by the decoder: - -*) decoding of PNGs with any color type, bit depth and interlace mode, to a 24- or 32-bit color raw image, - or the same color type as the PNG -*) encoding of PNGs, from any raw image to 24- or 32-bit color, or the same color type as the raw image -*) Adam7 interlace and deinterlace for any color type -*) loading the image from harddisk or decoding it from a buffer from other sources than harddisk -*) support for alpha channels, including RGBA color model, translucent palettes and color keying -*) zlib decompression (inflate) -*) zlib compression (deflate) -*) CRC32 and ADLER32 checksums -*) handling of unknown chunks, allowing making a PNG editor that stores custom and unknown chunks. -*) the following chunks are supported (generated/interpreted) by both encoder and decoder: - IHDR: header information - PLTE: color palette - IDAT: pixel data - IEND: the final chunk - tRNS: transparency for palettized images - tEXt: textual information - zTXt: compressed textual information - iTXt: international textual information - bKGD: suggested background color - pHYs: physical dimensions - tIME: modification time - -1.2. features not supported ---------------------------- - -The following features are _not_ supported: - -*) some features needed to make a conformant PNG-Editor might be still missing. -*) partial loading/stream processing. All data must be available and is processed in one call. -*) The following public chunks are not supported but treated as unknown chunks by LodePNG - cHRM, gAMA, iCCP, sRGB, sBIT, hIST, sPLT - Some of these are not supported on purpose: LodePNG wants to provide the RGB values - stored in the pixels, not values modified by system dependent gamma or color models. - - -2. C and C++ version --------------------- - -The C version uses buffers allocated with alloc that you need to free() -yourself. You need to use init and cleanup functions for each struct whenever -using a struct from the C version to avoid exploits and memory leaks. - -The C++ version has extra functions with std::vectors in the interface and the -lodepng::State class which is a LodePNGState with constructor and destructor. - -These files work without modification for both C and C++ compilers because all -the additional C++ code is in "#ifdef __cplusplus" blocks that make C-compilers -ignore it, and the C code is made to compile both with strict ISO C90 and C++. - -To use the C++ version, you need to rename the source file to lodepng.cpp -(instead of lodepng.c), and compile it with a C++ compiler. - -To use the C version, you need to rename the source file to lodepng.c (instead -of lodepng.cpp), and compile it with a C compiler. - - -3. Security ------------ - -Even if carefully designed, it's always possible that LodePNG contains possible -exploits. If you discover one, please let me know, and it will be fixed. - -When using LodePNG, care has to be taken with the C version of LodePNG, as well -as the C-style structs when working with C++. The following conventions are used -for all C-style structs: - --if a struct has a corresponding init function, always call the init function when making a new one --if a struct has a corresponding cleanup function, call it before the struct disappears to avoid memory leaks --if a struct has a corresponding copy function, use the copy function instead of "=". - The destination must also be inited already. - - -4. Decoding ------------ - -Decoding converts a PNG compressed image to a raw pixel buffer. - -Most documentation on using the decoder is at its declarations in the header -above. For C, simple decoding can be done with functions such as -lodepng_decode32, and more advanced decoding can be done with the struct -LodePNGState and lodepng_decode. For C++, all decoding can be done with the -various lodepng::decode functions, and lodepng::State can be used for advanced -features. - -When using the LodePNGState, it uses the following fields for decoding: -*) LodePNGInfo info_png: it stores extra information about the PNG (the input) in here -*) LodePNGColorMode info_raw: here you can say what color mode of the raw image (the output) you want to get -*) LodePNGDecoderSettings decoder: you can specify a few extra settings for the decoder to use - -LodePNGInfo info_png --------------------- - -After decoding, this contains extra information of the PNG image, except the actual -pixels, width and height because these are already gotten directly from the decoder -functions. - -It contains for example the original color type of the PNG image, text comments, -suggested background color, etc... More details about the LodePNGInfo struct are -at its declaration documentation. - -LodePNGColorMode info_raw -------------------------- - -When decoding, here you can specify which color type you want -the resulting raw image to be. If this is different from the colortype of the -PNG, then the decoder will automatically convert the result. This conversion -always works, except if you want it to convert a color PNG to greyscale or to -a palette with missing colors. - -By default, 32-bit color is used for the result. - -LodePNGDecoderSettings decoder ------------------------------- - -The settings can be used to ignore the errors created by invalid CRC and Adler32 -chunks, and to disable the decoding of tEXt chunks. - -There's also a setting color_convert, true by default. If false, no conversion -is done, the resulting data will be as it was in the PNG (after decompression) -and you'll have to puzzle the colors of the pixels together yourself using the -color type information in the LodePNGInfo. - - -5. Encoding ------------ - -Encoding converts a raw pixel buffer to a PNG compressed image. - -Most documentation on using the encoder is at its declarations in the header -above. For C, simple encoding can be done with functions such as -lodepng_encode32, and more advanced decoding can be done with the struct -LodePNGState and lodepng_encode. For C++, all encoding can be done with the -various lodepng::encode functions, and lodepng::State can be used for advanced -features. - -Like the decoder, the encoder can also give errors. However it gives less errors -since the encoder input is trusted, the decoder input (a PNG image that could -be forged by anyone) is not trusted. - -When using the LodePNGState, it uses the following fields for encoding: -*) LodePNGInfo info_png: here you specify how you want the PNG (the output) to be. -*) LodePNGColorMode info_raw: here you say what color type of the raw image (the input) has -*) LodePNGEncoderSettings encoder: you can specify a few settings for the encoder to use - -LodePNGInfo info_png --------------------- - -When encoding, you use this the opposite way as when decoding: for encoding, -you fill in the values you want the PNG to have before encoding. By default it's -not needed to specify a color type for the PNG since it's automatically chosen, -but it's possible to choose it yourself given the right settings. - -The encoder will not always exactly match the LodePNGInfo struct you give, -it tries as close as possible. Some things are ignored by the encoder. The -encoder uses, for example, the following settings from it when applicable: -colortype and bitdepth, text chunks, time chunk, the color key, the palette, the -background color, the interlace method, unknown chunks, ... - -When encoding to a PNG with colortype 3, the encoder will generate a PLTE chunk. -If the palette contains any colors for which the alpha channel is not 255 (so -there are translucent colors in the palette), it'll add a tRNS chunk. - -LodePNGColorMode info_raw -------------------------- - -You specify the color type of the raw image that you give to the input here, -including a possible transparent color key and palette you happen to be using in -your raw image data. - -By default, 32-bit color is assumed, meaning your input has to be in RGBA -format with 4 bytes (unsigned chars) per pixel. - -LodePNGEncoderSettings encoder ------------------------------- - -The following settings are supported (some are in sub-structs): -*) auto_convert: when this option is enabled, the encoder will -automatically choose the smallest possible color mode (including color key) that -can encode the colors of all pixels without information loss. -*) btype: the block type for LZ77. 0 = uncompressed, 1 = fixed huffman tree, - 2 = dynamic huffman tree (best compression). Should be 2 for proper - compression. -*) use_lz77: whether or not to use LZ77 for compressed block types. Should be - true for proper compression. -*) windowsize: the window size used by the LZ77 encoder (1 - 32768). Has value - 2048 by default, but can be set to 32768 for better, but slow, compression. -*) force_palette: if colortype is 2 or 6, you can make the encoder write a PLTE - chunk if force_palette is true. This can used as suggested palette to convert - to by viewers that don't support more than 256 colors (if those still exist) -*) add_id: add text chunk "Encoder: LodePNG " to the image. -*) text_compression: default 1. If 1, it'll store texts as zTXt instead of tEXt chunks. - zTXt chunks use zlib compression on the text. This gives a smaller result on - large texts but a larger result on small texts (such as a single program name). - It's all tEXt or all zTXt though, there's no separate setting per text yet. - - -6. color conversions --------------------- - -An important thing to note about LodePNG, is that the color type of the PNG, and -the color type of the raw image, are completely independent. By default, when -you decode a PNG, you get the result as a raw image in the color type you want, -no matter whether the PNG was encoded with a palette, greyscale or RGBA color. -And if you encode an image, by default LodePNG will automatically choose the PNG -color type that gives good compression based on the values of colors and amount -of colors in the image. It can be configured to let you control it instead as -well, though. - -To be able to do this, LodePNG does conversions from one color mode to another. -It can convert from almost any color type to any other color type, except the -following conversions: RGB to greyscale is not supported, and converting to a -palette when the palette doesn't have a required color is not supported. This is -not supported on purpose: this is information loss which requires a color -reduction algorithm that is beyong the scope of a PNG encoder (yes, RGB to grey -is easy, but there are multiple ways if you want to give some channels more -weight). - -By default, when decoding, you get the raw image in 32-bit RGBA or 24-bit RGB -color, no matter what color type the PNG has. And by default when encoding, -LodePNG automatically picks the best color model for the output PNG, and expects -the input image to be 32-bit RGBA or 24-bit RGB. So, unless you want to control -the color format of the images yourself, you can skip this chapter. - -6.1. PNG color types --------------------- - -A PNG image can have many color types, ranging from 1-bit color to 64-bit color, -as well as palettized color modes. After the zlib decompression and unfiltering -in the PNG image is done, the raw pixel data will have that color type and thus -a certain amount of bits per pixel. If you want the output raw image after -decoding to have another color type, a conversion is done by LodePNG. - -The PNG specification gives the following color types: - -0: greyscale, bit depths 1, 2, 4, 8, 16 -2: RGB, bit depths 8 and 16 -3: palette, bit depths 1, 2, 4 and 8 -4: greyscale with alpha, bit depths 8 and 16 -6: RGBA, bit depths 8 and 16 - -Bit depth is the amount of bits per pixel per color channel. So the total amount -of bits per pixel is: amount of channels * bitdepth. - -6.2. color conversions ----------------------- - -As explained in the sections about the encoder and decoder, you can specify -color types and bit depths in info_png and info_raw to change the default -behaviour. - -If, when decoding, you want the raw image to be something else than the default, -you need to set the color type and bit depth you want in the LodePNGColorMode, -or the parameters of the simple function of LodePNG you're using. - -If, when encoding, you use another color type than the default in the input -image, you need to specify its color type and bit depth in the LodePNGColorMode -of the raw image, or use the parameters of the simplefunction of LodePNG you're -using. - -If, when encoding, you don't want LodePNG to choose the output PNG color type -but control it yourself, you need to set auto_convert in the encoder settings -to LAC_NONE, and specify the color type you want in the LodePNGInfo of the -encoder. - -If you do any of the above, LodePNG may need to do a color conversion, which -follows the rules below, and may sometimes not be allowed. - -To avoid some confusion: --the decoder converts from PNG to raw image --the encoder converts from raw image to PNG --the colortype and bitdepth in LodePNGColorMode info_raw, are those of the raw image --the colortype and bitdepth in the color field of LodePNGInfo info_png, are those of the PNG --when encoding, the color type in LodePNGInfo is ignored if auto_convert - is enabled, it is automatically generated instead --when decoding, the color type in LodePNGInfo is set by the decoder to that of the original - PNG image, but it can be ignored since the raw image has the color type you requested instead --if the color type of the LodePNGColorMode and PNG image aren't the same, a conversion - between the color types is done if the color types are supported. If it is not - supported, an error is returned. If the types are the same, no conversion is done. --even though some conversions aren't supported, LodePNG supports loading PNGs from any - colortype and saving PNGs to any colortype, sometimes it just requires preparing - the raw image correctly before encoding. --both encoder and decoder use the same color converter. - -Non supported color conversions: --color to greyscale: no error is thrown, but the result will look ugly because -only the red channel is taken --anything, to palette when that palette does not have that color in it: in this -case an error is thrown - -Supported color conversions: --anything to 8-bit RGB, 8-bit RGBA, 16-bit RGB, 16-bit RGBA --any grey or grey+alpha, to grey or grey+alpha --anything to a palette, as long as the palette has the requested colors in it --removing alpha channel --higher to smaller bitdepth, and vice versa - -If you want no color conversion to be done: --In the encoder, you can make it save a PNG with any color type by giving the -raw color mode and LodePNGInfo the same color mode, and setting auto_convert to -LAC_NO. --In the decoder, you can make it store the pixel data in the same color type -as the PNG has, by setting the color_convert setting to false. Settings in -info_raw are then ignored. - -The function lodepng_convert does the color conversion. It is available in the -interface but normally isn't needed since the encoder and decoder already call -it. - -6.3. padding bits ------------------ - -In the PNG file format, if a less than 8-bit per pixel color type is used and the scanlines -have a bit amount that isn't a multiple of 8, then padding bits are used so that each -scanline starts at a fresh byte. But that is NOT true for the LodePNG raw input and output. -The raw input image you give to the encoder, and the raw output image you get from the decoder -will NOT have these padding bits, e.g. in the case of a 1-bit image with a width -of 7 pixels, the first pixel of the second scanline will the the 8th bit of the first byte, -not the first bit of a new byte. - -6.4. A note about 16-bits per channel and endianness ----------------------------------------------------- - -LodePNG uses unsigned char arrays for 16-bit per channel colors too, just like -for any other color format. The 16-bit values are stored in big endian (most -significant byte first) in these arrays. This is the opposite order of the -little endian used by x86 CPU's. - -LodePNG always uses big endian because the PNG file format does so internally. -Conversions to other formats than PNG uses internally are not supported by -LodePNG on purpose, there are myriads of formats, including endianness of 16-bit -colors, the order in which you store R, G, B and A, and so on. Supporting and -converting to/from all that is outside the scope of LodePNG. - -This may mean that, depending on your use case, you may want to convert the big -endian output of LodePNG to little endian with a for loop. This is certainly not -always needed, many applications and libraries support big endian 16-bit colors -anyway, but it means you cannot simply cast the unsigned char* buffer to an -unsigned short* buffer on x86 CPUs. - - -7. error values ---------------- - -All functions in LodePNG that return an error code, return 0 if everything went -OK, or a non-zero code if there was an error. - -The meaning of the LodePNG error values can be retrieved with the function -lodepng_error_text: given the numerical error code, it returns a description -of the error in English as a string. - -Check the implementation of lodepng_error_text to see the meaning of each code. - - -8. chunks and PNG editing -------------------------- - -If you want to add extra chunks to a PNG you encode, or use LodePNG for a PNG -editor that should follow the rules about handling of unknown chunks, or if your -program is able to read other types of chunks than the ones handled by LodePNG, -then that's possible with the chunk functions of LodePNG. - -A PNG chunk has the following layout: - -4 bytes length -4 bytes type name -length bytes data -4 bytes CRC - -8.1. iterating through chunks ------------------------------ - -If you have a buffer containing the PNG image data, then the first chunk (the -IHDR chunk) starts at byte number 8 of that buffer. The first 8 bytes are the -signature of the PNG and are not part of a chunk. But if you start at byte 8 -then you have a chunk, and can check the following things of it. - -NOTE: none of these functions check for memory buffer boundaries. To avoid -exploits, always make sure the buffer contains all the data of the chunks. -When using lodepng_chunk_next, make sure the returned value is within the -allocated memory. - -unsigned lodepng_chunk_length(const unsigned char* chunk): - -Get the length of the chunk's data. The total chunk length is this length + 12. - -void lodepng_chunk_type(char type[5], const unsigned char* chunk): -unsigned char lodepng_chunk_type_equals(const unsigned char* chunk, const char* type): - -Get the type of the chunk or compare if it's a certain type - -unsigned char lodepng_chunk_critical(const unsigned char* chunk): -unsigned char lodepng_chunk_private(const unsigned char* chunk): -unsigned char lodepng_chunk_safetocopy(const unsigned char* chunk): - -Check if the chunk is critical in the PNG standard (only IHDR, PLTE, IDAT and IEND are). -Check if the chunk is private (public chunks are part of the standard, private ones not). -Check if the chunk is safe to copy. If it's not, then, when modifying data in a critical -chunk, unsafe to copy chunks of the old image may NOT be saved in the new one if your -program doesn't handle that type of unknown chunk. - -unsigned char* lodepng_chunk_data(unsigned char* chunk): -const unsigned char* lodepng_chunk_data_const(const unsigned char* chunk): - -Get a pointer to the start of the data of the chunk. - -unsigned lodepng_chunk_check_crc(const unsigned char* chunk): -void lodepng_chunk_generate_crc(unsigned char* chunk): - -Check if the crc is correct or generate a correct one. - -unsigned char* lodepng_chunk_next(unsigned char* chunk): -const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk): - -Iterate to the next chunk. This works if you have a buffer with consecutive chunks. Note that these -functions do no boundary checking of the allocated data whatsoever, so make sure there is enough -data available in the buffer to be able to go to the next chunk. - -unsigned lodepng_chunk_append(unsigned char** out, size_t* outlength, const unsigned char* chunk): -unsigned lodepng_chunk_create(unsigned char** out, size_t* outlength, unsigned length, - const char* type, const unsigned char* data): - -These functions are used to create new chunks that are appended to the data in *out that has -length *outlength. The append function appends an existing chunk to the new data. The create -function creates a new chunk with the given parameters and appends it. Type is the 4-letter -name of the chunk. - -8.2. chunks in info_png ------------------------ - -The LodePNGInfo struct contains fields with the unknown chunk in it. It has 3 -buffers (each with size) to contain 3 types of unknown chunks: -the ones that come before the PLTE chunk, the ones that come between the PLTE -and the IDAT chunks, and the ones that come after the IDAT chunks. -It's necessary to make the distionction between these 3 cases because the PNG -standard forces to keep the ordering of unknown chunks compared to the critical -chunks, but does not force any other ordering rules. - -info_png.unknown_chunks_data[0] is the chunks before PLTE -info_png.unknown_chunks_data[1] is the chunks after PLTE, before IDAT -info_png.unknown_chunks_data[2] is the chunks after IDAT - -The chunks in these 3 buffers can be iterated through and read by using the same -way described in the previous subchapter. - -When using the decoder to decode a PNG, you can make it store all unknown chunks -if you set the option settings.remember_unknown_chunks to 1. By default, this -option is off (0). - -The encoder will always encode unknown chunks that are stored in the info_png. -If you need it to add a particular chunk that isn't known by LodePNG, you can -use lodepng_chunk_append or lodepng_chunk_create to the chunk data in -info_png.unknown_chunks_data[x]. - -Chunks that are known by LodePNG should not be added in that way. E.g. to make -LodePNG add a bKGD chunk, set background_defined to true and add the correct -parameters there instead. - - -9. compiler support -------------------- - -No libraries other than the current standard C library are needed to compile -LodePNG. For the C++ version, only the standard C++ library is needed on top. -Add the files lodepng.c(pp) and lodepng.h to your project, include -lodepng.h where needed, and your program can read/write PNG files. - -It is compatible with C90 and up, and C++03 and up. - -If performance is important, use optimization when compiling! For both the -encoder and decoder, this makes a large difference. - -Make sure that LodePNG is compiled with the same compiler of the same version -and with the same settings as the rest of the program, or the interfaces with -std::vectors and std::strings in C++ can be incompatible. - -CHAR_BITS must be 8 or higher, because LodePNG uses unsigned chars for octets. - -*) gcc and g++ - -LodePNG is developed in gcc so this compiler is natively supported. It gives no -warnings with compiler options "-Wall -Wextra -pedantic -ansi", with gcc and g++ -version 4.7.1 on Linux, 32-bit and 64-bit. - -*) Clang - -Fully supported and warning-free. - -*) Mingw - -The Mingw compiler (a port of gcc for Windows) should be fully supported by -LodePNG. - -*) Visual Studio and Visual C++ Express Edition - -LodePNG should be warning-free with warning level W4. Two warnings were disabled -with pragmas though: warning 4244 about implicit conversions, and warning 4996 -where it wants to use a non-standard function fopen_s instead of the standard C -fopen. - -Visual Studio may want "stdafx.h" files to be included in each source file and -give an error "unexpected end of file while looking for precompiled header". -This is not standard C++ and will not be added to the stock LodePNG. You can -disable it for lodepng.cpp only by right clicking it, Properties, C/C++, -Precompiled Headers, and set it to Not Using Precompiled Headers there. - -NOTE: Modern versions of VS should be fully supported, but old versions, e.g. -VS6, are not guaranteed to work. - -*) Compilers on Macintosh - -LodePNG has been reported to work both with gcc and LLVM for Macintosh, both for -C and C++. - -*) Other Compilers - -If you encounter problems on any compilers, feel free to let me know and I may -try to fix it if the compiler is modern and standards complient. - - -10. examples ------------- - -This decoder example shows the most basic usage of LodePNG. More complex -examples can be found on the LodePNG website. - -10.1. decoder C++ example -------------------------- - -#include "lodepng.h" -#include - -int main(int argc, char *argv[]) -{ - const char* filename = argc > 1 ? argv[1] : "test.png"; - - //load and decode - std::vector image; - unsigned width, height; - unsigned error = lodepng::decode(image, width, height, filename); - - //if there's an error, display it - if(error) std::cout << "decoder error " << error << ": " << lodepng_error_text(error) << std::endl; - - //the pixels are now in the vector "image", 4 bytes per pixel, ordered RGBARGBA..., use it as texture, draw it, ... -} - -10.2. decoder C example ------------------------ - -#include "lodepng.h" - -int main(int argc, char *argv[]) -{ - unsigned error; - unsigned char* image; - size_t width, height; - const char* filename = argc > 1 ? argv[1] : "test.png"; - - error = lodepng_decode32_file(&image, &width, &height, filename); - - if(error) printf("decoder error %u: %s\n", error, lodepng_error_text(error)); - - / * use image here * / - - free(image); - return 0; -} - - -11. changes ------------ - -The version number of LodePNG is the date of the change given in the format -yyyymmdd. - -Some changes aren't backwards compatible. Those are indicated with a (!) -symbol. - -*) 09 jun 2014: Faster encoder by fixing hash bug and more zeros optimization. -*) 22 dec 2013: Power of two windowsize required for optimization. -*) 15 apr 2013: Fixed bug with LAC_ALPHA and color key. -*) 25 mar 2013: Added an optional feature to ignore some PNG errors (fix_png). -*) 11 mar 2013 (!): Bugfix with custom free. Changed from "my" to "lodepng_" - prefix for the custom allocators and made it possible with a new #define to - use custom ones in your project without needing to change lodepng's code. -*) 28 jan 2013: Bugfix with color key. -*) 27 okt 2012: Tweaks in text chunk keyword length error handling. -*) 8 okt 2012 (!): Added new filter strategy (entropy) and new auto color mode. - (no palette). Better deflate tree encoding. New compression tweak settings. - Faster color conversions while decoding. Some internal cleanups. -*) 23 sep 2012: Reduced warnings in Visual Studio a little bit. -*) 1 sep 2012 (!): Removed #define's for giving custom (de)compression functions - and made it work with function pointers instead. -*) 23 jun 2012: Added more filter strategies. Made it easier to use custom alloc - and free functions and toggle #defines from compiler flags. Small fixes. -*) 6 may 2012 (!): Made plugging in custom zlib/deflate functions more flexible. -*) 22 apr 2012 (!): Made interface more consistent, renaming a lot. Removed - redundant C++ codec classes. Reduced amount of structs. Everything changed, - but it is cleaner now imho and functionality remains the same. Also fixed - several bugs and shrinked the implementation code. Made new samples. -*) 6 nov 2011 (!): By default, the encoder now automatically chooses the best - PNG color model and bit depth, based on the amount and type of colors of the - raw image. For this, autoLeaveOutAlphaChannel replaced by auto_choose_color. -*) 9 okt 2011: simpler hash chain implementation for the encoder. -*) 8 sep 2011: lz77 encoder lazy matching instead of greedy matching. -*) 23 aug 2011: tweaked the zlib compression parameters after benchmarking. - A bug with the PNG filtertype heuristic was fixed, so that it chooses much - better ones (it's quite significant). A setting to do an experimental, slow, - brute force search for PNG filter types is added. -*) 17 aug 2011 (!): changed some C zlib related function names. -*) 16 aug 2011: made the code less wide (max 120 characters per line). -*) 17 apr 2011: code cleanup. Bugfixes. Convert low to 16-bit per sample colors. -*) 21 feb 2011: fixed compiling for C90. Fixed compiling with sections disabled. -*) 11 dec 2010: encoding is made faster, based on suggestion by Peter Eastman - to optimize long sequences of zeros. -*) 13 nov 2010: added LodePNG_InfoColor_hasPaletteAlpha and - LodePNG_InfoColor_canHaveAlpha functions for convenience. -*) 7 nov 2010: added LodePNG_error_text function to get error code description. -*) 30 okt 2010: made decoding slightly faster -*) 26 okt 2010: (!) changed some C function and struct names (more consistent). - Reorganized the documentation and the declaration order in the header. -*) 08 aug 2010: only changed some comments and external samples. -*) 05 jul 2010: fixed bug thanks to warnings in the new gcc version. -*) 14 mar 2010: fixed bug where too much memory was allocated for char buffers. -*) 02 sep 2008: fixed bug where it could create empty tree that linux apps could - read by ignoring the problem but windows apps couldn't. -*) 06 jun 2008: added more error checks for out of memory cases. -*) 26 apr 2008: added a few more checks here and there to ensure more safety. -*) 06 mar 2008: crash with encoding of strings fixed -*) 02 feb 2008: support for international text chunks added (iTXt) -*) 23 jan 2008: small cleanups, and #defines to divide code in sections -*) 20 jan 2008: support for unknown chunks allowing using LodePNG for an editor. -*) 18 jan 2008: support for tIME and pHYs chunks added to encoder and decoder. -*) 17 jan 2008: ability to encode and decode compressed zTXt chunks added - Also vareous fixes, such as in the deflate and the padding bits code. -*) 13 jan 2008: Added ability to encode Adam7-interlaced images. Improved - filtering code of encoder. -*) 07 jan 2008: (!) changed LodePNG to use ISO C90 instead of C++. A - C++ wrapper around this provides an interface almost identical to before. - Having LodePNG be pure ISO C90 makes it more portable. The C and C++ code - are together in these files but it works both for C and C++ compilers. -*) 29 dec 2007: (!) changed most integer types to unsigned int + other tweaks -*) 30 aug 2007: bug fixed which makes this Borland C++ compatible -*) 09 aug 2007: some VS2005 warnings removed again -*) 21 jul 2007: deflate code placed in new namespace separate from zlib code -*) 08 jun 2007: fixed bug with 2- and 4-bit color, and small interlaced images -*) 04 jun 2007: improved support for Visual Studio 2005: crash with accessing - invalid std::vector element [0] fixed, and level 3 and 4 warnings removed -*) 02 jun 2007: made the encoder add a tag with version by default -*) 27 may 2007: zlib and png code separated (but still in the same file), - simple encoder/decoder functions added for more simple usage cases -*) 19 may 2007: minor fixes, some code cleaning, new error added (error 69), - moved some examples from here to lodepng_examples.cpp -*) 12 may 2007: palette decoding bug fixed -*) 24 apr 2007: changed the license from BSD to the zlib license -*) 11 mar 2007: very simple addition: ability to encode bKGD chunks. -*) 04 mar 2007: (!) tEXt chunk related fixes, and support for encoding - palettized PNG images. Plus little interface change with palette and texts. -*) 03 mar 2007: Made it encode dynamic Huffman shorter with repeat codes. - Fixed a bug where the end code of a block had length 0 in the Huffman tree. -*) 26 feb 2007: Huffman compression with dynamic trees (BTYPE 2) now implemented - and supported by the encoder, resulting in smaller PNGs at the output. -*) 27 jan 2007: Made the Adler-32 test faster so that a timewaste is gone. -*) 24 jan 2007: gave encoder an error interface. Added color conversion from any - greyscale type to 8-bit greyscale with or without alpha. -*) 21 jan 2007: (!) Totally changed the interface. It allows more color types - to convert to and is more uniform. See the manual for how it works now. -*) 07 jan 2007: Some cleanup & fixes, and a few changes over the last days: - encode/decode custom tEXt chunks, separate classes for zlib & deflate, and - at last made the decoder give errors for incorrect Adler32 or Crc. -*) 01 jan 2007: Fixed bug with encoding PNGs with less than 8 bits per channel. -*) 29 dec 2006: Added support for encoding images without alpha channel, and - cleaned out code as well as making certain parts faster. -*) 28 dec 2006: Added "Settings" to the encoder. -*) 26 dec 2006: The encoder now does LZ77 encoding and produces much smaller files now. - Removed some code duplication in the decoder. Fixed little bug in an example. -*) 09 dec 2006: (!) Placed output parameters of public functions as first parameter. - Fixed a bug of the decoder with 16-bit per color. -*) 15 okt 2006: Changed documentation structure -*) 09 okt 2006: Encoder class added. It encodes a valid PNG image from the - given image buffer, however for now it's not compressed. -*) 08 sep 2006: (!) Changed to interface with a Decoder class -*) 30 jul 2006: (!) LodePNG_InfoPng , width and height are now retrieved in different - way. Renamed decodePNG to decodePNGGeneric. -*) 29 jul 2006: (!) Changed the interface: image info is now returned as a - struct of type LodePNG::LodePNG_Info, instead of a vector, which was a bit clumsy. -*) 28 jul 2006: Cleaned the code and added new error checks. - Corrected terminology "deflate" into "inflate". -*) 23 jun 2006: Added SDL example in the documentation in the header, this - example allows easy debugging by displaying the PNG and its transparency. -*) 22 jun 2006: (!) Changed way to obtain error value. Added - loadFile function for convenience. Made decodePNG32 faster. -*) 21 jun 2006: (!) Changed type of info vector to unsigned. - Changed position of palette in info vector. Fixed an important bug that - happened on PNGs with an uncompressed block. -*) 16 jun 2006: Internally changed unsigned into unsigned where - needed, and performed some optimizations. -*) 07 jun 2006: (!) Renamed functions to decodePNG and placed them - in LodePNG namespace. Changed the order of the parameters. Rewrote the - documentation in the header. Renamed files to lodepng.cpp and lodepng.h -*) 22 apr 2006: Optimized and improved some code -*) 07 sep 2005: (!) Changed to std::vector interface -*) 12 aug 2005: Initial release (C++, decoder only) - - -12. contact information ------------------------ - -Feel free to contact me with suggestions, problems, comments, ... concerning -LodePNG. If you encounter a PNG image that doesn't work properly with this -decoder, feel free to send it and I'll use it to find and fix the problem. - -My email address is (puzzle the account and domain together with an @ symbol): -Domain: gmail dot com. -Account: lode dot vandevenne. - - -Copyright (c) 2005-2014 Lode Vandevenne -*/ diff --git a/GameMap.c b/GameMap.c index 2d6b31b..e186ee8 100644 --- a/GameMap.c +++ b/GameMap.c @@ -1,216 +1,173 @@ -// Copyright (C) 2011 Valeriano Alfonso Rodriguez (Kableado) +// Copyright (C) 2012 Valeriano Alfonso Rodriguez (Kableado) #include -#include +#include +#include #include "GameLib.h" -#include "GameEnts.h" +#include "GameEnts.h" #include "GameMap.h" -Entity GameMapAux_CreateEnt(Entity ent,int i,int j){ - Entity e; - e=Entity_Copy(ent); - vec2_set(e->pos,16+i*32,16+j*32); - Entity_CalcBBox(e); - GameLib_AddEntity(e); - return(e); -} -void Aux_Linea(FILE *f,char *line){ +int ReadLine(FILE *f,char *line,int max){ int c; int i=0; - memset(line,0,1024); - while(i<1024){ + while(i<(max-1)){ c=fgetc(f); if(c==EOF){ line[i]=0; - break; + return(-1); } if(c=='\r'){ continue; } if(c=='\n'){ line[i]=0; - break; + return(i); } line[i]=c; i++; } + line[i]=0; + return(i); } -int _startpoint; -int GameMapAux_CreatePlayer(Entity ent){ - if(ent->type==Ent_SavePoint){ - if(ent->A==_startpoint){ - Entity e; - e=Entity_Copy(ent_player); - vec2_copy(e->pos,ent->pos); - GameLib_AddEntity(e); - return(0); - } - } - return(1); + +Entity *GameMapAux_CreateEnt(Entity *ent,int i,int j,int res){ + Entity *e; + vec2 pos; + e=Entity_Copy(ent); + vec2_set(pos,(res/2)+i*res,(res/2)+j*res); + vec2_plus(e->pos,e->pos,pos); + GameLib_AddEntity(e); + return(e); } -int GameMapAux_IsFloor(char c){ - if( c=='.' || - c=='#' || - c=='m' || - c=='B' || - c=='S' || - c=='E' || - c=='F' || - c=='A' || - c=='V' || - c=='<' || - c=='>' || - c=='r' || - c=='T' || - c=='D' || - c=='l' ) - { - return(1); - } - return(0); -} -int GameMap_CreateLevel(int level,int point){ - char filename[128]; +#define MaxLineLen 1024 + +int GameMap_LoadLevel(char *filename,int res){ FILE *file; - char line[1024]; - int w,h; - int i,j,i2; - int floor; + char line[MaxLineLen]; + int len,i,j; + int width,height; + char *map; - sprintf(filename,"data/level_%02d.txt",level); - file=fopen(filename,"r"); + + // Open the file + file=fopen(filename,"rb"); if(!file){ return(0); } - GameLib_DelEnts(); + // Read the file to determine sizes + width=0; + height=0; + do{ + len=ReadLine(file,line,MaxLineLen); + if(len>-1){ + if(len>height){ + height=len; + } + width++; + } + }while(len>-1); + fseek(file,0,SEEK_SET); - Aux_Linea(file,line); - sscanf(line,"%d %d",&w,&h); - for(j=0;j0){ - if(GameMapAux_IsFloor(line[i2-2])){ - floor|=4; - } + + // Build the map + map=malloc(sizeof(char)*width*height); + memset(map,0,width*height); + #define MAP(x,y) map[(x)+((y)*width)] + j=0; + do{ + len=ReadLine(file,line,MaxLineLen); + for(i=0;i-1); + + + // Close the file + fclose(file); + + + // Parse the map + for(j=0;j=height)y=height-1; + down=MAP(x,y)=='#'?0:1; + x=i-1;y=j;if(x<0)x=0; + left=MAP(x,y)=='#'?0:1; + x=i+1;y=j;if(x>=width)x=width-1; + right=MAP(x,y)=='#'?0:1; + + EntEarth_Init(ent,up,down,left,right); } - if(GameMapAux_IsFloor(line[i2])){ - floor|=2; - } - if(floor==7){ - GameMapAux_CreateEnt(ent_floor,i,j); - } - if(floor==6){ - GameMapAux_CreateEnt(ent_floor_right,i,j); - } - if(floor==3){ - GameMapAux_CreateEnt(ent_floor_left,i,j); - } - if(floor==2){ - GameMapAux_CreateEnt(ent_floor_center,i,j); + if(MAP(i,j)=='R'){ + // StoneBrick + int x,y; + int up,down,left,right; + + ent=GameMapAux_CreateEnt(ent_StoneBrick,i,j,res); + + x=i;y=j-1;if(y<0)y=0; + up=MAP(x,y)=='R'?0:1; + x=i;y=j+1;if(y>=height)y=height-1; + down=MAP(x,y)=='R'?0:1; + x=i-1;y=j;if(x<0)x=0; + left=MAP(x,y)=='R'?0:1; + x=i+1;y=j;if(x>=width)x=width-1; + right=MAP(x,y)=='R'?0:1; + + EntStoneBrick_Init(ent,up,down,left,right); } - // Put the rest of the entities - if(line[i2]=='.'){ - // Floor - }else - if(line[i2]=='#'){ - // Column - GameMapAux_CreateEnt(ent_column,i,j); - }else - if(line[i2]=='m'){ - // Column faded - GameMapAux_CreateEnt(ent_column_faded,i,j); - }else - if(line[i2]=='r'){ - // Rock - GameMapAux_CreateEnt(ent_rock,i,j); - }else - if(line[i2]=='l'){ - // Lamp - GameMapAux_CreateEnt(ent_lamp,i,j); - }else - if(line[i2]=='B'){ - // Barrel - GameMapAux_CreateEnt(ent_barrel,i,j); - }else - if(line[i2]=='|'){ - // Spiked hole - GameMapAux_CreateEnt(ent_hole_spiked,i,j); - }else - if(line[i2]=='L'){ - // Lava hole - GameMapAux_CreateEnt(ent_hole_lava,i,j); - }else - if(line[i2]=='S'){ - Entity e; - // Save point - e=GameMapAux_CreateEnt(ent_savepoint,i,j); - e->A=line[i2+1]-'0'; - }else - if(line[i2]=='E'){ - // Exit point - GameMapAux_CreateEnt(ent_exitpoint,i,j); - }else - if(line[i2]=='F'){ - // End point - GameMapAux_CreateEnt(ent_endpoint,i,j); - }else - if(line[i2]=='>'){ - // ArrowShooter right - GameMapAux_CreateEnt(ent_arrowshooter_right,i,j); - }else - if(line[i2]=='<'){ - // ArrowShooter left - GameMapAux_CreateEnt(ent_arrowshooter_left,i,j); - }else - if(line[i2]=='V'){ - // ArrowShooter down - GameMapAux_CreateEnt(ent_arrowshooter_down,i,j); - }else - if(line[i2]=='A'){ - // ArrowShooter up - GameMapAux_CreateEnt(ent_arrowshooter_up,i,j); - }else - /*if(line[i2]=='T'){ - // Teleporter - Entity ent=GameMapAux_CreateEnt(ent_teleporter,i,j); - ent->A=line[i2+1]-'0'; - }else - if(line[i2]=='D'){ - // Teleporter Destination - Entity ent=GameMapAux_CreateEnt(ent_teleporter_dest,i,j); - ent->A=line[i2+1]-'0'; - }else -*/ - {} + if(MAP(i,j)=='S'){ + // Spiked Bush + ent=GameMapAux_CreateEnt(ent_SpikedBush,i,j,res); + } + + if(MAP(i,j)=='F'){ + // Flower + ent=GameMapAux_CreateEnt(ent_Flower[0],i,j,res); + } + if(MAP(i,j)=='f'){ + // Flower + ent=GameMapAux_CreateEnt(ent_Flower[1],i,j,res); + } + + if(MAP(i,j)=='B'){ + // Bunny + ent=GameMapAux_CreateEnt(ent_Bunny,i,j,res); + } } } - fclose(file); - // Find the player start position - _startpoint=point; - GameLib_ForEachEnt(GameMapAux_CreatePlayer); - - // Iluminate - //GameLib_Iluminate(); + // Cleanup + free(map); + #undef MAP return(1); } \ No newline at end of file diff --git a/GameMap.h b/GameMap.h index 117b9ff..1c40801 100644 --- a/GameMap.h +++ b/GameMap.h @@ -1,10 +1,8 @@ -// Copyright (C) 2011 Valeriano Alfonso Rodriguez (Kableado) - +// Copyright (C) 2012 Valeriano Alfonso Rodriguez (Kableado) #ifndef _GAMEMAP_H_ #define _GAMEMAP_H_ -int GameMap_CreateLevel(int level,int point); +int GameMap_LoadLevel(char *filename,int res); -#endif - +#endif _GAMEMAP_H_ diff --git a/Makefile.common b/Makefile.common index bc8814b..83fd151 100644 --- a/Makefile.common +++ b/Makefile.common @@ -7,7 +7,6 @@ CFLAGS += -IGameLib HEADS= \ GameLib/Time.h \ GameLib/Util.h \ - GameLib/QuadArray2D.h \ GameLib/Draw.h \ GameLib/Input.h \ GameLib/Audio.h \ @@ -17,7 +16,6 @@ HEADS= \ OBJS= \ $(BUILDDIR)/GameLib/Time.o \ $(BUILDDIR)/GameLib/Util.o \ - $(BUILDDIR)/GameLib/QuadArray2D.o \ $(BUILDDIR)/GameLib/Draw.o \ $(BUILDDIR)/GameLib/Input.o \ $(BUILDDIR)/GameLib/Audio.o \ @@ -26,6 +24,7 @@ OBJS= \ $(BUILDDIR)/GameLib/GameLib.o \ + ##################### # Game Declarations # ##################### @@ -37,6 +36,11 @@ OBJS+= \ $(BUILDDIR)/main.o + + + + + ################# # General Rules # ################# @@ -49,10 +53,12 @@ $(BUILDDIR): clean: rm -f $(OBJS) $(BUILDDIR)/$(RESULT) -run: $(BUILDDIR) $(BUILDDIR)/$(RESULT) - $(LAUNCHER) ./$(BUILDDIR)/$(RESULT) debug +run: $(BUILDDIR)/$(RESULT) + ./$(BUILDDIR)/$(RESULT) debug + + + -rebuild: clean all ################# # GameLib Rules # @@ -61,8 +67,6 @@ $(BUILDDIR)/GameLib/Time.o: GameLib/Time.c $(HEADS) $(CC) -c GameLib/Time.c -o $(BUILDDIR)/GameLib/Time.o $(CFLAGS) $(BUILDDIR)/GameLib/Util.o: GameLib/Util.c $(HEADS) $(CC) -c GameLib/Util.c -o $(BUILDDIR)/GameLib/Util.o $(CFLAGS) -$(BUILDDIR)/GameLib/QuadArray2D.o: GameLib/QuadArray2D.c $(HEADS) - $(CC) -c GameLib/QuadArray2D.c -o $(BUILDDIR)/GameLib/QuadArray2D.o $(CFLAGS) $(BUILDDIR)/GameLib/Draw.o: GameLib/Draw.c $(HEADS) $(CC) -c GameLib/Draw.c -o $(BUILDDIR)/GameLib/Draw.o $(CFLAGS) $(BUILDDIR)/GameLib/Input.o: GameLib/Input.c $(HEADS) @@ -77,6 +81,7 @@ $(BUILDDIR)/GameLib/GameLib.o: GameLib/GameLib.c $(HEADS) $(CC) -c GameLib/GameLib.c -o $(BUILDDIR)/GameLib/GameLib.o $(CFLAGS) + ############## # Game Rules # ############## @@ -90,13 +95,8 @@ $(BUILDDIR)/GameMap.o: GameMap.c $(HEADS) $(BUILDDIR)/main.o: main.c $(HEADS) $(CC) -c main.c -o $(BUILDDIR)/main.o $(CFLAGS) - -################ -# Result Rules # -################ - $(BUILDDIR)/$(RESULT): $(OBJS) - $(CC) -o $(BUILDDIR)/$(RESULT) $(OBJS) $(LIBS) $(CFLAGS) $(LDFLAGS) + $(CC) -o $(BUILDDIR)/$(RESULT) $(OBJS) $(LIBS) $(CFLAGS) diff --git a/Makefile.emscripten b/Makefile.emscripten deleted file mode 100644 index 779f15f..0000000 --- a/Makefile.emscripten +++ /dev/null @@ -1,21 +0,0 @@ -CC= emcc -LAUNCHER= start -RM=rm -rf - -LIBS= -CFLAGS= -s FULL_ES2=1 -s ASM_JS=1 -O1 -Wno-implicit-function-declaration -#LDFLAGS= --embed-file data -LDFLAGS= --preload-file data - - -RESULT=game.html -BUILDDIR=build-emscripten - -ifeq ($(target),release) - CFLAGS= -s FULL_ES2=1 -s ASM_JS=1 -O2 --llvm-lto 1 -Wno-implicit-function-declaration - BUILDDIR=build-emscripten-release -endif - -include Makefile.common - - diff --git a/Makefile.linux b/Makefile.linux index bee462e..3771781 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -1,10 +1,7 @@ -CC=gcc -LAUNCHER= -RM=rm -rf - LIBS= -lSDL -lpthread -L/usr/X11R6/lib -L/usr/lib -lm -lGL -lX11 CFLAGS= -Wall -g -I/usr/include/ -I/usr/include/SDL/ -I/usr/X11R6/include/ -LDFLAGS= +CC=gcc +RM=rm -rf RESULT=game BUILDDIR=build-linux diff --git a/Makefile.macosx b/Makefile.macosx new file mode 100644 index 0000000..5acd8c8 --- /dev/null +++ b/Makefile.macosx @@ -0,0 +1,9 @@ +LIBS=-lm -ldl -framework Cocoa -framework SDL -framework OpenGL macosx/SDLMain.m +CFLAGS=-g -DDEBUG -Wall -DMACOSX -ObjC -Dmain=SDL_main +CC=gcc +RM=rm -rf + +RESULT=game +BUILDDIR=build-macosx + +include Makefile.common \ No newline at end of file diff --git a/Makefile.mingw b/Makefile.mingw index 58e8e56..ff4151e 100644 --- a/Makefile.mingw +++ b/Makefile.mingw @@ -1,10 +1,7 @@ -CC= i486-mingw32-gcc -LAUNCHER= -RM=rm -rf - LIBS= -L/usr/i486-mingw/lib -D_GNU_SOURCE=1 -Dmain=SDL_main -lopengl32 CFLAGS= -I/usr/i486-mingw/include -lmingw32 -lSDLmain -lSDL -mwindows -LDFLAGS= +CC= i486-mingw32-gcc +RM=rm -rf RESULT=game.exe BUILDDIR=build-mingw diff --git a/Makefile.win32 b/Makefile.win32 index 1ae5bf6..91f85a9 100644 --- a/Makefile.win32 +++ b/Makefile.win32 @@ -1,10 +1,7 @@ -CC=gcc -LAUNCHER= -RM=rm -rf - LIBS=-I/mingw/include/SDL -D_GNU_SOURCE=1 -Dmain=SDL_main -lopengl32 CFLAGS= -L/mingw/lib -lmingw32 -lSDLmain -lSDL -mwindows -g -LDFLAGS= +CC=gcc +RM=rm -rf RESULT=game.exe BUILDDIR=build-mingw diff --git a/NOTES.txt b/NOTES.txt deleted file mode 100644 index 0efb8fb..0000000 --- a/NOTES.txt +++ /dev/null @@ -1,61 +0,0 @@ -TODO ----- -- Entities: - - Teleporters - - Doors and Buttons - - Buttons -- Music -- Non-SFXR sounds - - - - - -DONE ----- -- Util - - Circle collision -- Draw - - Screen init - - Image loading - - Image drawing - - Font loading - - Text Drawing - - Draw loop -- Input - - Keyboard - - Mouse -- Audio - - Sound loading - - Sound playing -- Anim - - Animation loading - - Animation playing -- Entity - - Process - - Overlap - - Collision -- GameLib - - Game loop - - Entity processing - - Sound playing spatially - - Lighting -- Game Map - - Loading -- Game Entities: - - Player - - Barrel - - Spikes - - Lava - - ArrowShooters - - Arrows - - Columns - - Rock - - Floor - - Save points - - Light points -- Title Screen -- Game End Screen -- Game saving and loading - - Level and savepoint - diff --git a/SDL.dll b/SDL.dll deleted file mode 100644 index a5da7bb..0000000 Binary files a/SDL.dll and /dev/null differ diff --git a/conv.c b/conv.c deleted file mode 100644 index c232922..0000000 --- a/conv.c +++ /dev/null @@ -1,88 +0,0 @@ - -#include -#include - - -int Aux_Linea(FILE *f,char *line){ - int c; - int i=0; - memset(line,0,1024); - while(i<1024){ - c=fgetc(f); - if(c==EOF){ - line[i]=0; - return(0); - } - if(c=='\r'){ - continue; - } - if(c=='\n'){ - line[i]=0; - break; - } - line[i]=c; - i++; - } - return(1); -} - -int convert(char *file){ - FILE *f,*f2; - char file2[1024]; - char line[1024]; - int w,h; - int i,n; - int loop; - - f=fopen(file,"rb"); - if(!f){ - return(0); - } - sprintf(file2,"%s.txt",file); - f2=fopen(file2,"wb"); - if(!f2){ - fclose(f); - return(0); - } - - Aux_Linea(f,line); - sscanf(line,"%d %d",&w,&h); - fprintf(f2,"%d %d\n",w,h); - - loop=0; - do{ - loop=Aux_Linea(f,line); - n=strlen(line); - for(i=0;i>....................## - ##..................AA......mm mm........AA............## - ##mmmmmmmmmmllmmmmmmmmmmmmmmmm mmmmmmmmmmmmll..llmmmmmm## - mm..mm - mm..mm - mm..mm - mm..mm - ##########S3########## - mm..................mm - mm............BBBB..mm - mm................<>................mm - mm............BBBB..mm - mm................<>................mm - mm..................mm - mm........EE........mm - mmmmmmmmmmmmmmmmmmmmmm diff --git a/data/level_05.txt b/data/level_05.txt deleted file mode 100644 index 7340676..0000000 --- a/data/level_05.txt +++ /dev/null @@ -1,69 +0,0 @@ -100 100 - - ################## - ##......S1......## - ##..............## - ##..............## - ##..............## - ##mmmmll..llmmmm## - mm..mm - mm..mm - mm..mm - mm..mm - mm..mm - mm..mm -####ll######S2######ll#### -##......................## -##..BB..BB......BB..BB..## -##......................## -##LLLLLLLLrr||rrLLLLLLLL## -##......AA......AA......## -##mmmmmmmmll..llmmmmmmmm## - mm..mm - mm..mm - mm..mm - mm..mm -############S3############ -##....VV..VV..........LL## -##LLLLLLLLLLLLLLLLLL..LL## -##LL..................LL## -##LL..LLLLLLLLLLLLLLLLLL## -##LL..................LL## -##LLLLLLLLLLLLLLLLLL..LL## -##LL..................LL## -##LL..LLLLLLLLLLLLLLLLLL## -##LL..........AA..AA....## -##mmmmmmmmll..llmmmmmmmm## - mm..mm - mm..mm - mm..mm - mm..mm - mm..mm -######VV##VVS4############ -##LLLLLLLLLL..LLLLLLLLLL## -##LLLLLLLLLL..........LL## ->>LLLLLLLLLLLLLLLLLL..LL## -mmLL..................LL## -mmLL..LLLLLLLLLLLLLLLLLL<< -mmLL..................LLmm ->>LLLLLLLLLLLLLLLLLL..LLmm -mmLL..................LLmm -mmLL..LLLLLLLLLLLLLLLLLL<< -mmLL..........LLLLLLLLLLmm -mmLLLLLLLLLL..LLLLLLLLLLmm -mmmmmmmmmmmm..AAmmAAmmmmmm - ll..ll - mm..mm - mm..mm - mm..mm - mm..mm - ########..######## - ##..............## - ##..............## - ##..............## - ##......EE......## - ##mmmmmmmmmmmmmm## - - - - diff --git a/data/level_06.txt b/data/level_06.txt deleted file mode 100644 index 902fd7c..0000000 --- a/data/level_06.txt +++ /dev/null @@ -1,21 +0,0 @@ -100 100 - - -################## -##......S1......## -##..............## -##..............## -##..............## -##mmmmll..llmmmm## - mm..mm - mm..mm - mm..mm - mm..mm -########..######## -##..............## -##..............## -##..............## -##......FF......## -##mmmmmmmmmmmmmm## - - diff --git a/data/logo.png b/data/logo.png deleted file mode 100644 index 2b2272a..0000000 Binary files a/data/logo.png and /dev/null differ diff --git a/data/magikball.bmp b/data/magikball.bmp new file mode 100644 index 0000000..42f8c9c Binary files /dev/null and b/data/magikball.bmp differ diff --git a/data/magikball.xcf b/data/magikball.xcf new file mode 100644 index 0000000..4499634 Binary files /dev/null and b/data/magikball.xcf differ diff --git a/data/platform.bmp b/data/platform.bmp new file mode 100644 index 0000000..848c053 Binary files /dev/null and b/data/platform.bmp differ diff --git a/data/player.bmp b/data/player.bmp new file mode 100644 index 0000000..c572e75 Binary files /dev/null and b/data/player.bmp differ diff --git a/data/player_broken.png b/data/player_broken.png deleted file mode 100644 index 5c7f957..0000000 Binary files a/data/player_broken.png and /dev/null differ diff --git a/data/player_down.png b/data/player_down.png deleted file mode 100644 index be46863..0000000 Binary files a/data/player_down.png and /dev/null differ diff --git a/data/player_left.png b/data/player_left.png deleted file mode 100644 index e76348e..0000000 Binary files a/data/player_left.png and /dev/null differ diff --git a/data/player_right.png b/data/player_right.png deleted file mode 100644 index e306754..0000000 Binary files a/data/player_right.png and /dev/null differ diff --git a/data/player_up.png b/data/player_up.png deleted file mode 100644 index 45ef1e2..0000000 Binary files a/data/player_up.png and /dev/null differ diff --git a/data/rock.bmp b/data/rock.bmp new file mode 100644 index 0000000..8b24019 Binary files /dev/null and b/data/rock.bmp differ diff --git a/data/rock.png b/data/rock.png deleted file mode 100644 index bebeaaf..0000000 Binary files a/data/rock.png and /dev/null differ diff --git a/data/save_point.png b/data/save_point.png deleted file mode 100644 index e584eb6..0000000 Binary files a/data/save_point.png and /dev/null differ diff --git a/data/save_point_active.png b/data/save_point_active.png deleted file mode 100644 index 7573775..0000000 Binary files a/data/save_point_active.png and /dev/null differ diff --git a/data/soldier.bmp b/data/soldier.bmp new file mode 100644 index 0000000..85c1519 Binary files /dev/null and b/data/soldier.bmp differ diff --git a/data/spider_left.bmp b/data/spider_left.bmp new file mode 100644 index 0000000..1d2b775 Binary files /dev/null and b/data/spider_left.bmp differ diff --git a/data/spider_right.bmp b/data/spider_right.bmp new file mode 100644 index 0000000..355dedc Binary files /dev/null and b/data/spider_right.bmp differ diff --git a/data/spider_right.xcf b/data/spider_right.xcf new file mode 100644 index 0000000..a650de9 Binary files /dev/null and b/data/spider_right.xcf differ diff --git a/data/spike_left.bmp b/data/spike_left.bmp new file mode 100644 index 0000000..c8d6879 Binary files /dev/null and b/data/spike_left.bmp differ diff --git a/data/spike_right.bmp b/data/spike_right.bmp new file mode 100644 index 0000000..6cf83e7 Binary files /dev/null and b/data/spike_right.bmp differ diff --git a/data/spikedbush.bmp b/data/spikedbush.bmp new file mode 100644 index 0000000..982df9f Binary files /dev/null and b/data/spikedbush.bmp differ diff --git a/data/spikedbush.xcf b/data/spikedbush.xcf new file mode 100644 index 0000000..2d33583 Binary files /dev/null and b/data/spikedbush.xcf differ diff --git a/data/textshadow.png b/data/textshadow.png deleted file mode 100644 index 3d7ac0f..0000000 Binary files a/data/textshadow.png and /dev/null differ diff --git a/data/wizard_left.bmp b/data/wizard_left.bmp new file mode 100644 index 0000000..b56f733 Binary files /dev/null and b/data/wizard_left.bmp differ diff --git a/data/wizard_right.bmp b/data/wizard_right.bmp new file mode 100644 index 0000000..06b7297 Binary files /dev/null and b/data/wizard_right.bmp differ diff --git a/data/wizard_right.xcf b/data/wizard_right.xcf new file mode 100644 index 0000000..5f8cc1e Binary files /dev/null and b/data/wizard_right.xcf differ diff --git a/dev-server.bat b/dev-server.bat deleted file mode 100644 index a4807b6..0000000 --- a/dev-server.bat +++ /dev/null @@ -1,2 +0,0 @@ - -php -S 0.0.0.0:80 -tbuild-emscripten \ No newline at end of file diff --git a/dist.emscripten.sh b/dist.emscripten.sh deleted file mode 100644 index 2a7900d..0000000 --- a/dist.emscripten.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -make -f Makefile.emscripten target=release clean -make -f Makefile.emscripten target=release - -mkdir -p DIST/web -cp -Rv web/* DIST/web/ -cp -v build-emscripten-release/game.* DIST/web/ diff --git a/dist.linux.sh b/dist.sh similarity index 84% rename from dist.linux.sh rename to dist.sh index 28af5e4..9988696 100644 --- a/dist.linux.sh +++ b/dist.sh @@ -1,12 +1,10 @@ #!/bin/sh -DIRNAME="Lonely_Ruins" +DIRNAME="TestGame" DATE=$(date +%Y%m%d) ZIPNAME="$DIRNAME.$DATE.zip" -make -f Makefile.linux clean -make -f Makefile.mingw clean make -f Makefile.linux make -f Makefile.mingw diff --git a/dist.win32.sh b/dist.win32.sh index 71ffe2e..004d617 100644 --- a/dist.win32.sh +++ b/dist.win32.sh @@ -1,12 +1,11 @@ #!/bin/sh -DIRNAME="Lonely_Ruins" +DIRNAME="TestGame" DATE=$(date +%Y%m%d) ZIPNAME="$DIRNAME.$DATE.zip" -make -f Makefile.win32 clean -make -f Makefile.win32 +make -f Makefile mkdir $DIRNAME cd $DIRNAME diff --git a/icon_32.png b/icon_32.png deleted file mode 100644 index c5f1d21..0000000 Binary files a/icon_32.png and /dev/null differ diff --git a/indiedb.header.png b/indiedb.header.png deleted file mode 100644 index 911a132..0000000 Binary files a/indiedb.header.png and /dev/null differ diff --git a/libSDL-1.2.so.0 b/libSDL-1.2.so.0 deleted file mode 100644 index b89eae1..0000000 Binary files a/libSDL-1.2.so.0 and /dev/null differ diff --git a/macosx/SDLMain.h b/macosx/SDLMain.h new file mode 100644 index 0000000..c56d90c --- /dev/null +++ b/macosx/SDLMain.h @@ -0,0 +1,16 @@ +/* SDLMain.m - main entry point for our Cocoa-ized SDL app + Initial Version: Darrell Walisser + Non-NIB-Code & other changes: Max Horn + + Feel free to customize this file to suit your needs +*/ + +#ifndef _SDLMain_h_ +#define _SDLMain_h_ + +#import + +@interface SDLMain : NSObject +@end + +#endif /* _SDLMain_h_ */ diff --git a/macosx/SDLMain.m b/macosx/SDLMain.m new file mode 100644 index 0000000..150d552 --- /dev/null +++ b/macosx/SDLMain.m @@ -0,0 +1,381 @@ +/* SDLMain.m - main entry point for our Cocoa-ized SDL app + Initial Version: Darrell Walisser + Non-NIB-Code & other changes: Max Horn + + Feel free to customize this file to suit your needs +*/ + +#include +#include "SDLMain.h" +#include /* for MAXPATHLEN */ +#include + +/* For some reaon, Apple removed setAppleMenu from the headers in 10.4, + but the method still is there and works. To avoid warnings, we declare + it ourselves here. */ +@interface NSApplication(SDL_Missing_Methods) +- (void)setAppleMenu:(NSMenu *)menu; +@end + +/* Use this flag to determine whether we use SDLMain.nib or not */ +#define SDL_USE_NIB_FILE 0 + +/* Use this flag to determine whether we use CPS (docking) or not */ +#define SDL_USE_CPS 1 +#ifdef SDL_USE_CPS +/* Portions of CPS.h */ +typedef struct CPSProcessSerNum +{ + UInt32 lo; + UInt32 hi; +} CPSProcessSerNum; + +extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn); +extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5); +extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn); + +#endif /* SDL_USE_CPS */ + +static int gArgc; +static char **gArgv; +static BOOL gFinderLaunch; +static BOOL gCalledAppMainline = FALSE; + +static NSString *getApplicationName(void) +{ + const NSDictionary *dict; + NSString *appName = 0; + + /* Determine the application name */ + dict = (const NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle()); + if (dict) + appName = [dict objectForKey: @"CFBundleName"]; + + if (![appName length]) + appName = [[NSProcessInfo processInfo] processName]; + + return appName; +} + +#if SDL_USE_NIB_FILE +/* A helper category for NSString */ +@interface NSString (ReplaceSubString) +- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString; +@end +#endif + +@interface NSApplication (SDLApplication) +@end + +@implementation NSApplication (SDLApplication) +/* Invoked from the Quit menu item */ +- (void)terminate:(id)sender +{ + /* Post a SDL_QUIT event */ + SDL_Event event; + event.type = SDL_QUIT; + SDL_PushEvent(&event); +} +@end + +/* The main class of the application, the application's delegate */ +@implementation SDLMain + +/* Set the working directory to the .app's parent directory */ +- (void) setupWorkingDirectory:(BOOL)shouldChdir +{ + if (shouldChdir) + { + char parentdir[MAXPATHLEN]; + CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle()); + CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url); + if (CFURLGetFileSystemRepresentation(url2, 1, (UInt8 *)parentdir, MAXPATHLEN)) { + chdir(parentdir); /* chdir to the binary app's parent */ + } + CFRelease(url); + CFRelease(url2); + } +} + +#if SDL_USE_NIB_FILE + +/* Fix menu to contain the real app name instead of "SDL App" */ +- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName +{ + NSRange aRange; + NSEnumerator *enumerator; + NSMenuItem *menuItem; + + aRange = [[aMenu title] rangeOfString:@"SDL App"]; + if (aRange.length != 0) + [aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]]; + + enumerator = [[aMenu itemArray] objectEnumerator]; + while ((menuItem = [enumerator nextObject])) + { + aRange = [[menuItem title] rangeOfString:@"SDL App"]; + if (aRange.length != 0) + [menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]]; + if ([menuItem hasSubmenu]) + [self fixMenu:[menuItem submenu] withAppName:appName]; + } +} + +#else + +static void setApplicationMenu(void) +{ + /* warning: this code is very odd */ + NSMenu *appleMenu; + NSMenuItem *menuItem; + NSString *title; + NSString *appName; + + appName = getApplicationName(); + appleMenu = [[NSMenu alloc] initWithTitle:@""]; + + /* Add menu items */ + title = [@"About " stringByAppendingString:appName]; + [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""]; + + [appleMenu addItem:[NSMenuItem separatorItem]]; + + title = [@"Hide " stringByAppendingString:appName]; + [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"]; + + menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"]; + [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)]; + + [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; + + [appleMenu addItem:[NSMenuItem separatorItem]]; + + title = [@"Quit " stringByAppendingString:appName]; + [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"]; + + + /* Put menu into the menubar */ + menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]; + [menuItem setSubmenu:appleMenu]; + [[NSApp mainMenu] addItem:menuItem]; + + /* Tell the application object that this is now the application menu */ + [NSApp setAppleMenu:appleMenu]; + + /* Finally give up our references to the objects */ + [appleMenu release]; + [menuItem release]; +} + +/* Create a window menu */ +static void setupWindowMenu(void) +{ + NSMenu *windowMenu; + NSMenuItem *windowMenuItem; + NSMenuItem *menuItem; + + windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; + + /* "Minimize" item */ + menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"]; + [windowMenu addItem:menuItem]; + [menuItem release]; + + /* Put menu into the menubar */ + windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""]; + [windowMenuItem setSubmenu:windowMenu]; + [[NSApp mainMenu] addItem:windowMenuItem]; + + /* Tell the application object that this is now the window menu */ + [NSApp setWindowsMenu:windowMenu]; + + /* Finally give up our references to the objects */ + [windowMenu release]; + [windowMenuItem release]; +} + +/* Replacement for NSApplicationMain */ +static void CustomApplicationMain (int argc, char **argv) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + SDLMain *sdlMain; + + /* Ensure the application object is initialised */ + [NSApplication sharedApplication]; + +#ifdef SDL_USE_CPS + { + CPSProcessSerNum PSN; + /* Tell the dock about us */ + if (!CPSGetCurrentProcess(&PSN)) + if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103)) + if (!CPSSetFrontProcess(&PSN)) + [NSApplication sharedApplication]; + } +#endif /* SDL_USE_CPS */ + + /* Set up the menubar */ + [NSApp setMainMenu:[[NSMenu alloc] init]]; + setApplicationMenu(); + setupWindowMenu(); + + /* Create SDLMain and make it the app delegate */ + sdlMain = [[SDLMain alloc] init]; + [NSApp setDelegate:sdlMain]; + + /* Start the main event loop */ + [NSApp run]; + + [sdlMain release]; + [pool release]; +} + +#endif + + +/* + * Catch document open requests...this lets us notice files when the app + * was launched by double-clicking a document, or when a document was + * dragged/dropped on the app's icon. You need to have a + * CFBundleDocumentsType section in your Info.plist to get this message, + * apparently. + * + * Files are added to gArgv, so to the app, they'll look like command line + * arguments. Previously, apps launched from the finder had nothing but + * an argv[0]. + * + * This message may be received multiple times to open several docs on launch. + * + * This message is ignored once the app's mainline has been called. + */ +- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename +{ + const char *temparg; + size_t arglen; + char *arg; + char **newargv; + + if (!gFinderLaunch) /* MacOS is passing command line args. */ + return FALSE; + + if (gCalledAppMainline) /* app has started, ignore this document. */ + return FALSE; + + temparg = [filename UTF8String]; + arglen = SDL_strlen(temparg) + 1; + arg = (char *) SDL_malloc(arglen); + if (arg == NULL) + return FALSE; + + newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2)); + if (newargv == NULL) + { + SDL_free(arg); + return FALSE; + } + gArgv = newargv; + + SDL_strlcpy(arg, temparg, arglen); + gArgv[gArgc++] = arg; + gArgv[gArgc] = NULL; + return TRUE; +} + + +/* Called when the internal event loop has just started running */ +- (void) applicationDidFinishLaunching: (NSNotification *) note +{ + int status; + + /* Set the working directory to the .app's parent directory */ + [self setupWorkingDirectory:gFinderLaunch]; + +#if SDL_USE_NIB_FILE + /* Set the main menu to contain the real app name instead of "SDL App" */ + [self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()]; +#endif + + /* Hand off to main application code */ + gCalledAppMainline = TRUE; + status = SDL_main (gArgc, gArgv); + + /* We're done, thank you for playing */ + exit(status); +} +@end + + +@implementation NSString (ReplaceSubString) + +- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString +{ + unsigned int bufferSize; + unsigned int selfLen = [self length]; + unsigned int aStringLen = [aString length]; + unichar *buffer; + NSRange localRange; + NSString *result; + + bufferSize = selfLen + aStringLen - aRange.length; + buffer = (unichar *)NSAllocateMemoryPages(bufferSize*sizeof(unichar)); + + /* Get first part into buffer */ + localRange.location = 0; + localRange.length = aRange.location; + [self getCharacters:buffer range:localRange]; + + /* Get middle part into buffer */ + localRange.location = 0; + localRange.length = aStringLen; + [aString getCharacters:(buffer+aRange.location) range:localRange]; + + /* Get last part into buffer */ + localRange.location = aRange.location + aRange.length; + localRange.length = selfLen - localRange.location; + [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange]; + + /* Build output string */ + result = [NSString stringWithCharacters:buffer length:bufferSize]; + + NSDeallocateMemoryPages(buffer, bufferSize); + + return result; +} + +@end + + + +#ifdef main +# undef main +#endif + + +/* Main entry point to executable - should *not* be SDL_main! */ +int main (int argc, char **argv) +{ + /* Copy the arguments into a global variable */ + /* This is passed if we are launched by double-clicking */ + if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) { + gArgv = (char **) SDL_malloc(sizeof (char *) * 2); + gArgv[0] = argv[0]; + gArgv[1] = NULL; + gArgc = 1; + gFinderLaunch = YES; + } else { + int i; + gArgc = argc; + gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1)); + for (i = 0; i <= argc; i++) + gArgv[i] = argv[i]; + gFinderLaunch = NO; + } + +#if SDL_USE_NIB_FILE + NSApplicationMain (argc, argv); +#else + CustomApplicationMain (argc, argv); +#endif + return 0; +} + diff --git a/macosx/SDL_dev.zip b/macosx/SDL_dev.zip new file mode 100644 index 0000000..e860dfb Binary files /dev/null and b/macosx/SDL_dev.zip differ diff --git a/main.c b/main.c index 8fe08ac..9b09f3a 100644 --- a/main.c +++ b/main.c @@ -1,17 +1,9 @@ -// Copyright (C) 2011 Valeriano Alfonso Rodriguez (Kableado) +// Copyright (C) 2012 Valeriano Alfonso Rodriguez (Kableado) #include #include -#include #include #include -#include - -#ifdef EMSCRIPTEN -#include -#define time stime -#endif - #include "GameLib.h" extern int gamelib_debug; @@ -19,202 +11,44 @@ extern int gamelib_debug; #include "GameEnts.h" #include "GameMap.h" -char *saveFilename="saves/game.save"; -int game_started=0; -int game_level=0; -int game_level_point=1; -int game_level_reset=0; - -DrawImg img_logo; -DrawImg img_end; DrawFnt font; +DrawFnt font_shad; -void GameLib_MkDir(char *dir){ -#ifdef WIN32 - mkdir(dir); -#else - mkdir(dir,0777); -#endif -} - - -void ProcGame(); -void PostProcGame(); -void DrawGame(float f); - - -void ProcTitle(void *data){ - int play=0; - if( Input_GetKey(InputKey_Jump)==InputKey_Pressed|| - Input_GetKey(InputKey_Continue)==InputKey_Pressed) - { - play=1; - } - if( (Input_GetKey(InputKey_Action1)==InputKey_Pressed|| - Input_GetKey(InputKey_Action2)==InputKey_Pressed) && - game_started) - { - play=1; - game_started=0; - } - if(play){ - if(!game_started){ - int pos[2]={0,0}; - GameLib_SetPos(pos); - game_level=0; - game_level_point=1; - game_level_reset=0; - - GameMap_CreateLevel(game_level,game_level_point); - game_started=1; - } - GameLib_Loop(ProcGame,PostProcGame,NULL,DrawGame); - } - if( Input_GetKey(InputKey_Exit)==InputKey_Pressed){ - Draw_BreakLoop(); - } -} - -void DrawTitle(void *data,float dt){ - Draw_Clean(0,0,0); - Draw_SetColor(1.0f,1.0f,1.0f,1.0f); - - Draw_DrawImg(img_logo,320,150); - if(!game_started){ - Draw_DrawText(font,"Press [Space] to Start.",300,300); - }else{ - Draw_DrawText(font,"Press [Space] to Continue.",300,300); - Draw_DrawText(font,"Press [X] to Start.",300,316); - } - - Draw_DrawText(font,"By Kableado (VAR)",200,440); -} - - -void ProcEnd(void *data){ - if( Input_GetKey(InputKey_Jump)==InputKey_Pressed|| - Input_GetKey(InputKey_Continue)==InputKey_Pressed || - Input_GetKey(InputKey_Exit)==InputKey_Pressed) - { - game_started=0; - game_level=0; - game_level_point=1; - game_level_reset=0; - Draw_Loop(ProcTitle,DrawTitle,NULL); - } -} - - -void DrawEnd(void *data,float dt){ - Draw_Clean(0,0,0); - Draw_SetColor(1.0f,1.0f,1.0f,1.0f); - - Draw_DrawImg(img_end,320,150); - - Draw_DrawText(font,"Congratulations you saved the kittie!",250,320); - Draw_DrawText(font,"Thanks for playing!",250,350); - Draw_DrawText(font,"Press [Space] to Title.",300,400); -} - +DrawImg img_background; void ProcGame(){ + } void PostProcGame(){ - if(game_level_reset){ - if(Input_AnyKey()){ - if(GameMap_CreateLevel(game_level,game_level_point)){ - if(game_level_reset==2){ - int pos[2]={0,0}; - GameLib_SetPos(pos); - } - game_level_reset=0; - }else{ - Draw_Loop(ProcEnd,DrawEnd,NULL); - } - } - } - if(Input_GetKey(InputKey_Exit)==InputKey_Pressed){ - Draw_Loop(ProcTitle,DrawTitle,NULL); - } + // Apply gravity to every entity + GameLib_ForEachEnt(EntityApplyGravity); } -void DrawGame(float f){ - char string[1024]; - +void PreDrawGame(){ + //Draw_Clean(128,128,128); Draw_SetColor(1.0f,1.0f,1.0f,1.0f); - - sprintf(string, "Level: %d.%d",game_level+1,game_level_point); - Draw_SetColor(0,0,0,0.5f); - Draw_DrawText(font,string,17,17); - Draw_SetColor(1,1,1,1); - Draw_DrawText(font,string,16,16); - - if(game_level_reset==2){ - Draw_SetColor(0,0,0,0.5f); - Draw_DrawText(font,"Level Complete",301,301); - Draw_SetColor(1,1,0,1); - Draw_DrawText(font,"Level Complete.",300,300); - }else - if(game_level_reset==1){ - Draw_SetColor(0,0,0,0.5f); - Draw_DrawText(font,"You are dead.",301,301); - Draw_SetColor(1,0,0,1); - Draw_DrawText(font,"You are dead.",300,300); - }else - if(game_level_reset==3){ - Draw_Loop(ProcEnd,DrawEnd,NULL); - } + Draw_DrawImgResized(img_background,0,0,640,480); } +void DrawGame(){ + char cadena[128]; -void LoadGame(){ - FILE *f; - - GameLib_MkDir("saves"); - - f=fopen(saveFilename,"rb"); - if(!f) - return; - - fread(&game_level,1,sizeof(int),f); - fread(&game_level_point,1,sizeof(int),f); - - if(game_level==0 && game_level_point==1){ - game_started=0; - return; - } - - GameMap_CreateLevel(game_level,game_level_point); - game_started=1; - - fclose(f); -} - -void SaveGame(){ - FILE *f; - - GameLib_MkDir("saves"); - - f=fopen(saveFilename,"wb"); - if(!f) - return; - - fwrite(&game_level,1,sizeof(int),f); - fwrite(&game_level_point,1,sizeof(int),f); - - fclose(f); -#if EMSCRIPTEN - EM_ASM( - FS.syncfs(function (err) { }); - ); -#endif + // Watermark + Draw_SetColor(0,0,0,0.3); + Draw_DrawText(font,"By Kableado (VAR)",201,461); + Draw_SetColor(1.0f,1.0f,1.0f,0.3f); + Draw_DrawText(font,"By Kableado (VAR)",200,460); } + int main(int argc,char *argv[]){ + int i,j; + Entity *e; + srand(time(NULL)); @@ -225,19 +59,35 @@ int main(int argc,char *argv[]){ } } - GameLib_Init(640,480,"Game",15,60); + GameLib_Init(640,480,"Game",60,60); - img_logo=Draw_LoadImage("data/logo.png"); - img_end=Draw_LoadImage("data/end.png"); + + ///////////////////////////// + // Load and initialize media. + // font=Draw_DefaultFont(255,255,255,255); + font_shad=Draw_DefaultFont(0,0,0,127); + + img_background=Draw_LoadImage("data/heaven.bmp"); + Draw_SetOffset(img_background,0,0); GameEnts_Init(); - LoadGame(); - Draw_OverrideExit(1); - Draw_Loop(ProcTitle,DrawTitle,NULL); + ///////////////////////// + // Initialize world. + // + GameLib_DelEnts(); + GameMap_LoadLevel("data/level_01.txt",32); + + + ///////////////////////// + // Run the world. + // + + GameLib_Loop(ProcGame,PostProcGame,PreDrawGame,DrawGame); + return(0); -} +} \ No newline at end of file diff --git a/readme.txt b/readme.txt deleted file mode 100644 index 5951ea5..0000000 --- a/readme.txt +++ /dev/null @@ -1,22 +0,0 @@ -Lonely Ruins ------------- -By Kableado (VAR) - -You are a robot on a rescue mision. -The rescuer and the rescued are alone -in a strange place. - -Good Luck! - - - - - -Controls: ---------- -Cursors to move. - - - -CopyRight (C) 2011-2012 Valeriano Alfonso Rodriguez -http://varstudio.net diff --git a/saves/game.save b/saves/game.save deleted file mode 100644 index d25f911..0000000 Binary files a/saves/game.save and /dev/null differ diff --git a/web/imagenes/logo_lonelyruins_web.png b/web/imagenes/logo_lonelyruins_web.png deleted file mode 100644 index a7bf849..0000000 Binary files a/web/imagenes/logo_lonelyruins_web.png and /dev/null differ diff --git a/web/imagenes/logo_lonelyruins_web_mini.png b/web/imagenes/logo_lonelyruins_web_mini.png deleted file mode 100644 index 94d9281..0000000 Binary files a/web/imagenes/logo_lonelyruins_web_mini.png and /dev/null differ diff --git a/web/imgview/anterior.png b/web/imgview/anterior.png deleted file mode 100644 index dace661..0000000 Binary files a/web/imgview/anterior.png and /dev/null differ diff --git a/web/imgview/cargando.gif b/web/imgview/cargando.gif deleted file mode 100644 index 6bdc3b5..0000000 Binary files a/web/imgview/cargando.gif and /dev/null differ diff --git a/web/imgview/fondo.png b/web/imgview/fondo.png deleted file mode 100644 index 7c97f18..0000000 Binary files a/web/imgview/fondo.png and /dev/null differ diff --git a/web/imgview/imgview.css b/web/imgview/imgview.css deleted file mode 100644 index 9cef235..0000000 --- a/web/imgview/imgview.css +++ /dev/null @@ -1,71 +0,0 @@ -/*********************************************** - * Copyright (c) 2010 Valeriano Alfonso * - ***********************************************/ -/* - NOTA DE DOMINIO PUBLICO - ----------------------- - ImgView es Dominio Publico. Esto significa que se puede hacer con el - lo que se quiera sin haber ninguna garantia de reembolso o idoneidad. - Se aprecia que la fuente sea citada. -*/ - -#imgview_fondo { - background-image: url(fondo.png); -} - -#imgview_imgcargando { - border: 10px solid white; -} - -#imgview_fondo a { - padding:0px; - margin:0px; -} - -#imgview { - background-color: white; - border: 10px solid white; -} - -#imgview img { - border: none; - padding:0px; - margin:0px; -} - -#imgview a { - padding:0px; - margin:0px; -} - -#imgview_control { - height: 30px; - background-color: white; -} - -#imgview_anterior { - background-color: white; - float: left; - width: 50%; - height:32px; - border:0px; - padding:0px; - margin:0px; - background-image:url('anterior.png'); - background-repeat:no-repeat; - background-position: 50% 0%; - cursor:pointer; -} -#imgview_siguiente { - background-color: white; - float: right; - width: 50%; - height:32px; - border:0px; - padding:0px; - margin:0px; - background-image:url('siguiente.png'); - background-repeat:no-repeat; - background-position: 50% 0%; - cursor:pointer; -} \ No newline at end of file diff --git a/web/imgview/imgview.js b/web/imgview/imgview.js deleted file mode 100644 index c924bc9..0000000 --- a/web/imgview/imgview.js +++ /dev/null @@ -1,497 +0,0 @@ -/*********************************************** - * Copyright (c) 2010 Valeriano Alfonso * - ***********************************************/ -/* - NOTA DE DOMINIO PUBLICO - ----------------------- - ImgView es Dominio Publico. Esto significa que se puede hacer con el - lo que se quiera sin haber ninguna garantia de reembolso o idoneidad. - Se aprecia que la fuente sea citada. -*/ - - -/* - Historial de cambios - -------------------- - 1.0 2010-1-3 : - * Version inicial. - 1.1 2010-1-5 : - * Corregida necesidad de cargar el script en la seccion head. - * Funcionalidad basica de album implementada. - 1.2 2010-5-18 : - * Asimilado de todos los enlaces a imagenes en un album general. - * Iconos de anterior y siguiente de los albums, nuevos. -*/ - -///////////////////////// -// Configuracion -// -var imgview_prefix = ""; // Se atoconfigura -var imgview_border = 10; // Tambien ajustar en el CSS. -var imgview_control_alto = 32; // Tambien ajustar en el CSS. - - - - -/////////////////////// -// Globales -// -var imgview_nombre_album=""; -var imgview_href_anterior=""; -var imgview_href_siguiente=""; -var imgview_preloader=false; - -///////////////////////////////////// -// ImgView_ShowImage -// - -function ImgView_ShowImage(href,is_album){ - var elemFondo = document.getElementById('imgview_fondo'); - var elemImgview = document.getElementById('imgview'); - var elemImgviewControl = document.getElementById('imgview_control'); - var elemImgCargando = document.getElementById('imgview_imgcargando'); - var elemEnlace = document.getElementById('imgview_enlace'); - var elemImg = document.getElementById('imgview_img'); - var elemAnt = document.getElementById('imgview_anterior'); - var elemSig = document.getElementById('imgview_siguiente'); - var preloader; - var max_horiz, max_vert; - var ventana_ancho, ventana_alto; - var pagina_ancho, pagina_alto; - var pos_horiz = 0, pos_vert = 0; - - - if(is_album){ - var enlaces; - var imgview_RegExp; - var nombre_temp; - var i,j; - - // Buscar imagenes anterior y siguientes - enlaces = document.getElementsByTagName("a"); - for(i=0;i0){ - j=i-1; - while(j>=0){ - if(enlaces[j].getAttribute("imgview_albumid")== - imgview_nombre_album) - { - imgview_href_anterior=enlaces[j].getAttribute("href"); - break; - } - j--; - } - } - - // Buscar Siguiente - imgview_href_siguiente=""; - if(i<(enlaces.length-1)){ - j=i+1; - while(j document.body.offsetHeight){ - // all but Explorer Mac - max_horiz = document.body.scrollWidth; - max_vert = document.body.scrollHeight; - }else{ - // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari - max_horiz = document.body.offsetWidth; - max_vert = document.body.offsetHeight; - } - - // Obtener tamanho de la ventana - if(window.innerHeight) { - // Todos excepto Explorer - ventana_ancho = window.innerWidth; - ventana_alto = window.innerHeight; - }else if(document.documentElement && document.documentElement.clientHeight){ - // Explorer 6 Strict - ventana_ancho = document.documentElement.clientWidth; - ventana_alto = document.documentElement.clientHeight; - }else if(document.body){ - // Resto de Explorers - ventana_ancho = document.body.clientWidth; - ventana_alto = document.body.clientHeight; - } - - // HACK: reducir el tamaho de ventana_ancho. Hace que no sobrepase los bordes - ventana_ancho-=20; - - // Obtener el tamanho de la pagina - if(max_vert < ventana_alto){ - pagina_alto = ventana_alto; - }else{ - pagina_alto = max_vert; - } - if(max_horiz < ventana_ancho){ - pagina_ancho = ventana_ancho; - }else{ - pagina_ancho = max_horiz; - } - - // Obtener posicion del los scrolls - if( typeof( window.pageYOffset ) == 'number' ) { - // La mayoria de navegadores - pos_vert = window.pageYOffset; - pos_horiz = window.pageXOffset; - } else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) { - // Explorer - pos_vert = document.body.scrollTop; - pos_horiz = document.body.scrollLeft; - } else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) { - // Explorer 6 Strict - pos_vert = document.documentElement.scrollTop; - pos_horiz = document.documentElement.scrollLeft; - } - - - - // Centrar y hacer visible la imagen de cargando - if(elemImgCargando){ - elemImgCargando.style.top = - (pos_vert + - ((ventana_alto - elemImgCargando.height) / 2)) + 'px'; - elemImgCargando.style.left = - (pos_horiz + - ((ventana_ancho - elemImgCargando.width) / 2)) + 'px'; - elemImgCargando.style.display = 'block'; - } - - // Hacer que el fondo ocupe la pagina y sea visible - elemFondo.style.height = (pagina_alto + 'px'); - elemFondo.style.display = 'block'; - - // Carga de la imagen - imgview_preloader=new Image(); - imgview_preloader.onload=function(){ - - // Mostrar imgview, necesario para que los tamanhos sean correctos - elemImgview.style.display = 'block'; - - // Mostrar/Ocultar control de albums - if(is_album){ - elemImgviewControl.style.display = 'block'; - ventana_alto-=imgview_control_alto; - if(imgview_href_anterior.length==0){ - elemAnt.style.display = 'none'; - }else{ - elemAnt.style.display = 'block'; - } - if(imgview_href_siguiente.length==0){ - elemSig.style.display = 'none'; - }else{ - elemSig.style.display = 'block'; - } - }else{ - elemImgviewControl.style.display = 'none'; - } - - // Establecer la imagen precargada - elemImg.src = href; - elemImg.width = imgview_preloader.width; - elemImg.height = imgview_preloader.height; - - // Ajustar el tamanho de la imagen - var relacion=elemImg.width/elemImg.height; - if((elemImg.height+imgview_border*2)>ventana_alto){ - elemImg.height=ventana_alto-imgview_border*2; - elemImg.width=elemImg.height*relacion; - } - if((elemImg.width+imgview_border*2)>ventana_ancho){ - elemImg.width=ventana_ancho-imgview_border*2; - elemImg.height=elemImg.width/relacion; - } - - // Centrar imgview - elemImgview.style.top = - (pos_vert + - ((ventana_alto - elemImg.height) / 2) - imgview_border) + 'px'; - elemImgview.style.left = - (pos_horiz + - ((ventana_ancho - elemImg.width) / 2) - imgview_border) + 'px'; - - - // Oclultar imagen de cargar y mostrar imgview - if(elemImgCargando) { - elemImgCargando.style.display = 'none'; - } - - return false; - } - imgview_preloader.src = href; - elemEnlace.href = href; -} - - - - - - - - - -///////////////////////////////////// -// ImgView_Show -// -function ImgView_Show(obj){ - imgview_nombre_album=obj.getAttribute("imgview_albumid"); - if(imgview_nombre_album){ - ImgView_ShowImage(obj.getAttribute("href"),true); - }else{ - ImgView_ShowImage(obj.getAttribute("href"),false); - } -} - - - - - -///////////////////////////////////// -// ImgView_Hide -// -function ImgView_Hide(){ - var elemFondo = document.getElementById('imgview_fondo'); - var elemImgview = document.getElementById('imgview'); - var elemImgCargando = document.getElementById('imgview_imgcargando'); - var elemEnlace = document.getElementById('imgview_enlace'); - elemFondo.style.display = 'none'; - elemImgview.style.display = 'none'; - elemImgCargando.style.display = 'none'; - imgview_preloader.onload=function(){return false;} - imgview_preloader.src = ""; - elemEnlace.href = ""; -} - - - - - -///////////////////////////////////// -// ImgView_ShowAnterior -// -function ImgView_ShowAnterior(obj){ - if(imgview_href_anterior.length){ - ImgView_ShowImage(imgview_href_anterior,true); - } -} - - - - -///////////////////////////////////// -// ImgView_ShowSiguiente -// -function ImgView_ShowSiguiente(obj){ - if(imgview_href_siguiente.length){ - ImgView_ShowImage(imgview_href_siguiente,true); - } -} - - - - - -///////////////////////////////////// -// ImgView_Init -// -// Asociar al evento "onclick" la funcion "ImgView_Show" a los links con rel="imgview". -// Anhadir el markup necesario para mostrar imagenes. -function ImgView_Init(){ - var i; - var enlaces; - var scripts; - var imgview_RegExp; - var isimage_RegExp; - - if (!document.getElementsByTagName){ - return; - } - - // HACK: Obtener el path donde de este mismo script - scripts=document.getElementsByTagName("script"); - imgview_RegExp = /imgview\.js$/i; - for(i=0;i - -Con esto todos los enlaces a imagenes usaran imgview. Es recomendable -insertar una imagen en miniatura dentro del enlace. - -Uso Avanzado: -------------- - -Para mostrar una imagen independiente de cualquier album: - - - -Para crear albumes independientes; poner a todas las imagenes del mismo grupo -rel="imgview.album", siendo "album" el nombre para esa coleccion: - - - - -Licencia: ---------- - ImgView es Dominio Publico. Esto significa que se puede hacer con el - lo que se quiera sin haber ninguna garantia de reembolso o idoneidad. - Se aprecia que la fuente sea citada. - - -Copyright (c) 2010 Valeriano Alfonso diff --git a/web/imgview/siguiente.png b/web/imgview/siguiente.png deleted file mode 100644 index 0cc0213..0000000 Binary files a/web/imgview/siguiente.png and /dev/null differ diff --git a/web/index.html b/web/index.html deleted file mode 100644 index 0d20967..0000000 --- a/web/index.html +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - - - - - - -Lonely Ruins - - - -
- - -
- -
- - -
- - -
- - - - - - -

About

-You are a robot on a rescue mision.
-The rescuer and the rescued are alone
-in a strange place.
-
-Good Luck!
-

 

- - - -

Play

-
-
- ► Play -
-
- Get it on Google Play -
-
-

 

- - - - - -

Screenshots

-

- - - - - -

-

 

- - - - -

Contact

- - -

 

- -

 

- - - - -
- Copyright © 2011-2014 Valeriano Alfonso. -
- -
- -
-
- - - \ No newline at end of file diff --git a/web/join.php b/web/join.php deleted file mode 100644 index 77278ac..0000000 --- a/web/join.php +++ /dev/null @@ -1,36 +0,0 @@ - - - -

OK!

- - \ No newline at end of file diff --git a/web/lonelyruins_banner.png b/web/lonelyruins_banner.png deleted file mode 100644 index b402f7f..0000000 Binary files a/web/lonelyruins_banner.png and /dev/null differ diff --git a/web/play.html b/web/play.html deleted file mode 100644 index b6e33ba..0000000 --- a/web/play.html +++ /dev/null @@ -1,133 +0,0 @@ - - - - - - Lonely Ruins - - - -
- -
-
-
-

Loading...

- Code:
-
-
- Data:
-
-
- -
- - - - - \ No newline at end of file diff --git a/web/sshots/20120102/shot-20120102-1.png b/web/sshots/20120102/shot-20120102-1.png deleted file mode 100644 index 1a3ad41..0000000 Binary files a/web/sshots/20120102/shot-20120102-1.png and /dev/null differ diff --git a/web/sshots/20120102/shot-20120102-1.thumb.png b/web/sshots/20120102/shot-20120102-1.thumb.png deleted file mode 100644 index c10eef1..0000000 Binary files a/web/sshots/20120102/shot-20120102-1.thumb.png and /dev/null differ diff --git a/web/sshots/20120102/shot-20120102-2.png b/web/sshots/20120102/shot-20120102-2.png deleted file mode 100644 index 7f18ffb..0000000 Binary files a/web/sshots/20120102/shot-20120102-2.png and /dev/null differ diff --git a/web/sshots/20120102/shot-20120102-2.thumb.png b/web/sshots/20120102/shot-20120102-2.thumb.png deleted file mode 100644 index 6436a93..0000000 Binary files a/web/sshots/20120102/shot-20120102-2.thumb.png and /dev/null differ diff --git a/web/sshots/20120102/shot-20120102-3.png b/web/sshots/20120102/shot-20120102-3.png deleted file mode 100644 index 2ae5264..0000000 Binary files a/web/sshots/20120102/shot-20120102-3.png and /dev/null differ diff --git a/web/sshots/20120102/shot-20120102-3.thumb.png b/web/sshots/20120102/shot-20120102-3.thumb.png deleted file mode 100644 index 1f4ba64..0000000 Binary files a/web/sshots/20120102/shot-20120102-3.thumb.png and /dev/null differ diff --git a/web/style.css b/web/style.css deleted file mode 100644 index 2e48216..0000000 --- a/web/style.css +++ /dev/null @@ -1,223 +0,0 @@ -/*********************************************** - * Copyright (c) 2012 Valeriano Alfonso * - ***********************************************/ - - - -/* Elementos Base */ -html, body { - height: 100%; - margin: 0; - padding: 0; - font-family: Verdana,Arial,Helvetica,sans-serif; - background-color:#000000; - color: #777777; - font-size: 10pt; -} -h1{ - text-align: left; - margin-top: 0; - margin-bottom: 1em; - font-size: 16pt; - font-weight: bold; -} -h2{ - text-align: left; - margin-top: 0; - margin-bottom: 0.75em; - font-size: 14pt; - font-weight: bold; -} -h3{ - text-align: left; - margin-top: 0; - margin-bottom: 0.5em; - font-size: 10pt; - font-weight: bold; -} -h4{ - margin-top: 0; - margin-bottom: 0.5em; - font-size: 11pt; - font-weight: bold; -} -p,li,td{ - margin-top: 0; - margin-bottom: 0.5em; - font-size: 10pt; -} -li { - padding:2px; -} -img { - border:0; -} - - - - - - -/* Links normales */ -a { - text-decoration:none; - font-weight: bold; - display:inline; -} -a:link { - color: #7777FF; -} -a:visited { - color: #7777FF; -} -a:hover { - color: #FFFFFF; - text-decoration: underline; -} -a:active { - color: #CBB545; -} - - - - - - - - - - -/* Estilo de Lonely Ruins */ -.contenedor { - margin: 0; - padding: 0; - float: left; - width: 100%; - min-height: 100%; -} -.cabecera { - width: 700px; - height:130px; - margin: 0 auto; - position: relative; -} -.titulo { - margin:0; - padding:0; - border:0; - vertical-align:bottom; - position:absolute; -} -a.titulo:hover { - background:none; -} -a.titulo img { - border:none; -} -a.titulo:hover img{ - border:none; -} -.contenido { - width: 700px; - margin:0; - padding:0; - border:0; - position:relative; - margin: 0 auto; - vertical-align:bottom; -} -.pie { - width:700px; - height: 64px; - margin:0; - padding:0; - border:0; - position:relative; - margin: 0 auto; - font-weight: bold; -} - - - - -.navbar { - height:130px; - width:500px; - margin:0; - padding:0; - border:0; - vertical-align:bottom; - position:absolute; - bottom:0px; - right:0px; -} -.navbar ul { - list-style:none; - list-style-type:none; - list-style-position:inside; - border:0; - padding:0; - margin:0; - display:block; - position:absolute; - bottom:0; - right:0; -} -.navbar li{ - padding:0px; - float: left; - text-align: center; - vertical-align: bottom; - margin: 1px; - border-left:1px solid #777777; -} -.navbar li:first-child{ - border-left:none; -} - -/* links del navbar */ -.navbar a { - padding: 4px; - font-size:12pt; - display:block; -} - - - -.toTop{ - text-align:right; - font-size:7pt; -} - - -.columnContainer{ - white-space: nowrap; - font-size: 0; - vertical-align: top; -} -.column2{ - width:50%; - display:inline-block; - font-size: 10pt; - vertical-align:top; -} - -.playLink{ - font-size:25px; - display: inline-block; - border-radius: 10px; - border: solid 1px grey; - width:127px; - height:43px; - line-height:43px; -} -.playLink:link{ - color: #777777; -} -.playLink:hover{ - box-shadow: 0 0 5px white; - text-shadow: 0 0 2px white; - border: solid 1px white; - text-decoration:none; - color: white; -} diff --git a/web/web_thumb.png b/web/web_thumb.png deleted file mode 100644 index 18b73ba..0000000 Binary files a/web/web_thumb.png and /dev/null differ

>>0);s=p}p=c[e>>2]|0;if((p|0)!=0){r=c[q>>2]|0;k=1;do{r=(c[n+(k+ -1<<2)>>2]|0)+r<<1;c[q+(k<<2)>>2]=r;k=k+1|0}while(!(k>>>0>p>>>0))}if((s|0)!=0){p=c[a+8>>2]|0;k=s;r=0;while(1){t=c[p+(r<<2)>>2]|0;if((t|0)==0){u=k}else{v=q+(t<<2)|0;t=c[v>>2]|0;c[v>>2]=t+1;c[(c[f>>2]|0)+(r<<2)>>2]=t;u=c[d>>2]|0}r=r+1|0;if(!(r>>>0>>0)){break}else{k=u}}}Qd(n);Qd(q);k=c[d>>2]|0;r=Pd(k<<3)|0;c[a>>2]=r;if((r|0)==0){w=83;i=b;return w|0}p=(k&2147483647|0)==0;if(!p){t=k<<1;v=0;do{c[r+(v<<2)>>2]=32767;v=v+1|0}while(v>>>0>>0)}if((k|0)==0){w=0;i=b;return w|0}t=c[a+8>>2]|0;v=k+ -2|0;x=0;y=0;z=0;a:while(1){A=t+(x<<2)|0;B=c[A>>2]|0;if((B|0)==0){C=y;D=z}else{E=B;B=0;F=y;G=z;while(1){if(G>>>0>v>>>0){w=55;o=44;break a}H=r+(((c[(c[f>>2]|0)+(x<<2)>>2]|0)>>>(E+~B|0)&1|G<<1)<<2)|0;I=c[H>>2]|0;do{if((I|0)==32767){J=B+1|0;if((J|0)==(E|0)){c[H>>2]=x;K=E;L=F;M=0;break}else{N=F+1|0;c[H>>2]=N+k;K=J;L=N;M=N;break}}else{K=B+1|0;L=F;M=I-k|0}}while(0);E=c[A>>2]|0;if(!(K>>>0>>0)){C=L;D=M;break}else{B=K;F=L;G=M}}}x=x+1|0;if(!(x>>>0>>0)){break}else{y=C;z=D}}if((o|0)==44){i=b;return w|0}if(p){w=0;i=b;return w|0}z=k<<1;y=0;do{x=r+(y<<2)|0;if((c[x>>2]|0)==32767){c[x>>2]=0}y=y+1|0}while(y>>>0>>0);w=0;i=b;return w|0}}}while(0);Qd(l);Qd(m);w=83;i=b;return w|0}function _c(a,e,f){a=a|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;a=i;g=(f|0)/4|0;he(e|0,0,f|0)|0;f=c[2318]|0;if((f|0)==0){i=a;return}h=f;f=0;a:while(1){j=f+12|0;b:do{if((f|0)==0){k=c[h>>2]|0;if((k|0)==0){l=h+12|0;m=c[l>>2]|0;c[l>>2]=c[2320];c[2320]=h;c[2318]=m;n=m;o=0}else{p=h;q=k;r=h;s=8}}else{k=h;while(1){m=c[k>>2]|0;if((m|0)!=0){p=k;q=m;r=k;s=8;break b}m=k+12|0;l=k;k=c[m>>2]|0;c[m>>2]=c[2320];c[2320]=l;c[j>>2]=k;if((k|0)==0){s=25;break a}}}}while(0);if((s|0)==8){s=0;j=r+4|0;k=c[j>>2]|0;l=(c[q+20>>2]|0)+(k<<1)|0;m=(c[q+16>>2]|0)-k|0;if((m|0)>(g|0)){t=g}else{c[p>>2]=0;t=m}if((t|0)>0){m=r+9|0;u=r+8|0;v=0;w=e;x=l;while(1){l=((aa(d[m>>0]|0,b[x>>1]|0)|0)>>8)+(b[w>>1]|0)|0;do{if((l|0)<=16384){if((l|0)<-16384){b[w>>1]=-16384;break}else{b[w>>1]=l;break}}else{b[w>>1]=16384}}while(0);l=w+2|0;y=((aa(d[u>>0]|0,b[x>>1]|0)|0)>>8)+(b[l>>1]|0)|0;do{if((y|0)<=16384){if((y|0)<-16384){b[l>>1]=-16384;break}else{b[l>>1]=y;break}}else{b[l>>1]=16384}}while(0);v=v+1|0;if((v|0)==(t|0)){break}else{w=w+4|0;x=x+2|0}}}c[j>>2]=k+t;n=c[r+12>>2]|0;o=r}if((n|0)==0){s=25;break}else{h=n;f=o}}if((s|0)==25){i=a;return}}function $c(d){d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;e=i;i=i+48|0;f=e;g=e+30|0;h=e+28|0;j=e+26|0;k=e+24|0;l=e+16|0;m=e+12|0;n=e+20|0;a[g+0>>0]=0;a[g+1>>0]=0;a[g+2>>0]=0;a[g+3>>0]=0;a[g+4>>0]=0;o=Pb(d|0,11936)|0;if((o|0)==0){Ja(9552)|0;p=0;i=e;return p|0}ra(g|0,4,1,o|0)|0;if((a[g>>0]|0)==82){d=g;q=9304;do{d=d+1|0;q=q+1|0;r=a[d>>0]|0;s=a[q>>0]|0}while(!((r<<24>>24==0?1:r<<24>>24!=s<<24>>24)|s<<24>>24==0));if(r<<24>>24==s<<24>>24){Cb(o|0,4,1)|0;ra(g|0,4,1,o|0)|0;if((a[g>>0]|0)==87){s=g;r=9312;do{s=s+1|0;r=r+1|0;t=a[s>>0]|0;u=a[r>>0]|0}while(!((t<<24>>24==0?1:t<<24>>24!=u<<24>>24)|u<<24>>24==0));if(t<<24>>24==u<<24>>24){ra(g|0,1,4,o|0)|0;ra(l|0,1,4,o|0)|0;u=c[l>>2]|0;if((u|0)<14){Ja(9672)|0;Fb(o|0)|0;p=0;i=e;return p|0}ra(h|0,1,2,o|0)|0;if((b[h>>1]|0)!=1){Ja(9632)|0;Fb(o|0)|0;p=0;i=e;return p|0}ra(j|0,1,2,o|0)|0;ra(m|0,1,4,o|0)|0;Cb(o|0,2,1)|0;Cb(o|0,2,1)|0;ra(k|0,1,2,o|0)|0;Cb(o|0,u+ -14|0,1)|0;u=c[m>>2]|0;m=b[j>>1]|0;j=b[k>>1]|0;if((u|0)==44100&m<<16>>16==1){if(j<<16>>16==2){a:do{if((ra(g|0,1,4,o|0)|0)>=4){do{if((a[g>>0]|0)==100){k=g;h=9400;do{k=k+1|0;h=h+1|0;v=a[k>>0]|0;w=a[h>>0]|0}while(!((v<<24>>24==0?1:v<<24>>24!=w<<24>>24)|w<<24>>24==0));if(v<<24>>24==w<<24>>24){break a}}ra(n|0,1,4,o|0)|0;Cb(o|0,c[n>>2]|0,1)|0}while((ra(g|0,1,4,o|0)|0)>=4)}}while(0);if((a[g>>0]|0)==100){w=g;g=9400;do{w=w+1|0;g=g+1|0;x=a[w>>0]|0;y=a[g>>0]|0}while(!((x<<24>>24==0?1:x<<24>>24!=y<<24>>24)|y<<24>>24==0));if(x<<24>>24==y<<24>>24){ra(n|0,1,4,o|0)|0;y=c[n>>2]|0;n=Pd(y)|0;ra(n|0,y|0,1,o|0)|0;Fb(o|0)|0;x=Pd(28)|0;c[x>>2]=44100;c[x+4>>2]=1;c[x+20>>2]=n;c[x+12>>2]=2;c[x+8>>2]=0;c[x+16>>2]=(y|0)/2|0;c[x+24>>2]=c[2316];c[2316]=x;p=x;i=e;return p|0}}Ja(9592)|0;Fb(o|0)|0;p=0;i=e;return p|0}else{z=1;A=j}}else{z=m;A=j}c[f>>2]=u;c[f+4>>2]=z<<16>>16;c[f+8>>2]=A<<16>>16;eb(9320,f|0)|0;Fb(o|0)|0;p=0;i=e;return p|0}}Ja(9712)|0;Fb(o|0)|0;p=0;i=e;return p|0}}Ja(9752)|0;Fb(o|0)|0;p=0;i=e;return p|0}function ad(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0.0,o=0.0,p=0.0;e=i;f=c[a>>2]|0;if((f|0)!=0){g=c[f>>2]|0;h=c[f+4>>2]|0;j=(c[g+4>>2]|0)+b|0;k=c[1284]|0;l=(c[g+8>>2]|0)+d|0;m=k-(c[g+16>>2]|0)-l|0;n=1.0/+(c[g+12>>2]|0);o=+(h|0);p=o*+(((c[a+12>>2]|0)/(c[f+16>>2]|0)|0|0)%(c[f+12>>2]|0)|0|0)*n;if((c[1280]|0)!=(g|0)){Sc();c[1280]=g}Lc(c[1278]|0,+(j|0),+(k-l|0),p,+(j+h|0),+(m|0),o*n+p);i=e;return}m=c[a+4>>2]|0;if((m|0)==0){i=e;return}a=(c[m+4>>2]|0)+b|0;b=(c[1284]|0)-((c[m+8>>2]|0)+d)|0;p=+((c[m+12>>2]|0)+a|0);n=+(b-(c[m+16>>2]|0)|0);if((c[1280]|0)!=(m|0)){Sc();c[1280]=m}Lc(c[1278]|0,+(a|0),+(b|0),0.0,p,n,1.0);i=e;return}function bd(a){a=a|0;var b=0,d=0,e=0,f=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0.0,E=0.0,F=0.0,G=0.0,H=0.0;b=i;d=c[2448]|0;if((d|0)==0){e=Pd(216)|0}else{c[2448]=c[d+212>>2];e=d}d=e+4|0;c[d>>2]=0;f=e+16|0;h=e+32|0;c[f+0>>2]=0;c[f+4>>2]=0;c[f+8>>2]=0;c[f+12>>2]=0;c[h>>2]=9;f=e+36|0;c[f>>2]=1;j=e+40|0;k=e+68|0;c[j+0>>2]=0;c[j+4>>2]=0;c[j+8>>2]=0;c[j+12>>2]=0;c[j+16>>2]=0;g[k>>2]=1.0;l=e+72|0;g[l>>2]=1.0;m=e+76|0;g[m>>2]=1.0;n=e+80|0;g[n>>2]=1.0;o=e+84|0;p=e+104|0;q=e+108|0;r=e+116|0;c[r>>2]=0;s=e+132|0;c[o+0>>2]=0;c[o+4>>2]=0;c[o+8>>2]=0;c[o+12>>2]=0;c[o+16>>2]=0;c[o+20>>2]=0;c[o+24>>2]=0;g[s>>2]=1.0;t=e+128|0;g[t>>2]=1.0;u=e+124|0;g[u>>2]=1.0;v=e+120|0;g[v>>2]=1.0;w=e+148|0;g[w>>2]=1.0;x=e+144|0;g[x>>2]=1.0;y=e+140|0;g[y>>2]=1.0;z=e+136|0;g[z>>2]=1.0;A=e+152|0;c[e+212>>2]=0;B=A+0|0;C=B+44|0;do{c[B>>2]=0;B=B+4|0}while((B|0)<(C|0));c[e>>2]=a;c[d>>2]=c[a+4>>2];d=e+24|0;g[d>>2]=+g[a+24>>2];B=e+28|0;g[B>>2]=+g[a+28>>2];c[h>>2]=c[a+32>>2];c[f>>2]=c[a+36>>2];g[j>>2]=+g[a+40>>2];j=e+52|0;g[j>>2]=+g[a+52>>2];f=e+56|0;g[f>>2]=+g[a+56>>2];g[k>>2]=+g[a+68>>2];g[l>>2]=+g[a+72>>2];D=+g[a+76>>2];g[m>>2]=D;g[n>>2]=+g[a+80>>2];g[o>>2]=+g[a+84>>2];g[e+88>>2]=+g[a+88>>2];g[e+92>>2]=+g[a+92>>2];g[e+96>>2]=+g[a+96>>2];g[e+100>>2]=+g[a+100>>2];c[q>>2]=c[a+108>>2];c[p>>2]=c[a+104>>2];c[r>>2]=c[a+116>>2];g[v>>2]=+g[a+120>>2];g[u>>2]=+g[a+124>>2];g[t>>2]=+g[a+128>>2];g[s>>2]=+g[a+132>>2];g[z>>2]=+g[a+136>>2];g[y>>2]=+g[a+140>>2];g[x>>2]=+g[a+144>>2];g[w>>2]=+g[a+148>>2];w=c[a+152>>2]|0;c[A>>2]=w;c[e+156>>2]=c[a+156>>2];c[e+160>>2]=c[a+160>>2];c[e+164>>2]=c[a+164>>2];c[e+168>>2]=c[a+168>>2];c[e+172>>2]=c[a+172>>2];c[e+176>>2]=c[a+176>>2];c[e+180>>2]=c[a+180>>2];c[e+184>>2]=c[a+184>>2];c[e+188>>2]=c[a+188>>2];c[e+192>>2]=c[a+192>>2];E=+g[k>>2];F=(D>E?D:E)*.5+10.0;D=+g[l>>2];G=(D>E?D:E)*.5+10.0;E=+g[j>>2];D=+g[d>>2];H=E+D;if(E>0.0){g[e+196>>2]=H+G;g[e+200>>2]=D-G}else{g[e+200>>2]=H-G;g[e+196>>2]=D+G}G=+g[f>>2];D=+g[B>>2];H=G+D;if(G>0.0){g[e+204>>2]=F+H;g[e+208>>2]=D-F}else{g[e+208>>2]=H-F;g[e+204>>2]=F+D}if((w|0)==0){i=b;return e|0}xc[w&7](e);i=b;return e|0}function cd(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0.0,p=0.0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0.0,F=0,G=0,H=0,I=0,J=0,K=0,L=0.0,M=0.0,N=0.0,O=0.0,P=0.0,R=0.0,S=0.0,T=0.0,U=0.0,V=0.0,W=0.0,X=0,Y=0,Z=0,_=0,$=0;e=i;i=i+48|0;f=e+40|0;h=e;j=e+8|0;k=e+16|0;l=e+24|0;m=e+32|0;n=(c[b+32>>2]|c[a+32>>2])&6;if((n|0)==2){o=+g[a+80>>2];p=+g[b+80>>2];if(!(o<=0.0&p>0.0)){if(p<=0.0&o>0.0){q=a;r=b}else{s=0;i=e;return s|0}}else{q=b;r=a}g[h>>2]=0.0;t=h+4|0;g[t>>2]=-1.0;o=(+g[q+76>>2]+ +g[r+76>>2])*.5;g[j>>2]=+g[r+24>>2]+o*0.0;g[j+4>>2]=+g[r+28>>2]+o*-1.0;if((Kc(q+24|0,q+52|0,h,j,+g[r+72>>2]+ +g[q+72>>2],f)|0)==0){s=0;i=e;return s|0}o=+g[f>>2];if((d|0)==0){s=1;i=e;return s|0}j=c[d>>2]|0;u=c[2450]|0;if((u|0)==0){v=Pd(32)|0}else{c[2450]=c[u+28>>2];v=u}u=v+28|0;c[u>>2]=0;c[v>>2]=2;c[v+4>>2]=q;c[v+8>>2]=r;g[v+12>>2]=o;g[v+16>>2]=+g[h>>2];g[v+20>>2]=+g[t>>2];c[v+24>>2]=1;if((j|0)!=0){t=j;j=0;while(1){if(!(+g[t+12>>2]>2]|0;if((r|0)==0){w=0;x=t;break}else{q=t;t=r;j=q}}if((x|0)==0){y=w;z=13}else{c[x+28>>2]=v;A=w}}else{y=0;z=13}if((z|0)==13){c[d>>2]=v;A=y}c[u>>2]=A;s=1;i=e;return s|0}else if((n|0)==4){o=+g[a+80>>2];p=+g[b+80>>2];if(!(o<=0.0&p>0.0)){if(p<=0.0&o>0.0){B=a;C=b}else{s=0;i=e;return s|0}}else{B=b;C=a}g[f>>2]=1.0;g[l>>2]=0.0;n=l+4|0;g[n>>2]=-1.0;A=B+76|0;u=C+76|0;o=(+g[A>>2]+ +g[u>>2])*.5;y=C+24|0;g[m>>2]=+g[y>>2]+o*0.0;v=C+28|0;w=m+4|0;g[w>>2]=+g[v>>2]+o*-1.0;x=C+72|0;j=B+72|0;t=B+24|0;q=B+52|0;if((Kc(t,q,l,m,+g[x>>2]+ +g[j>>2],k)|0)!=0?(o=+g[k>>2],o<+g[f>>2]):0){g[h>>2]=+g[l>>2];g[h+4>>2]=+g[n>>2];g[f>>2]=o}g[l>>2]=0.0;g[n>>2]=1.0;o=(+g[A>>2]+ +g[u>>2])*.5;g[m>>2]=+g[y>>2]+o*0.0;g[w>>2]=+g[v>>2]+o;if((Kc(t,q,l,m,+g[x>>2]+ +g[j>>2],k)|0)!=0?(o=+g[k>>2],o<+g[f>>2]):0){g[h>>2]=+g[l>>2];g[h+4>>2]=+g[n>>2];g[f>>2]=o}g[l>>2]=1.0;g[n>>2]=0.0;o=(+g[j>>2]+ +g[x>>2])*.5;g[m>>2]=+g[y>>2]+o;g[w>>2]=+g[v>>2]+o*0.0;if((Kc(t,q,l,m,+g[u>>2]+ +g[A>>2],k)|0)!=0?(o=+g[k>>2],o<+g[f>>2]):0){g[h>>2]=+g[l>>2];g[h+4>>2]=+g[n>>2];g[f>>2]=o;D=0}else{D=1}g[l>>2]=-1.0;g[n>>2]=0.0;o=(+g[j>>2]+ +g[x>>2])*.5;g[m>>2]=+g[y>>2]+o*-1.0;g[w>>2]=+g[v>>2]+o*0.0;if((Kc(t,q,l,m,+g[u>>2]+ +g[A>>2],k)|0)!=0){o=+g[k>>2];p=+g[f>>2];if(o>2]=+g[l>>2];g[h+4>>2]=+g[n>>2];g[f>>2]=o;E=o;F=0}else{E=p;F=D}}else{E=+g[f>>2];F=D}if(!(E<1.0)){s=0;i=e;return s|0}if((d|0)==0){s=1;i=e;return s|0}D=c[d>>2]|0;n=c[2450]|0;if((n|0)==0){G=Pd(32)|0}else{c[2450]=c[n+28>>2];G=n}n=G+28|0;c[n>>2]=0;c[G>>2]=2;c[G+4>>2]=B;c[G+8>>2]=C;g[G+12>>2]=E;g[G+16>>2]=+g[h>>2];g[G+20>>2]=+g[h+4>>2];c[G+24>>2]=F;if((D|0)!=0){F=D;D=0;while(1){if(!(+g[F+12>>2]>2]|0;if((C|0)==0){H=0;I=F;break}else{B=F;F=C;D=B}}if((I|0)==0){J=H;z=40}else{c[I+28>>2]=G;K=H}}else{J=0;z=40}if((z|0)==40){c[d>>2]=G;K=J}c[n>>2]=K;s=1;i=e;return s|0}else{E=+g[a+52>>2]- +g[b+52>>2];p=+g[a+56>>2]- +g[b+56>>2];o=+g[a+68>>2]+ +g[b+68>>2];L=+g[a+24>>2];M=L-o;N=o+L;if(E>0.0){O=N+E;P=M}else{O=N;P=M+E}M=+g[b+24>>2];if(MO){s=0;i=e;return s|0}O=+g[a+28>>2];P=O-o;N=o+O;if(p>0.0){R=N+p;S=P}else{R=N;S=P+p}P=+g[b+28>>2];if(PR){s=0;i=e;return s|0}R=1.0/o;o=R*E;S=R*p;N=o*o+S*S;if(N==0.0){s=0;i=e;return s|0}T=R*L-R*M;U=R*O-P*R;V=(S*U+o*T)*2.0;o=V*V-N*4.0*(U*U+T*T+-1.0);if(o<0.0){s=0;i=e;return s|0}T=N*2.0;if(T==0.0){s=0;i=e;return s|0}N=+Q(+o);o=(-V-N)/T;U=(N-V)/T;if(o>=-0.0?o=-0.0)){s=0;i=e;return s|0}if(o>U&U<=1.0){W=U}else{s=0;i=e;return s|0}}g[f>>2]=W;U=R*(W*E+L-M);g[h>>2]=U;M=R*(W*p+O-P);g[h+4>>2]=M;if((d|0)==0){s=1;i=e;return s|0}h=c[d>>2]|0;f=c[2450]|0;if((f|0)==0){X=Pd(32)|0}else{c[2450]=c[f+28>>2];X=f}f=X+28|0;c[f>>2]=0;c[X>>2]=1;c[X+4>>2]=a;c[X+8>>2]=b;g[X+12>>2]=W;g[X+16>>2]=U;g[X+20>>2]=M;c[X+24>>2]=0;if((h|0)!=0){b=h;h=0;while(1){if(!(+g[b+12>>2]>2]|0;if((a|0)==0){Y=0;Z=b;break}else{K=b;b=a;h=K}}if((Z|0)==0){_=Y;z=66}else{c[Z+28>>2]=X;$=Y}}else{_=0;z=66}if((z|0)==66){c[d>>2]=X;$=_}c[f>>2]=$;s=1;i=e;return s|0}return 0}function dd(a,b,c,d){a=a|0;b=b|0;c=+c;d=d|0;var e=0,f=0,h=0.0,j=0,k=0.0,l=0.0,m=0,n=0.0,o=0.0,p=0.0,q=0.0,r=0,s=0,t=0,u=0.0;e=i;c=+g[a+80>>2];do{if(c>0.0){f=b+80|0;h=+g[f>>2];if(!(h>0.0)){if(!(h<=0.0)){break}j=a+52|0;k=+g[j>>2];l=+g[d>>2];m=a+56|0;n=+g[m>>2];o=+g[d+4>>2];p=(+g[a+84>>2]+1.0)*(k*l+n*o);q=k-l*p;g[j>>2]=q;l=n-o*p;g[m>>2]=l;p=+g[a+76>>2];o=+g[a+68>>2];n=(p>o?p:o)*.5+10.0;p=+g[a+72>>2];k=(p>o?p:o)*.5+10.0;o=+g[a+24>>2];p=q+o;if(q>0.0){g[a+196>>2]=p+k;g[a+200>>2]=o-k}else{g[a+200>>2]=p-k;g[a+196>>2]=o+k}k=+g[a+28>>2];o=l+k;if(l>0.0){g[a+204>>2]=n+o;g[a+208>>2]=k-n;i=e;return}else{g[a+208>>2]=o-n;g[a+204>>2]=n+k;i=e;return}}k=c+h;m=a+52|0;n=+g[m>>2];o=+g[d>>2];j=a+56|0;l=+g[j>>2];r=d+4|0;p=+g[r>>2];q=+P(+(n*o+l*p));s=b+52|0;t=b+56|0;u=h*c*((c*+g[a+84>>2]+h*+g[b+84>>2])/k+1.0)*(q+ +P(+(o*+g[s>>2]+p*+g[t>>2])))/k;k=u/c;q=n-o*k;g[m>>2]=q;o=l-p*k;g[j>>2]=o;k=+g[a+76>>2];p=+g[a+68>>2];l=(k>p?k:p)*.5+10.0;k=+g[a+72>>2];n=(k>p?k:p)*.5+10.0;p=+g[a+24>>2];k=q+p;if(q>0.0){g[a+196>>2]=k+n;g[a+200>>2]=p-n}else{g[a+200>>2]=k-n;g[a+196>>2]=p+n}n=+g[a+28>>2];p=o+n;if(o>0.0){g[a+204>>2]=l+p;g[a+208>>2]=n-l}else{g[a+208>>2]=p-l;g[a+204>>2]=l+n}n=u/+g[f>>2];u=n*+g[r>>2];l=+g[d>>2]*n+ +g[s>>2];g[s>>2]=l;n=u+ +g[t>>2];g[t>>2]=n;u=+g[b+76>>2];p=+g[b+68>>2];o=(u>p?u:p)*.5+10.0;u=+g[b+72>>2];k=(u>p?u:p)*.5+10.0;p=+g[b+24>>2];u=l+p;if(l>0.0){g[b+196>>2]=u+k;g[b+200>>2]=p-k}else{g[b+200>>2]=u-k;g[b+196>>2]=p+k}k=+g[b+28>>2];p=n+k;if(n>0.0){g[b+204>>2]=o+p;g[b+208>>2]=k-o;i=e;return}else{g[b+208>>2]=p-o;g[b+204>>2]=o+k;i=e;return}}}while(0);if(c<=0.0?+g[b+80>>2]>0.0:0){t=b+52|0;c=+g[t>>2];k=+g[d>>2];s=b+56|0;o=+g[s>>2];p=+g[d+4>>2];n=(+g[b+84>>2]+1.0)*(c*k+o*p);u=c+k*n;g[t>>2]=u;k=o+p*n;g[s>>2]=k;n=+g[b+76>>2];p=+g[b+68>>2];o=(n>p?n:p)*.5+10.0;n=+g[b+72>>2];c=(n>p?n:p)*.5+10.0;p=+g[b+24>>2];n=u+p;if(u>0.0){g[b+196>>2]=n+c;g[b+200>>2]=p-c}else{g[b+200>>2]=n-c;g[b+196>>2]=p+c}c=+g[b+28>>2];p=k+c;if(k>0.0){g[b+204>>2]=o+p;g[b+208>>2]=c-o;i=e;return}else{g[b+208>>2]=p-o;g[b+204>>2]=o+c;i=e;return}}g[a+52>>2]=0.0;g[a+56>>2]=0.0;c=+g[a+76>>2];o=+g[a+68>>2];p=(c>o?c:o)*.5+10.0;c=+g[a+72>>2];k=(c>o?c:o)*.5+10.0;o=+g[a+24>>2];g[a+200>>2]=o+0.0-k;g[a+196>>2]=o+k;k=+g[a+28>>2];g[a+208>>2]=k+0.0-p;g[a+204>>2]=p+k;g[b+52>>2]=0.0;g[b+56>>2]=0.0;k=+g[b+76>>2];p=+g[b+68>>2];o=(k>p?k:p)*.5+10.0;k=+g[b+72>>2];c=(k>p?k:p)*.5+10.0;p=+g[b+24>>2];g[b+200>>2]=p+0.0-c;g[b+196>>2]=p+c;c=+g[b+28>>2];g[b+208>>2]=c+0.0-o;g[b+204>>2]=o+c;i=e;return}function ed(a,b,c,d){a=a|0;b=+b;c=+c;d=+d;var e=0,f=0.0,h=0.0,j=0.0,k=0,l=0,m=0.0,n=0.0,o=0.0,p=0.0;e=i;f=+Q(+(b*b+c*c));h=1.0/f;j=h*b;b=h*c;k=a+52|0;c=+g[k>>2];l=a+56|0;h=+g[l>>2];m=c*j+b*h;if(mf?f:n;n=c+j*m;g[k>>2]=n;j=b*m+h;g[l>>2]=j;o=n;p=j}else{o=c;p=h}h=+g[a+76>>2];c=+g[a+68>>2];j=(h>c?h:c)*.5+10.0;h=+g[a+72>>2];n=(h>c?h:c)*.5+10.0;c=+g[a+24>>2];h=o+c;if(o>0.0){g[a+196>>2]=h+n;g[a+200>>2]=c-n}else{g[a+200>>2]=h-n;g[a+196>>2]=c+n}n=+g[a+28>>2];c=p+n;if(p>0.0){g[a+204>>2]=j+c;g[a+208>>2]=n-j;i=e;return}else{g[a+208>>2]=c-j;g[a+204>>2]=j+n;i=e;return}}function fd(a){a=a|0;var b=0,d=0,e=0,f=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0.0,t=0.0,u=0.0,v=0.0,w=0.0,x=0.0,y=0.0,z=0.0,A=0.0;b=i;d=c[2456]|0;e=c[2458]|0;if((d|0)<(e|0)){f=c[2452]|0;h=d;j=c[2454]|0;k=d}else{l=(e|0)==0?32:e<<1;c[2458]=l;e=l<<2;l=Pd(e)|0;m=Pd(e)|0;e=c[2452]|0;if((d|0)<=0){if((e|0)==0){n=d;o=c[2456]|0}else{p=8}}else{q=c[2454]|0;r=0;do{c[l+(r<<2)>>2]=c[e+(r<<2)>>2];c[m+(r<<2)>>2]=c[q+(r<<2)>>2];r=r+1|0}while((r|0)<(d|0));p=8}if((p|0)==8){Qd(e);Qd(c[2454]|0);e=c[2456]|0;n=e;o=e}c[2452]=l;c[2454]=m;f=l;h=n;j=m;k=o}c[f+(h<<2)>>2]=a;c[j+(h<<2)>>2]=1;h=k+1|0;c[2456]=h;j=a+32|0;o=c[j>>2]|0;if((o&16|0)!=0){s=+g[a+24>>2];t=+g[a+8>>2];m=s>2];v=(m?s:t)-u;w=u+(m?t:s);t=+g[a+28>>2];x=+g[a+12>>2];m=t-1){k=0;do{m=c[f+(k<<2)>>2]|0;t=+g[m+24>>2];if(!(!(v<=t)|!(w>=t))?(t=+g[m+28>>2],!(!(y<=t)|!(z>=t))):0){n=m+32|0;c[n>>2]=c[n>>2]|32}k=k+1|0}while((k|0)!=(h|0));A=s}else{A=s}}else{c[j>>2]=o|32;A=+g[a+24>>2]}s=+g[a+76>>2];z=+g[a+68>>2];y=(s>z?s:z)*.5+10.0;s=+g[a+72>>2];w=(s>z?s:z)*.5+10.0;z=+g[a+52>>2];s=z+A;if(z>0.0){g[a+196>>2]=s+w;g[a+200>>2]=A-w}else{g[a+200>>2]=s-w;g[a+196>>2]=w+A}A=+g[a+56>>2];w=+g[a+28>>2];s=A+w;if(A>0.0){g[a+204>>2]=y+s;g[a+208>>2]=w-y;i=b;return}else{g[a+208>>2]=s-y;g[a+204>>2]=y+w;i=b;return}}function gd(a){a=a|0;var b=0,d=0,e=0,f=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0.0,p=0.0,q=0.0,r=0.0,s=0.0,t=0.0,u=0.0,v=0;b=i;d=c[2456]|0;if((d|0)<=0){e=0;i=b;return e|0}f=c[2452]|0;h=0;while(1){j=f+(h<<2)|0;k=h+1|0;if((c[j>>2]|0)==(a|0)){break}if((k|0)<(d|0)){h=k}else{e=0;l=21;break}}if((l|0)==21){i=b;return e|0}l=(c[2460]|0)==0;if(l){c[j>>2]=0;k=c[2454]|0;c[k+(h<<2)>>2]=0;m=k}else{k=c[2454]|0;c[k+(h<<2)>>2]=-2;m=k}c[2462]=1;k=a+32|0;n=c[k>>2]|0;if((n&16|0)==0){c[k>>2]=n|32}else{o=+g[a+24>>2];p=+g[a+8>>2];n=o>2];r=(n?o:p)-q;s=q+(n?p:o);o=+g[a+28>>2];p=+g[a+12>>2];n=o>2]|0;o=+g[k+24>>2];if(!(!(r<=o)|!(s>=o))?(o=+g[k+28>>2],!(!(t<=o)|!(u>=o))):0){v=k+32|0;c[v>>2]=c[v>>2]|32}n=n+1|0}while((n|0)!=(d|0))}if((h|0)==-1){e=0;i=b;return e|0}if(!l){c[j>>2]=a;c[m+(h<<2)>>2]=-1;e=1;i=b;return e|0}h=c[a+156>>2]|0;if((h|0)!=0){xc[h&7](a)}c[a+212>>2]=c[2448];c[2448]=a;e=1;i=b;return e|0}function hd(a){a=a|0;var b=0,d=0,e=0,f=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,F=0,G=0,H=0.0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,R=0,S=0,T=0,U=0,V=0,W=0.0,X=0.0,Y=0.0,Z=0.0,_=0.0,$=0.0,aa=0.0,ba=0.0,ca=0.0,da=0.0,ea=0.0,fa=0.0,ga=0.0,ha=0.0,ia=0.0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Fa=0,Ga=0,Ha=0.0,Ia=0.0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Ua=0,Va=0,Wa=0,Xa=0,Ya=0,Za=0,_a=0,$a=0,ab=0,bb=0,cb=0,db=0,eb=0,fb=0,gb=0,hb=0,ib=0,jb=0,kb=0,lb=0,mb=0;a=i;i=i+32|0;b=a+24|0;d=a;e=a+8|0;f=a+16|0;c[2476]=c[2480];c[2478]=c[2482];nb(e|0,0)|0;h=c[e>>2]|0;j=qe(h|0,((h|0)<0)<<31>>31|0,1e6,0)|0;h=c[e+4>>2]|0;k=ee(j|0,E|0,h|0,((h|0)<0)<<31>>31|0)|0;h=E;j=c[2456]|0;if((c[2462]|0)==0){l=j}else{if((j|0)>0){m=j;j=0;n=0;while(1){o=c[2452]|0;p=c[o+(j<<2)>>2]|0;do{if((p|0)!=0){q=c[2454]|0;r=c[q+(j<<2)>>2]|0;if((r|0)==-1){s=c[p+156>>2]|0;if((s|0)==0){t=m}else{xc[s&7](p);t=c[2456]|0}c[p+212>>2]=c[2448];c[2448]=p;u=t;v=n;break}else if((r|0)==-2){u=m;v=n;break}else{if((j|0)>(n|0)){c[o+(n<<2)>>2]=p;c[q+(n<<2)>>2]=r}u=m;v=n+1|0;break}}else{u=m;v=n}}while(0);j=j+1|0;if((j|0)>=(u|0)){w=v;break}else{m=u;n=v}}}else{w=0}c[2456]=w;c[2462]=0;c[2460]=0;l=w}c[2460]=1;if((l|0)>0){w=l;l=0;while(1){v=c[(c[2452]|0)+(l<<2)>>2]|0;if((v|0)!=0?(n=c[2484]|0,u=v+32|0,c[u>>2]=c[u>>2]&-65,u=c[v+160>>2]|0,(u|0)!=0):0){yc[u&15](v,n);x=c[2456]|0}else{x=w}l=l+1|0;if((l|0)>=(x|0)){break}else{w=x}}if((c[2462]|0)!=0){if((x|0)>0){w=x;x=0;l=0;while(1){n=c[2452]|0;v=c[n+(x<<2)>>2]|0;do{if((v|0)!=0){u=c[2454]|0;m=c[u+(x<<2)>>2]|0;if((m|0)==-1){j=c[v+156>>2]|0;if((j|0)==0){y=w}else{xc[j&7](v);y=c[2456]|0}c[v+212>>2]=c[2448];c[2448]=v;z=y;A=l;break}else if((m|0)==-2){z=w;A=l;break}else{if((x|0)>(l|0)){c[n+(l<<2)>>2]=v;c[u+(l<<2)>>2]=m}z=w;A=l+1|0;break}}else{z=w;A=l}}while(0);x=x+1|0;if((x|0)>=(z|0)){B=A;break}else{w=z;l=A}}}else{B=0}c[2456]=B;c[2462]=0;c[2460]=0}}nb(e|0,0)|0;B=c[e>>2]|0;A=qe(B|0,((B|0)<0)<<31>>31|0,1e6,0)|0;B=c[e+4>>2]|0;l=ee(A|0,E|0,B|0,((B|0)<0)<<31>>31|0)|0;B=de(l|0,E|0,k|0,h|0)|0;h=9944;k=ee(B|0,E|0,c[h>>2]|0,c[h+4>>2]|0)|0;h=9944;c[h>>2]=k;c[h+4>>2]=E;nb(e|0,0)|0;h=c[e>>2]|0;k=qe(h|0,((h|0)<0)<<31>>31|0,1e6,0)|0;h=c[e+4>>2]|0;e=ee(k|0,E|0,h|0,((h|0)<0)<<31>>31|0)|0;h=E;if((c[2462]|0)!=0){k=c[2456]|0;if((k|0)>0){B=k;k=0;l=0;while(1){A=c[2452]|0;z=c[A+(k<<2)>>2]|0;do{if((z|0)!=0){w=c[2454]|0;x=c[w+(k<<2)>>2]|0;if((x|0)==-2){C=B;D=l;break}else if((x|0)==-1){y=c[z+156>>2]|0;if((y|0)==0){F=B}else{xc[y&7](z);F=c[2456]|0}c[z+212>>2]=c[2448];c[2448]=z;C=F;D=l;break}else{if((k|0)>(l|0)){c[A+(l<<2)>>2]=z;c[w+(l<<2)>>2]=x}C=B;D=l+1|0;break}}else{C=B;D=l}}while(0);k=k+1|0;if((k|0)>=(C|0)){G=D;break}else{B=C;l=D}}}else{G=0}c[2456]=G;c[2462]=0;c[2460]=0}c[2460]=1;G=b+4|0;D=d+4|0;l=1;while(1){c[f>>2]=0;C=c[2456]|0;a:do{if((C|0)>0){B=C;k=0;while(1){F=c[2452]|0;z=c[F+(k<<2)>>2]|0;b:do{if((c[z+32>>2]&1|0)!=0?!(+g[z+80>>2]<0.0):0){H=+g[z+52>>2];if(!(H<=0.0)|!(H>=-0.0)){if((B|0)>0){I=F;J=B;K=0}else{L=B;break}}else{H=+g[z+56>>2];if((!(H<=0.0)|!(H>=-0.0))&(B|0)>0){I=F;J=B;K=0}else{L=B;break}}while(1){A=c[I+(K<<2)>>2]|0;c:do{if(((((c[A+32>>2]&1|0)!=0?(x=c[I+(k<<2)>>2]|0,+g[x+196>>2]>=+g[A+200>>2]):0)?+g[x+200>>2]<=+g[A+196>>2]:0)?+g[x+204>>2]>=+g[A+208>>2]:0)?+g[x+208>>2]<=+g[A+204>>2]:0){w=c[f>>2]|0;if((w|0)!=0){y=w;do{w=c[y+4>>2]|0;if((w|0)==(x|0)?(c[y+8>>2]|0)==(A|0):0){M=J;break c}if((w|0)==(A|0)?(c[y+8>>2]|0)==(x|0):0){M=J;break c}y=c[y+28>>2]|0}while((y|0)!=0)}cd(x,A,f)|0;M=c[2456]|0}else{M=J}}while(0);A=K+1|0;if((A|0)>=(M|0)){L=M;break b}I=c[2452]|0;J=M;K=A}}else{L=B}}while(0);k=k+1|0;if((k|0)>=(L|0)){break}else{B=L}}B=c[f>>2]|0;if((B|0)!=0){k=B;while(1){N=k+16|0;g[b>>2]=+g[N>>2];O=k+20|0;g[G>>2]=+g[O>>2];g[d>>2]=+g[N>>2]*-1.0;g[D>>2]=+g[O>>2]*-1.0;R=k+4|0;B=c[R>>2]|0;F=c[B+168>>2]|0;S=k+8|0;if((F|0)==0){T=1}else{z=wc[F&3](B,c[S>>2]|0,+g[k+12>>2],b)|0;T=(z|0)>1?2:(z|0)!=0&1}z=c[S>>2]|0;B=c[z+168>>2]|0;if((B|0)==0){U=T}else{F=wc[B&3](z,c[R>>2]|0,+g[k+12>>2],d)|0;U=(F|0)>1?2:(F|0)==0?0:T}if((U|0)==1){break}else if((U|0)==2){V=1;break a}F=c[k+28>>2]|0;if((F|0)==0){V=0;break a}else{k=F}}F=c[k>>2]|0;if((F|0)==1){z=c[R>>2]|0;H=+g[z+52>>2];W=+g[z+56>>2];B=c[S>>2]|0;X=+g[B+52>>2];Y=+g[B+56>>2];if(H*H+W*W>X*X+Y*Y){dd(z,B,0.0,d);V=1;break}else{dd(B,z,0.0,b);V=1;break}}else if((F|0)!=2){V=1;break}F=c[R>>2]|0;z=c[S>>2]|0;Y=+g[k+12>>2];X=(+g[F+96>>2]+ +g[z+96>>2])*.5;W=(+g[F+100>>2]+ +g[z+100>>2])*.5;z=F+52|0;H=+g[z>>2];Z=1.0-Y;B=F+56|0;_=+g[B>>2];$=+g[N>>2];aa=+g[O>>2];ba=-(Z*H*$+Z*_*aa);Z=+g[F+24>>2];ca=+g[F+28>>2];da=H+Z+$*ba;ea=_+ca+aa*ba;ba=H*Y+Z;H=_*Y+ca;do{if((c[k+24>>2]|0)!=0){Y=da-ba;_=ea-H;fa=+Q(+(Y*Y+_*_));if(!(fa0.0){ga=1.0-(W+X/fa);ha=ba+Y*ga;ia=H+_*ga;break}else{ga=1.0-W;ha=ba+ga*Y;ia=H+ga*_;break}}else{ha=ba;ia=H}}else{ha=da;ia=ea}}while(0);ea=ha+$*.10000000149011612-Z;g[z>>2]=ea;da=ia+aa*.10000000149011612-ca;g[B>>2]=da;H=+g[F+76>>2];ba=+g[F+68>>2];W=(H>ba?H:ba)*.5+10.0;H=+g[F+72>>2];X=(H>ba?H:ba)*.5+10.0;ba=ea+Z;if(ea>0.0){g[F+196>>2]=ba+X;g[F+200>>2]=Z-X}else{g[F+200>>2]=ba-X;g[F+196>>2]=Z+X}X=da+ca;if(da>0.0){g[F+204>>2]=W+X;g[F+208>>2]=ca-W;V=1;break}else{g[F+208>>2]=X-W;g[F+204>>2]=W+ca;V=1;break}}else{V=0}}else{V=0}}while(0);C=c[f>>2]|0;if((C|0)!=0){k=c[2450]|0;A=C;while(1){C=A+28|0;y=c[C>>2]|0;c[C>>2]=k;c[2450]=A;if((y|0)==0){break}else{C=A;A=y;k=C}}c[f>>2]=0}if(!(V&(l|0)<50)){break}l=l+1|0}if((l|0)==10?(l=c[2456]|0,(l|0)>0):0){V=l;l=0;while(1){f=c[2452]|0;O=c[f+(l<<2)>>2]|0;d:do{if((c[O+32>>2]&1|0)!=0?(V|0)>0?!(+g[O+80>>2]<0.0):0:0){N=f;S=0;while(1){R=c[N+(S<<2)>>2]|0;if(!((l|0)==(S|0)?1:(c[R+32>>2]&1|0)==0)?(cd(c[N+(l<<2)>>2]|0,R,0)|0)!=0:0){R=c[2452]|0;d=c[R+(l<<2)>>2]|0;g[d+52>>2]=0.0;g[d+56>>2]=0.0;ia=+g[d+76>>2];ha=+g[d+68>>2];W=(ia>ha?ia:ha)*.5+10.0;ia=+g[d+72>>2];X=(ia>ha?ia:ha)*.5+10.0;ha=+g[d+24>>2];g[d+200>>2]=ha+0.0-X;g[d+196>>2]=X+ha;ha=+g[d+28>>2];g[d+208>>2]=ha+0.0-W;g[d+204>>2]=W+ha;d=c[R+(S<<2)>>2]|0;g[d+52>>2]=0.0;g[d+56>>2]=0.0;ha=+g[d+76>>2];W=+g[d+68>>2];X=(ha>W?ha:W)*.5+10.0;ha=+g[d+72>>2];ia=(ha>W?ha:W)*.5+10.0;W=+g[d+24>>2];g[d+200>>2]=W+0.0-ia;g[d+196>>2]=ia+W;W=+g[d+28>>2];g[d+208>>2]=W+0.0-X;g[d+204>>2]=X+W}d=S+1|0;R=c[2456]|0;if((d|0)>=(R|0)){ja=R;break d}N=c[2452]|0;S=d}}else{ja=V}}while(0);l=l+1|0;if((l|0)>=(ja|0)){break}else{V=ja}}}if((c[2462]|0)!=0){ja=c[2456]|0;if((ja|0)>0){V=ja;ja=0;l=0;while(1){f=c[2452]|0;O=c[f+(ja<<2)>>2]|0;do{if((O|0)!=0){S=c[2454]|0;N=c[S+(ja<<2)>>2]|0;if((N|0)==-1){F=c[O+156>>2]|0;if((F|0)==0){ka=V}else{xc[F&7](O);ka=c[2456]|0}c[O+212>>2]=c[2448];c[2448]=O;la=ka;ma=l;break}else if((N|0)==-2){la=V;ma=l;break}else{if((ja|0)>(l|0)){c[f+(l<<2)>>2]=O;c[S+(l<<2)>>2]=N}la=V;ma=l+1|0;break}}else{la=V;ma=l}}while(0);ja=ja+1|0;if((ja|0)>=(la|0)){na=ma;break}else{V=la;l=ma}}}else{na=0}c[2456]=na;c[2462]=0;c[2460]=0}nb(b|0,0)|0;na=c[b>>2]|0;ma=qe(na|0,((na|0)<0)<<31>>31|0,1e6,0)|0;na=c[b+4>>2]|0;l=ee(ma|0,E|0,na|0,((na|0)<0)<<31>>31|0)|0;na=de(l|0,E|0,e|0,h|0)|0;h=9952;e=ee(na|0,E|0,c[h>>2]|0,c[h+4>>2]|0)|0;h=9952;c[h>>2]=e;c[h+4>>2]=E;nb(b|0,0)|0;h=c[b>>2]|0;e=qe(h|0,((h|0)<0)<<31>>31|0,1e6,0)|0;h=c[b+4>>2]|0;na=ee(e|0,E|0,h|0,((h|0)<0)<<31>>31|0)|0;h=E;e=c[2456]|0;if((c[2462]|0)==0){oa=e}else{if((e|0)>0){l=e;e=0;ma=0;while(1){la=c[2452]|0;V=c[la+(e<<2)>>2]|0;do{if((V|0)!=0){ja=c[2454]|0;ka=c[ja+(e<<2)>>2]|0;if((ka|0)==-1){O=c[V+156>>2]|0;if((O|0)==0){pa=l}else{xc[O&7](V);pa=c[2456]|0}c[V+212>>2]=c[2448];c[2448]=V;qa=pa;ra=ma;break}else if((ka|0)==-2){qa=l;ra=ma;break}else{if((e|0)>(ma|0)){c[la+(ma<<2)>>2]=V;c[ja+(ma<<2)>>2]=ka}qa=l;ra=ma+1|0;break}}else{qa=l;ra=ma}}while(0);e=e+1|0;if((e|0)>=(qa|0)){sa=ra;break}else{l=qa;ma=ra}}}else{sa=0}c[2456]=sa;c[2462]=0;c[2460]=0;oa=sa}c[2460]=1;if((oa|0)>0){sa=oa;oa=0;while(1){ra=c[2452]|0;ma=c[ra+(oa<<2)>>2]|0;e:do{if((c[ma+32>>2]&8|0)!=0?(sa|0)>0?!(+g[ma+80>>2]<0.0):0:0){qa=ra;l=sa;e=0;while(1){pa=c[qa+(e<<2)>>2]|0;if((oa|0)==(e|0)?1:(c[pa+32>>2]&8|0)==0){ta=l}else{V=c[qa+(oa<<2)>>2]|0;ca=+P(+(+g[V+24>>2]- +g[pa+24>>2]));Z=+P(+(+g[V+28>>2]- +g[pa+28>>2]));la=c[V+172>>2]|0;if((la|0)!=0?(aa=+g[V+68>>2],!(!(ca<=aa)|!(Z<=aa))):0){yc[la&15](V,pa)}la=c[pa+172>>2]|0;if((la|0)!=0?(aa=+g[pa+68>>2],!(!(ca<=aa)|!(Z<=aa))):0){yc[la&15](pa,V)}ta=c[2456]|0}V=e+1|0;if((V|0)>=(ta|0)){ua=ta;break e}qa=c[2452]|0;l=ta;e=V}}else{ua=sa}}while(0);oa=oa+1|0;if((oa|0)>=(ua|0)){break}else{sa=ua}}if((c[2462]|0)!=0){if((ua|0)>0){sa=ua;ua=0;oa=0;while(1){ta=c[2452]|0;ra=c[ta+(ua<<2)>>2]|0;do{if((ra|0)!=0){ma=c[2454]|0;e=c[ma+(ua<<2)>>2]|0;if((e|0)==-1){l=c[ra+156>>2]|0;if((l|0)==0){va=sa}else{xc[l&7](ra);va=c[2456]|0}c[ra+212>>2]=c[2448];c[2448]=ra;wa=va;xa=oa;break}else if((e|0)==-2){wa=sa;xa=oa;break}else{if((ua|0)>(oa|0)){c[ta+(oa<<2)>>2]=ra;c[ma+(oa<<2)>>2]=e}wa=sa;xa=oa+1|0;break}}else{wa=sa;xa=oa}}while(0);ua=ua+1|0;if((ua|0)>=(wa|0)){ya=xa;break}else{sa=wa;oa=xa}}}else{ya=0}c[2456]=ya;c[2462]=0;c[2460]=0}}nb(b|0,0)|0;ya=c[b>>2]|0;xa=qe(ya|0,((ya|0)<0)<<31>>31|0,1e6,0)|0;ya=c[b+4>>2]|0;oa=ee(xa|0,E|0,ya|0,((ya|0)<0)<<31>>31|0)|0;ya=de(oa|0,E|0,na|0,h|0)|0;h=9960;na=ee(ya|0,E|0,c[h>>2]|0,c[h+4>>2]|0)|0;h=9960;c[h>>2]=na;c[h+4>>2]=E;h=c[2456]|0;while(1){if((h|0)<=1){break}na=c[2452]|0;ya=c[na>>2]|0;oa=1;xa=0;while(1){wa=na+(oa+ -1<<2)|0;sa=na+(oa<<2)|0;ua=c[sa>>2]|0;va=c[ya+36>>2]|0;ra=c[ua+36>>2]|0;if((va|0)<=(ra|0)){if((va|0)>=(ra|0)?+g[ya+28>>2]+ +g[ya+40>>2]>+g[ua+28>>2]+ +g[ua+40>>2]:0){za=158}else{Aa=ua;Ba=xa}}else{za=158}if((za|0)==158){za=0;c[sa>>2]=ya;c[wa>>2]=ua;Aa=ya;Ba=oa}oa=oa+1|0;if((oa|0)==(h|0)){break}else{ya=Aa;xa=Ba}}if((Ba|0)>0){h=Ba}else{break}}nb(b|0,0)|0;Ba=c[b>>2]|0;h=qe(Ba|0,((Ba|0)<0)<<31>>31|0,1e6,0)|0;Ba=c[b+4>>2]|0;Aa=ee(h|0,E|0,Ba|0,((Ba|0)<0)<<31>>31|0)|0;Ba=E;h=c[2456]|0;if((c[2462]|0)==0){Ca=h}else{if((h|0)>0){za=h;h=0;xa=0;while(1){ya=c[2452]|0;oa=c[ya+(h<<2)>>2]|0;do{if((oa|0)!=0){na=c[2454]|0;ua=c[na+(h<<2)>>2]|0;if((ua|0)==-1){wa=c[oa+156>>2]|0;if((wa|0)==0){Da=za}else{xc[wa&7](oa);Da=c[2456]|0}c[oa+212>>2]=c[2448];c[2448]=oa;Ea=Da;Fa=xa;break}else if((ua|0)==-2){Ea=za;Fa=xa;break}else{if((h|0)>(xa|0)){c[ya+(xa<<2)>>2]=oa;c[na+(xa<<2)>>2]=ua}Ea=za;Fa=xa+1|0;break}}else{Ea=za;Fa=xa}}while(0);h=h+1|0;if((h|0)>=(Ea|0)){Ga=Fa;break}else{za=Ea;xa=Fa}}}else{Ga=0}c[2456]=Ga;c[2462]=0;c[2460]=0;Ca=Ga}c[2460]=1;if((Ca|0)>0){Ca=c[2452]|0;Ga=0;do{Fa=c[Ca+(Ga<<2)>>2]|0;xa=c[2484]|0;Ea=Fa+24|0;aa=+g[Ea>>2];g[Fa+16>>2]=aa;za=Fa+28|0;Z=+g[za>>2];g[Fa+20>>2]=Z;h=Fa+52|0;ca=+g[h>>2];Da=Fa+56|0;$=+g[Da>>2];W=ca*ca+$*$;do{if(W>0.0){X=ca+aa;g[Ea>>2]=X;ia=Z+$;g[za>>2]=ia;ha=+Q(+W);da=+g[Fa+88>>2];if(ha>2]=0.0;Ha=0.0;Ia=0.0}else{ba=1.0-(+g[Fa+92>>2]+da/ha);ha=ca*ba;g[h>>2]=ha;Ha=$*ba;Ia=ha}g[Da>>2]=Ha;g[Fa+8>>2]=X;g[Fa+12>>2]=ia;oa=Fa+32|0;c[oa>>2]=c[oa>>2]|64;ha=+g[Fa+76>>2];ba=+g[Fa+68>>2];da=(ha>ba?ha:ba)*.5+10.0;ha=+g[Fa+72>>2];ea=(ha>ba?ha:ba)*.5+10.0;ba=Ia+X;if(Ia>0.0){g[Fa+196>>2]=ba+ea;g[Fa+200>>2]=X-ea}else{g[Fa+200>>2]=ba-ea;g[Fa+196>>2]=X+ea}ea=Ha+ia;if(Ha>0.0){g[Fa+204>>2]=da+ea;g[Fa+208>>2]=ia-da;break}else{g[Fa+208>>2]=ea-da;g[Fa+204>>2]=da+ia;break}}}while(0);Da=c[Fa+164>>2]|0;if((Da|0)!=0){yc[Da&15](Fa,xa)}if((c[Fa+104>>2]|0)!=0?(c[Fa+112>>2]|0)==0:0){Da=Fa+116|0;c[Da>>2]=(c[Da>>2]|0)+xa}Ca=c[2452]|0;Da=c[Ca+(Ga<<2)>>2]|0;h=Da+32|0;za=c[h>>2]|0;Ea=c[2456]|0;do{if((za&64|0)!=0){if((za&16|0)==0){c[h>>2]=za|32;Ja=Ea;break}$=+g[Da+24>>2];ca=+g[Da+8>>2];oa=$>2];Z=(oa?$:ca)-W;aa=W+(oa?ca:$);$=+g[Da+28>>2];ca=+g[Da+12>>2];oa=$0){oa=0;do{ya=c[Ca+(oa<<2)>>2]|0;$=+g[ya+24>>2];do{if(!(!(Z<=$)|!(aa>=$))){ca=+g[ya+28>>2];if(!(ia<=ca)|!(da>=ca)){break}ua=ya+32|0;c[ua>>2]=c[ua>>2]|32}}while(0);oa=oa+1|0}while((oa|0)!=(Ea|0));Ja=Ea}else{Ja=Ea}}else{Ja=Ea}}while(0);Ga=Ga+1|0}while((Ga|0)<(Ja|0))}if((c[2466]|0)!=0){Id()}if((c[2462]|0)==0){nb(b|0,0)|0;Ka=c[b>>2]|0;La=(Ka|0)<0;Ma=La<<31>>31;Na=qe(Ka|0,Ma|0,1e6,0)|0;Oa=E;Pa=b+4|0;Qa=c[Pa>>2]|0;Ra=(Qa|0)<0;Sa=Ra<<31>>31;Ta=ee(Na|0,Oa|0,Qa|0,Sa|0)|0;Ua=E;Va=de(Ta|0,Ua|0,Aa|0,Ba|0)|0;Wa=E;Xa=9968;Ya=Xa;Za=c[Ya>>2]|0;_a=Xa+4|0;$a=_a;ab=c[$a>>2]|0;bb=ee(Va|0,Wa|0,Za|0,ab|0)|0;cb=E;db=9968;eb=db;c[eb>>2]=bb;fb=db+4|0;gb=fb;c[gb>>2]=cb;hb=c[2494]|0;ib=hb+1|0;c[2494]=ib;i=a;return}Ja=c[2456]|0;if((Ja|0)>0){Ga=Ja;Ja=0;Ca=0;while(1){Ea=c[2452]|0;Da=c[Ea+(Ja<<2)>>2]|0;do{if((Da|0)!=0){za=c[2454]|0;h=c[za+(Ja<<2)>>2]|0;if((h|0)==-2){jb=Ga;kb=Ca;break}else if((h|0)==-1){xa=c[Da+156>>2]|0;if((xa|0)==0){lb=Ga}else{xc[xa&7](Da);lb=c[2456]|0}c[Da+212>>2]=c[2448];c[2448]=Da;jb=lb;kb=Ca;break}else{if((Ja|0)>(Ca|0)){c[Ea+(Ca<<2)>>2]=Da;c[za+(Ca<<2)>>2]=h}jb=Ga;kb=Ca+1|0;break}}else{jb=Ga;kb=Ca}}while(0);Ja=Ja+1|0;if((Ja|0)>=(jb|0)){mb=kb;break}else{Ga=jb;Ca=kb}}}else{mb=0}c[2456]=mb;c[2462]=0;c[2460]=0;nb(b|0,0)|0;Ka=c[b>>2]|0;La=(Ka|0)<0;Ma=La<<31>>31;Na=qe(Ka|0,Ma|0,1e6,0)|0;Oa=E;Pa=b+4|0;Qa=c[Pa>>2]|0;Ra=(Qa|0)<0;Sa=Ra<<31>>31;Ta=ee(Na|0,Oa|0,Qa|0,Sa|0)|0;Ua=E;Va=de(Ta|0,Ua|0,Aa|0,Ba|0)|0;Wa=E;Xa=9968;Ya=Xa;Za=c[Ya>>2]|0;_a=Xa+4|0;$a=_a;ab=c[$a>>2]|0;bb=ee(Va|0,Wa|0,Za|0,ab|0)|0;cb=E;db=9968;eb=db;c[eb>>2]=bb;fb=db+4|0;gb=fb;c[gb>>2]=cb;hb=c[2494]|0;ib=hb+1|0;c[2494]=ib;i=a;return}function id(a,b){a=a|0;b=+b;var d=0,e=0,f=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0.0,y=0.0,z=0,A=0,B=0.0,C=0.0,D=0.0,F=0.0,G=0.0,H=0.0,I=0,J=0.0,K=0.0,L=0.0,M=0,N=0,O=0.0,P=0.0,Q=0.0,R=0,S=0,T=0.0,U=0.0,V=0.0,W=0.0,X=0.0,Y=0.0,Z=0.0,_=0.0,$=0.0,aa=0.0,ba=0,ca=0,da=0,ea=0;a=i;i=i+16|0;d=a;e=c[2476]|0;f=~~(+(e|0)+ +((c[2480]|0)-e|0)*b);e=c[2478]|0;h=~~(+(e|0)+ +((c[2482]|0)-e|0)*b);nb(d|0,0)|0;e=c[d>>2]|0;j=qe(e|0,((e|0)<0)<<31>>31|0,1e6,0)|0;e=c[d+4>>2]|0;k=ee(j|0,E|0,e|0,((e|0)<0)<<31>>31|0)|0;e=E;Tc();j=c[2456]|0;if((c[2462]|0)==0){l=j}else{if((j|0)>0){m=j;j=0;n=0;while(1){o=c[2452]|0;p=c[o+(j<<2)>>2]|0;do{if((p|0)!=0){q=c[2454]|0;r=c[q+(j<<2)>>2]|0;if((r|0)==-2){s=m;t=n;break}else if((r|0)==-1){u=c[p+156>>2]|0;if((u|0)==0){v=m}else{xc[u&7](p);v=c[2456]|0}c[p+212>>2]=c[2448];c[2448]=p;s=v;t=n;break}else{if((j|0)>(n|0)){c[o+(n<<2)>>2]=p;c[q+(n<<2)>>2]=r}s=m;t=n+1|0;break}}else{s=m;t=n}}while(0);j=j+1|0;if((j|0)>=(s|0)){w=t;break}else{m=s;n=t}}}else{w=0}c[2456]=w;c[2462]=0;c[2460]=0;l=w}c[2460]=1;if((l|0)>0){x=+(0-f|0);y=+(0-h|0);w=l;l=0;t=0;n=0;while(1){s=c[2452]|0;m=c[s+(l<<2)>>2]|0;j=c[2472]|0;v=c[2474]|0;p=c[m+104>>2]|0;if((p|0)==0){o=c[m+108>>2]|0;if((o|0)==0){z=t;A=n}else{z=c[o+16>>2]|0;A=c[o+12>>2]|0}}else{z=c[(c[p>>2]|0)+16>>2]|0;A=c[p+4>>2]|0}p=h-z|0;o=v+h+z|0;B=+g[m+24>>2];do{if(((!(B<+(f-A|0))?!(B>+(j+f+A|0)):0)?(C=+g[m+28>>2],!(C<+(p|0))):0)?!(C>+(o|0)):0){v=m+32|0;r=c[v>>2]|0;if((r&32|0)==0){D=+g[m+120>>2];F=+g[m+124>>2];G=+g[m+128>>2];H=+g[m+132>>2];I=r}else{if((r&16|0)==0){J=+g[m+136>>2];K=+g[m+140>>2];L=+g[m+144>>2];q=m+120|0;g[q>>2]=J;u=m+124|0;g[u>>2]=K;M=m+128|0;g[M>>2]=L;N=m+132|0;g[N>>2]=1.0;if((w|0)>0){O=J;P=K;Q=L;R=0;while(1){S=c[s+(R<<2)>>2]|0;if(((S|0)!=(m|0)?(c[S+32>>2]&16|0)!=0:0)?(T=B- +g[S+24>>2],U=C- +g[S+28>>2],V=T*T+U*U,U=+g[S+148>>2],T=U*U,V>2];V=U*+g[S+144>>2];W=U*+g[S+136>>2]+O;U=W>1.0?1.0:W;g[q>>2]=U;W=T+P;T=W>1.0?1.0:W;g[u>>2]=T;W=V+Q;V=W>1.0?1.0:W;g[M>>2]=V;g[N>>2]=1.0;X=V;Y=T;Z=U}else{X=Q;Y=P;Z=O}R=R+1|0;if((R|0)==(w|0)){_=X;$=Y;aa=Z;break}else{O=Z;P=Y;Q=X}}}else{_=L;$=K;aa=J}}else{g[m+120>>2]=1.0;g[m+124>>2]=1.0;g[m+128>>2]=1.0;g[m+132>>2]=1.0;_=1.0;$=1.0;aa=1.0}R=r&-33;c[v>>2]=R;D=aa;F=$;G=_;H=1.0;I=R}g[1566]=D;g[1568]=F;g[1570]=G;g[1572]=H;if((I&64|0)==0){ad(m+104|0,~~(x+B),~~(y+C));break}else{Q=+g[m+16>>2];P=+g[m+20>>2];ad(m+104|0,~~(x+(Q-(Q-B)*b)),~~(y+(P-(P-C)*b)));break}}}while(0);l=l+1|0;w=c[2456]|0;if((l|0)>=(w|0)){break}else{t=z;n=A}}}g[1566]=1.0;g[1568]=1.0;g[1570]=1.0;g[1572]=1.0;if((c[2468]|0)!=0){Dd(b)}if((c[2462]|0)!=0){A=c[2456]|0;if((A|0)>0){n=A;A=0;z=0;while(1){t=c[2452]|0;w=c[t+(A<<2)>>2]|0;do{if((w|0)!=0){l=c[2454]|0;I=c[l+(A<<2)>>2]|0;if((I|0)==-1){f=c[w+156>>2]|0;if((f|0)==0){ba=n}else{xc[f&7](w);ba=c[2456]|0}c[w+212>>2]=c[2448];c[2448]=w;ca=ba;da=z;break}else if((I|0)==-2){ca=n;da=z;break}else{if((A|0)>(z|0)){c[t+(z<<2)>>2]=w;c[l+(z<<2)>>2]=I}ca=n;da=z+1|0;break}}else{ca=n;da=z}}while(0);A=A+1|0;if((A|0)>=(ca|0)){ea=da;break}else{n=ca;z=da}}}else{ea=0}c[2456]=ea;c[2462]=0;c[2460]=0}nb(d|0,0)|0;ea=c[d>>2]|0;da=qe(ea|0,((ea|0)<0)<<31>>31|0,1e6,0)|0;ea=c[d+4>>2]|0;z=ee(da|0,E|0,ea|0,((ea|0)<0)<<31>>31|0)|0;ea=de(z|0,E|0,k|0,e|0)|0;e=9984;k=ee(ea|0,E|0,c[e>>2]|0,c[e+4>>2]|0)|0;e=9984;c[e>>2]=k;c[e+4>>2]=E;c[2498]=(c[2498]|0)+1;if((c[9260>>2]|0)!=1){i=a;return}Ja(10120)|0;e=c[2494]|0;if((e|0)>0){k=9944;ea=oe(c[k>>2]|0,c[k+4>>2]|0,e|0,((e|0)<0)<<31>>31|0)|0;e=d;c[e>>2]=ea;c[e+4>>2]=E;eb(1e4,d|0)|0;e=9952;ea=c[2494]|0;k=oe(c[e>>2]|0,c[e+4>>2]|0,ea|0,((ea|0)<0)<<31>>31|0)|0;ea=d;c[ea>>2]=k;c[ea+4>>2]=E;eb(10024,d|0)|0;ea=9960;k=c[2494]|0;e=oe(c[ea>>2]|0,c[ea+4>>2]|0,k|0,((k|0)<0)<<31>>31|0)|0;k=d;c[k>>2]=e;c[k+4>>2]=E;eb(10048,d|0)|0;k=9968;e=c[2494]|0;ea=oe(c[k>>2]|0,c[k+4>>2]|0,e|0,((e|0)<0)<<31>>31|0)|0;e=d;c[e>>2]=ea;c[e+4>>2]=E;eb(10072,d|0)|0}e=c[2498]|0;if((e|0)>0){ea=9984;k=oe(c[ea>>2]|0,c[ea+4>>2]|0,e|0,((e|0)<0)<<31>>31|0)|0;e=d;c[e>>2]=k;c[e+4>>2]=E;eb(10096,d|0)|0}d=9944;c[d>>2]=0;c[d+4>>2]=0;d=9952;c[d>>2]=0;c[d+4>>2]=0;d=9960;c[d>>2]=0;c[d+4>>2]=0;d=9968;c[d>>2]=0;c[d+4>>2]=0;d=9984;c[d>>2]=0;c[d+4>>2]=0;c[2494]=0;c[2498]=0;i=a;return}function jd(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0.0,m=0.0,n=0.0,o=0.0,p=0.0,q=0;f=i;g=c[2472]|0;h=g>>>1;j=c[2474]|0;k=j>>>1;l=+(~~(+((g>>>0>j>>>0?h:k)|0)*1.2000000476837158)|0);j=~~(l/10.0);g=d-(h+(c[2480]|0))|0;m=+(g-j|0);n=+(e-(c[2482]|0)-k|0);o=n*n;n=1.0- +Q(+(o+m*m))/l;m=+(g+j|0);p=1.0- +Q(+(o+m*m))/l;l=p<0.0?0.0:p;p=n<0.0?0.0:n;if((!(l<=0.0)|!(p<=0.0))^1|(b|0)==0){i=f;return}j=c[2320]|0;if((j|0)==0){g=Pd(16)|0;c[g+12>>2]=0;q=g}else{g=j+12|0;c[2320]=c[g>>2];c[g>>2]=0;q=j}c[q>>2]=b;c[q+4>>2]=0;a[q+8>>0]=~~(p*255.0);a[q+9>>0]=~~(l*255.0);c[q+12>>2]=c[2318];c[2318]=q;i=f;return}function kd(a,b,d,e,f){a=a|0;b=+b;d=+d;e=+e;f=+f;var h=0,j=0,k=0,l=0,m=0,n=0.0,o=0.0,p=0,q=0,r=0.0,s=0.0,t=0.0,u=0.0,v=0.0,w=0,x=0,y=0,z=0;h=i;j=a+32|0;k=c[j>>2]|0;if((k&16|0)==0){g[a+136>>2]=b;g[a+140>>2]=d;g[a+144>>2]=e;g[a+148>>2]=f;c[j>>2]=k|32;i=h;return}l=c[2452]|0;m=c[2456]|0;n=+g[a+24>>2];o=+g[a+8>>2];p=n>2];s=(p?n:o)-r;t=r+(p?o:n);n=+g[a+28>>2];o=+g[a+12>>2];p=n0){p=0;do{w=c[l+(p<<2)>>2]|0;n=+g[w+24>>2];if(!(!(s<=n)|!(t>=n))?(n=+g[w+28>>2],!(!(u<=n)|!(v>=n))):0){x=w+32|0;c[x>>2]=c[x>>2]|32}p=p+1|0}while((p|0)!=(m|0));y=c[j>>2]|0}else{y=k}g[a+136>>2]=b;g[a+140>>2]=d;g[a+144>>2]=e;g[q>>2]=f;if((y&16|0)==0){c[j>>2]=y|32;i=h;return}e=+g[a+24>>2];d=+g[a+8>>2];y=e>2];d=+g[a+12>>2];a=e0){z=0}else{i=h;return}do{a=c[l+(z<<2)>>2]|0;f=+g[a+24>>2];if(!(!(b<=f)|!(v>=f))?(f=+g[a+28>>2],!(!(u<=f)|!(t>=f))):0){y=a+32|0;c[y>>2]=c[y>>2]|32}z=z+1|0}while((z|0)!=(m|0));i=h;return}function ld(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,h=0,j=0.0,k=0.0,l=0.0,m=0.0,n=0.0,o=0.0,p=0;b=i;i=i+16|0;d=b+4|0;e=b;do{if((c[2470]|0)!=0&(c[9248>>2]|0)==1){f=a+32|0;h=c[f>>2]|0;if((h&1|0)==0){c[f>>2]=h|9;kd(a,.4000000059604645,.4000000059604645,.4000000059604645,160.0);break}else{c[f>>2]=h&-10;kd(a,.699999988079071,.699999988079071,.699999988079071,640.0);break}}}while(0);if((Db(d|0,e|0)|0)<<24>>24==0){j=(c[9232>>2]|0)==0?0.0:-1.0;if((c[9236>>2]|0)==0){k=j}else{k=j+1.0}j=(c[9240>>2]|0)==0?0.0:-1.0;if((c[9244>>2]|0)==0){l=j}else{l=j+1.0}j=l*l+k*k;if(j>0.0){m=1.0/+Q(+j);n=l*m;o=m*k;p=13}}else{k=+((c[d>>2]|0)-((c[1282]|0)>>>1)|0);m=+(c[e>>2]|0)- +(c[1284]|0)*.5;l=1.0/+Q(+(k*k+m*m));n=k*l;o=l*m;p=13}if((p|0)==13){m=n*0.0+o*-1.0;l=n+o*0.0;do{if(!(+P(+m)>=+P(+l))){p=a+104|0;if(l>0.0){e=c[2540]|0;c[p>>2]=0;c[a+108>>2]=e;c[a+116>>2]=0;break}else{e=c[2542]|0;c[p>>2]=0;c[a+108>>2]=e;c[a+116>>2]=0;break}}else{e=a+104|0;if(m>0.0){p=c[2536]|0;c[e>>2]=0;c[a+108>>2]=p;c[a+116>>2]=0;break}else{p=c[2538]|0;c[e>>2]=0;c[a+108>>2]=p;c[a+116>>2]=0;break}}}while(0);ed(a,n*7.0,o*7.0,15.0)}o=+(c[2480]|0);c[2480]=~~(o+(+g[a+24>>2]-(o+ +(c[2472]|0)*.5))*.30000001192092896);o=+(c[2482]|0);c[2482]=~~(o+(+g[a+28>>2]-(o+ +(c[2474]|0)*.5))*.30000001192092896);i=b;return}function md(a,b,d,e){a=a|0;b=b|0;d=+d;e=e|0;var f=0,h=0,j=0.0,k=0.0,l=0.0,m=0.0,n=0,o=0.0;f=i;if((c[b+4>>2]|0)!=1){h=1;i=f;return h|0}j=+g[a+52>>2];k=+g[a+56>>2];l=+Q(+(j*j+k*k));if(!(l>0.0)){h=1;i=f;return h|0}m=1.0/l;l=+g[e>>2];n=e+4|0;o=+g[n>>2];if(!(j*m*l+k*m*o<-.8999999761581421)){h=1;i=f;return h|0}do{if(+P(+l)>+P(+o)){if(!(l>=0.0)){g[e>>2]=-1.0;g[n>>2]=0.0;break}else{g[e>>2]=1.0;g[n>>2]=0.0;break}}else{if(!(o>=0.0)){g[n>>2]=-1.0;g[e>>2]=0.0;break}else{g[n>>2]=1.0;g[e>>2]=0.0;break}}}while(0);dd(b,a,d,e);h=2;i=f;return h|0}function nd(a,b){a=a|0;b=b|0;var d=0,e=0.0,f=0.0,h=0,j=0;b=i;i=i+16|0;d=b;e=+g[a+52>>2];f=+g[a+56>>2];if(!(e*e+f*f>0.0)){i=b;return}nb(d|0,0)|0;h=c[d>>2]|0;j=qe(h|0,((h|0)<0)<<31>>31|0,1e6,0)|0;h=c[d+4>>2]|0;d=ee(j|0,E|0,h|0,((h|0)<0)<<31>>31|0)|0;h=oe(d|0,E|0,1e3,0)|0;d=a+176|0;if((h+ -250|0)<=(c[d>>2]|0)){i=b;return}jd(c[2544]|0,~~+g[a+24>>2],~~+g[a+28>>2]);c[d>>2]=h;i=b;return}function od(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,h=0,j=0;d=i;e=b+4|0;f=c[e>>2]|0;if((f|0)==1){c[a+172>>2]=0;h=bd(c[2546]|0)|0;g[h+24>>2]=+g[a+24>>2];g[h+28>>2]=+g[a+28>>2];fd(h);jd(c[2548]|0,~~+g[b+24>>2],~~+g[b+28>>2]);gd(a)|0;gd(b)|0;j=c[e>>2]|0}else{j=f}if((j|0)!=0){i=d;return}j=bd(c[2550]|0)|0;f=b+24|0;g[j+24>>2]=+g[f>>2];e=b+28|0;g[j+28>>2]=+g[e>>2];fd(j);jd(c[2552]|0,~~+g[f>>2],~~+g[e>>2]);gd(b)|0;c[2910]=1;i=d;return}function pd(a){a=a|0;var b=0,d=0,e=0;b=i;d=(ce()|0)%1e3|0;if((c[a+104>>2]|0)==0){i=b;return}if((c[a+112>>2]|0)!=0){i=b;return}e=a+116|0;c[e>>2]=(c[e>>2]|0)+d;i=b;return}function qd(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,h=0,j=0,k=0;a=i;d=b+4|0;e=c[d>>2]|0;if((e|0)==1){f=bd(c[2554]|0)|0;h=b+24|0;g[f+24>>2]=+g[h>>2];j=b+28|0;g[f+28>>2]=+g[j>>2];fd(f);jd(c[2552]|0,~~+g[h>>2],~~+g[j>>2]);gd(b)|0;k=c[d>>2]|0}else{k=e}if((k|0)!=0){i=a;return}k=bd(c[2554]|0)|0;e=b+24|0;g[k+24>>2]=+g[e>>2];d=b+28|0;g[k+28>>2]=+g[d>>2];fd(k);k=bd(c[2550]|0)|0;g[k+24>>2]=+g[e>>2];g[k+28>>2]=+g[d>>2];fd(k);jd(c[2552]|0,~~+g[e>>2],~~+g[d>>2]);gd(b)|0;c[2910]=1;i=a;return}function rd(a,b,d,e){a=a|0;b=b|0;d=+d;e=e|0;var f=0,h=0,j=0;e=i;if((c[a+164>>2]|0)!=0){i=e;return 0}f=c[b+4>>2]|0;if((f|0)==8|(f|0)==7){i=e;return 0}else if((f|0)==0){f=bd(c[2550]|0)|0;h=b+24|0;g[f+24>>2]=+g[h>>2];j=b+28|0;g[f+28>>2]=+g[j>>2];fd(f);gd(b)|0;jd(c[2552]|0,~~+g[h>>2],~~+g[j>>2]);c[2910]=1}gd(a)|0;jd(c[2556]|0,~~+g[a+24>>2],~~+g[a+28>>2]);i=e;return 0}function sd(a){a=a|0;var b=0;b=i;c[a+176>>2]=(ce()|0)%15|0;i=b;return}function td(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,h=0,j=0,k=0;b=i;d=a+176|0;e=c[d>>2]|0;if((e|0)==0){f=bd(c[a+192>>2]|0)|0;h=a+24|0;g[f+24>>2]=+g[h>>2];j=a+28|0;g[f+28>>2]=+g[j>>2];fd(f);jd(c[2558]|0,~~+g[h>>2],~~+g[j>>2]);k=15;c[d>>2]=k;i=b;return}else{k=e+ -1|0;c[d>>2]=k;i=b;return}}function ud(a){a=a|0;if((c[2560]|0)==(a|0)){c[2560]=0}return}function vd(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=i;if((c[b+4>>2]|0)!=0){i=d;return}b=c[a+176>>2]|0;if((c[2908]|0)!=(b|0)){c[2908]=b;jd(c[2562]|0,~~+g[a+24>>2],~~+g[a+28>>2]);Jd()}b=c[2560]|0;if((b|0)==(a|0)){i=d;return}e=c[2564]|0;c[a+112>>2]=0;f=a+104|0;if((c[f>>2]|0)!=(e|0)){c[f>>2]=e;c[a+108>>2]=0;c[a+116>>2]=0}kd(a,0.0,0.0,.5,128.0);if((b|0)!=0){e=c[2566]|0;c[b+104>>2]=0;c[b+108>>2]=e;c[b+116>>2]=0;kd(b,0.0,0.0,.5,64.0)}c[2560]=a;i=d;return}function wd(a,b){a=a|0;b=b|0;var d=0;d=i;if((c[b+4>>2]|0)!=0){i=d;return}c[2906]=(c[2906]|0)+1;c[2908]=1;c[2910]=2;gd(b)|0;jd(c[2568]|0,~~+g[a+24>>2],~~+g[a+28>>2]);Jd();i=d;return}function xd(a,b){a=a|0;b=b|0;var d=0;d=i;if((c[b+4>>2]|0)!=0){i=d;return}c[2910]=3;gd(b)|0;jd(c[2568]|0,~~+g[a+24>>2],~~+g[a+28>>2]);Jd();i=d;return}function yd(a,b){a=a|0;b=b|0;var d=0,e=0;b=i;d=a+176|0;e=c[d>>2]|0;if((e|0)==0){gd(a)|0;i=b;return}else{c[d>>2]=e+ -1;i=b;return}}function zd(a,b){a=a|0;b=b|0;var d=0,e=0;d=i;if((c[a+4>>2]|0)!=12){e=0;i=d;return e|0}e=(c[a+176>>2]|0)==(c[b>>2]|0)&1;i=d;return e|0}function Ad(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,h=0,j=0,k=0;d=i;e=a+176|0;a=c[2456]|0;if((a|0)<=0){i=d;return}f=c[2452]|0;h=0;while(1){j=c[f+(h<<2)>>2]|0;if((j|0)!=0?(zd(j,e)|0)!=0:0){break}h=h+1|0;if((h|0)>=(a|0)){k=7;break}}if((k|0)==7){i=d;return}g[b+24>>2]=+g[j+24>>2];g[b+28>>2]=+g[j+28>>2];i=d;return} - - - -function te(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,F=0,G=0,H=0;g=a;h=b;i=h;j=d;k=e;l=k;if((i|0)==0){m=(f|0)!=0;if((l|0)==0){if(m){c[f>>2]=(g>>>0)%(j>>>0);c[f+4>>2]=0}n=0;o=(g>>>0)/(j>>>0)>>>0;return(E=n,o)|0}else{if(!m){n=0;o=0;return(E=n,o)|0}c[f>>2]=a|0;c[f+4>>2]=b&0;n=0;o=0;return(E=n,o)|0}}m=(l|0)==0;do{if((j|0)!=0){if(!m){p=(le(l|0)|0)-(le(i|0)|0)|0;if(p>>>0<=31){q=p+1|0;r=31-p|0;s=p-31>>31;t=q;u=g>>>(q>>>0)&s|i<>>(q>>>0)&s;w=0;x=g<>2]=a|0;c[f+4>>2]=h|b&0;n=0;o=0;return(E=n,o)|0}r=j-1|0;if((r&j|0)!=0){s=(le(j|0)|0)+33-(le(i|0)|0)|0;q=64-s|0;p=32-s|0;y=p>>31;z=s-32|0;A=z>>31;t=s;u=p-1>>31&i>>>(z>>>0)|(i<>>(s>>>0))&A;v=A&i>>>(s>>>0);w=g<>>(z>>>0))&y|g<>31;break}if((f|0)!=0){c[f>>2]=r&g;c[f+4>>2]=0}if((j|0)==1){n=h|b&0;o=a|0|0;return(E=n,o)|0}else{r=me(j|0)|0;n=i>>>(r>>>0)|0;o=i<<32-r|g>>>(r>>>0)|0;return(E=n,o)|0}}else{if(m){if((f|0)!=0){c[f>>2]=(i>>>0)%(j>>>0);c[f+4>>2]=0}n=0;o=(i>>>0)/(j>>>0)>>>0;return(E=n,o)|0}if((g|0)==0){if((f|0)!=0){c[f>>2]=0;c[f+4>>2]=(i>>>0)%(l>>>0)}n=0;o=(i>>>0)/(l>>>0)>>>0;return(E=n,o)|0}r=l-1|0;if((r&l|0)==0){if((f|0)!=0){c[f>>2]=a|0;c[f+4>>2]=r&i|b&0}n=0;o=i>>>((me(l|0)|0)>>>0);return(E=n,o)|0}r=(le(l|0)|0)-(le(i|0)|0)|0;if(r>>>0<=30){s=r+1|0;p=31-r|0;t=s;u=i<>>(s>>>0);v=i>>>(s>>>0);w=0;x=g<>2]=a|0;c[f+4>>2]=h|b&0;n=0;o=0;return(E=n,o)|0}}while(0);if((t|0)==0){B=x;C=w;D=v;F=u;G=0;H=0}else{b=d|0|0;d=k|e&0;e=ee(b,d,-1,-1)|0;k=E;h=x;x=w;w=v;v=u;u=t;t=0;do{a=h;h=x>>>31|h<<1;x=t|x<<1;g=v<<1|a>>>31|0;a=v>>>31|w<<1|0;de(e,k,g,a)|0;i=E;l=i>>31|((i|0)<0?-1:0)<<1;t=l&1;v=de(g,a,l&b,(((i|0)<0?-1:0)>>31|((i|0)<0?-1:0)<<1)&d)|0;w=E;u=u-1|0}while((u|0)!=0);B=h;C=x;D=w;F=v;G=0;H=t}t=C;C=0;if((f|0)!=0){c[f>>2]=F;c[f+4>>2]=D}n=(t|0)>>>31|(B|C)<<1|(C<<1|t>>>31)&0|G;o=(t<<1|0>>>31)&-2|H;return(E=n,o)|0}function ue(a,b,c,d,e,f){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;return tc[a&0](b|0,c|0,d|0,e|0,f|0)|0}function ve(a,b){a=a|0;b=+b;uc[a&1](+b)}function we(a,b,c){a=a|0;b=b|0;c=+c;vc[a&3](b|0,+c)}function xe(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=+d;e=e|0;return wc[a&3](b|0,c|0,+d,e|0)|0}function ye(a,b){a=a|0;b=b|0;xc[a&7](b|0)}function ze(a,b,c){a=a|0;b=b|0;c=c|0;yc[a&15](b|0,c|0)}function Ae(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;return zc[a&3](b|0,c|0,d|0)|0}function Be(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;Ac[a&1](b|0,c|0,d|0)}function Ce(a){a=a|0;Bc[a&3]()}function De(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;ba(0);return 0}function Ee(a){a=+a;ba(1)}function Fe(a,b){a=a|0;b=+b;ba(2)}function Ge(a,b,c,d){a=a|0;b=b|0;c=+c;d=d|0;ba(3);return 0}function He(a){a=a|0;ba(4)}function Ie(a,b){a=a|0;b=b|0;ba(5)}function Je(a,b,c){a=a|0;b=b|0;c=c|0;ba(6);return 0}function Ke(a,b,c){a=a|0;b=b|0;c=c|0;ba(7)}function Le(){ba(8)} - - - - -// EMSCRIPTEN_END_FUNCS -var tc=[De];var uc=[Ee,Dd];var vc=[Fe,id,Gd,Ed];var wc=[Ge,md,rd,Ge];var xc=[He,hd,Fd,Cd,pd,sd,ud,He];var yc=[Ie,ld,nd,od,qd,yd,td,vd,wd,xd,Ad,Ie,Ie,Ie,Ie,Ie];var zc=[Je,$d,Od,Je];var Ac=[Ke,_c];var Bc=[Le,Hd,Id,Uc];return{_i64Subtract:de,_free:Qd,_main:Kd,_rand_r:be,_realloc:Rd,_i64Add:ee,_strlen:fe,_memset:he,_malloc:Pd,_memcpy:ie,_bitshift64Lshr:ge,_rand:ce,_bitshift64Shl:je,runPostSets:ae,stackAlloc:Cc,stackSave:Dc,stackRestore:Ec,setThrew:Fc,setTempRet0:Ic,getTempRet0:Jc,dynCall_iiiiii:ue,dynCall_vd:ve,dynCall_vid:we,dynCall_iiidi:xe,dynCall_vi:ye,dynCall_vii:ze,dynCall_iiii:Ae,dynCall_viii:Be,dynCall_v:Ce} -// EMSCRIPTEN_END_ASM - -})({"Math":Math,"Int8Array":Int8Array,"Int16Array":Int16Array,"Int32Array":Int32Array,"Uint8Array":Uint8Array,"Uint16Array":Uint16Array,"Uint32Array":Uint32Array,"Float32Array":Float32Array,"Float64Array":Float64Array},{"abort":abort,"assert":assert,"asmPrintInt":asmPrintInt,"asmPrintFloat":asmPrintFloat,"min":Math_min,"invoke_iiiiii":invoke_iiiiii,"invoke_vd":invoke_vd,"invoke_vid":invoke_vid,"invoke_iiidi":invoke_iiidi,"invoke_vi":invoke_vi,"invoke_vii":invoke_vii,"invoke_iiii":invoke_iiii,"invoke_viii":invoke_viii,"invoke_v":invoke_v,"_glUseProgram":_glUseProgram,"_fabs":_fabs,"_fread":_fread,"_glUniformMatrix4fv":_glUniformMatrix4fv,"_SDL_RWFromFile":_SDL_RWFromFile,"_glDeleteProgram":_glDeleteProgram,"_glBindBuffer":_glBindBuffer,"_glCreateProgram":_glCreateProgram,"_fsync":_fsync,"_SDL_GetError":_SDL_GetError,"_sbrk":_sbrk,"_glBlendFunc":_glBlendFunc,"_glGetAttribLocation":_glGetAttribLocation,"_Mix_PlayChannel":_Mix_PlayChannel,"_glCreateShader":_glCreateShader,"_sysconf":_sysconf,"_close":_close,"_SDL_InitSubSystem":_SDL_InitSubSystem,"_Mix_PlayMusic":_Mix_PlayMusic,"_rewind":_rewind,"_puts":_puts,"_Mix_FreeChunk":_Mix_FreeChunk,"_write":_write,"_ftell":_ftell,"_glGenBuffers":_glGenBuffers,"_glShaderSource":_glShaderSource,"_Mix_HaltMusic":_Mix_HaltMusic,"_mknod":_mknod,"_mkdir":_mkdir,"_llvm_trap":_llvm_trap,"_fmodl":_fmodl,"_glVertexAttribPointer":_glVertexAttribPointer,"_send":_send,"_SDL_GetTicks":_SDL_GetTicks,"_SDL_GetKeyboardState":_SDL_GetKeyboardState,"_glBufferSubData":_glBufferSubData,"_SDL_LockSurface":_SDL_LockSurface,"_strerror_r":_strerror_r,"__reallyNegative":__reallyNegative,"___setErrNo":___setErrNo,"_SDL_OpenAudio":_SDL_OpenAudio,"_srand":_srand,"_glEnable":_glEnable,"_printf":_printf,"_glGenTextures":_glGenTextures,"_glGetString":_glGetString,"_glAttachShader":_glAttachShader,"_read":_read,"_SDL_SetVideoMode":_SDL_SetVideoMode,"_fwrite":_fwrite,"_time":_time,"_fprintf":_fprintf,"_gettimeofday":_gettimeofday,"_putenv":_putenv,"_IMG_Load":_IMG_Load,"_fmod":_fmod,"_lseek":_lseek,"___buildEnvironment":___buildEnvironment,"_pwrite":_pwrite,"_glBindTexture":_glBindTexture,"_open":_open,"_fabsf":_fabsf,"_emscripten_asm_const":_emscripten_asm_const,"_SDL_Init":_SDL_Init,"_glUniform1i":_glUniform1i,"_glDrawArrays":_glDrawArrays,"_TTF_RenderText_Solid":_TTF_RenderText_Solid,"_fseek":_fseek,"_SDL_GetMouseState":_SDL_GetMouseState,"_getenv":_getenv,"_fclose":_fclose,"_sqrtf":_sqrtf,"_stime":_stime,"_recv":_recv,"_fgetc":_fgetc,"_glCompileShader":_glCompileShader,"_glEnableVertexAttribArray":_glEnableVertexAttribArray,"_abort":_abort,"_glBufferData":_glBufferData,"_glTexImage2D":_glTexImage2D,"_fopen":_fopen,"_glDeleteShader":_glDeleteShader,"_glGetProgramiv":_glGetProgramiv,"_SDL_CloseAudio":_SDL_CloseAudio,"_fflush":_fflush,"_SDL_FreeRW":_SDL_FreeRW,"_SDL_PauseAudio":_SDL_PauseAudio,"_SDL_PollEvent":_SDL_PollEvent,"_glGetUniformLocation":_glGetUniformLocation,"_glTexParameteri":_glTexParameteri,"_fileno":_fileno,"_Mix_LoadWAV_RW":_Mix_LoadWAV_RW,"_SDL_WM_SetCaption":_SDL_WM_SetCaption,"_IMG_Load_RW":_IMG_Load_RW,"_glPixelStorei":_glPixelStorei,"_glGetShaderiv":_glGetShaderiv,"_pread":_pread,"_mkport":_mkport,"_glLinkProgram":_glLinkProgram,"_emscripten_memcpy_big":_emscripten_memcpy_big,"_emscripten_set_main_loop":_emscripten_set_main_loop,"___errno_location":___errno_location,"_copysign":_copysign,"_fputc":_fputc,"_copysignl":_copysignl,"_SDL_GL_SwapBuffers":_SDL_GL_SwapBuffers,"_strerror":_strerror,"__formatString":__formatString,"_fputs":_fputs,"_SDL_UpperBlit":_SDL_UpperBlit,"_SDL_RWFromConstMem":_SDL_RWFromConstMem,"STACKTOP":STACKTOP,"STACK_MAX":STACK_MAX,"tempDoublePtr":tempDoublePtr,"ABORT":ABORT,"cttz_i8":cttz_i8,"ctlz_i8":ctlz_i8,"___rand_seed":___rand_seed,"NaN":NaN,"Infinity":Infinity},buffer);var _i64Subtract=Module["_i64Subtract"]=asm["_i64Subtract"];var _free=Module["_free"]=asm["_free"];var _main=Module["_main"]=asm["_main"];var _rand_r=Module["_rand_r"]=asm["_rand_r"];var _realloc=Module["_realloc"]=asm["_realloc"];var _i64Add=Module["_i64Add"]=asm["_i64Add"];var _strlen=Module["_strlen"]=asm["_strlen"];var _memset=Module["_memset"]=asm["_memset"];var _malloc=Module["_malloc"]=asm["_malloc"];var _memcpy=Module["_memcpy"]=asm["_memcpy"];var _bitshift64Lshr=Module["_bitshift64Lshr"]=asm["_bitshift64Lshr"];var _rand=Module["_rand"]=asm["_rand"];var _bitshift64Shl=Module["_bitshift64Shl"]=asm["_bitshift64Shl"];var runPostSets=Module["runPostSets"]=asm["runPostSets"];var dynCall_iiiiii=Module["dynCall_iiiiii"]=asm["dynCall_iiiiii"];var dynCall_vd=Module["dynCall_vd"]=asm["dynCall_vd"];var dynCall_vid=Module["dynCall_vid"]=asm["dynCall_vid"];var dynCall_iiidi=Module["dynCall_iiidi"]=asm["dynCall_iiidi"];var dynCall_vi=Module["dynCall_vi"]=asm["dynCall_vi"];var dynCall_vii=Module["dynCall_vii"]=asm["dynCall_vii"];var dynCall_iiii=Module["dynCall_iiii"]=asm["dynCall_iiii"];var dynCall_viii=Module["dynCall_viii"]=asm["dynCall_viii"];var dynCall_v=Module["dynCall_v"]=asm["dynCall_v"];Runtime.stackAlloc=asm["stackAlloc"];Runtime.stackSave=asm["stackSave"];Runtime.stackRestore=asm["stackRestore"];Runtime.setTempRet0=asm["setTempRet0"];Runtime.getTempRet0=asm["getTempRet0"];var i64Math=(function(){var goog={math:{}};goog.math.Long=(function(low,high){this.low_=low|0;this.high_=high|0});goog.math.Long.IntCache_={};goog.math.Long.fromInt=(function(value){if(-128<=value&&value<128){var cachedObj=goog.math.Long.IntCache_[value];if(cachedObj){return cachedObj}}var obj=new goog.math.Long(value|0,value<0?-1:0);if(-128<=value&&value<128){goog.math.Long.IntCache_[value]=obj}return obj});goog.math.Long.fromNumber=(function(value){if(isNaN(value)||!isFinite(value)){return goog.math.Long.ZERO}else if(value<=-goog.math.Long.TWO_PWR_63_DBL_){return goog.math.Long.MIN_VALUE}else if(value+1>=goog.math.Long.TWO_PWR_63_DBL_){return goog.math.Long.MAX_VALUE}else if(value<0){return goog.math.Long.fromNumber(-value).negate()}else{return new goog.math.Long(value%goog.math.Long.TWO_PWR_32_DBL_|0,value/goog.math.Long.TWO_PWR_32_DBL_|0)}});goog.math.Long.fromBits=(function(lowBits,highBits){return new goog.math.Long(lowBits,highBits)});goog.math.Long.fromString=(function(str,opt_radix){if(str.length==0){throw Error("number format error: empty string")}var radix=opt_radix||10;if(radix<2||36=0){throw Error('number format error: interior "-" character: '+str)}var radixToPower=goog.math.Long.fromNumber(Math.pow(radix,8));var result=goog.math.Long.ZERO;for(var i=0;i=0?this.low_:goog.math.Long.TWO_PWR_32_DBL_+this.low_});goog.math.Long.prototype.getNumBitsAbs=(function(){if(this.isNegative()){if(this.equals(goog.math.Long.MIN_VALUE)){return 64}else{return this.negate().getNumBitsAbs()}}else{var val=this.high_!=0?this.high_:this.low_;for(var bit=31;bit>0;bit--){if((val&1<0});goog.math.Long.prototype.greaterThanOrEqual=(function(other){return this.compare(other)>=0});goog.math.Long.prototype.compare=(function(other){if(this.equals(other)){return 0}var thisNeg=this.isNegative();var otherNeg=other.isNegative();if(thisNeg&&!otherNeg){return-1}if(!thisNeg&&otherNeg){return 1}if(this.subtract(other).isNegative()){return-1}else{return 1}});goog.math.Long.prototype.negate=(function(){if(this.equals(goog.math.Long.MIN_VALUE)){return goog.math.Long.MIN_VALUE}else{return this.not().add(goog.math.Long.ONE)}});goog.math.Long.prototype.add=(function(other){var a48=this.high_>>>16;var a32=this.high_&65535;var a16=this.low_>>>16;var a00=this.low_&65535;var b48=other.high_>>>16;var b32=other.high_&65535;var b16=other.low_>>>16;var b00=other.low_&65535;var c48=0,c32=0,c16=0,c00=0;c00+=a00+b00;c16+=c00>>>16;c00&=65535;c16+=a16+b16;c32+=c16>>>16;c16&=65535;c32+=a32+b32;c48+=c32>>>16;c32&=65535;c48+=a48+b48;c48&=65535;return goog.math.Long.fromBits(c16<<16|c00,c48<<16|c32)});goog.math.Long.prototype.subtract=(function(other){return this.add(other.negate())});goog.math.Long.prototype.multiply=(function(other){if(this.isZero()){return goog.math.Long.ZERO}else if(other.isZero()){return goog.math.Long.ZERO}if(this.equals(goog.math.Long.MIN_VALUE)){return other.isOdd()?goog.math.Long.MIN_VALUE:goog.math.Long.ZERO}else if(other.equals(goog.math.Long.MIN_VALUE)){return this.isOdd()?goog.math.Long.MIN_VALUE:goog.math.Long.ZERO}if(this.isNegative()){if(other.isNegative()){return this.negate().multiply(other.negate())}else{return this.negate().multiply(other).negate()}}else if(other.isNegative()){return this.multiply(other.negate()).negate()}if(this.lessThan(goog.math.Long.TWO_PWR_24_)&&other.lessThan(goog.math.Long.TWO_PWR_24_)){return goog.math.Long.fromNumber(this.toNumber()*other.toNumber())}var a48=this.high_>>>16;var a32=this.high_&65535;var a16=this.low_>>>16;var a00=this.low_&65535;var b48=other.high_>>>16;var b32=other.high_&65535;var b16=other.low_>>>16;var b00=other.low_&65535;var c48=0,c32=0,c16=0,c00=0;c00+=a00*b00;c16+=c00>>>16;c00&=65535;c16+=a16*b00;c32+=c16>>>16;c16&=65535;c16+=a00*b16;c32+=c16>>>16;c16&=65535;c32+=a32*b00;c48+=c32>>>16;c32&=65535;c32+=a16*b16;c48+=c32>>>16;c32&=65535;c32+=a00*b32;c48+=c32>>>16;c32&=65535;c48+=a48*b00+a32*b16+a16*b32+a00*b48;c48&=65535;return goog.math.Long.fromBits(c16<<16|c00,c48<<16|c32)});goog.math.Long.prototype.div=(function(other){if(other.isZero()){throw Error("division by zero")}else if(this.isZero()){return goog.math.Long.ZERO}if(this.equals(goog.math.Long.MIN_VALUE)){if(other.equals(goog.math.Long.ONE)||other.equals(goog.math.Long.NEG_ONE)){return goog.math.Long.MIN_VALUE}else if(other.equals(goog.math.Long.MIN_VALUE)){return goog.math.Long.ONE}else{var halfThis=this.shiftRight(1);var approx=halfThis.div(other).shiftLeft(1);if(approx.equals(goog.math.Long.ZERO)){return other.isNegative()?goog.math.Long.ONE:goog.math.Long.NEG_ONE}else{var rem=this.subtract(other.multiply(approx));var result=approx.add(rem.div(other));return result}}}else if(other.equals(goog.math.Long.MIN_VALUE)){return goog.math.Long.ZERO}if(this.isNegative()){if(other.isNegative()){return this.negate().div(other.negate())}else{return this.negate().div(other).negate()}}else if(other.isNegative()){return this.div(other.negate()).negate()}var res=goog.math.Long.ZERO;var rem=this;while(rem.greaterThanOrEqual(other)){var approx=Math.max(1,Math.floor(rem.toNumber()/other.toNumber()));var log2=Math.ceil(Math.log(approx)/Math.LN2);var delta=log2<=48?1:Math.pow(2,log2-48);var approxRes=goog.math.Long.fromNumber(approx);var approxRem=approxRes.multiply(other);while(approxRem.isNegative()||approxRem.greaterThan(rem)){approx-=delta;approxRes=goog.math.Long.fromNumber(approx);approxRem=approxRes.multiply(other)}if(approxRes.isZero()){approxRes=goog.math.Long.ONE}res=res.add(approxRes);rem=rem.subtract(approxRem)}return res});goog.math.Long.prototype.modulo=(function(other){return this.subtract(this.div(other).multiply(other))});goog.math.Long.prototype.not=(function(){return goog.math.Long.fromBits(~this.low_,~this.high_)});goog.math.Long.prototype.and=(function(other){return goog.math.Long.fromBits(this.low_&other.low_,this.high_&other.high_)});goog.math.Long.prototype.or=(function(other){return goog.math.Long.fromBits(this.low_|other.low_,this.high_|other.high_)});goog.math.Long.prototype.xor=(function(other){return goog.math.Long.fromBits(this.low_^other.low_,this.high_^other.high_)});goog.math.Long.prototype.shiftLeft=(function(numBits){numBits&=63;if(numBits==0){return this}else{var low=this.low_;if(numBits<32){var high=this.high_;return goog.math.Long.fromBits(low<>>32-numBits)}else{return goog.math.Long.fromBits(0,low<>>numBits|high<<32-numBits,high>>numBits)}else{return goog.math.Long.fromBits(high>>numBits-32,high>=0?0:-1)}}});goog.math.Long.prototype.shiftRightUnsigned=(function(numBits){numBits&=63;if(numBits==0){return this}else{var high=this.high_;if(numBits<32){var low=this.low_;return goog.math.Long.fromBits(low>>>numBits|high<<32-numBits,high>>>numBits)}else if(numBits==32){return goog.math.Long.fromBits(high,0)}else{return goog.math.Long.fromBits(high>>>numBits-32,0)}}});var navigator={appName:"Modern Browser"};var dbits;var canary=0xdeadbeefcafe;var j_lm=(canary&16777215)==15715070;function BigInteger(a,b,c){if(a!=null)if("number"==typeof a)this.fromNumber(a,b,c);else if(b==null&&"string"!=typeof a)this.fromString(a,256);else this.fromString(a,b)}function nbi(){return new BigInteger(null)}function am1(i,x,w,j,c,n){while(--n>=0){var v=x*this[i++]+w[j]+c;c=Math.floor(v/67108864);w[j++]=v&67108863}return c}function am2(i,x,w,j,c,n){var xl=x&32767,xh=x>>15;while(--n>=0){var l=this[i]&32767;var h=this[i++]>>15;var m=xh*l+h*xl;l=xl*l+((m&32767)<<15)+w[j]+(c&1073741823);c=(l>>>30)+(m>>>15)+xh*h+(c>>>30);w[j++]=l&1073741823}return c}function am3(i,x,w,j,c,n){var xl=x&16383,xh=x>>14;while(--n>=0){var l=this[i]&16383;var h=this[i++]>>14;var m=xh*l+h*xl;l=xl*l+((m&16383)<<14)+w[j]+c;c=(l>>28)+(m>>14)+xh*h;w[j++]=l&268435455}return c}if(j_lm&&navigator.appName=="Microsoft Internet Explorer"){BigInteger.prototype.am=am2;dbits=30}else if(j_lm&&navigator.appName!="Netscape"){BigInteger.prototype.am=am1;dbits=26}else{BigInteger.prototype.am=am3;dbits=28}BigInteger.prototype.DB=dbits;BigInteger.prototype.DM=(1<=0;--i)r[i]=this[i];r.t=this.t;r.s=this.s}function bnpFromInt(x){this.t=1;this.s=x<0?-1:0;if(x>0)this[0]=x;else if(x<-1)this[0]=x+DV;else this.t=0}function nbv(i){var r=nbi();r.fromInt(i);return r}function bnpFromString(s,b){var k;if(b==16)k=4;else if(b==8)k=3;else if(b==256)k=8;else if(b==2)k=1;else if(b==32)k=5;else if(b==4)k=2;else{this.fromRadix(s,b);return}this.t=0;this.s=0;var i=s.length,mi=false,sh=0;while(--i>=0){var x=k==8?s[i]&255:intAt(s,i);if(x<0){if(s.charAt(i)=="-")mi=true;continue}mi=false;if(sh==0)this[this.t++]=x;else if(sh+k>this.DB){this[this.t-1]|=(x&(1<>this.DB-sh}else this[this.t-1]|=x<=this.DB)sh-=this.DB}if(k==8&&(s[0]&128)!=0){this.s=-1;if(sh>0)this[this.t-1]|=(1<0&&this[this.t-1]==c)--this.t}function bnToString(b){if(this.s<0)return"-"+this.negate().toString(b);var k;if(b==16)k=4;else if(b==8)k=3;else if(b==2)k=1;else if(b==32)k=5;else if(b==4)k=2;else return this.toRadix(b);var km=(1<0){if(p>p)>0){m=true;r=int2char(d)}while(i>=0){if(p>(p+=this.DB-k)}else{d=this[i]>>(p-=k)&km;if(p<=0){p+=this.DB;--i}}if(d>0)m=true;if(m)r+=int2char(d)}}return m?r:"0"}function bnNegate(){var r=nbi();BigInteger.ZERO.subTo(this,r);return r}function bnAbs(){return this.s<0?this.negate():this}function bnCompareTo(a){var r=this.s-a.s;if(r!=0)return r;var i=this.t;r=i-a.t;if(r!=0)return this.s<0?-r:r;while(--i>=0)if((r=this[i]-a[i])!=0)return r;return 0}function nbits(x){var r=1,t;if((t=x>>>16)!=0){x=t;r+=16}if((t=x>>8)!=0){x=t;r+=8}if((t=x>>4)!=0){x=t;r+=4}if((t=x>>2)!=0){x=t;r+=2}if((t=x>>1)!=0){x=t;r+=1}return r}function bnBitLength(){if(this.t<=0)return 0;return this.DB*(this.t-1)+nbits(this[this.t-1]^this.s&this.DM)}function bnpDLShiftTo(n,r){var i;for(i=this.t-1;i>=0;--i)r[i+n]=this[i];for(i=n-1;i>=0;--i)r[i]=0;r.t=this.t+n;r.s=this.s}function bnpDRShiftTo(n,r){for(var i=n;i=0;--i){r[i+ds+1]=this[i]>>cbs|c;c=(this[i]&bm)<=0;--i)r[i]=0;r[ds]=c;r.t=this.t+ds+1;r.s=this.s;r.clamp()}function bnpRShiftTo(n,r){r.s=this.s;var ds=Math.floor(n/this.DB);if(ds>=this.t){r.t=0;return}var bs=n%this.DB;var cbs=this.DB-bs;var bm=(1<>bs;for(var i=ds+1;i>bs}if(bs>0)r[this.t-ds-1]|=(this.s&bm)<>=this.DB}if(a.t>=this.DB}c+=this.s}else{c+=this.s;while(i>=this.DB}c-=a.s}r.s=c<0?-1:0;if(c<-1)r[i++]=this.DV+c;else if(c>0)r[i++]=c;r.t=i;r.clamp()}function bnpMultiplyTo(a,r){var x=this.abs(),y=a.abs();var i=x.t;r.t=i+y.t;while(--i>=0)r[i]=0;for(i=0;i=0)r[i]=0;for(i=0;i=x.DV){r[i+x.t]-=x.DV;r[i+x.t+1]=1}}if(r.t>0)r[r.t-1]+=x.am(i,x[i],r,2*i,0,1);r.s=0;r.clamp()}function bnpDivRemTo(m,q,r){var pm=m.abs();if(pm.t<=0)return;var pt=this.abs();if(pt.t0){pm.lShiftTo(nsh,y);pt.lShiftTo(nsh,r)}else{pm.copyTo(y);pt.copyTo(r)}var ys=y.t;var y0=y[ys-1];if(y0==0)return;var yt=y0*(1<1?y[ys-2]>>this.F2:0);var d1=this.FV/yt,d2=(1<=0){r[r.t++]=1;r.subTo(t,r)}BigInteger.ONE.dlShiftTo(ys,t);t.subTo(y,y);while(y.t=0){var qd=r[--i]==y0?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2);if((r[i]+=y.am(0,qd,r,j,0,ys))0)r.rShiftTo(nsh,r);if(ts<0)BigInteger.ZERO.subTo(r,r)}function bnMod(a){var r=nbi();this.abs().divRemTo(a,null,r);if(this.s<0&&r.compareTo(BigInteger.ZERO)>0)a.subTo(r,r);return r}function Classic(m){this.m=m}function cConvert(x){if(x.s<0||x.compareTo(this.m)>=0)return x.mod(this.m);else return x}function cRevert(x){return x}function cReduce(x){x.divRemTo(this.m,null,x)}function cMulTo(x,y,r){x.multiplyTo(y,r);this.reduce(r)}function cSqrTo(x,r){x.squareTo(r);this.reduce(r)}Classic.prototype.convert=cConvert;Classic.prototype.revert=cRevert;Classic.prototype.reduce=cReduce;Classic.prototype.mulTo=cMulTo;Classic.prototype.sqrTo=cSqrTo;function bnpInvDigit(){if(this.t<1)return 0;var x=this[0];if((x&1)==0)return 0;var y=x&3;y=y*(2-(x&15)*y)&15;y=y*(2-(x&255)*y)&255;y=y*(2-((x&65535)*y&65535))&65535;y=y*(2-x*y%this.DV)%this.DV;return y>0?this.DV-y:-y}function Montgomery(m){this.m=m;this.mp=m.invDigit();this.mpl=this.mp&32767;this.mph=this.mp>>15;this.um=(1<0)this.m.subTo(r,r);return r}function montRevert(x){var r=nbi();x.copyTo(r);this.reduce(r);return r}function montReduce(x){while(x.t<=this.mt2)x[x.t++]=0;for(var i=0;i>15)*this.mpl&this.um)<<15)&x.DM;j=i+this.m.t;x[j]+=this.m.am(0,u0,x,i,0,this.m.t);while(x[j]>=x.DV){x[j]-=x.DV;x[++j]++}}x.clamp();x.drShiftTo(this.m.t,x);if(x.compareTo(this.m)>=0)x.subTo(this.m,x)}function montSqrTo(x,r){x.squareTo(r);this.reduce(r)}function montMulTo(x,y,r){x.multiplyTo(y,r);this.reduce(r)}Montgomery.prototype.convert=montConvert;Montgomery.prototype.revert=montRevert;Montgomery.prototype.reduce=montReduce;Montgomery.prototype.mulTo=montMulTo;Montgomery.prototype.sqrTo=montSqrTo;function bnpIsEven(){return(this.t>0?this[0]&1:this.s)==0}function bnpExp(e,z){if(e>4294967295||e<1)return BigInteger.ONE;var r=nbi(),r2=nbi(),g=z.convert(this),i=nbits(e)-1;g.copyTo(r);while(--i>=0){z.sqrTo(r,r2);if((e&1<0)z.mulTo(r2,g,r);else{var t=r;r=r2;r2=t}}return z.revert(r)}function bnModPowInt(e,m){var z;if(e<256||m.isEven())z=new Classic(m);else z=new Montgomery(m);return this.exp(e,z)}BigInteger.prototype.copyTo=bnpCopyTo;BigInteger.prototype.fromInt=bnpFromInt;BigInteger.prototype.fromString=bnpFromString;BigInteger.prototype.clamp=bnpClamp;BigInteger.prototype.dlShiftTo=bnpDLShiftTo;BigInteger.prototype.drShiftTo=bnpDRShiftTo;BigInteger.prototype.lShiftTo=bnpLShiftTo;BigInteger.prototype.rShiftTo=bnpRShiftTo;BigInteger.prototype.subTo=bnpSubTo;BigInteger.prototype.multiplyTo=bnpMultiplyTo;BigInteger.prototype.squareTo=bnpSquareTo;BigInteger.prototype.divRemTo=bnpDivRemTo;BigInteger.prototype.invDigit=bnpInvDigit;BigInteger.prototype.isEven=bnpIsEven;BigInteger.prototype.exp=bnpExp;BigInteger.prototype.toString=bnToString;BigInteger.prototype.negate=bnNegate;BigInteger.prototype.abs=bnAbs;BigInteger.prototype.compareTo=bnCompareTo;BigInteger.prototype.bitLength=bnBitLength;BigInteger.prototype.mod=bnMod;BigInteger.prototype.modPowInt=bnModPowInt;BigInteger.ZERO=nbv(0);BigInteger.ONE=nbv(1);function bnpFromRadix(s,b){this.fromInt(0);if(b==null)b=10;var cs=this.chunkSize(b);var d=Math.pow(b,cs),mi=false,j=0,w=0;for(var i=0;i=cs){this.dMultiply(d);this.dAddOffset(w,0);j=0;w=0}}if(j>0){this.dMultiply(Math.pow(b,j));this.dAddOffset(w,0)}if(mi)BigInteger.ZERO.subTo(this,this)}function bnpChunkSize(r){return Math.floor(Math.LN2*this.DB/Math.log(r))}function bnSigNum(){if(this.s<0)return-1;else if(this.t<=0||this.t==1&&this[0]<=0)return 0;else return 1}function bnpDMultiply(n){this[this.t]=this.am(0,n-1,this,0,0,this.t);++this.t;this.clamp()}function bnpDAddOffset(n,w){if(n==0)return;while(this.t<=w)this[this.t++]=0;this[w]+=n;while(this[w]>=this.DV){this[w]-=this.DV;if(++w>=this.t)this[this.t++]=0;++this[w]}}function bnpToRadix(b){if(b==null)b=10;if(this.signum()==0||b<2||b>36)return"0";var cs=this.chunkSize(b);var a=Math.pow(b,cs);var d=nbv(a),y=nbi(),z=nbi(),r="";this.divRemTo(d,y,z);while(y.signum()>0){r=(a+z.intValue()).toString(b).substr(1)+r;y.divRemTo(d,y,z)}return z.intValue().toString(b)+r}function bnIntValue(){if(this.s<0){if(this.t==1)return this[0]-this.DV;else if(this.t==0)return-1}else if(this.t==1)return this[0];else if(this.t==0)return 0;return(this[1]&(1<<32-this.DB)-1)<>=this.DB}if(a.t>=this.DB}c+=this.s}else{c+=this.s;while(i>=this.DB}c+=a.s}r.s=c<0?-1:0;if(c>0)r[i++]=c;else if(c<-1)r[i++]=this.DV+c;r.t=i;r.clamp()}BigInteger.prototype.fromRadix=bnpFromRadix;BigInteger.prototype.chunkSize=bnpChunkSize;BigInteger.prototype.signum=bnSigNum;BigInteger.prototype.dMultiply=bnpDMultiply;BigInteger.prototype.dAddOffset=bnpDAddOffset;BigInteger.prototype.toRadix=bnpToRadix;BigInteger.prototype.intValue=bnIntValue;BigInteger.prototype.addTo=bnpAddTo;var Wrapper={abs:(function(l,h){var x=new goog.math.Long(l,h);var ret;if(x.isNegative()){ret=x.negate()}else{ret=x}HEAP32[tempDoublePtr>>2]=ret.low_;HEAP32[tempDoublePtr+4>>2]=ret.high_}),ensureTemps:(function(){if(Wrapper.ensuredTemps)return;Wrapper.ensuredTemps=true;Wrapper.two32=new BigInteger;Wrapper.two32.fromString("4294967296",10);Wrapper.two64=new BigInteger;Wrapper.two64.fromString("18446744073709551616",10);Wrapper.temp1=new BigInteger;Wrapper.temp2=new BigInteger}),lh2bignum:(function(l,h){var a=new BigInteger;a.fromString(h.toString(),10);var b=new BigInteger;a.multiplyTo(Wrapper.two32,b);var c=new BigInteger;c.fromString(l.toString(),10);var d=new BigInteger;c.addTo(b,d);return d}),stringify:(function(l,h,unsigned){var ret=(new goog.math.Long(l,h)).toString();if(unsigned&&ret[0]=="-"){Wrapper.ensureTemps();var bignum=new BigInteger;bignum.fromString(ret,10);ret=new BigInteger;Wrapper.two64.addTo(bignum,ret);ret=ret.toString(10)}return ret}),fromString:(function(str,base,min,max,unsigned){Wrapper.ensureTemps();var bignum=new BigInteger;bignum.fromString(str,base);var bigmin=new BigInteger;bigmin.fromString(min,10);var bigmax=new BigInteger;bigmax.fromString(max,10);if(unsigned&&bignum.compareTo(BigInteger.ZERO)<0){var temp=new BigInteger;bignum.addTo(Wrapper.two64,temp);bignum=temp}var error=false;if(bignum.compareTo(bigmin)<0){bignum=bigmin;error=true}else if(bignum.compareTo(bigmax)>0){bignum=bigmax;error=true}var ret=goog.math.Long.fromString(bignum.toString());HEAP32[tempDoublePtr>>2]=ret.low_;HEAP32[tempDoublePtr+4>>2]=ret.high_;if(error)throw"range error"})};return Wrapper})();if(memoryInitializer){if(ENVIRONMENT_IS_NODE||ENVIRONMENT_IS_SHELL){var data=Module["readBinary"](memoryInitializer);HEAPU8.set(data,STATIC_BASE)}else{addRunDependency("memory initializer");Browser.asyncLoad(memoryInitializer,(function(data){HEAPU8.set(data,STATIC_BASE);removeRunDependency("memory initializer")}),(function(data){throw"could not load memory initializer "+memoryInitializer}))}}function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}ExitStatus.prototype=new Error;ExitStatus.prototype.constructor=ExitStatus;var initialStackTop;var preloadStartTime=null;var calledMain=false;dependenciesFulfilled=function runCaller(){if(!Module["calledRun"]&&shouldRunNow)run();if(!Module["calledRun"])dependenciesFulfilled=runCaller};Module["callMain"]=Module.callMain=function callMain(args){assert(runDependencies==0,"cannot call main when async dependencies remain! (listen on __ATMAIN__)");assert(__ATPRERUN__.length==0,"cannot call main when preRun functions remain to be called");args=args||[];ensureInitRuntime();var argc=args.length+1;function pad(){for(var i=0;i<4-1;i++){argv.push(0)}}var argv=[allocate(intArrayFromString(Module["thisProgram"]||"/bin/this.program"),"i8",ALLOC_NORMAL)];pad();for(var i=0;i0){Module.printErr("run() called, but dependencies remain, so not running");return}preRun();if(runDependencies>0)return;if(Module["calledRun"])return;function doRun(){if(Module["calledRun"])return;Module["calledRun"]=true;ensureInitRuntime();preMain();if(ENVIRONMENT_IS_WEB&&preloadStartTime!==null){Module.printErr("pre-main prep time: "+(Date.now()-preloadStartTime)+" ms")}if(Module["_main"]&&shouldRunNow){Module["callMain"](args)}postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout((function(){setTimeout((function(){Module["setStatus"]("")}),1);if(!ABORT)doRun()}),1)}else{doRun()}}Module["run"]=Module.run=run;function exit(status){ABORT=true;EXITSTATUS=status;STACKTOP=initialStackTop;exitRuntime();throw new ExitStatus(status)}Module["exit"]=Module.exit=exit;function abort(text){if(text){Module.print(text);Module.printErr(text)}ABORT=true;EXITSTATUS=1;var extra="\nIf this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.";throw"abort() at "+stackTrace()+extra}Module["abort"]=Module.abort=abort;if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}var shouldRunNow=true;if(Module["noInitialRun"]){shouldRunNow=false}run() - - - - diff --git a/DIST/web/imagenes/logo_lonelyruins_web.png b/DIST/web/imagenes/logo_lonelyruins_web.png deleted file mode 100644 index a7bf849..0000000 Binary files a/DIST/web/imagenes/logo_lonelyruins_web.png and /dev/null differ diff --git a/DIST/web/imagenes/logo_lonelyruins_web_mini.png b/DIST/web/imagenes/logo_lonelyruins_web_mini.png deleted file mode 100644 index 94d9281..0000000 Binary files a/DIST/web/imagenes/logo_lonelyruins_web_mini.png and /dev/null differ diff --git a/DIST/web/imgview/anterior.png b/DIST/web/imgview/anterior.png deleted file mode 100644 index dace661..0000000 Binary files a/DIST/web/imgview/anterior.png and /dev/null differ diff --git a/DIST/web/imgview/cargando.gif b/DIST/web/imgview/cargando.gif deleted file mode 100644 index 6bdc3b5..0000000 Binary files a/DIST/web/imgview/cargando.gif and /dev/null differ diff --git a/DIST/web/imgview/fondo.png b/DIST/web/imgview/fondo.png deleted file mode 100644 index 7c97f18..0000000 Binary files a/DIST/web/imgview/fondo.png and /dev/null differ diff --git a/DIST/web/imgview/imgview.css b/DIST/web/imgview/imgview.css deleted file mode 100644 index 9cef235..0000000 --- a/DIST/web/imgview/imgview.css +++ /dev/null @@ -1,71 +0,0 @@ -/*********************************************** - * Copyright (c) 2010 Valeriano Alfonso * - ***********************************************/ -/* - NOTA DE DOMINIO PUBLICO - ----------------------- - ImgView es Dominio Publico. Esto significa que se puede hacer con el - lo que se quiera sin haber ninguna garantia de reembolso o idoneidad. - Se aprecia que la fuente sea citada. -*/ - -#imgview_fondo { - background-image: url(fondo.png); -} - -#imgview_imgcargando { - border: 10px solid white; -} - -#imgview_fondo a { - padding:0px; - margin:0px; -} - -#imgview { - background-color: white; - border: 10px solid white; -} - -#imgview img { - border: none; - padding:0px; - margin:0px; -} - -#imgview a { - padding:0px; - margin:0px; -} - -#imgview_control { - height: 30px; - background-color: white; -} - -#imgview_anterior { - background-color: white; - float: left; - width: 50%; - height:32px; - border:0px; - padding:0px; - margin:0px; - background-image:url('anterior.png'); - background-repeat:no-repeat; - background-position: 50% 0%; - cursor:pointer; -} -#imgview_siguiente { - background-color: white; - float: right; - width: 50%; - height:32px; - border:0px; - padding:0px; - margin:0px; - background-image:url('siguiente.png'); - background-repeat:no-repeat; - background-position: 50% 0%; - cursor:pointer; -} \ No newline at end of file diff --git a/DIST/web/imgview/imgview.js b/DIST/web/imgview/imgview.js deleted file mode 100644 index c924bc9..0000000 --- a/DIST/web/imgview/imgview.js +++ /dev/null @@ -1,497 +0,0 @@ -/*********************************************** - * Copyright (c) 2010 Valeriano Alfonso * - ***********************************************/ -/* - NOTA DE DOMINIO PUBLICO - ----------------------- - ImgView es Dominio Publico. Esto significa que se puede hacer con el - lo que se quiera sin haber ninguna garantia de reembolso o idoneidad. - Se aprecia que la fuente sea citada. -*/ - - -/* - Historial de cambios - -------------------- - 1.0 2010-1-3 : - * Version inicial. - 1.1 2010-1-5 : - * Corregida necesidad de cargar el script en la seccion head. - * Funcionalidad basica de album implementada. - 1.2 2010-5-18 : - * Asimilado de todos los enlaces a imagenes en un album general. - * Iconos de anterior y siguiente de los albums, nuevos. -*/ - -///////////////////////// -// Configuracion -// -var imgview_prefix = ""; // Se atoconfigura -var imgview_border = 10; // Tambien ajustar en el CSS. -var imgview_control_alto = 32; // Tambien ajustar en el CSS. - - - - -/////////////////////// -// Globales -// -var imgview_nombre_album=""; -var imgview_href_anterior=""; -var imgview_href_siguiente=""; -var imgview_preloader=false; - -///////////////////////////////////// -// ImgView_ShowImage -// - -function ImgView_ShowImage(href,is_album){ - var elemFondo = document.getElementById('imgview_fondo'); - var elemImgview = document.getElementById('imgview'); - var elemImgviewControl = document.getElementById('imgview_control'); - var elemImgCargando = document.getElementById('imgview_imgcargando'); - var elemEnlace = document.getElementById('imgview_enlace'); - var elemImg = document.getElementById('imgview_img'); - var elemAnt = document.getElementById('imgview_anterior'); - var elemSig = document.getElementById('imgview_siguiente'); - var preloader; - var max_horiz, max_vert; - var ventana_ancho, ventana_alto; - var pagina_ancho, pagina_alto; - var pos_horiz = 0, pos_vert = 0; - - - if(is_album){ - var enlaces; - var imgview_RegExp; - var nombre_temp; - var i,j; - - // Buscar imagenes anterior y siguientes - enlaces = document.getElementsByTagName("a"); - for(i=0;i0){ - j=i-1; - while(j>=0){ - if(enlaces[j].getAttribute("imgview_albumid")== - imgview_nombre_album) - { - imgview_href_anterior=enlaces[j].getAttribute("href"); - break; - } - j--; - } - } - - // Buscar Siguiente - imgview_href_siguiente=""; - if(i<(enlaces.length-1)){ - j=i+1; - while(j document.body.offsetHeight){ - // all but Explorer Mac - max_horiz = document.body.scrollWidth; - max_vert = document.body.scrollHeight; - }else{ - // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari - max_horiz = document.body.offsetWidth; - max_vert = document.body.offsetHeight; - } - - // Obtener tamanho de la ventana - if(window.innerHeight) { - // Todos excepto Explorer - ventana_ancho = window.innerWidth; - ventana_alto = window.innerHeight; - }else if(document.documentElement && document.documentElement.clientHeight){ - // Explorer 6 Strict - ventana_ancho = document.documentElement.clientWidth; - ventana_alto = document.documentElement.clientHeight; - }else if(document.body){ - // Resto de Explorers - ventana_ancho = document.body.clientWidth; - ventana_alto = document.body.clientHeight; - } - - // HACK: reducir el tamaho de ventana_ancho. Hace que no sobrepase los bordes - ventana_ancho-=20; - - // Obtener el tamanho de la pagina - if(max_vert < ventana_alto){ - pagina_alto = ventana_alto; - }else{ - pagina_alto = max_vert; - } - if(max_horiz < ventana_ancho){ - pagina_ancho = ventana_ancho; - }else{ - pagina_ancho = max_horiz; - } - - // Obtener posicion del los scrolls - if( typeof( window.pageYOffset ) == 'number' ) { - // La mayoria de navegadores - pos_vert = window.pageYOffset; - pos_horiz = window.pageXOffset; - } else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) { - // Explorer - pos_vert = document.body.scrollTop; - pos_horiz = document.body.scrollLeft; - } else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) { - // Explorer 6 Strict - pos_vert = document.documentElement.scrollTop; - pos_horiz = document.documentElement.scrollLeft; - } - - - - // Centrar y hacer visible la imagen de cargando - if(elemImgCargando){ - elemImgCargando.style.top = - (pos_vert + - ((ventana_alto - elemImgCargando.height) / 2)) + 'px'; - elemImgCargando.style.left = - (pos_horiz + - ((ventana_ancho - elemImgCargando.width) / 2)) + 'px'; - elemImgCargando.style.display = 'block'; - } - - // Hacer que el fondo ocupe la pagina y sea visible - elemFondo.style.height = (pagina_alto + 'px'); - elemFondo.style.display = 'block'; - - // Carga de la imagen - imgview_preloader=new Image(); - imgview_preloader.onload=function(){ - - // Mostrar imgview, necesario para que los tamanhos sean correctos - elemImgview.style.display = 'block'; - - // Mostrar/Ocultar control de albums - if(is_album){ - elemImgviewControl.style.display = 'block'; - ventana_alto-=imgview_control_alto; - if(imgview_href_anterior.length==0){ - elemAnt.style.display = 'none'; - }else{ - elemAnt.style.display = 'block'; - } - if(imgview_href_siguiente.length==0){ - elemSig.style.display = 'none'; - }else{ - elemSig.style.display = 'block'; - } - }else{ - elemImgviewControl.style.display = 'none'; - } - - // Establecer la imagen precargada - elemImg.src = href; - elemImg.width = imgview_preloader.width; - elemImg.height = imgview_preloader.height; - - // Ajustar el tamanho de la imagen - var relacion=elemImg.width/elemImg.height; - if((elemImg.height+imgview_border*2)>ventana_alto){ - elemImg.height=ventana_alto-imgview_border*2; - elemImg.width=elemImg.height*relacion; - } - if((elemImg.width+imgview_border*2)>ventana_ancho){ - elemImg.width=ventana_ancho-imgview_border*2; - elemImg.height=elemImg.width/relacion; - } - - // Centrar imgview - elemImgview.style.top = - (pos_vert + - ((ventana_alto - elemImg.height) / 2) - imgview_border) + 'px'; - elemImgview.style.left = - (pos_horiz + - ((ventana_ancho - elemImg.width) / 2) - imgview_border) + 'px'; - - - // Oclultar imagen de cargar y mostrar imgview - if(elemImgCargando) { - elemImgCargando.style.display = 'none'; - } - - return false; - } - imgview_preloader.src = href; - elemEnlace.href = href; -} - - - - - - - - - -///////////////////////////////////// -// ImgView_Show -// -function ImgView_Show(obj){ - imgview_nombre_album=obj.getAttribute("imgview_albumid"); - if(imgview_nombre_album){ - ImgView_ShowImage(obj.getAttribute("href"),true); - }else{ - ImgView_ShowImage(obj.getAttribute("href"),false); - } -} - - - - - -///////////////////////////////////// -// ImgView_Hide -// -function ImgView_Hide(){ - var elemFondo = document.getElementById('imgview_fondo'); - var elemImgview = document.getElementById('imgview'); - var elemImgCargando = document.getElementById('imgview_imgcargando'); - var elemEnlace = document.getElementById('imgview_enlace'); - elemFondo.style.display = 'none'; - elemImgview.style.display = 'none'; - elemImgCargando.style.display = 'none'; - imgview_preloader.onload=function(){return false;} - imgview_preloader.src = ""; - elemEnlace.href = ""; -} - - - - - -///////////////////////////////////// -// ImgView_ShowAnterior -// -function ImgView_ShowAnterior(obj){ - if(imgview_href_anterior.length){ - ImgView_ShowImage(imgview_href_anterior,true); - } -} - - - - -///////////////////////////////////// -// ImgView_ShowSiguiente -// -function ImgView_ShowSiguiente(obj){ - if(imgview_href_siguiente.length){ - ImgView_ShowImage(imgview_href_siguiente,true); - } -} - - - - - -///////////////////////////////////// -// ImgView_Init -// -// Asociar al evento "onclick" la funcion "ImgView_Show" a los links con rel="imgview". -// Anhadir el markup necesario para mostrar imagenes. -function ImgView_Init(){ - var i; - var enlaces; - var scripts; - var imgview_RegExp; - var isimage_RegExp; - - if (!document.getElementsByTagName){ - return; - } - - // HACK: Obtener el path donde de este mismo script - scripts=document.getElementsByTagName("script"); - imgview_RegExp = /imgview\.js$/i; - for(i=0;i - -Con esto todos los enlaces a imagenes usaran imgview. Es recomendable -insertar una imagen en miniatura dentro del enlace. - -Uso Avanzado: -------------- - -Para mostrar una imagen independiente de cualquier album: - - - -Para crear albumes independientes; poner a todas las imagenes del mismo grupo -rel="imgview.album", siendo "album" el nombre para esa coleccion: - - - - -Licencia: ---------- - ImgView es Dominio Publico. Esto significa que se puede hacer con el - lo que se quiera sin haber ninguna garantia de reembolso o idoneidad. - Se aprecia que la fuente sea citada. - - -Copyright (c) 2010 Valeriano Alfonso diff --git a/DIST/web/imgview/siguiente.png b/DIST/web/imgview/siguiente.png deleted file mode 100644 index 0cc0213..0000000 Binary files a/DIST/web/imgview/siguiente.png and /dev/null differ diff --git a/DIST/web/index.html b/DIST/web/index.html deleted file mode 100644 index 0d20967..0000000 --- a/DIST/web/index.html +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - - - - - - -Lonely Ruins - - - -