65a49b60bcd9d79ea242530596b3e394d10592c0
[WebKit-https.git] / PerformanceTests / JetStream / Octane2 / mandreel.js
1 // Portions copyright 2012 Google, Inc.
2 // Copyright 2012 Onan Games. All rights reserved.
3 // Redistribution and use in source and binary forms, with or without
4 // modification, are permitted provided that the following conditions are
5 // met:
6 //
7 //     * Redistributions of source code must retain the above copyright
8 //       notice, this list of conditions and the following disclaimer.
9 //     * Redistributions in binary form must reproduce the above
10 //       copyright notice, this list of conditions and the following
11 //       disclaimer in the documentation and/or other materials provided
12 //       with the distribution.
13 //     * Neither the name of Google Inc. nor the names of its
14 //       contributors may be used to endorse or promote products derived
15 //       from this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29 var MandreelBenchmark = new BenchmarkSuite('Mandreel', [16831872, 49852],
30                                             [new Benchmark('Mandreel',
31                                                            false,
32                                                            false,
33                                                            runMandreel,
34                                                            setupMandreel,
35                                                            tearDownMandreel,
36                                                            RMSMandreel,
37                                                            4)]);
38
39 var mandreelSumSquaredPauses = 0;
40 var mandreelSamples = 0;
41 var mandreelSampleTimeStart = 0.0;
42
43 function setupMandreel() {
44   // Check for Typed Arrays support, throw error if not.
45   if (!(typeof Uint8Array != "undefined" &&
46     typeof Float64Array != "undefined" &&
47     typeof (new Uint8Array(0)).subarray != "undefined")) {
48       throw "TypedArrayUnsupported";
49   }
50
51   my_old_constructors = mandreel_call_constructors;
52   mandreel_call_constructors = my_mandreel_call_constructors;
53   startMandreelTimer();
54   startApp();
55   _mandreelAppAudioReady();
56 }
57
58 function runMandreel() {
59   Mandreel_currentTime = 0;
60   var sp = g_stack_pointer+800*1024;
61   for (var i=0;i<mandreel_total_memory/4;i++) {
62     heap32[i] = my_heap32[i];
63   }
64   tlsf_ptr = 0;
65   heapNewPos = my_heapNewPos;
66   my_old_constructors(llvm_2E_global_ctors,5,sp);
67   heapU32[sp>>2] = 640;
68   heapU32[(sp+4)>>2] = 480;
69   __mandreel_internal_SetResolution(sp);
70   __mandreel_internal_init(g_stack_pointer+800*1024);
71   __init(g_stack_pointer+800*1024);
72   for (var i = 0; i < 20; i++) {
73     render();
74     Mandreel_flushTimeouts();
75     updateMandreelStats(performance.now());
76   }
77   Mandreel_checkState();
78 }
79
80 function updateMandreelStats(time) {
81   var pause = time - mandreelSampleTimeStart;
82   mandreelSampleTimeStart = time;
83   mandreelSumSquaredPauses += (pause * pause);
84   mandreelSamples++;
85 }
86
87 function startMandreelTimer() {
88   mandreelSampleTimeStart = performance.now();
89 }
90
91 function RMSMandreel() {
92   return Math.round(Math.sqrt(mandreelSumSquaredPauses / mandreelSamples) * 100);
93 }
94
95 function tearDownMandreel() {
96   my_old_constructors = null;
97   my_heap = null;
98   my_heap8 = null;
99   my_heap32 = null;
100
101   heap = null;
102   heap8 = null;
103   heapU8 = null;
104   heap16 = null;
105   heapU16 = null;
106   heap32 = null;
107   heapU32 = null;
108   heapFloat = null;
109   heapDouble = null;
110   mandreelAppUsePackAsyncTexture = null;
111   mandreelSumSquaredPauses = 0;
112   mandreelSamples = 0;
113 }
114
115 // Mocks for browser functions.
116
117 function Mandreel_setTimeout(cmd, delay) {
118   timeouts.push(cmd);
119 }
120
121 function Mandreel_flushTimeouts() {
122   while (Mandreel_timeouts.length != 0) {
123     var next = Mandreel_timeouts.pop();
124     eval(next);
125   }
126 }
127
128 Mandreel_timeouts = new Array();
129
130 Mandreel_XMLHttpRequest = function() {
131   this.open = function(type, url, some_bool) {
132     this.url = url;
133   }
134   this.overrideMimeType = function() {
135   }
136   this.send = function() {
137     this.response = null;
138     this.readyState = 4;
139     this.status = 0;
140     this.onreadystatechange();
141   }
142 };
143
144 function Mandreel_Element(type) {
145   this.element_type = type;
146   this.insertBefore = function() {
147   }
148 }
149
150
151 function Mandreel_Context() {
152 }
153
154 function Mandreel_Canvas() {
155 }
156
157 function Mandreel_CanvasDiv() {
158 }
159
160 Mandreel_document = {
161   createElement : function(element_type) {
162     var element = new Mandreel_Element(element_type);
163     element.parentNode = new Mandreel_Element("dummy_parent");
164     return element;
165   },
166   getElementById : function(name) {
167     if (name === "canvas") {
168       return new Mandreel_Canvas();
169     } else if (name === "canvasDiv") {
170       return new Mandreel_CanvasDiv();
171     } else {
172       return undefined;
173     }
174   },
175   getElementsByTagName : function(element) {
176     if (element === "script") {
177       return new Array(new this.createElement(element));
178     }
179   }
180
181 };
182
183 Mandreel_window = {
184   WebGLRenderingContext: {},
185   Float64Array: Float64Array,
186   Float32Array: Float32Array,
187   Int32Array: Int32Array,
188   Uint32Array: Uint32Array,
189   Int16Array: Int16Array,
190   Uint16Array: Uint16Array,
191   Int8Array: Int8Array,
192   Uint8Array: Uint8Array,
193   setTimeout: Mandreel_setTimeout,
194   addEventListener : function () {},
195   document: Mandreel_document
196 };
197
198 function dump(x) { }
199
200 alert = typeof alert != "undefined" ? alert : function(x) {
201   print(x);
202 }
203
204 var my_old_constructors;
205 var my_heap;
206 var my_heap8;
207 var my_heap32;
208 var my_heapNewPos;
209
210 function my_mandreel_call_constructors(_ptr, size,stackPos) {
211   my_heapNewPos = heapNewPos;
212   my_heap = new ArrayBuffer(mandreel_total_memory);
213   my_heap8 = new Int8Array(my_heap);
214   my_heap32 = new Int32Array(my_heap);
215   for (var i=0;i<mandreel_total_memory/4;i++) {
216     my_heap32[i] = heap32[i];
217   }
218   my_old_constructors(_ptr,size,stackPos);
219 }
220
221
222 var Mandreel_currentTime = 0;
223
224 function Date_now() {
225    Mandreel_currentTime += 16;
226    return Mandreel_currentTime;
227 }
228
229 function Mandreel_checkState() {
230   var sum = 0;
231   for (var i = 0; i < heap32.length; i += 100) {
232     sum = (sum * 3 + heap32[i]) & 0xFFFFFF;
233   }
234   if (sum != 8001026) {
235     alert("Check sum mismatch: expected ???, actual " + sum);
236   }
237 }
238
239 // Original Mandreel code follows.
240 // Modifications for benchmarking are marked in comments.
241
242 // Start of js/main.js file:
243
244 ////////////////////////////////////////////
245 function startApp(_platform)
246 {
247         // Start mandreel
248         var params =
249         {
250                 platform : _platform,
251                 width : 1024,
252                 height : 768,
253                 webglCanvas : "canvas",
254                 flashCanvas : "FlashDiv",
255                 workingFolderFlash : "data/as3/",
256                 workingFolderWebgl : "data/js/",
257                 swfFlash : "mandreel.swf",
258                 log : true
259         };
260         mandreelAppStart(appStartState,params);
261 }
262
263 ////////////////////////////////////////////
264 function appStartState(state,param)
265 {
266         // mandreel.js program is been loaded
267         if ( state == "loadingScript" )
268         {
269         }
270
271         // mandreel.js program has been loaded
272         if ( state == "scriptLoaded" )
273         {
274         }
275
276         // loading pack data file
277         if (state == "loadingData")
278         {
279                 // param bytes loaded
280         }
281
282         // Audio system is been started
283         if ( state == "loadingAudio" )
284         {
285         }
286
287         // Audio system is ready and the default audio preloading has been done
288         if ( state == "audioLoaded" )
289         {
290         }
291
292
293
294         // Mandreel has been started, render will start automatically
295         if ( state == "ready" )
296         {
297                 // Hide loading image
298                 var canvasElement = Mandreel_document.getElementById('loading');
299                 if ( canvasElement != null )
300                         canvasElement.style.visibility = "hidden";
301         }
302
303         // An error has been produced during the start process and the app must quit
304         if ( state == "error" )
305         {
306                 if ( param == "webgl_not_found" )
307                 {
308                         window.location = "http://get.webgl.org";
309                         return;
310                 }
311                 alert(param);
312         }
313 }
314
315 // End of js/main.js file.
316
317 // Start of js/mandreelapp.js file.
318
319 var mandreelAppMandreelJs = "mandreel.js";
320 var mandreelAppMandreelJsCompressed = false;
321 var mandreelAppWorkingFolder = "data/js/";
322 var mandreelAppLog = false;
323 var mandreelAppLocalHost = "http://localhost";
324 var mandreelAppReadDataFromLocalHost = false;
325 var mandreelAppReadMandreelJsFromLocalHost = false;
326 var mandreelAppHostedAudioServer = null;
327 var mandreelAppHostedAudioUrl = null;
328 var mandrelCurrentFatVersion = "1.4";
329 var mandreelAppPlatform = "webgl";
330 var mandreelAppCanvasWidth = 1024;
331 var mandreelAppCanvasHeight = 768;
332 var mandreelAppWidthSrc = 1024;
333 var mandreelAppHeightSrc = 768;
334 var mandreelAppCanvasName = "canvas";
335 var mandreelAppCanvasDiv = "canvasDiv";
336 var mandreelAppUseFlashSockets = false;
337 var mandreelAppUsePackAsyncTexture = new Array();
338 //var mandreelBufferPackAsyncTexture = null;
339 var mandreelAppForceFocus = true;
340 var _imandreel_pause_game = false;
341
342 /* The following code was removed for benchmarking:
343 navigator.pointer = navigator.pointer || navigator.webkitPointer || navigator.mozPointer || null;*/
344
345 /* The following code was removed for benchmarking:
346  if (!Date_now) {
347    Date_now = function() {
348      return +new Date();
349    };
350  };*/
351
352 ////////////////////////////////////////////
353
354 if (Mandreel_window["console"])
355 {
356         if (!Mandreel_window["dump"]) Mandreel_window["dump"] = function dump(str){ if ( mandreelAppLog ) console.log(str) };
357 }
358 else
359 {
360         if (!Mandreel_window["dump"]) Mandreel_window["dump"] = function dump(str){ };
361 }
362
363 /* The following code is removed for benchmarking:
364 var mandreel_BrowserDetect = {
365         init: function () {
366                 this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
367                 this.version = this.searchVersion(navigator.userAgent)
368                         || this.searchVersion(navigator.appVersion)
369                         || "an unknown version";
370                 this.OS = this.searchString(this.dataOS) || "an unknown OS";
371         },
372         searchString: function (data) {
373                 for (var i=0;i<data.length;i++) {
374                         var dataString = data[i].string;
375                         var dataProp = data[i].prop;
376                         this.versionSearchString = data[i].versionSearch || data[i].identity;
377                         if (dataString) {
378                                 if (dataString.indexOf(data[i].subString) != -1)
379                                         return data[i].identity;
380                         }
381                         else if (dataProp)
382                                 return data[i].identity;
383                 }
384         },
385         searchVersion: function (dataString) {
386                 var index = dataString.indexOf(this.versionSearchString);
387                 if (index == -1) return;
388                 return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
389         },
390         dataBrowser: [
391                 {
392                         string: navigator.userAgent,
393                         subString: "Chrome",
394                         identity: "Chrome"
395                 },
396                 {       string: navigator.userAgent,
397                         subString: "OmniWeb",
398                         versionSearch: "OmniWeb/",
399                         identity: "OmniWeb"
400                 },
401                 {
402                         string: navigator.vendor,
403                         subString: "Apple",
404                         identity: "Safari",
405                         versionSearch: "Version"
406                 },
407                 {
408                         prop: window.opera,
409                         identity: "Opera",
410                         versionSearch: "Version"
411                 },
412                 {
413                         string: navigator.vendor,
414                         subString: "iCab",
415                         identity: "iCab"
416                 },
417                 {
418                         string: navigator.vendor,
419                         subString: "KDE",
420                         identity: "Konqueror"
421                 },
422                 {
423                         string: navigator.userAgent,
424                         subString: "Firefox",
425                         identity: "Firefox"
426                 },
427                 {
428                         string: navigator.vendor,
429                         subString: "Camino",
430                         identity: "Camino"
431                 },
432                 {               // for newer Netscapes (6+)
433                         string: navigator.userAgent,
434                         subString: "Netscape",
435                         identity: "Netscape"
436                 },
437                 {
438                         string: navigator.userAgent,
439                         subString: "MSIE",
440                         identity: "Explorer",
441                         versionSearch: "MSIE"
442                 },
443                 {
444                         string: navigator.userAgent,
445                         subString: "Gecko",
446                         identity: "Mozilla",
447                         versionSearch: "rv"
448                 },
449                 {               // for older Netscapes (4-)
450                         string: navigator.userAgent,
451                         subString: "Mozilla",
452                         identity: "Netscape",
453                         versionSearch: "Mozilla"
454                 }
455         ],
456         dataOS : [
457                 {
458                         string: navigator.platform,
459                         subString: "Win",
460                         identity: "Windows"
461                 },
462                 {
463                         string: navigator.platform,
464                         subString: "Mac",
465                         identity: "Mac"
466                 },
467                 {
468                            string: navigator.userAgent,
469                            subString: "iPhone",
470                            identity: "iPhone/iPod"
471             },
472                 {
473                         string: navigator.platform,
474                         subString: "Linux",
475                         identity: "Linux"
476                 }
477         ]
478
479 };
480 mandreel_BrowserDetect.init(); */
481
482 ////////////////////////////////////////////
483 var mandreel_packfiledata_name = null;
484 var mandreel_packfiledata_compressed = false;
485 var mandreel_packfiledata_size = 0;
486 var mandreel_total_packtexture_size = 0;
487 var mandreel_total_pogfile_size = 0;
488 var mandreel_loaded_packtexture_size = 0;
489 var mandreel_jslzma_size = 0;
490 var mandreel_swf_size = 0;
491
492 var mandreelJsScriptLoaded_loaded = false;
493
494 var mandreel_swf_last_total_size = 0;
495 function mandreel_swf_size_updated(str)
496 {
497         var params = str.split(',');
498         if ( mandreel_swf_size == 0 )
499         {
500                 mandreel_swf_last_loaded_size = 0;
501         }
502         mandreel_swf_size = parseInt(params[0]);
503         var loaded = parseInt(params[1]);
504         var delta_size = loaded - mandreel_swf_last_loaded_size;
505         mandreel_swf_last_loaded_size = loaded;
506
507         var percentage = ((100*loaded)/mandreel_swf_size)|0;
508         if (percentage>100)
509                 percentage = 100;
510
511         if ( mandreelAppStartStateFunc )
512                 mandreelAppStartStateFunc("loadingScriptUpdate",percentage);
513
514         imandreel_update_load(delta_size,0);
515 }
516
517 function mandreel_swf_size_loaded(str)
518 {
519         if ( mandreelAppStartStateFunc )
520                 mandreelAppStartStateFunc("scriptLoaded","");
521 }
522
523 function mandreelNextDecompress(mandreel_result_lzma)
524 {
525
526         if ( mandreelAppStartStateFunc )
527         {
528                 var totalBytesLeft = mandreel_result_lzma.totalSize - mandreel_result_lzma.remainingBytes;
529
530                 var percentage;
531
532                 if (totalBytesLeft == 0)
533                         percentage = 0;
534                 else
535                         percentage = ((100*totalBytesLeft)/mandreel_result_lzma.totalSize)|0;
536
537                 mandreelAppStartStateFunc("uncompressingDataUpdate",percentage);
538         }
539
540         var old_result = mandreel_result_lzma;
541         mandreel_result_lzma = LZMA.decompress2(mandreel_result_lzma.inStream,mandreel_result_lzma.inStream,mandreel_result_lzma.outStream,mandreel_result_lzma);
542
543         if (mandreel_result_lzma == null)
544         {
545                 //setTimeout(mandreelLoadScript,10,old_result.my_outStream.data);
546
547                 //mandreel_fs_saveFile('data.bin', old_result.my_outStream.arrayBuffer);
548                 //callback(old_result.my_outStream.arrayBuffer);
549                 //alert('done');
550                 mandreelLoadPackData(old_result.my_outStream.arrayBuffer,true);
551         }
552         else
553         {
554                 Mandreel_setTimeout(mandreelNextDecompress,10,mandreel_result_lzma);
555         }
556
557
558 }
559
560 function mandreel_load_packfile(array_buffer)
561 {
562         if (array_buffer)
563         {
564                 mandreelLoadPackData(array_buffer,false);
565                 return;
566         }
567
568         var working_folder = mandreelAppWorkingFolder;
569         if ( mandreelAppReadDataFromLocalHost )
570                 working_folder = mandreelAppLocalHost+"/"+mandreelAppWorkingFolder;
571         var packdata_request = new XMLHttpRequest();
572         var url = working_folder+mandreel_packfiledata_name;
573
574         packdata_request.open("GET", url, true);
575
576         if("responseType" in packdata_request)
577                 packdata_request.responseType="arraybuffer";
578         else
579                 packdata_request.overrideMimeType('text/plain; charset=x-user-defined');
580
581         var last_loaded_size = 0;
582
583         packdata_request.onreadystatechange = function()
584         {
585                 if (packdata_request.readyState != 4) return;
586
587                 if (packdata_request.status == 200)
588                 {
589                         var buffer;
590                         if (packdata_request.responseType=="arraybuffer")
591                                 buffer=packdata_request.response;
592                         else if (packdata_request.mozResponseArrayBuffer != null)
593                                 buffer = packdata_request.mozResponseArrayBuffer;
594                         else
595                                 buffer=packdata_request.response;
596
597                         if (mandreel_packfiledata_compressed)
598                         {
599                                 var inStream = {
600                                   data: new Uint8Array(buffer),
601                                   offset: 0,
602                                   readByte: function(){
603                                         return this.data[this.offset ++];
604                                   }
605                                 };
606
607                                 var outStream = {
608                                   data: null,
609                                   offset: 0,
610                                   binary_mode : true,
611                                   writeByte: function(value){
612                                         this.data[this.offset ++] = value;
613                                   }
614                                 };
615
616
617                                 var result = LZMA.decompress2(inStream,inStream,outStream,null);
618
619                                 if (result == null)
620                                         mandreelLoadPackData(outStream.arrayBuffer,true);
621                                 else
622                                         Mandreel_setTimeout(mandreelNextDecompress,10,result);
623                         }
624                         else
625                                 mandreelLoadPackData(buffer,true);
626                 }
627                 else
628                 {
629                         if ( mandreelAppStartStateFunc )
630                                 mandreelAppStartStateFunc("error","can't load packfile data");
631                 }
632         }
633         packdata_request.onprogress = function(e)
634         {
635                 var delta_size = e.loaded - last_loaded_size;
636                 last_loaded_size = e.loaded;
637                 var percentage = ((100*e.loaded)/mandreel_packfiledata_size)|0;
638
639
640                 imandreel_update_load(delta_size,0);
641
642                 if (percentage>100)
643                         percentage = 100;
644
645                 if ( mandreelAppStartStateFunc )
646                         mandreelAppStartStateFunc("loadingData",percentage);
647         }
648
649         packdata_request.send();
650 }
651
652 function mandreelJsScriptLoaded()
653 {
654         if (mandreelJsScriptLoaded_loaded)
655                 return;
656
657         if (typeof(mandreel_cache_files)=="undefined")
658         {
659                 Mandreel_setTimeout(mandreelJsScriptLoaded,10);
660                 return;
661         }
662
663         mandreelJsScriptLoaded_loaded = true;
664
665         if ( mandreelAppStartStateFunc )
666                 mandreelAppStartStateFunc("scriptLoaded","");
667
668         if (mandreel_packfiledata_name)
669         {
670
671                 mandreel_fs_load_binary(mandreel_packfiledata_name, mandreel_load_packfile);
672
673
674         }
675         else
676         {
677                 mandreelCacheMandreelFat();
678                 imandreelJsScriptLoaded();
679         }
680 }
681
682 function imandreelLoadAudio()
683 {
684         g_mandreel_working_folder = mandreelAppWorkingFolder;
685         if ( mandreelAppReadDataFromLocalHost )
686                 g_mandreel_working_folder = mandreelAppLocalHost+"/"+mandreelAppWorkingFolder;
687
688         // load audio
689         if ( mandreelAppStartStateFunc )
690                 mandreelAppStartStateFunc("loadingAudio","");
691         mandreel_start_audio(mandreelAppHostedAudioServer,mandreelAppHostedAudioUrl,_mandreelAppAudioReady);
692 }
693
694 var _mandreel_currentPackTexture = '';
695
696 function imandreel_packasynctexture_loaded(buffer,save_file)
697 {
698         if (save_file)
699                 mandreel_fs_saveFile(_mandreel_currentPackTexture,buffer);
700
701         //mandreelBufferPackAsyncTexture = buffer;
702         Mandreel_TextureAsync_PackBufferData[_mandreel_currentPackTexture] = buffer;
703
704         imandreelLoadNextTexturePack();
705 }
706
707 var mandreel_update_total_size = 0;
708
709 function imandreel_update_load(size, total)
710 {
711         if (total == 0)
712                 total = mandreel_packfiledata_size + mandreel_total_packtexture_size + mandreel_total_pogfile_size + mandreel_jslzma_size + mandreel_swf_size;
713
714
715         mandreel_update_total_size+=size;
716
717         var percentage = ((100*mandreel_update_total_size)/total)|0;
718
719         if (percentage>100)
720                 percentage = 100;
721         if (mandreelAppStartStateFunc)
722                 mandreelAppStartStateFunc("loadingProgress",percentage);
723
724 }
725
726
727 function imandreel_packasynctexture_load(array_buffer)
728 {
729         if (array_buffer)
730         {
731                 imandreel_packasynctexture_loaded(array_buffer, false);
732                 return;
733         }
734
735
736         var working_folder = mandreelAppWorkingFolder;
737         if ( mandreelAppReadDataFromLocalHost )
738                 working_folder = mandreelAppLocalHost+"/"+mandreelAppWorkingFolder;
739         var packdata_request = new XMLHttpRequest();
740         var url = working_folder+_mandreel_currentPackTexture;
741
742         packdata_request.open("GET", url, true);
743
744         if("responseType" in packdata_request)
745                 packdata_request.responseType="arraybuffer";
746         else
747                 packdata_request.overrideMimeType('text/plain; charset=x-user-defined');
748
749         var last_loaded_size = 0;
750
751         packdata_request.onreadystatechange = function()
752         {
753                 if (packdata_request.readyState != 4) return;
754
755                 if (packdata_request.status == 200)
756                 {
757                         var buffer;
758                         if (packdata_request.responseType=="arraybuffer")
759                                 buffer=packdata_request.response;
760                         else if (packdata_request.mozResponseArrayBuffer != null)
761                                 buffer = packdata_request.mozResponseArrayBuffer;
762                         else
763                                 buffer=packdata_request.response;
764
765                         imandreel_packasynctexture_loaded(buffer, true);
766                 }
767                 else
768                 {
769                         if ( mandreelAppStartStateFunc )
770                                 mandreelAppStartStateFunc("error","can't load textureasync pack data");
771                 }
772         }
773         packdata_request.onprogress = function(e)
774         {
775                 var delta_size = e.loaded - last_loaded_size;
776                 last_loaded_size = e.loaded;
777                 mandreel_loaded_packtexture_size+=delta_size;
778
779                 imandreel_update_load(delta_size,0);
780
781                 var percentage = ((100*mandreel_loaded_packtexture_size)/mandreel_total_packtexture_size)|0;
782
783                 if (percentage>100)
784                         percentage = 100;
785
786                 if ( mandreelAppStartStateFunc )
787                         mandreelAppStartStateFunc("loadingTextureAsyncPack",percentage);
788         }
789
790         packdata_request.send();
791
792 }
793
794 function imandreelLoadNextTexturePack()
795 {
796         if (mandreelAppUsePackAsyncTexture.length)
797         {
798                 _mandreel_currentPackTexture = mandreelAppUsePackAsyncTexture.pop();
799                 mandreel_fs_load_binary(_mandreel_currentPackTexture, imandreel_packasynctexture_load);
800         }
801         else
802                 imandreelLoadAudio();
803 }
804
805 function imandreelJsScriptLoaded()
806 {
807         imandreelLoadNextTexturePack();
808 }
809
810 ////////////////////////////////////////////
811
812 function mandreelDecompressJSReady(code, save_file)
813 {
814         if (save_file)
815                 mandreel_fs_saveFile(mandreelAppMandreelJs + ".lzma", code);
816
817         var ga = Mandreel_document.createElement('script');
818         ga.type = "text/javascript";
819         ga.text = code;
820         var s = Mandreel_document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
821         s.parentNode.removeChild(ga);
822         mandreelJsScriptLoaded();
823 }
824
825 function mandreelNextDecompressJS(mandreel_result_lzma)
826 {
827
828         if ( mandreelAppStartStateFunc )
829         {
830                 var totalBytesLeft = mandreel_result_lzma.totalSize - mandreel_result_lzma.remainingBytes;
831
832                 var percentage;
833
834                 if (totalBytesLeft == 0)
835                         percentage = 0;
836                 else
837                         percentage = ((100*totalBytesLeft)/mandreel_result_lzma.totalSize)|0;
838
839                 mandreelAppStartStateFunc("uncompressingScriptUpdate",percentage);
840         }
841
842         var old_result = mandreel_result_lzma;
843         mandreel_result_lzma = LZMA.decompress2(mandreel_result_lzma.inStream,mandreel_result_lzma.inStream,mandreel_result_lzma.outStream,mandreel_result_lzma);
844
845         if (mandreel_result_lzma == null)
846         {
847                 mandreelDecompressJSReady(old_result.my_outStream.data,true);
848         }
849         else
850         {
851                 Mandreel_setTimeout(mandreelNextDecompressJS,10,mandreel_result_lzma);
852         }
853
854
855 }
856
857 function mandreel_load_compressed_js(code_js)
858 {
859         if (code_js)
860         {
861                 mandreelDecompressJSReady(code_js,false);
862                 return;
863         }
864          var xmlhttp_get = new XMLHttpRequest();
865
866          var url = mandreelAppMandreelJs + ".lzma";
867          if ( mandreelAppReadMandreelJsFromLocalHost )
868                 url = mandreelAppLocalHost+"/"+url;
869
870          xmlhttp_get.open('GET',url);
871
872
873         if("responseType" in xmlhttp_get)
874                 xmlhttp_get.responseType="arraybuffer";
875         else
876                 xmlhttp_get.overrideMimeType('text/plain; charset=x-user-defined');
877
878         var last_loaded_size = 0;
879
880         xmlhttp_get.onreadystatechange = function()
881         {
882                 if (xmlhttp_get.readyState==4)
883                 {
884                         if (xmlhttp_get.status==200 || xmlhttp_get.status==0)
885                         {
886
887                                 var inStream = {
888                                   data: new Uint8Array(xmlhttp_get.response),
889                                   offset: 0,
890                                   readByte: function(){
891                                         return this.data[this.offset ++];
892                                   }
893                                 };
894
895                                 var outStream = {
896                                   data: new String(""),
897                                   offset: 0,
898                                   binary_mode : false,
899                                   writeByte: function(value){
900                                         this.data+=String.fromCharCode(value);
901                                   }
902                                 };
903
904
905                                 var result = LZMA.decompress2(inStream,inStream,outStream,null);
906                                 if (result == null)
907                                         mandreelDecompressJSReady(outStream.data,true);
908                                 else
909                                         Mandreel_setTimeout(mandreelNextDecompressJS,10,result);
910                         }
911                         else
912                         {
913                                 alert('error ' + xmlhttp_get.status);
914                         }
915                 }
916
917         }
918
919         xmlhttp_get.onprogress = function(e)
920         {
921                 var delta_size = e.loaded - last_loaded_size;
922                 last_loaded_size = e.loaded;
923
924                 var percentage = ((100*e.loaded)/e.total)|0;
925
926                 mandreel_jslzma_size = e.total;
927
928                 imandreel_update_load(delta_size,0);
929
930                 if (percentage>100)
931                         percentage = 100;
932
933                 if ( mandreelAppStartStateFunc )
934                         mandreelAppStartStateFunc("loadingScriptUpdate",percentage);
935         }
936
937         xmlhttp_get.send();
938
939 }
940
941 function mandreelLoadMandreelJsScript()
942 {
943         if (mandreelAppMandreelJsCompressed)
944         {
945                 mandreel_fs_load_text(mandreelAppMandreelJs + ".lzma", mandreel_load_compressed_js);
946
947         }
948         else
949         {
950                 var ga = Mandreel_document.createElement('script');
951                 ga.type = 'text/javascript';
952                 ga.async = true;
953                 ga.onload = ga.onreadystatechange = mandreelJsScriptLoaded;
954                 var url = mandreelAppMandreelJs;
955                 if ( mandreelAppReadMandreelJsFromLocalHost )
956                         ga.src = mandreelAppLocalHost+"/"+url;
957                 else
958                         ga.src = url;
959                 var s = Mandreel_document.getElementsByTagName('script')[0];
960                 if ( mandreelAppStartStateFunc )
961                         mandreelAppStartStateFunc("loadingScript","");
962                 s.parentNode.insertBefore(ga, s);
963         }
964 }
965
966 ////////////////////////////////////////////
967 function mandreelFatLoaded()
968 {
969         if ( mandreelAppPlatform == "nacl" )
970         {
971                 g_mandreel_working_folder = mandreelAppWorkingFolder;
972                 if ( mandreelAppReadDataFromLocalHost )
973                         g_mandreel_working_folder = mandreelAppLocalHost+"/"+mandreelAppWorkingFolder;
974
975                 // load audio
976                 if ( mandreelAppStartStateFunc )
977                         mandreelAppStartStateFunc("loadingAudio","");
978                 _mandreelAppAudioReady();
979         }
980         else
981                 mandreelLoadMandreelJsScript();
982 }
983
984 var mandreelFatData = "";
985 var mandreelFatPreloadRequest = 0;
986 ////////////////////////////////////////////
987
988 function mandreel_chanka_fixfile(fileName)
989 {
990         var fileNameNoExt = fileName.toLowerCase();
991         fileNameNoExt = fileNameNoExt.replace(/\\/g,"/");
992
993         fileNameNoExt =  fileNameNoExt.substr(1);
994
995         var new_fileName = '';
996
997         for(var j = 0; j < fileNameNoExt.length; j++)
998         {
999                 var data = fileNameNoExt.charCodeAt(j);
1000
1001                 if (data != 13)
1002                 {
1003                          var t = String.fromCharCode(data);
1004                          new_fileName+=t;
1005                 }
1006         }
1007
1008         return  new_fileName;
1009 }
1010
1011 function mandreel_removecr(my_string)
1012 {
1013         var new_string = '';
1014         for(var j = 0; j < my_string.length; j++)
1015         {
1016                 var data = my_string.charCodeAt(j);
1017
1018                 if (data != 13)
1019                 {
1020                          var t = String.fromCharCode(data);
1021                          new_string+=t;
1022                 }
1023         }
1024
1025         return  new_string;
1026 }
1027
1028 function mandreelCacheMandreelFat()
1029 {
1030         var array_mandreel_fat = new ArrayBuffer(mandreelFatData.length+1);
1031
1032
1033         {
1034                 var j;
1035                 var len = mandreelFatData.length;
1036                 var data_char;
1037
1038                 var my_bytes = new Uint8Array(array_mandreel_fat);
1039
1040                 for(j = 0; j < len; j++)
1041                 {
1042                         data_char = mandreelFatData.charCodeAt(j);
1043
1044                         my_bytes[j] = data_char;
1045                 }
1046                 my_bytes[j] = 0;
1047         }
1048
1049
1050         mandreel_cache_files['mandreel.fat'] = array_mandreel_fat;
1051 }
1052
1053 function mandreelLoadPackData(data, save_pack)
1054 {
1055         var files = mandreelFatData.split('\n');
1056
1057         var current_dir = '';
1058         var current_offset = 0;
1059
1060         if (save_pack)
1061                 mandreel_fs_saveFile(mandreel_packfiledata_name,data);
1062
1063
1064         for (var i=0;i<files.length;++i)
1065         {
1066                 var file_data = files[i].split(',');
1067
1068                 if (file_data[0] == 'dir')
1069                 {
1070                         current_dir = file_data[1];
1071                         //current_dir = current_dir.substr(0,current_dir.lengh-1);
1072                 }
1073                 else if (file_data[0] == 'file')
1074                 {
1075                         var file_name = current_dir + file_data[1];
1076                         file_name = mandreel_chanka_fixfile(file_name) ;
1077                         //dump('new file ' + file_name + ' ' + current_offset);
1078                         //dump(file_name);
1079                         var file_size = parseInt(file_data[2]);
1080
1081                         var my_array = new ArrayBuffer(file_size);
1082
1083                         var my_bytes = new Uint8Array(my_array);
1084
1085                         var data_bytes = new Uint8Array(data,current_offset,file_size);
1086
1087                         my_bytes.set(data_bytes);
1088
1089                         mandreel_cache_files[file_name] = my_array;
1090
1091
1092                         current_offset+=file_size;
1093
1094
1095                 }
1096         }
1097
1098
1099
1100         g_mandreel_datafiles_sufix = '';
1101         mandreelCacheMandreelFat();
1102
1103         imandreelJsScriptLoaded();
1104 }
1105
1106 var preCreatedWebAudioContext = null;
1107
1108 function mandreelLoadFat()
1109 {
1110         mandreelFatPreloadRequest = new Mandreel_XMLHttpRequest();
1111         var working_folder = mandreelAppWorkingFolder;
1112         if ( mandreelAppReadDataFromLocalHost )
1113                 working_folder = mandreelAppLocalHost+"/"+mandreelAppWorkingFolder;
1114         var url = working_folder+"mandreel.fat.dat";
1115         if ( mandreelAppPlatform == "nacl" )
1116                 url = working_folder+"mandreel.fat";
1117         mandreelFatPreloadRequest.open("GET", url, true);
1118         mandreelFatPreloadRequest.onreadystatechange = function()
1119         {
1120                 if (mandreelFatPreloadRequest.readyState != 4) return;
1121                 if ( mandreelFatPreloadRequest.status != 404 && mandreelFatPreloadRequest.response != null )
1122                 {
1123                         mandreelFatData = mandreelFatPreloadRequest.response;
1124                 }
1125                 if ( mandreelFatData == "" )
1126                 {
1127                         dump("error loading mandreel.fat file, Maybe the working folder is not correctly set???");
1128                 }
1129
1130                 var packfiledata = null;
1131                 var compressed = false;
1132                 var packfiledata_size = 0;
1133                 var total_packtexture_size = 0;
1134                 var pogsize = 0;
1135
1136                 // Check version
1137                 var FatLines = mandreelFatData.split('\n');
1138                 for ( var i=0;i<FatLines.length;++i )
1139                 {
1140                         var line = mandreel_removecr(FatLines[i]);
1141                         var params = line.split(',');
1142                         if ( params[0] == "version" )
1143                         {
1144                                 if ( params[1] != mandrelCurrentFatVersion )
1145                                         dump("warning: mandreel.fat version number is ("+params[1]+") and it should be ("+mandrelCurrentFatVersion+")");
1146
1147                         }
1148                         else if ( params[0] == "platform" && params[1] != "js" && (mandreelAppPlatform == "webgl" || mandreelAppPlatform == "canvas")  )
1149                                 dump("warning: mandreel.fat platform is ("+params[1]+") and it should be (js)");
1150                         else if ( params[0] == "platform" && params[1] != "nacl" && mandreelAppPlatform == "nacl"  )
1151                                 dump("warning: mandreel.fat platform is ("+params[1]+") and it should be (nacl)");
1152                         else if (params[0] == 'packdata')
1153                         {
1154                                 packfiledata = params[1];
1155                                 compressed = params[2].charAt(0) == '1';
1156                                 packfiledata_size =  parseInt(params[3], 10);
1157                         }
1158                         else if (params[0] == 'flashsockets')
1159                         {
1160                                 mandreelAppUseFlashSockets = true;
1161                         }
1162                         else if (params[0] == 'packtexture')
1163                         {
1164                                 var filename = params[1];
1165                                 var size_packtexture = parseInt(params[3], 10);
1166                                 total_packtexture_size+=size_packtexture;
1167                                 mandreelAppUsePackAsyncTexture.push(filename);
1168                         }
1169                         else if (params[0] == 'audiopreloadfile')
1170                         {
1171                                 pogsize = parseInt(params[2],10);
1172                         }
1173                         else if (params[0] == 'audiodriver' && params[1] == 'webaudio')
1174                         {
1175                                 try     { preCreatedWebAudioContext = new webkitAudioContext(); } catch(err) { preCreatedWebAudioContext = null; }
1176                         }
1177                 }
1178
1179                 if ( preCreatedWebAudioContext != null )
1180                         mandreel_total_pogfile_size = pogsize;
1181                 mandreel_packfiledata_name = packfiledata;
1182                 mandreel_packfiledata_compressed = compressed;
1183                 mandreel_packfiledata_size = packfiledata_size;
1184                 mandreel_total_packtexture_size = total_packtexture_size;
1185                 mandreelFatLoaded();
1186         }
1187         mandreelFatPreloadRequest.send();
1188 }
1189
1190 var mandreelAppStartStateFunc = 0;
1191 var mandreelDisableSpaceKey = true;
1192 ////////////////////////////////////////////
1193 function mandreelAppStart(startStateFunc,params)
1194 {
1195         mandreelAppStartStateFunc = startStateFunc;
1196
1197
1198
1199
1200         if ( typeof(params.log) != 'undefined' )
1201                 mandreelAppLog = params.log;
1202
1203         if ( typeof(params.platform) != 'undefined' )
1204                 mandreelAppPlatform = params.platform;
1205
1206         if (typeof(params.mandreelJSCompressed) != 'undefined' )
1207                 mandreelAppMandreelJsCompressed = params.mandreelJSCompressed;
1208
1209
1210 /*       The following code is removed for benchmarking:
1211         if ((mandreel_BrowserDetect.browser == 'Chrome' || mandreel_BrowserDetect.browser == 'Safari') && mandreel_BrowserDetect.OS == 'Mac' && mandreelAppPlatform == "flash")
1212                 mandreelDisableSpaceKey = false; */
1213
1214         if ( mandreelAppPlatform != "webgl" && mandreelAppPlatform != "flash" && mandreelAppPlatform != "nacl" && mandreelAppPlatform != "canvas" && mandreelAppPlatform != "plugin")
1215         {
1216                 mandreelAppStartStateFunc("error",'platform ('+mandreelAppPlatform+') not supported');
1217                 return;
1218         }
1219
1220         if ( mandreelAppPlatform == "webgl" || mandreelAppPlatform == "canvas" )
1221         {
1222                 mandreelAppWorkingFolder = "data/js/";
1223                 if ( typeof(params.workingFolderWebgl) != 'undefined' )
1224                         mandreelAppWorkingFolder = params.workingFolderWebgl;
1225                 // Check Float64Array availability
1226                 if ( !Mandreel_window["Float64Array"] )
1227                 {
1228                         mandreelAppStartStateFunc("error",'Browser unsupported: Float64Array not available');
1229                         return;
1230                 }
1231
1232                 var flashElement = Mandreel_document.getElementById('FlashWrapper');
1233                 if ( flashElement != null )
1234                 {
1235                         flashElement.style.visibility = "hidden";
1236                         flashElement.style.width = "0px";
1237                         flashElement.style.height = "0px";
1238                 }
1239                 var flashElement = Mandreel_document.getElementById('FlashDiv');
1240                 if ( flashElement != null )
1241                 {
1242                         flashElement.style.visibility = "hidden";
1243                         flashElement.style.width = "0px";
1244                         flashElement.style.height = "0px";
1245                 }
1246
1247                 // Setup WebGL
1248                 if ( typeof(params.webglCanvas) == 'undefined' )
1249                 {
1250                         mandreelAppStartStateFunc("error",'canvas parameter not found');
1251                         return;
1252                 }
1253                 var canvas = Mandreel_document.getElementById(params.webglCanvas);
1254                 if ( canvas == null )
1255                 {
1256                         mandreelAppStartStateFunc("error",'canvas object ('+params.webglCanvas+') not found');
1257                         return;
1258                 }
1259                 if ( params.width != null )
1260                 {
1261                         canvas.width = params.width;
1262                         mandreelAppWidthSrc = params.width;
1263                 }
1264                 if ( params.height != null )
1265                 {
1266                         canvas.height = params.height;
1267                         mandreelAppHeightSrc = params.height;
1268                 }
1269                 if ( mandreelAppPlatform == "webgl" )
1270                 {
1271                         // The following code is removed for benchmarking:
1272                         // imandreel_gl = WebGLUtils.setupWebGL(canvas,{premultipliedAlpha:false,alpha:false});
1273                         // if (imandreel_gl == null)
1274                         // {
1275                         //      mandreelAppStartStateFunc("error","webgl_not_found");
1276                         //      return;
1277                         // }
1278                 }
1279
1280                 if ( mandreelAppPlatform == "canvas" )
1281                 {
1282                         imandreel_ctx_canvas = canvas.getContext('2d');
1283                         if ( imandreel_ctx_canvas == null )
1284                         {
1285                                 mandreelAppStartStateFunc("error","canvas context 2d not found");
1286                                 return;
1287                         }
1288                 }
1289
1290                 if (params.cache != null)
1291                 {
1292                         //alert( params.cache.size + params.cache.url);
1293                         mandreel_fs_init(function() { if ( mandreelAppStartStateFunc )
1294                                 mandreelAppStartStateFunc("loadingFat","");
1295                         mandreelLoadFat();}, params.cache.size,params.cache.url);
1296                 }
1297                 else
1298                 {
1299                         // load Fat
1300                         if ( mandreelAppStartStateFunc )
1301                                 mandreelAppStartStateFunc("loadingFat","");
1302                         mandreelLoadFat();
1303                 }
1304         }
1305
1306         if ( mandreelAppPlatform == "flash" )
1307         {
1308                 mandreelAppWorkingFolder = "data/as3/";
1309                 if ( typeof(params.workingFolderFlash) != 'undefined' )
1310                         mandreelAppWorkingFolder = params.workingFolderFlash;
1311                 if (!swfobject.hasFlashPlayerVersion('11.2.0'))
1312                 {
1313                         mandreelAppStartStateFunc("error","flash 11 not found");
1314                         return;
1315                 }
1316
1317                 if ( typeof(params.flashCanvas) == 'undefined' )
1318                 {
1319                         mandreelAppStartStateFunc("error",'canvas parameter not found');
1320                         return;
1321                 }
1322
1323                 if ( true ) // hide webgl canvas
1324                 {
1325                         var canvas = Mandreel_document.getElementById(mandreelAppCanvasDiv);
1326                         if ( canvas != null )
1327                         {
1328                                 canvas.style.visibility = "hidden";
1329                                 canvas.style.width = "0px";
1330                                 canvas.style.height = "0px";
1331                         }
1332                 }
1333
1334                 if ( params.width != null )
1335                 {
1336                         mandreelAppCanvasWidth = params.width;
1337                 }
1338                 if ( params.height != null )
1339                 {
1340                         mandreelAppCanvasHeight = params.height;
1341                 }
1342
1343                 mandreelAppCanvasDiv = params.flashCanvas;
1344
1345                 try
1346                 {
1347                         var mandreelSocketsSwf = "mandreel.swf";
1348                         if ( typeof(params.swfFlash) != 'undefined' )
1349                                 mandreelSocketsSwf = params.swfFlash;
1350
1351                         var my_flashvars = "workingFolder=" + encodeURIComponent(mandreelAppWorkingFolder);
1352                         if ( typeof(params.log) != 'undefined' && params.log == true)
1353                           my_flashvars += "&log=true"
1354                         my_flashvars += "&width=" + params.width;
1355                         my_flashvars += "&height=" + params.height;
1356                         my_flashvars += "&swfloader=" + mandreelSocketsSwf;
1357
1358                         if (typeof(params.restore_context) != 'undefined' && params.restore_context == true)
1359                                 my_flashvars += "&restore_context=1";
1360
1361                         if (typeof(params.antialiasing) != 'undefined')
1362                                 my_flashvars += "&antialiasing=" + params.antialiasing;
1363
1364                         if (typeof(params.right_click_enable) != 'undefined' && params.right_click_enable == true)
1365                                 my_flashvars += "&right_click=1";
1366
1367                         if (typeof(params.disable_depth) != 'undefined' && params.disable_depth == true)
1368                                 my_flashvars += "&disable_depth=1";
1369
1370                         var swfname = "mandreelloader.swf";
1371                         if ( typeof(params.swfPreloader) != 'undefined' && params.swfPreloader == false)
1372                                 swfname = mandreelSocketsSwf;
1373
1374                         var swf = swfobject.createSWF({ data:swfname, width:"100%", height:"100%" }, { menu:"false",allowScriptAccess:"always",allowFullScreen:"true",wmode:"direct",scale:"noscale",salign :"tl",bgcolor:"#000000",flashvars:my_flashvars}, params.flashCanvas);
1375                         if ( !swf )
1376                         {
1377                                 mandreelAppStartStateFunc("error","error loading " + swfname);
1378                                 return;
1379                         }
1380                         else
1381                         {
1382                                 if ( mandreelAppStartStateFunc )
1383                                         mandreelAppStartStateFunc("loadingScript","");
1384                         }
1385                 }
1386                 catch(err)
1387                 {
1388                         mandreelAppStartStateFunc("error","exception " + err + " while loading " + mandreelSocketsSwf);
1389                         return;
1390                 }
1391
1392                 appStartState('loadingScript');
1393         }
1394
1395         if ( mandreelAppPlatform == "nacl" )
1396         {
1397                 mandreelAppWorkingFolder = "data/nacl/";
1398
1399                 // load Fat
1400                 if ( mandreelAppStartStateFunc )
1401                         mandreelAppStartStateFunc("loadingFat","");
1402                 mandreelLoadFat();
1403
1404         }
1405
1406         if ( mandreelAppPlatform == "plugin" )
1407         {
1408                 mandreelInitPluginPlatform(params);
1409         }
1410 }
1411
1412
1413 ////////////////////////////////////////////
1414 function MandreelAudioStartedNacl()
1415 {
1416         var helloWorldModule = null;
1417         helloWorldModule = Mandreel_document.getElementById('hello_world');
1418         helloWorldModule.postMessage('init');
1419         var flashElement = Mandreel_document.getElementById('FlashWrapper');
1420         if ( flashElement != null )
1421                 flashElement.style.visibility = "hidden";
1422         mandreelAppStartStateFunc("ready",mandreelAppCanvasWidth,mandreelAppCanvasHeight);
1423 }
1424
1425 ////////////////////////////////////////////
1426 function _mandreelAppStartReady()
1427 {
1428         if ( mandreelAppPlatform == "nacl" )
1429         {
1430                 wa_initWebAudio();
1431                 mandreel_webAudio_PreloadAssets();
1432         }
1433         else
1434         {
1435                 if ( mandreelAppStartStateFunc )
1436                 {
1437                         mandreelAppStartRenderWebGL();
1438                         mandreelAppStartStateFunc("ready",mandreelAppCanvasWidth,mandreelAppCanvasHeight);
1439                 }
1440         }
1441 }
1442 ////////////////////////////////////////////
1443 function _mandreelAppAudioReady()
1444 {
1445         if ( mandreelAppStartStateFunc )
1446                 mandreelAppStartStateFunc("audioLoaded","");
1447
1448         if ( mandreelAppUseFlashSockets )
1449                 mandreel_flash_sockets_load_flash(_mandreelAppStartReady);
1450         else
1451                 _mandreelAppStartReady();
1452 }
1453
1454 ////////////////////////////////////////////
1455 function mandreelAppInit()
1456 {
1457         if ( mandreelAppPlatform == "webgl" || mandreelAppPlatform == "canvas" )
1458         {
1459                 global_init(g_stack_pointer+800*1024);
1460
1461                 //Mandreel_TextureAsync_PackBufferData[_mandreel_currentPackTexture] = mandreelBufferPackAsyncTexture;
1462                 //mandreelBufferPackAsyncTexture = null;
1463                 var sp = g_stack_pointer+800*1024;
1464                 heapU32[sp>>2] = mandreelAppCanvasWidth;
1465                 heapU32[(sp+4)>>2] = mandreelAppCanvasHeight;
1466                 __mandreel_internal_SetResolution(sp);
1467                 __mandreel_internal_init(g_stack_pointer+800*1024);
1468                 __init(g_stack_pointer+800*1024);
1469         }
1470 }
1471
1472 ////////////////////////////////////////////
1473 function mandreelAppDraw(elapsed)
1474 {
1475         if ( mandreelAppPlatform == "webgl" || mandreelAppPlatform == "canvas" )
1476         {
1477                 if ( mandreelAppPlatform == "canvas" && imandreel_ctx_canvas != null )
1478                 {
1479                         var canvas = Mandreel_document.getElementById(mandreelAppCanvasName);
1480                         imandreel_ctx_canvas.clearRect(0,0,canvas.width,canvas.height);
1481                 }
1482                 var sp = g_stack_pointer+800*1024;
1483                 __mandreel_internal_preupdate(sp);
1484                 heapU32[sp>>2] = elapsed;
1485                 __draw(sp);
1486                 __mandreel_internal_update(sp);
1487                 __mandreel_process_async_calls();
1488         }
1489 }
1490
1491 ////////////////////////////////////////////
1492 function mandreelAppMouseWheel(delta)
1493 {
1494         if ( mandreelAppPlatform == "webgl" || mandreelAppPlatform == "canvas" )
1495         {
1496                 var i7 = MandreelLockFrame();
1497                 heap32[(i7+0)>>2] = delta;
1498                 __mouseWheelDelta(i7);
1499                 MandreelUnlockFrame();
1500         }
1501 }
1502
1503 ////////////////////////////////////////////
1504 function mandreelAppMouseMove(x,y)
1505 {
1506         if ( mandreelAppPlatform == "webgl" || mandreelAppPlatform == "canvas" )
1507         {
1508                 var i7 = MandreelLockFrame();
1509                 heap32[(i7+0)>>2] = x;
1510                 heap32[(i7+4)>>2] = y;
1511                 __mouseMove(i7);
1512                 MandreelUnlockFrame();
1513         }
1514 }
1515
1516 ////////////////////////////////////////////
1517 function mandreelAppResize(x,y)
1518 {
1519         if ( mandreelAppPlatform == "webgl" || mandreelAppPlatform == "canvas" )
1520         {
1521                 var i7 = MandreelLockFrame();
1522                 heap32[(i7+0)>>2] = x;
1523                 heap32[(i7+4)>>2] = y;
1524                 __resize(i7);
1525                 heap32[(i7+0)>>2] = x;
1526                 heap32[(i7+4)>>2] = y;
1527                 __mandreel_internal_SetResolution(i7);
1528                 MandreelUnlockFrame();
1529         }
1530 }
1531
1532 ////////////////////////////////////////////
1533 function mandreelAppMouseButton(down,x,y)
1534 {
1535         if ( mandreelAppPlatform == "webgl" || mandreelAppPlatform == "canvas" )
1536         {
1537                 var i7 = MandreelLockFrame();
1538                 heap32[(i7+0)>>2] = down;
1539                 heap32[(i7+4)>>2] = x;
1540                 heap32[(i7+8)>>2] = y;
1541                 __mouseButton(i7);
1542                 MandreelUnlockFrame();
1543         }
1544 }
1545
1546 ////////////////////////////////////////////
1547 function mandreelAppMouseDblClick(x,y)
1548 {
1549         if ( mandreelAppPlatform == "webgl" || mandreelAppPlatform == "canvas" )
1550         {
1551                 var i7 = MandreelLockFrame();
1552                 heap32[(i7+0)>>2] = x;
1553                 heap32[(i7+4)>>2] = y;
1554                 __mouseDoubleClick(i7);
1555                 MandreelUnlockFrame();
1556         }
1557 }
1558
1559 ////////////////////////////////////////////
1560 function mandreelAppKeyEvent(down,keyId)
1561 {
1562         if ( mandreelAppPlatform == "webgl" || mandreelAppPlatform == "canvas" )
1563         {
1564                 var i7 = MandreelLockFrame();
1565                 heap32[(i7+0)>>2] = down;
1566                 heap32[(i7+4)>>2] = keyId;
1567                 __keyEvent(i7);
1568                 MandreelUnlockFrame();
1569         }
1570 }
1571
1572 ////////////////////////////////////////////
1573 function mandreelAppGetPlatform()
1574 {
1575         return mandreelAppPlatform;
1576 }
1577
1578 ////////////////////////////////////////////
1579 function mandreelAppGetElementAbsolutePos(elementName)
1580 {
1581         var element = Mandreel_document.getElementById(elementName);
1582         var res = new Object();
1583         res.x = 0; res.y = 0;
1584         if (element !== null)
1585         {
1586                 if (element.getBoundingClientRect)
1587                 {
1588                         var viewportElement = Mandreel_document.documentElement;
1589                         var box = element.getBoundingClientRect();
1590                         var scrollLeft = viewportElement.scrollLeft;
1591                         var scrollTop = viewportElement.scrollTop;
1592                         res.x = box.left + scrollLeft;
1593                         res.y = box.top + scrollTop;
1594                 }
1595                 else
1596                 { //for old browsers
1597                         res.x = element.offsetLeft;
1598                         res.y = element.offsetTop;
1599                         var parentNode = element.parentNode;
1600                         var borderWidth = null;
1601                         while (offsetParent != null)
1602                         {
1603                                 res.x += offsetParent.offsetLeft;
1604                                 res.y += offsetParent.offsetTop;
1605                                 var parentTagName = offsetParent.tagName.toLowerCase();
1606                                 if ((__isIEOld && parentTagName != "table") ||
1607                                         ((__isFireFoxNew || __isChrome) &&
1608                                                 parentTagName == "td"))
1609                                 {
1610                                         borderWidth = kGetBorderWidth(offsetParent);
1611                                         res.x += borderWidth.left;
1612                                         res.y += borderWidth.top;
1613                                 }
1614
1615                                 if (offsetParent != Mandreel_document.body &&
1616                                 offsetParent != Mandreel_document.documentElement)
1617                                 {
1618                                         res.x -= offsetParent.scrollLeft;
1619                                         res.y -= offsetParent.scrollTop;
1620                                 }
1621
1622                                 //next lines are necessary to fix the problem
1623                                 //with offsetParent
1624                                 if (!__isIE && !__isOperaOld || __isIENew)
1625                                 {
1626                                         while (offsetParent != parentNode &&
1627                                                 parentNode !== null) {
1628                                                 res.x -= parentNode.scrollLeft;
1629                                                 res.y -= parentNode.scrollTop;
1630                                                 if (__isFireFoxOld || __isWebKit)
1631                                                 {
1632                                                     borderWidth =
1633                                                      kGetBorderWidth(parentNode);
1634                                                     res.x += borderWidth.left;
1635                                                     res.y += borderWidth.top;
1636                                                 }
1637                                                 parentNode = parentNode.parentNode;
1638                                         }
1639                                 }
1640
1641                                 parentNode = offsetParent.parentNode;
1642                                 offsetParent = offsetParent.offsetParent;
1643                         }
1644                 }
1645         }
1646         return res;
1647 }
1648 function __getIEVersion()
1649 {
1650         var rv = -1; // Return value assumes failure.
1651         if (navigator.appName == 'Microsoft Internet Explorer')
1652         {
1653                 var ua = navigator.userAgent;
1654                 var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
1655                 if (re.exec(ua) != null)
1656                         rv = parseFloat(RegExp.$1);
1657         }
1658         return rv;
1659 }
1660 function __getOperaVersion()
1661 {
1662         var rv = 0; // Default value
1663         if (Mandreel_window.opera)
1664         {
1665                 var sver = Mandreel_window.opera.version();
1666                 rv = parseFloat(sver);
1667         }
1668         return rv;
1669 }
1670 /* The following code was removed for benchmarking:
1671 var __userAgent = navigator.userAgent;
1672 var __isIE =  navigator.appVersion.match(/MSIE/) != null;
1673 var __IEVersion = __getIEVersion();
1674 var __isIENew = __isIE && __IEVersion >= 8;
1675 var __isIEOld = __isIE && !__isIENew;
1676 var __isFireFox = __userAgent.match(/firefox/i) != null;
1677 var __isFireFoxOld = __isFireFox && ((__userAgent.match(/firefox\/2./i) != null) || (__userAgent.match(/firefox\/1./i) != null));
1678 var __isFireFoxNew = __isFireFox && !__isFireFoxOld;
1679 var __isWebKit =  navigator.appVersion.match(/WebKit/) != null;
1680 var __isChrome =  navigator.appVersion.match(/Chrome/) != null;
1681 var __isOpera =  Mandreel_window.opera != null;
1682 var __operaVersion = __getOperaVersion();
1683 var __isOperaOld = __isOpera && (__operaVersion < 10); */
1684 function __parseBorderWidth(width)
1685 {
1686         var res = 0;
1687         if (typeof(width) == "string" && width != null && width != "" )
1688         {
1689                 var p = width.indexOf("px");
1690                 if (p >= 0)
1691                 {
1692                         res = parseInt(width.substring(0, p));
1693                 }
1694                 else
1695                 {
1696                         //do not know how to calculate other values (such as 0.5em or 0.1cm) correctly now so just set the width to 1 pixel
1697                         res = 1;
1698                 }
1699         }
1700         return res;
1701 }
1702 function __getBorderWidth(element)
1703 {
1704         var res = new Object();
1705         res.left = 0; res.top = 0; res.right = 0; res.bottom = 0;
1706         if (Mandreel_window.getComputedStyle)
1707         {
1708                 //for Firefox
1709                 var elStyle = Mandreel_window.getComputedStyle(element, null);
1710                 res.left = parseInt(elStyle.borderLeftWidth.slice(0, -2));
1711                 res.top = parseInt(elStyle.borderTopWidth.slice(0, -2));
1712                 res.right = parseInt(elStyle.borderRightWidth.slice(0, -2));
1713                 res.bottom = parseInt(elStyle.borderBottomWidth.slice(0, -2));
1714         }
1715         else
1716         {
1717                 //for other browsers
1718                 res.left = __parseBorderWidth(element.style.borderLeftWidth);
1719                 res.top = __parseBorderWidth(element.style.borderTopWidth);
1720                 res.right = __parseBorderWidth(element.style.borderRightWidth);
1721                 res.bottom = __parseBorderWidth(element.style.borderBottomWidth);
1722         }
1723         return res;
1724 }
1725
1726
1727 ////////////////////////////////////////////
1728 // WebGL
1729 ////////////////////////////////////////////
1730         var imandreel_gl = null;
1731         var imandreel_ctx_canvas = null;
1732         var imandreel_is_ready = 0;
1733         var imandreel_oldTime = Date_now();
1734
1735         function mandreel_wheel(event) { imandreel_onMouseWheel(event);event.preventDefault(); event.returnValue=false; }
1736
1737         ////////////////////////////////////////////
1738         function mandreelAppStartRenderWebGL()
1739         {
1740 /* The following code was removed for benchmarking:
1741                 var canvas = document.getElementById(mandreelAppCanvasName);
1742
1743                 mandreelAppCanvasWidth = canvas.width;
1744                 mandreelAppCanvasHeight = canvas.height;
1745
1746                 // Register event handlers
1747                 if(window.addEventListener){ window.addEventListener('DOMMouseScroll',mandreel_wheel,false); }  window.onmousewheel=document.onmousewheel=mandreel_wheel;
1748
1749                 window.addEventListener('mousedown',imandreel_onMouseDown,false);
1750                 window.addEventListener('mouseup',imandreel_onMouseUp,false);
1751                 window.addEventListener('mousemove',imandreel_onMouseMove,false);
1752                 window.addEventListener('dblclick',imandreel_onMouseDblClick,false);
1753
1754                 document.body.oncontextmenu = function() { return false;};
1755
1756                 var canvasDiv = document.getElementById(mandreelAppCanvasDiv);
1757                 canvasDiv.addEventListener('keydown',imandreel_onKeyDown,false);
1758                 canvasDiv.addEventListener('keyup',imandreel_onKeyUp,false);
1759                 canvasDiv.focus();*/
1760
1761                 // Call mandreel app init funtion (__init())
1762                 mandreelAppInit();
1763
1764                 // Start rendering
1765                 imandreel_is_ready = 1;
1766                 //imandreel_render();
1767         }
1768
1769         ////////////////////////////////////////////
1770         function imandreel_render()
1771         {
1772                 if( ABORT )
1773                         return;
1774
1775                 var canvas = Mandreel_document.getElementById(mandreelAppCanvasName);
1776                 WebGLUtils.requestAnimationFrame(canvas, imandreel_render);
1777
1778
1779                 // Reshape
1780                 if (canvas.clientWidth != mandreelAppCanvasWidth || canvas.clientHeight != mandreelAppCanvasHeight)
1781                 {
1782                         mandreelAppCanvasWidth = canvas.clientWidth;
1783                         mandreelAppCanvasHeight = canvas.clientHeight;
1784                         imandreel_gl.viewport(0, 0, mandreelAppCanvasWidth, mandreelAppCanvasHeight);
1785                 }
1786
1787                 // Set the focus to the canvas div
1788                 if (mandreelAppForceFocus)
1789                 {
1790                         var canvasDiv = Mandreel_document.getElementById(mandreelAppCanvasDiv);
1791                         canvasDiv.focus();
1792                 }
1793
1794                 // Call mandreel app draw funtion (__draw())
1795                 var nowTime = Date_now();
1796                 if (!g_mandreel_frame_locked)
1797                 {
1798                         g_mandreel_frame_inframe = true;
1799                         if (!_imandreel_pause_game)
1800                                 mandreelAppDraw(nowTime-imandreel_oldTime);
1801                         g_mandreel_frame_inframe = false;
1802                 }
1803                 imandreel_oldTime = nowTime;
1804         }
1805
1806         function render()
1807         {
1808                 // Call mandreel app draw funtion (__draw())
1809                 var nowTime = Date_now();
1810                 if (!g_mandreel_frame_locked)
1811                 {
1812                         g_mandreel_frame_inframe = true;
1813                         if (!_imandreel_pause_game)
1814                                 mandreelAppDraw(nowTime-imandreel_oldTime);
1815                         g_mandreel_frame_inframe = false;
1816                 }
1817                 imandreel_oldTime = nowTime;
1818         }
1819
1820         var imandreel_last_movex = 0;
1821         var imandreel_last_movey = 0;
1822
1823         ////////////////////////////////////////////
1824         function imandreel_onMouseMove(e)
1825         {
1826                 if (!imandreel_is_ready)
1827                         return;
1828
1829                 if (_imandreel_pause_game)
1830                         return;
1831
1832                 var pos = mandreelAppGetElementAbsolutePos(mandreelAppCanvasName);
1833                 var setX = e.clientX - pos.x;
1834                 var setY = e.clientY - pos.y;
1835
1836                   if(navigator.pointer && navigator.pointer.isLocked) {
1837             var deltaX = event.movementX || event.webkitMovementX || event.mozMovementX || 0;
1838             var deltaY = event.movementY || event.webkitMovementY || event.mozMovementX || 0;
1839
1840                         setX = imandreel_last_movex+deltaX;
1841                         setY = imandreel_last_movey+deltaY;
1842                         }
1843
1844
1845                 imandreel_last_movex = setX;
1846                 imandreel_last_movey = setY;
1847                 mandreelAppMouseMove(setX,setY);
1848         }
1849
1850         ////////////////////////////////////////////
1851         function imandreel_onMouseDblClick(e)
1852         {
1853                 if (!imandreel_is_ready)
1854                         return;
1855
1856                 if (_imandreel_pause_game)
1857                         return;
1858
1859                 var pos = mandreelAppGetElementAbsolutePos(mandreelAppCanvasName);
1860                 var setX = e.clientX - pos.x;
1861                 var setY = e.clientY - pos.y;
1862                 mandreelAppMouseDblClick(setX,setY);
1863         }
1864
1865         ////////////////////////////////////////////
1866         var mandreel_mouse_down = false;
1867         var mandreel_rmouse_down = false;
1868         function imandreel_onMouseDown(e)
1869         {
1870                 if (!imandreel_is_ready)
1871                         return;
1872
1873                 if (_imandreel_pause_game)
1874                         return;
1875
1876                 var rightclick;
1877                 if (!e) var e = Mandreel_window.event;
1878                 if (e.which) rightclick = (e.which == 3);
1879                 else if (e.button) rightclick = (e.button == 2);
1880
1881                 var pos = mandreelAppGetElementAbsolutePos(mandreelAppCanvasName);
1882                 var setX = e.clientX - pos.x;
1883                 var setY = e.clientY - pos.y;
1884
1885                 if (!rightclick)
1886                 {
1887                         if (mandreel_mouse_down)
1888                                 return;
1889
1890                         mandreel_mouse_down = true;
1891                         mandreelAppMouseButton(1,setX,setY);
1892                 }
1893                 else
1894                 {
1895                         if (mandreel_rmouse_down)
1896                                 return;
1897
1898                         mandreel_rmouse_down = true;
1899                         mandreelAppMouseButton(3,setX,setY);
1900                 }
1901         }
1902
1903         ////////////////////////////////////////////
1904         function imandreel_onMouseUp(e)
1905         {
1906                 if (!imandreel_is_ready)
1907                         return;
1908
1909                 if (_imandreel_pause_game)
1910                         return;
1911
1912                 var rightclick;
1913                 if (!e) var e = Mandreel_window.event;
1914                 if (e.which) rightclick = (e.which == 3);
1915                 else if (e.button) rightclick = (e.button == 2);
1916
1917                 var pos = mandreelAppGetElementAbsolutePos(mandreelAppCanvasName);
1918                 var setX = e.clientX - pos.x;
1919                 var setY = e.clientY - pos.y;
1920
1921
1922                 if (!rightclick)
1923                 {
1924                         if (mandreel_mouse_down == false)
1925                                 return;
1926
1927                         mandreel_mouse_down = false;
1928                         mandreelAppMouseButton(0,setX,setY);
1929                 }
1930                 else
1931                 {
1932                         if (mandreel_rmouse_down == false)
1933                                 return;
1934
1935                         mandreel_rmouse_down = false;
1936                         mandreelAppMouseButton(2,setX,setY);
1937                 }
1938         }
1939
1940         ////////////////////////////////////////////
1941         function imandreel_onMouseWheel(e)
1942         {
1943                 if (!imandreel_is_ready)
1944                         return;
1945
1946                 if (_imandreel_pause_game)
1947                         return;
1948
1949                 mandreelAppMouseWheel(e.wheelDelta);
1950         }
1951
1952         ////////////////////////////////////////////
1953         function imandreel_onKeyUp(e)
1954         {
1955                 if (!imandreel_is_ready)
1956                         return;
1957
1958                 if (_imandreel_pause_game)
1959                         return;
1960
1961                 var KeyID = e.keyCode;
1962                 mandreelAppKeyEvent(0,KeyID);
1963         }
1964
1965         ////////////////////////////////////////////
1966         Mandreel_window.onkeydown = function(e)
1967         {
1968                 if (mandreelDisableSpaceKey == false && e.keyCode == 32)
1969                         return;
1970                 return !(e.keyCode == 32 || e.keyCode == 9);
1971         };
1972
1973         ////////////////////////////////////////////
1974         function imandreel_onKeyDown(e)
1975         {
1976                 if (e.which === 8) // disable back button on browser
1977         {
1978                 e.preventDefault();
1979             }
1980                 if (!imandreel_is_ready)
1981                         return;
1982
1983                 if (_imandreel_pause_game)
1984                         return;
1985
1986                 var KeyID = e.keyCode;
1987                 mandreelAppKeyEvent(1,KeyID);
1988         }
1989
1990
1991 ////////////////////////////////////////////
1992 // Flash
1993 ////////////////////////////////////////////
1994
1995 (function(){
1996                 try {
1997                         // Disabling SWFObject's Autohide feature
1998                         if (typeof swfobject.switchOffAutoHideShow === "function") {
1999                                 swfobject.switchOffAutoHideShow();
2000                         }
2001                 } catch(e) {}
2002         })();
2003
2004 var imandreel_flash_global_sp = 0;
2005 var imandreel_flash_global_sp2 = 0;
2006 var imandreel_flash_current_sp = 0;
2007
2008 function MandreelInterSwfLoaded2()
2009 {
2010 }
2011 function MandreelInterSwfLoaded()
2012 {
2013         appStartState('scriptLoaded');
2014         var flashMovie = swfobject.getObjectById(mandreelAppCanvasDiv)
2015         dump(flashMovie.width);
2016         flashMovie.MandreelInit();
2017
2018         imandreel_flash_global_sp = MandreelInterGetSWF().MandreelInterGetGlobalStack();
2019         imandreel_flash_global_sp2 = MandreelInterGetSWF().MandreelInterGetGlobalStack2();
2020         if ( mandreelAppStartStateFunc )
2021                 mandreelAppStartStateFunc("ready",mandreelAppCanvasWidth,mandreelAppCanvasHeight);
2022 }
2023
2024
2025
2026 var g_mandreel_swf = null;
2027
2028 function MandreelInterGetSWF()
2029 {
2030         if (g_mandreel_swf)
2031                 return g_mandreel_swf;
2032
2033         g_mandreel_swf = swfobject.getObjectById(mandreelAppCanvasDiv)
2034         return g_mandreel_swf;
2035 }
2036
2037 function MandreelInterWriteInt(ptr, value)
2038 {
2039         MandreelInterGetSWF().MandreelInterWriteInt(ptr,value);
2040 }
2041
2042 function MandreelInterWriteFloat(ptr, value)
2043 {
2044         MandreelInterGetSWF().MandreelInterWriteFloat(ptr,value);
2045 }
2046
2047 function MandreelInterWriteString(ptr, value)
2048 {
2049         MandreelInterGetSWF().MandreelInterWriteString(ptr,value);
2050 }
2051
2052 function MandreelInterWriteWString(ptr, value)
2053 {
2054         MandreelInterGetSWF().MandreelInterWriteWString(ptr,value);
2055 }
2056
2057 function MandreelInterCallFunctionRaw(sp, func_name, returnType)
2058 {
2059         return MandreelInterGetSWF().MandreelInterCallFunctionRaw(sp,func_name,returnType);
2060 }
2061
2062
2063 function assert(condition, _text) {
2064 //console.assert(condition, _text);
2065     if (!condition) {
2066       var text = "Assertion failed: " + _text;
2067       alert(text + ':\n' + (new Error).stack);
2068       ABORT = true;
2069       throw "Assertion: " + text;
2070     }
2071   }
2072
2073
2074
2075 function MandreelLockFrame()
2076 {
2077         MandreelInterGetSWF().MandreelLockFrame();
2078
2079         imandreel_flash_current_sp += 300*1024;
2080
2081         assert(imandreel_flash_current_sp<1024*1024);
2082
2083         return imandreel_flash_current_sp;
2084 }
2085
2086 function MandreelPause()
2087 {
2088         MandreelInterGetSWF().MandreelPause();
2089 }
2090
2091 function MandreelResume()
2092 {
2093         MandreelInterGetSWF().MandreelResume();
2094 }
2095
2096
2097 function MandreelUnlockFrame()
2098 {
2099         imandreel_flash_current_sp -= 300*1024;
2100         MandreelInterGetSWF().MandreelUnlockFrame();
2101 }
2102
2103
2104
2105 function MandreelInterCallFunctionAsync(func_name,param)
2106 {
2107         return MandreelInterGetSWF().MandreelInterCallFunctionAsync(func_name, param);
2108 }
2109
2110
2111 function MandreelInterCallFunction(returnType,func_name)
2112 {
2113         var size_params = 0;
2114
2115         var i;
2116         var num_params = (arguments.length-2)/2;
2117         num_params|=0;
2118         for (i=2;i<num_params*2+2;i+=2)
2119         {
2120                 var type = arguments[i];
2121
2122                 var size_arg = 0;
2123                 switch(type)
2124                 {
2125                         case 'int':
2126                                 size_arg = 4;
2127                                 break;
2128                         case 'float':
2129                                 size_arg = 4;
2130                                 break;
2131                         case 'string':
2132                                 size_arg = 4;
2133                                 size_arg += ((arguments[i+1].length + 4) & 0xfffffffc);
2134                                 break;
2135                         case 'wstring':
2136                                 size_arg = 4;
2137                                 size_arg += ((arguments[i+1].length*2 + 4) & 0xfffffffc);
2138                                 break;
2139                         default:
2140                                 assert(false);
2141                 }
2142
2143                 size_params += size_arg;
2144         }
2145
2146         // stack always 8 byte aligned
2147         size_params=((size_params+7)& 0xfffffff8);
2148
2149         var sp = 0;
2150
2151         if (i<(arguments.length))
2152                 sp = arguments[i];
2153         else
2154         {
2155                 assert(false);
2156         }
2157
2158
2159         sp-=size_params;
2160
2161         MandreelLockFrame();
2162
2163         var offset = 0;
2164         var ptr_data = num_params*4+sp;
2165     for (i=2;i<num_params*2+2;i+=2)
2166         {
2167                 var type = arguments[i];
2168
2169
2170                 var size_arg = 0;
2171                 switch(type)
2172                 {
2173                         case 'int':
2174                                 MandreelInterWriteInt((sp+offset),arguments[i+1]);
2175                                 break;
2176                         case 'float':
2177                                 MandreelInterWriteFloat((sp+offset),arguments[i+1]);
2178                                 break;
2179                         case 'string':
2180                                 {
2181                                         MandreelInterWriteInt((sp+offset),ptr_data);
2182                                         var string = arguments[i+1];
2183                                         MandreelInterWriteString(ptr_data,string);
2184
2185                                         ptr_data += ((string.length + 4) & 0xfffffffc);
2186                                 }
2187                                 break;
2188                         case 'wstring':
2189                                 {
2190                                         MandreelInterWriteInt((sp+offset),ptr_data);
2191                                         var string = arguments[i+1];
2192                                         MandreelInterWriteWString(ptr_data,string);
2193
2194                                         ptr_data += ((string.length*2 + 4) & 0xfffffffc);
2195                                 }
2196                                 break;
2197                         default:
2198                                 assert(false);
2199                 }
2200                 offset+=4;
2201         }
2202
2203         return_value = MandreelInterCallFunctionRaw(sp, func_name, returnType);
2204
2205         MandreelUnlockFrame();
2206
2207         if (returnType == 'int')
2208                 return parseInt(return_value);
2209         else if (returnType == 'float')
2210                 return parseFloat(return_value);
2211
2212         return;
2213 }
2214
2215
2216
2217 // file system
2218
2219 var g_mandreel_timestamp_fs = 0;
2220 var g_mandreel_fs = null;
2221
2222 function onMandreelQuotaOk(fs)
2223 {
2224         g_mandreel_fs = fs;
2225         dump('onMandreelQuotaOk');
2226 }
2227
2228
2229 function MandreelFsErrorHandler(e) {
2230   var msg = '';
2231
2232   switch (e.code) {
2233     case FileError.QUOTA_EXCEEDED_ERR:
2234       msg = 'QUOTA_EXCEEDED_ERR';
2235       break;
2236     case FileError.NOT_FOUND_ERR:
2237       msg = 'NOT_FOUND_ERR';
2238       break;
2239     case FileError.SECURITY_ERR:
2240       msg = 'SECURITY_ERR';
2241       break;
2242     case FileError.INVALID_MODIFICATION_ERR:
2243       msg = 'INVALID_MODIFICATION_ERR';
2244       break;
2245     case FileError.INVALID_STATE_ERR:
2246       msg = 'INVALID_STATE_ERR';
2247       break;
2248     default:
2249       msg = 'Unknown Error';
2250       break;
2251   };
2252
2253   dump('Error: ' + msg);
2254   dump(e);
2255 }
2256
2257 var indexedDB = Mandreel_window.indexedDB || Mandreel_window.webkitIndexedDB ||
2258                 Mandreel_window.mozIndexedDB;
2259
2260 if ('webkitIndexedDB' in Mandreel_window) {
2261   Mandreel_window.IDBTransaction = Mandreel_window.webkitIDBTransaction;
2262   Mandreel_window.IDBKeyRange = Mandreel_window.webkitIDBKeyRange;
2263 }
2264
2265
2266 var mandreel_indexedDB = {};
2267 mandreel_indexedDB.db = null;
2268 mandreel_indexedDB.callback_init = false;
2269
2270 mandreel_indexedDB.onerror = function(e) {
2271   dump(e);
2272 };
2273
2274 mandreel_indexedDB.init = function(callback)
2275 {
2276  try {
2277         var request = indexedDB.open('my_cache', 2);
2278
2279         request.onerror = function(event) {
2280                 callback(false);
2281                 };
2282         request.onupgradeneeded = function(event) {
2283         dump('onupgradeneeded\n');
2284         mandreel_indexedDB.db = event.target.result;
2285     var db = mandreel_indexedDB.db;
2286         var objectStore = db.createObjectStore("cache",{keyPath: "fileName"});
2287         }
2288
2289   request.onsuccess = function(event) {
2290   dump('onsuccess\n');
2291     mandreel_indexedDB.db = event.target.result;
2292         callback(true);
2293
2294   };
2295   }
2296   catch(e)
2297   {
2298         callback(false);
2299   }
2300
2301 }
2302
2303 function mandreel_fs_init(callback, size_bytes, url_time)
2304 {
2305
2306         g_mandreel_timestamp_fs = 99999999999999;
2307
2308
2309
2310
2311         var aux = null;
2312         try     { aux = webkitStorageInfo; } catch(err) { aux = null; }
2313         if (aux == null)
2314         {
2315                 //callback(false);
2316
2317                 var time_request = new XMLHttpRequest();
2318         time_request.open('GET',url_time);
2319         time_request.onreadystatechange = function()
2320         {
2321                 if (time_request.readyState==4)
2322                 {
2323                         if (time_request.status==200 || time_request.status==0)
2324                         {
2325
2326                                 if (time_request.responseText)
2327                                 {
2328                                         g_mandreel_timestamp_fs = parseFloat(time_request.responseText);
2329                                         dump('mandreel_init_fs time ' + g_mandreel_timestamp_fs);
2330                                 }
2331                         }
2332
2333                         mandreel_indexedDB.init(callback);
2334                 }
2335         }
2336         time_request.send();
2337
2338
2339                 return;
2340         }
2341
2342         webkitStorageInfo.requestQuota(
2343                 webkitStorageInfo.PERSISTENT ,   // or PERSISTENT
2344                 size_bytes,
2345                 function(bytes) {  dump('request quota succeed');},
2346                 function () { dump('request quota failed');} );
2347
2348
2349 //      g_mandreel_timestamp_fs =0;
2350
2351         var time_request = new XMLHttpRequest();
2352         time_request.open('GET',url_time);
2353         time_request.onreadystatechange = function()
2354         {
2355                 if (time_request.readyState==4)
2356                 {
2357                         if (time_request.status==200 || time_request.status==0)
2358                         {
2359
2360                                 if (time_request.responseText)
2361                                 {
2362                                         g_mandreel_timestamp_fs = parseFloat(time_request.responseText);
2363                                         dump('mandreel_init_fs time ' + g_mandreel_timestamp_fs);
2364                                 }
2365                         }
2366
2367                         var my_requestFileSystem  = Mandreel_window.requestFileSystem || Mandreel_window.webkitRequestFileSystem;
2368
2369                         my_requestFileSystem(Mandreel_window.PERSISTENT, size_bytes,
2370                                 function(result)
2371                                 {
2372                                         onMandreelQuotaOk(result);
2373
2374
2375                                         if (callback)
2376                                                 Mandreel_setTimeout(callback, 100, true);
2377                                 } , function(e) { MandreelFsErrorHandler(e); if (callback) callback(false); } );
2378                 }
2379         }
2380         time_request.send();
2381 }
2382
2383
2384 mandreel_indexedDB.load = function(file_name, callback)
2385 {
2386         var db = mandreel_indexedDB.db;
2387         var trans = db.transaction(["cache"]);
2388         var store = trans.objectStore("cache");
2389
2390         var key = file_name;
2391
2392          var getReq = store.get(key);
2393            getReq.onsuccess = function (ev) {
2394                         if (getReq.result)
2395         {
2396         dump('chanka ' + g_mandreel_timestamp_fs + ' ' + getReq.result.timeStamp + '\n');
2397                                 if (getReq.result.timeStamp>=g_mandreel_timestamp_fs)
2398                                         callback(getReq.result.data);
2399                                 else
2400                                         callback(null);
2401                         }
2402                         else
2403                                 callback(null);
2404            }
2405            getReq.onerror = function (ev) {
2406                    console.log("index.get failed. Error: " + ev.message);
2407            }
2408 }
2409
2410 function mandreel_fs_get_url(file_name, callback)
2411 {
2412         if (mandreel_indexedDB.db)
2413         {
2414                 callback(null);
2415                 return;
2416         }
2417
2418
2419         if (g_mandreel_fs == null)
2420         {
2421                 callback(null);
2422                 return;
2423         }
2424
2425         g_mandreel_fs.root.getFile(file_name, {}, function(fileEntry) {
2426
2427         fileEntry.getMetadata(function(metaData){
2428         var my_seconds = metaData.modificationTime.getTime()/1000;
2429
2430         if (g_mandreel_timestamp_fs>my_seconds)
2431         {
2432                 callback(null);
2433         }
2434         else
2435         {
2436                 //alert('mandreel_fscachefile2');
2437
2438
2439                 if (Mandreel_window.localStorage.getItem(mandreel_fs_get_key(file_name)) != null)
2440                         callback(fileEntry.toURL());
2441                 else
2442                         callback(null);
2443
2444         }
2445
2446
2447                 }, MandreelFsErrorHandler);
2448
2449
2450   }, function(error) {callback(null);});
2451
2452          return;
2453
2454 }
2455
2456 function mandreel_fs_load_binary(file_name, callback)
2457  {
2458         if (mandreel_indexedDB.db)
2459         {
2460                 mandreel_indexedDB.load(file_name,callback);
2461                 return;
2462         }
2463
2464
2465         if (g_mandreel_fs == null)
2466         {
2467                 callback(null);
2468                 return;
2469         }
2470
2471
2472         g_mandreel_fs.root.getFile(file_name, {}, function(fileEntry) {
2473
2474         fileEntry.getMetadata(function(metaData){
2475         var my_seconds = metaData.modificationTime.getTime()/1000;
2476
2477         if (g_mandreel_timestamp_fs>my_seconds)
2478         {
2479                 dump('mandreel_fscachefile1');
2480                 Mandreel_window.localStorage.removeItem(mandreel_fs_get_key(file_name));
2481                 fileEntry.remove(function() {
2482                                 callback(null);
2483                         }, MandreelFsErrorHandler);
2484
2485         }
2486         else
2487         {
2488                 //alert('mandreel_fscachefile2');
2489                 dump('mandreel_fscachefile2 ' + my_seconds);
2490
2491                 fileEntry.file(function(file) {
2492
2493                                 var reader = new FileReader();
2494
2495
2496                            reader.onloadend = function(e) {
2497
2498                                    if (this.result.byteLength && Mandreel_window.localStorage.getItem(mandreel_fs_get_key(file_name)) != null)
2499                                    {
2500                                                 dump('mandreel_fs_loadFile ' + file_name);
2501                                                 callback(this.result);
2502                                         }
2503                                         else
2504                                                 callback(null);
2505
2506                            };
2507
2508
2509                                  reader.readAsArrayBuffer(file);
2510
2511
2512                         }, MandreelFsErrorHandler);
2513
2514         }
2515
2516
2517                 }, MandreelFsErrorHandler);
2518
2519
2520   }, function(error) {dump('mandreel_fscachefile3');    callback(null);});
2521
2522          return;
2523  }
2524
2525
2526  mandreel_indexedDB.save = function(file_name, data)
2527 {
2528         var db = mandreel_indexedDB.db;
2529
2530
2531   var trans = db.transaction(["cache"], IDBTransaction.READ_WRITE);
2532   var store = trans.objectStore("cache");
2533   var request = store.put({
2534     "data": data,
2535         "timeStamp" : Date_now()/1000,
2536     "fileName" : file_name
2537   });
2538
2539   request.onsuccess = function(e) {
2540     // Re-render all the todo's
2541    // html5rocks.indexedDB.getAllTodoItems();
2542    dump('mandreel_indexedDB.save ok ');
2543   };
2544
2545   request.onerror = function(e) {
2546     dump('mandreel_indexedDB.save onerror ' + file_name);
2547         dump(e);
2548   };
2549 }
2550
2551 function mandreel_fs_get_key(name)
2552 {
2553         return 'mandreel_fs_' + name;
2554 }
2555
2556 function mandreel_is_filesystem()
2557 {
2558         if (mandreel_indexedDB.db)
2559                 return false;
2560
2561         if (!g_mandreel_fs)
2562                 return false;
2563
2564         return true;
2565 }
2566
2567 function mandreel_is_indexeddb()
2568 {
2569         if (mandreel_indexedDB.db)
2570                 return true;
2571
2572         return false;
2573 }
2574
2575  function mandreel_fs_saveFile(name, my_arrayBuffer)
2576 {
2577         if (mandreel_indexedDB.db)
2578         {
2579                 mandreel_indexedDB.save(name,my_arrayBuffer);
2580                 return;
2581         }
2582
2583         if (!g_mandreel_fs)
2584                 return;
2585
2586         Mandreel_window.localStorage.removeItem(mandreel_fs_get_key(name));
2587         g_mandreel_fs.root.getFile(name, {create: true}, function(fileEntry) {
2588
2589     // Create a FileWriter object for our FileEntry (log.txt).
2590     fileEntry.createWriter(function(fileWriter) {
2591
2592       fileWriter.onwriteend = function(e) {
2593                 Mandreel_window.localStorage.setItem(mandreel_fs_get_key(name),'valid');
2594         dump('Write completed.');
2595       };
2596
2597       fileWriter.onerror = function(e) {
2598         dump('Write failed: ' + e.toString());
2599       };
2600
2601           var my_BlobBuilder = Mandreel_window.MozBlobBuilder || Mandreel_window.WebKitBlobBuilder || Mandreel_window.BlobBuilder;
2602
2603           var bb = new my_BlobBuilder(); // Note: window.WebKitBlobBuilder in Chrome 12.
2604       bb.append(my_arrayBuffer);
2605       fileWriter.write(bb.getBlob('text/plain'));
2606
2607
2608
2609     }, MandreelFsErrorHandler);
2610
2611   }, MandreelFsErrorHandler);
2612 }
2613
2614
2615 function mandreel_fs_load_text(file_name, callback)
2616  {
2617
2618         if (mandreel_indexedDB.db)
2619         {
2620                 mandreel_indexedDB.load(file_name,callback);
2621                 return;
2622         }
2623
2624         if (g_mandreel_fs == null)
2625         {
2626                 callback(null);
2627                 return;
2628         }
2629
2630
2631         g_mandreel_fs.root.getFile(file_name, {}, function(fileEntry) {
2632
2633         fileEntry.getMetadata(function(metaData){
2634         var my_seconds = metaData.modificationTime.getTime()/1000;
2635
2636         if (g_mandreel_timestamp_fs>my_seconds)
2637         {
2638                 dump('mandreel_fscachefile1');
2639                 Mandreel_window.localStorage.removeItem(mandreel_fs_get_key(file_name));
2640                 fileEntry.remove(function() {
2641                                 callback(null);
2642                         }, MandreelFsErrorHandler);
2643
2644         }
2645         else
2646         {
2647                 //alert('mandreel_fscachefile2');
2648                 dump('mandreel_fscachefile2 ' + my_seconds);
2649
2650                 fileEntry.file(function(file) {
2651
2652                                 var reader = new FileReader();
2653
2654
2655                            reader.onloadend = function(e) {
2656
2657
2658                                    if (this.result.length && Mandreel_window.localStorage.getItem(mandreel_fs_get_key(file_name)) != null)
2659                                    {
2660                                                 dump('mandreel_fs_loadFile ' + file_name);
2661                                                 callback(this.result);
2662                                         }
2663                                         else
2664                                                 callback(null);
2665
2666                            };
2667
2668
2669                                  reader.readAsText(file);
2670
2671
2672                         }, MandreelFsErrorHandler);
2673
2674         }
2675
2676
2677                 }, MandreelFsErrorHandler);
2678
2679
2680   }, function(error) {dump('mandreel_fscachefile3');    callback(null);});
2681
2682          return;
2683  }
2684
2685
2686  // full screen
2687
2688
2689 /* The following code was removed for benchmarking:
2690  var __screen = screen; */
2691
2692         try
2693         {
2694         (function(global) {
2695     "use strict";
2696         var elementPrototype = (global.HTMLElement || global.Element)["prototype"];
2697
2698          // document.isFullScreen
2699     if(!Mandreel_document.hasOwnProperty("fullscreenEnabled")) {
2700         var getter = (function() {
2701             // These are the functions that match the spec, and should be preferred
2702             if("webkitIsFullScreen" in Mandreel_document) {
2703                 return function() { return Mandreel_document.webkitIsFullScreen; }
2704             }
2705             if("mozFullScreen" in Mandreel_document) {
2706                 return function() { return Mandreel_document.mozFullScreen; }
2707             }
2708             return function() { return false }; // not supported, never fullscreen
2709         })();
2710
2711         Object.defineProperty(Mandreel_document, "fullscreenEnabled", {
2712             enumerable: true, configurable: false, writeable: false,
2713             get: getter
2714         });
2715     }
2716
2717     if(!Mandreel_document.hasOwnProperty("fullscreenElement")) {
2718         var getter = (function() {
2719             // These are the functions that match the spec, and should be preferred
2720             if("webkitFullscreenElement" in Mandreel_document) {
2721                 return function() { return Mandreel_document.webkitFullscreenElement; }
2722             }
2723             if("mozFullscreenElemen" in Mandreel_document) {
2724                 return function() { return Mandreel_document.mozFullscreenElemen; }
2725             }
2726             return function() { return null }; // not supported
2727         })();
2728
2729         Object.defineProperty(Mandreel_document, "fullscreenElement", {
2730             enumerable: true, configurable: false, writeable: false,
2731             get: getter
2732         });
2733     }
2734
2735     // Document event: fullscreenchange
2736     function fullscreenchange(oldEvent) {
2737         var newEvent = Mandreel_document.createEvent("CustomEvent");
2738         newEvent.initCustomEvent("fullscreenchange", true, false, null);
2739         // TODO: Any need for variable copy?
2740         Mandreel_document.dispatchEvent(newEvent);
2741     }
2742     Mandreel_document.addEventListener("webkitfullscreenchange", fullscreenchange, false);
2743     Mandreel_document.addEventListener("mozfullscreenchange", fullscreenchange, false);
2744
2745     // Document event: fullscreenerror
2746     function fullscreenerror(oldEvent) {
2747         var newEvent = Mandreel_document.createEvent("CustomEvent");
2748         newEvent.initCustomEvent("fullscreenerror", true, false, null);
2749         // TODO: Any need for variable copy?
2750         Mandreel_document.dispatchEvent(newEvent);
2751     }
2752     Mandreel_document.addEventListener("webkitfullscreenerror", fullscreenerror, false);
2753     Mandreel_document.addEventListener("mozfullscreenerror", fullscreenerror, false);
2754
2755     // element.requestFullScreen
2756     if(!elementPrototype.requestFullScreen) {
2757         elementPrototype.requestFullScreen = (function() {
2758             if(elementPrototype.webkitRequestFullScreen) {
2759                 return function() {
2760                     this.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);
2761                 }
2762             }
2763
2764             return  elementPrototype.mozRequestFullScreen    ||
2765                     function(){ /* unsupported, fail silently */ };
2766         })();
2767     }
2768
2769     // document.cancelFullscreen
2770     if(!Mandreel_document.cancelFullScreen) {
2771         Mandreel_document.cancelFullScreen = (function() {
2772             return  Mandreel_document.webkitCancelFullScreen ||
2773                     Mandreel_document.mozCancelFullScreen ||
2774                     function(){ /* unsupported, fail silently */ };
2775         })();
2776     }
2777         })((typeof(exports) != 'undefined') ? global : Mandreel_window);
2778         }
2779         catch(e)
2780         {
2781         }
2782
2783
2784 try
2785         {
2786 var __onErrorFullscreen = function() {
2787   dump("Mouse lock was not successful.");
2788 };
2789
2790 Mandreel_document.addEventListener('fullscreenchange', function(e) {
2791
2792 var width;
2793 var height;
2794  var canvas = Mandreel_document.getElementById(mandreelAppCanvasName);
2795  if(Mandreel_document.fullscreenEnabled) {
2796
2797
2798             width = __screen.width;
2799             height = __screen.height;
2800
2801         } else {
2802             width = mandreelAppWidthSrc;
2803             height = mandreelAppHeightSrc;
2804         }
2805
2806                 canvas.width = width;
2807                 canvas.height = height;
2808                 mandreelAppResize(width, height);
2809
2810   if (Mandreel_document.fullscreenEnabled && navigator.pointer) {
2811     navigator.pointer.lock(Mandreel_document.body, function() {
2812       // Locked and ready to play.
2813     }, __onErrorFullscreen);
2814   }
2815 }, false);
2816
2817 }
2818 catch(e)
2819 {
2820 }
2821
2822
2823
2824 function mandreelAppFullscreen(enable)
2825 {
2826         var canvas = Mandreel_document.getElementById(mandreelAppCanvasName);
2827         if ( mandreelAppPlatform == "webgl" || mandreelAppPlatform == "canvas" )
2828         {
2829                 if (canvas)
2830                 {
2831                         if (enable)
2832                                 canvas.requestFullScreen();
2833                         else
2834                                 Mandreel_document.cancelFullScreen();
2835                 }
2836         }
2837 }
2838
2839
2840 function mandreelAppDisableForceFocus()
2841 {
2842         mandreelAppForceFocus = false;
2843 }
2844
2845 function mandreelAppEnableForceFocus()
2846 {
2847         mandreelAppForceFocus = true;
2848 }
2849
2850 var imandreel_base64 = {};
2851 imandreel_base64.PADCHAR = '=';
2852 imandreel_base64.ALPHA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
2853
2854 imandreel_base64.makeDOMException = function() {
2855     // sadly in FF,Safari,Chrome you can't make a DOMException
2856     var e, tmp;
2857
2858     try {
2859         return new DOMException(DOMException.INVALID_CHARACTER_ERR);
2860     } catch (tmp) {
2861         // not available, just passback a duck-typed equiv
2862         // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Error
2863         // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Error/prototype
2864         var ex = new Error("DOM Exception 5");
2865
2866         // ex.number and ex.description is IE-specific.
2867         ex.code = ex.number = 5;
2868         ex.name = ex.description = "INVALID_CHARACTER_ERR";
2869
2870         // Safari/Chrome output format
2871         ex.toString = function() { return 'Error: ' + ex.name + ': ' + ex.message; };
2872         return ex;
2873     }
2874 }
2875
2876 imandreel_base64.getbyte64 = function(s,i) {
2877     // This is oddly fast, except on Chrome/V8.
2878     //  Minimal or no improvement in performance by using a
2879     //   object with properties mapping chars to value (eg. 'A': 0)
2880     var idx = imandreel_base64.ALPHA.indexOf(s.charAt(i));
2881     if (idx === -1) {
2882         throw imandreel_base64.makeDOMException();
2883     }
2884     return idx;
2885 }
2886
2887 imandreel_base64.decode = function(s) {
2888     // convert to string
2889     s = '' + s;
2890     var getbyte64 = imandreel_base64.getbyte64;
2891     var pads, i, b10;
2892     var imax = s.length
2893     if (imax === 0) {
2894         return s;
2895     }
2896
2897     if (imax % 4 !== 0) {
2898         throw imandreel_base64.makeDOMException();
2899     }
2900
2901     pads = 0
2902     if (s.charAt(imax - 1) === imandreel_base64.PADCHAR) {
2903         pads = 1;
2904         if (s.charAt(imax - 2) === imandreel_base64.PADCHAR) {
2905             pads = 2;
2906         }
2907         // either way, we want to ignore this last block
2908         imax -= 4;
2909     }
2910
2911     var x = [];
2912     for (i = 0; i < imax; i += 4) {
2913         b10 = (getbyte64(s,i) << 18) | (getbyte64(s,i+1) << 12) |
2914             (getbyte64(s,i+2) << 6) | getbyte64(s,i+3);
2915         x.push(String.fromCharCode(b10 >> 16, (b10 >> 8) & 0xff, b10 & 0xff));
2916     }
2917
2918     switch (pads) {
2919     case 1:
2920         b10 = (getbyte64(s,i) << 18) | (getbyte64(s,i+1) << 12) | (getbyte64(s,i+2) << 6);
2921         x.push(String.fromCharCode(b10 >> 16, (b10 >> 8) & 0xff));
2922         break;
2923     case 2:
2924         b10 = (getbyte64(s,i) << 18) | (getbyte64(s,i+1) << 12);
2925         x.push(String.fromCharCode(b10 >> 16));
2926         break;
2927     }
2928     return x.join('');
2929 }
2930
2931 if (!Mandreel_window.atob) {
2932 Mandreel_window.atob = function(a) { return  imandreel_base64.decode(a); }
2933 }
2934
2935
2936 function imandreel_interop_callbridge(new_method, sp)
2937 {
2938
2939         var n = new Array();
2940
2941         for( var i = 2; i < arguments.length; i++ )
2942         {
2943
2944                 if (typeof arguments[i] == 'string')
2945                         n.push(atob(arguments[i]));
2946                 else
2947                         n.push(arguments[i]);
2948         }
2949
2950         var total_args = arguments.length-2;
2951
2952         switch(total_args)
2953         {
2954                 case 0:
2955                         return Mandreel_window[new_method](sp);
2956                 case 1:
2957                         return Mandreel_window[new_method](sp, n[0]);
2958                 case 2:
2959                         return Mandreel_window[new_method](sp, n[0], n[1]);
2960                 case 3:
2961                         return Mandreel_window[new_method](sp, n[0], n[1], n[2]);
2962                 case 4:
2963                         return Mandreel_window[new_method](sp, n[0], n[1], n[2], n[3]);
2964                 case 5:
2965                         return Mandreel_window[new_method](sp, n[0], n[1], n[2], n[3], n[4]);
2966                 case 6:
2967                         return Mandreel_window[new_method](sp, n[0], n[1], n[2], n[3], n[4], n[5]);
2968                 case 7:
2969                         return Mandreel_window[new_method](sp, n[0], n[1], n[2], n[3], n[4], n[5], n[6]);
2970                 case 8:
2971                         return Mandreel_window[new_method](sp, n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7]);
2972                 case 9:
2973                         return Mandreel_window[new_method](sp, n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[8]);
2974                 case 10:
2975                         return Mandreel_window[new_method](sp, n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[8], n[9]);
2976                 case 11:
2977                         return Mandreel_window[new_method](sp, n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[8], n[9], n[10]);
2978                 case 12:
2979                         return Mandreel_window[new_method](sp, n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[8], n[9], n[10], n[11]);
2980                 case 13:
2981                         return Mandreel_window[new_method](sp, n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[8], n[9], n[10], n[11], n[12]);
2982                 case 14:
2983                         return Mandreel_window[new_method](sp, n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[8], n[9], n[10], n[11], n[12], n[13]);
2984                 case 15:
2985                         return Mandreel_window[new_method](sp, n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[8], n[9], n[10], n[11], n[12], n[13], n[14]);
2986                 case 16:
2987                         return Mandreel_window[new_method](sp, n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[8], n[9], n[10], n[11], n[12], n[13], n[14], n[15]);
2988                 break;
2989         }
2990
2991 }
2992 function imandreel_as3_dump(param)
2993 {
2994         dump(atob(param));
2995 }
2996
2997
2998 var mandreel_embed_plugin;
2999
3000 function PluginMandreelInterWriteInt(ptr, value)
3001 {
3002         mandreel_embed_plugin.MandreelInterCalls("WriteInt", ptr,value);
3003 }
3004
3005 function PluginMandreelInterWriteFloat(ptr, value)
3006 {
3007         mandreel_embed_plugin.MandreelInterCalls("WriteFloat", ptr,value);
3008 }
3009
3010 function PluginMandreelInterWriteString(ptr, value)
3011 {
3012         mandreel_embed_plugin.MandreelInterCalls("WriteString", ptr,value);
3013 }
3014
3015 function PluginMandreelInterWriteWString(ptr, value)
3016 {
3017         mandreel_embed_plugin.MandreelInterCalls("WriteWString", ptr,value);
3018 }
3019
3020 var mandreel_plugin_current_sp = 0;
3021
3022 function PluginMandreelLockFrame()
3023 {
3024         var result = mandreel_embed_plugin.MandreelInterCalls("LockFrame");
3025
3026         mandreel_plugin_current_sp+=300*1024;
3027
3028         assert(mandreel_plugin_current_sp<1024*1024);
3029
3030         return result+mandreel_plugin_current_sp;
3031 }
3032
3033 function PluginMandreelPause()
3034 {
3035         mandreel_embed_plugin.MandreelInterCalls("Pause");
3036 }
3037
3038 function PluginMandreelResume()
3039 {
3040         mandreel_embed_plugin.MandreelInterCalls("Resume");
3041 }
3042
3043
3044 function PluginMandreelUnlockFrame()
3045 {
3046         mandreel_embed_plugin.MandreelInterCalls("UnlockFrame");
3047
3048         mandreel_plugin_current_sp-=300*1024;
3049 }
3050
3051 function PluginMandreelInterCallFunction()
3052 {
3053         var total_args = arguments.length;
3054
3055         switch(total_args)
3056         {
3057                 case 0:
3058                         return mandreel_embed_plugin.MandreelInterCallFunction();
3059                 case 1:
3060                         return mandreel_embed_plugin.MandreelInterCallFunction(arguments[0]);
3061                 case 2:
3062                         return mandreel_embed_plugin.MandreelInterCallFunction(arguments[0], arguments[1]);
3063                 case 3:
3064                         return mandreel_embed_plugin.MandreelInterCallFunction(arguments[0], arguments[1], arguments[2]);
3065                 case 4:
3066                         return mandreel_embed_plugin.MandreelInterCallFunction(arguments[0], arguments[1], arguments[2], arguments[3]);
3067                 case 5:
3068                         return mandreel_embed_plugin.MandreelInterCallFunction(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);
3069                 case 6:
3070                         return mandreel_embed_plugin.MandreelInterCallFunction(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
3071                 case 7:
3072                         return mandreel_embed_plugin.MandreelInterCallFunction(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6]);
3073                 case 8:
3074                         return mandreel_embed_plugin.MandreelInterCallFunction(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7]);
3075                 case 9:
3076                         return mandreel_embed_plugin.MandreelInterCallFunction(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8]);
3077                 case 10:
3078                         return mandreel_embed_plugin.MandreelInterCallFunction(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9]);
3079                 case 11:
3080                         return mandreel_embed_plugin.MandreelInterCallFunction(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10]);
3081                 case 12:
3082                         return mandreel_embed_plugin.MandreelInterCallFunction(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11]);
3083                 case 13:
3084                         return mandreel_embed_plugin.MandreelInterCallFunction(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11], arguments[12]);
3085                 case 14:
3086                         return mandreel_embed_plugin.MandreelInterCallFunction(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11], arguments[12], arguments[13]);
3087                 case 15:
3088                         return mandreel_embed_plugin.MandreelInterCallFunction(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11], arguments[12], arguments[13], arguments[14]);
3089                 case 16:
3090                         return mandreel_embed_plugin.MandreelInterCallFunction(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11], arguments[12], arguments[13], arguments[14], arguments[15]);
3091                 break;
3092         }
3093 }
3094
3095 function mandreel_plugin_draw()
3096 {
3097         var canvas = Mandreel_document.getElementById('canvasDiv');
3098         WebGLUtils.requestAnimationFrame(canvas, mandreel_plugin_draw);
3099         mandreel_embed_plugin.MandreelInterCalls("AppDraw");
3100
3101 }
3102
3103 function mandreelInitPluginPlatform(params)
3104 {
3105
3106         if ( params.width != null )
3107                 mandreelAppWidthSrc = params.width;
3108
3109         if ( params.height != null )
3110                 mandreelAppHeightSrc = params.height;
3111
3112
3113         mandreel_embed_plugin = Mandreel_document.createElement('embed');
3114         mandreel_embed_plugin.setAttribute('width',mandreelAppWidthSrc);
3115         mandreel_embed_plugin.setAttribute('height',mandreelAppHeightSrc);
3116         mandreel_embed_plugin.setAttribute('type',"application/halfbrick-npruntime-scriptable-plugin");
3117
3118         var div = Mandreel_document.getElementById('canvasDiv');
3119
3120
3121         var oChild=div.firstChild;
3122
3123         div.replaceChild(mandreel_embed_plugin, oChild);
3124
3125         var flashElement = Mandreel_document.getElementById('FlashWrapper');
3126         if ( flashElement != null )
3127         {
3128                 flashElement.style.visibility = "hidden";
3129                 flashElement.style.width = "0px";
3130                 flashElement.style.height = "0px";
3131         }
3132
3133
3134
3135
3136
3137         Mandreel_window.MandreelInterWriteInt     = PluginMandreelInterWriteInt;
3138         Mandreel_window.MandreelInterWriteFloat   = PluginMandreelInterWriteInt;
3139         Mandreel_window.MandreelInterWriteString  = PluginMandreelInterWriteString;
3140         Mandreel_window.MandreelInterWriteWString = PluginMandreelInterWriteWString;
3141         Mandreel_window.MandreelLockFrame         = PluginMandreelLockFrame;
3142         Mandreel_window.MandreelUnlockFrame       = PluginMandreelUnlockFrame;
3143         Mandreel_window.MandreelInterCallFunction = PluginMandreelInterCallFunction;
3144         Mandreel_window.MandreelPause                    = PluginMandreelPause;
3145         Mandreel_window.MandreelResume                   = PluginMandreelResume;
3146
3147         Mandreel_setTimeout(function () {
3148
3149         if ( typeof(params.pluginSolutionName) != 'undefined' )
3150                 mandreel_embed_plugin.init(params.pluginDLL, params.pluginWorkingFolder,params.pluginSolutionName);
3151         else
3152                 mandreel_embed_plugin.init(params.pluginDLL, params.pluginWorkingFolder);
3153
3154
3155         mandreelAppStartStateFunc("ready",mandreelAppWidthSrc,mandreelAppHeightSrc);
3156
3157         Mandreel_setTimeout("mandreel_plugin_draw()", 16);
3158         }, 100);
3159
3160 }
3161
3162
3163 function MandreelInterSwfProgress(mode, percentage, bytes, totalbytes)
3164 {
3165         imandreel_update_load(bytes, totalbytes);
3166         if (mode == 'files')
3167         {
3168                 if ( mandreelAppStartStateFunc )
3169                         mandreelAppStartStateFunc("loadingData",percentage);
3170         }
3171         else if (mode == 'audio')
3172         {
3173                 if ( mandreelAppStartStateFunc )
3174                         mandreelAppStartStateFunc("loadingAudioUpdate",percentage);
3175         }
3176         else if (mode == 'textureasync')
3177         {
3178                 if ( mandreelAppStartStateFunc )
3179                         mandreelAppStartStateFunc("loadingTextureAsyncPack",percentage);
3180         }
3181
3182 }
3183
3184 function MandreelInterSwfCheckMethod(method)
3185 {
3186         if (typeof(Mandreel_window[method])=="undefined")
3187                 return 0;
3188         else
3189                 return 1;
3190 }
3191
3192 // End of js/mandreelapp.js file.
3193
3194 // Start of mandreel.js file.
3195
3196 var mandreel_total_memory = 15908864;
3197 var mandreel_stack_memory = 1048576;
3198 var mandreel_heap_memory = 13591752; //init_memory = 744248
3199 /////////////////////////////////////////////
3200 // Heap
3201 /////////////////////////////////////////////
3202 var heap;
3203 var heap8;
3204 var heapU8;
3205 var heap16;
3206 var heapU16;
3207 var heap32;
3208 var heapU32;
3209 var heapFloat;
3210 var heapDouble;
3211 var heapNewPos = 512;
3212
3213 var ABORT = false;
3214
3215 var g_mandreel_cache_files = false;
3216
3217
3218 var g_mandreel_frame_locked = false;
3219 var g_mandreel_frame_inframe = false;
3220
3221 var mandreel_cache_files = [];
3222 var g_mandreel_working_folder = 'DataPC/';
3223 var g_mandreel_datafiles_sufix = '.dat';
3224 var __FUNCTION_TABLE__ = [];
3225 var mandreel_pos_function_table = 1;
3226 function register_delegate(ptr_func)
3227 {
3228         var functionId = mandreel_pos_function_table;
3229         __FUNCTION_TABLE__[functionId] = ptr_func;
3230
3231         mandreel_pos_function_table++;
3232         return functionId*4;
3233 }
3234
3235
3236 var g_addr_emit = 0;
3237 function emit_start(addr)
3238 {
3239         g_addr_emit = addr;
3240 }
3241
3242 function emit_8(data)
3243 {
3244         heapU8[g_addr_emit] = data;
3245         g_addr_emit++;
3246 }
3247
3248 function emit_16(data)
3249 {
3250         heapU16[g_addr_emit>>1] = data;
3251         g_addr_emit+=2;
3252 }
3253
3254 function emit_32(data)
3255 {
3256         heapU32[g_addr_emit>>2] = data;
3257         g_addr_emit+=4;
3258 }
3259
3260 function emit_fill(data, size)
3261 {
3262         var j;
3263         for (j=0;j<size;j++)
3264         {
3265                 heapU8[g_addr_emit] = data;
3266                 g_addr_emit++;
3267         }
3268 }
3269
3270 function emit_string(v)
3271 {
3272         var j;
3273         var len = v.length;
3274         var data;
3275
3276         for(j = 0; j < len; j++)
3277         {
3278                 data = v.charCodeAt(j);
3279
3280                 heapU8[g_addr_emit] = data;
3281                 g_addr_emit++;
3282         }
3283 }
3284
3285
3286
3287
3288
3289 var g_stack_pointer = Malloc(mandreel_stack_memory);
3290
3291 function assert_unalign()
3292 {
3293         dump("fatal error: unaligned memory access detected!!!!");
3294         assert(false);
3295 }
3296
3297 function _assert(sp)
3298 {
3299         var p0 = heap32[sp>>2];sp+=4;
3300   var p1 = heap32[sp>>2];sp+=4;
3301   var line = heap32[sp>>2];sp+=4;
3302         var name = get_string_from_ptr(p0);
3303         var file = get_string_from_ptr(p1);
3304         assert(false, name + file + ' ' + line);
3305 }
3306 __cxa_pure_virtual.__index__ = 0;
3307 function __cxa_pure_virtual()
3308 {
3309         assert(0);
3310 }
3311
3312 // operator delete[]
3313 function _ZdaPv(sp)
3314 {
3315         free(sp);
3316 }
3317
3318 // operator delete
3319 function _ZdlPv(sp)
3320 {
3321         free(sp);
3322 }
3323
3324 // operator new[](unsigned int)
3325 function _Znaj(sp)
3326 {
3327         malloc(sp);
3328 }
3329 // operator new[](unsigned int)
3330 function _Znwj(sp)
3331 {
3332         malloc(sp);
3333 }
3334
3335 function abort(sp)
3336 {
3337         assert(0);
3338 }
3339
3340 var r_g0 = 0;
3341 var r_g1 = 0;
3342 var f_g0 = 0;
3343
3344 //isFinite(aux)
3345 //isNaN(aux)
3346
3347 var tlsf_ptr = 0;
3348
3349
3350 function initHeap()
3351 {
3352         heap = new ArrayBuffer(mandreel_total_memory);
3353         heap8 = new Int8Array(heap);
3354         heapU8 = new Uint8Array(heap);
3355         heap16 = new Int16Array(heap);
3356         heapU16 = new Uint16Array(heap);
3357         heap32 = new Int32Array(heap);
3358         heapU32 = new Uint32Array(heap);
3359         heapFloat = new Float32Array(heap);
3360         heapDouble = new Float64Array(heap);
3361
3362
3363         for (var i=0;i<mandreel_total_memory/4;i++)
3364         {
3365                 heapU32[i] = 0;
3366         }
3367 }
3368
3369 function Malloc(bytes)
3370 {
3371         if ( heap == undefined )
3372         {
3373                 //initHeap();
3374         }
3375         var newOffset = heapNewPos;
3376         // Always 32 bit aligned
3377         heapNewPos += ((bytes + 3) & 0xfffffffc);
3378
3379         if (heapNewPos>mandreel_total_memory)
3380         {
3381                 assert(false);
3382         }
3383
3384         return newOffset;
3385 }
3386
3387 function assert(condition, _text) {
3388 //console.assert(condition, _text);
3389     if (!condition) {
3390       var text = "Assertion failed: " + _text;
3391       alert(text + ':\n' + (new Error).stack);
3392       ABORT = true;
3393       throw "Assertion: " + text;
3394     }
3395   }
3396
3397   function my_assert(sp)
3398   {
3399         var p0 = heap32[sp>>2];sp+=4;
3400   var p1 = heap32[sp>>2];sp+=4;
3401         //var name = get_string_from_ptr(p1);
3402
3403         assert(false, 'hola');
3404   }
3405
3406   function WriteHeapDouble(addr, value)
3407   {
3408   //assert((addr&7)==0);
3409         heapDouble[addr>>3] = value;
3410   }
3411
3412     function WriteHeapU64(addr, value)
3413   {
3414         heap32[addr>>2] = value.l;
3415         heap32[(addr>>2)+1] = value.h;
3416   }
3417
3418
3419 var arg_test_local = Malloc(8);
3420 function my_arg_test(sp)
3421 {
3422         var ptr = heapU32[sp>>2];
3423         var size = heapU32[(sp+4)>>2];
3424
3425         var arg = heapU32[ptr>>2];
3426
3427
3428         if (size == 4)
3429         {
3430         heap32[ptr>>2] = arg+4;
3431
3432         arg = heap32[arg>>2];
3433
3434         heap32[arg_test_local>>2] = arg;
3435
3436         //dump('my_arg_test ' + arg + ' ' + ptr + '\n');
3437
3438         }
3439         else
3440         {
3441                 arg = (arg+7) & ~7;
3442
3443                 heap32[ptr>>2] = arg+8;
3444
3445         //assert((arg&7)==0);
3446         var value0 = heap32[arg>>2];
3447         var value1 = heap32[(arg+4)>>2];
3448         //arg = llvm_readDouble(arg);
3449
3450         //assert((arg_test_local&7)==0);
3451
3452         heap32[arg_test_local>>2] = value0;
3453         heap32[(arg_test_local+4)>>2] = value1;
3454
3455         //llvm_writeDouble(arg_test_local,arg);
3456
3457         //dump('my_arg_test ' + arg + ' ' + ptr + '\n');
3458
3459
3460         }
3461
3462
3463
3464
3465         r_g0 = arg_test_local;
3466 }
3467
3468
3469
3470
3471
3472
3473 function uint(value) {
3474     if (value >= 0) return value;
3475     return 4294967296 + value;
3476   }
3477
3478
3479
3480 function puts(sp)
3481 {
3482         var addr = heapU32[sp>>2];
3483
3484         var name = get_string_from_ptr(addr);
3485
3486         name+='\n';
3487
3488         dump(name);
3489
3490 }
3491
3492 function _Z11print_valued(_stack_pos, value)
3493 {
3494         dump(value);
3495         dump('\n');
3496 }
3497
3498 function _Z11print_labelPKc(_stack_pos, addr)
3499 {
3500         puts(_stack_pos,addr);
3501         dump('\n');
3502 }
3503
3504
3505
3506
3507 function gettimeofday(sp)
3508   {
3509   var ptr = heap32[sp>>2];
3510   var time_ms = Date_now();
3511         heap32[ptr>>2] = time_ms/1000;
3512         heap32[(ptr>>2)+1] = (time_ms%1000)*1000;
3513         r_g0 = 0;
3514   }
3515
3516
3517   function free(sp)
3518   {
3519         var ptr = heapU32[sp>>2];
3520         sp-=8;
3521
3522         heap32[(sp)>>2] = tlsf_ptr;
3523         heap32[(sp+4)>>2] = ptr;
3524         tlsf_free(sp);
3525   }
3526
3527   function malloc_size(sp)
3528   {
3529   var ptr = heapU32[sp>>2];
3530
3531         sp-=4;
3532
3533         heap32[(sp)>>2] = ptr;
3534         tlsf_block_size(sp);
3535   }
3536
3537
3538   function realloc(sp)
3539   {
3540         var ptr = heapU32[sp>>2];
3541         var size = heapU32[(sp+4)>>2];
3542
3543         //assert(ptr == 0);
3544
3545         sp-=12;
3546
3547         //dump('realloc ' + sp + ' ' + ptr + ' ' + size + '\n');
3548
3549         heap32[(sp)>>2] = tlsf_ptr;
3550         heap32[(sp+4)>>2] = ptr;
3551         heap32[(sp+8)>>2] = size;
3552         tlsf_realloc(sp);
3553
3554         //dump('return ' + r_g0 + '\n');
3555   }
3556
3557   var llvm_double_addr = Malloc(8);
3558
3559   function llvm_writeDouble(addr,src)
3560   {
3561   //assert((llvm_double_addr&7)==0);
3562         heapDouble[llvm_double_addr>>3] = src;
3563
3564         //assert((addr&7)==0);
3565
3566         var val0 = heap32[(llvm_double_addr)>>2];
3567         var val1 = heap32[(llvm_double_addr+4)>>2];
3568
3569         heap32[(addr)>>2] = val0;
3570         heap32[(addr+4)>>2] = val1;
3571   }
3572
3573   function llvm_readDouble(addr)
3574   {
3575         //assert((addr&7)==0);
3576
3577         var val0 = heap32[(addr)>>2];
3578         var val1 = heap32[(addr+4)>>2];
3579
3580         heap32[(llvm_double_addr)>>2] = val0;
3581         heap32[(llvm_double_addr+4)>>2] = val1;
3582
3583
3584 //      assert((llvm_double_addr&7)==0);
3585         var result = heapDouble[llvm_double_addr>>3];
3586
3587
3588         return result;
3589
3590   }
3591
3592   function llvm_move_double(addr_dst, addr_src)
3593   {
3594
3595         var val0 = heapU32[(addr_src)>>2];
3596         var val1 = heapU32[(addr_src+4)>>2];
3597
3598         heapU32[(addr_dst)>>2] = val0;
3599         heapU32[(addr_dst+4)>>2] = val1;
3600
3601   }
3602
3603   function llvm_move_float(addr_dst, addr_src)
3604   {
3605         heapU32[(addr_dst)] = heapU32[(addr_src)];
3606   }
3607
3608   function malloc(sp)
3609   {
3610         var size = heapU32[sp>>2];
3611
3612         if (size == 0)
3613         {
3614                 size = 4;
3615         }
3616
3617
3618         if (tlsf_ptr == 0)
3619         {
3620                 var addr = Malloc(mandreel_heap_memory);
3621
3622                 sp-=8;
3623                 heap32[(sp)>>2] = addr;
3624                 heap32[(sp+4)>>2] = mandreel_heap_memory;
3625                 tlsf_create(sp);
3626                 tlsf_ptr = r_g0;
3627         }
3628
3629         sp-=8;
3630
3631         heap32[(sp)>>2] = tlsf_ptr;
3632         heap32[(sp+4)>>2] = size;
3633         tlsf_malloc(sp);
3634
3635         if (r_g0 == 0)
3636         {
3637                 dump('malloc failed ' + size + '\n');
3638                 assert(false);
3639         }
3640   }
3641
3642
3643    function log10f(sp)
3644   {
3645   var value = heapFloat[sp>>2];
3646         f_g0 = Math.log(value)/Math.LN10;
3647   }
3648
3649    function log10(sp)
3650   {
3651   var value = heapDouble[sp>>3];
3652         f_g0 = Math.log(value)/Math.LN10;
3653   }
3654
3655 function logf(sp)
3656   {
3657   var value = heapFloat[sp>>2];
3658         f_g0 = Math.log(value);
3659   }
3660
3661   function log(sp)
3662   {
3663   var value = heapDouble[sp>>3];
3664         f_g0 = Math.log(value);
3665   }
3666
3667
3668
3669   function cosf(sp)
3670   {
3671   var value = heapFloat[sp>>2];
3672         f_g0 = Math.cos(value);
3673         //assert (isNaN(f_g0) == false);
3674   }
3675
3676   function acosf(sp)
3677   {
3678   var value = heapFloat[sp>>2];
3679         f_g0 = Math.acos(value);
3680   }
3681
3682   function asinf(sp)
3683   {
3684   var value = heapFloat[sp>>2];
3685         f_g0 = Math.asin(value);
3686   }
3687
3688   function asin(sp)
3689   {
3690   var value = heapDouble[sp>>3];
3691         f_g0 = Math.asin(value);
3692   }
3693
3694   function acos(sp)
3695   {
3696   var value = heapDouble[sp>>3];
3697         f_g0 = Math.acos(value);
3698   }
3699
3700   function floor(sp)
3701   {
3702   var value = heapDouble[sp>>3];
3703         f_g0 = Math.floor(value);
3704   }
3705
3706   function floorf(sp)
3707   {
3708   var value = heapFloat[sp>>2];
3709         f_g0 = Math.floor(value);
3710   }
3711
3712   function round(sp)
3713   {
3714   var value = heapDouble[sp>>3];
3715         f_g0 = Math.round(value);
3716   }
3717
3718   function roundf(sp)
3719   {
3720   var value = heapFloat[sp>>2];
3721         f_g0 = Math.round(value);
3722   }
3723
3724   function ceilf(sp)
3725   {
3726   var value = heapFloat[sp>>2];
3727         f_g0 = Math.ceil(value);
3728   }
3729
3730   function ceil(sp)
3731   {
3732   var value = heapDouble[sp>>3];
3733         f_g0 = Math.ceil(value);
3734   }
3735
3736
3737   function exp2(sp)
3738   {
3739   var value = heapDouble[sp>>3];