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 0000000..bf56364 Binary files /dev/null and b/icon-114.png differ diff --git a/icon-128.png b/icon-128.png new file mode 100644 index 0000000..523ffd0 Binary files /dev/null and b/icon-128.png differ diff --git a/icon-16.png b/icon-16.png new file mode 100644 index 0000000..e1b785c Binary files /dev/null and b/icon-16.png differ diff --git a/icon-256.png b/icon-256.png new file mode 100644 index 0000000..0916f57 Binary files /dev/null and b/icon-256.png differ diff --git a/icon-32.png b/icon-32.png new file mode 100644 index 0000000..02edf8c Binary files /dev/null and b/icon-32.png differ diff --git a/images/baddyguy-sheet0.png b/images/baddyguy-sheet0.png new file mode 100644 index 0000000..e6fa417 Binary files /dev/null and b/images/baddyguy-sheet0.png differ diff --git a/images/ground-sheet0.png b/images/ground-sheet0.png new file mode 100644 index 0000000..b27e489 Binary files /dev/null and b/images/ground-sheet0.png differ diff --git a/images/life-sheet0.png b/images/life-sheet0.png new file mode 100644 index 0000000..9f84e04 Binary files /dev/null and b/images/life-sheet0.png differ diff --git a/images/life-sheet1.png b/images/life-sheet1.png new file mode 100644 index 0000000..50fc130 Binary files /dev/null and b/images/life-sheet1.png differ diff --git a/images/nevir-sheet0.png b/images/nevir-sheet0.png new file mode 100644 index 0000000..ea514c0 Binary files /dev/null and b/images/nevir-sheet0.png differ diff --git a/images/nevir-sheet1.png b/images/nevir-sheet1.png new file mode 100644 index 0000000..52120d5 Binary files /dev/null and b/images/nevir-sheet1.png differ diff --git a/images/nevir-sheet2.png b/images/nevir-sheet2.png new file mode 100644 index 0000000..a8b1490 Binary files /dev/null and b/images/nevir-sheet2.png differ diff --git a/images/playerbox-sheet0.png b/images/playerbox-sheet0.png new file mode 100644 index 0000000..61edd7d Binary files /dev/null and b/images/playerbox-sheet0.png differ diff --git a/images/sky-sheet0.png b/images/sky-sheet0.png new file mode 100644 index 0000000..ad061c3 Binary files /dev/null and b/images/sky-sheet0.png differ diff --git a/images/sprite-sheet0.png b/images/sprite-sheet0.png new file mode 100644 index 0000000..84a6275 Binary files /dev/null and b/images/sprite-sheet0.png differ diff --git a/images/sprite2-sheet0.png b/images/sprite2-sheet0.png new file mode 100644 index 0000000..275beb8 Binary files /dev/null and b/images/sprite2-sheet0.png differ diff --git a/images/turnleft-sheet0.png b/images/turnleft-sheet0.png new file mode 100644 index 0000000..8a5f0bb Binary files /dev/null and b/images/turnleft-sheet0.png differ diff --git a/images/turnright-sheet0.png b/images/turnright-sheet0.png new file mode 100644 index 0000000..f8433f7 Binary files /dev/null and b/images/turnright-sheet0.png differ diff --git a/images/wall-sheet0.png b/images/wall-sheet0.png new file mode 100644 index 0000000..3164c77 Binary files /dev/null and b/images/wall-sheet0.png differ 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 + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + +

Your browser does not appear to support HTML5. Try upgrading your browser to the latest version. What is a browser? +

Microsoft Internet Explorer
+ Mozilla Firefox
+ Google Chrome
+ Apple Safari
+ Google Chrome Frame for Internet Explorer

+
+ +
+ + + + + + + + + + + + + + \ 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("