From 853f8313870cde9984baf11d5e55de8e5d6c53aa Mon Sep 17 00:00:00 2001 From: Adam Weinstein Date: Wed, 1 Apr 2015 12:45:48 -0400 Subject: [PATCH] The demo of the side scroller game --- app.manifest | 19 + c2runtime.js | 17547 ++++++++++++++++++++++++++++++++++ data.js | 1 + icon-114.png | Bin 0 -> 25223 bytes icon-128.png | Bin 0 -> 33382 bytes icon-16.png | Bin 0 -> 1041 bytes icon-256.png | Bin 0 -> 98347 bytes icon-32.png | Bin 0 -> 2967 bytes images/baddyguy-sheet0.png | Bin 0 -> 868 bytes images/ground-sheet0.png | Bin 0 -> 621 bytes images/life-sheet0.png | Bin 0 -> 1324 bytes images/life-sheet1.png | Bin 0 -> 1438 bytes images/nevir-sheet0.png | Bin 0 -> 11622 bytes images/nevir-sheet1.png | Bin 0 -> 11220 bytes images/nevir-sheet2.png | Bin 0 -> 11300 bytes images/playerbox-sheet0.png | Bin 0 -> 155 bytes images/sky-sheet0.png | Bin 0 -> 10326 bytes images/sprite-sheet0.png | Bin 0 -> 168 bytes images/sprite2-sheet0.png | Bin 0 -> 662 bytes images/turnleft-sheet0.png | Bin 0 -> 367 bytes images/turnright-sheet0.png | Bin 0 -> 416 bytes images/wall-sheet0.png | Bin 0 -> 323 bytes index.html | 117 + jquery-2.1.1.min.js | 4 + loading-logo.png | Bin 0 -> 9375 bytes offline.appcache | 27 + 26 files changed, 17715 insertions(+) create mode 100644 app.manifest create mode 100644 c2runtime.js create mode 100644 data.js create mode 100644 icon-114.png create mode 100644 icon-128.png create mode 100644 icon-16.png create mode 100644 icon-256.png create mode 100644 icon-32.png create mode 100644 images/baddyguy-sheet0.png create mode 100644 images/ground-sheet0.png create mode 100644 images/life-sheet0.png create mode 100644 images/life-sheet1.png create mode 100644 images/nevir-sheet0.png create mode 100644 images/nevir-sheet1.png create mode 100644 images/nevir-sheet2.png create mode 100644 images/playerbox-sheet0.png create mode 100644 images/sky-sheet0.png create mode 100644 images/sprite-sheet0.png create mode 100644 images/sprite2-sheet0.png create mode 100644 images/turnleft-sheet0.png create mode 100644 images/turnright-sheet0.png create mode 100644 images/wall-sheet0.png create mode 100644 index.html create mode 100644 jquery-2.1.1.min.js create mode 100644 loading-logo.png create mode 100644 offline.appcache diff --git a/app.manifest b/app.manifest new file mode 100644 index 0000000..b6cdaba --- /dev/null +++ b/app.manifest @@ -0,0 +1,19 @@ +{ + "name": "New project", + "start_url": "/index.html", + "display": "fullscreen", + "orientation": "any", + "icons": [{ + "src": "icon-16.png", + "sizes": "16x16", + }, { + "src": "icon-32.png", + "sizes": "32x32", + }, { + "src": "icon-128.png", + "sizes": "128x128", + }, { + "src": "icon-256.png", + "sizes": "256x256", + }] +} diff --git a/c2runtime.js b/c2runtime.js new file mode 100644 index 0000000..8968ccf --- /dev/null +++ b/c2runtime.js @@ -0,0 +1,17547 @@ +// Generated by Construct 2, the HTML5 game and app creator :: http://www.scirra.com +var cr = {}; +cr.plugins_ = {}; +cr.behaviors = {}; +if (typeof Object.getPrototypeOf !== "function") +{ + if (typeof "test".__proto__ === "object") + { + Object.getPrototypeOf = function(object) { + return object.__proto__; + }; + } + else + { + Object.getPrototypeOf = function(object) { + return object.constructor.prototype; + }; + } +} +(function(){ + cr.logexport = function (msg) + { + if (window.console && window.console.log) + window.console.log(msg); + }; + cr.logerror = function (msg) + { + if (window.console && window.console.error) + window.console.error(msg); + }; + cr.seal = function(x) + { + return x; + }; + cr.freeze = function(x) + { + return x; + }; + cr.is_undefined = function (x) + { + return typeof x === "undefined"; + }; + cr.is_number = function (x) + { + return typeof x === "number"; + }; + cr.is_string = function (x) + { + return typeof x === "string"; + }; + cr.isPOT = function (x) + { + return x > 0 && ((x - 1) & x) === 0; + }; + cr.nextHighestPowerOfTwo = function(x) { + --x; + for (var i = 1; i < 32; i <<= 1) { + x = x | x >> i; + } + return x + 1; + } + cr.abs = function (x) + { + return (x < 0 ? -x : x); + }; + cr.max = function (a, b) + { + return (a > b ? a : b); + }; + cr.min = function (a, b) + { + return (a < b ? a : b); + }; + cr.PI = Math.PI; + cr.round = function (x) + { + return (x + 0.5) | 0; + }; + cr.floor = function (x) + { + if (x >= 0) + return x | 0; + else + return (x | 0) - 1; // correctly round down when negative + }; + cr.ceil = function (x) + { + var f = x | 0; + return (f === x ? f : f + 1); + }; + function Vector2(x, y) + { + this.x = x; + this.y = y; + cr.seal(this); + }; + Vector2.prototype.offset = function (px, py) + { + this.x += px; + this.y += py; + return this; + }; + Vector2.prototype.mul = function (px, py) + { + this.x *= px; + this.y *= py; + return this; + }; + cr.vector2 = Vector2; + cr.segments_intersect = function(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y) + { + var max_ax, min_ax, max_ay, min_ay, max_bx, min_bx, max_by, min_by; + if (a1x < a2x) + { + min_ax = a1x; + max_ax = a2x; + } + else + { + min_ax = a2x; + max_ax = a1x; + } + if (b1x < b2x) + { + min_bx = b1x; + max_bx = b2x; + } + else + { + min_bx = b2x; + max_bx = b1x; + } + if (max_ax < min_bx || min_ax > max_bx) + return false; + if (a1y < a2y) + { + min_ay = a1y; + max_ay = a2y; + } + else + { + min_ay = a2y; + max_ay = a1y; + } + if (b1y < b2y) + { + min_by = b1y; + max_by = b2y; + } + else + { + min_by = b2y; + max_by = b1y; + } + if (max_ay < min_by || min_ay > max_by) + return false; + var dpx = b1x - a1x + b2x - a2x; + var dpy = b1y - a1y + b2y - a2y; + var qax = a2x - a1x; + var qay = a2y - a1y; + var qbx = b2x - b1x; + var qby = b2y - b1y; + var d = cr.abs(qay * qbx - qby * qax); + var la = qbx * dpy - qby * dpx; + if (cr.abs(la) > d) + return false; + var lb = qax * dpy - qay * dpx; + return cr.abs(lb) <= d; + }; + function Rect(left, top, right, bottom) + { + this.set(left, top, right, bottom); + cr.seal(this); + }; + Rect.prototype.set = function (left, top, right, bottom) + { + this.left = left; + this.top = top; + this.right = right; + this.bottom = bottom; + }; + Rect.prototype.copy = function (r) + { + this.left = r.left; + this.top = r.top; + this.right = r.right; + this.bottom = r.bottom; + }; + Rect.prototype.width = function () + { + return this.right - this.left; + }; + Rect.prototype.height = function () + { + return this.bottom - this.top; + }; + Rect.prototype.offset = function (px, py) + { + this.left += px; + this.top += py; + this.right += px; + this.bottom += py; + return this; + }; + Rect.prototype.normalize = function () + { + var temp = 0; + if (this.left > this.right) + { + temp = this.left; + this.left = this.right; + this.right = temp; + } + if (this.top > this.bottom) + { + temp = this.top; + this.top = this.bottom; + this.bottom = temp; + } + }; + Rect.prototype.intersects_rect = function (rc) + { + return !(rc.right < this.left || rc.bottom < this.top || rc.left > this.right || rc.top > this.bottom); + }; + Rect.prototype.intersects_rect_off = function (rc, ox, oy) + { + return !(rc.right + ox < this.left || rc.bottom + oy < this.top || rc.left + ox > this.right || rc.top + oy > this.bottom); + }; + Rect.prototype.contains_pt = function (x, y) + { + return (x >= this.left && x <= this.right) && (y >= this.top && y <= this.bottom); + }; + Rect.prototype.equals = function (r) + { + return this.left === r.left && this.top === r.top && this.right === r.right && this.bottom === r.bottom; + }; + cr.rect = Rect; + function Quad() + { + this.tlx = 0; + this.tly = 0; + this.trx = 0; + this.try_ = 0; // is a keyword otherwise! + this.brx = 0; + this.bry = 0; + this.blx = 0; + this.bly = 0; + cr.seal(this); + }; + Quad.prototype.set_from_rect = function (rc) + { + this.tlx = rc.left; + this.tly = rc.top; + this.trx = rc.right; + this.try_ = rc.top; + this.brx = rc.right; + this.bry = rc.bottom; + this.blx = rc.left; + this.bly = rc.bottom; + }; + Quad.prototype.set_from_rotated_rect = function (rc, a) + { + if (a === 0) + { + this.set_from_rect(rc); + } + else + { + var sin_a = Math.sin(a); + var cos_a = Math.cos(a); + var left_sin_a = rc.left * sin_a; + var top_sin_a = rc.top * sin_a; + var right_sin_a = rc.right * sin_a; + var bottom_sin_a = rc.bottom * sin_a; + var left_cos_a = rc.left * cos_a; + var top_cos_a = rc.top * cos_a; + var right_cos_a = rc.right * cos_a; + var bottom_cos_a = rc.bottom * cos_a; + this.tlx = left_cos_a - top_sin_a; + this.tly = top_cos_a + left_sin_a; + this.trx = right_cos_a - top_sin_a; + this.try_ = top_cos_a + right_sin_a; + this.brx = right_cos_a - bottom_sin_a; + this.bry = bottom_cos_a + right_sin_a; + this.blx = left_cos_a - bottom_sin_a; + this.bly = bottom_cos_a + left_sin_a; + } + }; + Quad.prototype.offset = function (px, py) + { + this.tlx += px; + this.tly += py; + this.trx += px; + this.try_ += py; + this.brx += px; + this.bry += py; + this.blx += px; + this.bly += py; + return this; + }; + var minresult = 0; + var maxresult = 0; + function minmax4(a, b, c, d) + { + if (a < b) + { + if (c < d) + { + if (a < c) + minresult = a; + else + minresult = c; + if (b > d) + maxresult = b; + else + maxresult = d; + } + else + { + if (a < d) + minresult = a; + else + minresult = d; + if (b > c) + maxresult = b; + else + maxresult = c; + } + } + else + { + if (c < d) + { + if (b < c) + minresult = b; + else + minresult = c; + if (a > d) + maxresult = a; + else + maxresult = d; + } + else + { + if (b < d) + minresult = b; + else + minresult = d; + if (a > c) + maxresult = a; + else + maxresult = c; + } + } + }; + Quad.prototype.bounding_box = function (rc) + { + minmax4(this.tlx, this.trx, this.brx, this.blx); + rc.left = minresult; + rc.right = maxresult; + minmax4(this.tly, this.try_, this.bry, this.bly); + rc.top = minresult; + rc.bottom = maxresult; + }; + Quad.prototype.contains_pt = function (x, y) + { + var v0x = this.trx - this.tlx; + var v0y = this.try_ - this.tly; + var v1x = this.brx - this.tlx; + var v1y = this.bry - this.tly; + var v2x = x - this.tlx; + var v2y = y - this.tly; + var dot00 = v0x * v0x + v0y * v0y + var dot01 = v0x * v1x + v0y * v1y + var dot02 = v0x * v2x + v0y * v2y + var dot11 = v1x * v1x + v1y * v1y + var dot12 = v1x * v2x + v1y * v2y + var invDenom = 1.0 / (dot00 * dot11 - dot01 * dot01); + var u = (dot11 * dot02 - dot01 * dot12) * invDenom; + var v = (dot00 * dot12 - dot01 * dot02) * invDenom; + if ((u >= 0.0) && (v > 0.0) && (u + v < 1)) + return true; + v0x = this.blx - this.tlx; + v0y = this.bly - this.tly; + var dot00 = v0x * v0x + v0y * v0y + var dot01 = v0x * v1x + v0y * v1y + var dot02 = v0x * v2x + v0y * v2y + invDenom = 1.0 / (dot00 * dot11 - dot01 * dot01); + u = (dot11 * dot02 - dot01 * dot12) * invDenom; + v = (dot00 * dot12 - dot01 * dot02) * invDenom; + return (u >= 0.0) && (v > 0.0) && (u + v < 1); + }; + Quad.prototype.at = function (i, xory) + { + if (xory) + { + switch (i) + { + case 0: return this.tlx; + case 1: return this.trx; + case 2: return this.brx; + case 3: return this.blx; + case 4: return this.tlx; + default: return this.tlx; + } + } + else + { + switch (i) + { + case 0: return this.tly; + case 1: return this.try_; + case 2: return this.bry; + case 3: return this.bly; + case 4: return this.tly; + default: return this.tly; + } + } + }; + Quad.prototype.midX = function () + { + return (this.tlx + this.trx + this.brx + this.blx) / 4; + }; + Quad.prototype.midY = function () + { + return (this.tly + this.try_ + this.bry + this.bly) / 4; + }; + Quad.prototype.intersects_segment = function (x1, y1, x2, y2) + { + if (this.contains_pt(x1, y1) || this.contains_pt(x2, y2)) + return true; + var a1x, a1y, a2x, a2y; + var i; + for (i = 0; i < 4; i++) + { + a1x = this.at(i, true); + a1y = this.at(i, false); + a2x = this.at(i + 1, true); + a2y = this.at(i + 1, false); + if (cr.segments_intersect(x1, y1, x2, y2, a1x, a1y, a2x, a2y)) + return true; + } + return false; + }; + Quad.prototype.intersects_quad = function (rhs) + { + var midx = rhs.midX(); + var midy = rhs.midY(); + if (this.contains_pt(midx, midy)) + return true; + midx = this.midX(); + midy = this.midY(); + if (rhs.contains_pt(midx, midy)) + return true; + var a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y; + var i, j; + for (i = 0; i < 4; i++) + { + for (j = 0; j < 4; j++) + { + a1x = this.at(i, true); + a1y = this.at(i, false); + a2x = this.at(i + 1, true); + a2y = this.at(i + 1, false); + b1x = rhs.at(j, true); + b1y = rhs.at(j, false); + b2x = rhs.at(j + 1, true); + b2y = rhs.at(j + 1, false); + if (cr.segments_intersect(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y)) + return true; + } + } + return false; + }; + cr.quad = Quad; + cr.RGB = function (red, green, blue) + { + return Math.max(Math.min(red, 255), 0) + | (Math.max(Math.min(green, 255), 0) << 8) + | (Math.max(Math.min(blue, 255), 0) << 16); + }; + cr.GetRValue = function (rgb) + { + return rgb & 0xFF; + }; + cr.GetGValue = function (rgb) + { + return (rgb & 0xFF00) >> 8; + }; + cr.GetBValue = function (rgb) + { + return (rgb & 0xFF0000) >> 16; + }; + cr.shallowCopy = function (a, b, allowOverwrite) + { + var attr; + for (attr in b) + { + if (b.hasOwnProperty(attr)) + { +; + a[attr] = b[attr]; + } + } + return a; + }; + cr.arrayRemove = function (arr, index) + { + var i, len; + index = cr.floor(index); + if (index < 0 || index >= arr.length) + return; // index out of bounds + for (i = index, len = arr.length - 1; i < len; i++) + arr[i] = arr[i + 1]; + arr.length = len; + }; + cr.shallowAssignArray = function (dest, src) + { + dest.length = src.length; + var i, len; + for (i = 0, len = src.length; i < len; i++) + dest[i] = src[i]; + }; + cr.appendArray = function (a, b) + { + a.push.apply(a, b); + }; + cr.fastIndexOf = function (arr, item) + { + var i, len; + for (i = 0, len = arr.length; i < len; ++i) + { + if (arr[i] === item) + return i; + } + return -1; + }; + cr.arrayFindRemove = function (arr, item) + { + var index = cr.fastIndexOf(arr, item); + if (index !== -1) + cr.arrayRemove(arr, index); + }; + cr.clamp = function(x, a, b) + { + if (x < a) + return a; + else if (x > b) + return b; + else + return x; + }; + cr.to_radians = function(x) + { + return x / (180.0 / cr.PI); + }; + cr.to_degrees = function(x) + { + return x * (180.0 / cr.PI); + }; + cr.clamp_angle_degrees = function (a) + { + a %= 360; // now in (-360, 360) range + if (a < 0) + a += 360; // now in [0, 360) range + return a; + }; + cr.clamp_angle = function (a) + { + a %= 2 * cr.PI; // now in (-2pi, 2pi) range + if (a < 0) + a += 2 * cr.PI; // now in [0, 2pi) range + return a; + }; + cr.to_clamped_degrees = function (x) + { + return cr.clamp_angle_degrees(cr.to_degrees(x)); + }; + cr.to_clamped_radians = function (x) + { + return cr.clamp_angle(cr.to_radians(x)); + }; + cr.angleTo = function(x1, y1, x2, y2) + { + var dx = x2 - x1; + var dy = y2 - y1; + return Math.atan2(dy, dx); + }; + cr.angleDiff = function (a1, a2) + { + if (a1 === a2) + return 0; + var s1 = Math.sin(a1); + var c1 = Math.cos(a1); + var s2 = Math.sin(a2); + var c2 = Math.cos(a2); + var n = s1 * s2 + c1 * c2; + if (n >= 1) + return 0; + if (n <= -1) + return cr.PI; + return Math.acos(n); + }; + cr.angleRotate = function (start, end, step) + { + var ss = Math.sin(start); + var cs = Math.cos(start); + var se = Math.sin(end); + var ce = Math.cos(end); + if (Math.acos(ss * se + cs * ce) > step) + { + if (cs * se - ss * ce > 0) + return cr.clamp_angle(start + step); + else + return cr.clamp_angle(start - step); + } + else + return cr.clamp_angle(end); + }; + cr.angleClockwise = function (a1, a2) + { + var s1 = Math.sin(a1); + var c1 = Math.cos(a1); + var s2 = Math.sin(a2); + var c2 = Math.cos(a2); + return c1 * s2 - s1 * c2 <= 0; + }; + cr.rotatePtAround = function (px, py, a, ox, oy, getx) + { + if (a === 0) + return getx ? px : py; + var sin_a = Math.sin(a); + var cos_a = Math.cos(a); + px -= ox; + py -= oy; + var left_sin_a = px * sin_a; + var top_sin_a = py * sin_a; + var left_cos_a = px * cos_a; + var top_cos_a = py * cos_a; + px = left_cos_a - top_sin_a; + py = top_cos_a + left_sin_a; + px += ox; + py += oy; + return getx ? px : py; + } + cr.distanceTo = function(x1, y1, x2, y2) + { + var dx = x2 - x1; + var dy = y2 - y1; + return Math.sqrt(dx*dx + dy*dy); + }; + cr.xor = function (x, y) + { + return !x !== !y; + }; + cr.lerp = function (a, b, x) + { + return a + (b - a) * x; + }; + cr.unlerp = function (a, b, c) + { + if (a === b) + return 0; // avoid divide by 0 + return (c - a) / (b - a); + }; + cr.anglelerp = function (a, b, x) + { + var diff = cr.angleDiff(a, b); + if (cr.angleClockwise(b, a)) + { + return a + diff * x; + } + else + { + return a - diff * x; + } + }; + cr.qarp = function (a, b, c, x) + { + return cr.lerp(cr.lerp(a, b, x), cr.lerp(b, c, x), x); + }; + cr.cubic = function (a, b, c, d, x) + { + return cr.lerp(cr.qarp(a, b, c, x), cr.qarp(b, c, d, x), x); + }; + cr.cosp = function (a, b, x) + { + return (a + b + (a - b) * Math.cos(x * Math.PI)) / 2; + }; + cr.hasAnyOwnProperty = function (o) + { + var p; + for (p in o) + { + if (o.hasOwnProperty(p)) + return true; + } + return false; + }; + cr.wipe = function (obj) + { + var p; + for (p in obj) + { + if (obj.hasOwnProperty(p)) + delete obj[p]; + } + }; + var startup_time = +(new Date()); + cr.performance_now = function() + { + if (typeof window["performance"] !== "undefined") + { + var winperf = window["performance"]; + if (typeof winperf.now !== "undefined") + return winperf.now(); + else if (typeof winperf["webkitNow"] !== "undefined") + return winperf["webkitNow"](); + else if (typeof winperf["mozNow"] !== "undefined") + return winperf["mozNow"](); + else if (typeof winperf["msNow"] !== "undefined") + return winperf["msNow"](); + } + return Date.now() - startup_time; + }; + var isChrome = false; + var isSafari = false; + var isiOS = false; + var isEjecta = false; + if (typeof window !== "undefined") // not c2 editor + { + isChrome = /chrome/i.test(navigator.userAgent) || /chromium/i.test(navigator.userAgent); + isSafari = !isChrome && /safari/i.test(navigator.userAgent); + isiOS = /(iphone|ipod|ipad)/i.test(navigator.userAgent); + isEjecta = window["c2ejecta"]; + } + var supports_set = ((!isSafari && !isEjecta && !isiOS) && (typeof Set !== "undefined" && typeof Set.prototype["forEach"] !== "undefined")); + function ObjectSet_() + { + this.s = null; + this.items = null; // lazy allocated (hopefully results in better GC performance) + this.item_count = 0; + if (supports_set) + { + this.s = new Set(); + } + this.values_cache = []; + this.cache_valid = true; + cr.seal(this); + }; + ObjectSet_.prototype.contains = function (x) + { + if (this.isEmpty()) + return false; + if (supports_set) + return this.s["has"](x); + else + return (this.items && this.items.hasOwnProperty(x)); + }; + ObjectSet_.prototype.add = function (x) + { + if (supports_set) + { + if (!this.s["has"](x)) + { + this.s["add"](x); + this.cache_valid = false; + } + } + else + { + var str = x.toString(); + var items = this.items; + if (!items) + { + this.items = {}; + this.items[str] = x; + this.item_count = 1; + this.cache_valid = false; + } + else if (!items.hasOwnProperty(str)) + { + items[str] = x; + this.item_count++; + this.cache_valid = false; + } + } + }; + ObjectSet_.prototype.remove = function (x) + { + if (this.isEmpty()) + return; + if (supports_set) + { + if (this.s["has"](x)) + { + this.s["delete"](x); + this.cache_valid = false; + } + } + else if (this.items) + { + var str = x.toString(); + var items = this.items; + if (items.hasOwnProperty(str)) + { + delete items[str]; + this.item_count--; + this.cache_valid = false; + } + } + }; + ObjectSet_.prototype.clear = function (/*wipe_*/) + { + if (this.isEmpty()) + return; + if (supports_set) + { + this.s["clear"](); // best! + } + else + { + this.items = null; // creates garbage; will lazy allocate on next add() + this.item_count = 0; + } + this.values_cache.length = 0; + this.cache_valid = true; + }; + ObjectSet_.prototype.isEmpty = function () + { + return this.count() === 0; + }; + ObjectSet_.prototype.count = function () + { + if (supports_set) + return this.s["size"]; + else + return this.item_count; + }; + var current_arr = null; + var current_index = 0; + function set_append_to_arr(x) + { + current_arr[current_index++] = x; + }; + ObjectSet_.prototype.update_cache = function () + { + if (this.cache_valid) + return; + if (supports_set) + { + this.values_cache.length = this.s["size"]; + current_arr = this.values_cache; + current_index = 0; + this.s["forEach"](set_append_to_arr); +; + current_arr = null; + current_index = 0; + } + else + { + var values_cache = this.values_cache; + values_cache.length = this.item_count; + var p, n = 0, items = this.items; + if (items) + { + for (p in items) + { + if (items.hasOwnProperty(p)) + values_cache[n++] = items[p]; + } + } +; + } + this.cache_valid = true; + }; + ObjectSet_.prototype.valuesRef = function () + { + this.update_cache(); + return this.values_cache; + }; + cr.ObjectSet = ObjectSet_; + var tmpSet = new cr.ObjectSet(); + cr.removeArrayDuplicates = function (arr) + { + var i, len; + for (i = 0, len = arr.length; i < len; ++i) + { + tmpSet.add(arr[i]); + } + cr.shallowAssignArray(arr, tmpSet.valuesRef()); + tmpSet.clear(); + }; + cr.arrayRemoveAllFromObjectSet = function (arr, remset) + { + if (supports_set) + cr.arrayRemoveAll_set(arr, remset.s); + else + cr.arrayRemoveAll_arr(arr, remset.valuesRef()); + }; + cr.arrayRemoveAll_set = function (arr, s) + { + var i, j, len, item; + for (i = 0, j = 0, len = arr.length; i < len; ++i) + { + item = arr[i]; + if (!s["has"](item)) // not an item to remove + arr[j++] = item; // keep it + } + arr.length = j; + }; + cr.arrayRemoveAll_arr = function (arr, rem) + { + var i, j, len, item; + for (i = 0, j = 0, len = arr.length; i < len; ++i) + { + item = arr[i]; + if (cr.fastIndexOf(rem, item) === -1) // not an item to remove + arr[j++] = item; // keep it + } + arr.length = j; + }; + function KahanAdder_() + { + this.c = 0; + this.y = 0; + this.t = 0; + this.sum = 0; + cr.seal(this); + }; + KahanAdder_.prototype.add = function (v) + { + this.y = v - this.c; + this.t = this.sum + this.y; + this.c = (this.t - this.sum) - this.y; + this.sum = this.t; + }; + KahanAdder_.prototype.reset = function () + { + this.c = 0; + this.y = 0; + this.t = 0; + this.sum = 0; + }; + cr.KahanAdder = KahanAdder_; + cr.regexp_escape = function(text) + { + return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); + }; + function CollisionPoly_(pts_array_) + { + this.pts_cache = []; + this.bboxLeft = 0; + this.bboxTop = 0; + this.bboxRight = 0; + this.bboxBottom = 0; + this.convexpolys = null; // for physics behavior to cache separated polys + this.set_pts(pts_array_); + cr.seal(this); + }; + CollisionPoly_.prototype.set_pts = function(pts_array_) + { + this.pts_array = pts_array_; + this.pts_count = pts_array_.length / 2; // x, y, x, y... in array + this.pts_cache.length = pts_array_.length; + this.cache_width = -1; + this.cache_height = -1; + this.cache_angle = 0; + }; + CollisionPoly_.prototype.is_empty = function() + { + return !this.pts_array.length; + }; + CollisionPoly_.prototype.update_bbox = function () + { + var myptscache = this.pts_cache; + var bboxLeft_ = myptscache[0]; + var bboxRight_ = bboxLeft_; + var bboxTop_ = myptscache[1]; + var bboxBottom_ = bboxTop_; + var x, y, i = 1, i2, len = this.pts_count; + for ( ; i < len; ++i) + { + i2 = i*2; + x = myptscache[i2]; + y = myptscache[i2+1]; + if (x < bboxLeft_) + bboxLeft_ = x; + if (x > bboxRight_) + bboxRight_ = x; + if (y < bboxTop_) + bboxTop_ = y; + if (y > bboxBottom_) + bboxBottom_ = y; + } + this.bboxLeft = bboxLeft_; + this.bboxRight = bboxRight_; + this.bboxTop = bboxTop_; + this.bboxBottom = bboxBottom_; + }; + CollisionPoly_.prototype.set_from_rect = function(rc, offx, offy) + { + this.pts_cache.length = 8; + this.pts_count = 4; + var myptscache = this.pts_cache; + myptscache[0] = rc.left - offx; + myptscache[1] = rc.top - offy; + myptscache[2] = rc.right - offx; + myptscache[3] = rc.top - offy; + myptscache[4] = rc.right - offx; + myptscache[5] = rc.bottom - offy; + myptscache[6] = rc.left - offx; + myptscache[7] = rc.bottom - offy; + this.cache_width = rc.right - rc.left; + this.cache_height = rc.bottom - rc.top; + this.update_bbox(); + }; + CollisionPoly_.prototype.set_from_quad = function(q, offx, offy, w, h) + { + this.pts_cache.length = 8; + this.pts_count = 4; + var myptscache = this.pts_cache; + myptscache[0] = q.tlx - offx; + myptscache[1] = q.tly - offy; + myptscache[2] = q.trx - offx; + myptscache[3] = q.try_ - offy; + myptscache[4] = q.brx - offx; + myptscache[5] = q.bry - offy; + myptscache[6] = q.blx - offx; + myptscache[7] = q.bly - offy; + this.cache_width = w; + this.cache_height = h; + this.update_bbox(); + }; + CollisionPoly_.prototype.set_from_poly = function (r) + { + this.pts_count = r.pts_count; + cr.shallowAssignArray(this.pts_cache, r.pts_cache); + this.bboxLeft = r.bboxLeft; + this.bboxTop - r.bboxTop; + this.bboxRight = r.bboxRight; + this.bboxBottom = r.bboxBottom; + }; + CollisionPoly_.prototype.cache_poly = function(w, h, a) + { + if (this.cache_width === w && this.cache_height === h && this.cache_angle === a) + return; // cache up-to-date + this.cache_width = w; + this.cache_height = h; + this.cache_angle = a; + var i, i2, i21, len, x, y; + var sina = 0; + var cosa = 1; + var myptsarray = this.pts_array; + var myptscache = this.pts_cache; + if (a !== 0) + { + sina = Math.sin(a); + cosa = Math.cos(a); + } + for (i = 0, len = this.pts_count; i < len; i++) + { + i2 = i*2; + i21 = i2+1; + x = myptsarray[i2] * w; + y = myptsarray[i21] * h; + myptscache[i2] = (x * cosa) - (y * sina); + myptscache[i21] = (y * cosa) + (x * sina); + } + this.update_bbox(); + }; + CollisionPoly_.prototype.contains_pt = function (a2x, a2y) + { + var myptscache = this.pts_cache; + if (a2x === myptscache[0] && a2y === myptscache[1]) + return true; + var i, i2, imod, len = this.pts_count; + var a1x = this.bboxLeft - 110; + var a1y = this.bboxTop - 101; + var a3x = this.bboxRight + 131 + var a3y = this.bboxBottom + 120; + var b1x, b1y, b2x, b2y; + var count1 = 0, count2 = 0; + for (i = 0; i < len; i++) + { + i2 = i*2; + imod = ((i+1)%len)*2; + b1x = myptscache[i2]; + b1y = myptscache[i2+1]; + b2x = myptscache[imod]; + b2y = myptscache[imod+1]; + if (cr.segments_intersect(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y)) + count1++; + if (cr.segments_intersect(a3x, a3y, a2x, a2y, b1x, b1y, b2x, b2y)) + count2++; + } + return (count1 % 2 === 1) || (count2 % 2 === 1); + }; + CollisionPoly_.prototype.intersects_poly = function (rhs, offx, offy) + { + var rhspts = rhs.pts_cache; + var mypts = this.pts_cache; + if (this.contains_pt(rhspts[0] + offx, rhspts[1] + offy)) + return true; + if (rhs.contains_pt(mypts[0] - offx, mypts[1] - offy)) + return true; + var i, i2, imod, leni, j, j2, jmod, lenj; + var a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y; + for (i = 0, leni = this.pts_count; i < leni; i++) + { + i2 = i*2; + imod = ((i+1)%leni)*2; + a1x = mypts[i2]; + a1y = mypts[i2+1]; + a2x = mypts[imod]; + a2y = mypts[imod+1]; + for (j = 0, lenj = rhs.pts_count; j < lenj; j++) + { + j2 = j*2; + jmod = ((j+1)%lenj)*2; + b1x = rhspts[j2] + offx; + b1y = rhspts[j2+1] + offy; + b2x = rhspts[jmod] + offx; + b2y = rhspts[jmod+1] + offy; + if (cr.segments_intersect(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y)) + return true; + } + } + return false; + }; + CollisionPoly_.prototype.intersects_segment = function (offx, offy, x1, y1, x2, y2) + { + var mypts = this.pts_cache; + if (this.contains_pt(x1 - offx, y1 - offy)) + return true; + var i, leni, i2, imod; + var a1x, a1y, a2x, a2y; + for (i = 0, leni = this.pts_count; i < leni; i++) + { + i2 = i*2; + imod = ((i+1)%leni)*2; + a1x = mypts[i2] + offx; + a1y = mypts[i2+1] + offy; + a2x = mypts[imod] + offx; + a2y = mypts[imod+1] + offy; + if (cr.segments_intersect(x1, y1, x2, y2, a1x, a1y, a2x, a2y)) + return true; + } + return false; + }; + CollisionPoly_.prototype.mirror = function (px) + { + var i, leni, i2; + for (i = 0, leni = this.pts_count; i < leni; ++i) + { + i2 = i*2; + this.pts_cache[i2] = px * 2 - this.pts_cache[i2]; + } + }; + CollisionPoly_.prototype.flip = function (py) + { + var i, leni, i21; + for (i = 0, leni = this.pts_count; i < leni; ++i) + { + i21 = i*2+1; + this.pts_cache[i21] = py * 2 - this.pts_cache[i21]; + } + }; + CollisionPoly_.prototype.diag = function () + { + var i, leni, i2, i21, temp; + for (i = 0, leni = this.pts_count; i < leni; ++i) + { + i2 = i*2; + i21 = i2+1; + temp = this.pts_cache[i2]; + this.pts_cache[i2] = this.pts_cache[i21]; + this.pts_cache[i21] = temp; + } + }; + cr.CollisionPoly = CollisionPoly_; + function SparseGrid_(cellwidth_, cellheight_) + { + this.cellwidth = cellwidth_; + this.cellheight = cellheight_; + this.cells = {}; + }; + SparseGrid_.prototype.totalCellCount = 0; + SparseGrid_.prototype.getCell = function (x_, y_, create_if_missing) + { + var ret; + var col = this.cells[x_]; + if (!col) + { + if (create_if_missing) + { + ret = allocGridCell(this, x_, y_); + this.cells[x_] = {}; + this.cells[x_][y_] = ret; + return ret; + } + else + return null; + } + ret = col[y_]; + if (ret) + return ret; + else if (create_if_missing) + { + ret = allocGridCell(this, x_, y_); + this.cells[x_][y_] = ret; + return ret; + } + else + return null; + }; + SparseGrid_.prototype.XToCell = function (x_) + { + return cr.floor(x_ / this.cellwidth); + }; + SparseGrid_.prototype.YToCell = function (y_) + { + return cr.floor(y_ / this.cellheight); + }; + SparseGrid_.prototype.update = function (inst, oldrange, newrange) + { + var x, lenx, y, leny, cell; + if (oldrange) + { + for (x = oldrange.left, lenx = oldrange.right; x <= lenx; ++x) + { + for (y = oldrange.top, leny = oldrange.bottom; y <= leny; ++y) + { + if (newrange && newrange.contains_pt(x, y)) + continue; // is still in this cell + cell = this.getCell(x, y, false); // don't create if missing + if (!cell) + continue; // cell does not exist yet + cell.remove(inst); + if (cell.isEmpty()) + { + freeGridCell(cell); + this.cells[x][y] = null; + } + } + } + } + if (newrange) + { + for (x = newrange.left, lenx = newrange.right; x <= lenx; ++x) + { + for (y = newrange.top, leny = newrange.bottom; y <= leny; ++y) + { + if (oldrange && oldrange.contains_pt(x, y)) + continue; // is still in this cell + this.getCell(x, y, true).insert(inst); + } + } + } + }; + SparseGrid_.prototype.queryRange = function (rc, result) + { + var x, lenx, ystart, y, leny, cell; + x = this.XToCell(rc.left); + ystart = this.YToCell(rc.top); + lenx = this.XToCell(rc.right); + leny = this.YToCell(rc.bottom); + for ( ; x <= lenx; ++x) + { + for (y = ystart; y <= leny; ++y) + { + cell = this.getCell(x, y, false); + if (!cell) + continue; + cell.dump(result); + } + } + }; + cr.SparseGrid = SparseGrid_; + function RenderGrid_(cellwidth_, cellheight_) + { + this.cellwidth = cellwidth_; + this.cellheight = cellheight_; + this.cells = {}; + }; + RenderGrid_.prototype.totalCellCount = 0; + RenderGrid_.prototype.getCell = function (x_, y_, create_if_missing) + { + var ret; + var col = this.cells[x_]; + if (!col) + { + if (create_if_missing) + { + ret = allocRenderCell(this, x_, y_); + this.cells[x_] = {}; + this.cells[x_][y_] = ret; + return ret; + } + else + return null; + } + ret = col[y_]; + if (ret) + return ret; + else if (create_if_missing) + { + ret = allocRenderCell(this, x_, y_); + this.cells[x_][y_] = ret; + return ret; + } + else + return null; + }; + RenderGrid_.prototype.XToCell = function (x_) + { + return cr.floor(x_ / this.cellwidth); + }; + RenderGrid_.prototype.YToCell = function (y_) + { + return cr.floor(y_ / this.cellheight); + }; + RenderGrid_.prototype.update = function (inst, oldrange, newrange) + { + var x, lenx, y, leny, cell; + if (oldrange) + { + for (x = oldrange.left, lenx = oldrange.right; x <= lenx; ++x) + { + for (y = oldrange.top, leny = oldrange.bottom; y <= leny; ++y) + { + if (newrange && newrange.contains_pt(x, y)) + continue; // is still in this cell + cell = this.getCell(x, y, false); // don't create if missing + if (!cell) + continue; // cell does not exist yet + cell.remove(inst); + if (cell.isEmpty()) + { + freeRenderCell(cell); + this.cells[x][y] = null; + } + } + } + } + if (newrange) + { + for (x = newrange.left, lenx = newrange.right; x <= lenx; ++x) + { + for (y = newrange.top, leny = newrange.bottom; y <= leny; ++y) + { + if (oldrange && oldrange.contains_pt(x, y)) + continue; // is still in this cell + this.getCell(x, y, true).insert(inst); + } + } + } + }; + RenderGrid_.prototype.queryRange = function (left, top, right, bottom, result) + { + var x, lenx, ystart, y, leny, cell; + x = this.XToCell(left); + ystart = this.YToCell(top); + lenx = this.XToCell(right); + leny = this.YToCell(bottom); + for ( ; x <= lenx; ++x) + { + for (y = ystart; y <= leny; ++y) + { + cell = this.getCell(x, y, false); + if (!cell) + continue; + cell.dump(result); + } + } + }; + RenderGrid_.prototype.markRangeChanged = function (rc) + { + var x, lenx, ystart, y, leny, cell; + x = rc.left; + ystart = rc.top; + lenx = rc.right; + leny = rc.bottom; + for ( ; x <= lenx; ++x) + { + for (y = ystart; y <= leny; ++y) + { + cell = this.getCell(x, y, false); + if (!cell) + continue; + cell.is_sorted = false; + } + } + }; + cr.RenderGrid = RenderGrid_; + var gridcellcache = []; + function allocGridCell(grid_, x_, y_) + { + var ret; + SparseGrid_.prototype.totalCellCount++; + if (gridcellcache.length) + { + ret = gridcellcache.pop(); + ret.grid = grid_; + ret.x = x_; + ret.y = y_; + return ret; + } + else + return new cr.GridCell(grid_, x_, y_); + }; + function freeGridCell(c) + { + SparseGrid_.prototype.totalCellCount--; + c.objects.clear(); + if (gridcellcache.length < 1000) + gridcellcache.push(c); + }; + function GridCell_(grid_, x_, y_) + { + this.grid = grid_; + this.x = x_; + this.y = y_; + this.objects = new cr.ObjectSet(); + }; + GridCell_.prototype.isEmpty = function () + { + return this.objects.isEmpty(); + }; + GridCell_.prototype.insert = function (inst) + { + this.objects.add(inst); + }; + GridCell_.prototype.remove = function (inst) + { + this.objects.remove(inst); + }; + GridCell_.prototype.dump = function (result) + { + cr.appendArray(result, this.objects.valuesRef()); + }; + cr.GridCell = GridCell_; + var rendercellcache = []; + function allocRenderCell(grid_, x_, y_) + { + var ret; + RenderGrid_.prototype.totalCellCount++; + if (rendercellcache.length) + { + ret = rendercellcache.pop(); + ret.grid = grid_; + ret.x = x_; + ret.y = y_; + return ret; + } + else + return new cr.RenderCell(grid_, x_, y_); + }; + function freeRenderCell(c) + { + RenderGrid_.prototype.totalCellCount--; + c.reset(); + if (rendercellcache.length < 1000) + rendercellcache.push(c); + }; + function RenderCell_(grid_, x_, y_) + { + this.grid = grid_; + this.x = x_; + this.y = y_; + this.objects = []; // array which needs to be sorted by Z order + this.is_sorted = true; // whether array is in correct sort order or not + this.pending_removal = new cr.ObjectSet(); + this.any_pending_removal = false; + }; + RenderCell_.prototype.isEmpty = function () + { + if (!this.objects.length) + { +; +; + return true; + } + if (this.objects.length > this.pending_removal.count()) + return false; +; + this.flush_pending(); // takes fast path and just resets state + return true; + }; + RenderCell_.prototype.insert = function (inst) + { + if (this.pending_removal.contains(inst)) + { + this.pending_removal.remove(inst); + if (this.pending_removal.isEmpty()) + this.any_pending_removal = false; + return; + } + if (this.objects.length) + { + var top = this.objects[this.objects.length - 1]; + if (top.get_zindex() > inst.get_zindex()) + this.is_sorted = false; // 'inst' should be somewhere beneath 'top' + this.objects.push(inst); + } + else + { + this.objects.push(inst); + this.is_sorted = true; + } +; + }; + RenderCell_.prototype.remove = function (inst) + { + this.pending_removal.add(inst); + this.any_pending_removal = true; + if (this.pending_removal.count() >= 30) + this.flush_pending(); + }; + RenderCell_.prototype.flush_pending = function () + { +; + if (!this.any_pending_removal) + return; // not changed + if (this.pending_removal.count() === this.objects.length) + { + this.reset(); + return; + } + cr.arrayRemoveAllFromObjectSet(this.objects, this.pending_removal); + this.pending_removal.clear(); + this.any_pending_removal = false; + }; + function sortByInstanceZIndex(a, b) + { + return a.zindex - b.zindex; + }; + RenderCell_.prototype.ensure_sorted = function () + { + if (this.is_sorted) + return; // already sorted + this.objects.sort(sortByInstanceZIndex); + this.is_sorted = true; + }; + RenderCell_.prototype.reset = function () + { + this.objects.length = 0; + this.is_sorted = true; + this.pending_removal.clear(); + this.any_pending_removal = false; + }; + RenderCell_.prototype.dump = function (result) + { + this.flush_pending(); + this.ensure_sorted(); + if (this.objects.length) + result.push(this.objects); + }; + cr.RenderCell = RenderCell_; + var fxNames = [ "lighter", + "xor", + "copy", + "destination-over", + "source-in", + "destination-in", + "source-out", + "destination-out", + "source-atop", + "destination-atop"]; + cr.effectToCompositeOp = function(effect) + { + if (effect <= 0 || effect >= 11) + return "source-over"; + return fxNames[effect - 1]; // not including "none" so offset by 1 + }; + cr.setGLBlend = function(this_, effect, gl) + { + if (!gl) + return; + this_.srcBlend = gl.ONE; + this_.destBlend = gl.ONE_MINUS_SRC_ALPHA; + switch (effect) { + case 1: // lighter (additive) + this_.srcBlend = gl.ONE; + this_.destBlend = gl.ONE; + break; + case 2: // xor + break; // todo + case 3: // copy + this_.srcBlend = gl.ONE; + this_.destBlend = gl.ZERO; + break; + case 4: // destination-over + this_.srcBlend = gl.ONE_MINUS_DST_ALPHA; + this_.destBlend = gl.ONE; + break; + case 5: // source-in + this_.srcBlend = gl.DST_ALPHA; + this_.destBlend = gl.ZERO; + break; + case 6: // destination-in + this_.srcBlend = gl.ZERO; + this_.destBlend = gl.SRC_ALPHA; + break; + case 7: // source-out + this_.srcBlend = gl.ONE_MINUS_DST_ALPHA; + this_.destBlend = gl.ZERO; + break; + case 8: // destination-out + this_.srcBlend = gl.ZERO; + this_.destBlend = gl.ONE_MINUS_SRC_ALPHA; + break; + case 9: // source-atop + this_.srcBlend = gl.DST_ALPHA; + this_.destBlend = gl.ONE_MINUS_SRC_ALPHA; + break; + case 10: // destination-atop + this_.srcBlend = gl.ONE_MINUS_DST_ALPHA; + this_.destBlend = gl.SRC_ALPHA; + break; + } + }; + cr.round6dp = function (x) + { + return Math.round(x * 1000000) / 1000000; + }; + /* + var localeCompare_options = { + "usage": "search", + "sensitivity": "accent" + }; + var has_localeCompare = !!"a".localeCompare; + var localeCompare_works1 = (has_localeCompare && "a".localeCompare("A", undefined, localeCompare_options) === 0); + var localeCompare_works2 = (has_localeCompare && "a".localeCompare("á", undefined, localeCompare_options) !== 0); + var supports_localeCompare = (has_localeCompare && localeCompare_works1 && localeCompare_works2); + */ + cr.equals_nocase = function (a, b) + { + if (typeof a !== "string" || typeof b !== "string") + return false; + if (a.length !== b.length) + return false; + if (a === b) + return true; + /* + if (supports_localeCompare) + { + return (a.localeCompare(b, undefined, localeCompare_options) === 0); + } + else + { + */ + return a.toLowerCase() === b.toLowerCase(); + }; + cr.isCanvasInputEvent = function (e) + { + var target = e.target; + if (!target) + return true; + if (target === document || target === window) + return true; + if (document && document.body && target === document.body) + return true; + if (cr.equals_nocase(target.tagName, "canvas")) + return true; + return false; + }; +}()); +var MatrixArray=typeof Float32Array!=="undefined"?Float32Array:Array,glMatrixArrayType=MatrixArray,vec3={},mat3={},mat4={},quat4={};vec3.create=function(a){var b=new MatrixArray(3);a&&(b[0]=a[0],b[1]=a[1],b[2]=a[2]);return b};vec3.set=function(a,b){b[0]=a[0];b[1]=a[1];b[2]=a[2];return b};vec3.add=function(a,b,c){if(!c||a===c)return a[0]+=b[0],a[1]+=b[1],a[2]+=b[2],a;c[0]=a[0]+b[0];c[1]=a[1]+b[1];c[2]=a[2]+b[2];return c}; +vec3.subtract=function(a,b,c){if(!c||a===c)return a[0]-=b[0],a[1]-=b[1],a[2]-=b[2],a;c[0]=a[0]-b[0];c[1]=a[1]-b[1];c[2]=a[2]-b[2];return c};vec3.negate=function(a,b){b||(b=a);b[0]=-a[0];b[1]=-a[1];b[2]=-a[2];return b};vec3.scale=function(a,b,c){if(!c||a===c)return a[0]*=b,a[1]*=b,a[2]*=b,a;c[0]=a[0]*b;c[1]=a[1]*b;c[2]=a[2]*b;return c}; +vec3.normalize=function(a,b){b||(b=a);var c=a[0],d=a[1],e=a[2],g=Math.sqrt(c*c+d*d+e*e);if(g){if(g===1)return b[0]=c,b[1]=d,b[2]=e,b}else return b[0]=0,b[1]=0,b[2]=0,b;g=1/g;b[0]=c*g;b[1]=d*g;b[2]=e*g;return b};vec3.cross=function(a,b,c){c||(c=a);var d=a[0],e=a[1],a=a[2],g=b[0],f=b[1],b=b[2];c[0]=e*b-a*f;c[1]=a*g-d*b;c[2]=d*f-e*g;return c};vec3.length=function(a){var b=a[0],c=a[1],a=a[2];return Math.sqrt(b*b+c*c+a*a)};vec3.dot=function(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]}; +vec3.direction=function(a,b,c){c||(c=a);var d=a[0]-b[0],e=a[1]-b[1],a=a[2]-b[2],b=Math.sqrt(d*d+e*e+a*a);if(!b)return c[0]=0,c[1]=0,c[2]=0,c;b=1/b;c[0]=d*b;c[1]=e*b;c[2]=a*b;return c};vec3.lerp=function(a,b,c,d){d||(d=a);d[0]=a[0]+c*(b[0]-a[0]);d[1]=a[1]+c*(b[1]-a[1]);d[2]=a[2]+c*(b[2]-a[2]);return d};vec3.str=function(a){return"["+a[0]+", "+a[1]+", "+a[2]+"]"}; +mat3.create=function(a){var b=new MatrixArray(9);a&&(b[0]=a[0],b[1]=a[1],b[2]=a[2],b[3]=a[3],b[4]=a[4],b[5]=a[5],b[6]=a[6],b[7]=a[7],b[8]=a[8]);return b};mat3.set=function(a,b){b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];return b};mat3.identity=function(a){a[0]=1;a[1]=0;a[2]=0;a[3]=0;a[4]=1;a[5]=0;a[6]=0;a[7]=0;a[8]=1;return a}; +mat3.transpose=function(a,b){if(!b||a===b){var c=a[1],d=a[2],e=a[5];a[1]=a[3];a[2]=a[6];a[3]=c;a[5]=a[7];a[6]=d;a[7]=e;return a}b[0]=a[0];b[1]=a[3];b[2]=a[6];b[3]=a[1];b[4]=a[4];b[5]=a[7];b[6]=a[2];b[7]=a[5];b[8]=a[8];return b};mat3.toMat4=function(a,b){b||(b=mat4.create());b[15]=1;b[14]=0;b[13]=0;b[12]=0;b[11]=0;b[10]=a[8];b[9]=a[7];b[8]=a[6];b[7]=0;b[6]=a[5];b[5]=a[4];b[4]=a[3];b[3]=0;b[2]=a[2];b[1]=a[1];b[0]=a[0];return b}; +mat3.str=function(a){return"["+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+", "+a[4]+", "+a[5]+", "+a[6]+", "+a[7]+", "+a[8]+"]"};mat4.create=function(a){var b=new MatrixArray(16);a&&(b[0]=a[0],b[1]=a[1],b[2]=a[2],b[3]=a[3],b[4]=a[4],b[5]=a[5],b[6]=a[6],b[7]=a[7],b[8]=a[8],b[9]=a[9],b[10]=a[10],b[11]=a[11],b[12]=a[12],b[13]=a[13],b[14]=a[14],b[15]=a[15]);return b}; +mat4.set=function(a,b){b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];b[9]=a[9];b[10]=a[10];b[11]=a[11];b[12]=a[12];b[13]=a[13];b[14]=a[14];b[15]=a[15];return b};mat4.identity=function(a){a[0]=1;a[1]=0;a[2]=0;a[3]=0;a[4]=0;a[5]=1;a[6]=0;a[7]=0;a[8]=0;a[9]=0;a[10]=1;a[11]=0;a[12]=0;a[13]=0;a[14]=0;a[15]=1;return a}; +mat4.transpose=function(a,b){if(!b||a===b){var c=a[1],d=a[2],e=a[3],g=a[6],f=a[7],h=a[11];a[1]=a[4];a[2]=a[8];a[3]=a[12];a[4]=c;a[6]=a[9];a[7]=a[13];a[8]=d;a[9]=g;a[11]=a[14];a[12]=e;a[13]=f;a[14]=h;return a}b[0]=a[0];b[1]=a[4];b[2]=a[8];b[3]=a[12];b[4]=a[1];b[5]=a[5];b[6]=a[9];b[7]=a[13];b[8]=a[2];b[9]=a[6];b[10]=a[10];b[11]=a[14];b[12]=a[3];b[13]=a[7];b[14]=a[11];b[15]=a[15];return b}; +mat4.determinant=function(a){var b=a[0],c=a[1],d=a[2],e=a[3],g=a[4],f=a[5],h=a[6],i=a[7],j=a[8],k=a[9],l=a[10],n=a[11],o=a[12],m=a[13],p=a[14],a=a[15];return o*k*h*e-j*m*h*e-o*f*l*e+g*m*l*e+j*f*p*e-g*k*p*e-o*k*d*i+j*m*d*i+o*c*l*i-b*m*l*i-j*c*p*i+b*k*p*i+o*f*d*n-g*m*d*n-o*c*h*n+b*m*h*n+g*c*p*n-b*f*p*n-j*f*d*a+g*k*d*a+j*c*h*a-b*k*h*a-g*c*l*a+b*f*l*a}; +mat4.inverse=function(a,b){b||(b=a);var c=a[0],d=a[1],e=a[2],g=a[3],f=a[4],h=a[5],i=a[6],j=a[7],k=a[8],l=a[9],n=a[10],o=a[11],m=a[12],p=a[13],r=a[14],s=a[15],A=c*h-d*f,B=c*i-e*f,t=c*j-g*f,u=d*i-e*h,v=d*j-g*h,w=e*j-g*i,x=k*p-l*m,y=k*r-n*m,z=k*s-o*m,C=l*r-n*p,D=l*s-o*p,E=n*s-o*r,q=1/(A*E-B*D+t*C+u*z-v*y+w*x);b[0]=(h*E-i*D+j*C)*q;b[1]=(-d*E+e*D-g*C)*q;b[2]=(p*w-r*v+s*u)*q;b[3]=(-l*w+n*v-o*u)*q;b[4]=(-f*E+i*z-j*y)*q;b[5]=(c*E-e*z+g*y)*q;b[6]=(-m*w+r*t-s*B)*q;b[7]=(k*w-n*t+o*B)*q;b[8]=(f*D-h*z+j*x)*q; +b[9]=(-c*D+d*z-g*x)*q;b[10]=(m*v-p*t+s*A)*q;b[11]=(-k*v+l*t-o*A)*q;b[12]=(-f*C+h*y-i*x)*q;b[13]=(c*C-d*y+e*x)*q;b[14]=(-m*u+p*B-r*A)*q;b[15]=(k*u-l*B+n*A)*q;return b};mat4.toRotationMat=function(a,b){b||(b=mat4.create());b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];b[9]=a[9];b[10]=a[10];b[11]=a[11];b[12]=0;b[13]=0;b[14]=0;b[15]=1;return b}; +mat4.toMat3=function(a,b){b||(b=mat3.create());b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[4];b[4]=a[5];b[5]=a[6];b[6]=a[8];b[7]=a[9];b[8]=a[10];return b};mat4.toInverseMat3=function(a,b){var c=a[0],d=a[1],e=a[2],g=a[4],f=a[5],h=a[6],i=a[8],j=a[9],k=a[10],l=k*f-h*j,n=-k*g+h*i,o=j*g-f*i,m=c*l+d*n+e*o;if(!m)return null;m=1/m;b||(b=mat3.create());b[0]=l*m;b[1]=(-k*d+e*j)*m;b[2]=(h*d-e*f)*m;b[3]=n*m;b[4]=(k*c-e*i)*m;b[5]=(-h*c+e*g)*m;b[6]=o*m;b[7]=(-j*c+d*i)*m;b[8]=(f*c-d*g)*m;return b}; +mat4.multiply=function(a,b,c){c||(c=a);var d=a[0],e=a[1],g=a[2],f=a[3],h=a[4],i=a[5],j=a[6],k=a[7],l=a[8],n=a[9],o=a[10],m=a[11],p=a[12],r=a[13],s=a[14],a=a[15],A=b[0],B=b[1],t=b[2],u=b[3],v=b[4],w=b[5],x=b[6],y=b[7],z=b[8],C=b[9],D=b[10],E=b[11],q=b[12],F=b[13],G=b[14],b=b[15];c[0]=A*d+B*h+t*l+u*p;c[1]=A*e+B*i+t*n+u*r;c[2]=A*g+B*j+t*o+u*s;c[3]=A*f+B*k+t*m+u*a;c[4]=v*d+w*h+x*l+y*p;c[5]=v*e+w*i+x*n+y*r;c[6]=v*g+w*j+x*o+y*s;c[7]=v*f+w*k+x*m+y*a;c[8]=z*d+C*h+D*l+E*p;c[9]=z*e+C*i+D*n+E*r;c[10]=z*g+C* +j+D*o+E*s;c[11]=z*f+C*k+D*m+E*a;c[12]=q*d+F*h+G*l+b*p;c[13]=q*e+F*i+G*n+b*r;c[14]=q*g+F*j+G*o+b*s;c[15]=q*f+F*k+G*m+b*a;return c};mat4.multiplyVec3=function(a,b,c){c||(c=b);var d=b[0],e=b[1],b=b[2];c[0]=a[0]*d+a[4]*e+a[8]*b+a[12];c[1]=a[1]*d+a[5]*e+a[9]*b+a[13];c[2]=a[2]*d+a[6]*e+a[10]*b+a[14];return c}; +mat4.multiplyVec4=function(a,b,c){c||(c=b);var d=b[0],e=b[1],g=b[2],b=b[3];c[0]=a[0]*d+a[4]*e+a[8]*g+a[12]*b;c[1]=a[1]*d+a[5]*e+a[9]*g+a[13]*b;c[2]=a[2]*d+a[6]*e+a[10]*g+a[14]*b;c[3]=a[3]*d+a[7]*e+a[11]*g+a[15]*b;return c}; +mat4.translate=function(a,b,c){var d=b[0],e=b[1],b=b[2],g,f,h,i,j,k,l,n,o,m,p,r;if(!c||a===c)return a[12]=a[0]*d+a[4]*e+a[8]*b+a[12],a[13]=a[1]*d+a[5]*e+a[9]*b+a[13],a[14]=a[2]*d+a[6]*e+a[10]*b+a[14],a[15]=a[3]*d+a[7]*e+a[11]*b+a[15],a;g=a[0];f=a[1];h=a[2];i=a[3];j=a[4];k=a[5];l=a[6];n=a[7];o=a[8];m=a[9];p=a[10];r=a[11];c[0]=g;c[1]=f;c[2]=h;c[3]=i;c[4]=j;c[5]=k;c[6]=l;c[7]=n;c[8]=o;c[9]=m;c[10]=p;c[11]=r;c[12]=g*d+j*e+o*b+a[12];c[13]=f*d+k*e+m*b+a[13];c[14]=h*d+l*e+p*b+a[14];c[15]=i*d+n*e+r*b+a[15]; +return c};mat4.scale=function(a,b,c){var d=b[0],e=b[1],b=b[2];if(!c||a===c)return a[0]*=d,a[1]*=d,a[2]*=d,a[3]*=d,a[4]*=e,a[5]*=e,a[6]*=e,a[7]*=e,a[8]*=b,a[9]*=b,a[10]*=b,a[11]*=b,a;c[0]=a[0]*d;c[1]=a[1]*d;c[2]=a[2]*d;c[3]=a[3]*d;c[4]=a[4]*e;c[5]=a[5]*e;c[6]=a[6]*e;c[7]=a[7]*e;c[8]=a[8]*b;c[9]=a[9]*b;c[10]=a[10]*b;c[11]=a[11]*b;c[12]=a[12];c[13]=a[13];c[14]=a[14];c[15]=a[15];return c}; +mat4.rotate=function(a,b,c,d){var e=c[0],g=c[1],c=c[2],f=Math.sqrt(e*e+g*g+c*c),h,i,j,k,l,n,o,m,p,r,s,A,B,t,u,v,w,x,y,z;if(!f)return null;f!==1&&(f=1/f,e*=f,g*=f,c*=f);h=Math.sin(b);i=Math.cos(b);j=1-i;b=a[0];f=a[1];k=a[2];l=a[3];n=a[4];o=a[5];m=a[6];p=a[7];r=a[8];s=a[9];A=a[10];B=a[11];t=e*e*j+i;u=g*e*j+c*h;v=c*e*j-g*h;w=e*g*j-c*h;x=g*g*j+i;y=c*g*j+e*h;z=e*c*j+g*h;e=g*c*j-e*h;g=c*c*j+i;d?a!==d&&(d[12]=a[12],d[13]=a[13],d[14]=a[14],d[15]=a[15]):d=a;d[0]=b*t+n*u+r*v;d[1]=f*t+o*u+s*v;d[2]=k*t+m*u+A* +v;d[3]=l*t+p*u+B*v;d[4]=b*w+n*x+r*y;d[5]=f*w+o*x+s*y;d[6]=k*w+m*x+A*y;d[7]=l*w+p*x+B*y;d[8]=b*z+n*e+r*g;d[9]=f*z+o*e+s*g;d[10]=k*z+m*e+A*g;d[11]=l*z+p*e+B*g;return d};mat4.rotateX=function(a,b,c){var d=Math.sin(b),b=Math.cos(b),e=a[4],g=a[5],f=a[6],h=a[7],i=a[8],j=a[9],k=a[10],l=a[11];c?a!==c&&(c[0]=a[0],c[1]=a[1],c[2]=a[2],c[3]=a[3],c[12]=a[12],c[13]=a[13],c[14]=a[14],c[15]=a[15]):c=a;c[4]=e*b+i*d;c[5]=g*b+j*d;c[6]=f*b+k*d;c[7]=h*b+l*d;c[8]=e*-d+i*b;c[9]=g*-d+j*b;c[10]=f*-d+k*b;c[11]=h*-d+l*b;return c}; +mat4.rotateY=function(a,b,c){var d=Math.sin(b),b=Math.cos(b),e=a[0],g=a[1],f=a[2],h=a[3],i=a[8],j=a[9],k=a[10],l=a[11];c?a!==c&&(c[4]=a[4],c[5]=a[5],c[6]=a[6],c[7]=a[7],c[12]=a[12],c[13]=a[13],c[14]=a[14],c[15]=a[15]):c=a;c[0]=e*b+i*-d;c[1]=g*b+j*-d;c[2]=f*b+k*-d;c[3]=h*b+l*-d;c[8]=e*d+i*b;c[9]=g*d+j*b;c[10]=f*d+k*b;c[11]=h*d+l*b;return c}; +mat4.rotateZ=function(a,b,c){var d=Math.sin(b),b=Math.cos(b),e=a[0],g=a[1],f=a[2],h=a[3],i=a[4],j=a[5],k=a[6],l=a[7];c?a!==c&&(c[8]=a[8],c[9]=a[9],c[10]=a[10],c[11]=a[11],c[12]=a[12],c[13]=a[13],c[14]=a[14],c[15]=a[15]):c=a;c[0]=e*b+i*d;c[1]=g*b+j*d;c[2]=f*b+k*d;c[3]=h*b+l*d;c[4]=e*-d+i*b;c[5]=g*-d+j*b;c[6]=f*-d+k*b;c[7]=h*-d+l*b;return c}; +mat4.frustum=function(a,b,c,d,e,g,f){f||(f=mat4.create());var h=b-a,i=d-c,j=g-e;f[0]=e*2/h;f[1]=0;f[2]=0;f[3]=0;f[4]=0;f[5]=e*2/i;f[6]=0;f[7]=0;f[8]=(b+a)/h;f[9]=(d+c)/i;f[10]=-(g+e)/j;f[11]=-1;f[12]=0;f[13]=0;f[14]=-(g*e*2)/j;f[15]=0;return f};mat4.perspective=function(a,b,c,d,e){a=c*Math.tan(a*Math.PI/360);b*=a;return mat4.frustum(-b,b,-a,a,c,d,e)}; +mat4.ortho=function(a,b,c,d,e,g,f){f||(f=mat4.create());var h=b-a,i=d-c,j=g-e;f[0]=2/h;f[1]=0;f[2]=0;f[3]=0;f[4]=0;f[5]=2/i;f[6]=0;f[7]=0;f[8]=0;f[9]=0;f[10]=-2/j;f[11]=0;f[12]=-(a+b)/h;f[13]=-(d+c)/i;f[14]=-(g+e)/j;f[15]=1;return f}; +mat4.lookAt=function(a,b,c,d){d||(d=mat4.create());var e,g,f,h,i,j,k,l,n=a[0],o=a[1],a=a[2];g=c[0];f=c[1];e=c[2];c=b[1];j=b[2];if(n===b[0]&&o===c&&a===j)return mat4.identity(d);c=n-b[0];j=o-b[1];k=a-b[2];l=1/Math.sqrt(c*c+j*j+k*k);c*=l;j*=l;k*=l;b=f*k-e*j;e=e*c-g*k;g=g*j-f*c;(l=Math.sqrt(b*b+e*e+g*g))?(l=1/l,b*=l,e*=l,g*=l):g=e=b=0;f=j*g-k*e;h=k*b-c*g;i=c*e-j*b;(l=Math.sqrt(f*f+h*h+i*i))?(l=1/l,f*=l,h*=l,i*=l):i=h=f=0;d[0]=b;d[1]=f;d[2]=c;d[3]=0;d[4]=e;d[5]=h;d[6]=j;d[7]=0;d[8]=g;d[9]=i;d[10]=k;d[11]= +0;d[12]=-(b*n+e*o+g*a);d[13]=-(f*n+h*o+i*a);d[14]=-(c*n+j*o+k*a);d[15]=1;return d};mat4.fromRotationTranslation=function(a,b,c){c||(c=mat4.create());var d=a[0],e=a[1],g=a[2],f=a[3],h=d+d,i=e+e,j=g+g,a=d*h,k=d*i;d*=j;var l=e*i;e*=j;g*=j;h*=f;i*=f;f*=j;c[0]=1-(l+g);c[1]=k+f;c[2]=d-i;c[3]=0;c[4]=k-f;c[5]=1-(a+g);c[6]=e+h;c[7]=0;c[8]=d+i;c[9]=e-h;c[10]=1-(a+l);c[11]=0;c[12]=b[0];c[13]=b[1];c[14]=b[2];c[15]=1;return c}; +mat4.str=function(a){return"["+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+", "+a[4]+", "+a[5]+", "+a[6]+", "+a[7]+", "+a[8]+", "+a[9]+", "+a[10]+", "+a[11]+", "+a[12]+", "+a[13]+", "+a[14]+", "+a[15]+"]"};quat4.create=function(a){var b=new MatrixArray(4);a&&(b[0]=a[0],b[1]=a[1],b[2]=a[2],b[3]=a[3]);return b};quat4.set=function(a,b){b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];return b}; +quat4.calculateW=function(a,b){var c=a[0],d=a[1],e=a[2];if(!b||a===b)return a[3]=-Math.sqrt(Math.abs(1-c*c-d*d-e*e)),a;b[0]=c;b[1]=d;b[2]=e;b[3]=-Math.sqrt(Math.abs(1-c*c-d*d-e*e));return b};quat4.inverse=function(a,b){if(!b||a===b)return a[0]*=-1,a[1]*=-1,a[2]*=-1,a;b[0]=-a[0];b[1]=-a[1];b[2]=-a[2];b[3]=a[3];return b};quat4.length=function(a){var b=a[0],c=a[1],d=a[2],a=a[3];return Math.sqrt(b*b+c*c+d*d+a*a)}; +quat4.normalize=function(a,b){b||(b=a);var c=a[0],d=a[1],e=a[2],g=a[3],f=Math.sqrt(c*c+d*d+e*e+g*g);if(f===0)return b[0]=0,b[1]=0,b[2]=0,b[3]=0,b;f=1/f;b[0]=c*f;b[1]=d*f;b[2]=e*f;b[3]=g*f;return b};quat4.multiply=function(a,b,c){c||(c=a);var d=a[0],e=a[1],g=a[2],a=a[3],f=b[0],h=b[1],i=b[2],b=b[3];c[0]=d*b+a*f+e*i-g*h;c[1]=e*b+a*h+g*f-d*i;c[2]=g*b+a*i+d*h-e*f;c[3]=a*b-d*f-e*h-g*i;return c}; +quat4.multiplyVec3=function(a,b,c){c||(c=b);var d=b[0],e=b[1],g=b[2],b=a[0],f=a[1],h=a[2],a=a[3],i=a*d+f*g-h*e,j=a*e+h*d-b*g,k=a*g+b*e-f*d,d=-b*d-f*e-h*g;c[0]=i*a+d*-b+j*-h-k*-f;c[1]=j*a+d*-f+k*-b-i*-h;c[2]=k*a+d*-h+i*-f-j*-b;return c};quat4.toMat3=function(a,b){b||(b=mat3.create());var c=a[0],d=a[1],e=a[2],g=a[3],f=c+c,h=d+d,i=e+e,j=c*f,k=c*h;c*=i;var l=d*h;d*=i;e*=i;f*=g;h*=g;g*=i;b[0]=1-(l+e);b[1]=k+g;b[2]=c-h;b[3]=k-g;b[4]=1-(j+e);b[5]=d+f;b[6]=c+h;b[7]=d-f;b[8]=1-(j+l);return b}; +quat4.toMat4=function(a,b){b||(b=mat4.create());var c=a[0],d=a[1],e=a[2],g=a[3],f=c+c,h=d+d,i=e+e,j=c*f,k=c*h;c*=i;var l=d*h;d*=i;e*=i;f*=g;h*=g;g*=i;b[0]=1-(l+e);b[1]=k+g;b[2]=c-h;b[3]=0;b[4]=k-g;b[5]=1-(j+e);b[6]=d+f;b[7]=0;b[8]=c+h;b[9]=d-f;b[10]=1-(j+l);b[11]=0;b[12]=0;b[13]=0;b[14]=0;b[15]=1;return b}; +quat4.slerp=function(a,b,c,d){d||(d=a);var e=a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3],g,f;if(Math.abs(e)>=1)return d!==a&&(d[0]=a[0],d[1]=a[1],d[2]=a[2],d[3]=a[3]),d;g=Math.acos(e);f=Math.sqrt(1-e*e);if(Math.abs(f)<0.001)return d[0]=a[0]*0.5+b[0]*0.5,d[1]=a[1]*0.5+b[1]*0.5,d[2]=a[2]*0.5+b[2]*0.5,d[3]=a[3]*0.5+b[3]*0.5,d;e=Math.sin((1-c)*g)/f;c=Math.sin(c*g)/f;d[0]=a[0]*e+b[0]*c;d[1]=a[1]*e+b[1]*c;d[2]=a[2]*e+b[2]*c;d[3]=a[3]*e+b[3]*c;return d}; +quat4.str=function(a){return"["+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+"]"}; +(function() +{ + var MAX_VERTICES = 8000; // equates to 2500 objects being drawn + var MAX_INDICES = (MAX_VERTICES / 2) * 3; // 6 indices for every 4 vertices + var MAX_POINTS = 8000; + var MULTI_BUFFERS = 4; // cycle 4 buffers to try and avoid blocking + var BATCH_NULL = 0; + var BATCH_QUAD = 1; + var BATCH_SETTEXTURE = 2; + var BATCH_SETOPACITY = 3; + var BATCH_SETBLEND = 4; + var BATCH_UPDATEMODELVIEW = 5; + var BATCH_RENDERTOTEXTURE = 6; + var BATCH_CLEAR = 7; + var BATCH_POINTS = 8; + var BATCH_SETPROGRAM = 9; + var BATCH_SETPROGRAMPARAMETERS = 10; + var BATCH_SETTEXTURE1 = 11; + /* + var lose_ext = null; + window.lose_context = function () + { + if (!lose_ext) + { + console.log("WEBGL_lose_context not supported"); + return; + } + lose_ext.loseContext(); + }; + window.restore_context = function () + { + if (!lose_ext) + { + console.log("WEBGL_lose_context not supported"); + return; + } + lose_ext.restoreContext(); + }; + */ + function GLWrap_(gl, isMobile) + { + this.isIE = /msie/i.test(navigator.userAgent) || /trident/i.test(navigator.userAgent); + this.width = 0; // not yet known, wait for call to setSize() + this.height = 0; + this.cam = vec3.create([0, 0, 100]); // camera position + this.look = vec3.create([0, 0, 0]); // lookat position + this.up = vec3.create([0, 1, 0]); // up vector + this.worldScale = vec3.create([1, 1, 1]); // world scaling factor + this.enable_mipmaps = true; + this.matP = mat4.create(); // perspective matrix + this.matMV = mat4.create(); // model view matrix + this.lastMV = mat4.create(); + this.currentMV = mat4.create(); + this.gl = gl; + this.initState(); + }; + GLWrap_.prototype.initState = function () + { + var gl = this.gl; + var i, len; + this.lastOpacity = 1; + this.lastTexture0 = null; // last bound to TEXTURE0 + this.lastTexture1 = null; // last bound to TEXTURE1 + this.currentOpacity = 1; + gl.clearColor(0, 0, 0, 0); + gl.clear(gl.COLOR_BUFFER_BIT); + gl.enable(gl.BLEND); + gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + gl.disable(gl.CULL_FACE); + gl.disable(gl.DEPTH_TEST); + this.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); + this.lastSrcBlend = gl.ONE; + this.lastDestBlend = gl.ONE_MINUS_SRC_ALPHA; + this.pointBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, this.pointBuffer); + this.vertexBuffers = new Array(MULTI_BUFFERS); + this.texcoordBuffers = new Array(MULTI_BUFFERS); + for (i = 0; i < MULTI_BUFFERS; i++) + { + this.vertexBuffers[i] = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffers[i]); + this.texcoordBuffers[i] = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, this.texcoordBuffers[i]); + } + this.curBuffer = 0; + this.indexBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + this.vertexData = new Float32Array(MAX_VERTICES * 2); + this.texcoordData = new Float32Array(MAX_VERTICES * 2); + this.pointData = new Float32Array(MAX_POINTS * 4); + var indexData = new Uint16Array(MAX_INDICES); + i = 0, len = MAX_INDICES; + var fv = 0; + while (i < len) + { + indexData[i++] = fv; // top left + indexData[i++] = fv + 1; // top right + indexData[i++] = fv + 2; // bottom right (first tri) + indexData[i++] = fv; // top left + indexData[i++] = fv + 2; // bottom right + indexData[i++] = fv + 3; // bottom left + fv += 4; + } + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indexData, gl.STATIC_DRAW); + this.vertexPtr = 0; + this.pointPtr = 0; + var fsSource, vsSource; + this.shaderPrograms = []; + fsSource = [ + "varying mediump vec2 vTex;", + "uniform lowp float opacity;", + "uniform lowp sampler2D samplerFront;", + "void main(void) {", + " gl_FragColor = texture2D(samplerFront, vTex);", + " gl_FragColor *= opacity;", + "}" + ].join("\n"); + vsSource = [ + "attribute highp vec2 aPos;", + "attribute mediump vec2 aTex;", + "varying mediump vec2 vTex;", + "uniform highp mat4 matP;", + "uniform highp mat4 matMV;", + "void main(void) {", + " gl_Position = matP * matMV * vec4(aPos.x, aPos.y, 0.0, 1.0);", + " vTex = aTex;", + "}" + ].join("\n"); + var shaderProg = this.createShaderProgram({src: fsSource}, vsSource, ""); +; + this.shaderPrograms.push(shaderProg); // Default shader is always shader 0 + fsSource = [ + "uniform mediump sampler2D samplerFront;", + "varying lowp float opacity;", + "void main(void) {", + " gl_FragColor = texture2D(samplerFront, gl_PointCoord);", + " gl_FragColor *= opacity;", + "}" + ].join("\n"); + var pointVsSource = [ + "attribute vec4 aPos;", + "varying float opacity;", + "uniform mat4 matP;", + "uniform mat4 matMV;", + "void main(void) {", + " gl_Position = matP * matMV * vec4(aPos.x, aPos.y, 0.0, 1.0);", + " gl_PointSize = aPos.z;", + " opacity = aPos.w;", + "}" + ].join("\n"); + shaderProg = this.createShaderProgram({src: fsSource}, pointVsSource, ""); +; + this.shaderPrograms.push(shaderProg); // Point shader is always shader 1 + for (var shader_name in cr.shaders) + { + if (cr.shaders.hasOwnProperty(shader_name)) + this.shaderPrograms.push(this.createShaderProgram(cr.shaders[shader_name], vsSource, shader_name)); + } + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, null); + this.batch = []; + this.batchPtr = 0; + this.hasQuadBatchTop = false; + this.hasPointBatchTop = false; + this.lastProgram = -1; // start -1 so first switchProgram can do work + this.currentProgram = -1; // current program during batch execution + this.currentShader = null; + this.fbo = gl.createFramebuffer(); + this.renderToTex = null; + this.tmpVec3 = vec3.create([0, 0, 0]); +; + var pointsizes = gl.getParameter(gl.ALIASED_POINT_SIZE_RANGE); + this.minPointSize = pointsizes[0]; + this.maxPointSize = pointsizes[1]; + if (this.maxPointSize > 2048) + this.maxPointSize = 2048; +; + this.switchProgram(0); + cr.seal(this); + }; + function GLShaderProgram(gl, shaderProgram, name) + { + this.gl = gl; + this.shaderProgram = shaderProgram; + this.name = name; + this.locAPos = gl.getAttribLocation(shaderProgram, "aPos"); + this.locATex = gl.getAttribLocation(shaderProgram, "aTex"); + this.locMatP = gl.getUniformLocation(shaderProgram, "matP"); + this.locMatMV = gl.getUniformLocation(shaderProgram, "matMV"); + this.locOpacity = gl.getUniformLocation(shaderProgram, "opacity"); + this.locSamplerFront = gl.getUniformLocation(shaderProgram, "samplerFront"); + this.locSamplerBack = gl.getUniformLocation(shaderProgram, "samplerBack"); + this.locDestStart = gl.getUniformLocation(shaderProgram, "destStart"); + this.locDestEnd = gl.getUniformLocation(shaderProgram, "destEnd"); + this.locSeconds = gl.getUniformLocation(shaderProgram, "seconds"); + this.locPixelWidth = gl.getUniformLocation(shaderProgram, "pixelWidth"); + this.locPixelHeight = gl.getUniformLocation(shaderProgram, "pixelHeight"); + this.locLayerScale = gl.getUniformLocation(shaderProgram, "layerScale"); + this.locLayerAngle = gl.getUniformLocation(shaderProgram, "layerAngle"); + this.locViewOrigin = gl.getUniformLocation(shaderProgram, "viewOrigin"); + this.locScrollPos = gl.getUniformLocation(shaderProgram, "scrollPos"); + this.hasAnyOptionalUniforms = !!(this.locPixelWidth || this.locPixelHeight || this.locSeconds || this.locSamplerBack || this.locDestStart || this.locDestEnd || this.locLayerScale || this.locLayerAngle || this.locViewOrigin || this.locScrollPos); + this.lpPixelWidth = -999; // set to something unlikely so never counts as cached on first set + this.lpPixelHeight = -999; + this.lpOpacity = 1; + this.lpDestStartX = 0.0; + this.lpDestStartY = 0.0; + this.lpDestEndX = 1.0; + this.lpDestEndY = 1.0; + this.lpLayerScale = 1.0; + this.lpLayerAngle = 0.0; + this.lpViewOriginX = 0.0; + this.lpViewOriginY = 0.0; + this.lpScrollPosX = 0.0; + this.lpScrollPosY = 0.0; + this.lastCustomParams = []; + this.lpMatMV = mat4.create(); + if (this.locOpacity) + gl.uniform1f(this.locOpacity, 1); + if (this.locSamplerFront) + gl.uniform1i(this.locSamplerFront, 0); + if (this.locSamplerBack) + gl.uniform1i(this.locSamplerBack, 1); + if (this.locDestStart) + gl.uniform2f(this.locDestStart, 0.0, 0.0); + if (this.locDestEnd) + gl.uniform2f(this.locDestEnd, 1.0, 1.0); + if (this.locLayerScale) + gl.uniform1f(this.locLayerScale, 1.0); + if (this.locLayerAngle) + gl.uniform1f(this.locLayerAngle, 0.0); + if (this.locViewOrigin) + gl.uniform2f(this.locViewOrigin, 0.0, 0.0); + if (this.locScrollPos) + gl.uniform2f(this.locScrollPos, 0.0, 0.0); + this.hasCurrentMatMV = false; // matMV needs updating + }; + function areMat4sEqual(a, b) + { + return a[0]===b[0]&&a[1]===b[1]&&a[2]===b[2]&&a[3]===b[3]&& + a[4]===b[4]&&a[5]===b[5]&&a[6]===b[6]&&a[7]===b[7]&& + a[8]===b[8]&&a[9]===b[9]&&a[10]===b[10]&&a[11]===b[11]&& + a[12]===b[12]&&a[13]===b[13]&&a[14]===b[14]&&a[15]===b[15]; + }; + GLShaderProgram.prototype.updateMatMV = function (mv) + { + if (areMat4sEqual(this.lpMatMV, mv)) + return; // no change, save the expensive GL call + mat4.set(mv, this.lpMatMV); + this.gl.uniformMatrix4fv(this.locMatMV, false, mv); + }; + GLWrap_.prototype.createShaderProgram = function(shaderEntry, vsSource, name) + { + var gl = this.gl; + var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); + gl.shaderSource(fragmentShader, shaderEntry.src); + gl.compileShader(fragmentShader); + if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) + { +; + gl.deleteShader(fragmentShader); + return null; + } + var vertexShader = gl.createShader(gl.VERTEX_SHADER); + gl.shaderSource(vertexShader, vsSource); + gl.compileShader(vertexShader); + if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) + { +; + gl.deleteShader(fragmentShader); + gl.deleteShader(vertexShader); + return null; + } + var shaderProgram = gl.createProgram(); + gl.attachShader(shaderProgram, fragmentShader); + gl.attachShader(shaderProgram, vertexShader); + gl.linkProgram(shaderProgram); + if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) + { +; + gl.deleteShader(fragmentShader); + gl.deleteShader(vertexShader); + gl.deleteProgram(shaderProgram); + return null; + } + gl.useProgram(shaderProgram); + gl.deleteShader(fragmentShader); + gl.deleteShader(vertexShader); + var ret = new GLShaderProgram(gl, shaderProgram, name); + ret.extendBoxHorizontal = shaderEntry.extendBoxHorizontal || 0; + ret.extendBoxVertical = shaderEntry.extendBoxVertical || 0; + ret.crossSampling = !!shaderEntry.crossSampling; + ret.animated = !!shaderEntry.animated; + ret.parameters = shaderEntry.parameters || []; + var i, len; + for (i = 0, len = ret.parameters.length; i < len; i++) + { + ret.parameters[i][1] = gl.getUniformLocation(shaderProgram, ret.parameters[i][0]); + ret.lastCustomParams.push(0); + gl.uniform1f(ret.parameters[i][1], 0); + } + cr.seal(ret); + return ret; + }; + GLWrap_.prototype.getShaderIndex = function(name_) + { + var i, len; + for (i = 0, len = this.shaderPrograms.length; i < len; i++) + { + if (this.shaderPrograms[i].name === name_) + return i; + } + return -1; + }; + GLWrap_.prototype.project = function (x, y, out) + { + var mv = this.matMV; + var proj = this.matP; + var fTempo = [0, 0, 0, 0, 0, 0, 0, 0]; + fTempo[0] = mv[0]*x+mv[4]*y+mv[12]; + fTempo[1] = mv[1]*x+mv[5]*y+mv[13]; + fTempo[2] = mv[2]*x+mv[6]*y+mv[14]; + fTempo[3] = mv[3]*x+mv[7]*y+mv[15]; + fTempo[4] = proj[0]*fTempo[0]+proj[4]*fTempo[1]+proj[8]*fTempo[2]+proj[12]*fTempo[3]; + fTempo[5] = proj[1]*fTempo[0]+proj[5]*fTempo[1]+proj[9]*fTempo[2]+proj[13]*fTempo[3]; + fTempo[6] = proj[2]*fTempo[0]+proj[6]*fTempo[1]+proj[10]*fTempo[2]+proj[14]*fTempo[3]; + fTempo[7] = -fTempo[2]; + if(fTempo[7]===0.0) //The w value + return; + fTempo[7]=1.0/fTempo[7]; + fTempo[4]*=fTempo[7]; + fTempo[5]*=fTempo[7]; + fTempo[6]*=fTempo[7]; + out[0]=(fTempo[4]*0.5+0.5)*this.width; + out[1]=(fTempo[5]*0.5+0.5)*this.height; + }; + GLWrap_.prototype.setSize = function(w, h, force) + { + if (this.width === w && this.height === h && !force) + return; + this.endBatch(); + this.width = w; + this.height = h; + this.gl.viewport(0, 0, w, h); + mat4.perspective(45, w / h, 1, 1000, this.matP); + mat4.lookAt(this.cam, this.look, this.up, this.matMV); + var tl = [0, 0]; + var br = [0, 0]; + this.project(0, 0, tl); + this.project(1, 1, br); + this.worldScale[0] = 1 / (br[0] - tl[0]); + this.worldScale[1] = -1 / (br[1] - tl[1]); + var i, len, s; + for (i = 0, len = this.shaderPrograms.length; i < len; i++) + { + s = this.shaderPrograms[i]; + s.hasCurrentMatMV = false; + if (s.locMatP) + { + this.gl.useProgram(s.shaderProgram); + this.gl.uniformMatrix4fv(s.locMatP, false, this.matP); + } + } + this.gl.useProgram(this.shaderPrograms[this.lastProgram].shaderProgram); + this.gl.bindTexture(this.gl.TEXTURE_2D, null); + this.gl.activeTexture(this.gl.TEXTURE1); + this.gl.bindTexture(this.gl.TEXTURE_2D, null); + this.gl.activeTexture(this.gl.TEXTURE0); + this.lastTexture0 = null; + this.lastTexture1 = null; + }; + GLWrap_.prototype.resetModelView = function () + { + mat4.lookAt(this.cam, this.look, this.up, this.matMV); + mat4.scale(this.matMV, this.worldScale); + }; + GLWrap_.prototype.translate = function (x, y) + { + if (x === 0 && y === 0) + return; + this.tmpVec3[0] = x;// * this.worldScale[0]; + this.tmpVec3[1] = y;// * this.worldScale[1]; + this.tmpVec3[2] = 0; + mat4.translate(this.matMV, this.tmpVec3); + }; + GLWrap_.prototype.scale = function (x, y) + { + if (x === 1 && y === 1) + return; + this.tmpVec3[0] = x; + this.tmpVec3[1] = y; + this.tmpVec3[2] = 1; + mat4.scale(this.matMV, this.tmpVec3); + }; + GLWrap_.prototype.rotateZ = function (a) + { + if (a === 0) + return; + mat4.rotateZ(this.matMV, a); + }; + GLWrap_.prototype.updateModelView = function() + { + var anydiff = false; + for (var i = 0; i < 16; i++) + { + if (this.lastMV[i] !== this.matMV[i]) + { + anydiff = true; + break; + } + } + if (!anydiff) + return; + var b = this.pushBatch(); + b.type = BATCH_UPDATEMODELVIEW; + if (b.mat4param) + mat4.set(this.matMV, b.mat4param); + else + b.mat4param = mat4.create(this.matMV); + mat4.set(this.matMV, this.lastMV); + this.hasQuadBatchTop = false; + this.hasPointBatchTop = false; + }; + /* + var debugBatch = false; + jQuery(document).mousedown( + function(info) { + if (info.which === 2) + debugBatch = true; + } + ); + */ + function GLBatchJob(type_, glwrap_) + { + this.type = type_; + this.glwrap = glwrap_; + this.gl = glwrap_.gl; + this.opacityParam = 0; // for setOpacity() + this.startIndex = 0; // for quad() + this.indexCount = 0; // " + this.texParam = null; // for setTexture() + this.mat4param = null; // for updateModelView() + this.shaderParams = []; // for user parameters + cr.seal(this); + }; + GLBatchJob.prototype.doSetTexture = function () + { + this.gl.bindTexture(this.gl.TEXTURE_2D, this.texParam); + }; + GLBatchJob.prototype.doSetTexture1 = function () + { + var gl = this.gl; + gl.activeTexture(gl.TEXTURE1); + gl.bindTexture(gl.TEXTURE_2D, this.texParam); + gl.activeTexture(gl.TEXTURE0); + }; + GLBatchJob.prototype.doSetOpacity = function () + { + var o = this.opacityParam; + var glwrap = this.glwrap; + glwrap.currentOpacity = o; + var curProg = glwrap.currentShader; + if (curProg.locOpacity && curProg.lpOpacity !== o) + { + curProg.lpOpacity = o; + this.gl.uniform1f(curProg.locOpacity, o); + } + }; + GLBatchJob.prototype.doQuad = function () + { + this.gl.drawElements(this.gl.TRIANGLES, this.indexCount, this.gl.UNSIGNED_SHORT, this.startIndex * 2); + }; + GLBatchJob.prototype.doSetBlend = function () + { + this.gl.blendFunc(this.startIndex, this.indexCount); + }; + GLBatchJob.prototype.doUpdateModelView = function () + { + var i, len, s, shaderPrograms = this.glwrap.shaderPrograms, currentProgram = this.glwrap.currentProgram; + for (i = 0, len = shaderPrograms.length; i < len; i++) + { + s = shaderPrograms[i]; + if (i === currentProgram && s.locMatMV) + { + s.updateMatMV(this.mat4param); + s.hasCurrentMatMV = true; + } + else + s.hasCurrentMatMV = false; + } + mat4.set(this.mat4param, this.glwrap.currentMV); + }; + GLBatchJob.prototype.doRenderToTexture = function () + { + var gl = this.gl; + var glwrap = this.glwrap; + if (this.texParam) + { + if (glwrap.lastTexture1 === this.texParam) + { + gl.activeTexture(gl.TEXTURE1); + gl.bindTexture(gl.TEXTURE_2D, null); + glwrap.lastTexture1 = null; + gl.activeTexture(gl.TEXTURE0); + } + gl.bindFramebuffer(gl.FRAMEBUFFER, glwrap.fbo); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texParam, 0); + } + else + { + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 0); + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + } + }; + GLBatchJob.prototype.doClear = function () + { + var gl = this.gl; + if (this.startIndex === 0) // clear whole surface + { + gl.clearColor(this.mat4param[0], this.mat4param[1], this.mat4param[2], this.mat4param[3]); + gl.clear(gl.COLOR_BUFFER_BIT); + } + else // clear rectangle + { + gl.enable(gl.SCISSOR_TEST); + gl.scissor(this.mat4param[0], this.mat4param[1], this.mat4param[2], this.mat4param[3]); + gl.clearColor(0, 0, 0, 0); + gl.clear(this.gl.COLOR_BUFFER_BIT); + gl.disable(gl.SCISSOR_TEST); + } + }; + GLBatchJob.prototype.doPoints = function () + { + var gl = this.gl; + var glwrap = this.glwrap; + var s = glwrap.shaderPrograms[1]; + gl.useProgram(s.shaderProgram); + if (!s.hasCurrentMatMV && s.locMatMV) + { + s.updateMatMV(glwrap.currentMV); + s.hasCurrentMatMV = true; + } + gl.enableVertexAttribArray(s.locAPos); + gl.bindBuffer(gl.ARRAY_BUFFER, glwrap.pointBuffer); + gl.vertexAttribPointer(s.locAPos, 4, gl.FLOAT, false, 0, 0); + gl.drawArrays(gl.POINTS, this.startIndex / 4, this.indexCount); + s = glwrap.currentShader; + gl.useProgram(s.shaderProgram); + if (s.locAPos >= 0) + { + gl.enableVertexAttribArray(s.locAPos); + gl.bindBuffer(gl.ARRAY_BUFFER, glwrap.vertexBuffers[glwrap.curBuffer]); + gl.vertexAttribPointer(s.locAPos, 2, gl.FLOAT, false, 0, 0); + } + if (s.locATex >= 0) + { + gl.enableVertexAttribArray(s.locATex); + gl.bindBuffer(gl.ARRAY_BUFFER, glwrap.texcoordBuffers[glwrap.curBuffer]); + gl.vertexAttribPointer(s.locATex, 2, gl.FLOAT, false, 0, 0); + } + }; + GLBatchJob.prototype.doSetProgram = function () + { + var gl = this.gl; + var glwrap = this.glwrap; + var s = glwrap.shaderPrograms[this.startIndex]; // recycled param to save memory + glwrap.currentProgram = this.startIndex; // current batch program + glwrap.currentShader = s; + gl.useProgram(s.shaderProgram); // switch to + if (!s.hasCurrentMatMV && s.locMatMV) + { + s.updateMatMV(glwrap.currentMV); + s.hasCurrentMatMV = true; + } + if (s.locOpacity && s.lpOpacity !== glwrap.currentOpacity) + { + s.lpOpacity = glwrap.currentOpacity; + gl.uniform1f(s.locOpacity, glwrap.currentOpacity); + } + if (s.locAPos >= 0) + { + gl.enableVertexAttribArray(s.locAPos); + gl.bindBuffer(gl.ARRAY_BUFFER, glwrap.vertexBuffers[glwrap.curBuffer]); + gl.vertexAttribPointer(s.locAPos, 2, gl.FLOAT, false, 0, 0); + } + if (s.locATex >= 0) + { + gl.enableVertexAttribArray(s.locATex); + gl.bindBuffer(gl.ARRAY_BUFFER, glwrap.texcoordBuffers[glwrap.curBuffer]); + gl.vertexAttribPointer(s.locATex, 2, gl.FLOAT, false, 0, 0); + } + } + GLBatchJob.prototype.doSetProgramParameters = function () + { + var i, len, s = this.glwrap.currentShader; + var gl = this.gl; + var mat4param = this.mat4param; + if (s.locSamplerBack && this.glwrap.lastTexture1 !== this.texParam) + { + gl.activeTexture(gl.TEXTURE1); + gl.bindTexture(gl.TEXTURE_2D, this.texParam); + this.glwrap.lastTexture1 = this.texParam; + gl.activeTexture(gl.TEXTURE0); + } + var v = mat4param[0]; + var v2; + if (s.locPixelWidth && v !== s.lpPixelWidth) + { + s.lpPixelWidth = v; + gl.uniform1f(s.locPixelWidth, v); + } + v = mat4param[1]; + if (s.locPixelHeight && v !== s.lpPixelHeight) + { + s.lpPixelHeight = v; + gl.uniform1f(s.locPixelHeight, v); + } + v = mat4param[2]; + v2 = mat4param[3]; + if (s.locDestStart && (v !== s.lpDestStartX || v2 !== s.lpDestStartY)) + { + s.lpDestStartX = v; + s.lpDestStartY = v2; + gl.uniform2f(s.locDestStart, v, v2); + } + v = mat4param[4]; + v2 = mat4param[5]; + if (s.locDestEnd && (v !== s.lpDestEndX || v2 !== s.lpDestEndY)) + { + s.lpDestEndX = v; + s.lpDestEndY = v; + gl.uniform2f(s.locDestEnd, v, v2); + } + v = mat4param[6]; + if (s.locLayerScale && v !== s.lpLayerScale) + { + s.lpLayerScale = v; + gl.uniform1f(s.locLayerScale, v); + } + v = mat4param[7]; + if (s.locLayerAngle && v !== s.lpLayerAngle) + { + s.lpLayerAngle = v; + gl.uniform1f(s.locLayerAngle, v); + } + v = mat4param[8]; + v2 = mat4param[9]; + if (s.locViewOrigin && (v !== s.lpViewOriginX || v2 !== s.lpViewOriginY)) + { + s.lpViewOriginX = v; + s.lpViewOriginY = v2; + gl.uniform2f(s.locViewOrigin, v, v2); + } + v = mat4param[10]; + v2 = mat4param[11]; + if (s.locScrollPos && (v !== s.lpScrollPosX || v2 !== s.lpScrollPosY)) + { + s.lpScrollPosX = v; + s.lpScrollPosY = v2; + gl.uniform2f(s.locScrollPos, v, v2); + } + if (s.locSeconds) + gl.uniform1f(s.locSeconds, cr.performance_now() / 1000.0); + if (s.parameters.length) + { + for (i = 0, len = s.parameters.length; i < len; i++) + { + v = this.shaderParams[i]; + if (v !== s.lastCustomParams[i]) + { + s.lastCustomParams[i] = v; + gl.uniform1f(s.parameters[i][1], v); + } + } + } + }; + GLWrap_.prototype.pushBatch = function () + { + if (this.batchPtr === this.batch.length) + this.batch.push(new GLBatchJob(BATCH_NULL, this)); + return this.batch[this.batchPtr++]; + }; + GLWrap_.prototype.endBatch = function () + { + if (this.batchPtr === 0) + return; + if (this.gl.isContextLost()) + return; + var gl = this.gl; + if (this.pointPtr > 0) + { + gl.bindBuffer(gl.ARRAY_BUFFER, this.pointBuffer); + gl.bufferData(gl.ARRAY_BUFFER, this.pointData.subarray(0, this.pointPtr), gl.STREAM_DRAW); + if (s && s.locAPos >= 0 && s.name === "") + gl.vertexAttribPointer(s.locAPos, 4, gl.FLOAT, false, 0, 0); + } + if (this.vertexPtr > 0) + { + var s = this.currentShader; + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffers[this.curBuffer]); + gl.bufferData(gl.ARRAY_BUFFER, this.vertexData.subarray(0, this.vertexPtr), gl.STREAM_DRAW); + if (s && s.locAPos >= 0 && s.name !== "") + gl.vertexAttribPointer(s.locAPos, 2, gl.FLOAT, false, 0, 0); + gl.bindBuffer(gl.ARRAY_BUFFER, this.texcoordBuffers[this.curBuffer]); + gl.bufferData(gl.ARRAY_BUFFER, this.texcoordData.subarray(0, this.vertexPtr), gl.STREAM_DRAW); + if (s && s.locATex >= 0 && s.name !== "") + gl.vertexAttribPointer(s.locATex, 2, gl.FLOAT, false, 0, 0); + } + var i, len, b; + for (i = 0, len = this.batchPtr; i < len; i++) + { + b = this.batch[i]; + switch (b.type) { + case 1: + b.doQuad(); + break; + case 2: + b.doSetTexture(); + break; + case 3: + b.doSetOpacity(); + break; + case 4: + b.doSetBlend(); + break; + case 5: + b.doUpdateModelView(); + break; + case 6: + b.doRenderToTexture(); + break; + case 7: + b.doClear(); + break; + case 8: + b.doPoints(); + break; + case 9: + b.doSetProgram(); + break; + case 10: + b.doSetProgramParameters(); + break; + case 11: + b.doSetTexture1(); + break; + } + } + this.batchPtr = 0; + this.vertexPtr = 0; + this.pointPtr = 0; + this.hasQuadBatchTop = false; + this.hasPointBatchTop = false; + this.curBuffer++; + if (this.curBuffer >= MULTI_BUFFERS) + this.curBuffer = 0; + }; + GLWrap_.prototype.setOpacity = function (op) + { + if (op === this.lastOpacity) + return; + var b = this.pushBatch(); + b.type = BATCH_SETOPACITY; + b.opacityParam = op; + this.lastOpacity = op; + this.hasQuadBatchTop = false; + this.hasPointBatchTop = false; + }; + GLWrap_.prototype.setTexture = function (tex) + { + if (tex === this.lastTexture0) + return; +; + var b = this.pushBatch(); + b.type = BATCH_SETTEXTURE; + b.texParam = tex; + this.lastTexture0 = tex; + this.hasQuadBatchTop = false; + this.hasPointBatchTop = false; + }; + GLWrap_.prototype.setBlend = function (s, d) + { + if (s === this.lastSrcBlend && d === this.lastDestBlend) + return; + var b = this.pushBatch(); + b.type = BATCH_SETBLEND; + b.startIndex = s; // recycle params to save memory + b.indexCount = d; + this.lastSrcBlend = s; + this.lastDestBlend = d; + this.hasQuadBatchTop = false; + this.hasPointBatchTop = false; + }; + GLWrap_.prototype.isPremultipliedAlphaBlend = function () + { + return (this.lastSrcBlend === this.gl.ONE && this.lastDestBlend === this.gl.ONE_MINUS_SRC_ALPHA); + }; + GLWrap_.prototype.setAlphaBlend = function () + { + this.setBlend(this.gl.ONE, this.gl.ONE_MINUS_SRC_ALPHA); + }; + GLWrap_.prototype.setNoPremultiplyAlphaBlend = function () + { + this.setBlend(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA); + }; + var LAST_VERTEX = MAX_VERTICES * 2 - 8; + GLWrap_.prototype.quad = function(tlx, tly, trx, try_, brx, bry, blx, bly) + { + if (this.vertexPtr >= LAST_VERTEX) + this.endBatch(); + var v = this.vertexPtr; // vertex cursor + var vd = this.vertexData; // vertex data array + var td = this.texcoordData; // texture coord data array + if (this.hasQuadBatchTop) + { + this.batch[this.batchPtr - 1].indexCount += 6; + } + else + { + var b = this.pushBatch(); + b.type = BATCH_QUAD; + b.startIndex = (v / 4) * 3; + b.indexCount = 6; + this.hasQuadBatchTop = true; + this.hasPointBatchTop = false; + } + vd[v] = tlx; + td[v++] = 0; + vd[v] = tly; + td[v++] = 0; + vd[v] = trx; + td[v++] = 1; + vd[v] = try_; + td[v++] = 0; + vd[v] = brx; + td[v++] = 1; + vd[v] = bry; + td[v++] = 1; + vd[v] = blx; + td[v++] = 0; + vd[v] = bly; + td[v++] = 1; + this.vertexPtr = v; + }; + GLWrap_.prototype.quadTex = function(tlx, tly, trx, try_, brx, bry, blx, bly, rcTex) + { + if (this.vertexPtr >= LAST_VERTEX) + this.endBatch(); + var v = this.vertexPtr; // vertex cursor + var vd = this.vertexData; // vertex data array + var td = this.texcoordData; // texture coord data array + if (this.hasQuadBatchTop) + { + this.batch[this.batchPtr - 1].indexCount += 6; + } + else + { + var b = this.pushBatch(); + b.type = BATCH_QUAD; + b.startIndex = (v / 4) * 3; + b.indexCount = 6; + this.hasQuadBatchTop = true; + this.hasPointBatchTop = false; + } + var rc_left = rcTex.left; + var rc_top = rcTex.top; + var rc_right = rcTex.right; + var rc_bottom = rcTex.bottom; + vd[v] = tlx; + td[v++] = rc_left; + vd[v] = tly; + td[v++] = rc_top; + vd[v] = trx; + td[v++] = rc_right; + vd[v] = try_; + td[v++] = rc_top; + vd[v] = brx; + td[v++] = rc_right; + vd[v] = bry; + td[v++] = rc_bottom; + vd[v] = blx; + td[v++] = rc_left; + vd[v] = bly; + td[v++] = rc_bottom; + this.vertexPtr = v; + }; + GLWrap_.prototype.quadTexUV = function(tlx, tly, trx, try_, brx, bry, blx, bly, tlu, tlv, tru, trv, bru, brv, blu, blv) + { + if (this.vertexPtr >= LAST_VERTEX) + this.endBatch(); + var v = this.vertexPtr; // vertex cursor + var vd = this.vertexData; // vertex data array + var td = this.texcoordData; // texture coord data array + if (this.hasQuadBatchTop) + { + this.batch[this.batchPtr - 1].indexCount += 6; + } + else + { + var b = this.pushBatch(); + b.type = BATCH_QUAD; + b.startIndex = (v / 4) * 3; + b.indexCount = 6; + this.hasQuadBatchTop = true; + this.hasPointBatchTop = false; + } + vd[v] = tlx; + td[v++] = tlu; + vd[v] = tly; + td[v++] = tlv; + vd[v] = trx; + td[v++] = tru; + vd[v] = try_; + td[v++] = trv; + vd[v] = brx; + td[v++] = bru; + vd[v] = bry; + td[v++] = brv; + vd[v] = blx; + td[v++] = blu; + vd[v] = bly; + td[v++] = blv; + this.vertexPtr = v; + }; + GLWrap_.prototype.convexPoly = function(pts) + { + var pts_count = pts.length / 2; +; + var tris = pts_count - 2; // 3 points = 1 tri, 4 points = 2 tris, 5 points = 3 tris etc. + var last_tri = tris - 1; + var p0x = pts[0]; + var p0y = pts[1]; + var i, i2, p1x, p1y, p2x, p2y, p3x, p3y; + for (i = 0; i < tris; i += 2) // draw 2 triangles at a time + { + i2 = i * 2; + p1x = pts[i2 + 2]; + p1y = pts[i2 + 3]; + p2x = pts[i2 + 4]; + p2y = pts[i2 + 5]; + if (i === last_tri) + { + this.quad(p0x, p0y, p1x, p1y, p2x, p2y, p2x, p2y); + } + else + { + p3x = pts[i2 + 6]; + p3y = pts[i2 + 7]; + this.quad(p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y); + } + } + }; + var LAST_POINT = MAX_POINTS - 4; + GLWrap_.prototype.point = function(x_, y_, size_, opacity_) + { + if (this.pointPtr >= LAST_POINT) + this.endBatch(); + var p = this.pointPtr; // point cursor + var pd = this.pointData; // point data array + if (this.hasPointBatchTop) + { + this.batch[this.batchPtr - 1].indexCount++; + } + else + { + var b = this.pushBatch(); + b.type = BATCH_POINTS; + b.startIndex = p; + b.indexCount = 1; + this.hasPointBatchTop = true; + this.hasQuadBatchTop = false; + } + pd[p++] = x_; + pd[p++] = y_; + pd[p++] = size_; + pd[p++] = opacity_; + this.pointPtr = p; + }; + GLWrap_.prototype.switchProgram = function (progIndex) + { + if (this.lastProgram === progIndex) + return; // no change + var shaderProg = this.shaderPrograms[progIndex]; + if (!shaderProg) + { + if (this.lastProgram === 0) + return; // already on default shader + progIndex = 0; + shaderProg = this.shaderPrograms[0]; + } + var b = this.pushBatch(); + b.type = BATCH_SETPROGRAM; + b.startIndex = progIndex; + this.lastProgram = progIndex; + this.hasQuadBatchTop = false; + this.hasPointBatchTop = false; + }; + GLWrap_.prototype.programUsesDest = function (progIndex) + { + var s = this.shaderPrograms[progIndex]; + return !!(s.locDestStart || s.locDestEnd); + }; + GLWrap_.prototype.programUsesCrossSampling = function (progIndex) + { + var s = this.shaderPrograms[progIndex]; + return !!(s.locDestStart || s.locDestEnd || s.crossSampling); + }; + GLWrap_.prototype.programExtendsBox = function (progIndex) + { + var s = this.shaderPrograms[progIndex]; + return s.extendBoxHorizontal !== 0 || s.extendBoxVertical !== 0; + }; + GLWrap_.prototype.getProgramBoxExtendHorizontal = function (progIndex) + { + return this.shaderPrograms[progIndex].extendBoxHorizontal; + }; + GLWrap_.prototype.getProgramBoxExtendVertical = function (progIndex) + { + return this.shaderPrograms[progIndex].extendBoxVertical; + }; + GLWrap_.prototype.getProgramParameterType = function (progIndex, paramIndex) + { + return this.shaderPrograms[progIndex].parameters[paramIndex][2]; + }; + GLWrap_.prototype.programIsAnimated = function (progIndex) + { + return this.shaderPrograms[progIndex].animated; + }; + GLWrap_.prototype.setProgramParameters = function (backTex, pixelWidth, pixelHeight, destStartX, destStartY, destEndX, destEndY, layerScale, layerAngle, viewOriginLeft, viewOriginTop, scrollPosX, scrollPosY, params) + { + var i, len; + var s = this.shaderPrograms[this.lastProgram]; + var b, mat4param, shaderParams; + if (s.hasAnyOptionalUniforms || params.length) + { + b = this.pushBatch(); + b.type = BATCH_SETPROGRAMPARAMETERS; + if (b.mat4param) + mat4.set(this.matMV, b.mat4param); + else + b.mat4param = mat4.create(); + mat4param = b.mat4param; + mat4param[0] = pixelWidth; + mat4param[1] = pixelHeight; + mat4param[2] = destStartX; + mat4param[3] = destStartY; + mat4param[4] = destEndX; + mat4param[5] = destEndY; + mat4param[6] = layerScale; + mat4param[7] = layerAngle; + mat4param[8] = viewOriginLeft; + mat4param[9] = viewOriginTop; + mat4param[10] = scrollPosX; + mat4param[11] = scrollPosY; + if (s.locSamplerBack) + { +; + b.texParam = backTex; + } + else + b.texParam = null; + if (params.length) + { + shaderParams = b.shaderParams; + shaderParams.length = params.length; + for (i = 0, len = params.length; i < len; i++) + shaderParams[i] = params[i]; + } + this.hasQuadBatchTop = false; + this.hasPointBatchTop = false; + } + }; + GLWrap_.prototype.clear = function (r, g, b_, a) + { + var b = this.pushBatch(); + b.type = BATCH_CLEAR; + b.startIndex = 0; // clear all mode + if (!b.mat4param) + b.mat4param = mat4.create(); + b.mat4param[0] = r; + b.mat4param[1] = g; + b.mat4param[2] = b_; + b.mat4param[3] = a; + this.hasQuadBatchTop = false; + this.hasPointBatchTop = false; + }; + GLWrap_.prototype.clearRect = function (x, y, w, h) + { + if (w < 0 || h < 0) + return; // invalid clear area + var b = this.pushBatch(); + b.type = BATCH_CLEAR; + b.startIndex = 1; // clear rect mode + if (!b.mat4param) + b.mat4param = mat4.create(); + b.mat4param[0] = x; + b.mat4param[1] = y; + b.mat4param[2] = w; + b.mat4param[3] = h; + this.hasQuadBatchTop = false; + this.hasPointBatchTop = false; + }; + GLWrap_.prototype.present = function () + { + this.endBatch(); + this.gl.flush(); + /* + if (debugBatch) + { +; + debugBatch = false; + } + */ + }; + function nextHighestPowerOfTwo(x) { + --x; + for (var i = 1; i < 32; i <<= 1) { + x = x | x >> i; + } + return x + 1; + } + var all_textures = []; + var textures_by_src = {}; + GLWrap_.prototype.contextLost = function () + { + all_textures.length = 0; + textures_by_src = {}; + }; + var BF_RGBA8 = 0; + var BF_RGB8 = 1; + var BF_RGBA4 = 2; + var BF_RGB5_A1 = 3; + var BF_RGB565 = 4; + GLWrap_.prototype.loadTexture = function (img, tiling, linearsampling, pixelformat, tiletype, nomip) + { + tiling = !!tiling; + linearsampling = !!linearsampling; + var tex_key = img.src + "," + tiling + "," + linearsampling + (tiling ? ("," + tiletype) : ""); + var webGL_texture = null; + if (typeof img.src !== "undefined" && textures_by_src.hasOwnProperty(tex_key)) + { + webGL_texture = textures_by_src[tex_key]; + webGL_texture.c2refcount++; + return webGL_texture; + } + this.endBatch(); +; + var gl = this.gl; + var isPOT = (cr.isPOT(img.width) && cr.isPOT(img.height)); + webGL_texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, webGL_texture); + gl.pixelStorei(gl["UNPACK_PREMULTIPLY_ALPHA_WEBGL"], true); + var internalformat = gl.RGBA; + var format = gl.RGBA; + var type = gl.UNSIGNED_BYTE; + if (pixelformat && !this.isIE) + { + switch (pixelformat) { + case BF_RGB8: + internalformat = gl.RGB; + format = gl.RGB; + break; + case BF_RGBA4: + type = gl.UNSIGNED_SHORT_4_4_4_4; + break; + case BF_RGB5_A1: + type = gl.UNSIGNED_SHORT_5_5_5_1; + break; + case BF_RGB565: + internalformat = gl.RGB; + format = gl.RGB; + type = gl.UNSIGNED_SHORT_5_6_5; + break; + } + } + if (!isPOT && tiling) + { + var canvas = document.createElement("canvas"); + canvas.width = cr.nextHighestPowerOfTwo(img.width); + canvas.height = cr.nextHighestPowerOfTwo(img.height); + var ctx = canvas.getContext("2d"); + ctx["webkitImageSmoothingEnabled"] = linearsampling; + ctx["mozImageSmoothingEnabled"] = linearsampling; + ctx["msImageSmoothingEnabled"] = linearsampling; + ctx["imageSmoothingEnabled"] = linearsampling; + ctx.drawImage(img, + 0, 0, img.width, img.height, + 0, 0, canvas.width, canvas.height); + gl.texImage2D(gl.TEXTURE_2D, 0, internalformat, format, type, canvas); + } + else + gl.texImage2D(gl.TEXTURE_2D, 0, internalformat, format, type, img); + if (tiling) + { + if (tiletype === "repeat-x") + { + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + } + else if (tiletype === "repeat-y") + { + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); + } + else + { + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); + } + } + else + { + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + } + if (linearsampling) + { + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + if (isPOT && this.enable_mipmaps && !nomip) + { + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR); + gl.generateMipmap(gl.TEXTURE_2D); + } + else + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + } + else + { + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + } + gl.bindTexture(gl.TEXTURE_2D, null); + this.lastTexture0 = null; + webGL_texture.c2width = img.width; + webGL_texture.c2height = img.height; + webGL_texture.c2refcount = 1; + webGL_texture.c2texkey = tex_key; + all_textures.push(webGL_texture); + textures_by_src[tex_key] = webGL_texture; + return webGL_texture; + }; + GLWrap_.prototype.createEmptyTexture = function (w, h, linearsampling, _16bit, tiling) + { + this.endBatch(); + var gl = this.gl; + if (this.isIE) + _16bit = false; + var webGL_texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, webGL_texture); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, w, h, 0, gl.RGBA, _16bit ? gl.UNSIGNED_SHORT_4_4_4_4 : gl.UNSIGNED_BYTE, null); + if (tiling) + { + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); + } + else + { + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + } + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, linearsampling ? gl.LINEAR : gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, linearsampling ? gl.LINEAR : gl.NEAREST); + gl.bindTexture(gl.TEXTURE_2D, null); + this.lastTexture0 = null; + webGL_texture.c2width = w; + webGL_texture.c2height = h; + all_textures.push(webGL_texture); + return webGL_texture; + }; + GLWrap_.prototype.videoToTexture = function (video_, texture_, _16bit) + { + this.endBatch(); + var gl = this.gl; + if (this.isIE) + _16bit = false; + gl.bindTexture(gl.TEXTURE_2D, texture_); + gl.pixelStorei(gl["UNPACK_PREMULTIPLY_ALPHA_WEBGL"], true); + try { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, _16bit ? gl.UNSIGNED_SHORT_4_4_4_4 : gl.UNSIGNED_BYTE, video_); + } + catch (e) + { + if (console && console.error) + console.error("Error updating WebGL texture: ", e); + } + gl.bindTexture(gl.TEXTURE_2D, null); + this.lastTexture0 = null; + }; + GLWrap_.prototype.deleteTexture = function (tex) + { + if (!tex) + return; + if (typeof tex.c2refcount !== "undefined" && tex.c2refcount > 1) + { + tex.c2refcount--; + return; + } + this.endBatch(); + if (tex === this.lastTexture0) + { + this.gl.bindTexture(this.gl.TEXTURE_2D, null); + this.lastTexture0 = null; + } + if (tex === this.lastTexture1) + { + this.gl.activeTexture(this.gl.TEXTURE1); + this.gl.bindTexture(this.gl.TEXTURE_2D, null); + this.gl.activeTexture(this.gl.TEXTURE0); + this.lastTexture1 = null; + } + cr.arrayFindRemove(all_textures, tex); + if (typeof tex.c2texkey !== "undefined") + delete textures_by_src[tex.c2texkey]; + this.gl.deleteTexture(tex); + }; + GLWrap_.prototype.estimateVRAM = function () + { + var total = this.width * this.height * 4 * 2; + var i, len, t; + for (i = 0, len = all_textures.length; i < len; i++) + { + t = all_textures[i]; + total += (t.c2width * t.c2height * 4); + } + return total; + }; + GLWrap_.prototype.textureCount = function () + { + return all_textures.length; + }; + GLWrap_.prototype.setRenderingToTexture = function (tex) + { + if (tex === this.renderToTex) + return; +; + var b = this.pushBatch(); + b.type = BATCH_RENDERTOTEXTURE; + b.texParam = tex; + this.renderToTex = tex; + this.hasQuadBatchTop = false; + this.hasPointBatchTop = false; + }; + cr.GLWrap = GLWrap_; +}()); +; +(function() +{ + function window_innerWidth() + { + if (typeof jQuery !== "undefined") + return jQuery(window).width(); + else + return window.innerWidth; + }; + function window_innerHeight() + { + if (typeof jQuery !== "undefined") + return jQuery(window).height(); + else + return window.innerHeight; + }; + function Runtime(canvas) + { + if (!canvas || (!canvas.getContext && !canvas["dc"])) + return; + if (canvas["c2runtime"]) + return; + else + canvas["c2runtime"] = this; + var self = this; + this.isCrosswalk = /crosswalk/i.test(navigator.userAgent) || /xwalk/i.test(navigator.userAgent) || !!(typeof window["c2isCrosswalk"] !== "undefined" && window["c2isCrosswalk"]); + this.isCordova = this.isCrosswalk || (typeof window["device"] !== "undefined" && (typeof window["device"]["cordova"] !== "undefined" || typeof window["device"]["phonegap"] !== "undefined")) || (typeof window["c2iscordova"] !== "undefined" && window["c2iscordova"]); + this.isPhoneGap = this.isCordova; + this.isDirectCanvas = !!canvas["dc"]; + this.isAppMobi = (typeof window["AppMobi"] !== "undefined" || this.isDirectCanvas); + this.isCocoonJs = !!window["c2cocoonjs"]; + this.isEjecta = !!window["c2ejecta"]; + if (this.isCocoonJs) + { + CocoonJS["App"]["onSuspended"].addEventListener(function() { + self["setSuspended"](true); + }); + CocoonJS["App"]["onActivated"].addEventListener(function () { + self["setSuspended"](false); + }); + } + if (this.isEjecta) + { + document.addEventListener("pagehide", function() { + self["setSuspended"](true); + }); + document.addEventListener("pageshow", function() { + self["setSuspended"](false); + }); + document.addEventListener("resize", function () { + self["setSize"](window.innerWidth, window.innerHeight); + }); + } + this.isDomFree = (this.isDirectCanvas || this.isCocoonJs || this.isEjecta); + this.isIE = /msie/i.test(navigator.userAgent) || /trident/i.test(navigator.userAgent) || /iemobile/i.test(navigator.userAgent) || /edge\//i.test(navigator.userAgent); + this.isTizen = /tizen/i.test(navigator.userAgent); + this.isAndroid = /android/i.test(navigator.userAgent) && !this.isTizen && !this.isIE; // IE mobile and Tizen masquerade as Android + this.isiPhone = (/iphone/i.test(navigator.userAgent) || /ipod/i.test(navigator.userAgent)) && !this.isIE; // treat ipod as an iphone; IE mobile masquerades as iPhone + this.isiPad = /ipad/i.test(navigator.userAgent); + this.isiOS = this.isiPhone || this.isiPad || this.isEjecta; + this.isiPhoneiOS6 = (this.isiPhone && /os\s6/i.test(navigator.userAgent)); + this.isChrome = (/chrome/i.test(navigator.userAgent) || /chromium/i.test(navigator.userAgent)) && !this.isIE; // note true on Chromium-based webview on Android 4.4+; IE 'Edge' mode also pretends to be Chrome + this.isAmazonWebApp = /amazonwebappplatform/i.test(navigator.userAgent); + this.isFirefox = /firefox/i.test(navigator.userAgent); + this.isSafari = /safari/i.test(navigator.userAgent) && !this.isChrome && !this.isIE; // Chrome and IE Mobile masquerade as Safari + this.isWindows = /windows/i.test(navigator.userAgent); + this.isNodeWebkit = (typeof window["c2nodewebkit"] !== "undefined" || /nodewebkit/i.test(navigator.userAgent)); + this.isArcade = (typeof window["is_scirra_arcade"] !== "undefined"); + this.isWindows8App = !!(typeof window["c2isWindows8"] !== "undefined" && window["c2isWindows8"]); + this.isWindows8Capable = !!(typeof window["c2isWindows8Capable"] !== "undefined" && window["c2isWindows8Capable"]); + this.isWindowsPhone8 = !!(typeof window["c2isWindowsPhone8"] !== "undefined" && window["c2isWindowsPhone8"]); + this.isWindowsPhone81 = !!(typeof window["c2isWindowsPhone81"] !== "undefined" && window["c2isWindowsPhone81"]); + this.isWinJS = (this.isWindows8App || this.isWindows8Capable || this.isWindowsPhone81); // note not WP8.0 + this.isBlackberry10 = !!(typeof window["c2isBlackberry10"] !== "undefined" && window["c2isBlackberry10"]); + this.isAndroidStockBrowser = (this.isAndroid && !this.isChrome && !this.isCrosswalk && !this.isFirefox && !this.isAmazonWebApp && !this.isDomFree); + this.devicePixelRatio = 1; + this.isMobile = (this.isCordova || this.isCrosswalk || this.isAppMobi || this.isCocoonJs || this.isAndroid || this.isiOS || this.isWindowsPhone8 || this.isWindowsPhone81 || this.isBlackberry10 || this.isTizen || this.isEjecta); + if (!this.isMobile) + { + this.isMobile = /(blackberry|bb10|playbook|palm|symbian|nokia|windows\s+ce|phone|mobile|tablet|kindle|silk)/i.test(navigator.userAgent); + } + if (typeof cr_is_preview !== "undefined" && !this.isNodeWebkit && (window.location.search === "?nw" || /nodewebkit/i.test(navigator.userAgent))) + { + this.isNodeWebkit = true; + } + this.isDebug = (typeof cr_is_preview !== "undefined" && window.location.search.indexOf("debug") > -1); + this.canvas = canvas; + this.canvasdiv = document.getElementById("c2canvasdiv"); + this.gl = null; + this.glwrap = null; + this.ctx = null; + this.fullscreenOldMarginCss = ""; + this.firstInFullscreen = false; + this.oldWidth = 0; // for restoring non-fullscreen canvas after fullscreen + this.oldHeight = 0; + this.canvas.oncontextmenu = function (e) { if (e.preventDefault) e.preventDefault(); return false; }; + this.canvas.onselectstart = function (e) { if (e.preventDefault) e.preventDefault(); return false; }; + if (this.isDirectCanvas) + window["c2runtime"] = this; + if (this.isNodeWebkit) + { + window["ondragover"] = function(e) { e.preventDefault(); return false; }; + window["ondrop"] = function(e) { e.preventDefault(); return false; }; + require("nw.gui")["App"]["clearCache"](); + } + if (this.isAndroidStockBrowser && typeof jQuery !== "undefined") + { + jQuery("canvas").parents("*").css("overflow", "visible"); + } + this.width = canvas.width; + this.height = canvas.height; + this.draw_width = this.width; + this.draw_height = this.height; + this.cssWidth = this.width; + this.cssHeight = this.height; + this.lastWindowWidth = window.innerWidth; + this.lastWindowHeight = window.innerHeight; + this.forceCanvasAlpha = false; // allow plugins to force the canvas to display with alpha channel + this.redraw = true; + this.isSuspended = false; + if (!Date.now) { + Date.now = function now() { + return +new Date(); + }; + } + this.plugins = []; + this.types = {}; + this.types_by_index = []; + this.behaviors = []; + this.layouts = {}; + this.layouts_by_index = []; + this.eventsheets = {}; + this.eventsheets_by_index = []; + this.wait_for_textures = []; // for blocking until textures loaded + this.triggers_to_postinit = []; + this.all_global_vars = []; + this.all_local_vars = []; + this.solidBehavior = null; + this.jumpthruBehavior = null; + this.shadowcasterBehavior = null; + this.deathRow = {}; + this.hasPendingInstances = false; // true if anything exists in create row or death row + this.isInClearDeathRow = false; + this.isInOnDestroy = 0; // needs to support recursion so increments and decrements and is true if > 0 + this.isRunningEvents = false; + this.createRow = []; + this.isLoadingState = false; + this.saveToSlot = ""; + this.loadFromSlot = ""; + this.loadFromJson = ""; + this.lastSaveJson = ""; + this.signalledContinuousPreview = false; + this.suspendDrawing = false; // for hiding display until continuous preview loads + this.dt = 0; + this.dt1 = 0; + this.logictime = 0; // used to calculate CPUUtilisation + this.cpuutilisation = 0; + this.zeroDtCount = 0; + this.timescale = 1.0; + this.kahanTime = new cr.KahanAdder(); + this.wallTime = new cr.KahanAdder(); + this.last_tick_time = 0; + this.measuring_dt = true; + this.fps = 0; + this.last_fps_time = 0; + this.tickcount = 0; + this.execcount = 0; + this.framecount = 0; // for fps + this.objectcount = 0; + this.changelayout = null; + this.destroycallbacks = []; + this.event_stack = []; + this.event_stack_index = -1; + this.localvar_stack = [[]]; + this.localvar_stack_index = 0; + this.trigger_depth = 0; // recursion depth for triggers + this.pushEventStack(null); + this.loop_stack = []; + this.loop_stack_index = -1; + this.next_uid = 0; + this.next_puid = 0; // permanent unique ids + this.layout_first_tick = true; + this.family_count = 0; + this.suspend_events = []; + this.raf_id = -1; + this.timeout_id = -1; + this.isloading = true; + this.loadingprogress = 0; + this.isNodeFullscreen = false; + this.stackLocalCount = 0; // number of stack-based local vars for recursion + this.audioInstance = null; + this.halfFramerateMode = false; + this.lastRafTime = 0; // time of last requestAnimationFrame call + this.ranLastRaf = false; // false if last requestAnimationFrame was skipped for half framerate mode + this.had_a_click = false; + this.isInUserInputEvent = false; + this.objects_to_pretick = new cr.ObjectSet(); + this.objects_to_tick = new cr.ObjectSet(); + this.objects_to_tick2 = new cr.ObjectSet(); + this.registered_collisions = []; + this.temp_poly = new cr.CollisionPoly([]); + this.temp_poly2 = new cr.CollisionPoly([]); + this.allGroups = []; // array of all event groups + this.groups_by_name = {}; + this.cndsBySid = {}; + this.actsBySid = {}; + this.varsBySid = {}; + this.blocksBySid = {}; + this.running_layout = null; // currently running layout + this.layer_canvas = null; // for layers "render-to-texture" + this.layer_ctx = null; + this.layer_tex = null; + this.layout_tex = null; + this.layout_canvas = null; + this.layout_ctx = null; + this.is_WebGL_context_lost = false; + this.uses_background_blending = false; // if any shader uses background blending, so entire layout renders to texture + this.fx_tex = [null, null]; + this.fullscreen_scaling = 0; + this.files_subfolder = ""; // path with project files + this.objectsByUid = {}; // maps every in-use UID (as a string) to its instance + this.loaderlogo = null; + this.snapshotCanvas = null; + this.snapshotData = ""; + this.objectRefTable = []; + this.requestProjectData(); + }; + Runtime.prototype.requestProjectData = function () + { + var self = this; + var xhr; + if (this.isWindowsPhone8) + xhr = new ActiveXObject("Microsoft.XMLHTTP"); + else + xhr = new XMLHttpRequest(); + var datajs_filename = "data.js"; + if (this.isWindows8App || this.isWindowsPhone8 || this.isWindowsPhone81) + datajs_filename = "data.json"; + xhr.open("GET", datajs_filename, true); + var supportsJsonResponse = false; + if (!this.isDomFree && ("response" in xhr) && ("responseType" in xhr)) + { + try { + xhr["responseType"] = "json"; + supportsJsonResponse = (xhr["responseType"] === "json"); + } + catch (e) { + supportsJsonResponse = false; + } + } + if (!supportsJsonResponse && ("responseType" in xhr)) + { + try { + xhr["responseType"] = "text"; + } + catch (e) {} + } + if ("overrideMimeType" in xhr) + { + try { + xhr["overrideMimeType"]("application/json; charset=utf-8"); + } + catch (e) {} + } + if (this.isWindowsPhone8) + { + xhr.onreadystatechange = function () + { + if (xhr.readyState !== 4) + return; + self.loadProject(JSON.parse(xhr["responseText"])); + }; + } + else + { + xhr.onload = function () + { + if (supportsJsonResponse) + { + self.loadProject(xhr["response"]); // already parsed by browser + } + else + { + if (self.isEjecta) + { + var str = xhr["responseText"]; + str = str.substr(str.indexOf("{")); // trim any BOM + self.loadProject(JSON.parse(str)); + } + else + { + self.loadProject(JSON.parse(xhr["responseText"])); // forced to sync parse JSON + } + } + }; + xhr.onerror = function (e) + { + cr.logerror("Error requesting " + datajs_filename + ":"); + cr.logerror(e); + }; + } + xhr.send(); + }; + Runtime.prototype.initRendererAndLoader = function () + { + var self = this; + var i, len, j, lenj, k, lenk, t, s, l, y; + this.isRetina = ((!this.isDomFree || this.isEjecta) && this.useHighDpi && !this.isAndroidStockBrowser); + this.devicePixelRatio = (this.isRetina ? (window["devicePixelRatio"] || window["webkitDevicePixelRatio"] || window["mozDevicePixelRatio"] || window["msDevicePixelRatio"] || 1) : 1); + this.ClearDeathRow(); + var attribs; + var alpha_canvas = !!(this.forceCanvasAlpha || (this.alphaBackground && !(this.isNodeWebkit || this.isWinJS || this.isWindowsPhone8 || this.isCrosswalk || this.isCordova || this.isAmazonWebApp))); + if (this.fullscreen_mode > 0) + this["setSize"](window_innerWidth(), window_innerHeight(), true); + try { + if (this.enableWebGL && (this.isCocoonJs || this.isEjecta || !this.isDomFree)) + { + attribs = { + "alpha": alpha_canvas, + "depth": false, + "antialias": false, + "failIfMajorPerformanceCaveat": true + }; + this.gl = (this.canvas.getContext("webgl", attribs) || this.canvas.getContext("experimental-webgl", attribs)); + } + } + catch (e) { + } + if (this.gl) + { + if (!this.isDomFree) + { + this.overlay_canvas = document.createElement("canvas"); + jQuery(this.overlay_canvas).appendTo(this.canvas.parentNode); + this.overlay_canvas.oncontextmenu = function (e) { return false; }; + this.overlay_canvas.onselectstart = function (e) { return false; }; + this.overlay_canvas.width = this.cssWidth; + this.overlay_canvas.height = this.cssHeight; + jQuery(this.overlay_canvas).css({"width": this.cssWidth + "px", + "height": this.cssHeight + "px"}); + this.positionOverlayCanvas(); + this.overlay_ctx = this.overlay_canvas.getContext("2d"); + } + this.glwrap = new cr.GLWrap(this.gl, this.isMobile); + this.glwrap.setSize(this.canvas.width, this.canvas.height); + this.glwrap.enable_mipmaps = (this.downscalingQuality !== 0); + this.ctx = null; + this.canvas.addEventListener("webglcontextlost", function (ev) { + ev.preventDefault(); + self.onContextLost(); + cr.logexport("[Construct 2] WebGL context lost"); + window["cr_setSuspended"](true); // stop rendering + }, false); + this.canvas.addEventListener("webglcontextrestored", function (ev) { + self.glwrap.initState(); + self.glwrap.setSize(self.glwrap.width, self.glwrap.height, true); + self.layer_tex = null; + self.layout_tex = null; + self.fx_tex[0] = null; + self.fx_tex[1] = null; + self.onContextRestored(); + self.redraw = true; + cr.logexport("[Construct 2] WebGL context restored"); + window["cr_setSuspended"](false); // resume rendering + }, false); + for (i = 0, len = this.types_by_index.length; i < len; i++) + { + t = this.types_by_index[i]; + for (j = 0, lenj = t.effect_types.length; j < lenj; j++) + { + s = t.effect_types[j]; + s.shaderindex = this.glwrap.getShaderIndex(s.id); + this.uses_background_blending = this.uses_background_blending || this.glwrap.programUsesDest(s.shaderindex); + } + } + for (i = 0, len = this.layouts_by_index.length; i < len; i++) + { + l = this.layouts_by_index[i]; + for (j = 0, lenj = l.effect_types.length; j < lenj; j++) + { + s = l.effect_types[j]; + s.shaderindex = this.glwrap.getShaderIndex(s.id); + } + for (j = 0, lenj = l.layers.length; j < lenj; j++) + { + y = l.layers[j]; + for (k = 0, lenk = y.effect_types.length; k < lenk; k++) + { + s = y.effect_types[k]; + s.shaderindex = this.glwrap.getShaderIndex(s.id); + this.uses_background_blending = this.uses_background_blending || this.glwrap.programUsesDest(s.shaderindex); + } + } + } + } + else + { + if (this.fullscreen_mode > 0 && this.isDirectCanvas) + { +; + this.canvas = null; + document.oncontextmenu = function (e) { return false; }; + document.onselectstart = function (e) { return false; }; + this.ctx = AppMobi["canvas"]["getContext"]("2d"); + try { + this.ctx["samplingMode"] = this.linearSampling ? "smooth" : "sharp"; + this.ctx["globalScale"] = 1; + this.ctx["HTML5CompatibilityMode"] = true; + this.ctx["imageSmoothingEnabled"] = this.linearSampling; + } catch(e){} + if (this.width !== 0 && this.height !== 0) + { + this.ctx.width = this.width; + this.ctx.height = this.height; + } + } + if (!this.ctx) + { +; + if (this.isCocoonJs) + { + attribs = { + "antialias": !!this.linearSampling, + "alpha": alpha_canvas + }; + this.ctx = this.canvas.getContext("2d", attribs); + } + else + { + attribs = { + "alpha": alpha_canvas + }; + this.ctx = this.canvas.getContext("2d", attribs); + } + this.ctx["webkitImageSmoothingEnabled"] = this.linearSampling; + this.ctx["mozImageSmoothingEnabled"] = this.linearSampling; + this.ctx["msImageSmoothingEnabled"] = this.linearSampling; + this.ctx["imageSmoothingEnabled"] = this.linearSampling; + } + this.overlay_canvas = null; + this.overlay_ctx = null; + } + this.tickFunc = function () { self.tick(false); }; + if (window != window.top && !this.isDomFree && !this.isWinJS && !this.isWindowsPhone8) + { + document.addEventListener("mousedown", function () { + window.focus(); + }, true); + document.addEventListener("touchstart", function () { + window.focus(); + }, true); + } + if (typeof cr_is_preview !== "undefined") + { + if (this.isCocoonJs) + console.log("[Construct 2] In preview-over-wifi via CocoonJS mode"); + if (window.location.search.indexOf("continuous") > -1) + { + cr.logexport("Reloading for continuous preview"); + this.loadFromSlot = "__c2_continuouspreview"; + this.suspendDrawing = true; + } + if (this.pauseOnBlur && !this.isMobile) + { + jQuery(window).focus(function () + { + self["setSuspended"](false); + }); + jQuery(window).blur(function () + { + self["setSuspended"](true); + }); + } + } + if (!this.isDomFree) + { + var unfocusFormControlFunc = function (e) { + if (cr.isCanvasInputEvent(e) && document["activeElement"] && document["activeElement"] !== document.getElementsByTagName("body")[0] && document["activeElement"].blur) + { + try { + document["activeElement"].blur(); + } + catch (e) {} + } + } + if (window.navigator["pointerEnabled"]) + { + document.addEventListener("pointerdown", unfocusFormControlFunc); + } + else if (window.navigator["msPointerEnabled"]) + { + document.addEventListener("MSPointerDown", unfocusFormControlFunc); + } + else + { + document.addEventListener("touchstart", unfocusFormControlFunc); + } + document.addEventListener("mousedown", unfocusFormControlFunc); + } + if (this.fullscreen_mode === 0 && this.isRetina && this.devicePixelRatio > 1) + { + this["setSize"](this.original_width, this.original_height, true); + } + this.tryLockOrientation(); + this.getready(); // determine things to preload + this.go(); // run loading screen + this.extra = {}; + cr.seal(this); + }; + var webkitRepaintFlag = false; + Runtime.prototype["setSize"] = function (w, h, force) + { + var offx = 0, offy = 0; + var neww = 0, newh = 0, intscale = 0; + var tryHideAddressBar = (this.isiPhoneiOS6 && this.isSafari && !navigator["standalone"] && !this.isDomFree && !this.isCordova); + if (tryHideAddressBar) + h += 60; // height of Safari iPhone iOS 6 address bar + if (this.lastWindowWidth === w && this.lastWindowHeight === h && !force) + return; + this.lastWindowWidth = w; + this.lastWindowHeight = h; + var mode = this.fullscreen_mode; + var orig_aspect, cur_aspect; + var isfullscreen = (document["mozFullScreen"] || document["webkitIsFullScreen"] || !!document["msFullscreenElement"] || document["fullScreen"] || this.isNodeFullscreen) && !this.isCordova; + if (!isfullscreen && this.fullscreen_mode === 0 && !force) + return; // ignore size events when not fullscreen and not using a fullscreen-in-browser mode + if (isfullscreen && this.fullscreen_scaling > 0) + mode = this.fullscreen_scaling; + var dpr = this.devicePixelRatio; + if (mode >= 4) + { + orig_aspect = this.original_width / this.original_height; + cur_aspect = w / h; + if (cur_aspect > orig_aspect) + { + neww = h * orig_aspect; + if (mode === 5) // integer scaling + { + intscale = (neww * dpr) / this.original_width; + if (intscale > 1) + intscale = Math.floor(intscale); + else if (intscale < 1) + intscale = 1 / Math.ceil(1 / intscale); + neww = this.original_width * intscale / dpr; + newh = this.original_height * intscale / dpr; + offx = (w - neww) / 2; + offy = (h - newh) / 2; + w = neww; + h = newh; + } + else + { + offx = (w - neww) / 2; + w = neww; + } + } + else + { + newh = w / orig_aspect; + if (mode === 5) // integer scaling + { + intscale = (newh * dpr) / this.original_height; + if (intscale > 1) + intscale = Math.floor(intscale); + else if (intscale < 1) + intscale = 1 / Math.ceil(1 / intscale); + neww = this.original_width * intscale / dpr; + newh = this.original_height * intscale / dpr; + offx = (w - neww) / 2; + offy = (h - newh) / 2; + w = neww; + h = newh; + } + else + { + offy = (h - newh) / 2; + h = newh; + } + } + if (isfullscreen && !this.isNodeWebkit) + { + offx = 0; + offy = 0; + } + } + else if (this.isNodeWebkit && this.isNodeFullscreen && this.fullscreen_mode_set === 0) + { + offx = Math.floor((w - this.original_width) / 2); + offy = Math.floor((h - this.original_height) / 2); + w = this.original_width; + h = this.original_height; + } + if (mode < 2) + this.aspect_scale = dpr; + if (this.isRetina && this.isiPad && dpr > 1) // don't apply to iPad 1-2 + { + if (w >= 1024) + w = 1023; // 2046 retina pixels + if (h >= 1024) + h = 1023; + } + this.cssWidth = Math.round(w); + this.cssHeight = Math.round(h); + this.width = Math.round(w * dpr); + this.height = Math.round(h * dpr); + this.redraw = true; + if (this.wantFullscreenScalingQuality) + { + this.draw_width = this.width; + this.draw_height = this.height; + this.fullscreenScalingQuality = true; + } + else + { + if ((this.width < this.original_width && this.height < this.original_height) || mode === 1) + { + this.draw_width = this.width; + this.draw_height = this.height; + this.fullscreenScalingQuality = true; + } + else + { + this.draw_width = this.original_width; + this.draw_height = this.original_height; + this.fullscreenScalingQuality = false; + /*var orig_aspect = this.original_width / this.original_height; + var cur_aspect = this.width / this.height; + if ((this.fullscreen_mode !== 2 && cur_aspect > orig_aspect) || (this.fullscreen_mode === 2 && cur_aspect < orig_aspect)) + this.aspect_scale = this.height / this.original_height; + else + this.aspect_scale = this.width / this.original_width;*/ + if (mode === 2) // scale inner + { + orig_aspect = this.original_width / this.original_height; + cur_aspect = this.lastWindowWidth / this.lastWindowHeight; + if (cur_aspect < orig_aspect) + this.draw_width = this.draw_height * cur_aspect; + else if (cur_aspect > orig_aspect) + this.draw_height = this.draw_width / cur_aspect; + } + else if (mode === 3) + { + orig_aspect = this.original_width / this.original_height; + cur_aspect = this.lastWindowWidth / this.lastWindowHeight; + if (cur_aspect > orig_aspect) + this.draw_width = this.draw_height * cur_aspect; + else if (cur_aspect < orig_aspect) + this.draw_height = this.draw_width / cur_aspect; + } + } + } + if (this.canvasdiv && !this.isDomFree) + { + jQuery(this.canvasdiv).css({"width": Math.round(w) + "px", + "height": Math.round(h) + "px", + "margin-left": Math.floor(offx) + "px", + "margin-top": Math.floor(offy) + "px"}); + if (typeof cr_is_preview !== "undefined") + { + jQuery("#borderwrap").css({"width": Math.round(w) + "px", + "height": Math.round(h) + "px"}); + } + } + if (this.canvas) + { + this.canvas.width = Math.round(w * dpr); + this.canvas.height = Math.round(h * dpr); + if (this.isEjecta) + { + this.canvas.style.left = Math.floor(offx) + "px"; + this.canvas.style.top = Math.floor(offy) + "px"; + this.canvas.style.width = Math.round(w) + "px"; + this.canvas.style.height = Math.round(h) + "px"; + } + else if (this.isRetina && !this.isDomFree) + { + jQuery(this.canvas).css({"width": Math.round(w) + "px", + "height": Math.round(h) + "px"}); + } + } + if (this.overlay_canvas) + { + this.overlay_canvas.width = Math.round(w); + this.overlay_canvas.height = Math.round(h); + jQuery(this.overlay_canvas).css({"width": Math.round(w) + "px", + "height": Math.round(h) + "px"}); + } + if (this.glwrap) + { + this.glwrap.setSize(Math.round(w * dpr), Math.round(h * dpr)); + } + if (this.isDirectCanvas && this.ctx) + { + this.ctx.width = Math.round(w); + this.ctx.height = Math.round(h); + } + if (this.ctx) + { + this.ctx["webkitImageSmoothingEnabled"] = this.linearSampling; + this.ctx["mozImageSmoothingEnabled"] = this.linearSampling; + this.ctx["msImageSmoothingEnabled"] = this.linearSampling; + this.ctx["imageSmoothingEnabled"] = this.linearSampling; + } + this.tryLockOrientation(); + if (!this.isDomFree && (tryHideAddressBar || this.isiPhone)) + { + window.setTimeout(function () { + window.scrollTo(0, 1); + }, 100); + } + }; + Runtime.prototype.tryLockOrientation = function () + { + if (!this.autoLockOrientation || this.orientations === 0) + return; + var orientation = "portrait"; + if (this.orientations === 2) + orientation = "landscape"; + if (screen["orientation"] && screen["orientation"]["lock"]) + screen["orientation"]["lock"](orientation); + else if (screen["lockOrientation"]) + screen["lockOrientation"](orientation); + else if (screen["webkitLockOrientation"]) + screen["webkitLockOrientation"](orientation); + else if (screen["mozLockOrientation"]) + screen["mozLockOrientation"](orientation); + else if (screen["msLockOrientation"]) + screen["msLockOrientation"](orientation); + }; + Runtime.prototype.onContextLost = function () + { + this.glwrap.contextLost(); + this.is_WebGL_context_lost = true; + var i, len, t; + for (i = 0, len = this.types_by_index.length; i < len; i++) + { + t = this.types_by_index[i]; + if (t.onLostWebGLContext) + t.onLostWebGLContext(); + } + }; + Runtime.prototype.onContextRestored = function () + { + this.is_WebGL_context_lost = false; + var i, len, t; + for (i = 0, len = this.types_by_index.length; i < len; i++) + { + t = this.types_by_index[i]; + if (t.onRestoreWebGLContext) + t.onRestoreWebGLContext(); + } + }; + Runtime.prototype.positionOverlayCanvas = function() + { + if (this.isDomFree) + return; + var isfullscreen = (document["mozFullScreen"] || document["webkitIsFullScreen"] || document["fullScreen"] || !!document["msFullscreenElement"] || this.isNodeFullscreen) && !this.isCordova; + var overlay_position = isfullscreen ? jQuery(this.canvas).offset() : jQuery(this.canvas).position(); + overlay_position.position = "absolute"; + jQuery(this.overlay_canvas).css(overlay_position); + }; + var caf = window["cancelAnimationFrame"] || + window["mozCancelAnimationFrame"] || + window["webkitCancelAnimationFrame"] || + window["msCancelAnimationFrame"] || + window["oCancelAnimationFrame"]; + Runtime.prototype["setSuspended"] = function (s) + { + var i, len; + if (s && !this.isSuspended) + { + cr.logexport("[Construct 2] Suspending"); + this.isSuspended = true; // next tick will be last + if (this.raf_id !== -1 && caf) // note: CocoonJS does not implement cancelAnimationFrame + caf(this.raf_id); + if (this.timeout_id !== -1) + clearTimeout(this.timeout_id); + for (i = 0, len = this.suspend_events.length; i < len; i++) + this.suspend_events[i](true); + } + else if (!s && this.isSuspended) + { + cr.logexport("[Construct 2] Resuming"); + this.isSuspended = false; + this.last_tick_time = cr.performance_now(); // ensure first tick is a zero-dt one + this.last_fps_time = cr.performance_now(); // reset FPS counter + this.framecount = 0; + this.logictime = 0; + for (i = 0, len = this.suspend_events.length; i < len; i++) + this.suspend_events[i](false); + this.tick(false); // kick off runtime again + } + }; + Runtime.prototype.addSuspendCallback = function (f) + { + this.suspend_events.push(f); + }; + Runtime.prototype.GetObjectReference = function (i) + { +; + return this.objectRefTable[i]; + }; + Runtime.prototype.loadProject = function (data_response) + { +; + if (!data_response || !data_response["project"]) + cr.logerror("Project model unavailable"); + var pm = data_response["project"]; + this.name = pm[0]; + this.first_layout = pm[1]; + this.fullscreen_mode = pm[12]; // 0 = off, 1 = crop, 2 = scale inner, 3 = scale outer, 4 = letterbox scale, 5 = integer letterbox scale + this.fullscreen_mode_set = pm[12]; + this.original_width = pm[10]; + this.original_height = pm[11]; + this.parallax_x_origin = this.original_width / 2; + this.parallax_y_origin = this.original_height / 2; + if (this.isDomFree && !this.isEjecta && (pm[12] >= 4 || pm[12] === 0)) + { + cr.logexport("[Construct 2] Letterbox scale fullscreen modes are not supported on this platform - falling back to 'Scale outer'"); + this.fullscreen_mode = 3; + this.fullscreen_mode_set = 3; + } + this.uses_loader_layout = pm[18]; + this.loaderstyle = pm[19]; + if (this.loaderstyle === 0) + { + this.loaderlogo = new Image(); + this.loaderlogo.src = "loading-logo.png"; + } + this.next_uid = pm[21]; + this.objectRefTable = cr.getObjectRefTable(); + this.system = new cr.system_object(this); + var i, len, j, lenj, k, lenk, idstr, m, b, t, f, p; + var plugin, plugin_ctor; + for (i = 0, len = pm[2].length; i < len; i++) + { + m = pm[2][i]; + p = this.GetObjectReference(m[0]); +; + cr.add_common_aces(m, p.prototype); + plugin = new p(this); + plugin.singleglobal = m[1]; + plugin.is_world = m[2]; + plugin.must_predraw = m[9]; + if (plugin.onCreate) + plugin.onCreate(); // opportunity to override default ACEs + cr.seal(plugin); + this.plugins.push(plugin); + } + this.objectRefTable = cr.getObjectRefTable(); + for (i = 0, len = pm[3].length; i < len; i++) + { + m = pm[3][i]; + plugin_ctor = this.GetObjectReference(m[1]); +; + plugin = null; + for (j = 0, lenj = this.plugins.length; j < lenj; j++) + { + if (this.plugins[j] instanceof plugin_ctor) + { + plugin = this.plugins[j]; + break; + } + } +; +; + var type_inst = new plugin.Type(plugin); +; + type_inst.name = m[0]; + type_inst.is_family = m[2]; + type_inst.instvar_sids = m[3].slice(0); + type_inst.vars_count = m[3].length; + type_inst.behs_count = m[4]; + type_inst.fx_count = m[5]; + type_inst.sid = m[11]; + if (type_inst.is_family) + { + type_inst.members = []; // types in this family + type_inst.family_index = this.family_count++; + type_inst.families = null; + } + else + { + type_inst.members = null; + type_inst.family_index = -1; + type_inst.families = []; // families this type belongs to + } + type_inst.family_var_map = null; + type_inst.family_beh_map = null; + type_inst.family_fx_map = null; + type_inst.is_contained = false; + type_inst.container = null; + if (m[6]) + { + type_inst.texture_file = m[6][0]; + type_inst.texture_filesize = m[6][1]; + type_inst.texture_pixelformat = m[6][2]; + } + else + { + type_inst.texture_file = null; + type_inst.texture_filesize = 0; + type_inst.texture_pixelformat = 0; // rgba8 + } + if (m[7]) + { + type_inst.animations = m[7]; + } + else + { + type_inst.animations = null; + } + type_inst.index = i; // save index in to types array in type + type_inst.instances = []; // all instances of this type + type_inst.deadCache = []; // destroyed instances to recycle next create + type_inst.solstack = [new cr.selection(type_inst)]; // initialise SOL stack with one empty SOL + type_inst.cur_sol = 0; + type_inst.default_instance = null; + type_inst.default_layerindex = 0; + type_inst.stale_iids = true; + type_inst.updateIIDs = cr.type_updateIIDs; + type_inst.getFirstPicked = cr.type_getFirstPicked; + type_inst.getPairedInstance = cr.type_getPairedInstance; + type_inst.getCurrentSol = cr.type_getCurrentSol; + type_inst.pushCleanSol = cr.type_pushCleanSol; + type_inst.pushCopySol = cr.type_pushCopySol; + type_inst.popSol = cr.type_popSol; + type_inst.getBehaviorByName = cr.type_getBehaviorByName; + type_inst.getBehaviorIndexByName = cr.type_getBehaviorIndexByName; + type_inst.getEffectIndexByName = cr.type_getEffectIndexByName; + type_inst.applySolToContainer = cr.type_applySolToContainer; + type_inst.getInstanceByIID = cr.type_getInstanceByIID; + type_inst.collision_grid = new cr.SparseGrid(this.original_width, this.original_height); + type_inst.any_cell_changed = true; + type_inst.any_instance_parallaxed = false; + type_inst.extra = {}; + type_inst.toString = cr.type_toString; + type_inst.behaviors = []; + for (j = 0, lenj = m[8].length; j < lenj; j++) + { + b = m[8][j]; + var behavior_ctor = this.GetObjectReference(b[1]); + var behavior_plugin = null; + for (k = 0, lenk = this.behaviors.length; k < lenk; k++) + { + if (this.behaviors[k] instanceof behavior_ctor) + { + behavior_plugin = this.behaviors[k]; + break; + } + } + if (!behavior_plugin) + { + behavior_plugin = new behavior_ctor(this); + behavior_plugin.my_types = []; // types using this behavior + behavior_plugin.my_instances = new cr.ObjectSet(); // instances of this behavior + if (behavior_plugin.onCreate) + behavior_plugin.onCreate(); + cr.seal(behavior_plugin); + this.behaviors.push(behavior_plugin); + if (cr.behaviors.solid && behavior_plugin instanceof cr.behaviors.solid) + this.solidBehavior = behavior_plugin; + if (cr.behaviors.jumpthru && behavior_plugin instanceof cr.behaviors.jumpthru) + this.jumpthruBehavior = behavior_plugin; + if (cr.behaviors.shadowcaster && behavior_plugin instanceof cr.behaviors.shadowcaster) + this.shadowcasterBehavior = behavior_plugin; + } + if (behavior_plugin.my_types.indexOf(type_inst) === -1) + behavior_plugin.my_types.push(type_inst); + var behavior_type = new behavior_plugin.Type(behavior_plugin, type_inst); + behavior_type.name = b[0]; + behavior_type.sid = b[2]; + behavior_type.onCreate(); + cr.seal(behavior_type); + type_inst.behaviors.push(behavior_type); + } + type_inst.global = m[9]; + type_inst.isOnLoaderLayout = m[10]; + type_inst.effect_types = []; + for (j = 0, lenj = m[12].length; j < lenj; j++) + { + type_inst.effect_types.push({ + id: m[12][j][0], + name: m[12][j][1], + shaderindex: -1, + active: true, + index: j + }); + } + type_inst.tile_poly_data = m[13]; + if (!this.uses_loader_layout || type_inst.is_family || type_inst.isOnLoaderLayout || !plugin.is_world) + { + type_inst.onCreate(); + cr.seal(type_inst); + } + if (type_inst.name) + this.types[type_inst.name] = type_inst; + this.types_by_index.push(type_inst); + if (plugin.singleglobal) + { + var instance = new plugin.Instance(type_inst); + instance.uid = this.next_uid++; + instance.puid = this.next_puid++; + instance.iid = 0; + instance.get_iid = cr.inst_get_iid; + instance.toString = cr.inst_toString; + instance.properties = m[14]; + instance.onCreate(); + cr.seal(instance); + type_inst.instances.push(instance); + this.objectsByUid[instance.uid.toString()] = instance; + } + } + for (i = 0, len = pm[4].length; i < len; i++) + { + var familydata = pm[4][i]; + var familytype = this.types_by_index[familydata[0]]; + var familymember; + for (j = 1, lenj = familydata.length; j < lenj; j++) + { + familymember = this.types_by_index[familydata[j]]; + familymember.families.push(familytype); + familytype.members.push(familymember); + } + } + for (i = 0, len = pm[27].length; i < len; i++) + { + var containerdata = pm[27][i]; + var containertypes = []; + for (j = 0, lenj = containerdata.length; j < lenj; j++) + containertypes.push(this.types_by_index[containerdata[j]]); + for (j = 0, lenj = containertypes.length; j < lenj; j++) + { + containertypes[j].is_contained = true; + containertypes[j].container = containertypes; + } + } + if (this.family_count > 0) + { + for (i = 0, len = this.types_by_index.length; i < len; i++) + { + t = this.types_by_index[i]; + if (t.is_family || !t.families.length) + continue; + t.family_var_map = new Array(this.family_count); + t.family_beh_map = new Array(this.family_count); + t.family_fx_map = new Array(this.family_count); + var all_fx = []; + var varsum = 0; + var behsum = 0; + var fxsum = 0; + for (j = 0, lenj = t.families.length; j < lenj; j++) + { + f = t.families[j]; + t.family_var_map[f.family_index] = varsum; + varsum += f.vars_count; + t.family_beh_map[f.family_index] = behsum; + behsum += f.behs_count; + t.family_fx_map[f.family_index] = fxsum; + fxsum += f.fx_count; + for (k = 0, lenk = f.effect_types.length; k < lenk; k++) + all_fx.push(cr.shallowCopy({}, f.effect_types[k])); + } + t.effect_types = all_fx.concat(t.effect_types); + for (j = 0, lenj = t.effect_types.length; j < lenj; j++) + t.effect_types[j].index = j; + } + } + for (i = 0, len = pm[5].length; i < len; i++) + { + m = pm[5][i]; + var layout = new cr.layout(this, m); + cr.seal(layout); + this.layouts[layout.name] = layout; + this.layouts_by_index.push(layout); + } + for (i = 0, len = pm[6].length; i < len; i++) + { + m = pm[6][i]; + var sheet = new cr.eventsheet(this, m); + cr.seal(sheet); + this.eventsheets[sheet.name] = sheet; + this.eventsheets_by_index.push(sheet); + } + for (i = 0, len = this.eventsheets_by_index.length; i < len; i++) + this.eventsheets_by_index[i].postInit(); + for (i = 0, len = this.eventsheets_by_index.length; i < len; i++) + this.eventsheets_by_index[i].updateDeepIncludes(); + for (i = 0, len = this.triggers_to_postinit.length; i < len; i++) + this.triggers_to_postinit[i].postInit(); + this.triggers_to_postinit.length = 0; + this.audio_to_preload = pm[7]; + this.files_subfolder = pm[8]; + this.pixel_rounding = pm[9]; + this.aspect_scale = 1.0; + this.enableWebGL = pm[13]; + this.linearSampling = pm[14]; + this.alphaBackground = pm[15]; + this.versionstr = pm[16]; + this.useHighDpi = pm[17]; + this.orientations = pm[20]; // 0 = any, 1 = portrait, 2 = landscape + this.autoLockOrientation = (this.orientations > 0); + this.pauseOnBlur = pm[22]; + this.wantFullscreenScalingQuality = pm[23]; // false = low quality, true = high quality + this.fullscreenScalingQuality = this.wantFullscreenScalingQuality; + this.downscalingQuality = pm[24]; // 0 = low (mips off), 1 = medium (mips on, dense spritesheet), 2 = high (mips on, sparse spritesheet) + this.preloadSounds = pm[25]; // 0 = no, 1 = yes + this.projectName = pm[26]; + this.start_time = Date.now(); + this.objectRefTable.length = 0; + this.initRendererAndLoader(); + }; + var anyImageHadError = false; + Runtime.prototype.waitForImageLoad = function (img_, src_) + { + img_["cocoonLazyLoad"] = true; + img_.onerror = function (e) + { + img_.c2error = true; + anyImageHadError = true; + if (console && console.error) + console.error("Error loading image '" + img_.src + "': ", e); + }; + if (this.isEjecta) + { + img_.src = src_; + } + else if (!img_.src) + { + if (typeof XAPKReader !== "undefined") + { + XAPKReader.get(src_, function (expanded_url) + { + img_.src = expanded_url; + }, function (e) + { + img_.c2error = true; + anyImageHadError = true; + if (console && console.error) + console.error("Error extracting image '" + src_ + "' from expansion file: ", e); + }); + } + else + { + img_.src = src_; + } + } + this.wait_for_textures.push(img_); + }; + Runtime.prototype.findWaitingTexture = function (src_) + { + var i, len; + for (i = 0, len = this.wait_for_textures.length; i < len; i++) + { + if (this.wait_for_textures[i].cr_src === src_) + return this.wait_for_textures[i]; + } + return null; + }; + var audio_preload_totalsize = 0; + var audio_preload_started = false; + Runtime.prototype.getready = function () + { + if (!this.audioInstance) + return; + audio_preload_totalsize = this.audioInstance.setPreloadList(this.audio_to_preload); + }; + Runtime.prototype.areAllTexturesAndSoundsLoaded = function () + { + var totalsize = audio_preload_totalsize; + var completedsize = 0; + var audiocompletedsize = 0; + var ret = true; + var i, len, img; + for (i = 0, len = this.wait_for_textures.length; i < len; i++) + { + img = this.wait_for_textures[i]; + var filesize = img.cr_filesize; + if (!filesize || filesize <= 0) + filesize = 50000; + totalsize += filesize; + if (!!img.src && (img.complete || img["loaded"]) && !img.c2error) + completedsize += filesize; + else + ret = false; // not all textures loaded + } + if (ret && this.preloadSounds && this.audioInstance) + { + if (!audio_preload_started) + { + this.audioInstance.startPreloads(); + audio_preload_started = true; + } + audiocompletedsize = this.audioInstance.getPreloadedSize(); + completedsize += audiocompletedsize; + if (audiocompletedsize < audio_preload_totalsize) + ret = false; // not done yet + } + if (totalsize == 0) + this.progress = 0; + else + this.progress = (completedsize / totalsize); + return ret; + }; + Runtime.prototype.go = function () + { + if (!this.ctx && !this.glwrap) + return; + var ctx = this.ctx || this.overlay_ctx; + if (this.overlay_canvas) + this.positionOverlayCanvas(); + this.progress = 0; + this.last_progress = -1; + if (this.areAllTexturesAndSoundsLoaded()) + this.go_loading_finished(); + else + { + var ms_elapsed = Date.now() - this.start_time; + if (ctx) + { + var overlay_width = this.width; + var overlay_height = this.height; + var multiplier = this.devicePixelRatio; + if (this.overlay_canvas) + { + overlay_width = this.cssWidth; + overlay_height = this.cssHeight; + multiplier = 1; + } + if (this.loaderstyle !== 3 && (this.isCocoonJs || (ms_elapsed >= 500 && this.last_progress != this.progress))) + { + ctx.clearRect(0, 0, overlay_width, overlay_height); + var mx = overlay_width / 2; + var my = overlay_height / 2; + var haslogo = (this.loaderstyle === 0 && this.loaderlogo.complete); + var hlw = 40 * multiplier; + var hlh = 0; + var logowidth = 80 * multiplier; + var logoheight; + if (haslogo) + { + logowidth = this.loaderlogo.width * multiplier; + logoheight = this.loaderlogo.height * multiplier; + hlw = logowidth / 2; + hlh = logoheight / 2; + ctx.drawImage(this.loaderlogo, cr.floor(mx - hlw), cr.floor(my - hlh), logowidth, logoheight); + } + if (this.loaderstyle <= 1) + { + my += hlh + (haslogo ? 12 * multiplier : 0); + mx -= hlw; + mx = cr.floor(mx) + 0.5; + my = cr.floor(my) + 0.5; + ctx.fillStyle = anyImageHadError ? "red" : "DodgerBlue"; + ctx.fillRect(mx, my, Math.floor(logowidth * this.progress), 6 * multiplier); + ctx.strokeStyle = "black"; + ctx.strokeRect(mx, my, logowidth, 6 * multiplier); + ctx.strokeStyle = "white"; + ctx.strokeRect(mx - 1 * multiplier, my - 1 * multiplier, logowidth + 2 * multiplier, 8 * multiplier); + } + else if (this.loaderstyle === 2) + { + ctx.font = (this.isEjecta ? "12pt ArialMT" : "12pt Arial"); + ctx.fillStyle = anyImageHadError ? "#f00" : "#999"; + ctx.textBaseLine = "middle"; + var percent_text = Math.round(this.progress * 100) + "%"; + var text_dim = ctx.measureText ? ctx.measureText(percent_text) : null; + var text_width = text_dim ? text_dim.width : 0; + ctx.fillText(percent_text, mx - (text_width / 2), my); + } + } + this.last_progress = this.progress; + } + setTimeout((function (self) { return function () { self.go(); }; })(this), (this.isCocoonJs ? 10 : 100)); + } + }; + Runtime.prototype.go_loading_finished = function () + { + if (this.overlay_canvas) + { + this.canvas.parentNode.removeChild(this.overlay_canvas); + this.overlay_ctx = null; + this.overlay_canvas = null; + } + this.start_time = Date.now(); + this.last_fps_time = cr.performance_now(); // for counting framerate + var i, len, t; + if (this.uses_loader_layout) + { + for (i = 0, len = this.types_by_index.length; i < len; i++) + { + t = this.types_by_index[i]; + if (!t.is_family && !t.isOnLoaderLayout && t.plugin.is_world) + { + t.onCreate(); + cr.seal(t); + } + } + } + else + this.isloading = false; + for (i = 0, len = this.layouts_by_index.length; i < len; i++) + { + this.layouts_by_index[i].createGlobalNonWorlds(); + } + if (this.fullscreen_mode >= 2) + { + var orig_aspect = this.original_width / this.original_height; + var cur_aspect = this.width / this.height; + if ((this.fullscreen_mode !== 2 && cur_aspect > orig_aspect) || (this.fullscreen_mode === 2 && cur_aspect < orig_aspect)) + this.aspect_scale = this.height / this.original_height; + else + this.aspect_scale = this.width / this.original_width; + } + if (this.first_layout) + this.layouts[this.first_layout].startRunning(); + else + this.layouts_by_index[0].startRunning(); +; + if (!this.uses_loader_layout) + { + this.loadingprogress = 1; + this.trigger(cr.system_object.prototype.cnds.OnLoadFinished, null); + } + if (navigator["splashscreen"] && navigator["splashscreen"]["hide"]) + navigator["splashscreen"]["hide"](); + for (i = 0, len = this.types_by_index.length; i < len; i++) + { + t = this.types_by_index[i]; + if (t.onAppBegin) + t.onAppBegin(); + } + if (document["hidden"] || document["webkitHidden"] || document["mozHidden"] || document["msHidden"]) + { + window["cr_setSuspended"](true); // stop rendering + } + else + { + this.tick(false); + } + if (this.isDirectCanvas) + AppMobi["webview"]["execute"]("onGameReady();"); + }; + var raf = window["requestAnimationFrame"] || + window["mozRequestAnimationFrame"] || + window["webkitRequestAnimationFrame"] || + window["msRequestAnimationFrame"] || + window["oRequestAnimationFrame"]; + Runtime.prototype.tick = function (background_wake) + { + if (!this.running_layout) + return; + var logic_start = cr.performance_now(); + if (this.halfFramerateMode && this.ranLastRaf) + { + if (logic_start - this.lastRafTime < 29) + { + this.ranLastRaf = false; + this.lastRafTime = logic_start; + if (raf) + this.raf_id = raf(this.tickFunc, this.canvas); + else // no idea if this works without raf/hi res timers but let's hope for the best + this.timeout_id = setTimeout(this.tickFunc, this.isMobile ? 1 : 16); + return; // skipped this frame + } + } + this.ranLastRaf = true; + this.lastRafTime = logic_start; + var fsmode = this.fullscreen_mode; + var isfullscreen = (document["mozFullScreen"] || document["webkitIsFullScreen"] || document["fullScreen"] || !!document["msFullscreenElement"]) && !this.isCordova; + if ((isfullscreen || this.isNodeFullscreen) && this.fullscreen_scaling > 0) + fsmode = this.fullscreen_scaling; + if (fsmode > 0 && (!this.isiOS || window.self !== window.top)) + { + var curwidth = window.innerWidth; + var curheight = window.innerHeight; + if (this.lastWindowWidth !== curwidth || this.lastWindowHeight !== curheight) + { + this["setSize"](window_innerWidth(), window_innerHeight()); + } + } + if (!this.isDomFree) + { + if (isfullscreen) + { + if (!this.firstInFullscreen) + { + this.fullscreenOldMarginCss = jQuery(this.canvas).css("margin") || "0"; + this.firstInFullscreen = true; + } + if (!this.isChrome && !this.isNodeWebkit) + { + jQuery(this.canvas).css({ + "margin-left": "" + Math.floor((screen.width - (this.width / this.devicePixelRatio)) / 2) + "px", + "margin-top": "" + Math.floor((screen.height - (this.height / this.devicePixelRatio)) / 2) + "px" + }); + } + } + else + { + if (this.firstInFullscreen) + { + if (!this.isChrome && !this.isNodeWebkit) + { + jQuery(this.canvas).css("margin", this.fullscreenOldMarginCss); + } + this.fullscreenOldMarginCss = ""; + this.firstInFullscreen = false; + if (this.fullscreen_mode === 0) + { + this["setSize"](Math.round(this.oldWidth / this.devicePixelRatio), Math.round(this.oldHeight / this.devicePixelRatio), true); + } + } + else + { + this.oldWidth = this.width; + this.oldHeight = this.height; + } + } + } + if (this.isloading) + { + var done = this.areAllTexturesAndSoundsLoaded(); // updates this.progress + this.loadingprogress = this.progress; + if (done) + { + this.isloading = false; + this.progress = 1; + this.trigger(cr.system_object.prototype.cnds.OnLoadFinished, null); + } + } + this.logic(); + if ((this.redraw || this.isCocoonJs) && !this.is_WebGL_context_lost && !this.suspendDrawing && !background_wake) + { + this.redraw = false; + if (this.glwrap) + this.drawGL(); + else + this.draw(); + if (this.snapshotCanvas) + { + if (this.canvas && this.canvas.toDataURL) + { + this.snapshotData = this.canvas.toDataURL(this.snapshotCanvas[0], this.snapshotCanvas[1]); + this.trigger(cr.system_object.prototype.cnds.OnCanvasSnapshot, null); + } + this.snapshotCanvas = null; + } + } + if (!this.hit_breakpoint) + { + this.tickcount++; + this.execcount++; + this.framecount++; + } + this.logictime += cr.performance_now() - logic_start; + if (this.isSuspended || background_wake) + return; + if (raf) + this.raf_id = raf(this.tickFunc, this.canvas); + else + { + this.timeout_id = setTimeout(this.tickFunc, this.isMobile ? 1 : 16); + } + }; + Runtime.prototype.logic = function () + { + var i, leni, j, lenj, k, lenk, type, inst, binst; + var cur_time = cr.performance_now(); + if (cur_time - this.last_fps_time >= 1000) // every 1 second + { + this.last_fps_time += 1000; + if (cur_time - this.last_fps_time >= 1000) + this.last_fps_time = cur_time; + this.fps = this.framecount; + this.framecount = 0; + this.cpuutilisation = this.logictime; + this.logictime = 0; + } + if (this.measuring_dt) + { + if (this.last_tick_time !== 0) + { + var ms_diff = cur_time - this.last_tick_time; + if (ms_diff === 0 && !this.isDebug) + { + this.zeroDtCount++; + if (this.zeroDtCout >= 10) + this.measuring_dt = false; + this.dt1 = 1.0 / 60.0; // 60fps assumed (0.01666...) + } + else + { + this.dt1 = ms_diff / 1000.0; // dt measured in seconds + if (this.dt1 > 0.5) + this.dt1 = 0; + else if (this.dt1 > 0.1) + this.dt1 = 0.1; + } + } + this.last_tick_time = cur_time; + } + this.dt = this.dt1 * this.timescale; + this.kahanTime.add(this.dt); + this.wallTime.add(this.dt1); + var isfullscreen = (document["mozFullScreen"] || document["webkitIsFullScreen"] || document["fullScreen"] || !!document["msFullscreenElement"] || this.isNodeFullscreen) && !this.isCordova; + if (this.fullscreen_mode >= 2 /* scale */ || (isfullscreen && this.fullscreen_scaling > 0)) + { + var orig_aspect = this.original_width / this.original_height; + var cur_aspect = this.width / this.height; + var mode = this.fullscreen_mode; + if (isfullscreen && this.fullscreen_scaling > 0) + mode = this.fullscreen_scaling; + if ((mode !== 2 && cur_aspect > orig_aspect) || (mode === 2 && cur_aspect < orig_aspect)) + { + this.aspect_scale = this.height / this.original_height; + } + else + { + this.aspect_scale = this.width / this.original_width; + } + if (this.running_layout) + { + this.running_layout.scrollToX(this.running_layout.scrollX); + this.running_layout.scrollToY(this.running_layout.scrollY); + } + } + else + this.aspect_scale = (this.isRetina ? this.devicePixelRatio : 1); + this.ClearDeathRow(); + this.isInOnDestroy++; + this.system.runWaits(); // prevent instance list changing + this.isInOnDestroy--; + this.ClearDeathRow(); // allow instance list changing + this.isInOnDestroy++; + var tickarr = this.objects_to_pretick.valuesRef(); + for (i = 0, leni = tickarr.length; i < leni; i++) + tickarr[i].pretick(); + for (i = 0, leni = this.types_by_index.length; i < leni; i++) + { + type = this.types_by_index[i]; + if (type.is_family || (!type.behaviors.length && !type.families.length)) + continue; + for (j = 0, lenj = type.instances.length; j < lenj; j++) + { + inst = type.instances[j]; + for (k = 0, lenk = inst.behavior_insts.length; k < lenk; k++) + { + inst.behavior_insts[k].tick(); + } + } + } + for (i = 0, leni = this.types_by_index.length; i < leni; i++) + { + type = this.types_by_index[i]; + if (type.is_family || (!type.behaviors.length && !type.families.length)) + continue; // type doesn't have any behaviors + for (j = 0, lenj = type.instances.length; j < lenj; j++) + { + inst = type.instances[j]; + for (k = 0, lenk = inst.behavior_insts.length; k < lenk; k++) + { + binst = inst.behavior_insts[k]; + if (binst.posttick) + binst.posttick(); + } + } + } + tickarr = this.objects_to_tick.valuesRef(); + for (i = 0, leni = tickarr.length; i < leni; i++) + tickarr[i].tick(); + this.isInOnDestroy--; // end preventing instance lists from being changed + this.handleSaveLoad(); // save/load now if queued + i = 0; + while (this.changelayout && i++ < 10) + { + this.doChangeLayout(this.changelayout); + } + for (i = 0, leni = this.eventsheets_by_index.length; i < leni; i++) + this.eventsheets_by_index[i].hasRun = false; + if (this.running_layout.event_sheet) + this.running_layout.event_sheet.run(); + this.registered_collisions.length = 0; + this.layout_first_tick = false; + this.isInOnDestroy++; // prevent instance lists from being changed + for (i = 0, leni = this.types_by_index.length; i < leni; i++) + { + type = this.types_by_index[i]; + if (type.is_family || (!type.behaviors.length && !type.families.length)) + continue; // type doesn't have any behaviors + for (j = 0, lenj = type.instances.length; j < lenj; j++) + { + var inst = type.instances[j]; + for (k = 0, lenk = inst.behavior_insts.length; k < lenk; k++) + { + binst = inst.behavior_insts[k]; + if (binst.tick2) + binst.tick2(); + } + } + } + tickarr = this.objects_to_tick2.valuesRef(); + for (i = 0, leni = tickarr.length; i < leni; i++) + tickarr[i].tick2(); + this.isInOnDestroy--; // end preventing instance lists from being changed + }; + Runtime.prototype.doChangeLayout = function (changeToLayout) + { +; + var prev_layout = this.running_layout; + this.running_layout.stopRunning(); + var i, len, j, lenj, k, lenk, type, inst, binst; + if (this.glwrap) + { + for (i = 0, len = this.types_by_index.length; i < len; i++) + { + type = this.types_by_index[i]; + if (type.is_family) + continue; + if (type.unloadTextures && (!type.global || type.instances.length === 0) && changeToLayout.initial_types.indexOf(type) === -1) + { + type.unloadTextures(); + } + } + } + if (prev_layout == changeToLayout) + this.system.waits.length = 0; + changeToLayout.startRunning(); + for (i = 0, len = this.types_by_index.length; i < len; i++) + { + type = this.types_by_index[i]; + if (!type.global && !type.plugin.singleglobal) + continue; + for (j = 0, lenj = type.instances.length; j < lenj; j++) + { + inst = type.instances[j]; + if (inst.onLayoutChange) + inst.onLayoutChange(); + if (inst.behavior_insts) + { + for (k = 0, lenk = inst.behavior_insts.length; k < lenk; k++) + { + binst = inst.behavior_insts[k]; + if (binst.onLayoutChange) + binst.onLayoutChange(); + } + } + } + } + this.redraw = true; + this.layout_first_tick = true; + this.ClearDeathRow(); + }; + Runtime.prototype.pretickMe = function (inst) + { + this.objects_to_pretick.add(inst); + }; + Runtime.prototype.unpretickMe = function (inst) + { + this.objects_to_pretick.remove(inst); + }; + Runtime.prototype.tickMe = function (inst) + { + this.objects_to_tick.add(inst); + }; + Runtime.prototype.untickMe = function (inst) + { + this.objects_to_tick.remove(inst); + }; + Runtime.prototype.tick2Me = function (inst) + { + this.objects_to_tick2.add(inst); + }; + Runtime.prototype.untick2Me = function (inst) + { + this.objects_to_tick2.remove(inst); + }; + Runtime.prototype.getDt = function (inst) + { + if (!inst || inst.my_timescale === -1.0) + return this.dt; + return this.dt1 * inst.my_timescale; + }; + Runtime.prototype.draw = function () + { + this.running_layout.draw(this.ctx); + if (this.isDirectCanvas) + this.ctx["present"](); + }; + Runtime.prototype.drawGL = function () + { + this.running_layout.drawGL(this.glwrap); + this.glwrap.present(); + }; + Runtime.prototype.addDestroyCallback = function (f) + { + if (f) + this.destroycallbacks.push(f); + }; + Runtime.prototype.removeDestroyCallback = function (f) + { + cr.arrayFindRemove(this.destroycallbacks, f); + }; + Runtime.prototype.getObjectByUID = function (uid_) + { +; + var uidstr = uid_.toString(); + if (this.objectsByUid.hasOwnProperty(uidstr)) + return this.objectsByUid[uidstr]; + else + return null; + }; + var objectset_cache = []; + function alloc_objectset() + { + if (objectset_cache.length) + return objectset_cache.pop(); + else + return new cr.ObjectSet(); + }; + function free_objectset(s) + { + s.clear(); + objectset_cache.push(s); + }; + Runtime.prototype.DestroyInstance = function (inst) + { + var i, len; + var type = inst.type; + var typename = type.name; + var has_typename = this.deathRow.hasOwnProperty(typename); + var obj_set = null; + if (has_typename) + { + obj_set = this.deathRow[typename]; + if (obj_set.contains(inst)) + return; // already had DestroyInstance called + } + else + { + obj_set = alloc_objectset(); + this.deathRow[typename] = obj_set; + } + obj_set.add(inst); + this.hasPendingInstances = true; + if (inst.is_contained) + { + for (i = 0, len = inst.siblings.length; i < len; i++) + { + this.DestroyInstance(inst.siblings[i]); + } + } + if (this.isInClearDeathRow) + obj_set.values_cache.push(inst); + this.isInOnDestroy++; // support recursion + this.trigger(Object.getPrototypeOf(inst.type.plugin).cnds.OnDestroyed, inst); + this.isInOnDestroy--; + }; + Runtime.prototype.ClearDeathRow = function () + { + if (!this.hasPendingInstances) + return; + var inst, type, instances; + var i, j, leni, lenj, obj_set; + this.isInClearDeathRow = true; + for (i = 0, leni = this.createRow.length; i < leni; ++i) + { + inst = this.createRow[i]; + type = inst.type; + type.instances.push(inst); + for (j = 0, lenj = type.families.length; j < lenj; ++j) + { + type.families[j].instances.push(inst); + type.families[j].stale_iids = true; + } + } + this.createRow.length = 0; + this.IterateDeathRow(); // moved to separate function so for-in performance doesn't hobble entire function + cr.wipe(this.deathRow); // all objectsets have already been recycled + this.isInClearDeathRow = false; + this.hasPendingInstances = false; + }; + Runtime.prototype.IterateDeathRow = function () + { + for (var p in this.deathRow) + { + if (this.deathRow.hasOwnProperty(p)) + { + this.ClearDeathRowForType(this.deathRow[p]); + } + } + }; + Runtime.prototype.ClearDeathRowForType = function (obj_set) + { + var arr = obj_set.valuesRef(); // get array of items from set +; + var type = arr[0].type; +; +; + var i, len, j, lenj, w, f, layer_instances, inst; + cr.arrayRemoveAllFromObjectSet(type.instances, obj_set); + type.stale_iids = true; + if (type.instances.length === 0) + type.any_instance_parallaxed = false; + for (i = 0, len = type.families.length; i < len; ++i) + { + f = type.families[i]; + cr.arrayRemoveAllFromObjectSet(f.instances, obj_set); + f.stale_iids = true; + } + for (i = 0, len = this.system.waits.length; i < len; ++i) + { + w = this.system.waits[i]; + if (w.sols.hasOwnProperty(type.index)) + cr.arrayRemoveAllFromObjectSet(w.sols[type.index].insts, obj_set); + if (!type.is_family) + { + for (j = 0, lenj = type.families.length; j < lenj; ++j) + { + f = type.families[j]; + if (w.sols.hasOwnProperty(f.index)) + cr.arrayRemoveAllFromObjectSet(w.sols[f.index].insts, obj_set); + } + } + } + var first_layer = arr[0].layer; + if (first_layer) + { + if (first_layer.useRenderCells) + { + layer_instances = first_layer.instances; + for (i = 0, len = layer_instances.length; i < len; ++i) + { + inst = layer_instances[i]; + if (!obj_set.contains(inst)) + continue; // not destroying this instance + inst.update_bbox(); + first_layer.render_grid.update(inst, inst.rendercells, null); + inst.rendercells.set(0, 0, -1, -1); + } + } + cr.arrayRemoveAllFromObjectSet(first_layer.instances, obj_set); + first_layer.setZIndicesStaleFrom(0); + } + for (i = 0; i < arr.length; ++i) // check array length every time in case it changes + { + this.ClearDeathRowForSingleInstance(arr[i], type); + } + free_objectset(obj_set); + this.redraw = true; + }; + Runtime.prototype.ClearDeathRowForSingleInstance = function (inst, type) + { + var i, len, binst; + for (i = 0, len = this.destroycallbacks.length; i < len; ++i) + this.destroycallbacks[i](inst); + if (inst.collcells) + { + type.collision_grid.update(inst, inst.collcells, null); + } + var layer = inst.layer; + if (layer) + { + layer.removeFromInstanceList(inst, true); // remove from both instance list and render grid + } + if (inst.behavior_insts) + { + for (i = 0, len = inst.behavior_insts.length; i < len; ++i) + { + binst = inst.behavior_insts[i]; + if (binst.onDestroy) + binst.onDestroy(); + binst.behavior.my_instances.remove(inst); + } + } + this.objects_to_pretick.remove(inst); + this.objects_to_tick.remove(inst); + this.objects_to_tick2.remove(inst); + if (inst.onDestroy) + inst.onDestroy(); + if (this.objectsByUid.hasOwnProperty(inst.uid.toString())) + delete this.objectsByUid[inst.uid.toString()]; + this.objectcount--; + if (type.deadCache.length < 100) + type.deadCache.push(inst); + }; + Runtime.prototype.createInstance = function (type, layer, sx, sy) + { + if (type.is_family) + { + var i = cr.floor(Math.random() * type.members.length); + return this.createInstance(type.members[i], layer, sx, sy); + } + if (!type.default_instance) + { + return null; + } + return this.createInstanceFromInit(type.default_instance, layer, false, sx, sy, false); + }; + var all_behaviors = []; + Runtime.prototype.createInstanceFromInit = function (initial_inst, layer, is_startup_instance, sx, sy, skip_siblings) + { + var i, len, j, lenj, p, effect_fallback, x, y; + if (!initial_inst) + return null; + var type = this.types_by_index[initial_inst[1]]; +; +; + var is_world = type.plugin.is_world; +; + if (this.isloading && is_world && !type.isOnLoaderLayout) + return null; + if (is_world && !this.glwrap && initial_inst[0][11] === 11) + return null; + var original_layer = layer; + if (!is_world) + layer = null; + var inst; + if (type.deadCache.length) + { + inst = type.deadCache.pop(); + inst.recycled = true; + type.plugin.Instance.call(inst, type); + } + else + { + inst = new type.plugin.Instance(type); + inst.recycled = false; + } + if (is_startup_instance && !skip_siblings) + inst.uid = initial_inst[2]; + else + inst.uid = this.next_uid++; + this.objectsByUid[inst.uid.toString()] = inst; + inst.puid = this.next_puid++; + inst.iid = type.instances.length; + for (i = 0, len = this.createRow.length; i < len; ++i) + { + if (this.createRow[i].type === type) + inst.iid++; + } + inst.get_iid = cr.inst_get_iid; + inst.toString = cr.inst_toString; + var initial_vars = initial_inst[3]; + if (inst.recycled) + { + cr.wipe(inst.extra); + } + else + { + inst.extra = {}; + if (typeof cr_is_preview !== "undefined") + { + inst.instance_var_names = []; + inst.instance_var_names.length = initial_vars.length; + for (i = 0, len = initial_vars.length; i < len; i++) + inst.instance_var_names[i] = initial_vars[i][1]; + } + inst.instance_vars = []; + inst.instance_vars.length = initial_vars.length; + } + for (i = 0, len = initial_vars.length; i < len; i++) + inst.instance_vars[i] = initial_vars[i][0]; + if (is_world) + { + var wm = initial_inst[0]; +; + inst.x = cr.is_undefined(sx) ? wm[0] : sx; + inst.y = cr.is_undefined(sy) ? wm[1] : sy; + inst.z = wm[2]; + inst.width = wm[3]; + inst.height = wm[4]; + inst.depth = wm[5]; + inst.angle = wm[6]; + inst.opacity = wm[7]; + inst.hotspotX = wm[8]; + inst.hotspotY = wm[9]; + inst.blend_mode = wm[10]; + effect_fallback = wm[11]; + if (!this.glwrap && type.effect_types.length) // no WebGL renderer and shaders used + inst.blend_mode = effect_fallback; // use fallback blend mode - destroy mode was handled above + inst.compositeOp = cr.effectToCompositeOp(inst.blend_mode); + if (this.gl) + cr.setGLBlend(inst, inst.blend_mode, this.gl); + if (inst.recycled) + { + for (i = 0, len = wm[12].length; i < len; i++) + { + for (j = 0, lenj = wm[12][i].length; j < lenj; j++) + inst.effect_params[i][j] = wm[12][i][j]; + } + inst.bbox.set(0, 0, 0, 0); + inst.collcells.set(0, 0, -1, -1); + inst.rendercells.set(0, 0, -1, -1); + inst.bquad.set_from_rect(inst.bbox); + inst.bbox_changed_callbacks.length = 0; + } + else + { + inst.effect_params = wm[12].slice(0); + for (i = 0, len = inst.effect_params.length; i < len; i++) + inst.effect_params[i] = wm[12][i].slice(0); + inst.active_effect_types = []; + inst.active_effect_flags = []; + inst.active_effect_flags.length = type.effect_types.length; + inst.bbox = new cr.rect(0, 0, 0, 0); + inst.collcells = new cr.rect(0, 0, -1, -1); + inst.rendercells = new cr.rect(0, 0, -1, -1); + inst.bquad = new cr.quad(); + inst.bbox_changed_callbacks = []; + inst.set_bbox_changed = cr.set_bbox_changed; + inst.add_bbox_changed_callback = cr.add_bbox_changed_callback; + inst.contains_pt = cr.inst_contains_pt; + inst.update_bbox = cr.update_bbox; + inst.update_render_cell = cr.update_render_cell; + inst.update_collision_cell = cr.update_collision_cell; + inst.get_zindex = cr.inst_get_zindex; + } + inst.tilemap_exists = false; + inst.tilemap_width = 0; + inst.tilemap_height = 0; + inst.tilemap_data = null; + if (wm.length === 14) + { + inst.tilemap_exists = true; + inst.tilemap_width = wm[13][0]; + inst.tilemap_height = wm[13][1]; + inst.tilemap_data = wm[13][2]; + } + for (i = 0, len = type.effect_types.length; i < len; i++) + inst.active_effect_flags[i] = true; + inst.updateActiveEffects = cr.inst_updateActiveEffects; + inst.updateActiveEffects(); + inst.uses_shaders = !!inst.active_effect_types.length; + inst.bbox_changed = true; + inst.cell_changed = true; + type.any_cell_changed = true; + inst.visible = true; + inst.my_timescale = -1.0; + inst.layer = layer; + inst.zindex = layer.instances.length; // will be placed at top of current layer + if (typeof inst.collision_poly === "undefined") + inst.collision_poly = null; + inst.collisionsEnabled = true; + this.redraw = true; + } + var initial_props, binst; + all_behaviors.length = 0; + for (i = 0, len = type.families.length; i < len; i++) + { + all_behaviors.push.apply(all_behaviors, type.families[i].behaviors); + } + all_behaviors.push.apply(all_behaviors, type.behaviors); + if (inst.recycled) + { + for (i = 0, len = all_behaviors.length; i < len; i++) + { + var btype = all_behaviors[i]; + binst = inst.behavior_insts[i]; + binst.recycled = true; + btype.behavior.Instance.call(binst, btype, inst); + initial_props = initial_inst[4][i]; + for (j = 0, lenj = initial_props.length; j < lenj; j++) + binst.properties[j] = initial_props[j]; + binst.onCreate(); + btype.behavior.my_instances.add(inst); + } + } + else + { + inst.behavior_insts = []; + for (i = 0, len = all_behaviors.length; i < len; i++) + { + var btype = all_behaviors[i]; + var binst = new btype.behavior.Instance(btype, inst); + binst.recycled = false; + binst.properties = initial_inst[4][i].slice(0); + binst.onCreate(); + cr.seal(binst); + inst.behavior_insts.push(binst); + btype.behavior.my_instances.add(inst); + } + } + initial_props = initial_inst[5]; + if (inst.recycled) + { + for (i = 0, len = initial_props.length; i < len; i++) + inst.properties[i] = initial_props[i]; + } + else + inst.properties = initial_props.slice(0); + this.createRow.push(inst); + this.hasPendingInstances = true; + if (layer) + { +; + layer.appendToInstanceList(inst, true); + if (layer.parallaxX !== 1 || layer.parallaxY !== 1) + type.any_instance_parallaxed = true; + } + this.objectcount++; + if (type.is_contained) + { + inst.is_contained = true; + if (inst.recycled) + inst.siblings.length = 0; + else + inst.siblings = []; // note: should not include self in siblings + if (!is_startup_instance && !skip_siblings) // layout links initial instances + { + for (i = 0, len = type.container.length; i < len; i++) + { + if (type.container[i] === type) + continue; + if (!type.container[i].default_instance) + { + return null; + } + inst.siblings.push(this.createInstanceFromInit(type.container[i].default_instance, original_layer, false, is_world ? inst.x : sx, is_world ? inst.y : sy, true)); + } + for (i = 0, len = inst.siblings.length; i < len; i++) + { + inst.siblings[i].siblings.push(inst); + for (j = 0; j < len; j++) + { + if (i !== j) + inst.siblings[i].siblings.push(inst.siblings[j]); + } + } + } + } + else + { + inst.is_contained = false; + inst.siblings = null; + } + inst.onCreate(); + if (!inst.recycled) + cr.seal(inst); + for (i = 0, len = inst.behavior_insts.length; i < len; i++) + { + if (inst.behavior_insts[i].postCreate) + inst.behavior_insts[i].postCreate(); + } + return inst; + }; + Runtime.prototype.getLayerByName = function (layer_name) + { + var i, len; + for (i = 0, len = this.running_layout.layers.length; i < len; i++) + { + var layer = this.running_layout.layers[i]; + if (cr.equals_nocase(layer.name, layer_name)) + return layer; + } + return null; + }; + Runtime.prototype.getLayerByNumber = function (index) + { + index = cr.floor(index); + if (index < 0) + index = 0; + if (index >= this.running_layout.layers.length) + index = this.running_layout.layers.length - 1; + return this.running_layout.layers[index]; + }; + Runtime.prototype.getLayer = function (l) + { + if (cr.is_number(l)) + return this.getLayerByNumber(l); + else + return this.getLayerByName(l.toString()); + }; + Runtime.prototype.clearSol = function (solModifiers) + { + var i, len; + for (i = 0, len = solModifiers.length; i < len; i++) + { + solModifiers[i].getCurrentSol().select_all = true; + } + }; + Runtime.prototype.pushCleanSol = function (solModifiers) + { + var i, len; + for (i = 0, len = solModifiers.length; i < len; i++) + { + solModifiers[i].pushCleanSol(); + } + }; + Runtime.prototype.pushCopySol = function (solModifiers) + { + var i, len; + for (i = 0, len = solModifiers.length; i < len; i++) + { + solModifiers[i].pushCopySol(); + } + }; + Runtime.prototype.popSol = function (solModifiers) + { + var i, len; + for (i = 0, len = solModifiers.length; i < len; i++) + { + solModifiers[i].popSol(); + } + }; + Runtime.prototype.updateAllCells = function (type) + { + if (!type.any_cell_changed) + return; // all instances must already be up-to-date + var i, len, instances = type.instances; + for (i = 0, len = instances.length; i < len; ++i) + { + instances[i].update_collision_cell(); + } + var createRow = this.createRow; + for (i = 0, len = createRow.length; i < len; ++i) + { + if (createRow[i].type === type) + createRow[i].update_collision_cell(); + } + type.any_cell_changed = false; + }; + Runtime.prototype.getCollisionCandidates = function (layer, rtype, bbox, candidates) + { + var i, len, t; + var is_parallaxed = (layer ? (layer.parallaxX !== 1 || layer.parallaxY !== 1) : false); + if (rtype.is_family) + { + for (i = 0, len = rtype.members.length; i < len; ++i) + { + t = rtype.members[i]; + if (is_parallaxed || t.any_instance_parallaxed) + { + cr.appendArray(candidates, t.instances); + } + else + { + this.updateAllCells(t); + t.collision_grid.queryRange(bbox, candidates); + } + } + } + else + { + if (is_parallaxed || rtype.any_instance_parallaxed) + { + cr.appendArray(candidates, rtype.instances); + } + else + { + this.updateAllCells(rtype); + rtype.collision_grid.queryRange(bbox, candidates); + } + } + }; + Runtime.prototype.getTypesCollisionCandidates = function (layer, types, bbox, candidates) + { + var i, len; + for (i = 0, len = types.length; i < len; ++i) + { + this.getCollisionCandidates(layer, types[i], bbox, candidates); + } + }; + Runtime.prototype.getSolidCollisionCandidates = function (layer, bbox, candidates) + { + var solid = this.getSolidBehavior(); + if (!solid) + return null; + this.getTypesCollisionCandidates(layer, solid.my_types, bbox, candidates); + }; + Runtime.prototype.getJumpthruCollisionCandidates = function (layer, bbox, candidates) + { + var jumpthru = this.getJumpthruBehavior(); + if (!jumpthru) + return null; + this.getTypesCollisionCandidates(layer, jumpthru.my_types, bbox, candidates); + }; + Runtime.prototype.testAndSelectCanvasPointOverlap = function (type, ptx, pty, inverted) + { + var sol = type.getCurrentSol(); + var i, j, inst, len; + var lx, ly; + if (sol.select_all) + { + if (!inverted) + { + sol.select_all = false; + sol.instances.length = 0; // clear contents + } + for (i = 0, len = type.instances.length; i < len; i++) + { + inst = type.instances[i]; + inst.update_bbox(); + lx = inst.layer.canvasToLayer(ptx, pty, true); + ly = inst.layer.canvasToLayer(ptx, pty, false); + if (inst.contains_pt(lx, ly)) + { + if (inverted) + return false; + else + sol.instances.push(inst); + } + } + } + else + { + j = 0; + for (i = 0, len = sol.instances.length; i < len; i++) + { + inst = sol.instances[i]; + inst.update_bbox(); + lx = inst.layer.canvasToLayer(ptx, pty, true); + ly = inst.layer.canvasToLayer(ptx, pty, false); + if (inst.contains_pt(lx, ly)) + { + if (inverted) + return false; + else + { + sol.instances[j] = sol.instances[i]; + j++; + } + } + } + if (!inverted) + sol.instances.length = j; + } + type.applySolToContainer(); + if (inverted) + return true; // did not find anything overlapping + else + return sol.hasObjects(); + }; + Runtime.prototype.testOverlap = function (a, b) + { + if (!a || !b || a === b || !a.collisionsEnabled || !b.collisionsEnabled) + return false; + a.update_bbox(); + b.update_bbox(); + var layera = a.layer; + var layerb = b.layer; + var different_layers = (layera !== layerb && (layera.parallaxX !== layerb.parallaxX || layerb.parallaxY !== layerb.parallaxY || layera.scale !== layerb.scale || layera.angle !== layerb.angle || layera.zoomRate !== layerb.zoomRate)); + var i, len, i2, i21, x, y, haspolya, haspolyb, polya, polyb; + if (!different_layers) // same layers: easy check + { + if (!a.bbox.intersects_rect(b.bbox)) + return false; + if (!a.bquad.intersects_quad(b.bquad)) + return false; + if (a.tilemap_exists && b.tilemap_exists) + return false; + if (a.tilemap_exists) + return this.testTilemapOverlap(a, b); + if (b.tilemap_exists) + return this.testTilemapOverlap(b, a); + haspolya = (a.collision_poly && !a.collision_poly.is_empty()); + haspolyb = (b.collision_poly && !b.collision_poly.is_empty()); + if (!haspolya && !haspolyb) + return true; + if (haspolya) + { + a.collision_poly.cache_poly(a.width, a.height, a.angle); + polya = a.collision_poly; + } + else + { + this.temp_poly.set_from_quad(a.bquad, a.x, a.y, a.width, a.height); + polya = this.temp_poly; + } + if (haspolyb) + { + b.collision_poly.cache_poly(b.width, b.height, b.angle); + polyb = b.collision_poly; + } + else + { + this.temp_poly.set_from_quad(b.bquad, b.x, b.y, b.width, b.height); + polyb = this.temp_poly; + } + return polya.intersects_poly(polyb, b.x - a.x, b.y - a.y); + } + else // different layers: need to do full translated check + { + haspolya = (a.collision_poly && !a.collision_poly.is_empty()); + haspolyb = (b.collision_poly && !b.collision_poly.is_empty()); + if (haspolya) + { + a.collision_poly.cache_poly(a.width, a.height, a.angle); + this.temp_poly.set_from_poly(a.collision_poly); + } + else + { + this.temp_poly.set_from_quad(a.bquad, a.x, a.y, a.width, a.height); + } + polya = this.temp_poly; + if (haspolyb) + { + b.collision_poly.cache_poly(b.width, b.height, b.angle); + this.temp_poly2.set_from_poly(b.collision_poly); + } + else + { + this.temp_poly2.set_from_quad(b.bquad, b.x, b.y, b.width, b.height); + } + polyb = this.temp_poly2; + for (i = 0, len = polya.pts_count; i < len; i++) + { + i2 = i * 2; + i21 = i2 + 1; + x = polya.pts_cache[i2]; + y = polya.pts_cache[i21]; + polya.pts_cache[i2] = layera.layerToCanvas(x + a.x, y + a.y, true); + polya.pts_cache[i21] = layera.layerToCanvas(x + a.x, y + a.y, false); + } + polya.update_bbox(); + for (i = 0, len = polyb.pts_count; i < len; i++) + { + i2 = i * 2; + i21 = i2 + 1; + x = polyb.pts_cache[i2]; + y = polyb.pts_cache[i21]; + polyb.pts_cache[i2] = layerb.layerToCanvas(x + b.x, y + b.y, true); + polyb.pts_cache[i21] = layerb.layerToCanvas(x + b.x, y + b.y, false); + } + polyb.update_bbox(); + return polya.intersects_poly(polyb, 0, 0); + } + }; + var tmpQuad = new cr.quad(); + var tmpRect = new cr.rect(0, 0, 0, 0); + var collrect_candidates = []; + Runtime.prototype.testTilemapOverlap = function (tm, a) + { + var i, len, c, rc; + var bbox = a.bbox; + var tmx = tm.x; + var tmy = tm.y; + tm.getCollisionRectCandidates(bbox, collrect_candidates); + var collrects = collrect_candidates; + var haspolya = (a.collision_poly && !a.collision_poly.is_empty()); + for (i = 0, len = collrects.length; i < len; ++i) + { + c = collrects[i]; + rc = c.rc; + if (bbox.intersects_rect_off(rc, tmx, tmy)) + { + tmpQuad.set_from_rect(rc); + tmpQuad.offset(tmx, tmy); + if (tmpQuad.intersects_quad(a.bquad)) + { + if (haspolya) + { + a.collision_poly.cache_poly(a.width, a.height, a.angle); + if (c.poly) + { + if (c.poly.intersects_poly(a.collision_poly, a.x - (tmx + rc.left), a.y - (tmy + rc.top))) + { + collrect_candidates.length = 0; + return true; + } + } + else + { + this.temp_poly.set_from_quad(tmpQuad, 0, 0, rc.right - rc.left, rc.bottom - rc.top); + if (this.temp_poly.intersects_poly(a.collision_poly, a.x, a.y)) + { + collrect_candidates.length = 0; + return true; + } + } + } + else + { + if (c.poly) + { + this.temp_poly.set_from_quad(a.bquad, 0, 0, a.width, a.height); + if (c.poly.intersects_poly(this.temp_poly, -(tmx + rc.left), -(tmy + rc.top))) + { + collrect_candidates.length = 0; + return true; + } + } + else + { + collrect_candidates.length = 0; + return true; + } + } + } + } + } + collrect_candidates.length = 0; + return false; + }; + Runtime.prototype.testRectOverlap = function (r, b) + { + if (!b || !b.collisionsEnabled) + return false; + b.update_bbox(); + var layerb = b.layer; + var haspolyb, polyb; + if (!b.bbox.intersects_rect(r)) + return false; + if (b.tilemap_exists) + { + b.getCollisionRectCandidates(r, collrect_candidates); + var collrects = collrect_candidates; + var i, len, c, tilerc; + var tmx = b.x; + var tmy = b.y; + for (i = 0, len = collrects.length; i < len; ++i) + { + c = collrects[i]; + tilerc = c.rc; + if (r.intersects_rect_off(tilerc, tmx, tmy)) + { + if (c.poly) + { + this.temp_poly.set_from_rect(r, 0, 0); + if (c.poly.intersects_poly(this.temp_poly, -(tmx + tilerc.left), -(tmy + tilerc.top))) + { + collrect_candidates.length = 0; + return true; + } + } + else + { + collrect_candidates.length = 0; + return true; + } + } + } + collrect_candidates.length = 0; + return false; + } + else + { + tmpQuad.set_from_rect(r); + if (!b.bquad.intersects_quad(tmpQuad)) + return false; + haspolyb = (b.collision_poly && !b.collision_poly.is_empty()); + if (!haspolyb) + return true; + b.collision_poly.cache_poly(b.width, b.height, b.angle); + tmpQuad.offset(-r.left, -r.top); + this.temp_poly.set_from_quad(tmpQuad, 0, 0, 1, 1); + return b.collision_poly.intersects_poly(this.temp_poly, r.left - b.x, r.top - b.y); + } + }; + Runtime.prototype.testSegmentOverlap = function (x1, y1, x2, y2, b) + { + if (!b || !b.collisionsEnabled) + return false; + b.update_bbox(); + var layerb = b.layer; + var haspolyb, polyb; + tmpRect.set(cr.min(x1, x2), cr.min(y1, y2), cr.max(x1, x2), cr.max(y1, y2)); + if (!b.bbox.intersects_rect(tmpRect)) + return false; + if (b.tilemap_exists) + { + b.getCollisionRectCandidates(tmpRect, collrect_candidates); + var collrects = collrect_candidates; + var i, len, c, tilerc; + var tmx = b.x; + var tmy = b.y; + for (i = 0, len = collrects.length; i < len; ++i) + { + c = collrects[i]; + tilerc = c.rc; + if (tmpRect.intersects_rect_off(tilerc, tmx, tmy)) + { + tmpQuad.set_from_rect(tilerc); + tmpQuad.offset(tmx, tmy); + if (tmpQuad.intersects_segment(x1, y1, x2, y2)) + { + if (c.poly) + { + if (c.poly.intersects_segment(tmx + tilerc.left, tmy + tilerc.top, x1, y1, x2, y2)) + { + collrect_candidates.length = 0; + return true; + } + } + else + { + collrect_candidates.length = 0; + return true; + } + } + } + } + collrect_candidates.length = 0; + return false; + } + else + { + if (!b.bquad.intersects_segment(x1, y1, x2, y2)) + return false; + haspolyb = (b.collision_poly && !b.collision_poly.is_empty()); + if (!haspolyb) + return true; + b.collision_poly.cache_poly(b.width, b.height, b.angle); + return b.collision_poly.intersects_segment(b.x, b.y, x1, y1, x2, y2); + } + }; + Runtime.prototype.typeHasBehavior = function (t, b) + { + if (!b) + return false; + var i, len, j, lenj, f; + for (i = 0, len = t.behaviors.length; i < len; i++) + { + if (t.behaviors[i].behavior instanceof b) + return true; + } + if (!t.is_family) + { + for (i = 0, len = t.families.length; i < len; i++) + { + f = t.families[i]; + for (j = 0, lenj = f.behaviors.length; j < lenj; j++) + { + if (f.behaviors[j].behavior instanceof b) + return true; + } + } + } + return false; + }; + Runtime.prototype.typeHasNoSaveBehavior = function (t) + { + return this.typeHasBehavior(t, cr.behaviors.NoSave); + }; + Runtime.prototype.typeHasPersistBehavior = function (t) + { + return this.typeHasBehavior(t, cr.behaviors.Persist); + }; + Runtime.prototype.getSolidBehavior = function () + { + return this.solidBehavior; + }; + Runtime.prototype.getJumpthruBehavior = function () + { + return this.jumpthruBehavior; + }; + var candidates = []; + Runtime.prototype.testOverlapSolid = function (inst) + { + var i, len, s; + inst.update_bbox(); + this.getSolidCollisionCandidates(inst.layer, inst.bbox, candidates); + for (i = 0, len = candidates.length; i < len; ++i) + { + s = candidates[i]; + if (!s.extra["solidEnabled"]) + continue; + if (this.testOverlap(inst, s)) + { + candidates.length = 0; + return s; + } + } + candidates.length = 0; + return null; + }; + Runtime.prototype.testRectOverlapSolid = function (r) + { + var i, len, s; + this.getSolidCollisionCandidates(null, r, candidates); + for (i = 0, len = candidates.length; i < len; ++i) + { + s = candidates[i]; + if (!s.extra["solidEnabled"]) + continue; + if (this.testRectOverlap(r, s)) + { + candidates.length = 0; + return s; + } + } + candidates.length = 0; + return null; + }; + var jumpthru_array_ret = []; + Runtime.prototype.testOverlapJumpThru = function (inst, all) + { + var ret = null; + if (all) + { + ret = jumpthru_array_ret; + ret.length = 0; + } + inst.update_bbox(); + this.getJumpthruCollisionCandidates(inst.layer, inst.bbox, candidates); + var i, len, j; + for (i = 0, len = candidates.length; i < len; ++i) + { + j = candidates[i]; + if (!j.extra["jumpthruEnabled"]) + continue; + if (this.testOverlap(inst, j)) + { + if (all) + ret.push(j); + else + { + candidates.length = 0; + return j; + } + } + } + candidates.length = 0; + return ret; + }; + Runtime.prototype.pushOutSolid = function (inst, xdir, ydir, dist, include_jumpthrus, specific_jumpthru) + { + var push_dist = dist || 50; + var oldx = inst.x + var oldy = inst.y; + var i; + var last_overlapped = null, secondlast_overlapped = null; + for (i = 0; i < push_dist; i++) + { + inst.x = (oldx + (xdir * i)); + inst.y = (oldy + (ydir * i)); + inst.set_bbox_changed(); + if (!this.testOverlap(inst, last_overlapped)) + { + last_overlapped = this.testOverlapSolid(inst); + if (last_overlapped) + secondlast_overlapped = last_overlapped; + if (!last_overlapped) + { + if (include_jumpthrus) + { + if (specific_jumpthru) + last_overlapped = (this.testOverlap(inst, specific_jumpthru) ? specific_jumpthru : null); + else + last_overlapped = this.testOverlapJumpThru(inst); + if (last_overlapped) + secondlast_overlapped = last_overlapped; + } + if (!last_overlapped) + { + if (secondlast_overlapped) + this.pushInFractional(inst, xdir, ydir, secondlast_overlapped, 16); + return true; + } + } + } + } + inst.x = oldx; + inst.y = oldy; + inst.set_bbox_changed(); + return false; + }; + Runtime.prototype.pushOut = function (inst, xdir, ydir, dist, otherinst) + { + var push_dist = dist || 50; + var oldx = inst.x + var oldy = inst.y; + var i; + for (i = 0; i < push_dist; i++) + { + inst.x = (oldx + (xdir * i)); + inst.y = (oldy + (ydir * i)); + inst.set_bbox_changed(); + if (!this.testOverlap(inst, otherinst)) + return true; + } + inst.x = oldx; + inst.y = oldy; + inst.set_bbox_changed(); + return false; + }; + Runtime.prototype.pushInFractional = function (inst, xdir, ydir, obj, limit) + { + var divisor = 2; + var frac; + var forward = false; + var overlapping = false; + var bestx = inst.x; + var besty = inst.y; + while (divisor <= limit) + { + frac = 1 / divisor; + divisor *= 2; + inst.x += xdir * frac * (forward ? 1 : -1); + inst.y += ydir * frac * (forward ? 1 : -1); + inst.set_bbox_changed(); + if (this.testOverlap(inst, obj)) + { + forward = true; + overlapping = true; + } + else + { + forward = false; + overlapping = false; + bestx = inst.x; + besty = inst.y; + } + } + if (overlapping) + { + inst.x = bestx; + inst.y = besty; + inst.set_bbox_changed(); + } + }; + Runtime.prototype.pushOutSolidNearest = function (inst, max_dist_) + { + var max_dist = (cr.is_undefined(max_dist_) ? 100 : max_dist_); + var dist = 0; + var oldx = inst.x + var oldy = inst.y; + var dir = 0; + var dx = 0, dy = 0; + var last_overlapped = this.testOverlapSolid(inst); + if (!last_overlapped) + return true; // already clear of solids + while (dist <= max_dist) + { + switch (dir) { + case 0: dx = 0; dy = -1; dist++; break; + case 1: dx = 1; dy = -1; break; + case 2: dx = 1; dy = 0; break; + case 3: dx = 1; dy = 1; break; + case 4: dx = 0; dy = 1; break; + case 5: dx = -1; dy = 1; break; + case 6: dx = -1; dy = 0; break; + case 7: dx = -1; dy = -1; break; + } + dir = (dir + 1) % 8; + inst.x = cr.floor(oldx + (dx * dist)); + inst.y = cr.floor(oldy + (dy * dist)); + inst.set_bbox_changed(); + if (!this.testOverlap(inst, last_overlapped)) + { + last_overlapped = this.testOverlapSolid(inst); + if (!last_overlapped) + return true; + } + } + inst.x = oldx; + inst.y = oldy; + inst.set_bbox_changed(); + return false; + }; + Runtime.prototype.registerCollision = function (a, b) + { + if (!a.collisionsEnabled || !b.collisionsEnabled) + return; + this.registered_collisions.push([a, b]); + }; + Runtime.prototype.checkRegisteredCollision = function (a, b) + { + var i, len, x; + for (i = 0, len = this.registered_collisions.length; i < len; i++) + { + x = this.registered_collisions[i]; + if ((x[0] == a && x[1] == b) || (x[0] == b && x[1] == a)) + return true; + } + return false; + }; + Runtime.prototype.calculateSolidBounceAngle = function(inst, startx, starty, obj) + { + var objx = inst.x; + var objy = inst.y; + var radius = cr.max(10, cr.distanceTo(startx, starty, objx, objy)); + var startangle = cr.angleTo(startx, starty, objx, objy); + var firstsolid = obj || this.testOverlapSolid(inst); + if (!firstsolid) + return cr.clamp_angle(startangle + cr.PI); + var cursolid = firstsolid; + var i, curangle, anticlockwise_free_angle, clockwise_free_angle; + var increment = cr.to_radians(5); // 5 degree increments + for (i = 1; i < 36; i++) + { + curangle = startangle - i * increment; + inst.x = startx + Math.cos(curangle) * radius; + inst.y = starty + Math.sin(curangle) * radius; + inst.set_bbox_changed(); + if (!this.testOverlap(inst, cursolid)) + { + cursolid = obj ? null : this.testOverlapSolid(inst); + if (!cursolid) + { + anticlockwise_free_angle = curangle; + break; + } + } + } + if (i === 36) + anticlockwise_free_angle = cr.clamp_angle(startangle + cr.PI); + var cursolid = firstsolid; + for (i = 1; i < 36; i++) + { + curangle = startangle + i * increment; + inst.x = startx + Math.cos(curangle) * radius; + inst.y = starty + Math.sin(curangle) * radius; + inst.set_bbox_changed(); + if (!this.testOverlap(inst, cursolid)) + { + cursolid = obj ? null : this.testOverlapSolid(inst); + if (!cursolid) + { + clockwise_free_angle = curangle; + break; + } + } + } + if (i === 36) + clockwise_free_angle = cr.clamp_angle(startangle + cr.PI); + inst.x = objx; + inst.y = objy; + inst.set_bbox_changed(); + if (clockwise_free_angle === anticlockwise_free_angle) + return clockwise_free_angle; + var half_diff = cr.angleDiff(clockwise_free_angle, anticlockwise_free_angle) / 2; + var normal; + if (cr.angleClockwise(clockwise_free_angle, anticlockwise_free_angle)) + { + normal = cr.clamp_angle(anticlockwise_free_angle + half_diff + cr.PI); + } + else + { + normal = cr.clamp_angle(clockwise_free_angle + half_diff); + } +; + var vx = Math.cos(startangle); + var vy = Math.sin(startangle); + var nx = Math.cos(normal); + var ny = Math.sin(normal); + var v_dot_n = vx * nx + vy * ny; + var rx = vx - 2 * v_dot_n * nx; + var ry = vy - 2 * v_dot_n * ny; + return cr.angleTo(0, 0, rx, ry); + }; + var triggerSheetIndex = -1; + Runtime.prototype.trigger = function (method, inst, value /* for fast triggers */) + { +; + if (!this.running_layout) + return false; + var sheet = this.running_layout.event_sheet; + if (!sheet) + return false; // no event sheet active; nothing to trigger + var ret = false; + var r, i, len; + triggerSheetIndex++; + var deep_includes = sheet.deep_includes; + for (i = 0, len = deep_includes.length; i < len; ++i) + { + r = this.triggerOnSheet(method, inst, deep_includes[i], value); + ret = ret || r; + } + r = this.triggerOnSheet(method, inst, sheet, value); + ret = ret || r; + triggerSheetIndex--; + return ret; + }; + Runtime.prototype.triggerOnSheet = function (method, inst, sheet, value) + { + var ret = false; + var i, leni, r, families; + if (!inst) + { + r = this.triggerOnSheetForTypeName(method, inst, "system", sheet, value); + ret = ret || r; + } + else + { + r = this.triggerOnSheetForTypeName(method, inst, inst.type.name, sheet, value); + ret = ret || r; + families = inst.type.families; + for (i = 0, leni = families.length; i < leni; ++i) + { + r = this.triggerOnSheetForTypeName(method, inst, families[i].name, sheet, value); + ret = ret || r; + } + } + return ret; // true if anything got triggered + }; + Runtime.prototype.triggerOnSheetForTypeName = function (method, inst, type_name, sheet, value) + { + var i, leni; + var ret = false, ret2 = false; + var trig, index; + var fasttrigger = (typeof value !== "undefined"); + var triggers = (fasttrigger ? sheet.fasttriggers : sheet.triggers); + var obj_entry = triggers[type_name]; + if (!obj_entry) + return ret; + var triggers_list = null; + for (i = 0, leni = obj_entry.length; i < leni; ++i) + { + if (obj_entry[i].method == method) + { + triggers_list = obj_entry[i].evs; + break; + } + } + if (!triggers_list) + return ret; + var triggers_to_fire; + if (fasttrigger) + { + triggers_to_fire = triggers_list[value]; + } + else + { + triggers_to_fire = triggers_list; + } + if (!triggers_to_fire) + return null; + for (i = 0, leni = triggers_to_fire.length; i < leni; i++) + { + trig = triggers_to_fire[i][0]; + index = triggers_to_fire[i][1]; + ret2 = this.executeSingleTrigger(inst, type_name, trig, index); + ret = ret || ret2; + } + return ret; + }; + Runtime.prototype.executeSingleTrigger = function (inst, type_name, trig, index) + { + var i, leni; + var ret = false; + this.trigger_depth++; + var current_event = this.getCurrentEventStack().current_event; + if (current_event) + this.pushCleanSol(current_event.solModifiersIncludingParents); + var isrecursive = (this.trigger_depth > 1); // calling trigger from inside another trigger + this.pushCleanSol(trig.solModifiersIncludingParents); + if (isrecursive) + this.pushLocalVarStack(); + var event_stack = this.pushEventStack(trig); + event_stack.current_event = trig; + if (inst) + { + var sol = this.types[type_name].getCurrentSol(); + sol.select_all = false; + sol.instances.length = 1; + sol.instances[0] = inst; + this.types[type_name].applySolToContainer(); + } + var ok_to_run = true; + if (trig.parent) + { + var temp_parents_arr = event_stack.temp_parents_arr; + var cur_parent = trig.parent; + while (cur_parent) + { + temp_parents_arr.push(cur_parent); + cur_parent = cur_parent.parent; + } + temp_parents_arr.reverse(); + for (i = 0, leni = temp_parents_arr.length; i < leni; i++) + { + if (!temp_parents_arr[i].run_pretrigger()) // parent event failed + { + ok_to_run = false; + break; + } + } + } + if (ok_to_run) + { + this.execcount++; + if (trig.orblock) + trig.run_orblocktrigger(index); + else + trig.run(); + ret = ret || event_stack.last_event_true; + } + this.popEventStack(); + if (isrecursive) + this.popLocalVarStack(); + this.popSol(trig.solModifiersIncludingParents); + if (current_event) + this.popSol(current_event.solModifiersIncludingParents); + if (this.hasPendingInstances && this.isInOnDestroy === 0 && triggerSheetIndex === 0 && !this.isRunningEvents) + { + this.ClearDeathRow(); + } + this.trigger_depth--; + return ret; + }; + Runtime.prototype.getCurrentCondition = function () + { + var evinfo = this.getCurrentEventStack(); + return evinfo.current_event.conditions[evinfo.cndindex]; + }; + Runtime.prototype.getCurrentAction = function () + { + var evinfo = this.getCurrentEventStack(); + return evinfo.current_event.actions[evinfo.actindex]; + }; + Runtime.prototype.pushLocalVarStack = function () + { + this.localvar_stack_index++; + if (this.localvar_stack_index >= this.localvar_stack.length) + this.localvar_stack.push([]); + }; + Runtime.prototype.popLocalVarStack = function () + { +; + this.localvar_stack_index--; + }; + Runtime.prototype.getCurrentLocalVarStack = function () + { + return this.localvar_stack[this.localvar_stack_index]; + }; + Runtime.prototype.pushEventStack = function (cur_event) + { + this.event_stack_index++; + if (this.event_stack_index >= this.event_stack.length) + this.event_stack.push(new cr.eventStackFrame()); + var ret = this.getCurrentEventStack(); + ret.reset(cur_event); + return ret; + }; + Runtime.prototype.popEventStack = function () + { +; + this.event_stack_index--; + }; + Runtime.prototype.getCurrentEventStack = function () + { + return this.event_stack[this.event_stack_index]; + }; + Runtime.prototype.pushLoopStack = function (name_) + { + this.loop_stack_index++; + if (this.loop_stack_index >= this.loop_stack.length) + { + this.loop_stack.push(cr.seal({ name: name_, index: 0, stopped: false })); + } + var ret = this.getCurrentLoop(); + ret.name = name_; + ret.index = 0; + ret.stopped = false; + return ret; + }; + Runtime.prototype.popLoopStack = function () + { +; + this.loop_stack_index--; + }; + Runtime.prototype.getCurrentLoop = function () + { + return this.loop_stack[this.loop_stack_index]; + }; + Runtime.prototype.getEventVariableByName = function (name, scope) + { + var i, leni, j, lenj, sheet, e; + while (scope) + { + for (i = 0, leni = scope.subevents.length; i < leni; i++) + { + e = scope.subevents[i]; + if (e instanceof cr.eventvariable && cr.equals_nocase(name, e.name)) + return e; + } + scope = scope.parent; + } + for (i = 0, leni = this.eventsheets_by_index.length; i < leni; i++) + { + sheet = this.eventsheets_by_index[i]; + for (j = 0, lenj = sheet.events.length; j < lenj; j++) + { + e = sheet.events[j]; + if (e instanceof cr.eventvariable && cr.equals_nocase(name, e.name)) + return e; + } + } + return null; + }; + Runtime.prototype.getLayoutBySid = function (sid_) + { + var i, len; + for (i = 0, len = this.layouts_by_index.length; i < len; i++) + { + if (this.layouts_by_index[i].sid === sid_) + return this.layouts_by_index[i]; + } + return null; + }; + Runtime.prototype.getObjectTypeBySid = function (sid_) + { + var i, len; + for (i = 0, len = this.types_by_index.length; i < len; i++) + { + if (this.types_by_index[i].sid === sid_) + return this.types_by_index[i]; + } + return null; + }; + Runtime.prototype.getGroupBySid = function (sid_) + { + var i, len; + for (i = 0, len = this.allGroups.length; i < len; i++) + { + if (this.allGroups[i].sid === sid_) + return this.allGroups[i]; + } + return null; + }; + function makeSaveDb(e) + { + var db = e.target.result; + db.createObjectStore("saves", { keyPath: "slot" }); + }; + function IndexedDB_WriteSlot(slot_, data_, oncomplete_, onerror_) + { + var request = indexedDB.open("_C2SaveStates"); + request.onupgradeneeded = makeSaveDb; + request.onerror = onerror_; + request.onsuccess = function (e) + { + var db = e.target.result; + db.onerror = onerror_; + var transaction = db.transaction(["saves"], "readwrite"); + var objectStore = transaction.objectStore("saves"); + var putReq = objectStore.put({"slot": slot_, "data": data_ }); + putReq.onsuccess = oncomplete_; + }; + }; + function IndexedDB_ReadSlot(slot_, oncomplete_, onerror_) + { + var request = indexedDB.open("_C2SaveStates"); + request.onupgradeneeded = makeSaveDb; + request.onerror = onerror_; + request.onsuccess = function (e) + { + var db = e.target.result; + db.onerror = onerror_; + var transaction = db.transaction(["saves"]); + var objectStore = transaction.objectStore("saves"); + var readReq = objectStore.get(slot_); + readReq.onsuccess = function (e) + { + if (readReq.result) + oncomplete_(readReq.result["data"]); + else + oncomplete_(null); + }; + }; + }; + Runtime.prototype.signalContinuousPreview = function () + { + this.signalledContinuousPreview = true; + }; + function doContinuousPreviewReload() + { + cr.logexport("Reloading for continuous preview"); + if (!!window["c2cocoonjs"]) + { + CocoonJS["App"]["reload"](); + } + else + { + if (window.location.search.indexOf("continuous") > -1) + window.location.reload(true); + else + window.location = window.location + "?continuous"; + } + }; + Runtime.prototype.handleSaveLoad = function () + { + var self = this; + var savingToSlot = this.saveToSlot; + var savingJson = this.lastSaveJson; + var loadingFromSlot = this.loadFromSlot; + var continuous = false; + if (this.signalledContinuousPreview) + { + continuous = true; + savingToSlot = "__c2_continuouspreview"; + this.signalledContinuousPreview = false; + } + if (savingToSlot.length) + { + this.ClearDeathRow(); + savingJson = this.saveToJSONString(); + if (window.indexedDB && !this.isCocoonJs) + { + IndexedDB_WriteSlot(savingToSlot, savingJson, function () + { + cr.logexport("Saved state to IndexedDB storage (" + savingJson.length + " bytes)"); + self.lastSaveJson = savingJson; + self.trigger(cr.system_object.prototype.cnds.OnSaveComplete, null); + self.lastSaveJson = ""; + if (continuous) + doContinuousPreviewReload(); + }, function (e) + { + try { + localStorage.setItem("__c2save_" + savingToSlot, savingJson); + cr.logexport("Saved state to WebStorage (" + savingJson.length + " bytes)"); + self.lastSaveJson = savingJson; + self.trigger(cr.system_object.prototype.cnds.OnSaveComplete, null); + self.lastSaveJson = ""; + if (continuous) + doContinuousPreviewReload(); + } + catch (f) + { + cr.logexport("Failed to save game state: " + e + "; " + f); + } + }); + } + else + { + try { + localStorage.setItem("__c2save_" + savingToSlot, savingJson); + cr.logexport("Saved state to WebStorage (" + savingJson.length + " bytes)"); + self.lastSaveJson = savingJson; + this.trigger(cr.system_object.prototype.cnds.OnSaveComplete, null); + self.lastSaveJson = ""; + if (continuous) + doContinuousPreviewReload(); + } + catch (e) + { + cr.logexport("Error saving to WebStorage: " + e); + } + } + this.saveToSlot = ""; + this.loadFromSlot = ""; + this.loadFromJson = ""; + } + if (loadingFromSlot.length) + { + if (window.indexedDB && !this.isCocoonJs) + { + IndexedDB_ReadSlot(loadingFromSlot, function (result_) + { + if (result_) + { + self.loadFromJson = result_; + cr.logexport("Loaded state from IndexedDB storage (" + self.loadFromJson.length + " bytes)"); + } + else + { + self.loadFromJson = localStorage.getItem("__c2save_" + loadingFromSlot) || ""; + cr.logexport("Loaded state from WebStorage (" + self.loadFromJson.length + " bytes)"); + } + self.suspendDrawing = false; + if (!self.loadFromJson.length) + self.trigger(cr.system_object.prototype.cnds.OnLoadFailed, null); + }, function (e) + { + self.loadFromJson = localStorage.getItem("__c2save_" + loadingFromSlot) || ""; + cr.logexport("Loaded state from WebStorage (" + self.loadFromJson.length + " bytes)"); + self.suspendDrawing = false; + if (!self.loadFromJson.length) + self.trigger(cr.system_object.prototype.cnds.OnLoadFailed, null); + }); + } + else + { + this.loadFromJson = localStorage.getItem("__c2save_" + loadingFromSlot) || ""; + cr.logexport("Loaded state from WebStorage (" + this.loadFromJson.length + " bytes)"); + this.suspendDrawing = false; + if (!self.loadFromJson.length) + self.trigger(cr.system_object.prototype.cnds.OnLoadFailed, null); + } + this.loadFromSlot = ""; + this.saveToSlot = ""; + } + if (this.loadFromJson.length) + { + this.ClearDeathRow(); + this.loadFromJSONString(this.loadFromJson); + this.lastSaveJson = this.loadFromJson; + this.trigger(cr.system_object.prototype.cnds.OnLoadComplete, null); + this.lastSaveJson = ""; + this.loadFromJson = ""; + } + }; + function CopyExtraObject(extra) + { + var p, ret = {}; + for (p in extra) + { + if (extra.hasOwnProperty(p)) + { + if (extra[p] instanceof cr.ObjectSet) + continue; + if (extra[p] && typeof extra[p].c2userdata !== "undefined") + continue; + ret[p] = extra[p]; + } + } + return ret; + }; + Runtime.prototype.saveToJSONString = function() + { + var i, len, j, lenj, type, layout, typeobj, g, c, a, v, p; + var o = { + "c2save": true, + "version": 1, + "rt": { + "time": this.kahanTime.sum, + "walltime": this.wallTime.sum, + "timescale": this.timescale, + "tickcount": this.tickcount, + "execcount": this.execcount, + "next_uid": this.next_uid, + "running_layout": this.running_layout.sid, + "start_time_offset": (Date.now() - this.start_time) + }, + "types": {}, + "layouts": {}, + "events": { + "groups": {}, + "cnds": {}, + "acts": {}, + "vars": {} + } + }; + for (i = 0, len = this.types_by_index.length; i < len; i++) + { + type = this.types_by_index[i]; + if (type.is_family || this.typeHasNoSaveBehavior(type)) + continue; + typeobj = { + "instances": [] + }; + if (cr.hasAnyOwnProperty(type.extra)) + typeobj["ex"] = CopyExtraObject(type.extra); + for (j = 0, lenj = type.instances.length; j < lenj; j++) + { + typeobj["instances"].push(this.saveInstanceToJSON(type.instances[j])); + } + o["types"][type.sid.toString()] = typeobj; + } + for (i = 0, len = this.layouts_by_index.length; i < len; i++) + { + layout = this.layouts_by_index[i]; + o["layouts"][layout.sid.toString()] = layout.saveToJSON(); + } + var ogroups = o["events"]["groups"]; + for (i = 0, len = this.allGroups.length; i < len; i++) + { + g = this.allGroups[i]; + ogroups[g.sid.toString()] = this.groups_by_name[g.group_name].group_active; + } + var ocnds = o["events"]["cnds"]; + for (p in this.cndsBySid) + { + if (this.cndsBySid.hasOwnProperty(p)) + { + c = this.cndsBySid[p]; + if (cr.hasAnyOwnProperty(c.extra)) + ocnds[p] = { "ex": CopyExtraObject(c.extra) }; + } + } + var oacts = o["events"]["acts"]; + for (p in this.actsBySid) + { + if (this.actsBySid.hasOwnProperty(p)) + { + a = this.actsBySid[p]; + if (cr.hasAnyOwnProperty(a.extra)) + oacts[p] = { "ex": a.extra }; + } + } + var ovars = o["events"]["vars"]; + for (p in this.varsBySid) + { + if (this.varsBySid.hasOwnProperty(p)) + { + v = this.varsBySid[p]; + if (!v.is_constant && (!v.parent || v.is_static)) + ovars[p] = v.data; + } + } + o["system"] = this.system.saveToJSON(); + return JSON.stringify(o); + }; + Runtime.prototype.refreshUidMap = function () + { + var i, len, type, j, lenj, inst; + this.objectsByUid = {}; + for (i = 0, len = this.types_by_index.length; i < len; i++) + { + type = this.types_by_index[i]; + if (type.is_family) + continue; + for (j = 0, lenj = type.instances.length; j < lenj; j++) + { + inst = type.instances[j]; + this.objectsByUid[inst.uid.toString()] = inst; + } + } + }; + Runtime.prototype.loadFromJSONString = function (str) + { + var o = JSON.parse(str); + if (!o["c2save"]) + return; // probably not a c2 save state + if (o["version"] > 1) + return; // from future version of c2; assume not compatible + var rt = o["rt"]; + this.kahanTime.reset(); + this.kahanTime.sum = rt["time"]; + this.wallTime.reset(); + this.wallTime.sum = rt["walltime"] || 0; + this.timescale = rt["timescale"]; + this.tickcount = rt["tickcount"]; + this.execcount = rt["execcount"]; + this.start_time = Date.now() - rt["start_time_offset"]; + var layout_sid = rt["running_layout"]; + if (layout_sid !== this.running_layout.sid) + { + var changeToLayout = this.getLayoutBySid(layout_sid); + if (changeToLayout) + this.doChangeLayout(changeToLayout); + else + return; // layout that was saved on has gone missing (deleted?) + } + this.isLoadingState = true; + var i, len, j, lenj, k, lenk, p, type, existing_insts, load_insts, inst, binst, layout, layer, g, iid, t; + var otypes = o["types"]; + for (p in otypes) + { + if (otypes.hasOwnProperty(p)) + { + type = this.getObjectTypeBySid(parseInt(p, 10)); + if (!type || type.is_family || this.typeHasNoSaveBehavior(type)) + continue; + if (otypes[p]["ex"]) + type.extra = otypes[p]["ex"]; + else + cr.wipe(type.extra); + existing_insts = type.instances; + load_insts = otypes[p]["instances"]; + for (i = 0, len = cr.min(existing_insts.length, load_insts.length); i < len; i++) + { + this.loadInstanceFromJSON(existing_insts[i], load_insts[i]); + } + for (i = load_insts.length, len = existing_insts.length; i < len; i++) + this.DestroyInstance(existing_insts[i]); + for (i = existing_insts.length, len = load_insts.length; i < len; i++) + { + layer = null; + if (type.plugin.is_world) + { + layer = this.running_layout.getLayerBySid(load_insts[i]["w"]["l"]); + if (!layer) + continue; + } + inst = this.createInstanceFromInit(type.default_instance, layer, false, 0, 0, true); + this.loadInstanceFromJSON(inst, load_insts[i]); + } + type.stale_iids = true; + } + } + this.ClearDeathRow(); + this.refreshUidMap(); + var olayouts = o["layouts"]; + for (p in olayouts) + { + if (olayouts.hasOwnProperty(p)) + { + layout = this.getLayoutBySid(parseInt(p, 10)); + if (!layout) + continue; // must've gone missing + layout.loadFromJSON(olayouts[p]); + } + } + var ogroups = o["events"]["groups"]; + for (p in ogroups) + { + if (ogroups.hasOwnProperty(p)) + { + g = this.getGroupBySid(parseInt(p, 10)); + if (g && this.groups_by_name[g.group_name]) + this.groups_by_name[g.group_name].group_active = ogroups[p]; + } + } + var ocnds = o["events"]["cnds"]; + for (p in ocnds) + { + if (ocnds.hasOwnProperty(p) && this.cndsBySid.hasOwnProperty(p)) + { + this.cndsBySid[p].extra = ocnds[p]["ex"]; + } + } + var oacts = o["events"]["acts"]; + for (p in oacts) + { + if (oacts.hasOwnProperty(p) && this.actsBySid.hasOwnProperty(p)) + { + this.actsBySid[p].extra = oacts[p]["ex"]; + } + } + var ovars = o["events"]["vars"]; + for (p in ovars) + { + if (ovars.hasOwnProperty(p) && this.varsBySid.hasOwnProperty(p)) + { + this.varsBySid[p].data = ovars[p]; + } + } + this.next_uid = rt["next_uid"]; + this.isLoadingState = false; + this.system.loadFromJSON(o["system"]); + for (i = 0, len = this.types_by_index.length; i < len; i++) + { + type = this.types_by_index[i]; + if (type.is_family) + continue; + for (j = 0, lenj = type.instances.length; j < lenj; j++) + { + inst = type.instances[j]; + if (type.is_contained) + { + iid = inst.get_iid(); + inst.siblings.length = 0; + for (k = 0, lenk = type.container.length; k < lenk; k++) + { + t = type.container[k]; + if (type === t) + continue; +; + inst.siblings.push(t.instances[iid]); + } + } + if (inst.afterLoad) + inst.afterLoad(); + if (inst.behavior_insts) + { + for (k = 0, lenk = inst.behavior_insts.length; k < lenk; k++) + { + binst = inst.behavior_insts[k]; + if (binst.afterLoad) + binst.afterLoad(); + } + } + } + } + this.redraw = true; + }; + Runtime.prototype.saveInstanceToJSON = function(inst, state_only) + { + var i, len, world, behinst, et; + var type = inst.type; + var plugin = type.plugin; + var o = {}; + if (state_only) + o["c2"] = true; // mark as known json data from Construct 2 + else + o["uid"] = inst.uid; + if (cr.hasAnyOwnProperty(inst.extra)) + o["ex"] = CopyExtraObject(inst.extra); + if (inst.instance_vars && inst.instance_vars.length) + { + o["ivs"] = {}; + for (i = 0, len = inst.instance_vars.length; i < len; i++) + { + o["ivs"][inst.type.instvar_sids[i].toString()] = inst.instance_vars[i]; + } + } + if (plugin.is_world) + { + world = { + "x": inst.x, + "y": inst.y, + "w": inst.width, + "h": inst.height, + "l": inst.layer.sid, + "zi": inst.get_zindex() + }; + if (inst.angle !== 0) + world["a"] = inst.angle; + if (inst.opacity !== 1) + world["o"] = inst.opacity; + if (inst.hotspotX !== 0.5) + world["hX"] = inst.hotspotX; + if (inst.hotspotY !== 0.5) + world["hY"] = inst.hotspotY; + if (inst.blend_mode !== 0) + world["bm"] = inst.blend_mode; + if (!inst.visible) + world["v"] = inst.visible; + if (!inst.collisionsEnabled) + world["ce"] = inst.collisionsEnabled; + if (inst.my_timescale !== -1) + world["mts"] = inst.my_timescale; + if (type.effect_types.length) + { + world["fx"] = []; + for (i = 0, len = type.effect_types.length; i < len; i++) + { + et = type.effect_types[i]; + world["fx"].push({"name": et.name, + "active": inst.active_effect_flags[et.index], + "params": inst.effect_params[et.index] }); + } + } + o["w"] = world; + } + if (inst.behavior_insts && inst.behavior_insts.length) + { + o["behs"] = {}; + for (i = 0, len = inst.behavior_insts.length; i < len; i++) + { + behinst = inst.behavior_insts[i]; + if (behinst.saveToJSON) + o["behs"][behinst.type.sid.toString()] = behinst.saveToJSON(); + } + } + if (inst.saveToJSON) + o["data"] = inst.saveToJSON(); + return o; + }; + Runtime.prototype.getInstanceVarIndexBySid = function (type, sid_) + { + var i, len; + for (i = 0, len = type.instvar_sids.length; i < len; i++) + { + if (type.instvar_sids[i] === sid_) + return i; + } + return -1; + }; + Runtime.prototype.getBehaviorIndexBySid = function (inst, sid_) + { + var i, len; + for (i = 0, len = inst.behavior_insts.length; i < len; i++) + { + if (inst.behavior_insts[i].type.sid === sid_) + return i; + } + return -1; + }; + Runtime.prototype.loadInstanceFromJSON = function(inst, o, state_only) + { + var p, i, len, iv, oivs, world, fxindex, obehs, behindex; + var oldlayer; + var type = inst.type; + var plugin = type.plugin; + if (state_only) + { + if (!o["c2"]) + return; + } + else + inst.uid = o["uid"]; + if (o["ex"]) + inst.extra = o["ex"]; + else + cr.wipe(inst.extra); + oivs = o["ivs"]; + if (oivs) + { + for (p in oivs) + { + if (oivs.hasOwnProperty(p)) + { + iv = this.getInstanceVarIndexBySid(type, parseInt(p, 10)); + if (iv < 0 || iv >= inst.instance_vars.length) + continue; // must've gone missing + inst.instance_vars[iv] = oivs[p]; + } + } + } + if (plugin.is_world) + { + world = o["w"]; + if (inst.layer.sid !== world["l"]) + { + oldlayer = inst.layer; + inst.layer = this.running_layout.getLayerBySid(world["l"]); + if (inst.layer) + { + oldlayer.removeFromInstanceList(inst, true); + inst.layer.appendToInstanceList(inst, true); + inst.set_bbox_changed(); + inst.layer.setZIndicesStaleFrom(0); + } + else + { + inst.layer = oldlayer; + this.DestroyInstance(inst); + } + } + inst.x = world["x"]; + inst.y = world["y"]; + inst.width = world["w"]; + inst.height = world["h"]; + inst.zindex = world["zi"]; + inst.angle = world.hasOwnProperty("a") ? world["a"] : 0; + inst.opacity = world.hasOwnProperty("o") ? world["o"] : 1; + inst.hotspotX = world.hasOwnProperty("hX") ? world["hX"] : 0.5; + inst.hotspotY = world.hasOwnProperty("hY") ? world["hY"] : 0.5; + inst.visible = world.hasOwnProperty("v") ? world["v"] : true; + inst.collisionsEnabled = world.hasOwnProperty("ce") ? world["ce"] : true; + inst.my_timescale = world.hasOwnProperty("mts") ? world["mts"] : -1; + inst.blend_mode = world.hasOwnProperty("bm") ? world["bm"] : 0;; + inst.compositeOp = cr.effectToCompositeOp(inst.blend_mode); + if (this.gl) + cr.setGLBlend(inst, inst.blend_mode, this.gl); + inst.set_bbox_changed(); + if (world.hasOwnProperty("fx")) + { + for (i = 0, len = world["fx"].length; i < len; i++) + { + fxindex = type.getEffectIndexByName(world["fx"][i]["name"]); + if (fxindex < 0) + continue; // must've gone missing + inst.active_effect_flags[fxindex] = world["fx"][i]["active"]; + inst.effect_params[fxindex] = world["fx"][i]["params"]; + } + } + inst.updateActiveEffects(); + } + obehs = o["behs"]; + if (obehs) + { + for (p in obehs) + { + if (obehs.hasOwnProperty(p)) + { + behindex = this.getBehaviorIndexBySid(inst, parseInt(p, 10)); + if (behindex < 0) + continue; // must've gone missing + inst.behavior_insts[behindex].loadFromJSON(obehs[p]); + } + } + } + if (o["data"]) + inst.loadFromJSON(o["data"]); + }; + cr.runtime = Runtime; + cr.createRuntime = function (canvasid) + { + return new Runtime(document.getElementById(canvasid)); + }; + cr.createDCRuntime = function (w, h) + { + return new Runtime({ "dc": true, "width": w, "height": h }); + }; + window["cr_createRuntime"] = cr.createRuntime; + window["cr_createDCRuntime"] = cr.createDCRuntime; + window["createCocoonJSRuntime"] = function () + { + window["c2cocoonjs"] = true; + var canvas = document.createElement("screencanvas") || document.createElement("canvas"); + canvas.screencanvas = true; + document.body.appendChild(canvas); + var rt = new Runtime(canvas); + window["c2runtime"] = rt; + window.addEventListener("orientationchange", function () { + window["c2runtime"]["setSize"](window.innerWidth, window.innerHeight); + }); + window["c2runtime"]["setSize"](window.innerWidth, window.innerHeight); + return rt; + }; + window["createEjectaRuntime"] = function () + { + var canvas = document.getElementById("canvas"); + var rt = new Runtime(canvas); + window["c2runtime"] = rt; + window["c2runtime"]["setSize"](window.innerWidth, window.innerHeight); + return rt; + }; +}()); +window["cr_getC2Runtime"] = function() +{ + var canvas = document.getElementById("c2canvas"); + if (canvas) + return canvas["c2runtime"]; + else if (window["c2runtime"]) + return window["c2runtime"]; + else + return null; +} +window["cr_sizeCanvas"] = function(w, h) +{ + if (w === 0 || h === 0) + return; + var runtime = window["cr_getC2Runtime"](); + if (runtime) + runtime["setSize"](w, h); +} +window["cr_setSuspended"] = function(s) +{ + var runtime = window["cr_getC2Runtime"](); + if (runtime) + runtime["setSuspended"](s); +} +; +(function() +{ + function Layout(runtime, m) + { + this.runtime = runtime; + this.event_sheet = null; + this.scrollX = (this.runtime.original_width / 2); + this.scrollY = (this.runtime.original_height / 2); + this.scale = 1.0; + this.angle = 0; + this.first_visit = true; + this.name = m[0]; + this.width = m[1]; + this.height = m[2]; + this.unbounded_scrolling = m[3]; + this.sheetname = m[4]; + this.sid = m[5]; + var lm = m[6]; + var i, len; + this.layers = []; + this.initial_types = []; + for (i = 0, len = lm.length; i < len; i++) + { + var layer = new cr.layer(this, lm[i]); + layer.number = i; + cr.seal(layer); + this.layers.push(layer); + } + var im = m[7]; + this.initial_nonworld = []; + for (i = 0, len = im.length; i < len; i++) + { + var inst = im[i]; + var type = this.runtime.types_by_index[inst[1]]; +; + if (!type.default_instance) + type.default_instance = inst; + this.initial_nonworld.push(inst); + if (this.initial_types.indexOf(type) === -1) + this.initial_types.push(type); + } + this.effect_types = []; + this.active_effect_types = []; + this.effect_params = []; + for (i = 0, len = m[8].length; i < len; i++) + { + this.effect_types.push({ + id: m[8][i][0], + name: m[8][i][1], + shaderindex: -1, + active: true, + index: i + }); + this.effect_params.push(m[8][i][2].slice(0)); + } + this.updateActiveEffects(); + this.rcTex = new cr.rect(0, 0, 1, 1); + this.rcTex2 = new cr.rect(0, 0, 1, 1); + this.persist_data = {}; + }; + Layout.prototype.saveObjectToPersist = function (inst) + { + var sidStr = inst.type.sid.toString(); + if (!this.persist_data.hasOwnProperty(sidStr)) + this.persist_data[sidStr] = []; + var type_persist = this.persist_data[sidStr]; + type_persist.push(this.runtime.saveInstanceToJSON(inst)); + }; + Layout.prototype.hasOpaqueBottomLayer = function () + { + var layer = this.layers[0]; + return !layer.transparent && layer.opacity === 1.0 && !layer.forceOwnTexture && layer.visible; + }; + Layout.prototype.updateActiveEffects = function () + { + this.active_effect_types.length = 0; + var i, len, et; + for (i = 0, len = this.effect_types.length; i < len; i++) + { + et = this.effect_types[i]; + if (et.active) + this.active_effect_types.push(et); + } + }; + Layout.prototype.getEffectByName = function (name_) + { + var i, len, et; + for (i = 0, len = this.effect_types.length; i < len; i++) + { + et = this.effect_types[i]; + if (et.name === name_) + return et; + } + return null; + }; + var created_instances = []; + function sort_by_zindex(a, b) + { + return a.zindex - b.zindex; + }; + var first_layout = true; + Layout.prototype.startRunning = function () + { + if (this.sheetname) + { + this.event_sheet = this.runtime.eventsheets[this.sheetname]; +; + this.event_sheet.updateDeepIncludes(); + } + this.runtime.running_layout = this; + this.scrollX = (this.runtime.original_width / 2); + this.scrollY = (this.runtime.original_height / 2); + var i, k, len, lenk, type, type_instances, inst, iid, t, s, p, q, type_data, layer; + for (i = 0, len = this.runtime.types_by_index.length; i < len; i++) + { + type = this.runtime.types_by_index[i]; + if (type.is_family) + continue; // instances are only transferred for their real type + type_instances = type.instances; + for (k = 0, lenk = type_instances.length; k < lenk; k++) + { + inst = type_instances[k]; + if (inst.layer) + { + var num = inst.layer.number; + if (num >= this.layers.length) + num = this.layers.length - 1; + inst.layer = this.layers[num]; + if (inst.layer.instances.indexOf(inst) === -1) + inst.layer.instances.push(inst); + inst.layer.zindices_stale = true; + } + } + } + if (!first_layout) + { + for (i = 0, len = this.layers.length; i < len; ++i) + { + this.layers[i].instances.sort(sort_by_zindex); + } + } + var layer; + created_instances.length = 0; + this.boundScrolling(); + for (i = 0, len = this.layers.length; i < len; i++) + { + layer = this.layers[i]; + layer.createInitialInstances(); // fills created_instances + layer.updateViewport(null); + } + var uids_changed = false; + if (!this.first_visit) + { + for (p in this.persist_data) + { + if (this.persist_data.hasOwnProperty(p)) + { + type = this.runtime.getObjectTypeBySid(parseInt(p, 10)); + if (!type || type.is_family || !this.runtime.typeHasPersistBehavior(type)) + continue; + type_data = this.persist_data[p]; + for (i = 0, len = type_data.length; i < len; i++) + { + layer = null; + if (type.plugin.is_world) + { + layer = this.getLayerBySid(type_data[i]["w"]["l"]); + if (!layer) + continue; + } + inst = this.runtime.createInstanceFromInit(type.default_instance, layer, false, 0, 0, true); + this.runtime.loadInstanceFromJSON(inst, type_data[i]); + uids_changed = true; + created_instances.push(inst); + } + type_data.length = 0; + } + } + for (i = 0, len = this.layers.length; i < len; i++) + { + this.layers[i].instances.sort(sort_by_zindex); + this.layers[i].zindices_stale = true; // in case of duplicates/holes + } + } + if (uids_changed) + { + this.runtime.ClearDeathRow(); + this.runtime.refreshUidMap(); + } + for (i = 0; i < created_instances.length; i++) + { + inst = created_instances[i]; + if (!inst.type.is_contained) + continue; + iid = inst.get_iid(); + for (k = 0, lenk = inst.type.container.length; k < lenk; k++) + { + t = inst.type.container[k]; + if (inst.type === t) + continue; + if (t.instances.length > iid) + inst.siblings.push(t.instances[iid]); + else + { + if (!t.default_instance) + { + } + else + { + s = this.runtime.createInstanceFromInit(t.default_instance, inst.layer, true, inst.x, inst.y, true); + this.runtime.ClearDeathRow(); + t.updateIIDs(); + inst.siblings.push(s); + created_instances.push(s); // come back around and link up its own instances too + } + } + } + } + for (i = 0, len = this.initial_nonworld.length; i < len; i++) + { + inst = this.runtime.createInstanceFromInit(this.initial_nonworld[i], null, true); +; + } + this.runtime.changelayout = null; + this.runtime.ClearDeathRow(); + if (this.runtime.ctx && !this.runtime.isDomFree) + { + for (i = 0, len = this.runtime.types_by_index.length; i < len; i++) + { + t = this.runtime.types_by_index[i]; + if (t.is_family || !t.instances.length || !t.preloadCanvas2D) + continue; + t.preloadCanvas2D(this.runtime.ctx); + } + } + /* + if (this.runtime.glwrap) + { + console.log("Estimated VRAM at layout start: " + this.runtime.glwrap.textureCount() + " textures, approx. " + Math.round(this.runtime.glwrap.estimateVRAM() / 1024) + " kb"); + } + */ + for (i = 0, len = created_instances.length; i < len; i++) + { + inst = created_instances[i]; + this.runtime.trigger(Object.getPrototypeOf(inst.type.plugin).cnds.OnCreated, inst); + } + created_instances.length = 0; + this.runtime.trigger(cr.system_object.prototype.cnds.OnLayoutStart, null); + this.first_visit = false; + }; + Layout.prototype.createGlobalNonWorlds = function () + { + var i, k, len, initial_inst, inst, type; + for (i = 0, k = 0, len = this.initial_nonworld.length; i < len; i++) + { + initial_inst = this.initial_nonworld[i]; + type = this.runtime.types_by_index[initial_inst[1]]; + if (type.global) + inst = this.runtime.createInstanceFromInit(initial_inst, null, true); + else + { + this.initial_nonworld[k] = initial_inst; + k++; + } + } + this.initial_nonworld.length = k; + }; + Layout.prototype.stopRunning = function () + { +; + /* + if (this.runtime.glwrap) + { + console.log("Estimated VRAM at layout end: " + this.runtime.glwrap.textureCount() + " textures, approx. " + Math.round(this.runtime.glwrap.estimateVRAM() / 1024) + " kb"); + } + */ + this.runtime.trigger(cr.system_object.prototype.cnds.OnLayoutEnd, null); + this.runtime.system.waits.length = 0; + var i, leni, j, lenj; + var layer_instances, inst, type; + if (!this.first_visit) + { + for (i = 0, leni = this.layers.length; i < leni; i++) + { + this.layers[i].updateZIndices(); + layer_instances = this.layers[i].instances; + for (j = 0, lenj = layer_instances.length; j < lenj; j++) + { + inst = layer_instances[j]; + if (!inst.type.global) + { + if (this.runtime.typeHasPersistBehavior(inst.type)) + this.saveObjectToPersist(inst); + } + } + } + } + for (i = 0, leni = this.layers.length; i < leni; i++) + { + layer_instances = this.layers[i].instances; + for (j = 0, lenj = layer_instances.length; j < lenj; j++) + { + inst = layer_instances[j]; + if (!inst.type.global) + { + this.runtime.DestroyInstance(inst); + } + } + this.runtime.ClearDeathRow(); + layer_instances.length = 0; + this.layers[i].zindices_stale = true; + } + for (i = 0, leni = this.runtime.types_by_index.length; i < leni; i++) + { + type = this.runtime.types_by_index[i]; + if (type.global || type.plugin.is_world || type.plugin.singleglobal || type.is_family) + continue; + for (j = 0, lenj = type.instances.length; j < lenj; j++) + this.runtime.DestroyInstance(type.instances[j]); + this.runtime.ClearDeathRow(); + } + first_layout = false; + }; + var temp_rect = new cr.rect(0, 0, 0, 0); + Layout.prototype.recreateInitialObjects = function (type, x1, y1, x2, y2) + { + temp_rect.set(x1, y1, x2, y2); + var i, len; + for (i = 0, len = this.layers.length; i < len; i++) + { + this.layers[i].recreateInitialObjects(type, temp_rect); + } + }; + Layout.prototype.draw = function (ctx) + { + var layout_canvas; + var layout_ctx = ctx; + var ctx_changed = false; + var render_offscreen = !this.runtime.fullscreenScalingQuality; + if (render_offscreen) + { + if (!this.runtime.layout_canvas) + { + this.runtime.layout_canvas = document.createElement("canvas"); + layout_canvas = this.runtime.layout_canvas; + layout_canvas.width = this.runtime.draw_width; + layout_canvas.height = this.runtime.draw_height; + this.runtime.layout_ctx = layout_canvas.getContext("2d"); + ctx_changed = true; + } + layout_canvas = this.runtime.layout_canvas; + layout_ctx = this.runtime.layout_ctx; + if (layout_canvas.width !== this.runtime.draw_width) + { + layout_canvas.width = this.runtime.draw_width; + ctx_changed = true; + } + if (layout_canvas.height !== this.runtime.draw_height) + { + layout_canvas.height = this.runtime.draw_height; + ctx_changed = true; + } + if (ctx_changed) + { + layout_ctx["webkitImageSmoothingEnabled"] = this.runtime.linearSampling; + layout_ctx["mozImageSmoothingEnabled"] = this.runtime.linearSampling; + layout_ctx["msImageSmoothingEnabled"] = this.runtime.linearSampling; + layout_ctx["imageSmoothingEnabled"] = this.runtime.linearSampling; + } + } + layout_ctx.globalAlpha = 1; + layout_ctx.globalCompositeOperation = "source-over"; + if (this.runtime.alphaBackground && !this.hasOpaqueBottomLayer()) + layout_ctx.clearRect(0, 0, this.runtime.draw_width, this.runtime.draw_height); + var i, len, l; + for (i = 0, len = this.layers.length; i < len; i++) + { + l = this.layers[i]; + if (l.visible && l.opacity > 0 && l.blend_mode !== 11 && (l.instances.length || !l.transparent)) + l.draw(layout_ctx); + else + l.updateViewport(null); // even if not drawing, keep viewport up to date + } + if (render_offscreen) + { + ctx.drawImage(layout_canvas, 0, 0, this.runtime.width, this.runtime.height); + } + }; + Layout.prototype.drawGL = function (glw) + { + var render_to_texture = (this.active_effect_types.length > 0 || + this.runtime.uses_background_blending || + !this.runtime.fullscreenScalingQuality); + if (render_to_texture) + { + if (!this.runtime.layout_tex) + { + this.runtime.layout_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.linearSampling); + } + if (this.runtime.layout_tex.c2width !== this.runtime.draw_width || this.runtime.layout_tex.c2height !== this.runtime.draw_height) + { + glw.deleteTexture(this.runtime.layout_tex); + this.runtime.layout_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.linearSampling); + } + glw.setRenderingToTexture(this.runtime.layout_tex); + if (!this.runtime.fullscreenScalingQuality) + { + glw.setSize(this.runtime.draw_width, this.runtime.draw_height); + } + } + else + { + if (this.runtime.layout_tex) + { + glw.setRenderingToTexture(null); + glw.deleteTexture(this.runtime.layout_tex); + this.runtime.layout_tex = null; + } + } + if (this.runtime.alphaBackground && !this.hasOpaqueBottomLayer()) + glw.clear(0, 0, 0, 0); + var i, len, l; + for (i = 0, len = this.layers.length; i < len; i++) + { + l = this.layers[i]; + if (l.visible && l.opacity > 0 && (l.instances.length || !l.transparent)) + l.drawGL(glw); + else + l.updateViewport(null); // even if not drawing, keep viewport up to date + } + if (render_to_texture) + { + if (this.active_effect_types.length === 0 || + (this.active_effect_types.length === 1 && this.runtime.fullscreenScalingQuality)) + { + if (this.active_effect_types.length === 1) + { + var etindex = this.active_effect_types[0].index; + glw.switchProgram(this.active_effect_types[0].shaderindex); + glw.setProgramParameters(null, // backTex + 1.0 / this.runtime.draw_width, // pixelWidth + 1.0 / this.runtime.draw_height, // pixelHeight + 0.0, 0.0, // destStart + 1.0, 1.0, // destEnd + this.scale, // layerScale + this.angle, // layerAngle + 0.0, 0.0, // viewOrigin + this.runtime.draw_width / 2, this.runtime.draw_height / 2, // scrollPos + this.effect_params[etindex]); // fx parameters + if (glw.programIsAnimated(this.active_effect_types[0].shaderindex)) + this.runtime.redraw = true; + } + else + glw.switchProgram(0); + if (!this.runtime.fullscreenScalingQuality) + { + glw.setSize(this.runtime.width, this.runtime.height); + } + glw.setRenderingToTexture(null); // to backbuffer + glw.setOpacity(1); + glw.setTexture(this.runtime.layout_tex); + glw.setAlphaBlend(); + glw.resetModelView(); + glw.updateModelView(); + var halfw = this.runtime.width / 2; + var halfh = this.runtime.height / 2; + glw.quad(-halfw, halfh, halfw, halfh, halfw, -halfh, -halfw, -halfh); + glw.setTexture(null); + } + else + { + this.renderEffectChain(glw, null, null, null); + } + } + }; + Layout.prototype.getRenderTarget = function() + { + return (this.active_effect_types.length > 0 || + this.runtime.uses_background_blending || + !this.runtime.fullscreenScalingQuality) ? this.runtime.layout_tex : null; + }; + Layout.prototype.getMinLayerScale = function () + { + var m = this.layers[0].getScale(); + var i, len, l; + for (i = 1, len = this.layers.length; i < len; i++) + { + l = this.layers[i]; + if (l.parallaxX === 0 && l.parallaxY === 0) + continue; + if (l.getScale() < m) + m = l.getScale(); + } + return m; + }; + Layout.prototype.scrollToX = function (x) + { + if (!this.unbounded_scrolling) + { + var widthBoundary = (this.runtime.draw_width * (1 / this.getMinLayerScale()) / 2); + if (x > this.width - widthBoundary) + x = this.width - widthBoundary; + if (x < widthBoundary) + x = widthBoundary; + } + if (this.scrollX !== x) + { + this.scrollX = x; + this.runtime.redraw = true; + } + }; + Layout.prototype.scrollToY = function (y) + { + if (!this.unbounded_scrolling) + { + var heightBoundary = (this.runtime.draw_height * (1 / this.getMinLayerScale()) / 2); + if (y > this.height - heightBoundary) + y = this.height - heightBoundary; + if (y < heightBoundary) + y = heightBoundary; + } + if (this.scrollY !== y) + { + this.scrollY = y; + this.runtime.redraw = true; + } + }; + Layout.prototype.boundScrolling = function () + { + this.scrollToX(this.scrollX); + this.scrollToY(this.scrollY); + }; + Layout.prototype.renderEffectChain = function (glw, layer, inst, rendertarget) + { + var active_effect_types = inst ? + inst.active_effect_types : + layer ? + layer.active_effect_types : + this.active_effect_types; + var layerScale = 1, layerAngle = 0, viewOriginLeft = 0, viewOriginTop = 0, viewOriginRight = this.runtime.draw_width, viewOriginBottom = this.runtime.draw_height; + if (inst) + { + layerScale = inst.layer.getScale(); + layerAngle = inst.layer.getAngle(); + viewOriginLeft = inst.layer.viewLeft; + viewOriginTop = inst.layer.viewTop; + viewOriginRight = inst.layer.viewRight; + viewOriginBottom = inst.layer.viewBottom; + } + else if (layer) + { + layerScale = layer.getScale(); + layerAngle = layer.getAngle(); + viewOriginLeft = layer.viewLeft; + viewOriginTop = layer.viewTop; + viewOriginRight = layer.viewRight; + viewOriginBottom = layer.viewBottom; + } + var fx_tex = this.runtime.fx_tex; + var i, len, last, temp, fx_index = 0, other_fx_index = 1; + var y, h; + var windowWidth = this.runtime.draw_width; + var windowHeight = this.runtime.draw_height; + var halfw = windowWidth / 2; + var halfh = windowHeight / 2; + var rcTex = layer ? layer.rcTex : this.rcTex; + var rcTex2 = layer ? layer.rcTex2 : this.rcTex2; + var screenleft = 0, clearleft = 0; + var screentop = 0, cleartop = 0; + var screenright = windowWidth, clearright = windowWidth; + var screenbottom = windowHeight, clearbottom = windowHeight; + var boxExtendHorizontal = 0; + var boxExtendVertical = 0; + var inst_layer_angle = inst ? inst.layer.getAngle() : 0; + if (inst) + { + for (i = 0, len = active_effect_types.length; i < len; i++) + { + boxExtendHorizontal += glw.getProgramBoxExtendHorizontal(active_effect_types[i].shaderindex); + boxExtendVertical += glw.getProgramBoxExtendVertical(active_effect_types[i].shaderindex); + } + var bbox = inst.bbox; + screenleft = layer.layerToCanvas(bbox.left, bbox.top, true, true); + screentop = layer.layerToCanvas(bbox.left, bbox.top, false, true); + screenright = layer.layerToCanvas(bbox.right, bbox.bottom, true, true); + screenbottom = layer.layerToCanvas(bbox.right, bbox.bottom, false, true); + if (inst_layer_angle !== 0) + { + var screentrx = layer.layerToCanvas(bbox.right, bbox.top, true, true); + var screentry = layer.layerToCanvas(bbox.right, bbox.top, false, true); + var screenblx = layer.layerToCanvas(bbox.left, bbox.bottom, true, true); + var screenbly = layer.layerToCanvas(bbox.left, bbox.bottom, false, true); + temp = Math.min(screenleft, screenright, screentrx, screenblx); + screenright = Math.max(screenleft, screenright, screentrx, screenblx); + screenleft = temp; + temp = Math.min(screentop, screenbottom, screentry, screenbly); + screenbottom = Math.max(screentop, screenbottom, screentry, screenbly); + screentop = temp; + } + screenleft -= boxExtendHorizontal; + screentop -= boxExtendVertical; + screenright += boxExtendHorizontal; + screenbottom += boxExtendVertical; + rcTex2.left = screenleft / windowWidth; + rcTex2.top = 1 - screentop / windowHeight; + rcTex2.right = screenright / windowWidth; + rcTex2.bottom = 1 - screenbottom / windowHeight; + clearleft = screenleft = cr.floor(screenleft); + cleartop = screentop = cr.floor(screentop); + clearright = screenright = cr.ceil(screenright); + clearbottom = screenbottom = cr.ceil(screenbottom); + clearleft -= boxExtendHorizontal; + cleartop -= boxExtendVertical; + clearright += boxExtendHorizontal; + clearbottom += boxExtendVertical; + if (screenleft < 0) screenleft = 0; + if (screentop < 0) screentop = 0; + if (screenright > windowWidth) screenright = windowWidth; + if (screenbottom > windowHeight) screenbottom = windowHeight; + if (clearleft < 0) clearleft = 0; + if (cleartop < 0) cleartop = 0; + if (clearright > windowWidth) clearright = windowWidth; + if (clearbottom > windowHeight) clearbottom = windowHeight; + rcTex.left = screenleft / windowWidth; + rcTex.top = 1 - screentop / windowHeight; + rcTex.right = screenright / windowWidth; + rcTex.bottom = 1 - screenbottom / windowHeight; + } + else + { + rcTex.left = rcTex2.left = 0; + rcTex.top = rcTex2.top = 0; + rcTex.right = rcTex2.right = 1; + rcTex.bottom = rcTex2.bottom = 1; + } + var pre_draw = (inst && (((inst.angle || inst_layer_angle) && glw.programUsesDest(active_effect_types[0].shaderindex)) || boxExtendHorizontal !== 0 || boxExtendVertical !== 0 || inst.opacity !== 1 || inst.type.plugin.must_predraw)) || (layer && !inst && layer.opacity !== 1); + glw.setAlphaBlend(); + if (pre_draw) + { + if (!fx_tex[fx_index]) + { + fx_tex[fx_index] = glw.createEmptyTexture(windowWidth, windowHeight, this.runtime.linearSampling); + } + if (fx_tex[fx_index].c2width !== windowWidth || fx_tex[fx_index].c2height !== windowHeight) + { + glw.deleteTexture(fx_tex[fx_index]); + fx_tex[fx_index] = glw.createEmptyTexture(windowWidth, windowHeight, this.runtime.linearSampling); + } + glw.switchProgram(0); + glw.setRenderingToTexture(fx_tex[fx_index]); + h = clearbottom - cleartop; + y = (windowHeight - cleartop) - h; + glw.clearRect(clearleft, y, clearright - clearleft, h); + if (inst) + { + inst.drawGL(glw); + } + else + { + glw.setTexture(this.runtime.layer_tex); + glw.setOpacity(layer.opacity); + glw.resetModelView(); + glw.translate(-halfw, -halfh); + glw.updateModelView(); + glw.quadTex(screenleft, screenbottom, screenright, screenbottom, screenright, screentop, screenleft, screentop, rcTex); + } + rcTex2.left = rcTex2.top = 0; + rcTex2.right = rcTex2.bottom = 1; + if (inst) + { + temp = rcTex.top; + rcTex.top = rcTex.bottom; + rcTex.bottom = temp; + } + fx_index = 1; + other_fx_index = 0; + } + glw.setOpacity(1); + var last = active_effect_types.length - 1; + var post_draw = glw.programUsesCrossSampling(active_effect_types[last].shaderindex) || + (!layer && !inst && !this.runtime.fullscreenScalingQuality); + var etindex = 0; + for (i = 0, len = active_effect_types.length; i < len; i++) + { + if (!fx_tex[fx_index]) + { + fx_tex[fx_index] = glw.createEmptyTexture(windowWidth, windowHeight, this.runtime.linearSampling); + } + if (fx_tex[fx_index].c2width !== windowWidth || fx_tex[fx_index].c2height !== windowHeight) + { + glw.deleteTexture(fx_tex[fx_index]); + fx_tex[fx_index] = glw.createEmptyTexture(windowWidth, windowHeight, this.runtime.linearSampling); + } + glw.switchProgram(active_effect_types[i].shaderindex); + etindex = active_effect_types[i].index; + if (glw.programIsAnimated(active_effect_types[i].shaderindex)) + this.runtime.redraw = true; + if (i == 0 && !pre_draw) + { + glw.setRenderingToTexture(fx_tex[fx_index]); + h = clearbottom - cleartop; + y = (windowHeight - cleartop) - h; + glw.clearRect(clearleft, y, clearright - clearleft, h); + if (inst) + { + glw.setProgramParameters(rendertarget, // backTex + 1.0 / inst.width, // pixelWidth + 1.0 / inst.height, // pixelHeight + rcTex2.left, rcTex2.top, // destStart + rcTex2.right, rcTex2.bottom, // destEnd + layerScale, + layerAngle, + viewOriginLeft, viewOriginTop, + (viewOriginLeft + viewOriginRight) / 2, (viewOriginTop + viewOriginBottom) / 2, + inst.effect_params[etindex]); // fx params + inst.drawGL(glw); + } + else + { + glw.setProgramParameters(rendertarget, // backTex + 1.0 / windowWidth, // pixelWidth + 1.0 / windowHeight, // pixelHeight + 0.0, 0.0, // destStart + 1.0, 1.0, // destEnd + layerScale, + layerAngle, + viewOriginLeft, viewOriginTop, + (viewOriginLeft + viewOriginRight) / 2, (viewOriginTop + viewOriginBottom) / 2, + layer ? // fx params + layer.effect_params[etindex] : + this.effect_params[etindex]); + glw.setTexture(layer ? this.runtime.layer_tex : this.runtime.layout_tex); + glw.resetModelView(); + glw.translate(-halfw, -halfh); + glw.updateModelView(); + glw.quadTex(screenleft, screenbottom, screenright, screenbottom, screenright, screentop, screenleft, screentop, rcTex); + } + rcTex2.left = rcTex2.top = 0; + rcTex2.right = rcTex2.bottom = 1; + if (inst && !post_draw) + { + temp = screenbottom; + screenbottom = screentop; + screentop = temp; + } + } + else + { + glw.setProgramParameters(rendertarget, // backTex + 1.0 / windowWidth, // pixelWidth + 1.0 / windowHeight, // pixelHeight + rcTex2.left, rcTex2.top, // destStart + rcTex2.right, rcTex2.bottom, // destEnd + layerScale, + layerAngle, + viewOriginLeft, viewOriginTop, + (viewOriginLeft + viewOriginRight) / 2, (viewOriginTop + viewOriginBottom) / 2, + inst ? // fx params + inst.effect_params[etindex] : + layer ? + layer.effect_params[etindex] : + this.effect_params[etindex]); + glw.setTexture(null); + if (i === last && !post_draw) + { + if (inst) + glw.setBlend(inst.srcBlend, inst.destBlend); + else if (layer) + glw.setBlend(layer.srcBlend, layer.destBlend); + glw.setRenderingToTexture(rendertarget); + } + else + { + glw.setRenderingToTexture(fx_tex[fx_index]); + h = clearbottom - cleartop; + y = (windowHeight - cleartop) - h; + glw.clearRect(clearleft, y, clearright - clearleft, h); + } + glw.setTexture(fx_tex[other_fx_index]); + glw.resetModelView(); + glw.translate(-halfw, -halfh); + glw.updateModelView(); + glw.quadTex(screenleft, screenbottom, screenright, screenbottom, screenright, screentop, screenleft, screentop, rcTex); + if (i === last && !post_draw) + glw.setTexture(null); + } + fx_index = (fx_index === 0 ? 1 : 0); + other_fx_index = (fx_index === 0 ? 1 : 0); // will be opposite to fx_index since it was just assigned + } + if (post_draw) + { + glw.switchProgram(0); + if (inst) + glw.setBlend(inst.srcBlend, inst.destBlend); + else if (layer) + glw.setBlend(layer.srcBlend, layer.destBlend); + else + { + if (!this.runtime.fullscreenScalingQuality) + { + glw.setSize(this.runtime.width, this.runtime.height); + halfw = this.runtime.width / 2; + halfh = this.runtime.height / 2; + screenleft = 0; + screentop = 0; + screenright = this.runtime.width; + screenbottom = this.runtime.height; + } + } + glw.setRenderingToTexture(rendertarget); + glw.setTexture(fx_tex[other_fx_index]); + glw.resetModelView(); + glw.translate(-halfw, -halfh); + glw.updateModelView(); + if (inst && active_effect_types.length === 1 && !pre_draw) + glw.quadTex(screenleft, screentop, screenright, screentop, screenright, screenbottom, screenleft, screenbottom, rcTex); + else + glw.quadTex(screenleft, screenbottom, screenright, screenbottom, screenright, screentop, screenleft, screentop, rcTex); + glw.setTexture(null); + } + }; + Layout.prototype.getLayerBySid = function (sid_) + { + var i, len; + for (i = 0, len = this.layers.length; i < len; i++) + { + if (this.layers[i].sid === sid_) + return this.layers[i]; + } + return null; + }; + Layout.prototype.saveToJSON = function () + { + var i, len, layer, et; + var o = { + "sx": this.scrollX, + "sy": this.scrollY, + "s": this.scale, + "a": this.angle, + "w": this.width, + "h": this.height, + "fv": this.first_visit, // added r127 + "persist": this.persist_data, + "fx": [], + "layers": {} + }; + for (i = 0, len = this.effect_types.length; i < len; i++) + { + et = this.effect_types[i]; + o["fx"].push({"name": et.name, "active": et.active, "params": this.effect_params[et.index] }); + } + for (i = 0, len = this.layers.length; i < len; i++) + { + layer = this.layers[i]; + o["layers"][layer.sid.toString()] = layer.saveToJSON(); + } + return o; + }; + Layout.prototype.loadFromJSON = function (o) + { + var i, len, fx, p, layer; + this.scrollX = o["sx"]; + this.scrollY = o["sy"]; + this.scale = o["s"]; + this.angle = o["a"]; + this.width = o["w"]; + this.height = o["h"]; + this.persist_data = o["persist"]; + if (typeof o["fv"] !== "undefined") + this.first_visit = o["fv"]; + var ofx = o["fx"]; + for (i = 0, len = ofx.length; i < len; i++) + { + fx = this.getEffectByName(ofx[i]["name"]); + if (!fx) + continue; // must've gone missing + fx.active = ofx[i]["active"]; + this.effect_params[fx.index] = ofx[i]["params"]; + } + this.updateActiveEffects(); + var olayers = o["layers"]; + for (p in olayers) + { + if (olayers.hasOwnProperty(p)) + { + layer = this.getLayerBySid(parseInt(p, 10)); + if (!layer) + continue; // must've gone missing + layer.loadFromJSON(olayers[p]); + } + } + }; + cr.layout = Layout; + function Layer(layout, m) + { + this.layout = layout; + this.runtime = layout.runtime; + this.instances = []; // running instances + this.scale = 1.0; + this.angle = 0; + this.disableAngle = false; + this.tmprect = new cr.rect(0, 0, 0, 0); + this.tmpquad = new cr.quad(); + this.viewLeft = 0; + this.viewRight = 0; + this.viewTop = 0; + this.viewBottom = 0; + this.zindices_stale = false; + this.zindices_stale_from = -1; // first index that has changed, or -1 if no bound + this.name = m[0]; + this.index = m[1]; + this.sid = m[2]; + this.visible = m[3]; // initially visible + this.background_color = m[4]; + this.transparent = m[5]; + this.parallaxX = m[6]; + this.parallaxY = m[7]; + this.opacity = m[8]; + this.forceOwnTexture = m[9]; + this.useRenderCells = m[10]; + this.zoomRate = m[11]; + this.blend_mode = m[12]; + this.effect_fallback = m[13]; + this.compositeOp = "source-over"; + this.srcBlend = 0; + this.destBlend = 0; + this.render_grid = null; + this.last_render_list = alloc_arr(); + this.render_list_stale = true; + this.last_render_cells = new cr.rect(0, 0, -1, -1); + this.cur_render_cells = new cr.rect(0, 0, -1, -1); + if (this.useRenderCells) + { + this.render_grid = new cr.RenderGrid(this.runtime.original_width, this.runtime.original_height); + } + this.render_offscreen = false; + var im = m[14]; + var i, len; + this.initial_instances = []; + for (i = 0, len = im.length; i < len; i++) + { + var inst = im[i]; + var type = this.runtime.types_by_index[inst[1]]; +; + if (!type.default_instance) + { + type.default_instance = inst; + type.default_layerindex = this.index; + } + this.initial_instances.push(inst); + if (this.layout.initial_types.indexOf(type) === -1) + this.layout.initial_types.push(type); + } + this.effect_types = []; + this.active_effect_types = []; + this.effect_params = []; + for (i = 0, len = m[15].length; i < len; i++) + { + this.effect_types.push({ + id: m[15][i][0], + name: m[15][i][1], + shaderindex: -1, + active: true, + index: i + }); + this.effect_params.push(m[15][i][2].slice(0)); + } + this.updateActiveEffects(); + this.rcTex = new cr.rect(0, 0, 1, 1); + this.rcTex2 = new cr.rect(0, 0, 1, 1); + }; + Layer.prototype.updateActiveEffects = function () + { + this.active_effect_types.length = 0; + var i, len, et; + for (i = 0, len = this.effect_types.length; i < len; i++) + { + et = this.effect_types[i]; + if (et.active) + this.active_effect_types.push(et); + } + }; + Layer.prototype.getEffectByName = function (name_) + { + var i, len, et; + for (i = 0, len = this.effect_types.length; i < len; i++) + { + et = this.effect_types[i]; + if (et.name === name_) + return et; + } + return null; + }; + Layer.prototype.createInitialInstances = function () + { + var i, k, len, inst, initial_inst, type, keep, hasPersistBehavior; + for (i = 0, k = 0, len = this.initial_instances.length; i < len; i++) + { + initial_inst = this.initial_instances[i]; + type = this.runtime.types_by_index[initial_inst[1]]; +; + hasPersistBehavior = this.runtime.typeHasPersistBehavior(type); + keep = true; + if (!hasPersistBehavior || this.layout.first_visit) + { + inst = this.runtime.createInstanceFromInit(initial_inst, this, true); +; + created_instances.push(inst); + if (inst.type.global) + keep = false; + } + if (keep) + { + this.initial_instances[k] = this.initial_instances[i]; + k++; + } + } + this.initial_instances.length = k; + this.runtime.ClearDeathRow(); // flushes creation row so IIDs will be correct + if (!this.runtime.glwrap && this.effect_types.length) // no WebGL renderer and shaders used + this.blend_mode = this.effect_fallback; // use fallback blend mode + this.compositeOp = cr.effectToCompositeOp(this.blend_mode); + if (this.runtime.gl) + cr.setGLBlend(this, this.blend_mode, this.runtime.gl); + this.render_list_stale = true; + }; + Layer.prototype.recreateInitialObjects = function (only_type, rc) + { + var i, len, initial_inst, type, wm, x, y, inst, j, lenj, s; + var types_by_index = this.runtime.types_by_index; + var only_type_is_family = only_type.is_family; + var only_type_members = only_type.members; + for (i = 0, len = this.initial_instances.length; i < len; ++i) + { + initial_inst = this.initial_instances[i]; + wm = initial_inst[0]; + x = wm[0]; + y = wm[1]; + if (!rc.contains_pt(x, y)) + continue; // not in the given area + type = types_by_index[initial_inst[1]]; + if (type !== only_type) + { + if (only_type_is_family) + { + if (only_type_members.indexOf(type) < 0) + continue; + } + else + continue; // only_type is not a family, and the initial inst type does not match + } + inst = this.runtime.createInstanceFromInit(initial_inst, this, false); + this.runtime.isInOnDestroy++; + this.runtime.trigger(Object.getPrototypeOf(type.plugin).cnds.OnCreated, inst); + if (inst.is_contained) + { + for (j = 0, lenj = inst.siblings.length; j < lenj; j++) + { + s = inst.siblings[i]; + this.runtime.trigger(Object.getPrototypeOf(s.type.plugin).cnds.OnCreated, s); + } + } + this.runtime.isInOnDestroy--; + } + }; + Layer.prototype.removeFromInstanceList = function (inst, remove_from_grid) + { + var index = cr.fastIndexOf(this.instances, inst); + if (index < 0) + return; // not found + if (remove_from_grid && this.useRenderCells && inst.rendercells && inst.rendercells.right >= inst.rendercells.left) + { + inst.update_bbox(); // make sure actually in its current rendercells + this.render_grid.update(inst, inst.rendercells, null); // no new range provided - remove only + inst.rendercells.set(0, 0, -1, -1); // set to invalid state to indicate not inserted + } + if (index === this.instances.length - 1) + this.instances.pop(); + else + { + cr.arrayRemove(this.instances, index); + this.setZIndicesStaleFrom(index); + } + this.render_list_stale = true; + }; + Layer.prototype.appendToInstanceList = function (inst, add_to_grid) + { +; + inst.zindex = this.instances.length; + this.instances.push(inst); + if (add_to_grid && this.useRenderCells && inst.rendercells) + { + inst.set_bbox_changed(); // will cause immediate update and new insertion to grid + } + this.render_list_stale = true; + }; + Layer.prototype.prependToInstanceList = function (inst, add_to_grid) + { +; + this.instances.unshift(inst); + this.setZIndicesStaleFrom(0); + if (add_to_grid && this.useRenderCells && inst.rendercells) + { + inst.set_bbox_changed(); // will cause immediate update and new insertion to grid + } + }; + Layer.prototype.moveInstanceAdjacent = function (inst, other, isafter) + { +; + var myZ = inst.get_zindex(); + var insertZ = other.get_zindex(); + cr.arrayRemove(this.instances, myZ); + if (myZ < insertZ) + insertZ--; + if (isafter) + insertZ++; + if (insertZ === this.instances.length) + this.instances.push(inst); + else + this.instances.splice(insertZ, 0, inst); + this.setZIndicesStaleFrom(myZ < insertZ ? myZ : insertZ); + }; + Layer.prototype.setZIndicesStaleFrom = function (index) + { + if (this.zindices_stale_from === -1) // not yet set + this.zindices_stale_from = index; + else if (index < this.zindices_stale_from) // determine minimum z index affected + this.zindices_stale_from = index; + this.zindices_stale = true; + this.render_list_stale = true; + }; + Layer.prototype.updateZIndices = function () + { + if (!this.zindices_stale) + return; + if (this.zindices_stale_from === -1) + this.zindices_stale_from = 0; + var i, len, inst; + if (this.useRenderCells) + { + for (i = this.zindices_stale_from, len = this.instances.length; i < len; ++i) + { + inst = this.instances[i]; + inst.zindex = i; + this.render_grid.markRangeChanged(inst.rendercells); + } + } + else + { + for (i = this.zindices_stale_from, len = this.instances.length; i < len; ++i) + { + this.instances[i].zindex = i; + } + } + this.zindices_stale = false; + this.zindices_stale_from = -1; + }; + Layer.prototype.getScale = function (include_aspect) + { + return this.getNormalScale() * (this.runtime.fullscreenScalingQuality || include_aspect ? this.runtime.aspect_scale : 1); + }; + Layer.prototype.getNormalScale = function () + { + return ((this.scale * this.layout.scale) - 1) * this.zoomRate + 1; + }; + Layer.prototype.getAngle = function () + { + if (this.disableAngle) + return 0; + return cr.clamp_angle(this.layout.angle + this.angle); + }; + var arr_cache = []; + function alloc_arr() + { + if (arr_cache.length) + return arr_cache.pop(); + else + return []; + } + function free_arr(a) + { + a.length = 0; + arr_cache.push(a); + }; + function mergeSortedZArrays(a, b, out) + { + var i = 0, j = 0, k = 0, lena = a.length, lenb = b.length, ai, bj; + out.length = lena + lenb; + for ( ; i < lena && j < lenb; ++k) + { + ai = a[i]; + bj = b[j]; + if (ai.zindex < bj.zindex) + { + out[k] = ai; + ++i; + } + else + { + out[k] = bj; + ++j; + } + } + for ( ; i < lena; ++i, ++k) + out[k] = a[i]; + for ( ; j < lenb; ++j, ++k) + out[k] = b[j]; + }; + var next_arr = []; + function mergeAllSortedZArrays_pass(arr, first_pass) + { + var i, len, arr1, arr2, out; + for (i = 0, len = arr.length; i < len - 1; i += 2) + { + arr1 = arr[i]; + arr2 = arr[i+1]; + out = alloc_arr(); + mergeSortedZArrays(arr1, arr2, out); + if (!first_pass) + { + free_arr(arr1); + free_arr(arr2); + } + next_arr.push(out); + } + if (len % 2 === 1) + { + if (first_pass) + { + arr1 = alloc_arr(); + cr.shallowAssignArray(arr1, arr[len - 1]); + next_arr.push(arr1); + } + else + { + next_arr.push(arr[len - 1]); + } + } + cr.shallowAssignArray(arr, next_arr); + next_arr.length = 0; + }; + function mergeAllSortedZArrays(arr) + { + var first_pass = true; + while (arr.length > 1) + { + mergeAllSortedZArrays_pass(arr, first_pass); + first_pass = false; + } + return arr[0]; + }; + var render_arr = []; + Layer.prototype.getRenderCellInstancesToDraw = function () + { +; + this.updateZIndices(); + this.render_grid.queryRange(this.viewLeft, this.viewTop, this.viewRight, this.viewBottom, render_arr); + if (!render_arr.length) + return alloc_arr(); + if (render_arr.length === 1) + { + var a = alloc_arr(); + cr.shallowAssignArray(a, render_arr[0]); + render_arr.length = 0; + return a; + } + var draw_list = mergeAllSortedZArrays(render_arr); + render_arr.length = 0; + return draw_list; + }; + Layer.prototype.draw = function (ctx) + { + this.render_offscreen = (this.forceOwnTexture || this.opacity !== 1.0 || this.blend_mode !== 0); + var layer_canvas = this.runtime.canvas; + var layer_ctx = ctx; + var ctx_changed = false; + if (this.render_offscreen) + { + if (!this.runtime.layer_canvas) + { + this.runtime.layer_canvas = document.createElement("canvas"); +; + layer_canvas = this.runtime.layer_canvas; + layer_canvas.width = this.runtime.draw_width; + layer_canvas.height = this.runtime.draw_height; + this.runtime.layer_ctx = layer_canvas.getContext("2d"); +; + ctx_changed = true; + } + layer_canvas = this.runtime.layer_canvas; + layer_ctx = this.runtime.layer_ctx; + if (layer_canvas.width !== this.runtime.draw_width) + { + layer_canvas.width = this.runtime.draw_width; + ctx_changed = true; + } + if (layer_canvas.height !== this.runtime.draw_height) + { + layer_canvas.height = this.runtime.draw_height; + ctx_changed = true; + } + if (ctx_changed) + { + layer_ctx["webkitImageSmoothingEnabled"] = this.runtime.linearSampling; + layer_ctx["mozImageSmoothingEnabled"] = this.runtime.linearSampling; + layer_ctx["msImageSmoothingEnabled"] = this.runtime.linearSampling; + layer_ctx["imageSmoothingEnabled"] = this.runtime.linearSampling; + } + if (this.transparent) + layer_ctx.clearRect(0, 0, this.runtime.draw_width, this.runtime.draw_height); + } + layer_ctx.globalAlpha = 1; + layer_ctx.globalCompositeOperation = "source-over"; + if (!this.transparent) + { + layer_ctx.fillStyle = "rgb(" + this.background_color[0] + "," + this.background_color[1] + "," + this.background_color[2] + ")"; + layer_ctx.fillRect(0, 0, this.runtime.draw_width, this.runtime.draw_height); + } + layer_ctx.save(); + this.disableAngle = true; + var px = this.canvasToLayer(0, 0, true, true); + var py = this.canvasToLayer(0, 0, false, true); + this.disableAngle = false; + if (this.runtime.pixel_rounding) + { + px = Math.round(px); + py = Math.round(py); + } + this.rotateViewport(px, py, layer_ctx); + var myscale = this.getScale(); + layer_ctx.scale(myscale, myscale); + layer_ctx.translate(-px, -py); + var instances_to_draw; + if (this.useRenderCells) + { + this.cur_render_cells.left = this.render_grid.XToCell(this.viewLeft); + this.cur_render_cells.top = this.render_grid.YToCell(this.viewTop); + this.cur_render_cells.right = this.render_grid.XToCell(this.viewRight); + this.cur_render_cells.bottom = this.render_grid.YToCell(this.viewBottom); + if (this.render_list_stale || !this.cur_render_cells.equals(this.last_render_cells)) + { + free_arr(this.last_render_list); + instances_to_draw = this.getRenderCellInstancesToDraw(); + this.render_list_stale = false; + this.last_render_cells.copy(this.cur_render_cells); + } + else + instances_to_draw = this.last_render_list; + } + else + instances_to_draw = this.instances; + var i, len, inst, last_inst = null; + for (i = 0, len = instances_to_draw.length; i < len; ++i) + { + inst = instances_to_draw[i]; + if (inst === last_inst) + continue; + this.drawInstance(inst, layer_ctx); + last_inst = inst; + } + if (this.useRenderCells) + this.last_render_list = instances_to_draw; + layer_ctx.restore(); + if (this.render_offscreen) + { + ctx.globalCompositeOperation = this.compositeOp; + ctx.globalAlpha = this.opacity; + ctx.drawImage(layer_canvas, 0, 0); + } + }; + Layer.prototype.drawInstance = function(inst, layer_ctx) + { + if (!inst.visible || inst.width === 0 || inst.height === 0) + return; + inst.update_bbox(); + var bbox = inst.bbox; + if (bbox.right < this.viewLeft || bbox.bottom < this.viewTop || bbox.left > this.viewRight || bbox.top > this.viewBottom) + return; + layer_ctx.globalCompositeOperation = inst.compositeOp; + inst.draw(layer_ctx); + }; + Layer.prototype.updateViewport = function (ctx) + { + this.disableAngle = true; + var px = this.canvasToLayer(0, 0, true, true); + var py = this.canvasToLayer(0, 0, false, true); + this.disableAngle = false; + if (this.runtime.pixel_rounding) + { + px = Math.round(px); + py = Math.round(py); + } + this.rotateViewport(px, py, ctx); + }; + Layer.prototype.rotateViewport = function (px, py, ctx) + { + var myscale = this.getScale(); + this.viewLeft = px; + this.viewTop = py; + this.viewRight = px + (this.runtime.draw_width * (1 / myscale)); + this.viewBottom = py + (this.runtime.draw_height * (1 / myscale)); + var myAngle = this.getAngle(); + if (myAngle !== 0) + { + if (ctx) + { + ctx.translate(this.runtime.draw_width / 2, this.runtime.draw_height / 2); + ctx.rotate(-myAngle); + ctx.translate(this.runtime.draw_width / -2, this.runtime.draw_height / -2); + } + this.tmprect.set(this.viewLeft, this.viewTop, this.viewRight, this.viewBottom); + this.tmprect.offset((this.viewLeft + this.viewRight) / -2, (this.viewTop + this.viewBottom) / -2); + this.tmpquad.set_from_rotated_rect(this.tmprect, myAngle); + this.tmpquad.bounding_box(this.tmprect); + this.tmprect.offset((this.viewLeft + this.viewRight) / 2, (this.viewTop + this.viewBottom) / 2); + this.viewLeft = this.tmprect.left; + this.viewTop = this.tmprect.top; + this.viewRight = this.tmprect.right; + this.viewBottom = this.tmprect.bottom; + } + } + Layer.prototype.drawGL = function (glw) + { + var windowWidth = this.runtime.draw_width; + var windowHeight = this.runtime.draw_height; + var shaderindex = 0; + var etindex = 0; + this.render_offscreen = (this.forceOwnTexture || this.opacity !== 1.0 || this.active_effect_types.length > 0 || this.blend_mode !== 0); + if (this.render_offscreen) + { + if (!this.runtime.layer_tex) + { + this.runtime.layer_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.linearSampling); + } + if (this.runtime.layer_tex.c2width !== this.runtime.draw_width || this.runtime.layer_tex.c2height !== this.runtime.draw_height) + { + glw.deleteTexture(this.runtime.layer_tex); + this.runtime.layer_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.linearSampling); + } + glw.setRenderingToTexture(this.runtime.layer_tex); + if (this.transparent) + glw.clear(0, 0, 0, 0); + } + if (!this.transparent) + { + glw.clear(this.background_color[0] / 255, this.background_color[1] / 255, this.background_color[2] / 255, 1); + } + this.disableAngle = true; + var px = this.canvasToLayer(0, 0, true, true); + var py = this.canvasToLayer(0, 0, false, true); + this.disableAngle = false; + if (this.runtime.pixel_rounding) + { + px = Math.round(px); + py = Math.round(py); + } + this.rotateViewport(px, py, null); + var myscale = this.getScale(); + glw.resetModelView(); + glw.scale(myscale, myscale); + glw.rotateZ(-this.getAngle()); + glw.translate((this.viewLeft + this.viewRight) / -2, (this.viewTop + this.viewBottom) / -2); + glw.updateModelView(); + var instances_to_draw; + if (this.useRenderCells) + { + this.cur_render_cells.left = this.render_grid.XToCell(this.viewLeft); + this.cur_render_cells.top = this.render_grid.YToCell(this.viewTop); + this.cur_render_cells.right = this.render_grid.XToCell(this.viewRight); + this.cur_render_cells.bottom = this.render_grid.YToCell(this.viewBottom); + if (this.render_list_stale || !this.cur_render_cells.equals(this.last_render_cells)) + { + free_arr(this.last_render_list); + instances_to_draw = this.getRenderCellInstancesToDraw(); + this.render_list_stale = false; + this.last_render_cells.copy(this.cur_render_cells); + } + else + instances_to_draw = this.last_render_list; + } + else + instances_to_draw = this.instances; + var i, len, inst, last_inst = null; + for (i = 0, len = instances_to_draw.length; i < len; ++i) + { + inst = instances_to_draw[i]; + if (inst === last_inst) + continue; + this.drawInstanceGL(instances_to_draw[i], glw); + last_inst = inst; + } + if (this.useRenderCells) + this.last_render_list = instances_to_draw; + if (this.render_offscreen) + { + shaderindex = this.active_effect_types.length ? this.active_effect_types[0].shaderindex : 0; + etindex = this.active_effect_types.length ? this.active_effect_types[0].index : 0; + if (this.active_effect_types.length === 0 || (this.active_effect_types.length === 1 && + !glw.programUsesCrossSampling(shaderindex) && this.opacity === 1)) + { + if (this.active_effect_types.length === 1) + { + glw.switchProgram(shaderindex); + glw.setProgramParameters(this.layout.getRenderTarget(), // backTex + 1.0 / this.runtime.draw_width, // pixelWidth + 1.0 / this.runtime.draw_height, // pixelHeight + 0.0, 0.0, // destStart + 1.0, 1.0, // destEnd + myscale, // layerScale + this.getAngle(), + this.viewLeft, this.viewTop, + (this.viewLeft + this.viewRight) / 2, (this.viewTop + this.viewBottom) / 2, + this.effect_params[etindex]); // fx parameters + if (glw.programIsAnimated(shaderindex)) + this.runtime.redraw = true; + } + else + glw.switchProgram(0); + glw.setRenderingToTexture(this.layout.getRenderTarget()); + glw.setOpacity(this.opacity); + glw.setTexture(this.runtime.layer_tex); + glw.setBlend(this.srcBlend, this.destBlend); + glw.resetModelView(); + glw.updateModelView(); + var halfw = this.runtime.draw_width / 2; + var halfh = this.runtime.draw_height / 2; + glw.quad(-halfw, halfh, halfw, halfh, halfw, -halfh, -halfw, -halfh); + glw.setTexture(null); + } + else + { + this.layout.renderEffectChain(glw, this, null, this.layout.getRenderTarget()); + } + } + }; + Layer.prototype.drawInstanceGL = function (inst, glw) + { +; + if (!inst.visible || inst.width === 0 || inst.height === 0) + return; + inst.update_bbox(); + var bbox = inst.bbox; + if (bbox.right < this.viewLeft || bbox.bottom < this.viewTop || bbox.left > this.viewRight || bbox.top > this.viewBottom) + return; + if (inst.uses_shaders) + { + this.drawInstanceWithShadersGL(inst, glw); + } + else + { + glw.switchProgram(0); // un-set any previously set shader + glw.setBlend(inst.srcBlend, inst.destBlend); + inst.drawGL(glw); + } + }; + Layer.prototype.drawInstanceWithShadersGL = function (inst, glw) + { + var shaderindex = inst.active_effect_types[0].shaderindex; + var etindex = inst.active_effect_types[0].index; + var myscale = this.getScale(); + if (inst.active_effect_types.length === 1 && !glw.programUsesCrossSampling(shaderindex) && + !glw.programExtendsBox(shaderindex) && ((!inst.angle && !inst.layer.getAngle()) || !glw.programUsesDest(shaderindex)) && + inst.opacity === 1 && !inst.type.plugin.must_predraw) + { + glw.switchProgram(shaderindex); + glw.setBlend(inst.srcBlend, inst.destBlend); + if (glw.programIsAnimated(shaderindex)) + this.runtime.redraw = true; + var destStartX = 0, destStartY = 0, destEndX = 0, destEndY = 0; + if (glw.programUsesDest(shaderindex)) + { + var bbox = inst.bbox; + var screenleft = this.layerToCanvas(bbox.left, bbox.top, true, true); + var screentop = this.layerToCanvas(bbox.left, bbox.top, false, true); + var screenright = this.layerToCanvas(bbox.right, bbox.bottom, true, true); + var screenbottom = this.layerToCanvas(bbox.right, bbox.bottom, false, true); + destStartX = screenleft / windowWidth; + destStartY = 1 - screentop / windowHeight; + destEndX = screenright / windowWidth; + destEndY = 1 - screenbottom / windowHeight; + } + glw.setProgramParameters(this.render_offscreen ? this.runtime.layer_tex : this.layout.getRenderTarget(), // backTex + 1.0 / inst.width, // pixelWidth + 1.0 / inst.height, // pixelHeight + destStartX, destStartY, + destEndX, destEndY, + myscale, + this.getAngle(), + this.viewLeft, this.viewTop, + (this.viewLeft + this.viewRight) / 2, (this.viewTop + this.viewBottom) / 2, + inst.effect_params[etindex]); + inst.drawGL(glw); + } + else + { + this.layout.renderEffectChain(glw, this, inst, this.render_offscreen ? this.runtime.layer_tex : this.layout.getRenderTarget()); + glw.resetModelView(); + glw.scale(myscale, myscale); + glw.rotateZ(-this.getAngle()); + glw.translate((this.viewLeft + this.viewRight) / -2, (this.viewTop + this.viewBottom) / -2); + glw.updateModelView(); + } + }; + Layer.prototype.canvasToLayer = function (ptx, pty, getx, using_draw_area) + { + var multiplier = this.runtime.devicePixelRatio; + if (this.runtime.isRetina) + { + ptx *= multiplier; + pty *= multiplier; + } + var ox = this.runtime.parallax_x_origin; + var oy = this.runtime.parallax_y_origin; + var par_x = ((this.layout.scrollX - ox) * this.parallaxX) + ox; + var par_y = ((this.layout.scrollY - oy) * this.parallaxY) + oy; + var x = par_x; + var y = par_y; + var invScale = 1 / this.getScale(!using_draw_area); + if (using_draw_area) + { + x -= (this.runtime.draw_width * invScale) / 2; + y -= (this.runtime.draw_height * invScale) / 2; + } + else + { + x -= (this.runtime.width * invScale) / 2; + y -= (this.runtime.height * invScale) / 2; + } + x += ptx * invScale; + y += pty * invScale; + var a = this.getAngle(); + if (a !== 0) + { + x -= par_x; + y -= par_y; + var cosa = Math.cos(a); + var sina = Math.sin(a); + var x_temp = (x * cosa) - (y * sina); + y = (y * cosa) + (x * sina); + x = x_temp; + x += par_x; + y += par_y; + } + return getx ? x : y; + }; + Layer.prototype.layerToCanvas = function (ptx, pty, getx, using_draw_area) + { + var ox = this.runtime.parallax_x_origin; + var oy = this.runtime.parallax_y_origin; + var par_x = ((this.layout.scrollX - ox) * this.parallaxX) + ox; + var par_y = ((this.layout.scrollY - oy) * this.parallaxY) + oy; + var x = par_x; + var y = par_y; + var a = this.getAngle(); + if (a !== 0) + { + ptx -= par_x; + pty -= par_y; + var cosa = Math.cos(-a); + var sina = Math.sin(-a); + var x_temp = (ptx * cosa) - (pty * sina); + pty = (pty * cosa) + (ptx * sina); + ptx = x_temp; + ptx += par_x; + pty += par_y; + } + var invScale = 1 / this.getScale(!using_draw_area); + if (using_draw_area) + { + x -= (this.runtime.draw_width * invScale) / 2; + y -= (this.runtime.draw_height * invScale) / 2; + } + else + { + x -= (this.runtime.width * invScale) / 2; + y -= (this.runtime.height * invScale) / 2; + } + x = (ptx - x) / invScale; + y = (pty - y) / invScale; + var multiplier = this.runtime.devicePixelRatio; + if (this.runtime.isRetina && !using_draw_area) + { + x /= multiplier; + y /= multiplier; + } + return getx ? x : y; + }; + Layer.prototype.rotatePt = function (x_, y_, getx) + { + if (this.getAngle() === 0) + return getx ? x_ : y_; + var nx = this.layerToCanvas(x_, y_, true); + var ny = this.layerToCanvas(x_, y_, false); + this.disableAngle = true; + var px = this.canvasToLayer(nx, ny, true); + var py = this.canvasToLayer(nx, ny, true); + this.disableAngle = false; + return getx ? px : py; + }; + Layer.prototype.saveToJSON = function () + { + var i, len, et; + var o = { + "s": this.scale, + "a": this.angle, + "vl": this.viewLeft, + "vt": this.viewTop, + "vr": this.viewRight, + "vb": this.viewBottom, + "v": this.visible, + "bc": this.background_color, + "t": this.transparent, + "px": this.parallaxX, + "py": this.parallaxY, + "o": this.opacity, + "zr": this.zoomRate, + "fx": [], + "instances": [] + }; + for (i = 0, len = this.effect_types.length; i < len; i++) + { + et = this.effect_types[i]; + o["fx"].push({"name": et.name, "active": et.active, "params": this.effect_params[et.index] }); + } + return o; + }; + Layer.prototype.loadFromJSON = function (o) + { + var i, len, p, inst, fx; + this.scale = o["s"]; + this.angle = o["a"]; + this.viewLeft = o["vl"]; + this.viewTop = o["vt"]; + this.viewRight = o["vr"]; + this.viewBottom = o["vb"]; + this.visible = o["v"]; + this.background_color = o["bc"]; + this.transparent = o["t"]; + this.parallaxX = o["px"]; + this.parallaxY = o["py"]; + this.opacity = o["o"]; + this.zoomRate = o["zr"]; + var ofx = o["fx"]; + for (i = 0, len = ofx.length; i < len; i++) + { + fx = this.getEffectByName(ofx[i]["name"]); + if (!fx) + continue; // must've gone missing + fx.active = ofx[i]["active"]; + this.effect_params[fx.index] = ofx[i]["params"]; + } + this.updateActiveEffects(); + this.instances.sort(sort_by_zindex); + this.zindices_stale = true; + }; + cr.layer = Layer; +}()); +; +(function() +{ + var allUniqueSolModifiers = []; + function testSolsMatch(arr1, arr2) + { + var i, len = arr1.length; + switch (len) { + case 0: + return true; + case 1: + return arr1[0] === arr2[0]; + case 2: + return arr1[0] === arr2[0] && arr1[1] === arr2[1]; + default: + for (i = 0; i < len; i++) + { + if (arr1[i] !== arr2[i]) + return false; + } + return true; + } + }; + function solArraySorter(t1, t2) + { + return t1.index - t2.index; + }; + function findMatchingSolModifier(arr) + { + var i, len, u, temp, subarr; + if (arr.length === 2) + { + if (arr[0].index > arr[1].index) + { + temp = arr[0]; + arr[0] = arr[1]; + arr[1] = temp; + } + } + else if (arr.length > 2) + arr.sort(solArraySorter); // so testSolsMatch compares in same order + if (arr.length >= allUniqueSolModifiers.length) + allUniqueSolModifiers.length = arr.length + 1; + if (!allUniqueSolModifiers[arr.length]) + allUniqueSolModifiers[arr.length] = []; + subarr = allUniqueSolModifiers[arr.length]; + for (i = 0, len = subarr.length; i < len; i++) + { + u = subarr[i]; + if (testSolsMatch(arr, u)) + return u; + } + subarr.push(arr); + return arr; + }; + function EventSheet(runtime, m) + { + this.runtime = runtime; + this.triggers = {}; + this.fasttriggers = {}; + this.hasRun = false; + this.includes = new cr.ObjectSet(); // all event sheets included by this sheet, at first-level indirection only + this.deep_includes = []; // all includes from this sheet recursively, in trigger order + this.already_included_sheets = []; // used while building deep_includes + this.name = m[0]; + var em = m[1]; // events model + this.events = []; // triggers won't make it to this array + var i, len; + for (i = 0, len = em.length; i < len; i++) + this.init_event(em[i], null, this.events); + }; + EventSheet.prototype.toString = function () + { + return this.name; + }; + EventSheet.prototype.init_event = function (m, parent, nontriggers) + { + switch (m[0]) { + case 0: // event block + { + var block = new cr.eventblock(this, parent, m); + cr.seal(block); + if (block.orblock) + { + nontriggers.push(block); + var i, len; + for (i = 0, len = block.conditions.length; i < len; i++) + { + if (block.conditions[i].trigger) + this.init_trigger(block, i); + } + } + else + { + if (block.is_trigger()) + this.init_trigger(block, 0); + else + nontriggers.push(block); + } + break; + } + case 1: // variable + { + var v = new cr.eventvariable(this, parent, m); + cr.seal(v); + nontriggers.push(v); + break; + } + case 2: // include + { + var inc = new cr.eventinclude(this, parent, m); + cr.seal(inc); + nontriggers.push(inc); + break; + } + default: +; + } + }; + EventSheet.prototype.postInit = function () + { + var i, len; + for (i = 0, len = this.events.length; i < len; i++) + { + this.events[i].postInit(i < len - 1 && this.events[i + 1].is_else_block); + } + }; + EventSheet.prototype.updateDeepIncludes = function () + { + this.deep_includes.length = 0; + this.already_included_sheets.length = 0; + this.addDeepIncludes(this); + this.already_included_sheets.length = 0; + }; + EventSheet.prototype.addDeepIncludes = function (root_sheet) + { + var i, len, inc, sheet; + var deep_includes = root_sheet.deep_includes; + var already_included_sheets = root_sheet.already_included_sheets; + var arr = this.includes.valuesRef(); + for (i = 0, len = arr.length; i < len; ++i) + { + inc = arr[i]; + sheet = inc.include_sheet; + if (!inc.isActive() || root_sheet === sheet || already_included_sheets.indexOf(sheet) > -1) + continue; + already_included_sheets.push(sheet); + sheet.addDeepIncludes(root_sheet); + deep_includes.push(sheet); + } + }; + EventSheet.prototype.run = function (from_include) + { + if (!this.runtime.resuming_breakpoint) + { + this.hasRun = true; + if (!from_include) + this.runtime.isRunningEvents = true; + } + var i, len; + for (i = 0, len = this.events.length; i < len; i++) + { + var ev = this.events[i]; + ev.run(); + this.runtime.clearSol(ev.solModifiers); + if (this.runtime.hasPendingInstances) + this.runtime.ClearDeathRow(); + } + if (!from_include) + this.runtime.isRunningEvents = false; + }; + function isPerformanceSensitiveTrigger(method) + { + if (cr.plugins_.Sprite && method === cr.plugins_.Sprite.prototype.cnds.OnFrameChanged) + { + return true; + } + return false; + }; + EventSheet.prototype.init_trigger = function (trig, index) + { + if (!trig.orblock) + this.runtime.triggers_to_postinit.push(trig); // needs to be postInit'd later + var i, len; + var cnd = trig.conditions[index]; + var type_name; + if (cnd.type) + type_name = cnd.type.name; + else + type_name = "system"; + var fasttrigger = cnd.fasttrigger; + var triggers = (fasttrigger ? this.fasttriggers : this.triggers); + if (!triggers[type_name]) + triggers[type_name] = []; + var obj_entry = triggers[type_name]; + var method = cnd.func; + if (fasttrigger) + { + if (!cnd.parameters.length) // no parameters + return; + var firstparam = cnd.parameters[0]; + if (firstparam.type !== 1 || // not a string param + firstparam.expression.type !== 2) // not a string literal node + { + return; + } + var fastevs; + var firstvalue = firstparam.expression.value.toLowerCase(); + var i, len; + for (i = 0, len = obj_entry.length; i < len; i++) + { + if (obj_entry[i].method == method) + { + fastevs = obj_entry[i].evs; + if (!fastevs[firstvalue]) + fastevs[firstvalue] = [[trig, index]]; + else + fastevs[firstvalue].push([trig, index]); + return; + } + } + fastevs = {}; + fastevs[firstvalue] = [[trig, index]]; + obj_entry.push({ method: method, evs: fastevs }); + } + else + { + for (i = 0, len = obj_entry.length; i < len; i++) + { + if (obj_entry[i].method == method) + { + obj_entry[i].evs.push([trig, index]); + return; + } + } + if (isPerformanceSensitiveTrigger(method)) + obj_entry.unshift({ method: method, evs: [[trig, index]]}); + else + obj_entry.push({ method: method, evs: [[trig, index]]}); + } + }; + cr.eventsheet = EventSheet; + function Selection(type) + { + this.type = type; + this.instances = []; // subset of picked instances + this.else_instances = []; // subset of unpicked instances + this.select_all = true; + }; + Selection.prototype.hasObjects = function () + { + if (this.select_all) + return this.type.instances.length; + else + return this.instances.length; + }; + Selection.prototype.getObjects = function () + { + if (this.select_all) + return this.type.instances; + else + return this.instances; + }; + /* + Selection.prototype.ensure_picked = function (inst, skip_siblings) + { + var i, len; + var orblock = inst.runtime.getCurrentEventStack().current_event.orblock; + if (this.select_all) + { + this.select_all = false; + if (orblock) + { + cr.shallowAssignArray(this.else_instances, inst.type.instances); + cr.arrayFindRemove(this.else_instances, inst); + } + this.instances.length = 1; + this.instances[0] = inst; + } + else + { + if (orblock) + { + i = this.else_instances.indexOf(inst); + if (i !== -1) + { + this.instances.push(this.else_instances[i]); + this.else_instances.splice(i, 1); + } + } + else + { + if (this.instances.indexOf(inst) === -1) + this.instances.push(inst); + } + } + if (!skip_siblings) + { + } + }; + */ + Selection.prototype.pick_one = function (inst) + { + if (!inst) + return; + if (inst.runtime.getCurrentEventStack().current_event.orblock) + { + if (this.select_all) + { + this.instances.length = 0; + cr.shallowAssignArray(this.else_instances, inst.type.instances); + this.select_all = false; + } + var i = this.else_instances.indexOf(inst); + if (i !== -1) + { + this.instances.push(this.else_instances[i]); + this.else_instances.splice(i, 1); + } + } + else + { + this.select_all = false; + this.instances.length = 1; + this.instances[0] = inst; + } + }; + cr.selection = Selection; + function EventBlock(sheet, parent, m) + { + this.sheet = sheet; + this.parent = parent; + this.runtime = sheet.runtime; + this.solModifiers = []; + this.solModifiersIncludingParents = []; + this.solWriterAfterCnds = false; // block does not change SOL after running its conditions + this.group = false; // is group of events + this.initially_activated = false; // if a group, is active on startup + this.toplevelevent = false; // is an event block parented only by a top-level group + this.toplevelgroup = false; // is parented only by other groups or is top-level (i.e. not in a subevent) + this.has_else_block = false; // is followed by else +; + this.conditions = []; + this.actions = []; + this.subevents = []; + this.group_name = ""; + this.group = false; + this.initially_activated = false; + this.group_active = false; + this.contained_includes = null; + if (m[1]) + { + this.group_name = m[1][1].toLowerCase(); + this.group = true; + this.initially_activated = !!m[1][0]; + this.contained_includes = []; + this.group_active = this.initially_activated; + this.runtime.allGroups.push(this); + this.runtime.groups_by_name[this.group_name] = this; + } + this.orblock = m[2]; + this.sid = m[4]; + if (!this.group) + this.runtime.blocksBySid[this.sid.toString()] = this; + var i, len; + var cm = m[5]; + for (i = 0, len = cm.length; i < len; i++) + { + var cnd = new cr.condition(this, cm[i]); + cnd.index = i; + cr.seal(cnd); + this.conditions.push(cnd); + /* + if (cnd.is_logical()) + this.is_logical = true; + if (cnd.type && !cnd.type.plugin.singleglobal && this.cndReferences.indexOf(cnd.type) === -1) + this.cndReferences.push(cnd.type); + */ + this.addSolModifier(cnd.type); + } + var am = m[6]; + for (i = 0, len = am.length; i < len; i++) + { + var act = new cr.action(this, am[i]); + act.index = i; + cr.seal(act); + this.actions.push(act); + } + if (m.length === 8) + { + var em = m[7]; + for (i = 0, len = em.length; i < len; i++) + this.sheet.init_event(em[i], this, this.subevents); + } + this.is_else_block = false; + if (this.conditions.length) + { + this.is_else_block = (this.conditions[0].type == null && this.conditions[0].func == cr.system_object.prototype.cnds.Else); + } + }; + window["_c2hh_"] = ""; + EventBlock.prototype.postInit = function (hasElse/*, prevBlock_*/) + { + var i, len; + var p = this.parent; + if (this.group) + { + this.toplevelgroup = true; + while (p) + { + if (!p.group) + { + this.toplevelgroup = false; + break; + } + p = p.parent; + } + } + this.toplevelevent = !this.is_trigger() && (!this.parent || (this.parent.group && this.parent.toplevelgroup)); + this.has_else_block = !!hasElse; + this.solModifiersIncludingParents = this.solModifiers.slice(0); + p = this.parent; + while (p) + { + for (i = 0, len = p.solModifiers.length; i < len; i++) + this.addParentSolModifier(p.solModifiers[i]); + p = p.parent; + } + this.solModifiers = findMatchingSolModifier(this.solModifiers); + this.solModifiersIncludingParents = findMatchingSolModifier(this.solModifiersIncludingParents); + var i, len/*, s*/; + for (i = 0, len = this.conditions.length; i < len; i++) + this.conditions[i].postInit(); + for (i = 0, len = this.actions.length; i < len; i++) + this.actions[i].postInit(); + for (i = 0, len = this.subevents.length; i < len; i++) + { + this.subevents[i].postInit(i < len - 1 && this.subevents[i + 1].is_else_block); + } + /* + if (this.is_else_block && this.prev_block) + { + for (i = 0, len = this.prev_block.solModifiers.length; i < len; i++) + { + s = this.prev_block.solModifiers[i]; + if (this.solModifiers.indexOf(s) === -1) + this.solModifiers.push(s); + } + } + */ + }; + EventBlock.prototype.setGroupActive = function (a) + { + if (this.group_active === !!a) + return; // same state + this.group_active = !!a; + var i, len; + for (i = 0, len = this.contained_includes.length; i < len; ++i) + { + this.contained_includes[i].updateActive(); + } + if (len > 0 && this.runtime.running_layout.event_sheet) + this.runtime.running_layout.event_sheet.updateDeepIncludes(); + }; + function addSolModifierToList(type, arr) + { + var i, len, t; + if (!type) + return; + if (arr.indexOf(type) === -1) + arr.push(type); + if (type.is_contained) + { + for (i = 0, len = type.container.length; i < len; i++) + { + t = type.container[i]; + if (type === t) + continue; // already handled + if (arr.indexOf(t) === -1) + arr.push(t); + } + } + }; + EventBlock.prototype.addSolModifier = function (type) + { + addSolModifierToList(type, this.solModifiers); + }; + EventBlock.prototype.addParentSolModifier = function (type) + { + addSolModifierToList(type, this.solModifiersIncludingParents); + }; + EventBlock.prototype.setSolWriterAfterCnds = function () + { + this.solWriterAfterCnds = true; + if (this.parent) + this.parent.setSolWriterAfterCnds(); + }; + EventBlock.prototype.is_trigger = function () + { + if (!this.conditions.length) // no conditions + return false; + else + return this.conditions[0].trigger; + }; + EventBlock.prototype.run = function () + { + var i, len, any_true = false, cnd_result; + var runtime = this.runtime; + var evinfo = this.runtime.getCurrentEventStack(); + evinfo.current_event = this; + var conditions = this.conditions; + if (!this.is_else_block) + evinfo.else_branch_ran = false; + if (this.orblock) + { + if (conditions.length === 0) + any_true = true; // be sure to run if empty block + evinfo.cndindex = 0 + for (len = conditions.length; evinfo.cndindex < len; evinfo.cndindex++) + { + if (conditions[evinfo.cndindex].trigger) // skip triggers when running OR block + continue; + cnd_result = conditions[evinfo.cndindex].run(); + if (cnd_result) // make sure all conditions run and run if any were true + any_true = true; + } + evinfo.last_event_true = any_true; + if (any_true) + this.run_actions_and_subevents(); + } + else + { + evinfo.cndindex = 0 + for (len = conditions.length; evinfo.cndindex < len; evinfo.cndindex++) + { + cnd_result = conditions[evinfo.cndindex].run(); + if (!cnd_result) // condition failed + { + evinfo.last_event_true = false; + if (this.toplevelevent && runtime.hasPendingInstances) + runtime.ClearDeathRow(); + return; // bail out now + } + } + evinfo.last_event_true = true; + this.run_actions_and_subevents(); + } + this.end_run(evinfo); + }; + EventBlock.prototype.end_run = function (evinfo) + { + if (evinfo.last_event_true && this.has_else_block) + evinfo.else_branch_ran = true; + if (this.toplevelevent && this.runtime.hasPendingInstances) + this.runtime.ClearDeathRow(); + }; + EventBlock.prototype.run_orblocktrigger = function (index) + { + var evinfo = this.runtime.getCurrentEventStack(); + evinfo.current_event = this; + if (this.conditions[index].run()) + { + this.run_actions_and_subevents(); + this.runtime.getCurrentEventStack().last_event_true = true; + } + }; + EventBlock.prototype.run_actions_and_subevents = function () + { + var evinfo = this.runtime.getCurrentEventStack(); + var len; + for (evinfo.actindex = 0, len = this.actions.length; evinfo.actindex < len; evinfo.actindex++) + { + if (this.actions[evinfo.actindex].run()) + return; + } + this.run_subevents(); + }; + EventBlock.prototype.resume_actions_and_subevents = function () + { + var evinfo = this.runtime.getCurrentEventStack(); + var len; + for (len = this.actions.length; evinfo.actindex < len; evinfo.actindex++) + { + if (this.actions[evinfo.actindex].run()) + return; + } + this.run_subevents(); + }; + EventBlock.prototype.run_subevents = function () + { + if (!this.subevents.length) + return; + var i, len, subev, pushpop/*, skipped_pop = false, pop_modifiers = null*/; + var last = this.subevents.length - 1; + this.runtime.pushEventStack(this); + if (this.solWriterAfterCnds) + { + for (i = 0, len = this.subevents.length; i < len; i++) + { + subev = this.subevents[i]; + pushpop = (!this.toplevelgroup || (!this.group && i < last)); + if (pushpop) + this.runtime.pushCopySol(subev.solModifiers); + subev.run(); + if (pushpop) + this.runtime.popSol(subev.solModifiers); + else + this.runtime.clearSol(subev.solModifiers); + } + } + else + { + for (i = 0, len = this.subevents.length; i < len; i++) + { + this.subevents[i].run(); + } + } + this.runtime.popEventStack(); + }; + EventBlock.prototype.run_pretrigger = function () + { + var evinfo = this.runtime.getCurrentEventStack(); + evinfo.current_event = this; + var any_true = false; + var i, len; + for (evinfo.cndindex = 0, len = this.conditions.length; evinfo.cndindex < len; evinfo.cndindex++) + { +; + if (this.conditions[evinfo.cndindex].run()) + any_true = true; + else if (!this.orblock) // condition failed (let OR blocks run all conditions anyway) + return false; // bail out + } + return this.orblock ? any_true : true; + }; + EventBlock.prototype.retrigger = function () + { + this.runtime.execcount++; + var prevcndindex = this.runtime.getCurrentEventStack().cndindex; + var len; + var evinfo = this.runtime.pushEventStack(this); + if (!this.orblock) + { + for (evinfo.cndindex = prevcndindex + 1, len = this.conditions.length; evinfo.cndindex < len; evinfo.cndindex++) + { + if (!this.conditions[evinfo.cndindex].run()) // condition failed + { + this.runtime.popEventStack(); // moving up level of recursion + return false; // bail out + } + } + } + this.run_actions_and_subevents(); + this.runtime.popEventStack(); + return true; // ran an iteration + }; + EventBlock.prototype.isFirstConditionOfType = function (cnd) + { + var cndindex = cnd.index; + if (cndindex === 0) + return true; + --cndindex; + for ( ; cndindex >= 0; --cndindex) + { + if (this.conditions[cndindex].type === cnd.type) + return false; + } + return true; + }; + cr.eventblock = EventBlock; + function Condition(block, m) + { + this.block = block; + this.sheet = block.sheet; + this.runtime = block.runtime; + this.parameters = []; + this.results = []; + this.extra = {}; // for plugins to stow away some custom info + this.index = -1; + this.anyParamVariesPerInstance = false; + this.func = this.runtime.GetObjectReference(m[1]); +; + this.trigger = (m[3] > 0); + this.fasttrigger = (m[3] === 2); + this.looping = m[4]; + this.inverted = m[5]; + this.isstatic = m[6]; + this.sid = m[7]; + this.runtime.cndsBySid[this.sid.toString()] = this; + if (m[0] === -1) // system object + { + this.type = null; + this.run = this.run_system; + this.behaviortype = null; + this.beh_index = -1; + } + else + { + this.type = this.runtime.types_by_index[m[0]]; +; + if (this.isstatic) + this.run = this.run_static; + else + this.run = this.run_object; + if (m[2]) + { + this.behaviortype = this.type.getBehaviorByName(m[2]); +; + this.beh_index = this.type.getBehaviorIndexByName(m[2]); +; + } + else + { + this.behaviortype = null; + this.beh_index = -1; + } + if (this.block.parent) + this.block.parent.setSolWriterAfterCnds(); + } + if (this.fasttrigger) + this.run = this.run_true; + if (m.length === 10) + { + var i, len; + var em = m[9]; + for (i = 0, len = em.length; i < len; i++) + { + var param = new cr.parameter(this, em[i]); + cr.seal(param); + this.parameters.push(param); + } + this.results.length = em.length; + } + }; + Condition.prototype.postInit = function () + { + var i, len, p; + for (i = 0, len = this.parameters.length; i < len; i++) + { + p = this.parameters[i]; + p.postInit(); + if (p.variesPerInstance) + this.anyParamVariesPerInstance = true; + } + }; + /* + Condition.prototype.is_logical = function () + { + return !this.type || this.type.plugin.singleglobal; + }; + */ + Condition.prototype.run_true = function () + { + return true; + }; + Condition.prototype.run_system = function () + { + var i, len; + for (i = 0, len = this.parameters.length; i < len; i++) + this.results[i] = this.parameters[i].get(); + return cr.xor(this.func.apply(this.runtime.system, this.results), this.inverted); + }; + Condition.prototype.run_static = function () + { + var i, len; + for (i = 0, len = this.parameters.length; i < len; i++) + this.results[i] = this.parameters[i].get(); + var ret = this.func.apply(this.behaviortype ? this.behaviortype : this.type, this.results); + this.type.applySolToContainer(); + return ret; + }; + Condition.prototype.run_object = function () + { + var i, j, k, leni, lenj, p, ret, met, inst, s, sol2; + var type = this.type; + var sol = type.getCurrentSol(); + var is_orblock = this.block.orblock && !this.trigger; // triggers in OR blocks need to work normally + var offset = 0; + var is_contained = type.is_contained; + var is_family = type.is_family; + var family_index = type.family_index; + var beh_index = this.beh_index; + var is_beh = (beh_index > -1); + var params_vary = this.anyParamVariesPerInstance; + var parameters = this.parameters; + var results = this.results; + var inverted = this.inverted; + var func = this.func; + var arr, container; + if (params_vary) + { + for (j = 0, lenj = parameters.length; j < lenj; ++j) + { + p = parameters[j]; + if (!p.variesPerInstance) + results[j] = p.get(0); + } + } + else + { + for (j = 0, lenj = parameters.length; j < lenj; ++j) + results[j] = parameters[j].get(0); + } + if (sol.select_all) { + sol.instances.length = 0; // clear contents + sol.else_instances.length = 0; + arr = type.instances; + for (i = 0, leni = arr.length; i < leni; ++i) + { + inst = arr[i]; +; + if (params_vary) + { + for (j = 0, lenj = parameters.length; j < lenj; ++j) + { + p = parameters[j]; + if (p.variesPerInstance) + results[j] = p.get(i); // default SOL index is current object + } + } + if (is_beh) + { + offset = 0; + if (is_family) + { + offset = inst.type.family_beh_map[family_index]; + } + ret = func.apply(inst.behavior_insts[beh_index + offset], results); + } + else + ret = func.apply(inst, results); + met = cr.xor(ret, inverted); + if (met) + sol.instances.push(inst); + else if (is_orblock) // in OR blocks, keep the instances not meeting the condition for subsequent testing + sol.else_instances.push(inst); + } + if (type.finish) + type.finish(true); + sol.select_all = false; + type.applySolToContainer(); + return sol.hasObjects(); + } + else { + k = 0; + var using_else_instances = (is_orblock && !this.block.isFirstConditionOfType(this)); + arr = (using_else_instances ? sol.else_instances : sol.instances); + var any_true = false; + for (i = 0, leni = arr.length; i < leni; ++i) + { + inst = arr[i]; +; + if (params_vary) + { + for (j = 0, lenj = parameters.length; j < lenj; ++j) + { + p = parameters[j]; + if (p.variesPerInstance) + results[j] = p.get(i); // default SOL index is current object + } + } + if (is_beh) + { + offset = 0; + if (is_family) + { + offset = inst.type.family_beh_map[family_index]; + } + ret = func.apply(inst.behavior_insts[beh_index + offset], results); + } + else + ret = func.apply(inst, results); + if (cr.xor(ret, inverted)) + { + any_true = true; + if (using_else_instances) + { + sol.instances.push(inst); + if (is_contained) + { + for (j = 0, lenj = inst.siblings.length; j < lenj; j++) + { + s = inst.siblings[j]; + s.type.getCurrentSol().instances.push(s); + } + } + } + else + { + arr[k] = inst; + if (is_contained) + { + for (j = 0, lenj = inst.siblings.length; j < lenj; j++) + { + s = inst.siblings[j]; + s.type.getCurrentSol().instances[k] = s; + } + } + k++; + } + } + else + { + if (using_else_instances) + { + arr[k] = inst; + if (is_contained) + { + for (j = 0, lenj = inst.siblings.length; j < lenj; j++) + { + s = inst.siblings[j]; + s.type.getCurrentSol().else_instances[k] = s; + } + } + k++; + } + else if (is_orblock) + { + sol.else_instances.push(inst); + if (is_contained) + { + for (j = 0, lenj = inst.siblings.length; j < lenj; j++) + { + s = inst.siblings[j]; + s.type.getCurrentSol().else_instances.push(s); + } + } + } + } + } + arr.length = k; + if (is_contained) + { + container = type.container; + for (i = 0, leni = container.length; i < leni; i++) + { + sol2 = container[i].getCurrentSol(); + if (using_else_instances) + sol2.else_instances.length = k; + else + sol2.instances.length = k; + } + } + var pick_in_finish = any_true; // don't pick in finish() if we're only doing the logic test below + if (using_else_instances && !any_true) + { + for (i = 0, leni = sol.instances.length; i < leni; i++) + { + inst = sol.instances[i]; + if (params_vary) + { + for (j = 0, lenj = parameters.length; j < lenj; j++) + { + p = parameters[j]; + if (p.variesPerInstance) + results[j] = p.get(i); + } + } + if (is_beh) + ret = func.apply(inst.behavior_insts[beh_index], results); + else + ret = func.apply(inst, results); + if (cr.xor(ret, inverted)) + { + any_true = true; + break; // got our flag, don't need to test any more + } + } + } + if (type.finish) + type.finish(pick_in_finish || is_orblock); + return is_orblock ? any_true : sol.hasObjects(); + } + }; + cr.condition = Condition; + function Action(block, m) + { + this.block = block; + this.sheet = block.sheet; + this.runtime = block.runtime; + this.parameters = []; + this.results = []; + this.extra = {}; // for plugins to stow away some custom info + this.index = -1; + this.anyParamVariesPerInstance = false; + this.func = this.runtime.GetObjectReference(m[1]); +; + if (m[0] === -1) // system + { + this.type = null; + this.run = this.run_system; + this.behaviortype = null; + this.beh_index = -1; + } + else + { + this.type = this.runtime.types_by_index[m[0]]; +; + this.run = this.run_object; + if (m[2]) + { + this.behaviortype = this.type.getBehaviorByName(m[2]); +; + this.beh_index = this.type.getBehaviorIndexByName(m[2]); +; + } + else + { + this.behaviortype = null; + this.beh_index = -1; + } + } + this.sid = m[3]; + this.runtime.actsBySid[this.sid.toString()] = this; + if (m.length === 6) + { + var i, len; + var em = m[5]; + for (i = 0, len = em.length; i < len; i++) + { + var param = new cr.parameter(this, em[i]); + cr.seal(param); + this.parameters.push(param); + } + this.results.length = em.length; + } + }; + Action.prototype.postInit = function () + { + var i, len, p; + for (i = 0, len = this.parameters.length; i < len; i++) + { + p = this.parameters[i]; + p.postInit(); + if (p.variesPerInstance) + this.anyParamVariesPerInstance = true; + } + }; + Action.prototype.run_system = function () + { + var i, len; + for (i = 0, len = this.parameters.length; i < len; i++) + this.results[i] = this.parameters[i].get(); + return this.func.apply(this.runtime.system, this.results); + }; + Action.prototype.run_object = function () + { + var instances = this.type.getCurrentSol().getObjects(); + var is_family = this.type.is_family; + var family_index = this.type.family_index; + var beh_index = this.beh_index; + var is_beh = (beh_index > -1); + var params_vary = this.anyParamVariesPerInstance; + var parameters = this.parameters; + var results = this.results; + var func = this.func; + var i, j, leni, lenj, p, inst, offset; + if (params_vary) + { + for (j = 0, lenj = parameters.length; j < lenj; ++j) + { + p = parameters[j]; + if (!p.variesPerInstance) + results[j] = p.get(0); + } + } + else + { + for (j = 0, lenj = parameters.length; j < lenj; ++j) + results[j] = parameters[j].get(0); + } + for (i = 0, leni = instances.length; i < leni; ++i) + { + inst = instances[i]; + if (params_vary) + { + for (j = 0, lenj = parameters.length; j < lenj; ++j) + { + p = parameters[j]; + if (p.variesPerInstance) + results[j] = p.get(i); // pass i to use as default SOL index + } + } + if (is_beh) + { + offset = 0; + if (is_family) + { + offset = inst.type.family_beh_map[family_index]; + } + func.apply(inst.behavior_insts[beh_index + offset], results); + } + else + func.apply(inst, results); + } + return false; + }; + cr.action = Action; + var tempValues = []; + var tempValuesPtr = -1; + function Parameter(owner, m) + { + this.owner = owner; + this.block = owner.block; + this.sheet = owner.sheet; + this.runtime = owner.runtime; + this.type = m[0]; + this.expression = null; + this.solindex = 0; + this.get = null; + this.combosel = 0; + this.layout = null; + this.key = 0; + this.object = null; + this.index = 0; + this.varname = null; + this.eventvar = null; + this.fileinfo = null; + this.subparams = null; + this.variadicret = null; + this.subparams = null; + this.variadicret = null; + this.variesPerInstance = false; + var i, len, param; + switch (m[0]) + { + case 0: // number + case 7: // any + this.expression = new cr.expNode(this, m[1]); + this.solindex = 0; + this.get = this.get_exp; + break; + case 1: // string + this.expression = new cr.expNode(this, m[1]); + this.solindex = 0; + this.get = this.get_exp_str; + break; + case 5: // layer + this.expression = new cr.expNode(this, m[1]); + this.solindex = 0; + this.get = this.get_layer; + break; + case 3: // combo + case 8: // cmp + this.combosel = m[1]; + this.get = this.get_combosel; + break; + case 6: // layout + this.layout = this.runtime.layouts[m[1]]; +; + this.get = this.get_layout; + break; + case 9: // keyb + this.key = m[1]; + this.get = this.get_key; + break; + case 4: // object + this.object = this.runtime.types_by_index[m[1]]; +; + this.get = this.get_object; + this.block.addSolModifier(this.object); + if (this.owner instanceof cr.action) + this.block.setSolWriterAfterCnds(); + else if (this.block.parent) + this.block.parent.setSolWriterAfterCnds(); + break; + case 10: // instvar + this.index = m[1]; + if (owner.type.is_family) + { + this.get = this.get_familyvar; + this.variesPerInstance = true; + } + else + this.get = this.get_instvar; + break; + case 11: // eventvar + this.varname = m[1]; + this.eventvar = null; + this.get = this.get_eventvar; + break; + case 2: // audiofile ["name", ismusic] + case 12: // fileinfo "name" + this.fileinfo = m[1]; + this.get = this.get_audiofile; + break; + case 13: // variadic + this.get = this.get_variadic; + this.subparams = []; + this.variadicret = []; + for (i = 1, len = m.length; i < len; i++) + { + param = new cr.parameter(this.owner, m[i]); + cr.seal(param); + this.subparams.push(param); + this.variadicret.push(0); + } + break; + default: +; + } + }; + Parameter.prototype.postInit = function () + { + var i, len; + if (this.type === 11) // eventvar + { + this.eventvar = this.runtime.getEventVariableByName(this.varname, this.block.parent); +; + } + else if (this.type === 13) // variadic, postInit all sub-params + { + for (i = 0, len = this.subparams.length; i < len; i++) + this.subparams[i].postInit(); + } + if (this.expression) + this.expression.postInit(); + }; + Parameter.prototype.maybeVaryForType = function (t) + { + if (this.variesPerInstance) + return; // already varies per instance, no need to check again + if (!t) + return; // never vary for system type + if (!t.plugin.singleglobal) + { + this.variesPerInstance = true; + return; + } + }; + Parameter.prototype.setVaries = function () + { + this.variesPerInstance = true; + }; + Parameter.prototype.pushTempValue = function () + { + tempValuesPtr++; + if (tempValues.length === tempValuesPtr) + tempValues.push(new cr.expvalue()); + return tempValues[tempValuesPtr]; + }; + Parameter.prototype.popTempValue = function () + { + tempValuesPtr--; + }; + Parameter.prototype.get_exp = function (solindex) + { + this.solindex = solindex || 0; // default SOL index to use + var temp = this.pushTempValue(); + this.expression.get(temp); + this.popTempValue(); + return temp.data; // return actual JS value, not expvalue + }; + Parameter.prototype.get_exp_str = function (solindex) + { + this.solindex = solindex || 0; // default SOL index to use + var temp = this.pushTempValue(); + this.expression.get(temp); + this.popTempValue(); + if (cr.is_string(temp.data)) + return temp.data; + else + return ""; + }; + Parameter.prototype.get_object = function () + { + return this.object; + }; + Parameter.prototype.get_combosel = function () + { + return this.combosel; + }; + Parameter.prototype.get_layer = function (solindex) + { + this.solindex = solindex || 0; // default SOL index to use + var temp = this.pushTempValue(); + this.expression.get(temp); + this.popTempValue(); + if (temp.is_number()) + return this.runtime.getLayerByNumber(temp.data); + else + return this.runtime.getLayerByName(temp.data); + } + Parameter.prototype.get_layout = function () + { + return this.layout; + }; + Parameter.prototype.get_key = function () + { + return this.key; + }; + Parameter.prototype.get_instvar = function () + { + return this.index; + }; + Parameter.prototype.get_familyvar = function (solindex_) + { + var solindex = solindex_ || 0; + var familytype = this.owner.type; + var realtype = null; + var sol = familytype.getCurrentSol(); + var objs = sol.getObjects(); + if (objs.length) + realtype = objs[solindex % objs.length].type; + else if (sol.else_instances.length) + realtype = sol.else_instances[solindex % sol.else_instances.length].type; + else if (familytype.instances.length) + realtype = familytype.instances[solindex % familytype.instances.length].type; + else + return 0; + return this.index + realtype.family_var_map[familytype.family_index]; + }; + Parameter.prototype.get_eventvar = function () + { + return this.eventvar; + }; + Parameter.prototype.get_audiofile = function () + { + return this.fileinfo; + }; + Parameter.prototype.get_variadic = function () + { + var i, len; + for (i = 0, len = this.subparams.length; i < len; i++) + { + this.variadicret[i] = this.subparams[i].get(); + } + return this.variadicret; + }; + cr.parameter = Parameter; + function EventVariable(sheet, parent, m) + { + this.sheet = sheet; + this.parent = parent; + this.runtime = sheet.runtime; + this.solModifiers = []; + this.name = m[1]; + this.vartype = m[2]; + this.initial = m[3]; + this.is_static = !!m[4]; + this.is_constant = !!m[5]; + this.sid = m[6]; + this.runtime.varsBySid[this.sid.toString()] = this; + this.data = this.initial; // note: also stored in event stack frame for local nonstatic nonconst vars + if (this.parent) // local var + { + if (this.is_static || this.is_constant) + this.localIndex = -1; + else + this.localIndex = this.runtime.stackLocalCount++; + this.runtime.all_local_vars.push(this); + } + else // global var + { + this.localIndex = -1; + this.runtime.all_global_vars.push(this); + } + }; + EventVariable.prototype.postInit = function () + { + this.solModifiers = findMatchingSolModifier(this.solModifiers); + }; + EventVariable.prototype.setValue = function (x) + { +; + var lvs = this.runtime.getCurrentLocalVarStack(); + if (!this.parent || this.is_static || !lvs) + this.data = x; + else // local nonstatic variable: use event stack to keep value at this level of recursion + { + if (this.localIndex >= lvs.length) + lvs.length = this.localIndex + 1; + lvs[this.localIndex] = x; + } + }; + EventVariable.prototype.getValue = function () + { + var lvs = this.runtime.getCurrentLocalVarStack(); + if (!this.parent || this.is_static || !lvs || this.is_constant) + return this.data; + else // local nonstatic variable + { + if (this.localIndex >= lvs.length) + { +; + return this.initial; + } + if (typeof lvs[this.localIndex] === "undefined") + { +; + return this.initial; + } + return lvs[this.localIndex]; + } + }; + EventVariable.prototype.run = function () + { + if (this.parent && !this.is_static && !this.is_constant) + this.setValue(this.initial); + }; + cr.eventvariable = EventVariable; + function EventInclude(sheet, parent, m) + { + this.sheet = sheet; + this.parent = parent; + this.runtime = sheet.runtime; + this.solModifiers = []; + this.include_sheet = null; // determined in postInit + this.include_sheet_name = m[1]; + this.active = true; + }; + EventInclude.prototype.toString = function () + { + return "include:" + this.include_sheet.toString(); + }; + EventInclude.prototype.postInit = function () + { + this.include_sheet = this.runtime.eventsheets[this.include_sheet_name]; +; +; + this.sheet.includes.add(this); + this.solModifiers = findMatchingSolModifier(this.solModifiers); + var p = this.parent; + while (p) + { + if (p.group) + p.contained_includes.push(this); + p = p.parent; + } + this.updateActive(); + }; + EventInclude.prototype.run = function () + { + if (this.parent) + this.runtime.pushCleanSol(this.runtime.types_by_index); + if (!this.include_sheet.hasRun) + this.include_sheet.run(true); // from include + if (this.parent) + this.runtime.popSol(this.runtime.types_by_index); + }; + EventInclude.prototype.updateActive = function () + { + var p = this.parent; + while (p) + { + if (p.group && !p.group_active) + { + this.active = false; + return; + } + p = p.parent; + } + this.active = true; + }; + EventInclude.prototype.isActive = function () + { + return this.active; + }; + cr.eventinclude = EventInclude; + function EventStackFrame() + { + this.temp_parents_arr = []; + this.reset(null); + cr.seal(this); + }; + EventStackFrame.prototype.reset = function (cur_event) + { + this.current_event = cur_event; + this.cndindex = 0; + this.actindex = 0; + this.temp_parents_arr.length = 0; + this.last_event_true = false; + this.else_branch_ran = false; + this.any_true_state = false; + }; + EventStackFrame.prototype.isModifierAfterCnds = function () + { + if (this.current_event.solWriterAfterCnds) + return true; + if (this.cndindex < this.current_event.conditions.length - 1) + return !!this.current_event.solModifiers.length; + return false; + }; + cr.eventStackFrame = EventStackFrame; +}()); +(function() +{ + function ExpNode(owner_, m) + { + this.owner = owner_; + this.runtime = owner_.runtime; + this.type = m[0]; +; + this.get = [this.eval_int, + this.eval_float, + this.eval_string, + this.eval_unaryminus, + this.eval_add, + this.eval_subtract, + this.eval_multiply, + this.eval_divide, + this.eval_mod, + this.eval_power, + this.eval_and, + this.eval_or, + this.eval_equal, + this.eval_notequal, + this.eval_less, + this.eval_lessequal, + this.eval_greater, + this.eval_greaterequal, + this.eval_conditional, + this.eval_system_exp, + this.eval_object_behavior_exp, + this.eval_instvar_exp, + this.eval_object_behavior_exp, + this.eval_eventvar_exp][this.type]; + var paramsModel = null; + this.value = null; + this.first = null; + this.second = null; + this.third = null; + this.func = null; + this.results = null; + this.parameters = null; + this.object_type = null; + this.beh_index = -1; + this.instance_expr = null; + this.varindex = -1; + this.behavior_type = null; + this.varname = null; + this.eventvar = null; + this.return_string = false; + switch (this.type) { + case 0: // int + case 1: // float + case 2: // string + this.value = m[1]; + break; + case 3: // unaryminus + this.first = new cr.expNode(owner_, m[1]); + break; + case 18: // conditional + this.first = new cr.expNode(owner_, m[1]); + this.second = new cr.expNode(owner_, m[2]); + this.third = new cr.expNode(owner_, m[3]); + break; + case 19: // system_exp + this.func = this.runtime.GetObjectReference(m[1]); +; + if (this.func === cr.system_object.prototype.exps.random + || this.func === cr.system_object.prototype.exps.choose) + { + this.owner.setVaries(); + } + this.results = []; + this.parameters = []; + if (m.length === 3) + { + paramsModel = m[2]; + this.results.length = paramsModel.length + 1; // must also fit 'ret' + } + else + this.results.length = 1; // to fit 'ret' + break; + case 20: // object_exp + this.object_type = this.runtime.types_by_index[m[1]]; +; + this.beh_index = -1; + this.func = this.runtime.GetObjectReference(m[2]); + this.return_string = m[3]; + if (cr.plugins_.Function && this.func === cr.plugins_.Function.prototype.exps.Call) + { + this.owner.setVaries(); + } + if (m[4]) + this.instance_expr = new cr.expNode(owner_, m[4]); + else + this.instance_expr = null; + this.results = []; + this.parameters = []; + if (m.length === 6) + { + paramsModel = m[5]; + this.results.length = paramsModel.length + 1; + } + else + this.results.length = 1; // to fit 'ret' + break; + case 21: // instvar_exp + this.object_type = this.runtime.types_by_index[m[1]]; +; + this.return_string = m[2]; + if (m[3]) + this.instance_expr = new cr.expNode(owner_, m[3]); + else + this.instance_expr = null; + this.varindex = m[4]; + break; + case 22: // behavior_exp + this.object_type = this.runtime.types_by_index[m[1]]; +; + this.behavior_type = this.object_type.getBehaviorByName(m[2]); +; + this.beh_index = this.object_type.getBehaviorIndexByName(m[2]); + this.func = this.runtime.GetObjectReference(m[3]); + this.return_string = m[4]; + if (m[5]) + this.instance_expr = new cr.expNode(owner_, m[5]); + else + this.instance_expr = null; + this.results = []; + this.parameters = []; + if (m.length === 7) + { + paramsModel = m[6]; + this.results.length = paramsModel.length + 1; + } + else + this.results.length = 1; // to fit 'ret' + break; + case 23: // eventvar_exp + this.varname = m[1]; + this.eventvar = null; // assigned in postInit + break; + } + this.owner.maybeVaryForType(this.object_type); + if (this.type >= 4 && this.type <= 17) + { + this.first = new cr.expNode(owner_, m[1]); + this.second = new cr.expNode(owner_, m[2]); + } + if (paramsModel) + { + var i, len; + for (i = 0, len = paramsModel.length; i < len; i++) + this.parameters.push(new cr.expNode(owner_, paramsModel[i])); + } + cr.seal(this); + }; + ExpNode.prototype.postInit = function () + { + if (this.type === 23) // eventvar_exp + { + this.eventvar = this.owner.runtime.getEventVariableByName(this.varname, this.owner.block.parent); +; + } + if (this.first) + this.first.postInit(); + if (this.second) + this.second.postInit(); + if (this.third) + this.third.postInit(); + if (this.instance_expr) + this.instance_expr.postInit(); + if (this.parameters) + { + var i, len; + for (i = 0, len = this.parameters.length; i < len; i++) + this.parameters[i].postInit(); + } + }; + ExpNode.prototype.eval_system_exp = function (ret) + { + this.results[0] = ret; + var temp = this.owner.pushTempValue(); + var i, len; + for (i = 0, len = this.parameters.length; i < len; i++) + { + this.parameters[i].get(temp); + this.results[i + 1] = temp.data; // passing actual javascript value as argument instead of expvalue + } + this.owner.popTempValue(); + this.func.apply(this.runtime.system, this.results); + }; + ExpNode.prototype.eval_object_behavior_exp = function (ret) + { + var sol = this.object_type.getCurrentSol(); + var instances = sol.getObjects(); + if (!instances.length) + { + if (sol.else_instances.length) + instances = sol.else_instances; + else + { + if (this.return_string) + ret.set_string(""); + else + ret.set_int(0); + return; + } + } + this.results[0] = ret; + ret.object_class = this.object_type; // so expression can access family type if need be + var temp = this.owner.pushTempValue(); + var i, len; + for (i = 0, len = this.parameters.length; i < len; i++) { + this.parameters[i].get(temp); + this.results[i + 1] = temp.data; // passing actual javascript value as argument instead of expvalue + } + var index = this.owner.solindex; + if (this.instance_expr) { + this.instance_expr.get(temp); + if (temp.is_number()) { + index = temp.data; + instances = this.object_type.instances; // pick from all instances, not SOL + } + } + this.owner.popTempValue(); + index %= instances.length; // wraparound + if (index < 0) + index += instances.length; + var returned_val; + var inst = instances[index]; + if (this.beh_index > -1) + { + var offset = 0; + if (this.object_type.is_family) + { + offset = inst.type.family_beh_map[this.object_type.family_index]; + } + returned_val = this.func.apply(inst.behavior_insts[this.beh_index + offset], this.results); + } + else + returned_val = this.func.apply(inst, this.results); +; + }; + ExpNode.prototype.eval_instvar_exp = function (ret) + { + var sol = this.object_type.getCurrentSol(); + var instances = sol.getObjects(); + if (!instances.length) + { + if (sol.else_instances.length) + instances = sol.else_instances; + else + { + if (this.return_string) + ret.set_string(""); + else + ret.set_int(0); + return; + } + } + var index = this.owner.solindex; + if (this.instance_expr) + { + var temp = this.owner.pushTempValue(); + this.instance_expr.get(temp); + if (temp.is_number()) + { + index = temp.data; + var type_instances = this.object_type.instances; + index %= type_instances.length; // wraparound + if (index < 0) // offset + index += type_instances.length; + var to_ret = type_instances[index].instance_vars[this.varindex]; + if (cr.is_string(to_ret)) + ret.set_string(to_ret); + else + ret.set_float(to_ret); + this.owner.popTempValue(); + return; // done + } + this.owner.popTempValue(); + } + index %= instances.length; // wraparound + if (index < 0) + index += instances.length; + var inst = instances[index]; + var offset = 0; + if (this.object_type.is_family) + { + offset = inst.type.family_var_map[this.object_type.family_index]; + } + var to_ret = inst.instance_vars[this.varindex + offset]; + if (cr.is_string(to_ret)) + ret.set_string(to_ret); + else + ret.set_float(to_ret); + }; + ExpNode.prototype.eval_int = function (ret) + { + ret.type = cr.exptype.Integer; + ret.data = this.value; + }; + ExpNode.prototype.eval_float = function (ret) + { + ret.type = cr.exptype.Float; + ret.data = this.value; + }; + ExpNode.prototype.eval_string = function (ret) + { + ret.type = cr.exptype.String; + ret.data = this.value; + }; + ExpNode.prototype.eval_unaryminus = function (ret) + { + this.first.get(ret); // retrieve operand + if (ret.is_number()) + ret.data = -ret.data; + }; + ExpNode.prototype.eval_add = function (ret) + { + this.first.get(ret); // left operand + var temp = this.owner.pushTempValue(); + this.second.get(temp); // right operand + if (ret.is_number() && temp.is_number()) + { + ret.data += temp.data; // both operands numbers: add + if (temp.is_float()) + ret.make_float(); + } + this.owner.popTempValue(); + }; + ExpNode.prototype.eval_subtract = function (ret) + { + this.first.get(ret); // left operand + var temp = this.owner.pushTempValue(); + this.second.get(temp); // right operand + if (ret.is_number() && temp.is_number()) + { + ret.data -= temp.data; // both operands numbers: subtract + if (temp.is_float()) + ret.make_float(); + } + this.owner.popTempValue(); + }; + ExpNode.prototype.eval_multiply = function (ret) + { + this.first.get(ret); // left operand + var temp = this.owner.pushTempValue(); + this.second.get(temp); // right operand + if (ret.is_number() && temp.is_number()) + { + ret.data *= temp.data; // both operands numbers: multiply + if (temp.is_float()) + ret.make_float(); + } + this.owner.popTempValue(); + }; + ExpNode.prototype.eval_divide = function (ret) + { + this.first.get(ret); // left operand + var temp = this.owner.pushTempValue(); + this.second.get(temp); // right operand + if (ret.is_number() && temp.is_number()) + { + ret.data /= temp.data; // both operands numbers: divide + ret.make_float(); + } + this.owner.popTempValue(); + }; + ExpNode.prototype.eval_mod = function (ret) + { + this.first.get(ret); // left operand + var temp = this.owner.pushTempValue(); + this.second.get(temp); // right operand + if (ret.is_number() && temp.is_number()) + { + ret.data %= temp.data; // both operands numbers: modulo + if (temp.is_float()) + ret.make_float(); + } + this.owner.popTempValue(); + }; + ExpNode.prototype.eval_power = function (ret) + { + this.first.get(ret); // left operand + var temp = this.owner.pushTempValue(); + this.second.get(temp); // right operand + if (ret.is_number() && temp.is_number()) + { + ret.data = Math.pow(ret.data, temp.data); // both operands numbers: raise to power + if (temp.is_float()) + ret.make_float(); + } + this.owner.popTempValue(); + }; + ExpNode.prototype.eval_and = function (ret) + { + this.first.get(ret); // left operand + var temp = this.owner.pushTempValue(); + this.second.get(temp); // right operand + if (ret.is_number()) + { + if (temp.is_string()) + { + ret.set_string(ret.data.toString() + temp.data); + } + else + { + if (ret.data && temp.data) + ret.set_int(1); + else + ret.set_int(0); + } + } + else if (ret.is_string()) + { + if (temp.is_string()) + ret.data += temp.data; + else + { + ret.data += (Math.round(temp.data * 1e10) / 1e10).toString(); + } + } + this.owner.popTempValue(); + }; + ExpNode.prototype.eval_or = function (ret) + { + this.first.get(ret); // left operand + var temp = this.owner.pushTempValue(); + this.second.get(temp); // right operand + if (ret.is_number() && temp.is_number()) + { + if (ret.data || temp.data) + ret.set_int(1); + else + ret.set_int(0); + } + this.owner.popTempValue(); + }; + ExpNode.prototype.eval_conditional = function (ret) + { + this.first.get(ret); // condition operand + if (ret.data) // is true + this.second.get(ret); // evaluate second operand to ret + else + this.third.get(ret); // evaluate third operand to ret + }; + ExpNode.prototype.eval_equal = function (ret) + { + this.first.get(ret); // left operand + var temp = this.owner.pushTempValue(); + this.second.get(temp); // right operand + ret.set_int(ret.data === temp.data ? 1 : 0); + this.owner.popTempValue(); + }; + ExpNode.prototype.eval_notequal = function (ret) + { + this.first.get(ret); // left operand + var temp = this.owner.pushTempValue(); + this.second.get(temp); // right operand + ret.set_int(ret.data !== temp.data ? 1 : 0); + this.owner.popTempValue(); + }; + ExpNode.prototype.eval_less = function (ret) + { + this.first.get(ret); // left operand + var temp = this.owner.pushTempValue(); + this.second.get(temp); // right operand + ret.set_int(ret.data < temp.data ? 1 : 0); + this.owner.popTempValue(); + }; + ExpNode.prototype.eval_lessequal = function (ret) + { + this.first.get(ret); // left operand + var temp = this.owner.pushTempValue(); + this.second.get(temp); // right operand + ret.set_int(ret.data <= temp.data ? 1 : 0); + this.owner.popTempValue(); + }; + ExpNode.prototype.eval_greater = function (ret) + { + this.first.get(ret); // left operand + var temp = this.owner.pushTempValue(); + this.second.get(temp); // right operand + ret.set_int(ret.data > temp.data ? 1 : 0); + this.owner.popTempValue(); + }; + ExpNode.prototype.eval_greaterequal = function (ret) + { + this.first.get(ret); // left operand + var temp = this.owner.pushTempValue(); + this.second.get(temp); // right operand + ret.set_int(ret.data >= temp.data ? 1 : 0); + this.owner.popTempValue(); + }; + ExpNode.prototype.eval_eventvar_exp = function (ret) + { + var val = this.eventvar.getValue(); + if (cr.is_number(val)) + ret.set_float(val); + else + ret.set_string(val); + }; + cr.expNode = ExpNode; + function ExpValue(type, data) + { + this.type = type || cr.exptype.Integer; + this.data = data || 0; + this.object_class = null; +; +; +; + if (this.type == cr.exptype.Integer) + this.data = Math.floor(this.data); + cr.seal(this); + }; + ExpValue.prototype.is_int = function () + { + return this.type === cr.exptype.Integer; + }; + ExpValue.prototype.is_float = function () + { + return this.type === cr.exptype.Float; + }; + ExpValue.prototype.is_number = function () + { + return this.type === cr.exptype.Integer || this.type === cr.exptype.Float; + }; + ExpValue.prototype.is_string = function () + { + return this.type === cr.exptype.String; + }; + ExpValue.prototype.make_int = function () + { + if (!this.is_int()) + { + if (this.is_float()) + this.data = Math.floor(this.data); // truncate float + else if (this.is_string()) + this.data = parseInt(this.data, 10); + this.type = cr.exptype.Integer; + } + }; + ExpValue.prototype.make_float = function () + { + if (!this.is_float()) + { + if (this.is_string()) + this.data = parseFloat(this.data); + this.type = cr.exptype.Float; + } + }; + ExpValue.prototype.make_string = function () + { + if (!this.is_string()) + { + this.data = this.data.toString(); + this.type = cr.exptype.String; + } + }; + ExpValue.prototype.set_int = function (val) + { +; + this.type = cr.exptype.Integer; + this.data = Math.floor(val); + }; + ExpValue.prototype.set_float = function (val) + { +; + this.type = cr.exptype.Float; + this.data = val; + }; + ExpValue.prototype.set_string = function (val) + { +; + this.type = cr.exptype.String; + this.data = val; + }; + ExpValue.prototype.set_any = function (val) + { + if (cr.is_number(val)) + { + this.type = cr.exptype.Float; + this.data = val; + } + else if (cr.is_string(val)) + { + this.type = cr.exptype.String; + this.data = val.toString(); + } + else + { + this.type = cr.exptype.Integer; + this.data = 0; + } + }; + cr.expvalue = ExpValue; + cr.exptype = { + Integer: 0, // emulated; no native integer support in javascript + Float: 1, + String: 2 + }; +}()); +; +cr.system_object = function (runtime) +{ + this.runtime = runtime; + this.waits = []; +}; +cr.system_object.prototype.saveToJSON = function () +{ + var o = {}; + var i, len, j, lenj, p, w, t, sobj; + o["waits"] = []; + var owaits = o["waits"]; + var waitobj; + for (i = 0, len = this.waits.length; i < len; i++) + { + w = this.waits[i]; + waitobj = { + "t": w.time, + "st": w.signaltag, + "s": w.signalled, + "ev": w.ev.sid, + "sm": [], + "sols": {} + }; + if (w.ev.actions[w.actindex]) + waitobj["act"] = w.ev.actions[w.actindex].sid; + for (j = 0, lenj = w.solModifiers.length; j < lenj; j++) + waitobj["sm"].push(w.solModifiers[j].sid); + for (p in w.sols) + { + if (w.sols.hasOwnProperty(p)) + { + t = this.runtime.types_by_index[parseInt(p, 10)]; +; + sobj = { + "sa": w.sols[p].sa, + "insts": [] + }; + for (j = 0, lenj = w.sols[p].insts.length; j < lenj; j++) + sobj["insts"].push(w.sols[p].insts[j].uid); + waitobj["sols"][t.sid.toString()] = sobj; + } + } + owaits.push(waitobj); + } + return o; +}; +cr.system_object.prototype.loadFromJSON = function (o) +{ + var owaits = o["waits"]; + var i, len, j, lenj, p, w, addWait, e, aindex, t, savedsol, nusol, inst; + this.waits.length = 0; + for (i = 0, len = owaits.length; i < len; i++) + { + w = owaits[i]; + e = this.runtime.blocksBySid[w["ev"].toString()]; + if (!e) + continue; // event must've gone missing + aindex = -1; + for (j = 0, lenj = e.actions.length; j < lenj; j++) + { + if (e.actions[j].sid === w["act"]) + { + aindex = j; + break; + } + } + if (aindex === -1) + continue; // action must've gone missing + addWait = {}; + addWait.sols = {}; + addWait.solModifiers = []; + addWait.deleteme = false; + addWait.time = w["t"]; + addWait.signaltag = w["st"] || ""; + addWait.signalled = !!w["s"]; + addWait.ev = e; + addWait.actindex = aindex; + for (j = 0, lenj = w["sm"].length; j < lenj; j++) + { + t = this.runtime.getObjectTypeBySid(w["sm"][j]); + if (t) + addWait.solModifiers.push(t); + } + for (p in w["sols"]) + { + if (w["sols"].hasOwnProperty(p)) + { + t = this.runtime.getObjectTypeBySid(parseInt(p, 10)); + if (!t) + continue; // type must've been deleted + savedsol = w["sols"][p]; + nusol = { + sa: savedsol["sa"], + insts: [] + }; + for (j = 0, lenj = savedsol["insts"].length; j < lenj; j++) + { + inst = this.runtime.getObjectByUID(savedsol["insts"][j]); + if (inst) + nusol.insts.push(inst); + } + addWait.sols[t.index.toString()] = nusol; + } + } + this.waits.push(addWait); + } +}; +(function () +{ + var sysProto = cr.system_object.prototype; + function SysCnds() {}; + SysCnds.prototype.EveryTick = function() + { + return true; + }; + SysCnds.prototype.OnLayoutStart = function() + { + return true; + }; + SysCnds.prototype.OnLayoutEnd = function() + { + return true; + }; + SysCnds.prototype.Compare = function(x, cmp, y) + { + return cr.do_cmp(x, cmp, y); + }; + SysCnds.prototype.CompareTime = function (cmp, t) + { + var elapsed = this.runtime.kahanTime.sum; + if (cmp === 0) + { + var cnd = this.runtime.getCurrentCondition(); + if (!cnd.extra["CompareTime_executed"]) + { + if (elapsed >= t) + { + cnd.extra["CompareTime_executed"] = true; + return true; + } + } + return false; + } + return cr.do_cmp(elapsed, cmp, t); + }; + SysCnds.prototype.LayerVisible = function (layer) + { + if (!layer) + return false; + else + return layer.visible; + }; + SysCnds.prototype.LayerEmpty = function (layer) + { + if (!layer) + return false; + else + return !layer.instances.length; + }; + SysCnds.prototype.LayerCmpOpacity = function (layer, cmp, opacity_) + { + if (!layer) + return false; + return cr.do_cmp(layer.opacity * 100, cmp, opacity_); + }; + SysCnds.prototype.Repeat = function (count) + { + var current_frame = this.runtime.getCurrentEventStack(); + var current_event = current_frame.current_event; + var solModifierAfterCnds = current_frame.isModifierAfterCnds(); + var current_loop = this.runtime.pushLoopStack(); + var i; + if (solModifierAfterCnds) + { + for (i = 0; i < count && !current_loop.stopped; i++) + { + this.runtime.pushCopySol(current_event.solModifiers); + current_loop.index = i; + current_event.retrigger(); + this.runtime.popSol(current_event.solModifiers); + } + } + else + { + for (i = 0; i < count && !current_loop.stopped; i++) + { + current_loop.index = i; + current_event.retrigger(); + } + } + this.runtime.popLoopStack(); + return false; + }; + SysCnds.prototype.While = function (count) + { + var current_frame = this.runtime.getCurrentEventStack(); + var current_event = current_frame.current_event; + var solModifierAfterCnds = current_frame.isModifierAfterCnds(); + var current_loop = this.runtime.pushLoopStack(); + var i; + if (solModifierAfterCnds) + { + for (i = 0; !current_loop.stopped; i++) + { + this.runtime.pushCopySol(current_event.solModifiers); + current_loop.index = i; + if (!current_event.retrigger()) // one of the other conditions returned false + current_loop.stopped = true; // break + this.runtime.popSol(current_event.solModifiers); + } + } + else + { + for (i = 0; !current_loop.stopped; i++) + { + current_loop.index = i; + if (!current_event.retrigger()) + current_loop.stopped = true; + } + } + this.runtime.popLoopStack(); + return false; + }; + SysCnds.prototype.For = function (name, start, end) + { + var current_frame = this.runtime.getCurrentEventStack(); + var current_event = current_frame.current_event; + var solModifierAfterCnds = current_frame.isModifierAfterCnds(); + var current_loop = this.runtime.pushLoopStack(name); + var i; + if (end < start) + { + if (solModifierAfterCnds) + { + for (i = start; i >= end && !current_loop.stopped; --i) // inclusive to end + { + this.runtime.pushCopySol(current_event.solModifiers); + current_loop.index = i; + current_event.retrigger(); + this.runtime.popSol(current_event.solModifiers); + } + } + else + { + for (i = start; i >= end && !current_loop.stopped; --i) // inclusive to end + { + current_loop.index = i; + current_event.retrigger(); + } + } + } + else + { + if (solModifierAfterCnds) + { + for (i = start; i <= end && !current_loop.stopped; ++i) // inclusive to end + { + this.runtime.pushCopySol(current_event.solModifiers); + current_loop.index = i; + current_event.retrigger(); + this.runtime.popSol(current_event.solModifiers); + } + } + else + { + for (i = start; i <= end && !current_loop.stopped; ++i) // inclusive to end + { + current_loop.index = i; + current_event.retrigger(); + } + } + } + this.runtime.popLoopStack(); + return false; + }; + var foreach_instancestack = []; + var foreach_instanceptr = -1; + SysCnds.prototype.ForEach = function (obj) + { + var sol = obj.getCurrentSol(); + foreach_instanceptr++; + if (foreach_instancestack.length === foreach_instanceptr) + foreach_instancestack.push([]); + var instances = foreach_instancestack[foreach_instanceptr]; + cr.shallowAssignArray(instances, sol.getObjects()); + var current_frame = this.runtime.getCurrentEventStack(); + var current_event = current_frame.current_event; + var solModifierAfterCnds = current_frame.isModifierAfterCnds(); + var current_loop = this.runtime.pushLoopStack(); + var i, len, j, lenj, inst, s, sol2; + var is_contained = obj.is_contained; + if (solModifierAfterCnds) + { + for (i = 0, len = instances.length; i < len && !current_loop.stopped; i++) + { + this.runtime.pushCopySol(current_event.solModifiers); + inst = instances[i]; + sol = obj.getCurrentSol(); + sol.select_all = false; + sol.instances.length = 1; + sol.instances[0] = inst; + if (is_contained) + { + for (j = 0, lenj = inst.siblings.length; j < lenj; j++) + { + s = inst.siblings[j]; + sol2 = s.type.getCurrentSol(); + sol2.select_all = false; + sol2.instances.length = 1; + sol2.instances[0] = s; + } + } + current_loop.index = i; + current_event.retrigger(); + this.runtime.popSol(current_event.solModifiers); + } + } + else + { + sol.select_all = false; + sol.instances.length = 1; + for (i = 0, len = instances.length; i < len && !current_loop.stopped; i++) + { + inst = instances[i]; + sol.instances[0] = inst; + if (is_contained) + { + for (j = 0, lenj = inst.siblings.length; j < lenj; j++) + { + s = inst.siblings[j]; + sol2 = s.type.getCurrentSol(); + sol2.select_all = false; + sol2.instances.length = 1; + sol2.instances[0] = s; + } + } + current_loop.index = i; + current_event.retrigger(); + } + } + instances.length = 0; + this.runtime.popLoopStack(); + foreach_instanceptr--; + return false; + }; + function foreach_sortinstances(a, b) + { + var va = a.extra["c2_feo_val"]; + var vb = b.extra["c2_feo_val"]; + if (cr.is_number(va) && cr.is_number(vb)) + return va - vb; + else + { + va = "" + va; + vb = "" + vb; + if (va < vb) + return -1; + else if (va > vb) + return 1; + else + return 0; + } + }; + SysCnds.prototype.ForEachOrdered = function (obj, exp, order) + { + var sol = obj.getCurrentSol(); + foreach_instanceptr++; + if (foreach_instancestack.length === foreach_instanceptr) + foreach_instancestack.push([]); + var instances = foreach_instancestack[foreach_instanceptr]; + cr.shallowAssignArray(instances, sol.getObjects()); + var current_frame = this.runtime.getCurrentEventStack(); + var current_event = current_frame.current_event; + var current_condition = this.runtime.getCurrentCondition(); + var solModifierAfterCnds = current_frame.isModifierAfterCnds(); + var current_loop = this.runtime.pushLoopStack(); + var i, len, j, lenj, inst, s, sol2; + for (i = 0, len = instances.length; i < len; i++) + { + instances[i].extra["c2_feo_val"] = current_condition.parameters[1].get(i); + } + instances.sort(foreach_sortinstances); + if (order === 1) + instances.reverse(); + var is_contained = obj.is_contained; + if (solModifierAfterCnds) + { + for (i = 0, len = instances.length; i < len && !current_loop.stopped; i++) + { + this.runtime.pushCopySol(current_event.solModifiers); + inst = instances[i]; + sol = obj.getCurrentSol(); + sol.select_all = false; + sol.instances.length = 1; + sol.instances[0] = inst; + if (is_contained) + { + for (j = 0, lenj = inst.siblings.length; j < lenj; j++) + { + s = inst.siblings[j]; + sol2 = s.type.getCurrentSol(); + sol2.select_all = false; + sol2.instances.length = 1; + sol2.instances[0] = s; + } + } + current_loop.index = i; + current_event.retrigger(); + this.runtime.popSol(current_event.solModifiers); + } + } + else + { + sol.select_all = false; + sol.instances.length = 1; + for (i = 0, len = instances.length; i < len && !current_loop.stopped; i++) + { + inst = instances[i]; + sol.instances[0] = inst; + if (is_contained) + { + for (j = 0, lenj = inst.siblings.length; j < lenj; j++) + { + s = inst.siblings[j]; + sol2 = s.type.getCurrentSol(); + sol2.select_all = false; + sol2.instances.length = 1; + sol2.instances[0] = s; + } + } + current_loop.index = i; + current_event.retrigger(); + } + } + instances.length = 0; + this.runtime.popLoopStack(); + foreach_instanceptr--; + return false; + }; + SysCnds.prototype.PickByComparison = function (obj_, exp_, cmp_, val_) + { + var i, len, k, inst; + if (!obj_) + return; + foreach_instanceptr++; + if (foreach_instancestack.length === foreach_instanceptr) + foreach_instancestack.push([]); + var tmp_instances = foreach_instancestack[foreach_instanceptr]; + var sol = obj_.getCurrentSol(); + cr.shallowAssignArray(tmp_instances, sol.getObjects()); + if (sol.select_all) + sol.else_instances.length = 0; + var current_condition = this.runtime.getCurrentCondition(); + for (i = 0, k = 0, len = tmp_instances.length; i < len; i++) + { + inst = tmp_instances[i]; + tmp_instances[k] = inst; + exp_ = current_condition.parameters[1].get(i); + val_ = current_condition.parameters[3].get(i); + if (cr.do_cmp(exp_, cmp_, val_)) + { + k++; + } + else + { + sol.else_instances.push(inst); + } + } + tmp_instances.length = k; + sol.select_all = false; + cr.shallowAssignArray(sol.instances, tmp_instances); + tmp_instances.length = 0; + foreach_instanceptr--; + obj_.applySolToContainer(); + return !!sol.instances.length; + }; + SysCnds.prototype.PickByEvaluate = function (obj_, exp_) + { + var i, len, k, inst; + if (!obj_) + return; + foreach_instanceptr++; + if (foreach_instancestack.length === foreach_instanceptr) + foreach_instancestack.push([]); + var tmp_instances = foreach_instancestack[foreach_instanceptr]; + var sol = obj_.getCurrentSol(); + cr.shallowAssignArray(tmp_instances, sol.getObjects()); + if (sol.select_all) + sol.else_instances.length = 0; + var current_condition = this.runtime.getCurrentCondition(); + for (i = 0, k = 0, len = tmp_instances.length; i < len; i++) + { + inst = tmp_instances[i]; + tmp_instances[k] = inst; + exp_ = current_condition.parameters[1].get(i); + if (exp_) + { + k++; + } + else + { + sol.else_instances.push(inst); + } + } + tmp_instances.length = k; + sol.select_all = false; + cr.shallowAssignArray(sol.instances, tmp_instances); + tmp_instances.length = 0; + foreach_instanceptr--; + obj_.applySolToContainer(); + return !!sol.instances.length; + }; + SysCnds.prototype.TriggerOnce = function () + { + var cndextra = this.runtime.getCurrentCondition().extra; + if (typeof cndextra["TriggerOnce_lastTick"] === "undefined") + cndextra["TriggerOnce_lastTick"] = -1; + var last_tick = cndextra["TriggerOnce_lastTick"]; + var cur_tick = this.runtime.tickcount; + cndextra["TriggerOnce_lastTick"] = cur_tick; + return this.runtime.layout_first_tick || last_tick !== cur_tick - 1; + }; + SysCnds.prototype.Every = function (seconds) + { + var cnd = this.runtime.getCurrentCondition(); + var last_time = cnd.extra["Every_lastTime"] || 0; + var cur_time = this.runtime.kahanTime.sum; + if (typeof cnd.extra["Every_seconds"] === "undefined") + cnd.extra["Every_seconds"] = seconds; + var this_seconds = cnd.extra["Every_seconds"]; + if (cur_time >= last_time + this_seconds) + { + cnd.extra["Every_lastTime"] = last_time + this_seconds; + if (cur_time >= cnd.extra["Every_lastTime"] + 0.04) + { + cnd.extra["Every_lastTime"] = cur_time; + } + cnd.extra["Every_seconds"] = seconds; + return true; + } + else if (cur_time < last_time - 0.1) + { + cnd.extra["Every_lastTime"] = cur_time; + } + return false; + }; + SysCnds.prototype.PickNth = function (obj, index) + { + if (!obj) + return false; + var sol = obj.getCurrentSol(); + var instances = sol.getObjects(); + index = cr.floor(index); + if (index < 0 || index >= instances.length) + return false; + var inst = instances[index]; + sol.pick_one(inst); + obj.applySolToContainer(); + return true; + }; + SysCnds.prototype.PickRandom = function (obj) + { + if (!obj) + return false; + var sol = obj.getCurrentSol(); + var instances = sol.getObjects(); + var index = cr.floor(Math.random() * instances.length); + if (index >= instances.length) + return false; + var inst = instances[index]; + sol.pick_one(inst); + obj.applySolToContainer(); + return true; + }; + SysCnds.prototype.CompareVar = function (v, cmp, val) + { + return cr.do_cmp(v.getValue(), cmp, val); + }; + SysCnds.prototype.IsGroupActive = function (group) + { + var g = this.runtime.groups_by_name[group.toLowerCase()]; + return g && g.group_active; + }; + SysCnds.prototype.IsPreview = function () + { + return typeof cr_is_preview !== "undefined"; + }; + SysCnds.prototype.PickAll = function (obj) + { + if (!obj) + return false; + if (!obj.instances.length) + return false; + var sol = obj.getCurrentSol(); + sol.select_all = true; + obj.applySolToContainer(); + return true; + }; + SysCnds.prototype.IsMobile = function () + { + return this.runtime.isMobile; + }; + SysCnds.prototype.CompareBetween = function (x, a, b) + { + return x >= a && x <= b; + }; + SysCnds.prototype.Else = function () + { + var current_frame = this.runtime.getCurrentEventStack(); + if (current_frame.else_branch_ran) + return false; // another event in this else-if chain has run + else + return !current_frame.last_event_true; + /* + var current_frame = this.runtime.getCurrentEventStack(); + var current_event = current_frame.current_event; + var prev_event = current_event.prev_block; + if (!prev_event) + return false; + if (prev_event.is_logical) + return !this.runtime.last_event_true; + var i, len, j, lenj, s, sol, temp, inst, any_picked = false; + for (i = 0, len = prev_event.cndReferences.length; i < len; i++) + { + s = prev_event.cndReferences[i]; + sol = s.getCurrentSol(); + if (sol.select_all || sol.instances.length === s.instances.length) + { + sol.select_all = false; + sol.instances.length = 0; + } + else + { + if (sol.instances.length === 1 && sol.else_instances.length === 0 && s.instances.length >= 2) + { + inst = sol.instances[0]; + sol.instances.length = 0; + for (j = 0, lenj = s.instances.length; j < lenj; j++) + { + if (s.instances[j] != inst) + sol.instances.push(s.instances[j]); + } + any_picked = true; + } + else + { + temp = sol.instances; + sol.instances = sol.else_instances; + sol.else_instances = temp; + any_picked = true; + } + } + } + return any_picked; + */ + }; + SysCnds.prototype.OnLoadFinished = function () + { + return true; + }; + SysCnds.prototype.OnCanvasSnapshot = function () + { + return true; + }; + SysCnds.prototype.EffectsSupported = function () + { + return !!this.runtime.glwrap; + }; + SysCnds.prototype.OnSaveComplete = function () + { + return true; + }; + SysCnds.prototype.OnLoadComplete = function () + { + return true; + }; + SysCnds.prototype.OnLoadFailed = function () + { + return true; + }; + SysCnds.prototype.ObjectUIDExists = function (u) + { + return !!this.runtime.getObjectByUID(u); + }; + SysCnds.prototype.IsOnPlatform = function (p) + { + var rt = this.runtime; + switch (p) { + case 0: // HTML5 website + return !rt.isDomFree && !rt.isNodeWebkit && !rt.isCordova && !rt.isWinJS && !rt.isWindowsPhone8 && !rt.isBlackberry10 && !rt.isAmazonWebApp; + case 1: // iOS + return rt.isiOS; + case 2: // Android + return rt.isAndroid; + case 3: // Windows 8 + return rt.isWindows8App; + case 4: // Windows Phone 8 + return rt.isWindowsPhone8; + case 5: // Blackberry 10 + return rt.isBlackberry10; + case 6: // Tizen + return rt.isTizen; + case 7: // CocoonJS + return rt.isCocoonJs; + case 8: // Cordova + return rt.isCordova; + case 9: // Scirra Arcade + return rt.isArcade; + case 10: // node-webkit + return rt.isNodeWebkit; + case 11: // crosswalk + return rt.isCrosswalk; + case 12: // amazon webapp + return rt.isAmazonWebApp; + default: // should not be possible + return false; + } + }; + var cacheRegex = null; + var lastRegex = ""; + var lastFlags = ""; + function getRegex(regex_, flags_) + { + if (!cacheRegex || regex_ !== lastRegex || flags_ !== lastFlags) + { + cacheRegex = new RegExp(regex_, flags_); + lastRegex = regex_; + lastFlags = flags_; + } + cacheRegex.lastIndex = 0; // reset + return cacheRegex; + }; + SysCnds.prototype.RegexTest = function (str_, regex_, flags_) + { + var regex = getRegex(regex_, flags_); + return regex.test(str_); + }; + var tmp_arr = []; + SysCnds.prototype.PickOverlappingPoint = function (obj_, x_, y_) + { + if (!obj_) + return false; + var sol = obj_.getCurrentSol(); + var instances = sol.getObjects(); + var current_event = this.runtime.getCurrentEventStack().current_event; + var orblock = current_event.orblock; + var cnd = this.runtime.getCurrentCondition(); + var i, len, inst, pick; + if (sol.select_all) + { + cr.shallowAssignArray(tmp_arr, instances); + sol.else_instances.length = 0; + sol.select_all = false; + sol.instances.length = 0; + } + else + { + if (orblock) + { + cr.shallowAssignArray(tmp_arr, sol.else_instances); + sol.else_instances.length = 0; + } + else + { + cr.shallowAssignArray(tmp_arr, instances); + sol.instances.length = 0; + } + } + for (i = 0, len = tmp_arr.length; i < len; ++i) + { + inst = tmp_arr[i]; + inst.update_bbox(); + pick = cr.xor(inst.contains_pt(x_, y_), cnd.inverted); + if (pick) + sol.instances.push(inst); + else + sol.else_instances.push(inst); + } + obj_.applySolToContainer(); + return cr.xor(!!sol.instances.length, cnd.inverted); + }; + SysCnds.prototype.IsNaN = function (n) + { + return !!isNaN(n); + }; + SysCnds.prototype.AngleWithin = function (a1, within, a2) + { + return cr.angleDiff(cr.to_radians(a1), cr.to_radians(a2)) <= cr.to_radians(within); + }; + SysCnds.prototype.IsClockwiseFrom = function (a1, a2) + { + return cr.angleClockwise(cr.to_radians(a1), cr.to_radians(a2)); + }; + SysCnds.prototype.IsBetweenAngles = function (a, la, ua) + { + var angle = cr.to_clamped_radians(a); + var lower = cr.to_clamped_radians(la); + var upper = cr.to_clamped_radians(ua); + var obtuse = (!cr.angleClockwise(upper, lower)); + if (obtuse) + return !(!cr.angleClockwise(angle, lower) && cr.angleClockwise(angle, upper)); + else + return cr.angleClockwise(angle, lower) && !cr.angleClockwise(angle, upper); + }; + SysCnds.prototype.IsValueType = function (x, t) + { + if (typeof x === "number") + return t === 0; + else // string + return t === 1; + }; + sysProto.cnds = new SysCnds(); + function SysActs() {}; + SysActs.prototype.GoToLayout = function (to) + { + if (this.runtime.isloading) + return; // cannot change layout while loading on loader layout + if (this.runtime.changelayout) + return; // already changing to a different layout +; + this.runtime.changelayout = to; + }; + SysActs.prototype.NextPrevLayout = function (prev) + { + if (this.runtime.isloading) + return; // cannot change layout while loading on loader layout + if (this.runtime.changelayout) + return; // already changing to a different layout + var index = this.runtime.layouts_by_index.indexOf(this.runtime.running_layout); + if (prev && index === 0) + return; // cannot go to previous layout from first layout + if (!prev && index === this.runtime.layouts_by_index.length - 1) + return; // cannot go to next layout from last layout + var to = this.runtime.layouts_by_index[index + (prev ? -1 : 1)]; +; + this.runtime.changelayout = to; + }; + SysActs.prototype.CreateObject = function (obj, layer, x, y) + { + if (!layer || !obj) + return; + var inst = this.runtime.createInstance(obj, layer, x, y); + if (!inst) + return; + this.runtime.isInOnDestroy++; + var i, len, s; + this.runtime.trigger(Object.getPrototypeOf(obj.plugin).cnds.OnCreated, inst); + if (inst.is_contained) + { + for (i = 0, len = inst.siblings.length; i < len; i++) + { + s = inst.siblings[i]; + this.runtime.trigger(Object.getPrototypeOf(s.type.plugin).cnds.OnCreated, s); + } + } + this.runtime.isInOnDestroy--; + var sol = obj.getCurrentSol(); + sol.select_all = false; + sol.instances.length = 1; + sol.instances[0] = inst; + if (inst.is_contained) + { + for (i = 0, len = inst.siblings.length; i < len; i++) + { + s = inst.siblings[i]; + sol = s.type.getCurrentSol(); + sol.select_all = false; + sol.instances.length = 1; + sol.instances[0] = s; + } + } + }; + SysActs.prototype.SetLayerVisible = function (layer, visible_) + { + if (!layer) + return; + if (layer.visible !== visible_) + { + layer.visible = visible_; + this.runtime.redraw = true; + } + }; + SysActs.prototype.SetLayerOpacity = function (layer, opacity_) + { + if (!layer) + return; + opacity_ = cr.clamp(opacity_ / 100, 0, 1); + if (layer.opacity !== opacity_) + { + layer.opacity = opacity_; + this.runtime.redraw = true; + } + }; + SysActs.prototype.SetLayerScaleRate = function (layer, sr) + { + if (!layer) + return; + if (layer.zoomRate !== sr) + { + layer.zoomRate = sr; + this.runtime.redraw = true; + } + }; + SysActs.prototype.SetLayoutScale = function (s) + { + if (!this.runtime.running_layout) + return; + if (this.runtime.running_layout.scale !== s) + { + this.runtime.running_layout.scale = s; + this.runtime.running_layout.boundScrolling(); + this.runtime.redraw = true; + } + }; + SysActs.prototype.ScrollX = function(x) + { + this.runtime.running_layout.scrollToX(x); + }; + SysActs.prototype.ScrollY = function(y) + { + this.runtime.running_layout.scrollToY(y); + }; + SysActs.prototype.Scroll = function(x, y) + { + this.runtime.running_layout.scrollToX(x); + this.runtime.running_layout.scrollToY(y); + }; + SysActs.prototype.ScrollToObject = function(obj) + { + var inst = obj.getFirstPicked(); + if (inst) + { + this.runtime.running_layout.scrollToX(inst.x); + this.runtime.running_layout.scrollToY(inst.y); + } + }; + SysActs.prototype.SetVar = function(v, x) + { +; + if (v.vartype === 0) + { + if (cr.is_number(x)) + v.setValue(x); + else + v.setValue(parseFloat(x)); + } + else if (v.vartype === 1) + v.setValue(x.toString()); + }; + SysActs.prototype.AddVar = function(v, x) + { +; + if (v.vartype === 0) + { + if (cr.is_number(x)) + v.setValue(v.getValue() + x); + else + v.setValue(v.getValue() + parseFloat(x)); + } + else if (v.vartype === 1) + v.setValue(v.getValue() + x.toString()); + }; + SysActs.prototype.SubVar = function(v, x) + { +; + if (v.vartype === 0) + { + if (cr.is_number(x)) + v.setValue(v.getValue() - x); + else + v.setValue(v.getValue() - parseFloat(x)); + } + }; + SysActs.prototype.SetGroupActive = function (group, active) + { + var g = this.runtime.groups_by_name[group.toLowerCase()]; + if (!g) + return; + switch (active) { + case 0: + g.setGroupActive(false); + break; + case 1: + g.setGroupActive(true); + break; + case 2: + g.setGroupActive(!g.group_active); + break; + } + }; + SysActs.prototype.SetTimescale = function (ts_) + { + var ts = ts_; + if (ts < 0) + ts = 0; + this.runtime.timescale = ts; + }; + SysActs.prototype.SetObjectTimescale = function (obj, ts_) + { + var ts = ts_; + if (ts < 0) + ts = 0; + if (!obj) + return; + var sol = obj.getCurrentSol(); + var instances = sol.getObjects(); + var i, len; + for (i = 0, len = instances.length; i < len; i++) + { + instances[i].my_timescale = ts; + } + }; + SysActs.prototype.RestoreObjectTimescale = function (obj) + { + if (!obj) + return false; + var sol = obj.getCurrentSol(); + var instances = sol.getObjects(); + var i, len; + for (i = 0, len = instances.length; i < len; i++) + { + instances[i].my_timescale = -1.0; + } + }; + var waitobjrecycle = []; + function allocWaitObject() + { + var w; + if (waitobjrecycle.length) + w = waitobjrecycle.pop(); + else + { + w = {}; + w.sols = {}; + w.solModifiers = []; + } + w.deleteme = false; + return w; + }; + function freeWaitObject(w) + { + cr.wipe(w.sols); + w.solModifiers.length = 0; + waitobjrecycle.push(w); + }; + var solstateobjects = []; + function allocSolStateObject() + { + var s; + if (solstateobjects.length) + s = solstateobjects.pop(); + else + { + s = {}; + s.insts = []; + } + s.sa = false; + return s; + }; + function freeSolStateObject(s) + { + s.insts.length = 0; + solstateobjects.push(s); + }; + SysActs.prototype.Wait = function (seconds) + { + if (seconds < 0) + return; + var i, len, s, t, ss; + var evinfo = this.runtime.getCurrentEventStack(); + var waitobj = allocWaitObject(); + waitobj.time = this.runtime.kahanTime.sum + seconds; + waitobj.signaltag = ""; + waitobj.signalled = false; + waitobj.ev = evinfo.current_event; + waitobj.actindex = evinfo.actindex + 1; // pointing at next action + for (i = 0, len = this.runtime.types_by_index.length; i < len; i++) + { + t = this.runtime.types_by_index[i]; + s = t.getCurrentSol(); + if (s.select_all && evinfo.current_event.solModifiers.indexOf(t) === -1) + continue; + waitobj.solModifiers.push(t); + ss = allocSolStateObject(); + ss.sa = s.select_all; + cr.shallowAssignArray(ss.insts, s.instances); + waitobj.sols[i.toString()] = ss; + } + this.waits.push(waitobj); + return true; + }; + SysActs.prototype.WaitForSignal = function (tag) + { + var i, len, s, t, ss; + var evinfo = this.runtime.getCurrentEventStack(); + var waitobj = allocWaitObject(); + waitobj.time = -1; + waitobj.signaltag = tag.toLowerCase(); + waitobj.signalled = false; + waitobj.ev = evinfo.current_event; + waitobj.actindex = evinfo.actindex + 1; // pointing at next action + for (i = 0, len = this.runtime.types_by_index.length; i < len; i++) + { + t = this.runtime.types_by_index[i]; + s = t.getCurrentSol(); + if (s.select_all && evinfo.current_event.solModifiers.indexOf(t) === -1) + continue; + waitobj.solModifiers.push(t); + ss = allocSolStateObject(); + ss.sa = s.select_all; + cr.shallowAssignArray(ss.insts, s.instances); + waitobj.sols[i.toString()] = ss; + } + this.waits.push(waitobj); + return true; + }; + SysActs.prototype.Signal = function (tag) + { + var lowertag = tag.toLowerCase(); + var i, len, w; + for (i = 0, len = this.waits.length; i < len; ++i) + { + w = this.waits[i]; + if (w.time !== -1) + continue; // timer wait, ignore + if (w.signaltag === lowertag) // waiting for this signal + w.signalled = true; // will run on next check + } + }; + SysActs.prototype.SetLayerScale = function (layer, scale) + { + if (!layer) + return; + if (layer.scale === scale) + return; + layer.scale = scale; + this.runtime.redraw = true; + }; + SysActs.prototype.ResetGlobals = function () + { + var i, len, g; + for (i = 0, len = this.runtime.all_global_vars.length; i < len; i++) + { + g = this.runtime.all_global_vars[i]; + g.data = g.initial; + } + }; + SysActs.prototype.SetLayoutAngle = function (a) + { + a = cr.to_radians(a); + a = cr.clamp_angle(a); + if (this.runtime.running_layout) + { + if (this.runtime.running_layout.angle !== a) + { + this.runtime.running_layout.angle = a; + this.runtime.redraw = true; + } + } + }; + SysActs.prototype.SetLayerAngle = function (layer, a) + { + if (!layer) + return; + a = cr.to_radians(a); + a = cr.clamp_angle(a); + if (layer.angle === a) + return; + layer.angle = a; + this.runtime.redraw = true; + }; + SysActs.prototype.SetLayerParallax = function (layer, px, py) + { + if (!layer) + return; + if (layer.parallaxX === px / 100 && layer.parallaxY === py / 100) + return; + layer.parallaxX = px / 100; + layer.parallaxY = py / 100; + if (layer.parallaxX !== 1 || layer.parallaxY !== 1) + { + var i, len, instances = layer.instances; + for (i = 0, len = instances.length; i < len; ++i) + { + instances[i].type.any_instance_parallaxed = true; + } + } + this.runtime.redraw = true; + }; + SysActs.prototype.SetLayerBackground = function (layer, c) + { + if (!layer) + return; + var r = cr.GetRValue(c); + var g = cr.GetGValue(c); + var b = cr.GetBValue(c); + if (layer.background_color[0] === r && layer.background_color[1] === g && layer.background_color[2] === b) + return; + layer.background_color[0] = r; + layer.background_color[1] = g; + layer.background_color[2] = b; + this.runtime.redraw = true; + }; + SysActs.prototype.SetLayerTransparent = function (layer, t) + { + if (!layer) + return; + if (!!t === !!layer.transparent) + return; + layer.transparent = !!t; + this.runtime.redraw = true; + }; + SysActs.prototype.SetLayerBlendMode = function (layer, bm) + { + if (!layer) + return; + if (layer.blend_mode === bm) + return; + layer.blend_mode = bm; + layer.compositeOp = cr.effectToCompositeOp(layer.blend_mode); + if (this.runtime.gl) + cr.setGLBlend(layer, layer.blend_mode, this.runtime.gl); + this.runtime.redraw = true; + }; + SysActs.prototype.StopLoop = function () + { + if (this.runtime.loop_stack_index < 0) + return; // no loop currently running + this.runtime.getCurrentLoop().stopped = true; + }; + SysActs.prototype.GoToLayoutByName = function (layoutname) + { + if (this.runtime.isloading) + return; // cannot change layout while loading on loader layout + if (this.runtime.changelayout) + return; // already changing to different layout +; + var l; + for (l in this.runtime.layouts) + { + if (this.runtime.layouts.hasOwnProperty(l) && cr.equals_nocase(l, layoutname)) + { + this.runtime.changelayout = this.runtime.layouts[l]; + return; + } + } + }; + SysActs.prototype.RestartLayout = function (layoutname) + { + if (this.runtime.isloading) + return; // cannot restart loader layouts + if (this.runtime.changelayout) + return; // already changing to a different layout +; + if (!this.runtime.running_layout) + return; + this.runtime.changelayout = this.runtime.running_layout; + var i, len, g; + for (i = 0, len = this.runtime.allGroups.length; i < len; i++) + { + g = this.runtime.allGroups[i]; + g.setGroupActive(g.initially_activated); + } + }; + SysActs.prototype.SnapshotCanvas = function (format_, quality_) + { + this.runtime.snapshotCanvas = [format_ === 0 ? "image/png" : "image/jpeg", quality_ / 100]; + this.runtime.redraw = true; // force redraw so snapshot is always taken + }; + SysActs.prototype.SetCanvasSize = function (w, h) + { + if (w <= 0 || h <= 0) + return; + var mode = this.runtime.fullscreen_mode; + var isfullscreen = (document["mozFullScreen"] || document["webkitIsFullScreen"] || !!document["msFullscreenElement"] || document["fullScreen"] || this.runtime.isNodeFullscreen); + if (isfullscreen && this.runtime.fullscreen_scaling > 0) + mode = this.runtime.fullscreen_scaling; + if (mode === 0) + { + this.runtime["setSize"](w, h, true); + } + else + { + this.runtime.original_width = w; + this.runtime.original_height = h; + this.runtime["setSize"](this.runtime.lastWindowWidth, this.runtime.lastWindowHeight, true); + } + }; + SysActs.prototype.SetLayoutEffectEnabled = function (enable_, effectname_) + { + if (!this.runtime.running_layout || !this.runtime.glwrap) + return; + var et = this.runtime.running_layout.getEffectByName(effectname_); + if (!et) + return; // effect name not found + var enable = (enable_ === 1); + if (et.active == enable) + return; // no change + et.active = enable; + this.runtime.running_layout.updateActiveEffects(); + this.runtime.redraw = true; + }; + SysActs.prototype.SetLayerEffectEnabled = function (layer, enable_, effectname_) + { + if (!layer || !this.runtime.glwrap) + return; + var et = layer.getEffectByName(effectname_); + if (!et) + return; // effect name not found + var enable = (enable_ === 1); + if (et.active == enable) + return; // no change + et.active = enable; + layer.updateActiveEffects(); + this.runtime.redraw = true; + }; + SysActs.prototype.SetLayoutEffectParam = function (effectname_, index_, value_) + { + if (!this.runtime.running_layout || !this.runtime.glwrap) + return; + var et = this.runtime.running_layout.getEffectByName(effectname_); + if (!et) + return; // effect name not found + var params = this.runtime.running_layout.effect_params[et.index]; + index_ = Math.floor(index_); + if (index_ < 0 || index_ >= params.length) + return; // effect index out of bounds + if (this.runtime.glwrap.getProgramParameterType(et.shaderindex, index_) === 1) + value_ /= 100.0; + if (params[index_] === value_) + return; // no change + params[index_] = value_; + if (et.active) + this.runtime.redraw = true; + }; + SysActs.prototype.SetLayerEffectParam = function (layer, effectname_, index_, value_) + { + if (!layer || !this.runtime.glwrap) + return; + var et = layer.getEffectByName(effectname_); + if (!et) + return; // effect name not found + var params = layer.effect_params[et.index]; + index_ = Math.floor(index_); + if (index_ < 0 || index_ >= params.length) + return; // effect index out of bounds + if (this.runtime.glwrap.getProgramParameterType(et.shaderindex, index_) === 1) + value_ /= 100.0; + if (params[index_] === value_) + return; // no change + params[index_] = value_; + if (et.active) + this.runtime.redraw = true; + }; + SysActs.prototype.SaveState = function (slot_) + { + this.runtime.saveToSlot = slot_; + }; + SysActs.prototype.LoadState = function (slot_) + { + this.runtime.loadFromSlot = slot_; + }; + SysActs.prototype.LoadStateJSON = function (jsonstr_) + { + this.runtime.loadFromJson = jsonstr_; + }; + SysActs.prototype.SetHalfFramerateMode = function (set_) + { + this.runtime.halfFramerateMode = (set_ !== 0); + }; + SysActs.prototype.SetFullscreenQuality = function (q) + { + var isfullscreen = (document["mozFullScreen"] || document["webkitIsFullScreen"] || !!document["msFullscreenElement"] || document["fullScreen"] || this.isNodeFullscreen); + if (!isfullscreen && this.runtime.fullscreen_mode === 0) + return; + this.runtime.wantFullscreenScalingQuality = (q !== 0); + this.runtime["setSize"](this.runtime.lastWindowWidth, this.runtime.lastWindowHeight, true); + }; + SysActs.prototype.ResetPersisted = function () + { + var i, len; + for (i = 0, len = this.runtime.layouts_by_index.length; i < len; ++i) + { + this.runtime.layouts_by_index[i].persist_data = {}; + this.runtime.layouts_by_index[i].first_visit = true; + } + }; + SysActs.prototype.RecreateInitialObjects = function (obj, x1, y1, x2, y2) + { + if (!obj) + return; + this.runtime.running_layout.recreateInitialObjects(obj, x1, y1, x2, y2); + }; + sysProto.acts = new SysActs(); + function SysExps() {}; + SysExps.prototype["int"] = function(ret, x) + { + if (cr.is_string(x)) + { + ret.set_int(parseInt(x, 10)); + if (isNaN(ret.data)) + ret.data = 0; + } + else + ret.set_int(x); + }; + SysExps.prototype["float"] = function(ret, x) + { + if (cr.is_string(x)) + { + ret.set_float(parseFloat(x)); + if (isNaN(ret.data)) + ret.data = 0; + } + else + ret.set_float(x); + }; + SysExps.prototype.str = function(ret, x) + { + if (cr.is_string(x)) + ret.set_string(x); + else + ret.set_string(x.toString()); + }; + SysExps.prototype.len = function(ret, x) + { + ret.set_int(x.length || 0); + }; + SysExps.prototype.random = function (ret, a, b) + { + if (b === undefined) + { + ret.set_float(Math.random() * a); + } + else + { + ret.set_float(Math.random() * (b - a) + a); + } + }; + SysExps.prototype.sqrt = function(ret, x) + { + ret.set_float(Math.sqrt(x)); + }; + SysExps.prototype.abs = function(ret, x) + { + ret.set_float(Math.abs(x)); + }; + SysExps.prototype.round = function(ret, x) + { + ret.set_int(Math.round(x)); + }; + SysExps.prototype.floor = function(ret, x) + { + ret.set_int(Math.floor(x)); + }; + SysExps.prototype.ceil = function(ret, x) + { + ret.set_int(Math.ceil(x)); + }; + SysExps.prototype.sin = function(ret, x) + { + ret.set_float(Math.sin(cr.to_radians(x))); + }; + SysExps.prototype.cos = function(ret, x) + { + ret.set_float(Math.cos(cr.to_radians(x))); + }; + SysExps.prototype.tan = function(ret, x) + { + ret.set_float(Math.tan(cr.to_radians(x))); + }; + SysExps.prototype.asin = function(ret, x) + { + ret.set_float(cr.to_degrees(Math.asin(x))); + }; + SysExps.prototype.acos = function(ret, x) + { + ret.set_float(cr.to_degrees(Math.acos(x))); + }; + SysExps.prototype.atan = function(ret, x) + { + ret.set_float(cr.to_degrees(Math.atan(x))); + }; + SysExps.prototype.exp = function(ret, x) + { + ret.set_float(Math.exp(x)); + }; + SysExps.prototype.ln = function(ret, x) + { + ret.set_float(Math.log(x)); + }; + SysExps.prototype.log10 = function(ret, x) + { + ret.set_float(Math.log(x) / Math.LN10); + }; + SysExps.prototype.max = function(ret) + { + var max_ = arguments[1]; + if (typeof max_ !== "number") + max_ = 0; + var i, len, a; + for (i = 2, len = arguments.length; i < len; i++) + { + a = arguments[i]; + if (typeof a !== "number") + continue; // ignore non-numeric types + if (max_ < a) + max_ = a; + } + ret.set_float(max_); + }; + SysExps.prototype.min = function(ret) + { + var min_ = arguments[1]; + if (typeof min_ !== "number") + min_ = 0; + var i, len, a; + for (i = 2, len = arguments.length; i < len; i++) + { + a = arguments[i]; + if (typeof a !== "number") + continue; // ignore non-numeric types + if (min_ > a) + min_ = a; + } + ret.set_float(min_); + }; + SysExps.prototype.dt = function(ret) + { + ret.set_float(this.runtime.dt); + }; + SysExps.prototype.timescale = function(ret) + { + ret.set_float(this.runtime.timescale); + }; + SysExps.prototype.wallclocktime = function(ret) + { + ret.set_float((Date.now() - this.runtime.start_time) / 1000.0); + }; + SysExps.prototype.time = function(ret) + { + ret.set_float(this.runtime.kahanTime.sum); + }; + SysExps.prototype.tickcount = function(ret) + { + ret.set_int(this.runtime.tickcount); + }; + SysExps.prototype.objectcount = function(ret) + { + ret.set_int(this.runtime.objectcount); + }; + SysExps.prototype.fps = function(ret) + { + ret.set_int(this.runtime.fps); + }; + SysExps.prototype.loopindex = function(ret, name_) + { + var loop, i, len; + if (!this.runtime.loop_stack.length) + { + ret.set_int(0); + return; + } + if (name_) + { + for (i = 0, len = this.runtime.loop_stack.length; i < len; i++) + { + loop = this.runtime.loop_stack[i]; + if (loop.name === name_) + { + ret.set_int(loop.index); + return; + } + } + ret.set_int(0); + } + else + { + loop = this.runtime.getCurrentLoop(); + ret.set_int(loop ? loop.index : -1); + } + }; + SysExps.prototype.distance = function(ret, x1, y1, x2, y2) + { + ret.set_float(cr.distanceTo(x1, y1, x2, y2)); + }; + SysExps.prototype.angle = function(ret, x1, y1, x2, y2) + { + ret.set_float(cr.to_degrees(cr.angleTo(x1, y1, x2, y2))); + }; + SysExps.prototype.scrollx = function(ret) + { + ret.set_float(this.runtime.running_layout.scrollX); + }; + SysExps.prototype.scrolly = function(ret) + { + ret.set_float(this.runtime.running_layout.scrollY); + }; + SysExps.prototype.newline = function(ret) + { + ret.set_string("\n"); + }; + SysExps.prototype.lerp = function(ret, a, b, x) + { + ret.set_float(cr.lerp(a, b, x)); + }; + SysExps.prototype.qarp = function(ret, a, b, c, x) + { + ret.set_float(cr.qarp(a, b, c, x)); + }; + SysExps.prototype.cubic = function(ret, a, b, c, d, x) + { + ret.set_float(cr.cubic(a, b, c, d, x)); + }; + SysExps.prototype.cosp = function(ret, a, b, x) + { + ret.set_float(cr.cosp(a, b, x)); + }; + SysExps.prototype.windowwidth = function(ret) + { + ret.set_int(this.runtime.width); + }; + SysExps.prototype.windowheight = function(ret) + { + ret.set_int(this.runtime.height); + }; + SysExps.prototype.uppercase = function(ret, str) + { + ret.set_string(cr.is_string(str) ? str.toUpperCase() : ""); + }; + SysExps.prototype.lowercase = function(ret, str) + { + ret.set_string(cr.is_string(str) ? str.toLowerCase() : ""); + }; + SysExps.prototype.clamp = function(ret, x, l, u) + { + if (x < l) + ret.set_float(l); + else if (x > u) + ret.set_float(u); + else + ret.set_float(x); + }; + SysExps.prototype.layerscale = function (ret, layerparam) + { + var layer = this.runtime.getLayer(layerparam); + if (!layer) + ret.set_float(0); + else + ret.set_float(layer.scale); + }; + SysExps.prototype.layeropacity = function (ret, layerparam) + { + var layer = this.runtime.getLayer(layerparam); + if (!layer) + ret.set_float(0); + else + ret.set_float(layer.opacity * 100); + }; + SysExps.prototype.layerscalerate = function (ret, layerparam) + { + var layer = this.runtime.getLayer(layerparam); + if (!layer) + ret.set_float(0); + else + ret.set_float(layer.zoomRate); + }; + SysExps.prototype.layerparallaxx = function (ret, layerparam) + { + var layer = this.runtime.getLayer(layerparam); + if (!layer) + ret.set_float(0); + else + ret.set_float(layer.parallaxX * 100); + }; + SysExps.prototype.layerparallaxy = function (ret, layerparam) + { + var layer = this.runtime.getLayer(layerparam); + if (!layer) + ret.set_float(0); + else + ret.set_float(layer.parallaxY * 100); + }; + SysExps.prototype.layerindex = function (ret, layerparam) + { + var layer = this.runtime.getLayer(layerparam); + if (!layer) + ret.set_int(-1); + else + ret.set_int(layer.index); + }; + SysExps.prototype.layoutscale = function (ret) + { + if (this.runtime.running_layout) + ret.set_float(this.runtime.running_layout.scale); + else + ret.set_float(0); + }; + SysExps.prototype.layoutangle = function (ret) + { + ret.set_float(cr.to_degrees(this.runtime.running_layout.angle)); + }; + SysExps.prototype.layerangle = function (ret, layerparam) + { + var layer = this.runtime.getLayer(layerparam); + if (!layer) + ret.set_float(0); + else + ret.set_float(cr.to_degrees(layer.angle)); + }; + SysExps.prototype.layoutwidth = function (ret) + { + ret.set_int(this.runtime.running_layout.width); + }; + SysExps.prototype.layoutheight = function (ret) + { + ret.set_int(this.runtime.running_layout.height); + }; + SysExps.prototype.find = function (ret, text, searchstr) + { + if (cr.is_string(text) && cr.is_string(searchstr)) + ret.set_int(text.search(new RegExp(cr.regexp_escape(searchstr), "i"))); + else + ret.set_int(-1); + }; + SysExps.prototype.left = function (ret, text, n) + { + ret.set_string(cr.is_string(text) ? text.substr(0, n) : ""); + }; + SysExps.prototype.right = function (ret, text, n) + { + ret.set_string(cr.is_string(text) ? text.substr(text.length - n) : ""); + }; + SysExps.prototype.mid = function (ret, text, index_, length_) + { + ret.set_string(cr.is_string(text) ? text.substr(index_, length_) : ""); + }; + SysExps.prototype.tokenat = function (ret, text, index_, sep) + { + if (cr.is_string(text) && cr.is_string(sep)) + { + var arr = text.split(sep); + var i = cr.floor(index_); + if (i < 0 || i >= arr.length) + ret.set_string(""); + else + ret.set_string(arr[i]); + } + else + ret.set_string(""); + }; + SysExps.prototype.tokencount = function (ret, text, sep) + { + if (cr.is_string(text) && text.length) + ret.set_int(text.split(sep).length); + else + ret.set_int(0); + }; + SysExps.prototype.replace = function (ret, text, find_, replace_) + { + if (cr.is_string(text) && cr.is_string(find_) && cr.is_string(replace_)) + ret.set_string(text.replace(new RegExp(cr.regexp_escape(find_), "gi"), replace_)); + else + ret.set_string(cr.is_string(text) ? text : ""); + }; + SysExps.prototype.trim = function (ret, text) + { + ret.set_string(cr.is_string(text) ? text.trim() : ""); + }; + SysExps.prototype.pi = function (ret) + { + ret.set_float(cr.PI); + }; + SysExps.prototype.layoutname = function (ret) + { + if (this.runtime.running_layout) + ret.set_string(this.runtime.running_layout.name); + else + ret.set_string(""); + }; + SysExps.prototype.renderer = function (ret) + { + ret.set_string(this.runtime.gl ? "webgl" : "canvas2d"); + }; + SysExps.prototype.anglediff = function (ret, a, b) + { + ret.set_float(cr.to_degrees(cr.angleDiff(cr.to_radians(a), cr.to_radians(b)))); + }; + SysExps.prototype.choose = function (ret) + { + var index = cr.floor(Math.random() * (arguments.length - 1)); + ret.set_any(arguments[index + 1]); + }; + SysExps.prototype.rgb = function (ret, r, g, b) + { + ret.set_int(cr.RGB(r, g, b)); + }; + SysExps.prototype.projectversion = function (ret) + { + ret.set_string(this.runtime.versionstr); + }; + SysExps.prototype.projectname = function (ret) + { + ret.set_string(this.runtime.projectName); + }; + SysExps.prototype.anglelerp = function (ret, a, b, x) + { + a = cr.to_radians(a); + b = cr.to_radians(b); + var diff = cr.angleDiff(a, b); + if (cr.angleClockwise(b, a)) + { + ret.set_float(cr.to_clamped_degrees(a + diff * x)); + } + else + { + ret.set_float(cr.to_clamped_degrees(a - diff * x)); + } + }; + SysExps.prototype.anglerotate = function (ret, a, b, c) + { + a = cr.to_radians(a); + b = cr.to_radians(b); + c = cr.to_radians(c); + ret.set_float(cr.to_clamped_degrees(cr.angleRotate(a, b, c))); + }; + SysExps.prototype.zeropad = function (ret, n, d) + { + var s = (n < 0 ? "-" : ""); + if (n < 0) n = -n; + var zeroes = d - n.toString().length; + for (var i = 0; i < zeroes; i++) + s += "0"; + ret.set_string(s + n.toString()); + }; + SysExps.prototype.cpuutilisation = function (ret) + { + ret.set_float(this.runtime.cpuutilisation / 1000); + }; + SysExps.prototype.viewportleft = function (ret, layerparam) + { + var layer = this.runtime.getLayer(layerparam); + ret.set_float(layer ? layer.viewLeft : 0); + }; + SysExps.prototype.viewporttop = function (ret, layerparam) + { + var layer = this.runtime.getLayer(layerparam); + ret.set_float(layer ? layer.viewTop : 0); + }; + SysExps.prototype.viewportright = function (ret, layerparam) + { + var layer = this.runtime.getLayer(layerparam); + ret.set_float(layer ? layer.viewRight : 0); + }; + SysExps.prototype.viewportbottom = function (ret, layerparam) + { + var layer = this.runtime.getLayer(layerparam); + ret.set_float(layer ? layer.viewBottom : 0); + }; + SysExps.prototype.loadingprogress = function (ret) + { + ret.set_float(this.runtime.loadingprogress); + }; + SysExps.prototype.unlerp = function(ret, a, b, y) + { + ret.set_float(cr.unlerp(a, b, y)); + }; + SysExps.prototype.canvassnapshot = function (ret) + { + ret.set_string(this.runtime.snapshotData); + }; + SysExps.prototype.urlencode = function (ret, s) + { + ret.set_string(encodeURIComponent(s)); + }; + SysExps.prototype.urldecode = function (ret, s) + { + ret.set_string(decodeURIComponent(s)); + }; + SysExps.prototype.canvastolayerx = function (ret, layerparam, x, y) + { + var layer = this.runtime.getLayer(layerparam); + ret.set_float(layer ? layer.canvasToLayer(x, y, true) : 0); + }; + SysExps.prototype.canvastolayery = function (ret, layerparam, x, y) + { + var layer = this.runtime.getLayer(layerparam); + ret.set_float(layer ? layer.canvasToLayer(x, y, false) : 0); + }; + SysExps.prototype.layertocanvasx = function (ret, layerparam, x, y) + { + var layer = this.runtime.getLayer(layerparam); + ret.set_float(layer ? layer.layerToCanvas(x, y, true) : 0); + }; + SysExps.prototype.layertocanvasy = function (ret, layerparam, x, y) + { + var layer = this.runtime.getLayer(layerparam); + ret.set_float(layer ? layer.layerToCanvas(x, y, false) : 0); + }; + SysExps.prototype.savestatejson = function (ret) + { + ret.set_string(this.runtime.lastSaveJson); + }; + SysExps.prototype.imagememoryusage = function (ret) + { + if (this.runtime.glwrap) + ret.set_float(Math.round(100 * this.runtime.glwrap.estimateVRAM() / (1024 * 1024)) / 100); + else + ret.set_float(0); + }; + SysExps.prototype.regexsearch = function (ret, str_, regex_, flags_) + { + var regex = getRegex(regex_, flags_); + ret.set_int(str_ ? str_.search(regex) : -1); + }; + SysExps.prototype.regexreplace = function (ret, str_, regex_, flags_, replace_) + { + var regex = getRegex(regex_, flags_); + ret.set_string(str_ ? str_.replace(regex, replace_) : ""); + }; + var regexMatches = []; + var lastMatchesStr = ""; + var lastMatchesRegex = ""; + var lastMatchesFlags = ""; + function updateRegexMatches(str_, regex_, flags_) + { + if (str_ === lastMatchesStr && regex_ === lastMatchesRegex && flags_ === lastMatchesFlags) + return; + var regex = getRegex(regex_, flags_); + regexMatches = str_.match(regex); + lastMatchesStr = str_; + lastMatchesRegex = regex_; + lastMatchesFlags = flags_; + }; + SysExps.prototype.regexmatchcount = function (ret, str_, regex_, flags_) + { + var regex = getRegex(regex_, flags_); + updateRegexMatches(str_, regex_, flags_); + ret.set_int(regexMatches ? regexMatches.length : 0); + }; + SysExps.prototype.regexmatchat = function (ret, str_, regex_, flags_, index_) + { + index_ = Math.floor(index_); + var regex = getRegex(regex_, flags_); + updateRegexMatches(str_, regex_, flags_); + if (!regexMatches || index_ < 0 || index_ >= regexMatches.length) + ret.set_string(""); + else + ret.set_string(regexMatches[index_]); + }; + SysExps.prototype.infinity = function (ret) + { + ret.set_float(Infinity); + }; + SysExps.prototype.setbit = function (ret, n, b, v) + { + n = n | 0; + b = b | 0; + v = (v !== 0 ? 1 : 0); + ret.set_int((n & ~(1 << b)) | (v << b)); + }; + SysExps.prototype.togglebit = function (ret, n, b) + { + n = n | 0; + b = b | 0; + ret.set_int(n ^ (1 << b)); + }; + SysExps.prototype.getbit = function (ret, n, b) + { + n = n | 0; + b = b | 0; + ret.set_int((n & (1 << b)) ? 1 : 0); + }; + SysExps.prototype.originalwindowwidth = function (ret) + { + ret.set_int(this.runtime.original_width); + }; + SysExps.prototype.originalwindowheight = function (ret) + { + ret.set_int(this.runtime.original_height); + }; + sysProto.exps = new SysExps(); + sysProto.runWaits = function () + { + var i, j, len, w, k, s, ss; + var evinfo = this.runtime.getCurrentEventStack(); + for (i = 0, len = this.waits.length; i < len; i++) + { + w = this.waits[i]; + if (w.time === -1) // signalled wait + { + if (!w.signalled) + continue; // not yet signalled + } + else // timer wait + { + if (w.time > this.runtime.kahanTime.sum) + continue; // timer not yet expired + } + evinfo.current_event = w.ev; + evinfo.actindex = w.actindex; + evinfo.cndindex = 0; + for (k in w.sols) + { + if (w.sols.hasOwnProperty(k)) + { + s = this.runtime.types_by_index[parseInt(k, 10)].getCurrentSol(); + ss = w.sols[k]; + s.select_all = ss.sa; + cr.shallowAssignArray(s.instances, ss.insts); + freeSolStateObject(ss); + } + } + w.ev.resume_actions_and_subevents(); + this.runtime.clearSol(w.solModifiers); + w.deleteme = true; + } + for (i = 0, j = 0, len = this.waits.length; i < len; i++) + { + w = this.waits[i]; + this.waits[j] = w; + if (w.deleteme) + freeWaitObject(w); + else + j++; + } + this.waits.length = j; + }; +}()); +; +(function () { + cr.add_common_aces = function (m, pluginProto) + { + var singleglobal_ = m[1]; + var position_aces = m[3]; + var size_aces = m[4]; + var angle_aces = m[5]; + var appearance_aces = m[6]; + var zorder_aces = m[7]; + var effects_aces = m[8]; + if (!pluginProto.cnds) + pluginProto.cnds = {}; + if (!pluginProto.acts) + pluginProto.acts = {}; + if (!pluginProto.exps) + pluginProto.exps = {}; + var cnds = pluginProto.cnds; + var acts = pluginProto.acts; + var exps = pluginProto.exps; + if (position_aces) + { + cnds.CompareX = function (cmp, x) + { + return cr.do_cmp(this.x, cmp, x); + }; + cnds.CompareY = function (cmp, y) + { + return cr.do_cmp(this.y, cmp, y); + }; + cnds.IsOnScreen = function () + { + var layer = this.layer; + this.update_bbox(); + var bbox = this.bbox; + return !(bbox.right < layer.viewLeft || bbox.bottom < layer.viewTop || bbox.left > layer.viewRight || bbox.top > layer.viewBottom); + }; + cnds.IsOutsideLayout = function () + { + this.update_bbox(); + var bbox = this.bbox; + var layout = this.runtime.running_layout; + return (bbox.right < 0 || bbox.bottom < 0 || bbox.left > layout.width || bbox.top > layout.height); + }; + cnds.PickDistance = function (which, x, y) + { + var sol = this.getCurrentSol(); + var instances = sol.getObjects(); + if (!instances.length) + return false; + var inst = instances[0]; + var pickme = inst; + var dist = cr.distanceTo(inst.x, inst.y, x, y); + var i, len, d; + for (i = 1, len = instances.length; i < len; i++) + { + inst = instances[i]; + d = cr.distanceTo(inst.x, inst.y, x, y); + if ((which === 0 && d < dist) || (which === 1 && d > dist)) + { + dist = d; + pickme = inst; + } + } + sol.pick_one(pickme); + return true; + }; + acts.SetX = function (x) + { + if (this.x !== x) + { + this.x = x; + this.set_bbox_changed(); + } + }; + acts.SetY = function (y) + { + if (this.y !== y) + { + this.y = y; + this.set_bbox_changed(); + } + }; + acts.SetPos = function (x, y) + { + if (this.x !== x || this.y !== y) + { + this.x = x; + this.y = y; + this.set_bbox_changed(); + } + }; + acts.SetPosToObject = function (obj, imgpt) + { + var inst = obj.getPairedInstance(this); + if (!inst) + return; + var newx, newy; + if (inst.getImagePoint) + { + newx = inst.getImagePoint(imgpt, true); + newy = inst.getImagePoint(imgpt, false); + } + else + { + newx = inst.x; + newy = inst.y; + } + if (this.x !== newx || this.y !== newy) + { + this.x = newx; + this.y = newy; + this.set_bbox_changed(); + } + }; + acts.MoveForward = function (dist) + { + if (dist !== 0) + { + this.x += Math.cos(this.angle) * dist; + this.y += Math.sin(this.angle) * dist; + this.set_bbox_changed(); + } + }; + acts.MoveAtAngle = function (a, dist) + { + if (dist !== 0) + { + this.x += Math.cos(cr.to_radians(a)) * dist; + this.y += Math.sin(cr.to_radians(a)) * dist; + this.set_bbox_changed(); + } + }; + exps.X = function (ret) + { + ret.set_float(this.x); + }; + exps.Y = function (ret) + { + ret.set_float(this.y); + }; + exps.dt = function (ret) + { + ret.set_float(this.runtime.getDt(this)); + }; + } + if (size_aces) + { + cnds.CompareWidth = function (cmp, w) + { + return cr.do_cmp(this.width, cmp, w); + }; + cnds.CompareHeight = function (cmp, h) + { + return cr.do_cmp(this.height, cmp, h); + }; + acts.SetWidth = function (w) + { + if (this.width !== w) + { + this.width = w; + this.set_bbox_changed(); + } + }; + acts.SetHeight = function (h) + { + if (this.height !== h) + { + this.height = h; + this.set_bbox_changed(); + } + }; + acts.SetSize = function (w, h) + { + if (this.width !== w || this.height !== h) + { + this.width = w; + this.height = h; + this.set_bbox_changed(); + } + }; + exps.Width = function (ret) + { + ret.set_float(this.width); + }; + exps.Height = function (ret) + { + ret.set_float(this.height); + }; + exps.BBoxLeft = function (ret) + { + this.update_bbox(); + ret.set_float(this.bbox.left); + }; + exps.BBoxTop = function (ret) + { + this.update_bbox(); + ret.set_float(this.bbox.top); + }; + exps.BBoxRight = function (ret) + { + this.update_bbox(); + ret.set_float(this.bbox.right); + }; + exps.BBoxBottom = function (ret) + { + this.update_bbox(); + ret.set_float(this.bbox.bottom); + }; + } + if (angle_aces) + { + cnds.AngleWithin = function (within, a) + { + return cr.angleDiff(this.angle, cr.to_radians(a)) <= cr.to_radians(within); + }; + cnds.IsClockwiseFrom = function (a) + { + return cr.angleClockwise(this.angle, cr.to_radians(a)); + }; + cnds.IsBetweenAngles = function (a, b) + { + var lower = cr.to_clamped_radians(a); + var upper = cr.to_clamped_radians(b); + var angle = cr.clamp_angle(this.angle); + var obtuse = (!cr.angleClockwise(upper, lower)); + if (obtuse) + return !(!cr.angleClockwise(angle, lower) && cr.angleClockwise(angle, upper)); + else + return cr.angleClockwise(angle, lower) && !cr.angleClockwise(angle, upper); + }; + acts.SetAngle = function (a) + { + var newangle = cr.to_radians(cr.clamp_angle_degrees(a)); + if (isNaN(newangle)) + return; + if (this.angle !== newangle) + { + this.angle = newangle; + this.set_bbox_changed(); + } + }; + acts.RotateClockwise = function (a) + { + if (a !== 0 && !isNaN(a)) + { + this.angle += cr.to_radians(a); + this.angle = cr.clamp_angle(this.angle); + this.set_bbox_changed(); + } + }; + acts.RotateCounterclockwise = function (a) + { + if (a !== 0 && !isNaN(a)) + { + this.angle -= cr.to_radians(a); + this.angle = cr.clamp_angle(this.angle); + this.set_bbox_changed(); + } + }; + acts.RotateTowardAngle = function (amt, target) + { + var newangle = cr.angleRotate(this.angle, cr.to_radians(target), cr.to_radians(amt)); + if (isNaN(newangle)) + return; + if (this.angle !== newangle) + { + this.angle = newangle; + this.set_bbox_changed(); + } + }; + acts.RotateTowardPosition = function (amt, x, y) + { + var dx = x - this.x; + var dy = y - this.y; + var target = Math.atan2(dy, dx); + var newangle = cr.angleRotate(this.angle, target, cr.to_radians(amt)); + if (isNaN(newangle)) + return; + if (this.angle !== newangle) + { + this.angle = newangle; + this.set_bbox_changed(); + } + }; + acts.SetTowardPosition = function (x, y) + { + var dx = x - this.x; + var dy = y - this.y; + var newangle = Math.atan2(dy, dx); + if (isNaN(newangle)) + return; + if (this.angle !== newangle) + { + this.angle = newangle; + this.set_bbox_changed(); + } + }; + exps.Angle = function (ret) + { + ret.set_float(cr.to_clamped_degrees(this.angle)); + }; + } + if (!singleglobal_) + { + cnds.CompareInstanceVar = function (iv, cmp, val) + { + return cr.do_cmp(this.instance_vars[iv], cmp, val); + }; + cnds.IsBoolInstanceVarSet = function (iv) + { + return this.instance_vars[iv]; + }; + cnds.PickInstVarHiLow = function (which, iv) + { + var sol = this.getCurrentSol(); + var instances = sol.getObjects(); + if (!instances.length) + return false; + var inst = instances[0]; + var pickme = inst; + var val = inst.instance_vars[iv]; + var i, len, v; + for (i = 1, len = instances.length; i < len; i++) + { + inst = instances[i]; + v = inst.instance_vars[iv]; + if ((which === 0 && v < val) || (which === 1 && v > val)) + { + val = v; + pickme = inst; + } + } + sol.pick_one(pickme); + return true; + }; + cnds.PickByUID = function (u) + { + var i, len, j, inst, families, instances, sol; + var cnd = this.runtime.getCurrentCondition(); + if (cnd.inverted) + { + sol = this.getCurrentSol(); + if (sol.select_all) + { + sol.select_all = false; + sol.instances.length = 0; + sol.else_instances.length = 0; + instances = this.instances; + for (i = 0, len = instances.length; i < len; i++) + { + inst = instances[i]; + if (inst.uid === u) + sol.else_instances.push(inst); + else + sol.instances.push(inst); + } + this.applySolToContainer(); + return !!sol.instances.length; + } + else + { + for (i = 0, j = 0, len = sol.instances.length; i < len; i++) + { + inst = sol.instances[i]; + sol.instances[j] = inst; + if (inst.uid === u) + { + sol.else_instances.push(inst); + } + else + j++; + } + sol.instances.length = j; + this.applySolToContainer(); + return !!sol.instances.length; + } + } + else + { + inst = this.runtime.getObjectByUID(u); + if (!inst) + return false; + sol = this.getCurrentSol(); + if (!sol.select_all && sol.instances.indexOf(inst) === -1) + return false; // not picked + if (this.is_family) + { + families = inst.type.families; + for (i = 0, len = families.length; i < len; i++) + { + if (families[i] === this) + { + sol.pick_one(inst); + this.applySolToContainer(); + return true; + } + } + } + else if (inst.type === this) + { + sol.pick_one(inst); + this.applySolToContainer(); + return true; + } + return false; + } + }; + cnds.OnCreated = function () + { + return true; + }; + cnds.OnDestroyed = function () + { + return true; + }; + acts.SetInstanceVar = function (iv, val) + { + var myinstvars = this.instance_vars; + if (cr.is_number(myinstvars[iv])) + { + if (cr.is_number(val)) + myinstvars[iv] = val; + else + myinstvars[iv] = parseFloat(val); + } + else if (cr.is_string(myinstvars[iv])) + { + if (cr.is_string(val)) + myinstvars[iv] = val; + else + myinstvars[iv] = val.toString(); + } + else +; + }; + acts.AddInstanceVar = function (iv, val) + { + var myinstvars = this.instance_vars; + if (cr.is_number(myinstvars[iv])) + { + if (cr.is_number(val)) + myinstvars[iv] += val; + else + myinstvars[iv] += parseFloat(val); + } + else if (cr.is_string(myinstvars[iv])) + { + if (cr.is_string(val)) + myinstvars[iv] += val; + else + myinstvars[iv] += val.toString(); + } + else +; + }; + acts.SubInstanceVar = function (iv, val) + { + var myinstvars = this.instance_vars; + if (cr.is_number(myinstvars[iv])) + { + if (cr.is_number(val)) + myinstvars[iv] -= val; + else + myinstvars[iv] -= parseFloat(val); + } + else +; + }; + acts.SetBoolInstanceVar = function (iv, val) + { + this.instance_vars[iv] = val ? 1 : 0; + }; + acts.ToggleBoolInstanceVar = function (iv) + { + this.instance_vars[iv] = 1 - this.instance_vars[iv]; + }; + acts.Destroy = function () + { + this.runtime.DestroyInstance(this); + }; + if (!acts.LoadFromJsonString) + { + acts.LoadFromJsonString = function (str_) + { + var o, i, len, binst; + try { + o = JSON.parse(str_); + } + catch (e) { + return; + } + this.runtime.loadInstanceFromJSON(this, o, true); + if (this.afterLoad) + this.afterLoad(); + if (this.behavior_insts) + { + for (i = 0, len = this.behavior_insts.length; i < len; ++i) + { + binst = this.behavior_insts[i]; + if (binst.afterLoad) + binst.afterLoad(); + } + } + }; + } + exps.Count = function (ret) + { + var count = ret.object_class.instances.length; + var i, len, inst; + for (i = 0, len = this.runtime.createRow.length; i < len; i++) + { + inst = this.runtime.createRow[i]; + if (ret.object_class.is_family) + { + if (inst.type.families.indexOf(ret.object_class) >= 0) + count++; + } + else + { + if (inst.type === ret.object_class) + count++; + } + } + ret.set_int(count); + }; + exps.PickedCount = function (ret) + { + ret.set_int(ret.object_class.getCurrentSol().getObjects().length); + }; + exps.UID = function (ret) + { + ret.set_int(this.uid); + }; + exps.IID = function (ret) + { + ret.set_int(this.get_iid()); + }; + if (!exps.AsJSON) + { + exps.AsJSON = function (ret) + { + ret.set_string(JSON.stringify(this.runtime.saveInstanceToJSON(this, true))); + }; + } + } + if (appearance_aces) + { + cnds.IsVisible = function () + { + return this.visible; + }; + acts.SetVisible = function (v) + { + if (!v !== !this.visible) + { + this.visible = v; + this.runtime.redraw = true; + } + }; + cnds.CompareOpacity = function (cmp, x) + { + return cr.do_cmp(cr.round6dp(this.opacity * 100), cmp, x); + }; + acts.SetOpacity = function (x) + { + var new_opacity = x / 100.0; + if (new_opacity < 0) + new_opacity = 0; + else if (new_opacity > 1) + new_opacity = 1; + if (new_opacity !== this.opacity) + { + this.opacity = new_opacity; + this.runtime.redraw = true; + } + }; + exps.Opacity = function (ret) + { + ret.set_float(cr.round6dp(this.opacity * 100.0)); + }; + } + if (zorder_aces) + { + cnds.IsOnLayer = function (layer_) + { + if (!layer_) + return false; + return this.layer === layer_; + }; + cnds.PickTopBottom = function (which_) + { + var sol = this.getCurrentSol(); + var instances = sol.getObjects(); + if (!instances.length) + return false; + var inst = instances[0]; + var pickme = inst; + var i, len; + for (i = 1, len = instances.length; i < len; i++) + { + inst = instances[i]; + if (which_ === 0) + { + if (inst.layer.index > pickme.layer.index || (inst.layer.index === pickme.layer.index && inst.get_zindex() > pickme.get_zindex())) + { + pickme = inst; + } + } + else + { + if (inst.layer.index < pickme.layer.index || (inst.layer.index === pickme.layer.index && inst.get_zindex() < pickme.get_zindex())) + { + pickme = inst; + } + } + } + sol.pick_one(pickme); + return true; + }; + acts.MoveToTop = function () + { + var layer = this.layer; + var layer_instances = layer.instances; + if (layer_instances.length && layer_instances[layer_instances.length - 1] === this) + return; // is already at top + layer.removeFromInstanceList(this, false); + layer.appendToInstanceList(this, false); + this.runtime.redraw = true; + }; + acts.MoveToBottom = function () + { + var layer = this.layer; + var layer_instances = layer.instances; + if (layer_instances.length && layer_instances[0] === this) + return; // is already at bottom + layer.removeFromInstanceList(this, false); + layer.prependToInstanceList(this, false); + this.runtime.redraw = true; + }; + acts.MoveToLayer = function (layerMove) + { + if (!layerMove || layerMove == this.layer) + return; + this.layer.removeFromInstanceList(this, true); + this.layer = layerMove; + layerMove.appendToInstanceList(this, true); + this.runtime.redraw = true; + }; + acts.ZMoveToObject = function (where_, obj_) + { + var isafter = (where_ === 0); + if (!obj_) + return; + var other = obj_.getFirstPicked(this); + if (!other || other.uid === this.uid) + return; + if (this.layer.index !== other.layer.index) + { + this.layer.removeFromInstanceList(this, true); + this.layer = other.layer; + other.layer.appendToInstanceList(this, true); + } + this.layer.moveInstanceAdjacent(this, other, isafter); + this.runtime.redraw = true; + }; + exps.LayerNumber = function (ret) + { + ret.set_int(this.layer.number); + }; + exps.LayerName = function (ret) + { + ret.set_string(this.layer.name); + }; + exps.ZIndex = function (ret) + { + ret.set_int(this.get_zindex()); + }; + } + if (effects_aces) + { + acts.SetEffectEnabled = function (enable_, effectname_) + { + if (!this.runtime.glwrap) + return; + var i = this.type.getEffectIndexByName(effectname_); + if (i < 0) + return; // effect name not found + var enable = (enable_ === 1); + if (this.active_effect_flags[i] === enable) + return; // no change + this.active_effect_flags[i] = enable; + this.updateActiveEffects(); + this.runtime.redraw = true; + }; + acts.SetEffectParam = function (effectname_, index_, value_) + { + if (!this.runtime.glwrap) + return; + var i = this.type.getEffectIndexByName(effectname_); + if (i < 0) + return; // effect name not found + var et = this.type.effect_types[i]; + var params = this.effect_params[i]; + index_ = Math.floor(index_); + if (index_ < 0 || index_ >= params.length) + return; // effect index out of bounds + if (this.runtime.glwrap.getProgramParameterType(et.shaderindex, index_) === 1) + value_ /= 100.0; + if (params[index_] === value_) + return; // no change + params[index_] = value_; + if (et.active) + this.runtime.redraw = true; + }; + } + }; + cr.set_bbox_changed = function () + { + this.bbox_changed = true; // will recreate next time box requested + this.cell_changed = true; + this.type.any_cell_changed = true; // avoid unnecessary updateAllBBox() calls + this.runtime.redraw = true; // assume runtime needs to redraw + var i, len, callbacks = this.bbox_changed_callbacks; + for (i = 0, len = callbacks.length; i < len; ++i) + { + callbacks[i](this); + } + if (this.layer.useRenderCells) + this.update_bbox(); + }; + cr.add_bbox_changed_callback = function (f) + { + if (f) + { + this.bbox_changed_callbacks.push(f); + } + }; + cr.update_bbox = function () + { + if (!this.bbox_changed) + return; // bounding box not changed + var bbox = this.bbox; + var bquad = this.bquad; + bbox.set(this.x, this.y, this.x + this.width, this.y + this.height); + bbox.offset(-this.hotspotX * this.width, -this.hotspotY * this.height); + if (!this.angle) + { + bquad.set_from_rect(bbox); // make bounding quad from box + } + else + { + bbox.offset(-this.x, -this.y); // translate to origin + bquad.set_from_rotated_rect(bbox, this.angle); // rotate around origin + bquad.offset(this.x, this.y); // translate back to original position + bquad.bounding_box(bbox); + } + bbox.normalize(); + this.bbox_changed = false; // bounding box up to date + this.update_render_cell(); + }; + var tmprc = new cr.rect(0, 0, 0, 0); + cr.update_render_cell = function () + { + if (!this.layer.useRenderCells) + return; + var mygrid = this.layer.render_grid; + var bbox = this.bbox; + tmprc.set(mygrid.XToCell(bbox.left), mygrid.YToCell(bbox.top), mygrid.XToCell(bbox.right), mygrid.YToCell(bbox.bottom)); + if (this.rendercells.equals(tmprc)) + return; + if (this.rendercells.right < this.rendercells.left) + mygrid.update(this, null, tmprc); // first insertion with invalid rect: don't provide old range + else + mygrid.update(this, this.rendercells, tmprc); + this.rendercells.copy(tmprc); + this.layer.render_list_stale = true; + }; + cr.update_collision_cell = function () + { + if (!this.cell_changed || !this.collisionsEnabled) + return; + this.update_bbox(); + var mygrid = this.type.collision_grid; + var bbox = this.bbox; + tmprc.set(mygrid.XToCell(bbox.left), mygrid.YToCell(bbox.top), mygrid.XToCell(bbox.right), mygrid.YToCell(bbox.bottom)); + if (this.collcells.equals(tmprc)) + return; + if (this.collcells.right < this.collcells.left) + mygrid.update(this, null, tmprc); // first insertion with invalid rect: don't provide old range + else + mygrid.update(this, this.collcells, tmprc); + this.collcells.copy(tmprc); + this.cell_changed = false; + }; + cr.inst_contains_pt = function (x, y) + { + if (!this.bbox.contains_pt(x, y)) + return false; + if (!this.bquad.contains_pt(x, y)) + return false; + if (this.collision_poly && !this.collision_poly.is_empty()) + { + this.collision_poly.cache_poly(this.width, this.height, this.angle); + return this.collision_poly.contains_pt(x - this.x, y - this.y); + } + else + return true; + }; + cr.inst_get_iid = function () + { + this.type.updateIIDs(); + return this.iid; + }; + cr.inst_get_zindex = function () + { + this.layer.updateZIndices(); + return this.zindex; + }; + cr.inst_updateActiveEffects = function () + { + this.active_effect_types.length = 0; + var i, len, et, inst; + for (i = 0, len = this.active_effect_flags.length; i < len; i++) + { + if (this.active_effect_flags[i]) + this.active_effect_types.push(this.type.effect_types[i]); + } + this.uses_shaders = !!this.active_effect_types.length; + }; + cr.inst_toString = function () + { + return "Inst" + this.puid; + }; + cr.type_getFirstPicked = function (frominst) + { + if (frominst && frominst.is_contained && frominst.type != this) + { + var i, len, s; + for (i = 0, len = frominst.siblings.length; i < len; i++) + { + s = frominst.siblings[i]; + if (s.type == this) + return s; + } + } + var instances = this.getCurrentSol().getObjects(); + if (instances.length) + return instances[0]; + else + return null; + }; + cr.type_getPairedInstance = function (inst) + { + var instances = this.getCurrentSol().getObjects(); + if (instances.length) + return instances[inst.get_iid() % instances.length]; + else + return null; + }; + cr.type_updateIIDs = function () + { + if (!this.stale_iids || this.is_family) + return; // up to date or is family - don't want family to overwrite IIDs + var i, len; + for (i = 0, len = this.instances.length; i < len; i++) + this.instances[i].iid = i; + var next_iid = i; + var createRow = this.runtime.createRow; + for (i = 0, len = createRow.length; i < len; ++i) + { + if (createRow[i].type === this) + createRow[i].iid = next_iid++; + } + this.stale_iids = false; + }; + cr.type_getInstanceByIID = function (i) + { + if (i < this.instances.length) + return this.instances[i]; + i -= this.instances.length; + var createRow = this.runtime.createRow; + var j, lenj; + for (j = 0, lenj = createRow.length; j < lenj; ++j) + { + if (createRow[j].type === this) + { + if (i === 0) + return createRow[j]; + --i; + } + } +; + return null; + }; + cr.type_getCurrentSol = function () + { + return this.solstack[this.cur_sol]; + }; + cr.type_pushCleanSol = function () + { + this.cur_sol++; + if (this.cur_sol === this.solstack.length) + this.solstack.push(new cr.selection(this)); + else + this.solstack[this.cur_sol].select_all = true; // else clear next SOL + }; + cr.type_pushCopySol = function () + { + this.cur_sol++; + if (this.cur_sol === this.solstack.length) + this.solstack.push(new cr.selection(this)); + var clonesol = this.solstack[this.cur_sol]; + var prevsol = this.solstack[this.cur_sol - 1]; + if (prevsol.select_all) + clonesol.select_all = true; + else + { + clonesol.select_all = false; + cr.shallowAssignArray(clonesol.instances, prevsol.instances); + cr.shallowAssignArray(clonesol.else_instances, prevsol.else_instances); + } + }; + cr.type_popSol = function () + { +; + this.cur_sol--; + }; + cr.type_getBehaviorByName = function (behname) + { + var i, len, j, lenj, f, index = 0; + if (!this.is_family) + { + for (i = 0, len = this.families.length; i < len; i++) + { + f = this.families[i]; + for (j = 0, lenj = f.behaviors.length; j < lenj; j++) + { + if (behname === f.behaviors[j].name) + { + this.extra["lastBehIndex"] = index; + return f.behaviors[j]; + } + index++; + } + } + } + for (i = 0, len = this.behaviors.length; i < len; i++) { + if (behname === this.behaviors[i].name) + { + this.extra["lastBehIndex"] = index; + return this.behaviors[i]; + } + index++; + } + return null; + }; + cr.type_getBehaviorIndexByName = function (behname) + { + var b = this.getBehaviorByName(behname); + if (b) + return this.extra["lastBehIndex"]; + else + return -1; + }; + cr.type_getEffectIndexByName = function (name_) + { + var i, len; + for (i = 0, len = this.effect_types.length; i < len; i++) + { + if (this.effect_types[i].name === name_) + return i; + } + return -1; + }; + cr.type_applySolToContainer = function () + { + if (!this.is_contained || this.is_family) + return; + var i, len, j, lenj, t, sol, sol2; + this.updateIIDs(); + sol = this.getCurrentSol(); + var select_all = sol.select_all; + var es = this.runtime.getCurrentEventStack(); + var orblock = es && es.current_event && es.current_event.orblock; + for (i = 0, len = this.container.length; i < len; i++) + { + t = this.container[i]; + if (t === this) + continue; + t.updateIIDs(); + sol2 = t.getCurrentSol(); + sol2.select_all = select_all; + if (!select_all) + { + sol2.instances.length = sol.instances.length; + for (j = 0, lenj = sol.instances.length; j < lenj; j++) + sol2.instances[j] = t.getInstanceByIID(sol.instances[j].iid); + if (orblock) + { + sol2.else_instances.length = sol.else_instances.length; + for (j = 0, lenj = sol.else_instances.length; j < lenj; j++) + sol2.else_instances[j] = t.getInstanceByIID(sol.else_instances[j].iid); + } + } + } + }; + cr.type_toString = function () + { + return "Type" + this.sid; + }; + cr.do_cmp = function (x, cmp, y) + { + if (typeof x === "undefined" || typeof y === "undefined") + return false; + switch (cmp) + { + case 0: // equal + return x === y; + case 1: // not equal + return x !== y; + case 2: // less + return x < y; + case 3: // less/equal + return x <= y; + case 4: // greater + return x > y; + case 5: // greater/equal + return x >= y; + default: +; + return false; + } + }; +})(); +cr.shaders = {}; +; +; +cr.plugins_.Keyboard = function(runtime) +{ + this.runtime = runtime; +}; +(function () +{ + var pluginProto = cr.plugins_.Keyboard.prototype; + pluginProto.Type = function(plugin) + { + this.plugin = plugin; + this.runtime = plugin.runtime; + }; + var typeProto = pluginProto.Type.prototype; + typeProto.onCreate = function() + { + }; + pluginProto.Instance = function(type) + { + this.type = type; + this.runtime = type.runtime; + this.keyMap = new Array(256); // stores key up/down state + this.usedKeys = new Array(256); + this.triggerKey = 0; + }; + var instanceProto = pluginProto.Instance.prototype; + instanceProto.onCreate = function() + { + var self = this; + if (!this.runtime.isDomFree) + { + jQuery(document).keydown( + function(info) { + self.onKeyDown(info); + } + ); + jQuery(document).keyup( + function(info) { + self.onKeyUp(info); + } + ); + } + }; + var keysToBlockWhenFramed = [32, 33, 34, 35, 36, 37, 38, 39, 40, 44]; + instanceProto.onKeyDown = function (info) + { + var alreadyPreventedDefault = false; + if (window != window.top && keysToBlockWhenFramed.indexOf(info.which) > -1) + { + info.preventDefault(); + alreadyPreventedDefault = true; + info.stopPropagation(); + } + if (this.keyMap[info.which]) + { + if (this.usedKeys[info.which] && !alreadyPreventedDefault) + info.preventDefault(); + return; + } + this.keyMap[info.which] = true; + this.triggerKey = info.which; + this.runtime.isInUserInputEvent = true; + this.runtime.trigger(cr.plugins_.Keyboard.prototype.cnds.OnAnyKey, this); + var eventRan = this.runtime.trigger(cr.plugins_.Keyboard.prototype.cnds.OnKey, this); + var eventRan2 = this.runtime.trigger(cr.plugins_.Keyboard.prototype.cnds.OnKeyCode, this); + this.runtime.isInUserInputEvent = false; + if (eventRan || eventRan2) + { + this.usedKeys[info.which] = true; + if (!alreadyPreventedDefault) + info.preventDefault(); + } + }; + instanceProto.onKeyUp = function (info) + { + this.keyMap[info.which] = false; + this.triggerKey = info.which; + this.runtime.isInUserInputEvent = true; + this.runtime.trigger(cr.plugins_.Keyboard.prototype.cnds.OnAnyKeyReleased, this); + var eventRan = this.runtime.trigger(cr.plugins_.Keyboard.prototype.cnds.OnKeyReleased, this); + var eventRan2 = this.runtime.trigger(cr.plugins_.Keyboard.prototype.cnds.OnKeyCodeReleased, this); + this.runtime.isInUserInputEvent = false; + if (eventRan || eventRan2 || this.usedKeys[info.which]) + { + this.usedKeys[info.which] = true; + info.preventDefault(); + } + }; + instanceProto.saveToJSON = function () + { + return { "triggerKey": this.triggerKey }; + }; + instanceProto.loadFromJSON = function (o) + { + this.triggerKey = o["triggerKey"]; + }; + function Cnds() {}; + Cnds.prototype.IsKeyDown = function(key) + { + return this.keyMap[key]; + }; + Cnds.prototype.OnKey = function(key) + { + return (key === this.triggerKey); + }; + Cnds.prototype.OnAnyKey = function(key) + { + return true; + }; + Cnds.prototype.OnAnyKeyReleased = function(key) + { + return true; + }; + Cnds.prototype.OnKeyReleased = function(key) + { + return (key === this.triggerKey); + }; + Cnds.prototype.IsKeyCodeDown = function(key) + { + key = Math.floor(key); + if (key < 0 || key >= this.keyMap.length) + return false; + return this.keyMap[key]; + }; + Cnds.prototype.OnKeyCode = function(key) + { + return (key === this.triggerKey); + }; + Cnds.prototype.OnKeyCodeReleased = function(key) + { + return (key === this.triggerKey); + }; + pluginProto.cnds = new Cnds(); + function Acts() {}; + pluginProto.acts = new Acts(); + function Exps() {}; + Exps.prototype.LastKeyCode = function (ret) + { + ret.set_int(this.triggerKey); + }; + function fixedStringFromCharCode(kc) + { + kc = Math.floor(kc); + switch (kc) { + case 8: return "backspace"; + case 9: return "tab"; + case 13: return "enter"; + case 16: return "shift"; + case 17: return "control"; + case 18: return "alt"; + case 19: return "pause"; + case 20: return "capslock"; + case 27: return "esc"; + case 33: return "pageup"; + case 34: return "pagedown"; + case 35: return "end"; + case 36: return "home"; + case 37: return "←"; + case 38: return "↑"; + case 39: return "→"; + case 40: return "↓"; + case 45: return "insert"; + case 46: return "del"; + case 91: return "left window key"; + case 92: return "right window key"; + case 93: return "select"; + case 96: return "numpad 0"; + case 97: return "numpad 1"; + case 98: return "numpad 2"; + case 99: return "numpad 3"; + case 100: return "numpad 4"; + case 101: return "numpad 5"; + case 102: return "numpad 6"; + case 103: return "numpad 7"; + case 104: return "numpad 8"; + case 105: return "numpad 9"; + case 106: return "numpad *"; + case 107: return "numpad +"; + case 109: return "numpad -"; + case 110: return "numpad ."; + case 111: return "numpad /"; + case 112: return "F1"; + case 113: return "F2"; + case 114: return "F3"; + case 115: return "F4"; + case 116: return "F5"; + case 117: return "F6"; + case 118: return "F7"; + case 119: return "F8"; + case 120: return "F9"; + case 121: return "F10"; + case 122: return "F11"; + case 123: return "F12"; + case 144: return "numlock"; + case 145: return "scroll lock"; + case 186: return ";"; + case 187: return "="; + case 188: return ","; + case 189: return "-"; + case 190: return "."; + case 191: return "/"; + case 192: return "'"; + case 219: return "["; + case 220: return "\\"; + case 221: return "]"; + case 222: return "#"; + case 223: return "`"; + default: return String.fromCharCode(kc); + } + }; + Exps.prototype.StringFromKeyCode = function (ret, kc) + { + ret.set_string(fixedStringFromCharCode(kc)); + }; + pluginProto.exps = new Exps(); +}()); +; +; +cr.plugins_.Sprite = function(runtime) +{ + this.runtime = runtime; +}; +(function () +{ + var pluginProto = cr.plugins_.Sprite.prototype; + pluginProto.Type = function(plugin) + { + this.plugin = plugin; + this.runtime = plugin.runtime; + }; + var typeProto = pluginProto.Type.prototype; + function frame_getDataUri() + { + if (this.datauri.length === 0) + { + var tmpcanvas = document.createElement("canvas"); + tmpcanvas.width = this.width; + tmpcanvas.height = this.height; + var tmpctx = tmpcanvas.getContext("2d"); + if (this.spritesheeted) + { + tmpctx.drawImage(this.texture_img, this.offx, this.offy, this.width, this.height, + 0, 0, this.width, this.height); + } + else + { + tmpctx.drawImage(this.texture_img, 0, 0, this.width, this.height); + } + this.datauri = tmpcanvas.toDataURL("image/png"); + } + return this.datauri; + }; + typeProto.onCreate = function() + { + if (this.is_family) + return; + var i, leni, j, lenj; + var anim, frame, animobj, frameobj, wt, uv; + this.all_frames = []; + this.has_loaded_textures = false; + for (i = 0, leni = this.animations.length; i < leni; i++) + { + anim = this.animations[i]; + animobj = {}; + animobj.name = anim[0]; + animobj.speed = anim[1]; + animobj.loop = anim[2]; + animobj.repeatcount = anim[3]; + animobj.repeatto = anim[4]; + animobj.pingpong = anim[5]; + animobj.sid = anim[6]; + animobj.frames = []; + for (j = 0, lenj = anim[7].length; j < lenj; j++) + { + frame = anim[7][j]; + frameobj = {}; + frameobj.texture_file = frame[0]; + frameobj.texture_filesize = frame[1]; + frameobj.offx = frame[2]; + frameobj.offy = frame[3]; + frameobj.width = frame[4]; + frameobj.height = frame[5]; + frameobj.duration = frame[6]; + frameobj.hotspotX = frame[7]; + frameobj.hotspotY = frame[8]; + frameobj.image_points = frame[9]; + frameobj.poly_pts = frame[10]; + frameobj.pixelformat = frame[11]; + frameobj.spritesheeted = (frameobj.width !== 0); + frameobj.datauri = ""; // generated on demand and cached + frameobj.getDataUri = frame_getDataUri; + uv = {}; + uv.left = 0; + uv.top = 0; + uv.right = 1; + uv.bottom = 1; + frameobj.sheetTex = uv; + frameobj.webGL_texture = null; + wt = this.runtime.findWaitingTexture(frame[0]); + if (wt) + { + frameobj.texture_img = wt; + } + else + { + frameobj.texture_img = new Image(); + frameobj.texture_img.cr_src = frame[0]; + frameobj.texture_img.cr_filesize = frame[1]; + frameobj.texture_img.c2webGL_texture = null; + this.runtime.waitForImageLoad(frameobj.texture_img, frame[0]); + } + cr.seal(frameobj); + animobj.frames.push(frameobj); + this.all_frames.push(frameobj); + } + cr.seal(animobj); + this.animations[i] = animobj; // swap array data for object + } + }; + typeProto.updateAllCurrentTexture = function () + { + var i, len, inst; + for (i = 0, len = this.instances.length; i < len; i++) + { + inst = this.instances[i]; + inst.curWebGLTexture = inst.curFrame.webGL_texture; + } + }; + typeProto.onLostWebGLContext = function () + { + if (this.is_family) + return; + var i, len, frame; + for (i = 0, len = this.all_frames.length; i < len; ++i) + { + frame = this.all_frames[i]; + frame.texture_img.c2webGL_texture = null; + frame.webGL_texture = null; + } + this.has_loaded_textures = false; + this.updateAllCurrentTexture(); + }; + typeProto.onRestoreWebGLContext = function () + { + if (this.is_family || !this.instances.length) + return; + var i, len, frame; + for (i = 0, len = this.all_frames.length; i < len; ++i) + { + frame = this.all_frames[i]; + frame.webGL_texture = this.runtime.glwrap.loadTexture(frame.texture_img, false, this.runtime.linearSampling, frame.pixelformat); + } + this.updateAllCurrentTexture(); + }; + typeProto.loadTextures = function () + { + if (this.is_family || this.has_loaded_textures || !this.runtime.glwrap) + return; + var i, len, frame; + for (i = 0, len = this.all_frames.length; i < len; ++i) + { + frame = this.all_frames[i]; + frame.webGL_texture = this.runtime.glwrap.loadTexture(frame.texture_img, false, this.runtime.linearSampling, frame.pixelformat); + } + this.has_loaded_textures = true; + }; + typeProto.unloadTextures = function () + { + if (this.is_family || this.instances.length || !this.has_loaded_textures) + return; + var i, len, frame; + for (i = 0, len = this.all_frames.length; i < len; ++i) + { + frame = this.all_frames[i]; + this.runtime.glwrap.deleteTexture(frame.webGL_texture); + frame.webGL_texture = null; + } + this.has_loaded_textures = false; + }; + var already_drawn_images = []; + typeProto.preloadCanvas2D = function (ctx) + { + var i, len, frameimg; + already_drawn_images.length = 0; + for (i = 0, len = this.all_frames.length; i < len; ++i) + { + frameimg = this.all_frames[i].texture_img; + if (already_drawn_images.indexOf(frameimg) !== -1) + continue; + ctx.drawImage(frameimg, 0, 0); + already_drawn_images.push(frameimg); + } + }; + pluginProto.Instance = function(type) + { + this.type = type; + this.runtime = type.runtime; + var poly_pts = this.type.animations[0].frames[0].poly_pts; + if (this.recycled) + this.collision_poly.set_pts(poly_pts); + else + this.collision_poly = new cr.CollisionPoly(poly_pts); + }; + var instanceProto = pluginProto.Instance.prototype; + instanceProto.onCreate = function() + { + this.visible = (this.properties[0] === 0); // 0=visible, 1=invisible + this.isTicking = false; + this.inAnimTrigger = false; + this.collisionsEnabled = (this.properties[3] !== 0); + if (!(this.type.animations.length === 1 && this.type.animations[0].frames.length === 1) && this.type.animations[0].speed !== 0) + { + this.runtime.tickMe(this); + this.isTicking = true; + } + this.cur_animation = this.getAnimationByName(this.properties[1]) || this.type.animations[0]; + this.cur_frame = this.properties[2]; + if (this.cur_frame < 0) + this.cur_frame = 0; + if (this.cur_frame >= this.cur_animation.frames.length) + this.cur_frame = this.cur_animation.frames.length - 1; + var curanimframe = this.cur_animation.frames[this.cur_frame]; + this.collision_poly.set_pts(curanimframe.poly_pts); + this.hotspotX = curanimframe.hotspotX; + this.hotspotY = curanimframe.hotspotY; + this.cur_anim_speed = this.cur_animation.speed; + if (this.recycled) + this.animTimer.reset(); + else + this.animTimer = new cr.KahanAdder(); + this.frameStart = this.getNowTime(); + this.animPlaying = true; + this.animRepeats = 0; + this.animForwards = true; + this.animTriggerName = ""; + this.changeAnimName = ""; + this.changeAnimFrom = 0; + this.changeAnimFrame = -1; + this.type.loadTextures(); + var i, leni, j, lenj; + var anim, frame, uv, maintex; + for (i = 0, leni = this.type.animations.length; i < leni; i++) + { + anim = this.type.animations[i]; + for (j = 0, lenj = anim.frames.length; j < lenj; j++) + { + frame = anim.frames[j]; + if (frame.width === 0) + { + frame.width = frame.texture_img.width; + frame.height = frame.texture_img.height; + } + if (frame.spritesheeted) + { + maintex = frame.texture_img; + uv = frame.sheetTex; + uv.left = frame.offx / maintex.width; + uv.top = frame.offy / maintex.height; + uv.right = (frame.offx + frame.width) / maintex.width; + uv.bottom = (frame.offy + frame.height) / maintex.height; + if (frame.offx === 0 && frame.offy === 0 && frame.width === maintex.width && frame.height === maintex.height) + { + frame.spritesheeted = false; + } + } + } + } + this.curFrame = this.cur_animation.frames[this.cur_frame]; + this.curWebGLTexture = this.curFrame.webGL_texture; + }; + instanceProto.saveToJSON = function () + { + var o = { + "a": this.cur_animation.sid, + "f": this.cur_frame, + "cas": this.cur_anim_speed, + "fs": this.frameStart, + "ar": this.animRepeats, + "at": this.animTimer.sum + }; + if (!this.animPlaying) + o["ap"] = this.animPlaying; + if (!this.animForwards) + o["af"] = this.animForwards; + return o; + }; + instanceProto.loadFromJSON = function (o) + { + var anim = this.getAnimationBySid(o["a"]); + if (anim) + this.cur_animation = anim; + this.cur_frame = o["f"]; + if (this.cur_frame < 0) + this.cur_frame = 0; + if (this.cur_frame >= this.cur_animation.frames.length) + this.cur_frame = this.cur_animation.frames.length - 1; + this.cur_anim_speed = o["cas"]; + this.frameStart = o["fs"]; + this.animRepeats = o["ar"]; + this.animTimer.reset(); + this.animTimer.sum = o["at"]; + this.animPlaying = o.hasOwnProperty("ap") ? o["ap"] : true; + this.animForwards = o.hasOwnProperty("af") ? o["af"] : true; + this.curFrame = this.cur_animation.frames[this.cur_frame]; + this.curWebGLTexture = this.curFrame.webGL_texture; + this.collision_poly.set_pts(this.curFrame.poly_pts); + this.hotspotX = this.curFrame.hotspotX; + this.hotspotY = this.curFrame.hotspotY; + }; + instanceProto.animationFinish = function (reverse) + { + this.cur_frame = reverse ? 0 : this.cur_animation.frames.length - 1; + this.animPlaying = false; + this.animTriggerName = this.cur_animation.name; + this.inAnimTrigger = true; + this.runtime.trigger(cr.plugins_.Sprite.prototype.cnds.OnAnyAnimFinished, this); + this.runtime.trigger(cr.plugins_.Sprite.prototype.cnds.OnAnimFinished, this); + this.inAnimTrigger = false; + this.animRepeats = 0; + }; + instanceProto.getNowTime = function() + { + return this.animTimer.sum; + }; + instanceProto.tick = function() + { + this.animTimer.add(this.runtime.getDt(this)); + if (this.changeAnimName.length) + this.doChangeAnim(); + if (this.changeAnimFrame >= 0) + this.doChangeAnimFrame(); + var now = this.getNowTime(); + var cur_animation = this.cur_animation; + var prev_frame = cur_animation.frames[this.cur_frame]; + var next_frame; + var cur_frame_time = prev_frame.duration / this.cur_anim_speed; + if (this.animPlaying && now >= this.frameStart + cur_frame_time) + { + if (this.animForwards) + { + this.cur_frame++; + } + else + { + this.cur_frame--; + } + this.frameStart += cur_frame_time; + if (this.cur_frame >= cur_animation.frames.length) + { + if (cur_animation.pingpong) + { + this.animForwards = false; + this.cur_frame = cur_animation.frames.length - 2; + } + else if (cur_animation.loop) + { + this.cur_frame = cur_animation.repeatto; + } + else + { + this.animRepeats++; + if (this.animRepeats >= cur_animation.repeatcount) + { + this.animationFinish(false); + } + else + { + this.cur_frame = cur_animation.repeatto; + } + } + } + if (this.cur_frame < 0) + { + if (cur_animation.pingpong) + { + this.cur_frame = 1; + this.animForwards = true; + if (!cur_animation.loop) + { + this.animRepeats++; + if (this.animRepeats >= cur_animation.repeatcount) + { + this.animationFinish(true); + } + } + } + else + { + if (cur_animation.loop) + { + this.cur_frame = cur_animation.repeatto; + } + else + { + this.animRepeats++; + if (this.animRepeats >= cur_animation.repeatcount) + { + this.animationFinish(true); + } + else + { + this.cur_frame = cur_animation.repeatto; + } + } + } + } + if (this.cur_frame < 0) + this.cur_frame = 0; + else if (this.cur_frame >= cur_animation.frames.length) + this.cur_frame = cur_animation.frames.length - 1; + if (now > this.frameStart + (cur_animation.frames[this.cur_frame].duration / this.cur_anim_speed)) + { + this.frameStart = now; + } + next_frame = cur_animation.frames[this.cur_frame]; + this.OnFrameChanged(prev_frame, next_frame); + this.runtime.redraw = true; + } + }; + instanceProto.getAnimationByName = function (name_) + { + var i, len, a; + for (i = 0, len = this.type.animations.length; i < len; i++) + { + a = this.type.animations[i]; + if (cr.equals_nocase(a.name, name_)) + return a; + } + return null; + }; + instanceProto.getAnimationBySid = function (sid_) + { + var i, len, a; + for (i = 0, len = this.type.animations.length; i < len; i++) + { + a = this.type.animations[i]; + if (a.sid === sid_) + return a; + } + return null; + }; + instanceProto.doChangeAnim = function () + { + var prev_frame = this.cur_animation.frames[this.cur_frame]; + var anim = this.getAnimationByName(this.changeAnimName); + this.changeAnimName = ""; + if (!anim) + return; + if (cr.equals_nocase(anim.name, this.cur_animation.name) && this.animPlaying) + return; + this.cur_animation = anim; + this.cur_anim_speed = anim.speed; + if (this.cur_frame < 0) + this.cur_frame = 0; + if (this.cur_frame >= this.cur_animation.frames.length) + this.cur_frame = this.cur_animation.frames.length - 1; + if (this.changeAnimFrom === 1) + this.cur_frame = 0; + this.animPlaying = true; + this.frameStart = this.getNowTime(); + this.animForwards = true; + this.OnFrameChanged(prev_frame, this.cur_animation.frames[this.cur_frame]); + this.runtime.redraw = true; + }; + instanceProto.doChangeAnimFrame = function () + { + var prev_frame = this.cur_animation.frames[this.cur_frame]; + var prev_frame_number = this.cur_frame; + this.cur_frame = cr.floor(this.changeAnimFrame); + if (this.cur_frame < 0) + this.cur_frame = 0; + if (this.cur_frame >= this.cur_animation.frames.length) + this.cur_frame = this.cur_animation.frames.length - 1; + if (prev_frame_number !== this.cur_frame) + { + this.OnFrameChanged(prev_frame, this.cur_animation.frames[this.cur_frame]); + this.frameStart = this.getNowTime(); + this.runtime.redraw = true; + } + this.changeAnimFrame = -1; + }; + instanceProto.OnFrameChanged = function (prev_frame, next_frame) + { + var oldw = prev_frame.width; + var oldh = prev_frame.height; + var neww = next_frame.width; + var newh = next_frame.height; + if (oldw != neww) + this.width *= (neww / oldw); + if (oldh != newh) + this.height *= (newh / oldh); + this.hotspotX = next_frame.hotspotX; + this.hotspotY = next_frame.hotspotY; + this.collision_poly.set_pts(next_frame.poly_pts); + this.set_bbox_changed(); + this.curFrame = next_frame; + this.curWebGLTexture = next_frame.webGL_texture; + var i, len, b; + for (i = 0, len = this.behavior_insts.length; i < len; i++) + { + b = this.behavior_insts[i]; + if (b.onSpriteFrameChanged) + b.onSpriteFrameChanged(prev_frame, next_frame); + } + this.runtime.trigger(cr.plugins_.Sprite.prototype.cnds.OnFrameChanged, this); + }; + instanceProto.draw = function(ctx) + { + ctx.globalAlpha = this.opacity; + var cur_frame = this.curFrame; + var spritesheeted = cur_frame.spritesheeted; + var cur_image = cur_frame.texture_img; + var myx = this.x; + var myy = this.y; + var w = this.width; + var h = this.height; + if (this.angle === 0 && w >= 0 && h >= 0) + { + myx -= this.hotspotX * w; + myy -= this.hotspotY * h; + if (this.runtime.pixel_rounding) + { + myx = Math.round(myx); + myy = Math.round(myy); + } + if (spritesheeted) + { + ctx.drawImage(cur_image, cur_frame.offx, cur_frame.offy, cur_frame.width, cur_frame.height, + myx, myy, w, h); + } + else + { + ctx.drawImage(cur_image, myx, myy, w, h); + } + } + else + { + if (this.runtime.pixel_rounding) + { + myx = Math.round(myx); + myy = Math.round(myy); + } + ctx.save(); + var widthfactor = w > 0 ? 1 : -1; + var heightfactor = h > 0 ? 1 : -1; + ctx.translate(myx, myy); + if (widthfactor !== 1 || heightfactor !== 1) + ctx.scale(widthfactor, heightfactor); + ctx.rotate(this.angle * widthfactor * heightfactor); + var drawx = 0 - (this.hotspotX * cr.abs(w)) + var drawy = 0 - (this.hotspotY * cr.abs(h)); + if (spritesheeted) + { + ctx.drawImage(cur_image, cur_frame.offx, cur_frame.offy, cur_frame.width, cur_frame.height, + drawx, drawy, cr.abs(w), cr.abs(h)); + } + else + { + ctx.drawImage(cur_image, drawx, drawy, cr.abs(w), cr.abs(h)); + } + ctx.restore(); + } + /* + ctx.strokeStyle = "#f00"; + ctx.lineWidth = 3; + ctx.beginPath(); + this.collision_poly.cache_poly(this.width, this.height, this.angle); + var i, len, ax, ay, bx, by; + for (i = 0, len = this.collision_poly.pts_count; i < len; i++) + { + ax = this.collision_poly.pts_cache[i*2] + this.x; + ay = this.collision_poly.pts_cache[i*2+1] + this.y; + bx = this.collision_poly.pts_cache[((i+1)%len)*2] + this.x; + by = this.collision_poly.pts_cache[((i+1)%len)*2+1] + this.y; + ctx.moveTo(ax, ay); + ctx.lineTo(bx, by); + } + ctx.stroke(); + ctx.closePath(); + */ + /* + if (this.behavior_insts.length >= 1 && this.behavior_insts[0].draw) + { + this.behavior_insts[0].draw(ctx); + } + */ + }; + instanceProto.drawGL = function(glw) + { + glw.setTexture(this.curWebGLTexture); + glw.setOpacity(this.opacity); + var cur_frame = this.curFrame; + var q = this.bquad; + if (this.runtime.pixel_rounding) + { + var ox = Math.round(this.x) - this.x; + var oy = Math.round(this.y) - this.y; + if (cur_frame.spritesheeted) + glw.quadTex(q.tlx + ox, q.tly + oy, q.trx + ox, q.try_ + oy, q.brx + ox, q.bry + oy, q.blx + ox, q.bly + oy, cur_frame.sheetTex); + else + glw.quad(q.tlx + ox, q.tly + oy, q.trx + ox, q.try_ + oy, q.brx + ox, q.bry + oy, q.blx + ox, q.bly + oy); + } + else + { + if (cur_frame.spritesheeted) + glw.quadTex(q.tlx, q.tly, q.trx, q.try_, q.brx, q.bry, q.blx, q.bly, cur_frame.sheetTex); + else + glw.quad(q.tlx, q.tly, q.trx, q.try_, q.brx, q.bry, q.blx, q.bly); + } + }; + instanceProto.getImagePointIndexByName = function(name_) + { + var cur_frame = this.curFrame; + var i, len; + for (i = 0, len = cur_frame.image_points.length; i < len; i++) + { + if (cr.equals_nocase(name_, cur_frame.image_points[i][0])) + return i; + } + return -1; + }; + instanceProto.getImagePoint = function(imgpt, getX) + { + var cur_frame = this.curFrame; + var image_points = cur_frame.image_points; + var index; + if (cr.is_string(imgpt)) + index = this.getImagePointIndexByName(imgpt); + else + index = imgpt - 1; // 0 is origin + index = cr.floor(index); + if (index < 0 || index >= image_points.length) + return getX ? this.x : this.y; // return origin + var x = (image_points[index][1] - cur_frame.hotspotX) * this.width; + var y = image_points[index][2]; + y = (y - cur_frame.hotspotY) * this.height; + var cosa = Math.cos(this.angle); + var sina = Math.sin(this.angle); + var x_temp = (x * cosa) - (y * sina); + y = (y * cosa) + (x * sina); + x = x_temp; + x += this.x; + y += this.y; + return getX ? x : y; + }; + function Cnds() {}; + var arrCache = []; + function allocArr() + { + if (arrCache.length) + return arrCache.pop(); + else + return [0, 0, 0]; + }; + function freeArr(a) + { + a[0] = 0; + a[1] = 0; + a[2] = 0; + arrCache.push(a); + }; + function makeCollKey(a, b) + { + if (a < b) + return "" + a + "," + b; + else + return "" + b + "," + a; + }; + function collmemory_add(collmemory, a, b, tickcount) + { + var a_uid = a.uid; + var b_uid = b.uid; + var key = makeCollKey(a_uid, b_uid); + if (collmemory.hasOwnProperty(key)) + { + collmemory[key][2] = tickcount; + return; + } + var arr = allocArr(); + arr[0] = a_uid; + arr[1] = b_uid; + arr[2] = tickcount; + collmemory[key] = arr; + }; + function collmemory_remove(collmemory, a, b) + { + var key = makeCollKey(a.uid, b.uid); + if (collmemory.hasOwnProperty(key)) + { + freeArr(collmemory[key]); + delete collmemory[key]; + } + }; + function collmemory_removeInstance(collmemory, inst) + { + var uid = inst.uid; + var p, entry; + for (p in collmemory) + { + if (collmemory.hasOwnProperty(p)) + { + entry = collmemory[p]; + if (entry[0] === uid || entry[1] === uid) + { + freeArr(collmemory[p]); + delete collmemory[p]; + } + } + } + }; + var last_coll_tickcount = -2; + function collmemory_has(collmemory, a, b) + { + var key = makeCollKey(a.uid, b.uid); + if (collmemory.hasOwnProperty(key)) + { + last_coll_tickcount = collmemory[key][2]; + return true; + } + else + { + last_coll_tickcount = -2; + return false; + } + }; + var candidates1 = []; + Cnds.prototype.OnCollision = function (rtype) + { + if (!rtype) + return false; + var runtime = this.runtime; + var cnd = runtime.getCurrentCondition(); + var ltype = cnd.type; + if (!cnd.extra["collmemory"]) + { + cnd.extra["collmemory"] = {}; + runtime.addDestroyCallback((function (collmemory) { + return function(inst) { + collmemory_removeInstance(collmemory, inst); + }; + })(cnd.extra["collmemory"])); + } + var collmemory = cnd.extra["collmemory"]; + var lsol = ltype.getCurrentSol(); + var rsol = rtype.getCurrentSol(); + var linstances = lsol.getObjects(); + var rinstances; + var l, linst, r, rinst; + var curlsol, currsol; + var tickcount = this.runtime.tickcount; + var lasttickcount = tickcount - 1; + var exists, run; + var current_event = runtime.getCurrentEventStack().current_event; + var orblock = current_event.orblock; + for (l = 0; l < linstances.length; l++) + { + linst = linstances[l]; + if (rsol.select_all) + { + linst.update_bbox(); + this.runtime.getCollisionCandidates(linst.layer, rtype, linst.bbox, candidates1); + rinstances = candidates1; + } + else + rinstances = rsol.getObjects(); + for (r = 0; r < rinstances.length; r++) + { + rinst = rinstances[r]; + if (runtime.testOverlap(linst, rinst) || runtime.checkRegisteredCollision(linst, rinst)) + { + exists = collmemory_has(collmemory, linst, rinst); + run = (!exists || (last_coll_tickcount < lasttickcount)); + collmemory_add(collmemory, linst, rinst, tickcount); + if (run) + { + runtime.pushCopySol(current_event.solModifiers); + curlsol = ltype.getCurrentSol(); + currsol = rtype.getCurrentSol(); + curlsol.select_all = false; + currsol.select_all = false; + if (ltype === rtype) + { + curlsol.instances.length = 2; // just use lsol, is same reference as rsol + curlsol.instances[0] = linst; + curlsol.instances[1] = rinst; + ltype.applySolToContainer(); + } + else + { + curlsol.instances.length = 1; + currsol.instances.length = 1; + curlsol.instances[0] = linst; + currsol.instances[0] = rinst; + ltype.applySolToContainer(); + rtype.applySolToContainer(); + } + current_event.retrigger(); + runtime.popSol(current_event.solModifiers); + } + } + else + { + collmemory_remove(collmemory, linst, rinst); + } + } + candidates1.length = 0; + } + return false; + }; + var rpicktype = null; + var rtopick = new cr.ObjectSet(); + var needscollisionfinish = false; + var candidates2 = []; + var temp_bbox = new cr.rect(0, 0, 0, 0); + function DoOverlapCondition(rtype, offx, offy) + { + if (!rtype) + return false; + var do_offset = (offx !== 0 || offy !== 0); + var oldx, oldy, ret = false, r, lenr, rinst; + var cnd = this.runtime.getCurrentCondition(); + var ltype = cnd.type; + var inverted = cnd.inverted; + var rsol = rtype.getCurrentSol(); + var orblock = this.runtime.getCurrentEventStack().current_event.orblock; + var rinstances; + if (rsol.select_all) + { + this.update_bbox(); + temp_bbox.copy(this.bbox); + temp_bbox.offset(offx, offy); + this.runtime.getCollisionCandidates(this.layer, rtype, temp_bbox, candidates2); + rinstances = candidates2; + } + else if (orblock) + rinstances = rsol.else_instances; + else + rinstances = rsol.instances; + rpicktype = rtype; + needscollisionfinish = (ltype !== rtype && !inverted); + if (do_offset) + { + oldx = this.x; + oldy = this.y; + this.x += offx; + this.y += offy; + this.set_bbox_changed(); + } + for (r = 0, lenr = rinstances.length; r < lenr; r++) + { + rinst = rinstances[r]; + if (this.runtime.testOverlap(this, rinst)) + { + ret = true; + if (inverted) + break; + if (ltype !== rtype) + rtopick.add(rinst); + } + } + if (do_offset) + { + this.x = oldx; + this.y = oldy; + this.set_bbox_changed(); + } + candidates2.length = 0; + return ret; + }; + typeProto.finish = function (do_pick) + { + if (!needscollisionfinish) + return; + if (do_pick) + { + var orblock = this.runtime.getCurrentEventStack().current_event.orblock; + var sol = rpicktype.getCurrentSol(); + var topick = rtopick.valuesRef(); + var i, len, inst; + if (sol.select_all) + { + sol.select_all = false; + sol.instances.length = topick.length; + for (i = 0, len = topick.length; i < len; i++) + { + sol.instances[i] = topick[i]; + } + if (orblock) + { + sol.else_instances.length = 0; + for (i = 0, len = rpicktype.instances.length; i < len; i++) + { + inst = rpicktype.instances[i]; + if (!rtopick.contains(inst)) + sol.else_instances.push(inst); + } + } + } + else + { + if (orblock) + { + var initsize = sol.instances.length; + sol.instances.length = initsize + topick.length; + for (i = 0, len = topick.length; i < len; i++) + { + sol.instances[initsize + i] = topick[i]; + cr.arrayFindRemove(sol.else_instances, topick[i]); + } + } + else + { + cr.shallowAssignArray(sol.instances, topick); + } + } + rpicktype.applySolToContainer(); + } + rtopick.clear(); + needscollisionfinish = false; + }; + Cnds.prototype.IsOverlapping = function (rtype) + { + return DoOverlapCondition.call(this, rtype, 0, 0); + }; + Cnds.prototype.IsOverlappingOffset = function (rtype, offx, offy) + { + return DoOverlapCondition.call(this, rtype, offx, offy); + }; + Cnds.prototype.IsAnimPlaying = function (animname) + { + if (this.changeAnimName.length) + return cr.equals_nocase(this.changeAnimName, animname); + else + return cr.equals_nocase(this.cur_animation.name, animname); + }; + Cnds.prototype.CompareFrame = function (cmp, framenum) + { + return cr.do_cmp(this.cur_frame, cmp, framenum); + }; + Cnds.prototype.CompareAnimSpeed = function (cmp, x) + { + var s = (this.animForwards ? this.cur_anim_speed : -this.cur_anim_speed); + return cr.do_cmp(s, cmp, x); + }; + Cnds.prototype.OnAnimFinished = function (animname) + { + return cr.equals_nocase(this.animTriggerName, animname); + }; + Cnds.prototype.OnAnyAnimFinished = function () + { + return true; + }; + Cnds.prototype.OnFrameChanged = function () + { + return true; + }; + Cnds.prototype.IsMirrored = function () + { + return this.width < 0; + }; + Cnds.prototype.IsFlipped = function () + { + return this.height < 0; + }; + Cnds.prototype.OnURLLoaded = function () + { + return true; + }; + Cnds.prototype.IsCollisionEnabled = function () + { + return this.collisionsEnabled; + }; + pluginProto.cnds = new Cnds(); + function Acts() {}; + Acts.prototype.Spawn = function (obj, layer, imgpt) + { + if (!obj || !layer) + return; + var inst = this.runtime.createInstance(obj, layer, this.getImagePoint(imgpt, true), this.getImagePoint(imgpt, false)); + if (!inst) + return; + if (typeof inst.angle !== "undefined") + { + inst.angle = this.angle; + inst.set_bbox_changed(); + } + this.runtime.isInOnDestroy++; + var i, len, s; + this.runtime.trigger(Object.getPrototypeOf(obj.plugin).cnds.OnCreated, inst); + if (inst.is_contained) + { + for (i = 0, len = inst.siblings.length; i < len; i++) + { + s = inst.siblings[i]; + this.runtime.trigger(Object.getPrototypeOf(s.type.plugin).cnds.OnCreated, s); + } + } + this.runtime.isInOnDestroy--; + var cur_act = this.runtime.getCurrentAction(); + var reset_sol = false; + if (cr.is_undefined(cur_act.extra["Spawn_LastExec"]) || cur_act.extra["Spawn_LastExec"] < this.runtime.execcount) + { + reset_sol = true; + cur_act.extra["Spawn_LastExec"] = this.runtime.execcount; + } + var sol; + if (obj != this.type) + { + sol = obj.getCurrentSol(); + sol.select_all = false; + if (reset_sol) + { + sol.instances.length = 1; + sol.instances[0] = inst; + } + else + sol.instances.push(inst); + if (inst.is_contained) + { + for (i = 0, len = inst.siblings.length; i < len; i++) + { + s = inst.siblings[i]; + sol = s.type.getCurrentSol(); + sol.select_all = false; + if (reset_sol) + { + sol.instances.length = 1; + sol.instances[0] = s; + } + else + sol.instances.push(s); + } + } + } + }; + Acts.prototype.SetEffect = function (effect) + { + this.compositeOp = cr.effectToCompositeOp(effect); + cr.setGLBlend(this, effect, this.runtime.gl); + this.runtime.redraw = true; + }; + Acts.prototype.StopAnim = function () + { + this.animPlaying = false; + }; + Acts.prototype.StartAnim = function (from) + { + this.animPlaying = true; + this.frameStart = this.getNowTime(); + if (from === 1 && this.cur_frame !== 0) + { + this.changeAnimFrame = 0; + if (!this.inAnimTrigger) + this.doChangeAnimFrame(); + } + if (!this.isTicking) + { + this.runtime.tickMe(this); + this.isTicking = true; + } + }; + Acts.prototype.SetAnim = function (animname, from) + { + this.changeAnimName = animname; + this.changeAnimFrom = from; + if (!this.isTicking) + { + this.runtime.tickMe(this); + this.isTicking = true; + } + if (!this.inAnimTrigger) + this.doChangeAnim(); + }; + Acts.prototype.SetAnimFrame = function (framenumber) + { + this.changeAnimFrame = framenumber; + if (!this.isTicking) + { + this.runtime.tickMe(this); + this.isTicking = true; + } + if (!this.inAnimTrigger) + this.doChangeAnimFrame(); + }; + Acts.prototype.SetAnimSpeed = function (s) + { + this.cur_anim_speed = cr.abs(s); + this.animForwards = (s >= 0); + if (!this.isTicking) + { + this.runtime.tickMe(this); + this.isTicking = true; + } + }; + Acts.prototype.SetMirrored = function (m) + { + var neww = cr.abs(this.width) * (m === 0 ? -1 : 1); + if (this.width === neww) + return; + this.width = neww; + this.set_bbox_changed(); + }; + Acts.prototype.SetFlipped = function (f) + { + var newh = cr.abs(this.height) * (f === 0 ? -1 : 1); + if (this.height === newh) + return; + this.height = newh; + this.set_bbox_changed(); + }; + Acts.prototype.SetScale = function (s) + { + var cur_frame = this.curFrame; + var mirror_factor = (this.width < 0 ? -1 : 1); + var flip_factor = (this.height < 0 ? -1 : 1); + var new_width = cur_frame.width * s * mirror_factor; + var new_height = cur_frame.height * s * flip_factor; + if (this.width !== new_width || this.height !== new_height) + { + this.width = new_width; + this.height = new_height; + this.set_bbox_changed(); + } + }; + Acts.prototype.LoadURL = function (url_, resize_) + { + var img = new Image(); + var self = this; + var curFrame_ = this.curFrame; + img.onload = function () + { + if (curFrame_.texture_img.src === img.src) + { + if (self.runtime.glwrap && self.curFrame === curFrame_) + self.curWebGLTexture = curFrame_.webGL_texture; + self.runtime.redraw = true; + self.runtime.trigger(cr.plugins_.Sprite.prototype.cnds.OnURLLoaded, self); + return; + } + curFrame_.texture_img = img; + curFrame_.offx = 0; + curFrame_.offy = 0; + curFrame_.width = img.width; + curFrame_.height = img.height; + curFrame_.spritesheeted = false; + curFrame_.datauri = ""; + curFrame_.pixelformat = 0; // reset to RGBA, since we don't know what type of image will have come in + if (self.runtime.glwrap) + { + if (curFrame_.webGL_texture) + self.runtime.glwrap.deleteTexture(curFrame_.webGL_texture); + curFrame_.webGL_texture = self.runtime.glwrap.loadTexture(img, false, self.runtime.linearSampling); + if (self.curFrame === curFrame_) + self.curWebGLTexture = curFrame_.webGL_texture; + self.type.updateAllCurrentTexture(); + } + if (resize_ === 0) // resize to image size + { + self.width = img.width; + self.height = img.height; + self.set_bbox_changed(); + } + self.runtime.redraw = true; + self.runtime.trigger(cr.plugins_.Sprite.prototype.cnds.OnURLLoaded, self); + }; + if (url_.substr(0, 5) !== "data:") + img["crossOrigin"] = "anonymous"; + img.src = url_; + }; + Acts.prototype.SetCollisions = function (set_) + { + if (this.collisionsEnabled === (set_ !== 0)) + return; // no change + this.collisionsEnabled = (set_ !== 0); + if (this.collisionsEnabled) + this.set_bbox_changed(); // needs to be added back to cells + else + { + if (this.collcells.right >= this.collcells.left) + this.type.collision_grid.update(this, this.collcells, null); + this.collcells.set(0, 0, -1, -1); + } + }; + pluginProto.acts = new Acts(); + function Exps() {}; + Exps.prototype.AnimationFrame = function (ret) + { + ret.set_int(this.cur_frame); + }; + Exps.prototype.AnimationFrameCount = function (ret) + { + ret.set_int(this.cur_animation.frames.length); + }; + Exps.prototype.AnimationName = function (ret) + { + ret.set_string(this.cur_animation.name); + }; + Exps.prototype.AnimationSpeed = function (ret) + { + ret.set_float(this.animForwards ? this.cur_anim_speed : -this.cur_anim_speed); + }; + Exps.prototype.ImagePointX = function (ret, imgpt) + { + ret.set_float(this.getImagePoint(imgpt, true)); + }; + Exps.prototype.ImagePointY = function (ret, imgpt) + { + ret.set_float(this.getImagePoint(imgpt, false)); + }; + Exps.prototype.ImagePointCount = function (ret) + { + ret.set_int(this.curFrame.image_points.length); + }; + Exps.prototype.ImageWidth = function (ret) + { + ret.set_float(this.curFrame.width); + }; + Exps.prototype.ImageHeight = function (ret) + { + ret.set_float(this.curFrame.height); + }; + pluginProto.exps = new Exps(); +}()); +; +; +cr.plugins_.Text = function(runtime) +{ + this.runtime = runtime; +}; +(function () +{ + var pluginProto = cr.plugins_.Text.prototype; + pluginProto.onCreate = function () + { + pluginProto.acts.SetWidth = function (w) + { + if (this.width !== w) + { + this.width = w; + this.text_changed = true; // also recalculate text wrapping + this.set_bbox_changed(); + } + }; + }; + pluginProto.Type = function(plugin) + { + this.plugin = plugin; + this.runtime = plugin.runtime; + }; + var typeProto = pluginProto.Type.prototype; + typeProto.onCreate = function() + { + }; + typeProto.onLostWebGLContext = function () + { + if (this.is_family) + return; + var i, len, inst; + for (i = 0, len = this.instances.length; i < len; i++) + { + inst = this.instances[i]; + inst.mycanvas = null; + inst.myctx = null; + inst.mytex = null; + } + }; + pluginProto.Instance = function(type) + { + this.type = type; + this.runtime = type.runtime; + if (this.recycled) + this.lines.length = 0; + else + this.lines = []; // for word wrapping + this.text_changed = true; + }; + var instanceProto = pluginProto.Instance.prototype; + var requestedWebFonts = {}; // already requested web fonts have an entry here + instanceProto.onCreate = function() + { + this.text = this.properties[0]; + this.visible = (this.properties[1] === 0); // 0=visible, 1=invisible + this.font = this.properties[2]; + this.color = this.properties[3]; + this.halign = this.properties[4]; // 0=left, 1=center, 2=right + this.valign = this.properties[5]; // 0=top, 1=center, 2=bottom + this.wrapbyword = (this.properties[7] === 0); // 0=word, 1=character + this.lastwidth = this.width; + this.lastwrapwidth = this.width; + this.lastheight = this.height; + this.line_height_offset = this.properties[8]; + this.facename = ""; + this.fontstyle = ""; + this.ptSize = 0; + this.textWidth = 0; + this.textHeight = 0; + this.parseFont(); + this.mycanvas = null; + this.myctx = null; + this.mytex = null; + this.need_text_redraw = false; + this.last_render_tick = this.runtime.tickcount; + if (this.recycled) + this.rcTex.set(0, 0, 1, 1); + else + this.rcTex = new cr.rect(0, 0, 1, 1); + if (this.runtime.glwrap) + this.runtime.tickMe(this); +; + }; + instanceProto.parseFont = function () + { + var arr = this.font.split(" "); + var i; + for (i = 0; i < arr.length; i++) + { + if (arr[i].substr(arr[i].length - 2, 2) === "pt") + { + this.ptSize = parseInt(arr[i].substr(0, arr[i].length - 2)); + this.pxHeight = Math.ceil((this.ptSize / 72.0) * 96.0) + 4; // assume 96dpi... + if (i > 0) + this.fontstyle = arr[i - 1]; + this.facename = arr[i + 1]; + for (i = i + 2; i < arr.length; i++) + this.facename += " " + arr[i]; + break; + } + } + }; + instanceProto.saveToJSON = function () + { + return { + "t": this.text, + "f": this.font, + "c": this.color, + "ha": this.halign, + "va": this.valign, + "wr": this.wrapbyword, + "lho": this.line_height_offset, + "fn": this.facename, + "fs": this.fontstyle, + "ps": this.ptSize, + "pxh": this.pxHeight, + "tw": this.textWidth, + "th": this.textHeight, + "lrt": this.last_render_tick + }; + }; + instanceProto.loadFromJSON = function (o) + { + this.text = o["t"]; + this.font = o["f"]; + this.color = o["c"]; + this.halign = o["ha"]; + this.valign = o["va"]; + this.wrapbyword = o["wr"]; + this.line_height_offset = o["lho"]; + this.facename = o["fn"]; + this.fontstyle = o["fs"]; + this.ptSize = o["ps"]; + this.pxHeight = o["pxh"]; + this.textWidth = o["tw"]; + this.textHeight = o["th"]; + this.last_render_tick = o["lrt"]; + this.text_changed = true; + this.lastwidth = this.width; + this.lastwrapwidth = this.width; + this.lastheight = this.height; + }; + instanceProto.tick = function () + { + if (this.runtime.glwrap && this.mytex && (this.runtime.tickcount - this.last_render_tick >= 300)) + { + var layer = this.layer; + this.update_bbox(); + var bbox = this.bbox; + if (bbox.right < layer.viewLeft || bbox.bottom < layer.viewTop || bbox.left > layer.viewRight || bbox.top > layer.viewBottom) + { + this.runtime.glwrap.deleteTexture(this.mytex); + this.mytex = null; + this.myctx = null; + this.mycanvas = null; + } + } + }; + instanceProto.onDestroy = function () + { + this.myctx = null; + this.mycanvas = null; + if (this.runtime.glwrap && this.mytex) + this.runtime.glwrap.deleteTexture(this.mytex); + this.mytex = null; + }; + instanceProto.updateFont = function () + { + this.font = this.fontstyle + " " + this.ptSize.toString() + "pt " + this.facename; + this.text_changed = true; + this.runtime.redraw = true; + }; + instanceProto.draw = function(ctx, glmode) + { + ctx.font = this.font; + ctx.textBaseline = "top"; + ctx.fillStyle = this.color; + ctx.globalAlpha = glmode ? 1 : this.opacity; + var myscale = 1; + if (glmode) + { + myscale = this.layer.getScale(); + ctx.save(); + ctx.scale(myscale, myscale); + } + if (this.text_changed || this.width !== this.lastwrapwidth) + { + this.type.plugin.WordWrap(this.text, this.lines, ctx, this.width, this.wrapbyword); + this.text_changed = false; + this.lastwrapwidth = this.width; + } + this.update_bbox(); + var penX = glmode ? 0 : this.bquad.tlx; + var penY = glmode ? 0 : this.bquad.tly; + if (this.runtime.pixel_rounding) + { + penX = (penX + 0.5) | 0; + penY = (penY + 0.5) | 0; + } + if (this.angle !== 0 && !glmode) + { + ctx.save(); + ctx.translate(penX, penY); + ctx.rotate(this.angle); + penX = 0; + penY = 0; + } + var endY = penY + this.height; + var line_height = this.pxHeight; + line_height += this.line_height_offset; + var drawX; + var i; + if (this.valign === 1) // center + penY += Math.max(this.height / 2 - (this.lines.length * line_height) / 2, 0); + else if (this.valign === 2) // bottom + penY += Math.max(this.height - (this.lines.length * line_height) - 2, 0); + for (i = 0; i < this.lines.length; i++) + { + drawX = penX; + if (this.halign === 1) // center + drawX = penX + (this.width - this.lines[i].width) / 2; + else if (this.halign === 2) // right + drawX = penX + (this.width - this.lines[i].width); + ctx.fillText(this.lines[i].text, drawX, penY); + penY += line_height; + if (penY >= endY - line_height) + break; + } + if (this.angle !== 0 || glmode) + ctx.restore(); + this.last_render_tick = this.runtime.tickcount; + }; + instanceProto.drawGL = function(glw) + { + if (this.width < 1 || this.height < 1) + return; + var need_redraw = this.text_changed || this.need_text_redraw; + this.need_text_redraw = false; + var layer_scale = this.layer.getScale(); + var layer_angle = this.layer.getAngle(); + var rcTex = this.rcTex; + var floatscaledwidth = layer_scale * this.width; + var floatscaledheight = layer_scale * this.height; + var scaledwidth = Math.ceil(floatscaledwidth); + var scaledheight = Math.ceil(floatscaledheight); + var halfw = this.runtime.draw_width / 2; + var halfh = this.runtime.draw_height / 2; + if (!this.myctx) + { + this.mycanvas = document.createElement("canvas"); + this.mycanvas.width = scaledwidth; + this.mycanvas.height = scaledheight; + this.lastwidth = scaledwidth; + this.lastheight = scaledheight; + need_redraw = true; + this.myctx = this.mycanvas.getContext("2d"); + } + if (scaledwidth !== this.lastwidth || scaledheight !== this.lastheight) + { + this.mycanvas.width = scaledwidth; + this.mycanvas.height = scaledheight; + if (this.mytex) + { + glw.deleteTexture(this.mytex); + this.mytex = null; + } + need_redraw = true; + } + if (need_redraw) + { + this.myctx.clearRect(0, 0, scaledwidth, scaledheight); + this.draw(this.myctx, true); + if (!this.mytex) + this.mytex = glw.createEmptyTexture(scaledwidth, scaledheight, this.runtime.linearSampling, this.runtime.isMobile); + glw.videoToTexture(this.mycanvas, this.mytex, this.runtime.isMobile); + } + this.lastwidth = scaledwidth; + this.lastheight = scaledheight; + glw.setTexture(this.mytex); + glw.setOpacity(this.opacity); + glw.resetModelView(); + glw.translate(-halfw, -halfh); + glw.updateModelView(); + var q = this.bquad; + var tlx = this.layer.layerToCanvas(q.tlx, q.tly, true, true); + var tly = this.layer.layerToCanvas(q.tlx, q.tly, false, true); + var trx = this.layer.layerToCanvas(q.trx, q.try_, true, true); + var try_ = this.layer.layerToCanvas(q.trx, q.try_, false, true); + var brx = this.layer.layerToCanvas(q.brx, q.bry, true, true); + var bry = this.layer.layerToCanvas(q.brx, q.bry, false, true); + var blx = this.layer.layerToCanvas(q.blx, q.bly, true, true); + var bly = this.layer.layerToCanvas(q.blx, q.bly, false, true); + if (this.runtime.pixel_rounding || (this.angle === 0 && layer_angle === 0)) + { + var ox = ((tlx + 0.5) | 0) - tlx; + var oy = ((tly + 0.5) | 0) - tly + tlx += ox; + tly += oy; + trx += ox; + try_ += oy; + brx += ox; + bry += oy; + blx += ox; + bly += oy; + } + if (this.angle === 0 && layer_angle === 0) + { + trx = tlx + scaledwidth; + try_ = tly; + brx = trx; + bry = tly + scaledheight; + blx = tlx; + bly = bry; + rcTex.right = 1; + rcTex.bottom = 1; + } + else + { + rcTex.right = floatscaledwidth / scaledwidth; + rcTex.bottom = floatscaledheight / scaledheight; + } + glw.quadTex(tlx, tly, trx, try_, brx, bry, blx, bly, rcTex); + glw.resetModelView(); + glw.scale(layer_scale, layer_scale); + glw.rotateZ(-this.layer.getAngle()); + glw.translate((this.layer.viewLeft + this.layer.viewRight) / -2, (this.layer.viewTop + this.layer.viewBottom) / -2); + glw.updateModelView(); + this.last_render_tick = this.runtime.tickcount; + }; + var wordsCache = []; + pluginProto.TokeniseWords = function (text) + { + wordsCache.length = 0; + var cur_word = ""; + var ch; + var i = 0; + while (i < text.length) + { + ch = text.charAt(i); + if (ch === "\n") + { + if (cur_word.length) + { + wordsCache.push(cur_word); + cur_word = ""; + } + wordsCache.push("\n"); + ++i; + } + else if (ch === " " || ch === "\t" || ch === "-") + { + do { + cur_word += text.charAt(i); + i++; + } + while (i < text.length && (text.charAt(i) === " " || text.charAt(i) === "\t")); + wordsCache.push(cur_word); + cur_word = ""; + } + else if (i < text.length) + { + cur_word += ch; + i++; + } + } + if (cur_word.length) + wordsCache.push(cur_word); + }; + var linesCache = []; + function allocLine() + { + if (linesCache.length) + return linesCache.pop(); + else + return {}; + }; + function freeLine(l) + { + linesCache.push(l); + }; + function freeAllLines(arr) + { + var i, len; + for (i = 0, len = arr.length; i < len; i++) + { + freeLine(arr[i]); + } + arr.length = 0; + }; + pluginProto.WordWrap = function (text, lines, ctx, width, wrapbyword) + { + if (!text || !text.length) + { + freeAllLines(lines); + return; + } + if (width <= 2.0) + { + freeAllLines(lines); + return; + } + if (text.length <= 100 && text.indexOf("\n") === -1) + { + var all_width = ctx.measureText(text).width; + if (all_width <= width) + { + freeAllLines(lines); + lines.push(allocLine()); + lines[0].text = text; + lines[0].width = all_width; + return; + } + } + this.WrapText(text, lines, ctx, width, wrapbyword); + }; + pluginProto.WrapText = function (text, lines, ctx, width, wrapbyword) + { + var wordArray; + if (wrapbyword) + { + this.TokeniseWords(text); // writes to wordsCache + wordArray = wordsCache; + } + else + wordArray = text; + var cur_line = ""; + var prev_line; + var line_width; + var i; + var lineIndex = 0; + var line; + for (i = 0; i < wordArray.length; i++) + { + if (wordArray[i] === "\n") + { + if (lineIndex >= lines.length) + lines.push(allocLine()); + line = lines[lineIndex]; + line.text = cur_line; + line.width = ctx.measureText(cur_line).width; + lineIndex++; + cur_line = ""; + continue; + } + prev_line = cur_line; + cur_line += wordArray[i]; + line_width = ctx.measureText(cur_line).width; + if (line_width >= width) + { + if (lineIndex >= lines.length) + lines.push(allocLine()); + line = lines[lineIndex]; + line.text = prev_line; + line.width = ctx.measureText(prev_line).width; + lineIndex++; + cur_line = wordArray[i]; + if (!wrapbyword && cur_line === " ") + cur_line = ""; + } + } + if (cur_line.length) + { + if (lineIndex >= lines.length) + lines.push(allocLine()); + line = lines[lineIndex]; + line.text = cur_line; + line.width = ctx.measureText(cur_line).width; + lineIndex++; + } + for (i = lineIndex; i < lines.length; i++) + freeLine(lines[i]); + lines.length = lineIndex; + }; + function Cnds() {}; + Cnds.prototype.CompareText = function(text_to_compare, case_sensitive) + { + if (case_sensitive) + return this.text == text_to_compare; + else + return cr.equals_nocase(this.text, text_to_compare); + }; + pluginProto.cnds = new Cnds(); + function Acts() {}; + Acts.prototype.SetText = function(param) + { + if (cr.is_number(param) && param < 1e9) + param = Math.round(param * 1e10) / 1e10; // round to nearest ten billionth - hides floating point errors + var text_to_set = param.toString(); + if (this.text !== text_to_set) + { + this.text = text_to_set; + this.text_changed = true; + this.runtime.redraw = true; + } + }; + Acts.prototype.AppendText = function(param) + { + if (cr.is_number(param)) + param = Math.round(param * 1e10) / 1e10; // round to nearest ten billionth - hides floating point errors + var text_to_append = param.toString(); + if (text_to_append) // not empty + { + this.text += text_to_append; + this.text_changed = true; + this.runtime.redraw = true; + } + }; + Acts.prototype.SetFontFace = function (face_, style_) + { + var newstyle = ""; + switch (style_) { + case 1: newstyle = "bold"; break; + case 2: newstyle = "italic"; break; + case 3: newstyle = "bold italic"; break; + } + if (face_ === this.facename && newstyle === this.fontstyle) + return; // no change + this.facename = face_; + this.fontstyle = newstyle; + this.updateFont(); + }; + Acts.prototype.SetFontSize = function (size_) + { + if (this.ptSize === size_) + return; + this.ptSize = size_; + this.pxHeight = Math.ceil((this.ptSize / 72.0) * 96.0) + 4; // assume 96dpi... + this.updateFont(); + }; + Acts.prototype.SetFontColor = function (rgb) + { + var newcolor = "rgb(" + cr.GetRValue(rgb).toString() + "," + cr.GetGValue(rgb).toString() + "," + cr.GetBValue(rgb).toString() + ")"; + if (newcolor === this.color) + return; + this.color = newcolor; + this.need_text_redraw = true; + this.runtime.redraw = true; + }; + Acts.prototype.SetWebFont = function (familyname_, cssurl_) + { + if (this.runtime.isDomFree) + { + cr.logexport("[Construct 2] Text plugin: 'Set web font' not supported on this platform - the action has been ignored"); + return; // DC todo + } + var self = this; + var refreshFunc = (function () { + self.runtime.redraw = true; + self.text_changed = true; + }); + if (requestedWebFonts.hasOwnProperty(cssurl_)) + { + var newfacename = "'" + familyname_ + "'"; + if (this.facename === newfacename) + return; // no change + this.facename = newfacename; + this.updateFont(); + for (var i = 1; i < 10; i++) + { + setTimeout(refreshFunc, i * 100); + setTimeout(refreshFunc, i * 1000); + } + return; + } + var wf = document.createElement("link"); + wf.href = cssurl_; + wf.rel = "stylesheet"; + wf.type = "text/css"; + wf.onload = refreshFunc; + document.getElementsByTagName('head')[0].appendChild(wf); + requestedWebFonts[cssurl_] = true; + this.facename = "'" + familyname_ + "'"; + this.updateFont(); + for (var i = 1; i < 10; i++) + { + setTimeout(refreshFunc, i * 100); + setTimeout(refreshFunc, i * 1000); + } +; + }; + Acts.prototype.SetEffect = function (effect) + { + this.compositeOp = cr.effectToCompositeOp(effect); + cr.setGLBlend(this, effect, this.runtime.gl); + this.runtime.redraw = true; + }; + pluginProto.acts = new Acts(); + function Exps() {}; + Exps.prototype.Text = function(ret) + { + ret.set_string(this.text); + }; + Exps.prototype.FaceName = function (ret) + { + ret.set_string(this.facename); + }; + Exps.prototype.FaceSize = function (ret) + { + ret.set_int(this.ptSize); + }; + Exps.prototype.TextWidth = function (ret) + { + var w = 0; + var i, len, x; + for (i = 0, len = this.lines.length; i < len; i++) + { + x = this.lines[i].width; + if (w < x) + w = x; + } + ret.set_int(w); + }; + Exps.prototype.TextHeight = function (ret) + { + ret.set_int(this.lines.length * (this.pxHeight + this.line_height_offset) - this.line_height_offset); + }; + pluginProto.exps = new Exps(); +}()); +; +; +cr.behaviors.Anchor = function(runtime) +{ + this.runtime = runtime; +}; +(function () +{ + var behaviorProto = cr.behaviors.Anchor.prototype; + behaviorProto.Type = function(behavior, objtype) + { + this.behavior = behavior; + this.objtype = objtype; + this.runtime = behavior.runtime; + }; + var behtypeProto = behaviorProto.Type.prototype; + behtypeProto.onCreate = function() + { + }; + behaviorProto.Instance = function(type, inst) + { + this.type = type; + this.behavior = type.behavior; + this.inst = inst; // associated object instance to modify + this.runtime = type.runtime; + }; + var behinstProto = behaviorProto.Instance.prototype; + behinstProto.onCreate = function() + { + this.anch_left = this.properties[0]; // 0 = left, 1 = right, 2 = none + this.anch_top = this.properties[1]; // 0 = top, 1 = bottom, 2 = none + this.anch_right = this.properties[2]; // 0 = none, 1 = right + this.anch_bottom = this.properties[3]; // 0 = none, 1 = bottom + this.inst.update_bbox(); + this.xleft = this.inst.bbox.left; + this.ytop = this.inst.bbox.top; + this.xright = this.runtime.original_width - this.inst.bbox.left; + this.ybottom = this.runtime.original_height - this.inst.bbox.top; + this.rdiff = this.runtime.original_width - this.inst.bbox.right; + this.bdiff = this.runtime.original_height - this.inst.bbox.bottom; + this.enabled = (this.properties[4] !== 0); + }; + behinstProto.saveToJSON = function () + { + return { + "xleft": this.xleft, + "ytop": this.ytop, + "xright": this.xright, + "ybottom": this.ybottom, + "rdiff": this.rdiff, + "bdiff": this.bdiff, + "enabled": this.enabled + }; + }; + behinstProto.loadFromJSON = function (o) + { + this.xleft = o["xleft"]; + this.ytop = o["ytop"]; + this.xright = o["xright"]; + this.ybottom = o["ybottom"]; + this.rdiff = o["rdiff"]; + this.bdiff = o["bdiff"]; + this.enabled = o["enabled"]; + }; + behinstProto.tick = function () + { + if (!this.enabled) + return; + var n; + var layer = this.inst.layer; + var inst = this.inst; + var bbox = this.inst.bbox; + if (this.anch_left === 0) + { + inst.update_bbox(); + n = (layer.viewLeft + this.xleft) - bbox.left; + if (n !== 0) + { + inst.x += n; + inst.set_bbox_changed(); + } + } + else if (this.anch_left === 1) + { + inst.update_bbox(); + n = (layer.viewRight - this.xright) - bbox.left; + if (n !== 0) + { + inst.x += n; + inst.set_bbox_changed(); + } + } + if (this.anch_top === 0) + { + inst.update_bbox(); + n = (layer.viewTop + this.ytop) - bbox.top; + if (n !== 0) + { + inst.y += n; + inst.set_bbox_changed(); + } + } + else if (this.anch_top === 1) + { + inst.update_bbox(); + n = (layer.viewBottom - this.ybottom) - bbox.top; + if (n !== 0) + { + inst.y += n; + inst.set_bbox_changed(); + } + } + if (this.anch_right === 1) + { + inst.update_bbox(); + n = (layer.viewRight - this.rdiff) - bbox.right; + if (n !== 0) + { + inst.width += n; + if (inst.width < 0) + inst.width = 0; + inst.set_bbox_changed(); + } + } + if (this.anch_bottom === 1) + { + inst.update_bbox(); + n = (layer.viewBottom - this.bdiff) - bbox.bottom; + if (n !== 0) + { + inst.height += n; + if (inst.height < 0) + inst.height = 0; + inst.set_bbox_changed(); + } + } + }; + function Cnds() {}; + behaviorProto.cnds = new Cnds(); + function Acts() {}; + Acts.prototype.SetEnabled = function (e) + { + if (this.enabled && e === 0) + this.enabled = false; + else if (!this.enabled && e !== 0) + { + this.inst.update_bbox(); + this.xleft = this.inst.bbox.left; + this.ytop = this.inst.bbox.top; + this.xright = this.runtime.original_width - this.inst.bbox.left; + this.ybottom = this.runtime.original_height - this.inst.bbox.top; + this.rdiff = this.runtime.original_width - this.inst.bbox.right; + this.bdiff = this.runtime.original_height - this.inst.bbox.bottom; + this.enabled = true; + } + }; + behaviorProto.acts = new Acts(); + function Exps() {}; + behaviorProto.exps = new Exps(); +}()); +; +; +cr.behaviors.Flash = function(runtime) +{ + this.runtime = runtime; +}; +(function () +{ + var behaviorProto = cr.behaviors.Flash.prototype; + behaviorProto.Type = function(behavior, objtype) + { + this.behavior = behavior; + this.objtype = objtype; + this.runtime = behavior.runtime; + }; + var behtypeProto = behaviorProto.Type.prototype; + behtypeProto.onCreate = function() + { + }; + behaviorProto.Instance = function(type, inst) + { + this.type = type; + this.behavior = type.behavior; + this.inst = inst; // associated object instance to modify + this.runtime = type.runtime; + }; + var behinstProto = behaviorProto.Instance.prototype; + behinstProto.onCreate = function() + { + this.ontime = 0; + this.offtime = 0; + this.stage = 0; // 0 = on, 1 = off + this.stagetimeleft = 0; + this.timeleft = 0; + }; + behinstProto.saveToJSON = function () + { + return { + "ontime": this.ontime, + "offtime": this.offtime, + "stage": this.stage, + "stagetimeleft": this.stagetimeleft, + "timeleft": this.timeleft + }; + }; + behinstProto.loadFromJSON = function (o) + { + this.ontime = o["ontime"]; + this.offtime = o["offtime"]; + this.stage = o["stage"]; + this.stagetimeleft = o["stagetimeleft"]; + this.timeleft = o["timeleft"]; + }; + behinstProto.tick = function () + { + if (this.timeleft <= 0) + return; // not flashing + var dt = this.runtime.getDt(this.inst); + this.timeleft -= dt; + if (this.timeleft <= 0) + { + this.timeleft = 0; + this.inst.visible = true; + this.runtime.redraw = true; + this.runtime.trigger(cr.behaviors.Flash.prototype.cnds.OnFlashEnded, this.inst); + return; + } + this.stagetimeleft -= dt; + if (this.stagetimeleft <= 0) + { + if (this.stage === 0) + { + this.inst.visible = false; + this.stage = 1; + this.stagetimeleft += this.offtime; + } + else + { + this.inst.visible = true; + this.stage = 0; + this.stagetimeleft += this.ontime; + } + this.runtime.redraw = true; + } + }; + function Cnds() {}; + Cnds.prototype.IsFlashing = function () + { + return this.timeleft > 0; + }; + Cnds.prototype.OnFlashEnded = function () + { + return true; + }; + behaviorProto.cnds = new Cnds(); + function Acts() {}; + Acts.prototype.Flash = function (on_, off_, dur_) + { + this.ontime = on_; + this.offtime = off_; + this.stage = 1; // always start off + this.stagetimeleft = off_; + this.timeleft = dur_; + this.inst.visible = false; + this.runtime.redraw = true; + }; + Acts.prototype.StopFlashing = function () + { + this.timeleft = 0; + this.inst.visible = true; + this.runtime.redraw = true; + return; + }; + behaviorProto.acts = new Acts(); + function Exps() {}; + behaviorProto.exps = new Exps(); +}()); +; +; +cr.behaviors.Pin = function(runtime) +{ + this.runtime = runtime; +}; +(function () +{ + var behaviorProto = cr.behaviors.Pin.prototype; + behaviorProto.Type = function(behavior, objtype) + { + this.behavior = behavior; + this.objtype = objtype; + this.runtime = behavior.runtime; + }; + var behtypeProto = behaviorProto.Type.prototype; + behtypeProto.onCreate = function() + { + }; + behaviorProto.Instance = function(type, inst) + { + this.type = type; + this.behavior = type.behavior; + this.inst = inst; // associated object instance to modify + this.runtime = type.runtime; + }; + var behinstProto = behaviorProto.Instance.prototype; + behinstProto.onCreate = function() + { + this.pinObject = null; + this.pinObjectUid = -1; // for loading + this.pinAngle = 0; + this.pinDist = 0; + this.myStartAngle = 0; + this.theirStartAngle = 0; + this.lastKnownAngle = 0; + this.mode = 0; // 0 = position & angle; 1 = position; 2 = angle; 3 = rope; 4 = bar + var self = this; + if (!this.recycled) + { + this.myDestroyCallback = (function(inst) { + self.onInstanceDestroyed(inst); + }); + } + this.runtime.addDestroyCallback(this.myDestroyCallback); + }; + behinstProto.saveToJSON = function () + { + return { + "uid": this.pinObject ? this.pinObject.uid : -1, + "pa": this.pinAngle, + "pd": this.pinDist, + "msa": this.myStartAngle, + "tsa": this.theirStartAngle, + "lka": this.lastKnownAngle, + "m": this.mode + }; + }; + behinstProto.loadFromJSON = function (o) + { + this.pinObjectUid = o["uid"]; // wait until afterLoad to look up + this.pinAngle = o["pa"]; + this.pinDist = o["pd"]; + this.myStartAngle = o["msa"]; + this.theirStartAngle = o["tsa"]; + this.lastKnownAngle = o["lka"]; + this.mode = o["m"]; + }; + behinstProto.afterLoad = function () + { + if (this.pinObjectUid === -1) + this.pinObject = null; + else + { + this.pinObject = this.runtime.getObjectByUID(this.pinObjectUid); +; + } + this.pinObjectUid = -1; + }; + behinstProto.onInstanceDestroyed = function (inst) + { + if (this.pinObject == inst) + this.pinObject = null; + }; + behinstProto.onDestroy = function() + { + this.pinObject = null; + this.runtime.removeDestroyCallback(this.myDestroyCallback); + }; + behinstProto.tick = function () + { + }; + behinstProto.tick2 = function () + { + if (!this.pinObject) + return; + if (this.lastKnownAngle !== this.inst.angle) + this.myStartAngle = cr.clamp_angle(this.myStartAngle + (this.inst.angle - this.lastKnownAngle)); + var newx = this.inst.x; + var newy = this.inst.y; + if (this.mode === 3 || this.mode === 4) // rope mode or bar mode + { + var dist = cr.distanceTo(this.inst.x, this.inst.y, this.pinObject.x, this.pinObject.y); + if ((dist > this.pinDist) || (this.mode === 4 && dist < this.pinDist)) + { + var a = cr.angleTo(this.pinObject.x, this.pinObject.y, this.inst.x, this.inst.y); + newx = this.pinObject.x + Math.cos(a) * this.pinDist; + newy = this.pinObject.y + Math.sin(a) * this.pinDist; + } + } + else + { + newx = this.pinObject.x + Math.cos(this.pinObject.angle + this.pinAngle) * this.pinDist; + newy = this.pinObject.y + Math.sin(this.pinObject.angle + this.pinAngle) * this.pinDist; + } + var newangle = cr.clamp_angle(this.myStartAngle + (this.pinObject.angle - this.theirStartAngle)); + this.lastKnownAngle = newangle; + if ((this.mode === 0 || this.mode === 1 || this.mode === 3 || this.mode === 4) + && (this.inst.x !== newx || this.inst.y !== newy)) + { + this.inst.x = newx; + this.inst.y = newy; + this.inst.set_bbox_changed(); + } + if ((this.mode === 0 || this.mode === 2) && (this.inst.angle !== newangle)) + { + this.inst.angle = newangle; + this.inst.set_bbox_changed(); + } + }; + function Cnds() {}; + Cnds.prototype.IsPinned = function () + { + return !!this.pinObject; + }; + behaviorProto.cnds = new Cnds(); + function Acts() {}; + Acts.prototype.Pin = function (obj, mode_) + { + if (!obj) + return; + var otherinst = obj.getFirstPicked(this.inst); + if (!otherinst) + return; + this.pinObject = otherinst; + this.pinAngle = cr.angleTo(otherinst.x, otherinst.y, this.inst.x, this.inst.y) - otherinst.angle; + this.pinDist = cr.distanceTo(otherinst.x, otherinst.y, this.inst.x, this.inst.y); + this.myStartAngle = this.inst.angle; + this.lastKnownAngle = this.inst.angle; + this.theirStartAngle = otherinst.angle; + this.mode = mode_; + }; + Acts.prototype.Unpin = function () + { + this.pinObject = null; + }; + behaviorProto.acts = new Acts(); + function Exps() {}; + Exps.prototype.PinnedUID = function (ret) + { + ret.set_int(this.pinObject ? this.pinObject.uid : -1); + }; + behaviorProto.exps = new Exps(); +}()); +; +; +cr.behaviors.Platform = function(runtime) +{ + this.runtime = runtime; +}; +(function () +{ + var behaviorProto = cr.behaviors.Platform.prototype; + behaviorProto.Type = function(behavior, objtype) + { + this.behavior = behavior; + this.objtype = objtype; + this.runtime = behavior.runtime; + }; + var behtypeProto = behaviorProto.Type.prototype; + behtypeProto.onCreate = function() + { + }; + var ANIMMODE_STOPPED = 0; + var ANIMMODE_MOVING = 1; + var ANIMMODE_JUMPING = 2; + var ANIMMODE_FALLING = 3; + behaviorProto.Instance = function(type, inst) + { + this.type = type; + this.behavior = type.behavior; + this.inst = inst; // associated object instance to modify + this.runtime = type.runtime; + this.leftkey = false; + this.rightkey = false; + this.jumpkey = false; + this.jumped = false; // prevent bunnyhopping + this.doubleJumped = false; + this.canDoubleJump = false; + this.ignoreInput = false; + this.simleft = false; + this.simright = false; + this.simjump = false; + this.lastFloorObject = null; + this.loadFloorObject = -1; + this.lastFloorX = 0; + this.lastFloorY = 0; + this.floorIsJumpthru = false; + this.animMode = ANIMMODE_STOPPED; + this.fallthrough = 0; // fall through jump-thru. >0 to disable, lasts a few ticks + this.firstTick = true; + this.dx = 0; + this.dy = 0; + }; + var behinstProto = behaviorProto.Instance.prototype; + behinstProto.updateGravity = function() + { + this.downx = Math.cos(this.ga); + this.downy = Math.sin(this.ga); + this.rightx = Math.cos(this.ga - Math.PI / 2); + this.righty = Math.sin(this.ga - Math.PI / 2); + this.downx = cr.round6dp(this.downx); + this.downy = cr.round6dp(this.downy); + this.rightx = cr.round6dp(this.rightx); + this.righty = cr.round6dp(this.righty); + this.g1 = this.g; + if (this.g < 0) + { + this.downx *= -1; + this.downy *= -1; + this.g = Math.abs(this.g); + } + }; + behinstProto.onCreate = function() + { + this.maxspeed = this.properties[0]; + this.acc = this.properties[1]; + this.dec = this.properties[2]; + this.jumpStrength = this.properties[3]; + this.g = this.properties[4]; + this.g1 = this.g; + this.maxFall = this.properties[5]; + this.enableDoubleJump = (this.properties[6] !== 0); // 0=disabled, 1=enabled + this.jumpSustain = (this.properties[7] / 1000); // convert ms to s + this.defaultControls = (this.properties[8] === 1); // 0=no, 1=yes + this.enabled = (this.properties[9] !== 0); + this.wasOnFloor = false; + this.wasOverJumpthru = this.runtime.testOverlapJumpThru(this.inst); + this.loadOverJumpthru = -1; + this.sustainTime = 0; // time of jump sustain remaining + this.ga = cr.to_radians(90); + this.updateGravity(); + var self = this; + if (this.defaultControls && !this.runtime.isDomFree) + { + jQuery(document).keydown(function(info) { + self.onKeyDown(info); + }); + jQuery(document).keyup(function(info) { + self.onKeyUp(info); + }); + } + if (!this.recycled) + { + this.myDestroyCallback = function(inst) { + self.onInstanceDestroyed(inst); + }; + } + this.runtime.addDestroyCallback(this.myDestroyCallback); + this.inst.extra["isPlatformBehavior"] = true; + }; + behinstProto.saveToJSON = function () + { + return { + "ii": this.ignoreInput, + "lfx": this.lastFloorX, + "lfy": this.lastFloorY, + "lfo": (this.lastFloorObject ? this.lastFloorObject.uid : -1), + "am": this.animMode, + "en": this.enabled, + "fall": this.fallthrough, + "ft": this.firstTick, + "dx": this.dx, + "dy": this.dy, + "ms": this.maxspeed, + "acc": this.acc, + "dec": this.dec, + "js": this.jumpStrength, + "g": this.g, + "g1": this.g1, + "mf": this.maxFall, + "wof": this.wasOnFloor, + "woj": (this.wasOverJumpthru ? this.wasOverJumpthru.uid : -1), + "ga": this.ga, + "edj": this.enableDoubleJump, + "cdj": this.canDoubleJump, + "dj": this.doubleJumped, + "sus": this.jumpSustain + }; + }; + behinstProto.loadFromJSON = function (o) + { + this.ignoreInput = o["ii"]; + this.lastFloorX = o["lfx"]; + this.lastFloorY = o["lfy"]; + this.loadFloorObject = o["lfo"]; + this.animMode = o["am"]; + this.enabled = o["en"]; + this.fallthrough = o["fall"]; + this.firstTick = o["ft"]; + this.dx = o["dx"]; + this.dy = o["dy"]; + this.maxspeed = o["ms"]; + this.acc = o["acc"]; + this.dec = o["dec"]; + this.jumpStrength = o["js"]; + this.g = o["g"]; + this.g1 = o["g1"]; + this.maxFall = o["mf"]; + this.wasOnFloor = o["wof"]; + this.loadOverJumpthru = o["woj"]; + this.ga = o["ga"]; + this.enableDoubleJump = o["edj"]; + this.canDoubleJump = o["cdj"]; + this.doubleJumped = o["dj"]; + this.jumpSustain = o["sus"]; + this.leftkey = false; + this.rightkey = false; + this.jumpkey = false; + this.jumped = false; + this.simleft = false; + this.simright = false; + this.simjump = false; + this.sustainTime = 0; + this.updateGravity(); + }; + behinstProto.afterLoad = function () + { + if (this.loadFloorObject === -1) + this.lastFloorObject = null; + else + this.lastFloorObject = this.runtime.getObjectByUID(this.loadFloorObject); + if (this.loadOverJumpthru === -1) + this.wasOverJumpthru = null; + else + this.wasOverJumpthru = this.runtime.getObjectByUID(this.loadOverJumpthru); + }; + behinstProto.onInstanceDestroyed = function (inst) + { + if (this.lastFloorObject == inst) + this.lastFloorObject = null; + }; + behinstProto.onDestroy = function () + { + this.lastFloorObject = null; + this.runtime.removeDestroyCallback(this.myDestroyCallback); + }; + behinstProto.onKeyDown = function (info) + { + switch (info.which) { + case 38: // up + info.preventDefault(); + this.jumpkey = true; + break; + case 37: // left + info.preventDefault(); + this.leftkey = true; + break; + case 39: // right + info.preventDefault(); + this.rightkey = true; + break; + } + }; + behinstProto.onKeyUp = function (info) + { + switch (info.which) { + case 38: // up + info.preventDefault(); + this.jumpkey = false; + this.jumped = false; + break; + case 37: // left + info.preventDefault(); + this.leftkey = false; + break; + case 39: // right + info.preventDefault(); + this.rightkey = false; + break; + } + }; + behinstProto.getGDir = function () + { + if (this.g < 0) + return -1; + else + return 1; + }; + behinstProto.isOnFloor = function () + { + var ret = null; + var ret2 = null; + var i, len, j; + var oldx = this.inst.x; + var oldy = this.inst.y; + this.inst.x += this.downx; + this.inst.y += this.downy; + this.inst.set_bbox_changed(); + if (this.lastFloorObject && this.runtime.testOverlap(this.inst, this.lastFloorObject)) + { + this.inst.x = oldx; + this.inst.y = oldy; + this.inst.set_bbox_changed(); + return this.lastFloorObject; + } + else + { + ret = this.runtime.testOverlapSolid(this.inst); + if (!ret && this.fallthrough === 0) + ret2 = this.runtime.testOverlapJumpThru(this.inst, true); + this.inst.x = oldx; + this.inst.y = oldy; + this.inst.set_bbox_changed(); + if (ret) // was overlapping solid + { + if (this.runtime.testOverlap(this.inst, ret)) + return null; + else + { + this.floorIsJumpthru = false; + return ret; + } + } + if (ret2 && ret2.length) + { + for (i = 0, j = 0, len = ret2.length; i < len; i++) + { + ret2[j] = ret2[i]; + if (!this.runtime.testOverlap(this.inst, ret2[i])) + j++; + } + if (j >= 1) + { + this.floorIsJumpthru = true; + return ret2[0]; + } + } + return null; + } + }; + behinstProto.tick = function () + { + }; + behinstProto.posttick = function () + { + var dt = this.runtime.getDt(this.inst); + var mx, my, obstacle, mag, allover, i, len, j, oldx, oldy; + if (!this.jumpkey && !this.simjump) + this.jumped = false; + var left = this.leftkey || this.simleft; + var right = this.rightkey || this.simright; + var jumpkey = (this.jumpkey || this.simjump); + var jump = jumpkey && !this.jumped; + this.simleft = false; + this.simright = false; + this.simjump = false; + if (!this.enabled) + return; + if (this.ignoreInput) + { + left = false; + right = false; + jumpkey = false; + jump = false; + } + if (!jumpkey) + this.sustainTime = 0; + var lastFloor = this.lastFloorObject; + var floor_moved = false; + if (this.firstTick) + { + if (this.runtime.testOverlapSolid(this.inst) || this.runtime.testOverlapJumpThru(this.inst)) + { + this.runtime.pushOutSolid(this.inst, -this.downx, -this.downy, 4, true); + } + this.firstTick = false; + } + if (lastFloor && this.dy === 0 && (lastFloor.y !== this.lastFloorY || lastFloor.x !== this.lastFloorX)) + { + mx = (lastFloor.x - this.lastFloorX); + my = (lastFloor.y - this.lastFloorY); + this.inst.x += mx; + this.inst.y += my; + this.inst.set_bbox_changed(); + this.lastFloorX = lastFloor.x; + this.lastFloorY = lastFloor.y; + floor_moved = true; + if (this.runtime.testOverlapSolid(this.inst)) + { + this.runtime.pushOutSolid(this.inst, -mx, -my, Math.sqrt(mx * mx + my * my) * 2.5); + } + } + var floor_ = this.isOnFloor(); + var collobj = this.runtime.testOverlapSolid(this.inst); + if (collobj) + { + if (this.inst.extra["inputPredicted"]) + { + this.runtime.pushOutSolid(this.inst, -this.downx, -this.downy, 10, false); + } + else if (this.runtime.pushOutSolidNearest(this.inst, Math.max(this.inst.width, this.inst.height) / 2)) + { + this.runtime.registerCollision(this.inst, collobj); + } + else + return; + } + if (floor_) + { + this.doubleJumped = false; // reset double jump flags for next jump + this.canDoubleJump = false; + if (this.dy > 0) + { + if (!this.wasOnFloor) + { + this.runtime.pushInFractional(this.inst, -this.downx, -this.downy, floor_, 16); + this.wasOnFloor = true; + } + this.dy = 0; + } + if (lastFloor != floor_) + { + this.lastFloorObject = floor_; + this.lastFloorX = floor_.x; + this.lastFloorY = floor_.y; + this.runtime.registerCollision(this.inst, floor_); + } + else if (floor_moved) + { + collobj = this.runtime.testOverlapSolid(this.inst); + if (collobj) + { + this.runtime.registerCollision(this.inst, collobj); + if (mx !== 0) + { + if (mx > 0) + this.runtime.pushOutSolid(this.inst, -this.rightx, -this.righty); + else + this.runtime.pushOutSolid(this.inst, this.rightx, this.righty); + } + this.runtime.pushOutSolid(this.inst, -this.downx, -this.downy); + } + } + } + else + { + if (!jumpkey) + this.canDoubleJump = true; + } + if ((floor_ && jump) || (!floor_ && this.enableDoubleJump && jumpkey && this.canDoubleJump && !this.doubleJumped)) + { + oldx = this.inst.x; + oldy = this.inst.y; + this.inst.x -= this.downx; + this.inst.y -= this.downy; + this.inst.set_bbox_changed(); + if (!this.runtime.testOverlapSolid(this.inst)) + { + this.sustainTime = this.jumpSustain; + this.runtime.trigger(cr.behaviors.Platform.prototype.cnds.OnJump, this.inst); + this.animMode = ANIMMODE_JUMPING; + this.dy = -this.jumpStrength; + jump = true; // set in case is double jump + if (floor_) + this.jumped = true; + else + this.doubleJumped = true; + } + else + jump = false; + this.inst.x = oldx; + this.inst.y = oldy; + this.inst.set_bbox_changed(); + } + if (!floor_) + { + if (jumpkey && this.sustainTime > 0) + { + this.dy = -this.jumpStrength; + this.sustainTime -= dt; + } + else + { + this.lastFloorObject = null; + this.dy += this.g * dt; + if (this.dy > this.maxFall) + this.dy = this.maxFall; + } + if (jump) + this.jumped = true; + } + this.wasOnFloor = !!floor_; + if (left == right) // both up or both down + { + if (this.dx < 0) + { + this.dx += this.dec * dt; + if (this.dx > 0) + this.dx = 0; + } + else if (this.dx > 0) + { + this.dx -= this.dec * dt; + if (this.dx < 0) + this.dx = 0; + } + } + if (left && !right) + { + if (this.dx > 0) + this.dx -= (this.acc + this.dec) * dt; + else + this.dx -= this.acc * dt; + } + if (right && !left) + { + if (this.dx < 0) + this.dx += (this.acc + this.dec) * dt; + else + this.dx += this.acc * dt; + } + if (this.dx > this.maxspeed) + this.dx = this.maxspeed; + else if (this.dx < -this.maxspeed) + this.dx = -this.maxspeed; + var landed = false; + if (this.dx !== 0) + { + oldx = this.inst.x; + oldy = this.inst.y; + mx = this.dx * dt * this.rightx; + my = this.dx * dt * this.righty; + this.inst.x += this.rightx * (this.dx > 1 ? 1 : -1) - this.downx; + this.inst.y += this.righty * (this.dx > 1 ? 1 : -1) - this.downy; + this.inst.set_bbox_changed(); + var is_jumpthru = false; + var slope_too_steep = this.runtime.testOverlapSolid(this.inst); + /* + if (!slope_too_steep && floor_) + { + slope_too_steep = this.runtime.testOverlapJumpThru(this.inst); + is_jumpthru = true; + if (slope_too_steep) + { + this.inst.x = oldx; + this.inst.y = oldy; + this.inst.set_bbox_changed(); + if (this.runtime.testOverlap(this.inst, slope_too_steep)) + { + slope_too_steep = null; + is_jumpthru = false; + } + } + } + */ + this.inst.x = oldx + mx; + this.inst.y = oldy + my; + this.inst.set_bbox_changed(); + obstacle = this.runtime.testOverlapSolid(this.inst); + if (!obstacle && floor_) + { + obstacle = this.runtime.testOverlapJumpThru(this.inst); + if (obstacle) + { + this.inst.x = oldx; + this.inst.y = oldy; + this.inst.set_bbox_changed(); + if (this.runtime.testOverlap(this.inst, obstacle)) + { + obstacle = null; + is_jumpthru = false; + } + else + is_jumpthru = true; + this.inst.x = oldx + mx; + this.inst.y = oldy + my; + this.inst.set_bbox_changed(); + } + } + if (obstacle) + { + var push_dist = Math.abs(this.dx * dt) + 2; + if (slope_too_steep || !this.runtime.pushOutSolid(this.inst, -this.downx, -this.downy, push_dist, is_jumpthru, obstacle)) + { + this.runtime.registerCollision(this.inst, obstacle); + push_dist = Math.max(Math.abs(this.dx * dt * 2.5), 30); + if (!this.runtime.pushOutSolid(this.inst, this.rightx * (this.dx < 0 ? 1 : -1), this.righty * (this.dx < 0 ? 1 : -1), push_dist, false)) + { + this.inst.x = oldx; + this.inst.y = oldy; + this.inst.set_bbox_changed(); + } + else if (floor_ && !is_jumpthru && !this.floorIsJumpthru) + { + oldx = this.inst.x; + oldy = this.inst.y; + this.inst.x += this.downx; + this.inst.y += this.downy; + if (this.runtime.testOverlapSolid(this.inst)) + { + if (!this.runtime.pushOutSolid(this.inst, -this.downx, -this.downy, 3, false)) + { + this.inst.x = oldx; + this.inst.y = oldy; + this.inst.set_bbox_changed(); + } + } + else + { + this.inst.x = oldx; + this.inst.y = oldy; + this.inst.set_bbox_changed(); + } + } + if (!is_jumpthru) + this.dx = 0; // stop + } + else if (!slope_too_steep && !jump && (Math.abs(this.dy) < Math.abs(this.jumpStrength / 4))) + { + this.dy = 0; + if (!floor_) + landed = true; + } + } + else + { + var newfloor = this.isOnFloor(); + if (floor_ && !newfloor) + { + mag = Math.ceil(Math.abs(this.dx * dt)) + 2; + oldx = this.inst.x; + oldy = this.inst.y; + this.inst.x += this.downx * mag; + this.inst.y += this.downy * mag; + this.inst.set_bbox_changed(); + if (this.runtime.testOverlapSolid(this.inst) || this.runtime.testOverlapJumpThru(this.inst)) + this.runtime.pushOutSolid(this.inst, -this.downx, -this.downy, mag + 2, true); + else + { + this.inst.x = oldx; + this.inst.y = oldy; + this.inst.set_bbox_changed(); + } + } + else if (newfloor && this.dy === 0) + { + this.runtime.pushInFractional(this.inst, -this.downx, -this.downy, newfloor, 16); + } + } + } + if (this.dy !== 0) + { + oldx = this.inst.x; + oldy = this.inst.y; + this.inst.x += this.dy * dt * this.downx; + this.inst.y += this.dy * dt * this.downy; + var newx = this.inst.x; + var newy = this.inst.y; + this.inst.set_bbox_changed(); + collobj = this.runtime.testOverlapSolid(this.inst); + var fell_on_jumpthru = false; + if (!collobj && (this.dy > 0) && !floor_) + { + allover = this.fallthrough > 0 ? null : this.runtime.testOverlapJumpThru(this.inst, true); + if (allover && allover.length) + { + if (this.wasOverJumpthru) + { + this.inst.x = oldx; + this.inst.y = oldy; + this.inst.set_bbox_changed(); + for (i = 0, j = 0, len = allover.length; i < len; i++) + { + allover[j] = allover[i]; + if (!this.runtime.testOverlap(this.inst, allover[i])) + j++; + } + allover.length = j; + this.inst.x = newx; + this.inst.y = newy; + this.inst.set_bbox_changed(); + } + if (allover.length >= 1) + collobj = allover[0]; + } + fell_on_jumpthru = !!collobj; + } + if (collobj) + { + this.runtime.registerCollision(this.inst, collobj); + this.sustainTime = 0; + var push_dist = (fell_on_jumpthru ? Math.abs(this.dy * dt * 2.5 + 10) : Math.max(Math.abs(this.dy * dt * 2.5 + 10), 30)); + if (!this.runtime.pushOutSolid(this.inst, this.downx * (this.dy < 0 ? 1 : -1), this.downy * (this.dy < 0 ? 1 : -1), push_dist, fell_on_jumpthru, collobj)) + { + this.inst.x = oldx; + this.inst.y = oldy; + this.inst.set_bbox_changed(); + this.wasOnFloor = true; // prevent adjustment for unexpected floor landings + if (!fell_on_jumpthru) + this.dy = 0; // stop + } + else + { + this.lastFloorObject = collobj; + this.lastFloorX = collobj.x; + this.lastFloorY = collobj.y; + this.floorIsJumpthru = fell_on_jumpthru; + if (fell_on_jumpthru) + landed = true; + this.dy = 0; // stop + } + } + } + if (this.animMode !== ANIMMODE_FALLING && this.dy > 0 && !floor_) + { + this.runtime.trigger(cr.behaviors.Platform.prototype.cnds.OnFall, this.inst); + this.animMode = ANIMMODE_FALLING; + } + if (floor_ || landed) + { + if (this.animMode === ANIMMODE_FALLING || landed || (jump && this.dy === 0)) + { + this.runtime.trigger(cr.behaviors.Platform.prototype.cnds.OnLand, this.inst); + if (this.dx === 0 && this.dy === 0) + this.animMode = ANIMMODE_STOPPED; + else + this.animMode = ANIMMODE_MOVING; + } + else + { + if (this.animMode !== ANIMMODE_STOPPED && this.dx === 0 && this.dy === 0) + { + this.runtime.trigger(cr.behaviors.Platform.prototype.cnds.OnStop, this.inst); + this.animMode = ANIMMODE_STOPPED; + } + if (this.animMode !== ANIMMODE_MOVING && (this.dx !== 0 || this.dy !== 0) && !jump) + { + this.runtime.trigger(cr.behaviors.Platform.prototype.cnds.OnMove, this.inst); + this.animMode = ANIMMODE_MOVING; + } + } + } + if (this.fallthrough > 0) + this.fallthrough--; + this.wasOverJumpthru = this.runtime.testOverlapJumpThru(this.inst); + }; + function Cnds() {}; + Cnds.prototype.IsMoving = function () + { + return this.dx !== 0 || this.dy !== 0; + }; + Cnds.prototype.CompareSpeed = function (cmp, s) + { + var speed = Math.sqrt(this.dx * this.dx + this.dy * this.dy); + return cr.do_cmp(speed, cmp, s); + }; + Cnds.prototype.IsOnFloor = function () + { + if (this.dy !== 0) + return false; + var ret = null; + var ret2 = null; + var i, len, j; + var oldx = this.inst.x; + var oldy = this.inst.y; + this.inst.x += this.downx; + this.inst.y += this.downy; + this.inst.set_bbox_changed(); + ret = this.runtime.testOverlapSolid(this.inst); + if (!ret && this.fallthrough === 0) + ret2 = this.runtime.testOverlapJumpThru(this.inst, true); + this.inst.x = oldx; + this.inst.y = oldy; + this.inst.set_bbox_changed(); + if (ret) // was overlapping solid + { + return !this.runtime.testOverlap(this.inst, ret); + } + if (ret2 && ret2.length) + { + for (i = 0, j = 0, len = ret2.length; i < len; i++) + { + ret2[j] = ret2[i]; + if (!this.runtime.testOverlap(this.inst, ret2[i])) + j++; + } + if (j >= 1) + return true; + } + return false; + }; + Cnds.prototype.IsByWall = function (side) + { + var ret = false; + var oldx = this.inst.x; + var oldy = this.inst.y; + this.inst.x -= this.downx * 3; + this.inst.y -= this.downy * 3; + this.inst.set_bbox_changed(); + if (this.runtime.testOverlapSolid(this.inst)) + { + this.inst.x = oldx; + this.inst.y = oldy; + this.inst.set_bbox_changed(); + return false; + } + if (side === 0) // left + { + this.inst.x -= this.rightx * 2; + this.inst.y -= this.righty * 2; + } + else + { + this.inst.x += this.rightx * 2; + this.inst.y += this.righty * 2; + } + this.inst.set_bbox_changed(); + ret = this.runtime.testOverlapSolid(this.inst); + this.inst.x = oldx; + this.inst.y = oldy; + this.inst.set_bbox_changed(); + return ret; + }; + Cnds.prototype.IsJumping = function () + { + return this.dy < 0; + }; + Cnds.prototype.IsFalling = function () + { + return this.dy > 0; + }; + Cnds.prototype.OnJump = function () + { + return true; + }; + Cnds.prototype.OnFall = function () + { + return true; + }; + Cnds.prototype.OnStop = function () + { + return true; + }; + Cnds.prototype.OnMove = function () + { + return true; + }; + Cnds.prototype.OnLand = function () + { + return true; + }; + Cnds.prototype.IsDoubleJumpEnabled = function () + { + return this.enableDoubleJump; + }; + behaviorProto.cnds = new Cnds(); + function Acts() {}; + Acts.prototype.SetIgnoreInput = function (ignoring) + { + this.ignoreInput = ignoring; + }; + Acts.prototype.SetMaxSpeed = function (maxspeed) + { + this.maxspeed = maxspeed; + if (this.maxspeed < 0) + this.maxspeed = 0; + }; + Acts.prototype.SetAcceleration = function (acc) + { + this.acc = acc; + if (this.acc < 0) + this.acc = 0; + }; + Acts.prototype.SetDeceleration = function (dec) + { + this.dec = dec; + if (this.dec < 0) + this.dec = 0; + }; + Acts.prototype.SetJumpStrength = function (js) + { + this.jumpStrength = js; + if (this.jumpStrength < 0) + this.jumpStrength = 0; + }; + Acts.prototype.SetGravity = function (grav) + { + if (this.g1 === grav) + return; // no change + this.g = grav; + this.updateGravity(); + if (this.runtime.testOverlapSolid(this.inst)) + { + this.runtime.pushOutSolid(this.inst, this.downx, this.downy, 10); + this.inst.x += this.downx * 2; + this.inst.y += this.downy * 2; + this.inst.set_bbox_changed(); + } + this.lastFloorObject = null; + }; + Acts.prototype.SetMaxFallSpeed = function (mfs) + { + this.maxFall = mfs; + if (this.maxFall < 0) + this.maxFall = 0; + }; + Acts.prototype.SimulateControl = function (ctrl) + { + switch (ctrl) { + case 0: this.simleft = true; break; + case 1: this.simright = true; break; + case 2: this.simjump = true; break; + } + }; + Acts.prototype.SetVectorX = function (vx) + { + this.dx = vx; + }; + Acts.prototype.SetVectorY = function (vy) + { + this.dy = vy; + }; + Acts.prototype.SetGravityAngle = function (a) + { + a = cr.to_radians(a); + a = cr.clamp_angle(a); + if (this.ga === a) + return; // no change + this.ga = a; + this.updateGravity(); + this.lastFloorObject = null; + }; + Acts.prototype.SetEnabled = function (en) + { + if (this.enabled !== (en === 1)) + { + this.enabled = (en === 1); + if (!this.enabled) + this.lastFloorObject = null; + } + }; + Acts.prototype.FallThrough = function () + { + var oldx = this.inst.x; + var oldy = this.inst.y; + this.inst.x += this.downx; + this.inst.y += this.downy; + this.inst.set_bbox_changed(); + var overlaps = this.runtime.testOverlapJumpThru(this.inst, false); + this.inst.x = oldx; + this.inst.y = oldy; + this.inst.set_bbox_changed(); + if (!overlaps) + return; + this.fallthrough = 3; // disable jumpthrus for 3 ticks (1 doesn't do it, 2 does, 3 to be on safe side) + this.lastFloorObject = null; + }; + Acts.prototype.SetDoubleJumpEnabled = function (e) + { + this.enableDoubleJump = (e !== 0); + }; + Acts.prototype.SetJumpSustain = function (s) + { + this.jumpSustain = s / 1000; // convert to ms + }; + behaviorProto.acts = new Acts(); + function Exps() {}; + Exps.prototype.Speed = function (ret) + { + ret.set_float(Math.sqrt(this.dx * this.dx + this.dy * this.dy)); + }; + Exps.prototype.MaxSpeed = function (ret) + { + ret.set_float(this.maxspeed); + }; + Exps.prototype.Acceleration = function (ret) + { + ret.set_float(this.acc); + }; + Exps.prototype.Deceleration = function (ret) + { + ret.set_float(this.dec); + }; + Exps.prototype.JumpStrength = function (ret) + { + ret.set_float(this.jumpStrength); + }; + Exps.prototype.Gravity = function (ret) + { + ret.set_float(this.g); + }; + Exps.prototype.GravityAngle = function (ret) + { + ret.set_float(cr.to_degrees(this.ga)); + }; + Exps.prototype.MaxFallSpeed = function (ret) + { + ret.set_float(this.maxFall); + }; + Exps.prototype.MovingAngle = function (ret) + { + ret.set_float(cr.to_degrees(Math.atan2(this.dy, this.dx))); + }; + Exps.prototype.VectorX = function (ret) + { + ret.set_float(this.dx); + }; + Exps.prototype.VectorY = function (ret) + { + ret.set_float(this.dy); + }; + Exps.prototype.JumpSustain = function (ret) + { + ret.set_float(this.jumpSustain * 1000); // convert back to ms + }; + behaviorProto.exps = new Exps(); +}()); +; +; +cr.behaviors.Timer = function(runtime) +{ + this.runtime = runtime; +}; +(function () +{ + var behaviorProto = cr.behaviors.Timer.prototype; + behaviorProto.Type = function(behavior, objtype) + { + this.behavior = behavior; + this.objtype = objtype; + this.runtime = behavior.runtime; + }; + var behtypeProto = behaviorProto.Type.prototype; + behtypeProto.onCreate = function() + { + }; + behaviorProto.Instance = function(type, inst) + { + this.type = type; + this.behavior = type.behavior; + this.inst = inst; // associated object instance to modify + this.runtime = type.runtime; + }; + var behinstProto = behaviorProto.Instance.prototype; + behinstProto.onCreate = function() + { + this.timers = {}; + }; + behinstProto.onDestroy = function () + { + cr.wipe(this.timers); + }; + behinstProto.saveToJSON = function () + { + var o = {}; + var p, t; + for (p in this.timers) + { + if (this.timers.hasOwnProperty(p)) + { + t = this.timers[p]; + o[p] = { + "c": t.current.sum, + "t": t.total.sum, + "d": t.duration, + "r": t.regular + }; + } + } + return o; + }; + behinstProto.loadFromJSON = function (o) + { + this.timers = {}; + var p; + for (p in o) + { + if (o.hasOwnProperty(p)) + { + this.timers[p] = { + current: new cr.KahanAdder(), + total: new cr.KahanAdder(), + duration: o[p]["d"], + regular: o[p]["r"] + }; + this.timers[p].current.sum = o[p]["c"]; + this.timers[p].total.sum = o[p]["t"]; + } + } + }; + behinstProto.tick = function () + { + var dt = this.runtime.getDt(this.inst); + var p, t; + for (p in this.timers) + { + if (this.timers.hasOwnProperty(p)) + { + t = this.timers[p]; + t.current.add(dt); + t.total.add(dt); + } + } + }; + behinstProto.tick2 = function () + { + var p, t; + for (p in this.timers) + { + if (this.timers.hasOwnProperty(p)) + { + t = this.timers[p]; + if (t.current.sum >= t.duration) + { + if (t.regular) + t.current.sum -= t.duration; + else + delete this.timers[p]; + } + } + } + }; + function Cnds() {}; + Cnds.prototype.OnTimer = function (tag_) + { + tag_ = tag_.toLowerCase(); + var t = this.timers[tag_]; + if (!t) + return false; + return t.current.sum >= t.duration; + }; + behaviorProto.cnds = new Cnds(); + function Acts() {}; + Acts.prototype.StartTimer = function (duration_, type_, tag_) + { + this.timers[tag_.toLowerCase()] = { + current: new cr.KahanAdder(), + total: new cr.KahanAdder(), + duration: duration_, + regular: (type_ === 1) + }; + }; + Acts.prototype.StopTimer = function (tag_) + { + tag_ = tag_.toLowerCase(); + if (this.timers.hasOwnProperty(tag_)) + delete this.timers[tag_]; + }; + behaviorProto.acts = new Acts(); + function Exps() {}; + Exps.prototype.CurrentTime = function (ret, tag_) + { + var t = this.timers[tag_.toLowerCase()]; + ret.set_float(t ? t.current.sum : 0); + }; + Exps.prototype.TotalTime = function (ret, tag_) + { + var t = this.timers[tag_.toLowerCase()]; + ret.set_float(t ? t.total.sum : 0); + }; + Exps.prototype.Duration = function (ret, tag_) + { + var t = this.timers[tag_.toLowerCase()]; + ret.set_float(t ? t.duration : 0); + }; + behaviorProto.exps = new Exps(); +}()); +; +; +cr.behaviors.solid = function(runtime) +{ + this.runtime = runtime; +}; +(function () +{ + var behaviorProto = cr.behaviors.solid.prototype; + behaviorProto.Type = function(behavior, objtype) + { + this.behavior = behavior; + this.objtype = objtype; + this.runtime = behavior.runtime; + }; + var behtypeProto = behaviorProto.Type.prototype; + behtypeProto.onCreate = function() + { + }; + behaviorProto.Instance = function(type, inst) + { + this.type = type; + this.behavior = type.behavior; + this.inst = inst; // associated object instance to modify + this.runtime = type.runtime; + }; + var behinstProto = behaviorProto.Instance.prototype; + behinstProto.onCreate = function() + { + this.inst.extra["solidEnabled"] = (this.properties[0] !== 0); + }; + behinstProto.tick = function () + { + }; + function Cnds() {}; + Cnds.prototype.IsEnabled = function () + { + return this.inst.extra["solidEnabled"]; + }; + behaviorProto.cnds = new Cnds(); + function Acts() {}; + Acts.prototype.SetEnabled = function (e) + { + this.inst.extra["solidEnabled"] = !!e; + }; + behaviorProto.acts = new Acts(); +}()); +cr.getObjectRefTable = function () { return [ + cr.plugins_.Keyboard, + cr.plugins_.Sprite, + cr.plugins_.Text, + cr.behaviors.solid, + cr.behaviors.Platform, + cr.behaviors.Flash, + cr.behaviors.Pin, + cr.behaviors.Timer, + cr.behaviors.Anchor, + cr.system_object.prototype.cnds.EveryTick, + cr.plugins_.Sprite.prototype.acts.SetPosToObject, + cr.plugins_.Keyboard.prototype.cnds.IsKeyDown, + cr.plugins_.Sprite.prototype.acts.SetAnim, + cr.plugins_.Sprite.prototype.acts.SetInstanceVar, + cr.plugins_.Keyboard.prototype.cnds.OnKeyReleased, + cr.plugins_.Sprite.prototype.acts.SetMirrored, + cr.system_object.prototype.acts.ScrollToObject, + cr.system_object.prototype.cnds.OnLayoutStart, + cr.behaviors.Pin.prototype.acts.Pin, + cr.plugins_.Keyboard.prototype.cnds.OnKey, + cr.plugins_.Sprite.prototype.cnds.IsMirrored, + cr.system_object.prototype.cnds.CompareVar, + cr.plugins_.Sprite.prototype.acts.MoveForward, + cr.plugins_.Sprite.prototype.cnds.IsOutsideLayout, + cr.system_object.prototype.acts.ResetGlobals, + cr.system_object.prototype.acts.RestartLayout, + cr.plugins_.Text.prototype.acts.SetText, + cr.system_object.prototype.cnds.IsGroupActive, + cr.system_object.prototype.acts.AddVar, + cr.system_object.prototype.acts.SetGroupActive, + cr.system_object.prototype.acts.SetVar, + cr.system_object.prototype.cnds.Every, + cr.system_object.prototype.acts.SubVar, + cr.plugins_.Sprite.prototype.cnds.IsAnimPlaying, + cr.plugins_.Sprite.prototype.cnds.CompareInstanceVar, + cr.plugins_.Sprite.prototype.cnds.IsOverlapping, + cr.plugins_.Sprite.prototype.cnds.IsOnScreen, + cr.behaviors.Platform.prototype.acts.SimulateControl, + cr.plugins_.Sprite.prototype.cnds.OnCollision, + cr.behaviors.Flash.prototype.cnds.IsFlashing, + cr.behaviors.Flash.prototype.acts.Flash +];}; + diff --git a/data.js b/data.js new file mode 100644 index 0000000..77e70e3 --- /dev/null +++ b/data.js @@ -0,0 +1 @@ +{"project": [null,null,[[0,true,false,false,false,false,false,false,false,false],[1,false,true,true,true,true,true,true,true,false],[2,false,true,true,true,true,true,true,true,false]],[["t0",1,false,[],0,0,null,[["Default",5,false,1,0,false,894588555433977,[["images/sky-sheet0.png",10326,0,0,1024,1024,1,0.5,0.5,[],[],1]]]],[],false,false,8840387436439488,[],null],["t1",1,false,[],1,0,null,[["Default",5,false,1,0,false,8496970021665571,[["images/ground-sheet0.png",621,0,0,70,70,1,0.5,0.5,[],[],1]]]],[["Solid",3,7124959039363926]],false,false,193727495283393,[],null],["t2",1,false,[9122339041308179,7035951631058867],2,0,null,[["Default",5,false,1,0,false,2021366376608442,[["images/nevir-sheet0.png",11622,0,0,100,100,1,0.5,0.5,[],[-0.2800000011920929,-0.2800000011920929,0,-0.4200000166893005,0.1200000047683716,-0.1200000047683716,0.1600000262260437,0,0.01999998092651367,0.01999998092651367,0,0.1000000238418579,-0.09999999403953552,0.1000000238418579,-0.2800000011920929,0],0]]],["walk",5,false,1,0,false,8195749422792433,[["images/nevir-sheet1.png",11220,0,0,100,100,1,0.5,0.5,[],[-0.2800000011920929,-0.2800000011920929,0,-0.4200000166893005,0.1200000047683716,-0.1200000047683716,0.1600000262260437,0,0.01999998092651367,0.01999998092651367,0,0.1000000238418579,-0.09999999403953552,0.1000000238418579,-0.2800000011920929,0],0],["images/nevir-sheet2.png",11300,0,0,100,100,1,0.5,0.5,[],[-0.2800000011920929,-0.2800000011920929,0,-0.4200000166893005,0.1200000047683716,-0.1200000047683716,0.1600000262260437,0,0.01999998092651367,0.01999998092651367,0,0.199999988079071,-0.199999988079071,0.199999988079071,-0.2800000011920929,0],0]]]],[["Platform",4,8064274975689883],["Flash",5,6752849918288591]],false,false,4823972837373065,[],null],["t3",1,false,[1336123800314399],1,0,null,[["Default",5,false,1,0,false,1935776649275112,[["images/playerbox-sheet0.png",155,0,0,250,250,1,0.5,0.5,[],[],1]]]],[["Platform",4,2763172461996025]],false,false,3449725673839276,[],null],["t4",0,false,[],0,0,null,null,[],false,false,4233970867963345,[],null,[]],["t5",1,false,[],0,0,null,[["Default",5,false,1,0,false,3217811244445085,[["images/sprite-sheet0.png",168,0,0,250,250,1,0.5,0.5,[],[],3]]]],[],false,false,2753277509592283,[],null],["t6",1,false,[],2,0,null,[["Default",5,false,1,0,false,1910204875116093,[["images/life-sheet0.png",1324,1,1,20,13,1,0.5,0.5384615659713745,[],[-0.4056603908538818,-0.4273505806922913,-0.009434014558792114,-0.4717948734760284,0.4056599736213684,-0.4273505806922913,0.4622640013694763,-0.04957255721092224,0.2735850214958191,0.1948714256286621,-0.009434014558792114,0.4615384340286255,-0.2924529910087585,0.2170944213867188,-0.4811320900917053,-0.04957255721092224],0]]],["Half",5,false,1,0,false,9848056392904339,[["images/life-sheet0.png",1324,1,16,20,13,1,0.5,0.5384615659713745,[],[-0.4056603908538818,-0.4273505806922913,-0.009434014558792114,-0.4717948734760284,0.4056599736213684,-0.4273505806922913,0.4622640013694763,-0.04957255721092224,0.2735850214958191,0.1948714256286621,-0.009434014558792114,0.4615384340286255,-0.2924529910087585,0.2170944213867188,-0.4811320900917053,-0.04957255721092224],0]]],["low",5,false,1,0,false,3907904317568607,[["images/life-sheet1.png",1438,1,1,20,13,1,0.5,0.5384615659713745,[],[-0.4056603908538818,-0.4273505806922913,-0.009434014558792114,-0.4717948734760284,0.4056599736213684,-0.4273505806922913,0.4622640013694763,-0.04957255721092224,0.2735850214958191,0.1948714256286621,-0.009434014558792114,0.4615384340286255,-0.2924529910087585,0.2170944213867188,-0.4811320900917053,-0.04957255721092224],0]]],["shield",5,false,1,0,false,6822313287789241,[["images/life-sheet1.png",1438,1,16,20,13,1,0.5,0.5384615659713745,[],[-0.4056603908538818,-0.4273505806922913,-0.009434014558792114,-0.4717948734760284,0.4056599736213684,-0.4273505806922913,0.4622640013694763,-0.04957255721092224,0.2735850214958191,0.1948714256286621,-0.009434014558792114,0.4615384340286255,-0.2924529910087585,0.2170944213867188,-0.4811320900917053,-0.04957255721092224],0]]]],[["Pin",6,6651456857673585],["Timer",7,1787521435674711]],false,false,9536276670010288,[],null],["t7",2,false,[],2,0,null,null,[["Pin",6,4045118079746779],["Anchor",8,6149296144671221]],false,false,3868569434358858,[],null],["t8",1,false,[],1,0,null,[["Default",5,false,1,0,false,2204843303846439,[["images/wall-sheet0.png",323,0,0,70,70,1,0.5,0.5,[],[],1]]]],[["Solid",3,8742690640549589]],false,false,6686598094246122,[],null],["t9",1,false,[7064066674935988],1,0,null,[["Default",5,false,1,0,false,2721422099611482,[["images/baddyguy-sheet0.png",868,0,0,54,31,1,0.5,0.5161290168762207,[],[-0.3333330154418945,-0.2258060276508331,0,-0.4838709235191345,0.3888890147209168,-0.322581022977829,0.4629629850387573,-0.03225800395011902,0.4814810156822205,0.4516130089759827,0,0.4838709831237793,-0.4259259104728699,0.3548389673233032,-0.4259259104728699,-0.03225800395011902],0]]]],[["Platform",4,2723526339163831]],false,false,65507768244669,[],null],["t10",1,false,[],0,0,null,[["Default",5,false,1,0,false,5352799767886567,[["images/turnleft-sheet0.png",367,0,0,250,250,1,0.5,0.5,[],[],0]]]],[],false,false,7423590022667733,[],null],["t11",1,false,[],0,0,null,[["Default",5,false,1,0,false,522560930924522,[["images/turnright-sheet0.png",416,0,0,250,250,1,0.5,0.5,[],[],0]]]],[],false,false,2337679433718662,[],null],["t12",1,false,[],0,0,null,[["Default",5,false,1,0,false,766640484057433,[["images/sprite2-sheet0.png",662,0,0,250,250,1,0.5,0.5,[],[],0]]]],[],false,false,5620698777406111,[],null]],[],[["Layout 1",10000,960,false,"Event sheet 1",3905167510839031,[["Layer 0",0,2662565032698401,true,[255,255,255],false,1,1,1,false,false,1,0,0,[[[6048,480,0,1728,960,0,0,1,0.5,0.5,0,0,[]],0,24,[],[],[0,"Default",0,1]],[[4320,480,0,1728,960,0,0,1,0.5,0.5,0,0,[]],0,23,[],[],[0,"Default",0,1]],[[2592,480,0,1728,960,0,0,1,0.5,0.5,0,0,[]],0,22,[],[],[0,"Default",0,1]],[[864,480,0,1728,960,0,0,1,0.5,0.5,0,0,[]],0,0,[],[],[0,"Default",0,1]],[[36,517,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,1,[],[[1]],[0,"Default",0,1]],[[100,517,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,2,[],[[1]],[0,"Default",0,1]],[[164,517,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,3,[],[[1]],[0,"Default",0,1]],[[228,517,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,4,[],[[1]],[0,"Default",0,1]],[[292,517,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,5,[],[[1]],[0,"Default",0,1]],[[356,517,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,6,[],[[1]],[0,"Default",0,1]],[[420,517,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,7,[],[[1]],[0,"Default",0,1]],[[484,517,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,8,[],[[1]],[0,"Default",0,1]],[[548,517,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,9,[],[[1]],[0,"Default",0,1]],[[127,447,0,49,70,0,0,1,0.5,0.5,0,0,[]],3,12,[[0]],[[330,1500,1500,650,1500,1000,0,0,1,1]],[1,"Default",0,1]],[[101,415,0,20,13,0,0,1,0.5,0.5384615659713745,0,0,[]],6,14,[],[[],[]],[0,"Default",0,1]],[[1120,512,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,17,[],[[1]],[0,"Default",0,1]],[[1184,512,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,18,[],[[1]],[0,"Default",0,1]],[[1248,512,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,19,[],[[1]],[0,"Default",0,1]],[[1312,512,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,20,[],[[1]],[0,"Default",0,1]],[[1376,512,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,21,[],[[1]],[0,"Default",0,1]],[[7776,480,0,1728,960,0,0,1,0.5,0.5,0,0,[]],0,25,[],[],[0,"Default",0,1]],[[9504,480,0,1728,960,0,0,1,0.5,0.5,0,0,[]],0,26,[],[],[0,"Default",0,1]],[[1440,512,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,27,[],[[1]],[0,"Default",0,1]],[[1504,512,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,28,[],[[1]],[0,"Default",0,1]],[[1568,512,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,29,[],[[1]],[0,"Default",0,1]],[[1632,512,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,30,[],[[1]],[0,"Default",0,1]],[[1696,512,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,31,[],[[1]],[0,"Default",0,1]],[[1760,512,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,32,[],[[1]],[0,"Default",0,1]],[[1408,448,0,70,70,0,0,1,0.5,0.5,0,0,[]],8,33,[],[[1]],[0,"Default",0,1]],[[1408,384,0,70,70,0,0,1,0.5,0.5,0,0,[]],8,34,[],[[1]],[0,"Default",0,1]],[[1408,320,0,70,70,0,0,1,0.5,0.5,0,0,[]],8,35,[],[[1]],[0,"Default",0,1]],[[1408,256,0,70,70,0,0,1,0.5,0.5,0,0,[]],8,36,[],[[1]],[0,"Default",0,1]],[[1408,192,0,70,70,0,0,1,0.5,0.5,0,0,[]],8,37,[],[[1]],[0,"Default",0,1]],[[1472,448,0,70,70,0,0,1,0.5,0.5,0,0,[]],8,38,[],[[1]],[0,"Default",0,1]],[[1472,384,0,70,70,0,0,1,0.5,0.5,0,0,[]],8,39,[],[[1]],[0,"Default",0,1]],[[1472,320,0,70,70,0,0,1,0.5,0.5,0,0,[]],8,40,[],[[1]],[0,"Default",0,1]],[[1472,256,0,70,70,0,0,1,0.5,0.5,0,0,[]],8,41,[],[[1]],[0,"Default",0,1]],[[1472,192,0,70,70,0,0,1,0.5,0.5,0,0,[]],8,42,[],[[1]],[0,"Default",0,1]],[[1280,480,0,54,31,0,0,1,0.5,0.5161290168762207,0,0,[]],9,43,[[0]],[[330,1500,1500,650,1500,1000,0,0,0,1]],[0,"Default",0,1]],[[1056,480,0,34.85684967041016,34.85684967041016,0,0,1,0.5,0.5,0,0,[]],10,44,[],[],[1,"Default",0,1]],[[1056,512,0,70,70,0,0,1,0.5,0.5,0,0,[]],8,45,[],[[1]],[0,"Default",0,1]],[[617.5623168945313,517.4644775390625,0,70,70,0,0,1,0.5,0.5,0,0,[]],8,46,[],[[1]],[0,"Default",0,1]],[[1824,512,0,70,70,0,0,1,0.5,0.5,0,0,[]],8,47,[],[[1]],[0,"Default",0,1]],[[1360,464,0,64,64,0,0,1,0.5,0.5,0,0,[]],11,10,[],[],[1,"Default",0,1]],[[2240,384,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,16,[],[[1]],[0,"Default",0,1]],[[2176,384,0,70,70,0,0,1,0.5,0.5,0,0,[]],8,48,[],[[1]],[0,"Default",0,1]],[[2304,384,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,49,[],[[1]],[0,"Default",0,1]],[[2368,384,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,50,[],[[1]],[0,"Default",0,1]],[[2432,384,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,51,[],[[1]],[0,"Default",0,1]],[[2560,384,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,52,[],[[1]],[0,"Default",0,1]],[[2496,384,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,53,[],[[1]],[0,"Default",0,1]],[[2624,384,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,54,[],[[1]],[0,"Default",0,1]],[[2624,352,0,54,31,0,0,1,0.5,0.5161290168762207,0,0,[]],9,55,[[0]],[[330,1500,1500,650,1500,1000,0,0,0,1]],[0,"Default",0,1]],[[2688,384,0,70,70,0,0,1,0.5,0.5,0,0,[]],8,56,[],[[1]],[0,"Default",0,1]],[[2688,320,0,64,64,0,0,1,0.5,0.5,0,0,[]],11,57,[],[],[1,"Default",0,1]],[[2080,384,0,34.85684967041016,34.85684967041016,0,0,1,0.5,0.5,0,0,[]],10,58,[],[],[1,"Default",0,1]],[[3008,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,60,[],[[1]],[0,"Default",0,1]],[[3488,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,62,[],[[1]],[0,"Default",0,1]],[[2816,288,0,70,70,0,0,1,0.5,0.5,0,0,[]],8,63,[],[[1]],[0,"Default",0,1]],[[2816,352,0,70,70,0,0,1,0.5,0.5,0,0,[]],8,64,[],[[1]],[0,"Default",0,1]],[[2816,384,0,70,70,0,0,1,0.5,0.5,0,0,[]],8,65,[],[[1]],[0,"Default",0,1]],[[2816,448,0,70,70,0,0,1,0.5,0.5,0,0,[]],8,66,[],[[1]],[0,"Default",0,1]],[[2816,512,0,70,70,0,0,1,0.5,0.5,0,0,[]],8,67,[],[[1]],[0,"Default",0,1]],[[2816,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],8,68,[],[[1]],[0,"Default",0,1]],[[2816,640,0,70,70,0,0,1,0.5,0.5,0,0,[]],8,69,[],[[1]],[0,"Default",0,1]],[[2816,704,0,70,70,0,0,1,0.5,0.5,0,0,[]],8,70,[],[[1]],[0,"Default",0,1]],[[2816,224,0,70,70,0,0,1,0.5,0.5,0,0,[]],8,71,[],[[1]],[0,"Default",0,1]],[[2816,160,0,70,70,0,0,1,0.5,0.5,0,0,[]],8,72,[],[[1]],[0,"Default",0,1]],[[2816,96,0,70,70,0,0,1,0.5,0.5,0,0,[]],8,73,[],[[1]],[0,"Default",0,1]],[[2816,32,0,70,70,0,0,1,0.5,0.5,0,0,[]],8,74,[],[[1]],[0,"Default",0,1]],[[3552,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,75,[],[[1]],[0,"Default",0,1]],[[3424,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],8,77,[],[[1]],[0,"Default",0,1]],[[4064,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,79,[],[[1]],[0,"Default",0,1]],[[4128,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,80,[],[[1]],[0,"Default",0,1]],[[4192,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,81,[],[[1]],[0,"Default",0,1]],[[4256,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,82,[],[[1]],[0,"Default",0,1]],[[4320,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,83,[],[[1]],[0,"Default",0,1]],[[4384,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,84,[],[[1]],[0,"Default",0,1]],[[4448,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,85,[],[[1]],[0,"Default",0,1]],[[4512,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,86,[],[[1]],[0,"Default",0,1]],[[4576,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,87,[],[[1]],[0,"Default",0,1]],[[4640,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,88,[],[[1]],[0,"Default",0,1]],[[4704,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,89,[],[[1]],[0,"Default",0,1]],[[4768,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,90,[],[[1]],[0,"Default",0,1]],[[4832,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,91,[],[[1]],[0,"Default",0,1]],[[4896,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,92,[],[[1]],[0,"Default",0,1]],[[4960,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,93,[],[[1]],[0,"Default",0,1]],[[5024,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,94,[],[[1]],[0,"Default",0,1]],[[5088,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,95,[],[[1]],[0,"Default",0,1]],[[5152,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,96,[],[[1]],[0,"Default",0,1]],[[5216,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,97,[],[[1]],[0,"Default",0,1]],[[5280,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,98,[],[[1]],[0,"Default",0,1]],[[5280,512,0,64,64,0,0,1,0.5,0.5,0,0,[]],11,99,[],[],[1,"Default",0,1]],[[4000,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],8,100,[],[[1]],[0,"Default",0,1]],[[4000,544,0,34.85684967041016,34.85684967041016,0,0,1,0.5,0.5,0,0,[]],10,78,[],[],[1,"Default",0,1]],[[3616,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],8,76,[],[[1]],[0,"Default",0,1]],[[3072,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],8,101,[],[[1]],[0,"Default",0,1]],[[2944,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],8,59,[],[[1]],[0,"Default",0,1]],[[5218,534,0,54,31,0,0,1,0.5,0.5161290168762207,0,0,[]],9,61,[[0]],[[330,1500,1500,650,1500,1000,0,0,0,1]],[0,"Default",0,1]],[[5154,537,0,54,31,0,0,1,0.5,0.5161290168762207,0,0,[]],9,102,[[0]],[[330,1500,1500,650,1500,1000,0,0,0,1]],[0,"Default",0,1]],[[5091,535,0,54,31,0,0,1,0.5,0.5161290168762207,0,0,[]],9,103,[[0]],[[330,1500,1500,650,1500,1000,0,0,0,1]],[0,"Default",0,1]],[[4128,537,0,54,31,0,0,1,0.5,0.5161290168762207,0,0,[]],9,104,[[0]],[[330,1500,1500,650,1500,1000,0,0,0,1]],[0,"Default",0,1]],[[4259,535,0,54,31,0,0,1,0.5,0.5161290168762207,0,0,[]],9,105,[[0]],[[330,1500,1500,650,1500,1000,0,0,0,1]],[0,"Default",0,1]],[[4423,535,0,54,31,0,0,1,0.5,0.5161290168762207,0,0,[]],9,106,[[0]],[[330,1500,1500,650,1500,1000,0,0,0,1]],[0,"Default",0,1]],[[4573,533,0,54,31,0,0,1,0.5,0.5161290168762207,0,0,[]],9,107,[[0]],[[330,1500,1500,650,1500,1000,0,0,0,1]],[0,"Default",0,1]],[[4728,532,0,54,31,0,0,1,0.5,0.5161290168762207,0,0,[]],9,108,[[0]],[[330,1500,1500,650,1500,1000,0,0,0,1]],[0,"Default",0,1]],[[4844,533,0,54,31,0,0,1,0.5,0.5161290168762207,0,0,[]],9,109,[[0]],[[330,1500,1500,650,1500,1000,0,0,0,1]],[0,"Default",0,1]],[[4982,535,0,54,31,0,0,1,0.5,0.5161290168762207,0,0,[]],9,110,[[0]],[[330,1500,1500,650,1500,1000,0,0,0,1]],[0,"Default",0,1]],[[5344,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],8,111,[],[[1]],[0,"Default",0,1]],[[5920,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],8,112,[],[[1]],[0,"Default",0,1]],[[5984,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,113,[],[[1]],[0,"Default",0,1]],[[6048,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,114,[],[[1]],[0,"Default",0,1]],[[6112,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,115,[],[[1]],[0,"Default",0,1]],[[6176,576,0,70,70,0,0,1,0.5,0.5,0,0,[]],1,116,[],[[1]],[0,"Default",0,1]],[[6048,448,0,250,250,0,0,1,0.5,0.5,0,0,[]],12,117,[],[],[0,"Default",0,1]],[[128,439,0,100,100,0,0,1,0.5,0.5,0,0,[]],2,11,[[0],[100]],[[330,1500,1500,650,1500,1000,0,0,1,1],[]],[0,"Default",0,1]],[[736,0,0,86,47,0,0,1,0,0,0,0,[]],7,15,[],[[],[1,0,0,0,1]],["Blink",0,"20pt Arial","rgb(0,0,0)",0,0,0,0,0]]],[]]],[],[]]],[["Event sheet 1",[[1,"WCD",0,0,false,false,1649505260174007,false],[1,"ECD",0,0,false,false,7300469877559958,false],[0,null,false,null,8402837080993532,[[-1,9,null,0,false,false,false,172097913585221,false]],[[2,10,null,7750701627934874,false,[[4,3],[7,[0,0]]]]]],[0,null,false,null,8315845556816156,[[4,11,null,0,false,false,false,6795905735130401,false,[[9,37]]]],[[2,12,null,4007225235353441,false,[[1,[2,"walk"]],[3,1]]],[2,13,null,349047072573051,false,[[10,0],[7,[0,0]]]]]],[0,null,false,null,8054214278648363,[[4,11,null,0,false,false,false,1570404509555294,false,[[9,39]]]],[[2,12,null,9404513644917341,false,[[1,[2,"walk"]],[3,1]]],[2,13,null,1696670090745574,false,[[10,0],[7,[0,1]]]]]],[0,null,false,null,4613493028023321,[[4,14,null,1,false,false,false,567098522749664,false,[[9,37]]]],[[2,12,null,2883531736001042,false,[[1,[2,"Default"]],[3,1]]]]],[0,null,false,null,1021674742000514,[[4,14,null,1,false,false,false,4886346495761034,false,[[9,39]]]],[[2,12,null,282249211599699,false,[[1,[2,"Default"]],[3,1]]]]],[0,null,false,null,4731058027023328,[[4,11,null,0,false,false,false,9579143083252616,false,[[9,37]]]],[[2,15,null,2268341494351133,false,[[3,1]]]]],[0,null,false,null,8095365901414142,[[4,11,null,0,false,false,false,5239372665165889,false,[[9,39]]]],[[2,15,null,5863966758203257,false,[[3,0]]]]],[0,null,false,null,9533262153631531,[[-1,9,null,0,false,false,false,2630838906810946,false]],[[-1,16,null,7950376801174324,false,[[4,3]]]]],[0,null,false,null,3021112899934958,[[-1,17,null,1,false,false,false,1897997535450513,false]],[[6,18,"Pin",3300236508731602,false,[[4,3],[3,4]]]]],[0,null,false,null,2848961658290552,[[4,19,null,1,false,false,false,6397268624745562,false,[[9,69]]],[2,20,null,0,false,false,false,5448487095797558,false],[-1,21,null,0,false,false,false,5405275718507695,false,[[11,"ECD"],[8,0],[7,[0,0]]]]],[[3,22,null,5929801517613323,false,[[0,[0,200]]]]]],[0,null,false,null,4508078774366284,[[2,23,null,0,false,false,false,5467520118199952,false]],[[-1,24,null,1217798340996445,false],[-1,25,null,721350812051633,false]]],[0,null,false,null,9796843449208352,[[-1,9,null,0,false,false,false,3193095720315902,false]],[[7,26,null,4261911667896095,false,[[7,[23,"ECD"]]]]]],[0,[true,"BLINK"],false,null,8514643772734608,[[-1,27,null,0,false,false,false,8514643772734608,false,[[1,[2,"BLINK"]]]]],[],[[0,null,false,null,5869494840151275,[[4,19,null,1,false,false,false,2651875743897079,false,[[9,69]]],[2,20,null,0,false,false,false,2964587997511465,false],[-1,21,null,0,false,false,false,1589361955715915,false,[[11,"ECD"],[8,0],[7,[0,0]]]]],[[-1,28,null,9459121986482162,false,[[11,"ECD"],[7,[0,1]]]]]]]],[0,null,false,null,8828330096455349,[[-1,21,null,0,false,false,false,8076178203954277,false,[[11,"ECD"],[8,4],[7,[0,1]]]]],[[-1,29,null,7045588149252272,false,[[1,[2,"BLINK"]],[3,0]]]]],[0,null,false,null,104533399925561,[[-1,21,null,0,false,false,false,4690977819411265,false,[[11,"ECD"],[8,2],[7,[0,1]]]]],[[-1,29,null,4176464903409654,false,[[1,[2,"BLINK"]],[3,1]]],[-1,30,null,3040872046703717,false,[[11,"ECD"],[7,[0,0]]]]]],[0,null,false,null,5078227506612242,[[-1,31,null,0,false,false,false,325449902072911,false,[[0,[1,1]]]],[-1,21,null,0,false,false,false,8227872010322167,false,[[11,"ECD"],[8,4],[7,[0,0]]]]],[[-1,32,null,8001106906684652,false,[[11,"ECD"],[7,[0,1]]]]]],[0,null,false,null,2324016914920465,[[6,33,null,0,false,false,false,1241663006215924,false,[[1,[2,"shield"]]]],[-1,21,null,0,false,false,false,5033486698135752,false,[[11,"ECD"],[8,0],[7,[0,0]]]]],[[6,12,null,4439142457653575,false,[[1,[2,"Default"]],[3,1]]]]],[0,null,false,null,8226248630216459,[[4,19,null,1,false,false,false,3936026181869194,false,[[9,69]]],[2,34,null,0,false,false,false,8930383567649603,false,[[10,0],[8,0],[7,[0,1]]]],[-1,21,null,0,false,false,false,6410673273090691,false,[[11,"ECD"],[8,0],[7,[0,0]]]]],[[3,22,null,2495841030406222,false,[[0,[0,200]]]],[6,12,null,8103933471473252,false,[[1,[2,"shield"]],[3,1]]]]],[0,null,false,null,7284930308589648,[[3,35,null,0,false,false,false,150420018029332,false,[[4,8]]]],[[-1,24,null,1441108667321817,false],[-1,25,null,4832726023275241,false]]],[0,null,false,null,5012663881190627,[[9,34,null,0,false,false,false,1491924272849626,false,[[10,0],[8,0],[7,[0,0]]]],[9,36,null,0,false,false,false,6561387514688766,false]],[[9,37,"Platform",76907666187335,false,[[3,0]]],[9,15,null,5987409550521368,false,[[3,1]]]]],[0,null,false,null,9897071995843908,[[9,38,null,0,false,false,true,9771875540541059,false,[[4,10]]]],[[9,13,null,9906848170289546,false,[[10,0],[7,[0,1]]]]]],[0,null,false,null,4944065371105447,[[9,34,null,0,false,false,false,8177958786320413,false,[[10,0],[8,0],[7,[0,1]]]]],[[9,37,"Platform",6864766820604797,false,[[3,1]]],[9,15,null,1972022001829472,false,[[3,0]]]]],[0,null,false,null,9859908169616586,[[9,38,null,0,false,false,true,7159676650297529,false,[[4,11]]]],[[9,13,null,1096495092074691,false,[[10,0],[7,[0,0]]]]]],[0,null,false,null,4208946961247948,[[2,38,null,0,false,false,true,4986060928758627,false,[[4,9]]],[6,33,null,0,false,false,false,4187510631494738,false,[[1,[2,"shield"]]]],[2,39,"Flash",0,false,true,false,6518508831550161,false]],[[6,12,null,2905628128308413,false,[[1,[2,"Default"]],[3,1]]],[2,40,"Flash",9566640152266645,false,[[0,[1,0.1]],[0,[1,0.1]],[0,[1,1]]]]]],[0,null,false,null,2033162971591972,[[2,38,null,0,false,false,true,6956132920291719,false,[[4,9]]],[6,33,null,0,false,false,false,3194004660662896,false,[[1,[2,"Default"]]]],[2,39,"Flash",0,false,true,false,909459653866614,false]],[[6,12,null,5854987664949433,false,[[1,[2,"Half"]],[3,1]]],[2,40,"Flash",155413242025834,false,[[0,[1,0.1]],[0,[1,0.1]],[0,[1,1]]]]]],[0,null,false,null,26159099763803,[[2,38,null,0,false,false,true,67036062047033,false,[[4,9]]],[6,33,null,0,false,false,false,7256175438296207,false,[[1,[2,"Half"]]]],[2,39,"Flash",0,false,true,false,289649257523314,false]],[[6,12,null,944698428929039,false,[[1,[2,"low"]],[3,1]]],[2,40,"Flash",9694982868594157,false,[[0,[1,0.1]],[0,[1,0.1]],[0,[1,1]]]]]],[0,null,false,null,7228094648420385,[[6,33,null,0,false,false,false,8042174108414996,false,[[1,[2,"low"]]]]],[[-1,25,null,8374915172801903,false],[-1,24,null,7659924457650936,false]]],[0,null,false,null,6091116293202279,[[4,19,null,1,false,false,false,4291167223425373,false,[[9,69]]],[6,33,null,0,false,false,false,5424108161868079,false,[[1,[2,"Default"]]]]],[[6,12,null,5175786064317191,false,[[1,[2,"shield"]],[3,1]]]]],[0,null,false,null,4557990642454362,[[3,38,null,0,false,false,true,6520022569541936,false,[[4,12]]]],[[-1,25,null,9841801007004162,false],[-1,24,null,9400357326364126,false]]],[0,null,false,null,9241191955429388,[[4,19,null,1,false,false,false,8064953315882658,false,[[9,69]]],[2,34,null,0,false,false,false,9625173605621603,false,[[10,0],[8,0],[7,[0,0]]]],[-1,21,null,0,false,false,false,5662310590449692,false,[[11,"ECD"],[8,0],[7,[0,0]]]]],[[3,22,null,4853914383153177,false,[[0,[0,-200]]]],[6,12,null,6339878257617711,false,[[1,[2,"shield"]],[3,1]]],[-1,28,null,3563720405638554,false,[[11,"ECD"],[7,[0,1]]]]]]]]],[],"media/",false,854,480,4,true,true,true,"1.0.0.0",true,false,0,0,143,false,true,1,true,"New project",[]]} \ No newline at end of file diff --git a/icon-114.png b/icon-114.png new file mode 100644 index 0000000000000000000000000000000000000000..bf56364da41841cdff16e406c4d5d818e03a102c GIT binary patch literal 25223 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%0A5%m_PO*V84?fv&&Duq6nw{Lpti^Twxo|kNT1Q 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 S2?iX6O(SjR}|-qqqr?Y=#6DQ9+SxzU+mS zft_f&Wt)Oy#jS6YZqB)OYkPOSUVG=$MT{|C^4uR!e&6r&d49j=i_tU&|NbZyom2i$ z(Tl~K*41Wbn>2mjI)~kp(=X{*O+FV-SQJHZqq4|9f{elawZCP*vH8fpG2h)0Wx_M6 zctURFy|&kuR_0I*Uv|GU+kWHm!I8ThrfTK({nHQ=X~Z0#LoIh+MAkMHY`P# z(1}S%Awfn=sVL|h_yK0-!Vrz|@YUr{m*MeNNy!4c%?5f_tq2Jbya5gbE^8I} zbbYm4WYvMmtcS=_9O9e^TOTfjva&U*$;r_2s7p%oanw!trl(t(o99st4{Dtj?%eTV zL~fqt((7*>+s+GVG|mL@$eq@**v698TcXiOVng9NTivee0|SFDL)D{?VWpc2uu1O> zc&Geu>HLKr^bE0M9iM*uW^wU)SVRO#Q3NR^1BphbrA0`m0A$d@??G4k#&8JRv7;Vu zefPNQ$7?_JAh>n{{U*XOeosx^Q+g?#h74*FQAm;qi;F1`5E&hdj{DM?HsGZ_ey09MZc&vRg2RfwmB z2=w*epyxs}XVAza_;MbobZ2yKw)D4&+cwKeYL=pDz%xP}0|9?fIn(i3RFW0cA09@= z16+Ss?=u3=doo(`eyE%dhp(}z(KL3`A2#NULP>D}Xc!$hdIy8fD~{TGKHujw!;)i8 zXA`2n`oC%XJK7d>{PT>#c<}*i{#7-jdj%!Wfc8~r;s34wOMn3Y*EgJK6ii?p00000 LNkvXXu0mjfnWFNZ literal 0 HcmV?d00001 diff --git a/icon-256.png b/icon-256.png new file mode 100644 index 0000000000000000000000000000000000000000..0916f5734ed4474cfe03f4a496836ac3cb11eb8f GIT binary patch literal 98347 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

d*qGs2OXG_z~}TNeSxWgAp# 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 N002ovPDHLkV1g8}tnB~* literal 0 HcmV?d00001 diff --git a/images/baddyguy-sheet0.png b/images/baddyguy-sheet0.png new file mode 100644 index 0000000000000000000000000000000000000000..e6fa417627ab35c8677174898bd140bb5f683add GIT binary patch literal 868 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 literal 0 HcmV?d00001 diff --git a/images/nevir-sheet0.png b/images/nevir-sheet0.png new file mode 100644 index 0000000000000000000000000000000000000000..ea514c0bda0ace0b9f67f407ac78c4e17a4dfefc GIT binary patch literal 11622 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 qzW literal 0 HcmV?d00001 diff --git a/images/nevir-sheet2.png b/images/nevir-sheet2.png new file mode 100644 index 0000000000000000000000000000000000000000..a8b1490f13729d0c70b4dd0072668ffaa6b632e9 GIT binary patch literal 11300 zcmbW7Wm6n%tcDj~e4!K;DXzucU5Znn#eIPyi@Uo^DMgFB6^BKOyK8Y4E$;5;J?AH! znI}(@Z<$PHGIQOD`mFj18-oM`003Ys$jfN_=gt4ufT;idj$6rJ{&UFRBvm8-#`x-I|!{{I<5EOiSS0Khz;AS3z3bNQs*+A(Xvi~hcS&-cjCiQPSLgZ@W8 zz_y5my^ggU;;|)gdV0wDCAnEtwVYW|yI82q)w0|t@e5LEdijBC>WO<1_q&R%#drqZ z57g-_FpEKT{lb&QIu;u=+8@;D_>?fr)t8k?!L#S)jr@M{m0IP-;F3ea$kx85%)9oL zD=|3Qu^Ca@Vn3UEZH(dnC%lkDGd#mI3G7-hKnv;?e#_3vdly)$!g_gq-A>hdiJc~y z+WGy^?Ld3w%kzft%{1I^(Zo4X&CgLKzN*K_9!0C0HKVM%JMA<>^X&oty1d>PfA3~7 z*0#8j$1?u}<8b z)G-!9S8YF&*v)!GoHjbs0Fwzx7tfU71$F9g{hPF(-#*L{mvRCaN6iwL@H3bs`Its- zX+Qq?3OsVxm*=16K|N;$HA|N;+Iw)SLf3xh;YwV3d>HgH88j;V54 z?%kJ5{sX5`jj`hwI|*iTdS=(u-)o0leiepgs1(IfEOit`$f0H#aGnJM)d{GMQQhaT zPiPfP(oFSJPL``!i)7OJ!qYVeVGk-6AnNmr?HIGiMOxJ?RH2)4w)jfo3LhjC)hxv? zTV+HGU=P)ckhhZ<*Zu5*P~$9Q)$7~GMla;F?S-LexJS31!RV^%;?89U+f6cOod=fD z#HT6jnm;XJ|J*+)BnGDEX`*CVgY77FIBZ!BCX5ym=&B+DSXjomZDM?@W;hzlWW}0< z6em^=kpY?^gIFZkArOw_J8~X@WsXwT*G2c;K8hE&+&Uf_e8vJdp`?EiI;3h`Jl`8p2voFV22h$ z*c@R0x_jYWb+?WCmKvb3isRC6z!ssE;`sOP&R!7!U7en4$daisuj)tnlEO?}c+qm% z@Q6ijda*PXHxPaFN+fC2BI!}_+>oMQ3PA>W#c9gAv1{4H7J?~9%Ge8|8FD7O8&94~ zmt;^Ki{zf1+ugBBCaQ^?vCIGjL7OM);kp}3ErRsEXHzbgJ{$2mQFqN{XC)(iA7^QK zkU6c8KvK6N#+Rmqpw_D-Tz{GHD{xd2-|l`znY>kskI!vH1#;+3HJ&7+geQb|14z5Wi9g23{;N@< zY+AD~==h2ToYD(P&*KVXjGwmQ0fkY;a!v`&_N2KHHoUhgT6a~*qR`!aeTj-%VWS{X z982eR`|)MPb8u#6w7mz)`yI9X`BX~Xn`Rq{G1-@grkYD=>MlE|JIK#(7o(2lg!LaU z+kM>?Isy|=w|L6VZOVqn)D1B(NQp>WLI#`#mTu7q-)@orNwB6xv_i@Yt(;GwX9E9g zINP%Q@dK`!WpiJAH0Nb02dK{#pAENwHG&?8?G)EqUFQW+T6(2fp9_B zV@bM(`1Y>L6T|Jv;C%=BjEOuQK#2Jsq#U zzIlr{$9Lbj%~liAV&0RN<~xw82NrGNn_9*Z&rKIQ-n%N;wINRK_K!V*hd8%{GDc4y zxKEw9|DZ)DxHA*~uadPW;DEe&daxxDJ~9;wOX9hU;Aeaq1&z7Cd{jlDmX>+0_!b8# ztmE1kVgVh$FYwpyT6P#}<^HNoa7tim)|{V{AaRHY9z0KY-q`)f`~ z{q(-iel~%x|3SMog`NpS`_Vz?Z5EeTLoHT@h%ifUweeh$crsLI6%d(r?}l_mVHy?~ zicIE;RHOJ{>t0X@t)y+7fEI{0p`7QU=%pFk*ANl+<>~D?fUP|ih!RK)vi!y&j5#(w zo_=HrvZNoIz_;uS81iBrQ&Wp+VsEn8rp#o2rRb#ee_LGdRmizf<4MOA)YTiaW7u%V z;7f5_lj_i@H1ma%$DVxnRA4li-aoroHLw0L+3EZ|E^V<5ts_VJS8;;IR`NXKSsy!f za09JLpj1a-GZ~c|nY>bPBmglIIri_+7C}biIBoRSU^vF%cih$b7kn`k4!CXB!(}D@ zXjFGEcF2-~m=mIzjm?khl8C7?G>QhHr_`N|=ijFPj?p+r#>QgPe(4n+L@=8@tiT5j z4%*5wKjEy^8G_DEQu;adr#i%dI}kLdf0WEijJR4H{@dh96&C+>4*I(q(gurL9^gA{ zI&5+*sFv1%LCDcLf~Y;oc=w_W760driSb%dIp-YU|UU15z)A#Zwcw? z#C6ZJ@pLY#^?!b=W~T81j4J3$Mu**AU#&SkvA&2HQUTI*e7}er`hP0R>TNTFKkUhN zIxL=9IvO7X)c6xb;9&_b;H=E9*Iu+K8$QR!2clZTm2eG`{(RhIS}S|QK9qM|PT;UD zm7%@MDJjD;SSSc2Wq_`|kv&Kd9hSZ4=&;i>5Gdc}1a%cQbj>hq?x~d;C4W)tyk%dn zyUV_Z?s2M9s<7$8{>dNGu~@*fFzUll&abamZ@7o%=BUFe6ZLCYjcu8Uy^FIi$6^J8 z-XQ{PG^IsEMTgUj3pH`ILba_wZyM6@=pYT2bXoCW5eCth)Wtx%>PNR7ob06(7@VMElT=gyUy>m|~Kjmk} z{Z6JniK{QPA;2?$w1sXB@8Ij1m5_7&AZkw1m9C*0jxJ1_-rHcxnme-CX}l_Iu+@Jm zlq1wQAfO|;wZFLQHbawF=m zI5rGvbdnV}2{62YGbQ?3hCn z@p7cEi&dDAvE-WhQDR{#7M1B`o4h~sfr{K#b|5(f9mNHwKLzSgdinHImkQ5U(I#G! zD*!4#+Dm@rPHC#VGHdyfkwut-+{~gB2J5@5`tl-JSs|NfZDy{Ez&F%MUS&JSSptU^ z1vO8qgR{S~;WMN0)AXwNrE{F_dZ9TLBV5oE%4qJsbSeCjMT0eo0;5k;2R&9{ul_+u zXwX$xP4rLp<<#2FAdmOX{-k5r?VhbsH%cTjgpcK3U~s4@03TligCJUVCk91cNveX} z*t#J+2!WPL0bj;+ju|AMkm2%&HtNoXZ(c5!U=2C z91B=K(!K@u%bw32BVJuM^gRo5nk2YjlUWj?qDJ##k;*IOekNeN!(;i8H>)~zVs)SW zeKU{i@gtv+NL%=)4lhFWwC;NJvo;5O4+_!Hl{1nch`#4$Kigp(mcq!n9|9F{EY`gq z1wT~7n7HFiTJO(FN(u^f*994{MH7|VyB}e6EMZt6hkM~%IreFfmm4_i>nCbXSpOXS zoJ!9t*H#4p^P$It@XR0YXe_-)O#^VaSU5@wtGq)B9rr=0p<^9~@gxuuTXLi!Kmb&L zNrt44h~~7dAJ8XJ6zNFkZSXWm3`ClOK6N}Ax&{*%P4q5Wp)|pr0q>qFYPyHG!uDGT zg@S^d3_uEu7E{)4d2!)M&V!WrmL)8F%Yoyz>};GrGyJR3sWw~pK!DFZ;Pl}|Cpvxz zC0bW$s4%Q38m4hS{{1RhVWtu5>>7k*xTfxuH0=AE%7~6IfzV_na00M`2PPq04Cs<| z8eOe1&#*O$~D?R-u#KOV0~dR#I2@?b_6WL354CwEMSOt zLzJB)Gxj=D1iO-HWEEQ-y>w5FW8H#6!K_u%a zQ4mOwU-WLq+Z*a`G+ixnzpTw6UX8F1|Kel&V+|fkz*GgS+s6eJC}a_9=>0JY^EMp;BcW2t2LgjbLAj}#0Cvre=b=n;D}VoA026P^L@#^7P$M>c z@lZ*D9NaGqG26b)48F9=)D3uL(eGEvv)D{D)Y;7;mX>k`ukDu{6i*bdX3RfY>97+= zqnnwbtN=bh3DyX>LzZy|#o#-@5?r*g6dI&R9^nA)-j_$w02W3Cb4rMvnNDVN;e7bG zc}|7)bjOW~#^W3x9`#-*4zO~huhZEOelpJ5r{3UVB=^f==*!=gq7;Dml}si~){sd^U| zk-^-D2Wuzj-p1YdI1}K0R{RC~O+P}({>nYK-qRZt{=|#LIre^{tjW#;CNCKn7J3O> z=Ewyv1LD4z2vf=!#`*F~PE5G(|M<{?uJ1@jBprg0BF{OMV`?kh-LFIiBPCw8j^-GX zR74o`0017O5EK%rhc&G1D5G?~IsIFjK;dw(p}N@>5fJ80KlAr$8CWSi&W6;;B6SR|Ikv8bF(yGViu7&+= zT_^!(wZLvN_ofzlV#%*usLiwSO2`d)m^{%UH5#2Xve|#7~)?vyI7yjf3_g!U-%t!H-9?{ zwl5UUswQ~@l(g)+?jcw~wCqIUrj`6fMU9}!`@216^JRM<&W%XDtT0wibe5LaD3?OJ z4{Otb+vHE<0LDv8@c!-)vMsL+6(K~Y<4(F$HpnbufO2D4h5?q%RWXb>x(VKvYJ#sv zUt`Ft8`0jGLq*77y!ET;XqL`n6uE6D>H$p~d{9{R zx}mbWP@0)Uh6fQ0351y$6eiU!V_c%#&*7&i;9D+RbBrD89~o%OU8O`N(EY=WovppT2GS~Z_= zsG^Uo@~}~`!@a(a5RiNh;*`vvamOs)>0-Liri%?l=z>zZe*{*(Ph^w>hnrZ`{I%Zh zx5WNFpQ`>TP{cr9O)7mm@+@>GJMd8_V)Ok<0&BH$bT(&?ipiVh|mAHe6?L zxTxNd6-)UUSRV_IqSUc7aQaJb^0a6=7lF(b2)TID7m0y5l5gqcNQ$-^r{Qdv+SevzRA~ zMjtR5#-|<1Ulo(v!!GcygBc-=CU~UTQiQEAC}njRB@l#csw7eBIND!E8K3>x={5yW zZ02McOQW)GpSdYa}RvXN~CKfL@6KJ8EARB~?Zj+_5uiUF9(no&|oBq{Kn{qZRIPmu1 zp~?mr)DP(Fd-2v}s9>)X^nT}|r4jvDF{cpP9Ny|p+&)Cub6rS@ikcTyyKV#7-Qwf2 z4@QN7zG~MVF!2bfSn&ySV;+OiQV4n!{o?m)=k+{^vTRZc{FaA$?bkgLWoX6$R#Gh3 zBtcSS#LY7UfwK`bA)n4QBi18?2jaI@l;C|a`jZe*gNP*j?4#}k$xy&(79f+8pn|Nh zgGS9ig@Kr=aq^w|)$Z|o&dH8;+c&3(N(zAp4vBB;?iI0+#j1`?8aoq zv+3{+pOk(Uc2XHh8eS4pepyIMoC{nq=4ZeS$Lqi9SCUE57lK5A@a@)wR9$WA8k#Sk zfG;QWC#&9MTEl6Ic^Y+(Xm|OG0m$~7z}PeihSL0L$7vhuo!=tsP8%op55lh~r^4r& z0#gB?kQeFmM}q{9hhmgM8c7sNRyyD_fGUE8xB9!#!)&sz#qfL>@&bZ*bHv!#=XO{6 z!F~fVUIbytu0e&!3e1WfmzLy7UU2FvzK&wlr{-t5%N{B za%e@Ga5eNef&mes$p^u+<2XC(wH^joN%1$|lW^~FahCf>OdGZ(c~(ePNRO-r^dozK zYXHYf9D5ScSm9eZ`hjAD3Mr}OhcEP=tVDBEHHX;6&`DHXM3^1TtghC~=>bjuA>0l1 zmW|fO{umJO5Uui1P+{+Xj4Fr#gpcgXn%yjQ#9zkSvx_`n{OIkOkLM;*tPq5vZ-NBR zH}wVYQ_$*wlAO{ai{Tf)Hmbr^@FDvV*cA*~KM`T$@ryVNvbp9?0T!ziOsiUzp7R}b zYCRVTO^>EeV$k%EQ+bdvauSLKkIfQ&wv|5-S4yNxY}hULR7&{SZf+|H6o4;0@~Ol_ zRSC0j7qIy;H`jm<(QpAow9#aYCshVG=3Up=&^=O6(6A?O!KP8%n*UEq*5+<$%dP zzK3cINdMyE;Q}qypqMCiB_ae7E*g7twaou%HqOEa@F`B1!k-4J<@au-4x%c{Yz-G|I2&^bq zN|Gx%q`Pn&>q;*Kv#kxW?Fz0 z>}NFippjEfF0ys5AO7ddv20>|moqI3JlMguAw&gQRkgKsKqoW4E>gHb__>%1U#13v zHU)s8D_Ykm`~2oWqCHULE#ak6;mOy^cmDNP?($X%{vZ3g7h8Qing+d2eI>;6WU;4p zW{x4F;mLrB=1Y@a&2BY%6XIpq*@`}e8yr2)k0=qT8SCkW?}Cprz&+Rn1z`74umr+O zU0~vNFN~E|FYoJ_+|5;Eb%oNJxO>P})T0~$Yu0+-Ry~oUby1j%Zp{aZ6bqVB4Od}1 z*Ipc2+S`8&jz2x#l}n2E?1IOO_!9L{*LY3lNySVVJPcj{a^ODqk4H{69STh z3ew6d7Zq}u^>-r$xUq+A{uWh`*K7Xl`*bz``3vWi=$|`(^z~2l!y}$JIKH6bQN?Sz zhGd(UtVMys^+W?;usX+o%$S|eUE*TbTVZV0u%_5;}ZC zmm7;-U*f)p$Vn9OP0SEO(@9#LqLo3vWrDjBWH{t#l+BXJFn{_yIbC5t0Ts$>8lm>g z<ssYy9AwyZcTlgwg1fBf}o*Q9uM zA3Q$Bi6?uv-gdUae{;h>S#AI8pH@X;xvPnpZ(pU>rTGeBS`cHj`oXBFd4tW`QH#&( z5}HHi<%sP&q>z!nwQ-&_vVL?D->yUo_shQO2>nN)wK)>_Kn&PGe6S^E3ODiu?1vn$ zYa&>yiGj`n^;@ohMZr(yrT)BfAD;)%y2rNu=CD&HGig%?p<0!(0deg1X%S}Y%l&S4 zLF!m_>0z}4Mes5;CNF+%rG8;tE%&MY{Lf=Gqaus6;wDtP#Fwu#WW6_jvh1Vf68$&ehGUqGqP}liEkV+Z;Rzf!#8c^uM_I z5#a}IyHg|myT3?fmnu~!E-RApVTX2oPQktWI9s>+48D$!@i*hQb{`88j|BRgy$DZY z)Fk*x&aVP(eQI9RcTPZp(^4Qd1X6gI^_&S=l#I|6R+2^-Qk0Yp7|KP9Q9AhXRQhiE zVg*-BWc4ju{|R%ROcwHq4|dhkJ>BkjiQKu-Gr1SSh}A};a+PH5ayJ7=U$Ri>`@&f`?vyJ}Nb+Qk>4C24b)ZvLK*tm5LQ@2igICw%)o8b5l zvZn?jPi6~x998l|6_~~>E5ig-Yg^`nlaNOf!NjNaET-WNrdFt1T9{6Yvdfi0E5znF zjB3i=q~eHFygl`B3D*PJv|9|uBezY(>+p41X~!iwGvxeOJadV~c{#?l`|m_@IncEm zTP3&(#aV;axVX5q{+-px-Fqd$B-F=get|S=LhHxHb@2Uaybj2-MjcNxCdRVl=jM^t zEn-)cZe%w}pNXA1mYKZ3Jf4l6^%BJ{%kOS`R$Td#<-G206_@{1N1e2tgJFe%)vrW3 znVBpE&JXP%b2Q1&n>f_J{J*UDkX(hR@)?7Y5MgvvR^dxUN;kIy?qGA4I18j1_Fhs^ ztbj?@z#6>D&QS9s4TqF1`2;!yYe^kG=wSE>$OKPAQa-9H-jy59=11~f_sQNXFNN9Q z(Z1mIIemOLtgyuk!Fo0Di1hlqp!1oe!~W@aHj2lwZ(@gr_H^G7!I`VR5M?Y|%@_mH z&@yb*UuBSte`SwC5!8IOU+BdR_&y#wu2iH$8mR`7MQ@x1XZNkv8w-b!k|vYn_#>xJ z27tZDS*nq$3=)a7R&LbevG3L>ACztXTmZiT+cU8dX_h)d8{ElfoIj^EqrC1@$@8O0 zov9-+u_h#Zro|%;f*}eKCxGQJc82i1o`%k+h9`&|QjlWq$lEzvoy<#*mR<3jzTsJW zk`x)tRwf;N;%<8|Wf=c+0-<7IJ#^QUt(+@M5);bm*{yx;}|Q)@

TYTPiWtk!l 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 literal 0 HcmV?d00001 diff --git a/images/sky-sheet0.png b/images/sky-sheet0.png new file mode 100644 index 0000000000000000000000000000000000000000..ad061c3ddc60c25ca715abcca925d3313008a240 GIT binary patch literal 10326 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 O>g(#-R|~ILJ^3HGHPv4L literal 0 HcmV?d00001 diff --git a/images/sprite-sheet0.png b/images/sprite-sheet0.png new file mode 100644 index 0000000000000000000000000000000000000000..84a6275304b32d51184710c1da74a91e116cbb9b GIT binary patch literal 168 zcmeAS@N?(olHy`uVBq!ia0vp^zd)FS8A$FoTE!2fm;-!5T>t<7zx;^w2_ToTB*-tA z!Qt7BG$1F~)5S5QBJS-0Lq;I)kizff+YaYNumIU)1DUUK42*vtG5i6U;OXk;vd$@? F2>>|yAjALw literal 0 HcmV?d00001 diff --git a/images/sprite2-sheet0.png b/images/sprite2-sheet0.png new file mode 100644 index 0000000000000000000000000000000000000000..275beb895f002cbffbe8b52dd5514335fbeea68a GIT binary patch literal 662 zcmeAS@N?(olHy`uVBq!ia0vp^zd)FS8A$FoTE!2fcmjMvT!HjEKJRyYUO*JFE6NVY zXDJEt3uf3?cW+ILoHhdklc}eRV@O5Z+gpZx%9aAGfye%T-~U-EyP&ZsP0_UbvgCR3 z76+|J*2dTSRXislqeJ^Q@p-P(w4clOnr{Q&;tOd>RSjbI`uro;bG%*swQK>eFLfE5S3M)I z%F1kRT1Hie|JVC7@^-z1%B59VeY+nqYvD`9>?!Jj`{MR$A>^kS@Vsrh`QL3{qfpD%ueWfc2Y z{r(ucuIB4oo2Q?yKfN2b?`Lh}8s|;V%bvW7ymjYOmh7pM=Yvn|ekpBh^<8v9O*zl^ z^R?<`<#%r9^#9Luns+=ca`{CWd;JGLH@RFZR9vpl6kv9$id)9x|AVCOXP4W&&KEtk z;Y;tNg)bNKc;COZ@uf-d}>PNzlH~XQ)Epj|#vX|5|O!~trv5%#_3Yef6JYD@<);T3K0RTLv BJO2Ox literal 0 HcmV?d00001 diff --git a/images/turnleft-sheet0.png b/images/turnleft-sheet0.png new file mode 100644 index 0000000000000000000000000000000000000000..8a5f0bbac5fd727504699f7e1b5d91b9eabe83cb GIT binary patch literal 367 zcmeAS@N?(olHy`uVBq!ia0vp^zd)FS8A$FoTE!2fgaUj*T!HjEKJRyYUJ&%2&r4y_ z`mI1wwvr&fV1|A7>fU`jJ8g430|O(Qr;B4qMcmsP7jusq@Gv_B7k!K0ncwh7gq3T{ zp4$xxGAHfqLB^wj1Lx*?W`22o?#;?6C+~PB|MD$*|DU-z?p4P{`_soCq znf=~4-Mjkyn@rh4>zh~BZJ9meU1?GN+miEN{Jx)^8=Uq2Zm`z*IrrY|-Fshs?`q$- z%~#WQ<-gB7JFnk9;>Pzq^|xj|_uTZ~=2!Hgv$b5)Zk=7d^ZU$Vt;6SYGGk8zwd&CJYD@<);T3K0RWAon$rLP literal 0 HcmV?d00001 diff --git a/images/turnright-sheet0.png b/images/turnright-sheet0.png new file mode 100644 index 0000000000000000000000000000000000000000..f8433f74a05c0dbeb5a4ec6aed280a1124a7ed6c GIT binary patch literal 416 zcmeAS@N?(olHy`uVBq!ia0vp^zd)FS8A$FoTE!2fL<4+6T!HjEKJRyYUJ&%2&kKka z)-9C+O0bs%`2{oVtGoB^+b>W16{i>&7>zw$978JN-rnAr*X$s`5|AeT{J*`WqTgdK z%c)B%{hQ7m&EON8|3HHss2u|wICC*;`<73(`_G+wVkw_)W$hnyt5R+4Tz|8vbKk4Y zJa(?$=Vj@=nKhec`lLQy`u*F@xv%G(%KTTZXFPj<@!Xuu=f_j#ef+I5b@ks#Th#V1 zTK?td){mO!?7!TqzT@{YVfLB#ff|)^v1h(`E;Ighuhgz`Yh^j}lOI0S_e$rT?JnQ; ze$#yETDkr^H}2>(&%R&xY2WX;mjCA0+Es2b71}%TMXJmEoa`?-$BOcms+2EEciwaV z;v4iU@5$-7+2*X$_j}g9t(zrYXL8@;^K{?zip}@dY)_6>zk2=8Wr?y{q4}T6F}w>A ZcpyDrnptdRH1h-y-_zC4Wt~$(698B`uwMWG literal 0 HcmV?d00001 diff --git a/images/wall-sheet0.png b/images/wall-sheet0.png new file mode 100644 index 0000000000000000000000000000000000000000..3164c774c488d0891e47704d83bcb518754f3b98 GIT binary patch literal 323 zcmV-J0lfZ+P)0yz3~cx6V*$fvjd8}vw#K+baTt?r3T0>#%0wuWwpS+ph8cx&g%!Dm+kF8v?EydO V40t2PGy(ts002ovPDHLkV1j^dn;8HA literal 0 HcmV?d00001 diff --git a/index.html b/index.html new file mode 100644 index 0000000..5648e45 --- /dev/null +++ b/index.html @@ -0,0 +1,117 @@ + + + + + + New project + + + + + + + + + + + + + + + + + + + + + + +

+ + + + +
+ + + + + + + + + + + + + + \ No newline at end of file diff --git a/jquery-2.1.1.min.js b/jquery-2.1.1.min.js new file mode 100644 index 0000000..e150866 --- /dev/null +++ b/jquery-2.1.1.min.js @@ -0,0 +1,4 @@ +/*! jQuery v2.1.1 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l=a.document,m="2.1.1",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!n.isArray(a)&&a-parseFloat(a)>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=l.createElement("script"),b.text=a,l.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+-new Date,v=a.document,w=0,x=0,y=gb(),z=gb(),A=gb(),B=function(a,b){return a===b&&(l=!0),0},C="undefined",D=1<<31,E={}.hasOwnProperty,F=[],G=F.pop,H=F.push,I=F.push,J=F.slice,K=F.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},L="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",N="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=N.replace("w","w#"),P="\\["+M+"*("+N+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+O+"))|)"+M+"*\\]",Q=":("+N+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+P+")*)|.*)\\)|)",R=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),S=new RegExp("^"+M+"*,"+M+"*"),T=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),V=new RegExp(Q),W=new RegExp("^"+O+"$"),X={ID:new RegExp("^#("+N+")"),CLASS:new RegExp("^\\.("+N+")"),TAG:new RegExp("^("+N.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+Q),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+L+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),db=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{I.apply(F=J.call(v.childNodes),v.childNodes),F[v.childNodes.length].nodeType}catch(eb){I={apply:F.length?function(a,b){H.apply(a,J.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],!a||"string"!=typeof a)return d;if(1!==(k=b.nodeType)&&9!==k)return[];if(p&&!e){if(f=_.exec(a))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return I.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return I.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=9===k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+qb(o[l]);w=ab.test(a)&&ob(b.parentNode)||b,x=o.join(",")}if(x)try{return I.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function gb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function hb(a){return a[u]=!0,a}function ib(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function jb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function kb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||D)-(~a.sourceIndex||D);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function lb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function nb(a){return hb(function(b){return b=+b,hb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function ob(a){return a&&typeof a.getElementsByTagName!==C&&a}c=fb.support={},f=fb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fb.setDocument=function(a){var b,e=a?a.ownerDocument||a:v,g=e.defaultView;return e!==n&&9===e.nodeType&&e.documentElement?(n=e,o=e.documentElement,p=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){m()},!1):g.attachEvent&&g.attachEvent("onunload",function(){m()})),c.attributes=ib(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ib(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(e.getElementsByClassName)&&ib(function(a){return a.innerHTML="
",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=ib(function(a){return o.appendChild(a).id=u,!e.getElementsByName||!e.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==C&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c=typeof a.getAttributeNode!==C&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==C?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==C&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(e.querySelectorAll))&&(ib(function(a){a.innerHTML="",a.querySelectorAll("[msallowclip^='']").length&&q.push("[*^$]="+M+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+M+"*(?:value|"+L+")"),a.querySelectorAll(":checked").length||q.push(":checked")}),ib(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+M+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ib(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",Q)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===v&&t(v,a)?-1:b===e||b.ownerDocument===v&&t(v,b)?1:k?K.call(k,a)-K.call(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],i=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:k?K.call(k,a)-K.call(k,b):0;if(f===g)return kb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?kb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},e):n},fb.matches=function(a,b){return fb(a,null,null,b)},fb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fb(b,n,null,[a]).length>0},fb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&E.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fb.selectors={cacheLength:50,createPseudo:hb,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+M+")"+a+"("+M+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==C&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?hb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=K.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:hb(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?hb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:hb(function(a){return function(b){return fb(a,b).length>0}}),contains:hb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:hb(function(a){return W.test(a||"")||fb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:nb(function(){return[0]}),last:nb(function(a,b){return[b-1]}),eq:nb(function(a,b,c){return[0>c?c+b:c]}),even:nb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:nb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:nb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:nb(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function rb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function sb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function tb(a,b,c){for(var d=0,e=b.length;e>d;d++)fb(a,b[d],c);return c}function ub(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function vb(a,b,c,d,e,f){return d&&!d[u]&&(d=vb(d)),e&&!e[u]&&(e=vb(e,f)),hb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||tb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ub(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ub(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?K.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ub(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):I.apply(g,r)})}function wb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=rb(function(a){return a===b},h,!0),l=rb(function(a){return K.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>i;i++)if(c=d.relative[a[i].type])m=[rb(sb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return vb(i>1&&sb(m),i>1&&qb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&wb(a.slice(i,e)),f>e&&wb(a=a.slice(e)),f>e&&qb(a))}m.push(c)}return sb(m)}function xb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=G.call(i));s=ub(s)}I.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&fb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?hb(f):f}return h=fb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xb(e,d)),f.selector=a}return f},i=fb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&ob(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qb(j),!a)return I.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&ob(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ib(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ib(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||jb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ib(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||jb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ib(function(a){return null==a.getAttribute("disabled")})||jb(L,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fb}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler("ready"),n(l).off("ready"))))}});function I(){l.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),"complete"===l.readyState?setTimeout(n.ready):(l.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+Math.random()}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b) +},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:n.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthx",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\/>/gi,bb=/<([\w:]+)/,cb=/<|&#?\w+;/,db=/<(?:script|style|link)/i,eb=/checked\s*(?:[^=]|=\s*.checked.)/i,fb=/^$|\/(?:java|ecma)script/i,gb=/^true\/(.*)/,hb=/^\s*\s*$/g,ib={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ib.optgroup=ib.option,ib.tbody=ib.tfoot=ib.colgroup=ib.caption=ib.thead,ib.th=ib.td;function jb(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function kb(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function lb(a){var b=gb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function mb(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function nb(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function ob(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pb(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=ob(h),f=ob(a),d=0,e=f.length;e>d;d++)pb(f[d],g[d]);if(b)if(c)for(f=f||ob(a),g=g||ob(h),d=0,e=f.length;e>d;d++)nb(f[d],g[d]);else nb(a,h);return g=ob(h,"script"),g.length>0&&mb(g,!i&&ob(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(cb.test(e)){f=f||k.appendChild(b.createElement("div")),g=(bb.exec(e)||["",""])[1].toLowerCase(),h=ib[g]||ib._default,f.innerHTML=h[1]+e.replace(ab,"<$1>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=ob(k.appendChild(e),"script"),i&&mb(f),c)){j=0;while(e=f[j++])fb.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(ob(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&mb(ob(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(ob(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!db.test(a)&&!ib[(bb.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(ab,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ob(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(ob(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&eb.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(ob(c,"script"),kb),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,ob(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,lb),j=0;g>j;j++)h=f[j],fb.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(hb,"")))}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qb,rb={};function sb(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function tb(a){var b=l,c=rb[a];return c||(c=sb(a,b),"none"!==c&&c||(qb=(qb||n("