Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
mamayaya1
GitHub Repository: mamayaya1/game
Path: blob/main/projects/craftmine/c2runtime.js
4625 views
1
// Generated by Construct 2, the HTML5 game and app creator :: https://www.construct.net
2
var cr = {};
3
cr.plugins_ = {};
4
cr.behaviors = {};
5
if (typeof Object.getPrototypeOf !== "function")
6
{
7
if (typeof "test".__proto__ === "object")
8
{
9
Object.getPrototypeOf = function(object) {
10
return object.__proto__;
11
};
12
}
13
else
14
{
15
Object.getPrototypeOf = function(object) {
16
return object.constructor.prototype;
17
};
18
}
19
}
20
(function(){
21
cr.logexport = function (msg)
22
{
23
if (window.console && window.console.log)
24
window.console.log(msg);
25
};
26
cr.logerror = function (msg)
27
{
28
if (window.console && window.console.error)
29
window.console.error(msg);
30
};
31
cr.seal = function(x)
32
{
33
return x;
34
};
35
cr.freeze = function(x)
36
{
37
return x;
38
};
39
cr.is_undefined = function (x)
40
{
41
return typeof x === "undefined";
42
};
43
cr.is_number = function (x)
44
{
45
return typeof x === "number";
46
};
47
cr.is_string = function (x)
48
{
49
return typeof x === "string";
50
};
51
cr.isPOT = function (x)
52
{
53
return x > 0 && ((x - 1) & x) === 0;
54
};
55
cr.nextHighestPowerOfTwo = function(x) {
56
--x;
57
for (var i = 1; i < 32; i <<= 1) {
58
x = x | x >> i;
59
}
60
return x + 1;
61
}
62
cr.abs = function (x)
63
{
64
return (x < 0 ? -x : x);
65
};
66
cr.max = function (a, b)
67
{
68
return (a > b ? a : b);
69
};
70
cr.min = function (a, b)
71
{
72
return (a < b ? a : b);
73
};
74
cr.PI = Math.PI;
75
cr.round = function (x)
76
{
77
return (x + 0.5) | 0;
78
};
79
cr.floor = function (x)
80
{
81
if (x >= 0)
82
return x | 0;
83
else
84
return (x | 0) - 1; // correctly round down when negative
85
};
86
cr.ceil = function (x)
87
{
88
var f = x | 0;
89
return (f === x ? f : f + 1);
90
};
91
function Vector2(x, y)
92
{
93
this.x = x;
94
this.y = y;
95
cr.seal(this);
96
};
97
Vector2.prototype.offset = function (px, py)
98
{
99
this.x += px;
100
this.y += py;
101
return this;
102
};
103
Vector2.prototype.mul = function (px, py)
104
{
105
this.x *= px;
106
this.y *= py;
107
return this;
108
};
109
cr.vector2 = Vector2;
110
cr.segments_intersect = function(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y)
111
{
112
var max_ax, min_ax, max_ay, min_ay, max_bx, min_bx, max_by, min_by;
113
if (a1x < a2x)
114
{
115
min_ax = a1x;
116
max_ax = a2x;
117
}
118
else
119
{
120
min_ax = a2x;
121
max_ax = a1x;
122
}
123
if (b1x < b2x)
124
{
125
min_bx = b1x;
126
max_bx = b2x;
127
}
128
else
129
{
130
min_bx = b2x;
131
max_bx = b1x;
132
}
133
if (max_ax < min_bx || min_ax > max_bx)
134
return false;
135
if (a1y < a2y)
136
{
137
min_ay = a1y;
138
max_ay = a2y;
139
}
140
else
141
{
142
min_ay = a2y;
143
max_ay = a1y;
144
}
145
if (b1y < b2y)
146
{
147
min_by = b1y;
148
max_by = b2y;
149
}
150
else
151
{
152
min_by = b2y;
153
max_by = b1y;
154
}
155
if (max_ay < min_by || min_ay > max_by)
156
return false;
157
var dpx = b1x - a1x + b2x - a2x;
158
var dpy = b1y - a1y + b2y - a2y;
159
var qax = a2x - a1x;
160
var qay = a2y - a1y;
161
var qbx = b2x - b1x;
162
var qby = b2y - b1y;
163
var d = cr.abs(qay * qbx - qby * qax);
164
var la = qbx * dpy - qby * dpx;
165
if (cr.abs(la) > d)
166
return false;
167
var lb = qax * dpy - qay * dpx;
168
return cr.abs(lb) <= d;
169
};
170
function Rect(left, top, right, bottom)
171
{
172
this.set(left, top, right, bottom);
173
cr.seal(this);
174
};
175
Rect.prototype.set = function (left, top, right, bottom)
176
{
177
this.left = left;
178
this.top = top;
179
this.right = right;
180
this.bottom = bottom;
181
};
182
Rect.prototype.copy = function (r)
183
{
184
this.left = r.left;
185
this.top = r.top;
186
this.right = r.right;
187
this.bottom = r.bottom;
188
};
189
Rect.prototype.width = function ()
190
{
191
return this.right - this.left;
192
};
193
Rect.prototype.height = function ()
194
{
195
return this.bottom - this.top;
196
};
197
Rect.prototype.offset = function (px, py)
198
{
199
this.left += px;
200
this.top += py;
201
this.right += px;
202
this.bottom += py;
203
return this;
204
};
205
Rect.prototype.normalize = function ()
206
{
207
var temp = 0;
208
if (this.left > this.right)
209
{
210
temp = this.left;
211
this.left = this.right;
212
this.right = temp;
213
}
214
if (this.top > this.bottom)
215
{
216
temp = this.top;
217
this.top = this.bottom;
218
this.bottom = temp;
219
}
220
};
221
Rect.prototype.intersects_rect = function (rc)
222
{
223
return !(rc.right < this.left || rc.bottom < this.top || rc.left > this.right || rc.top > this.bottom);
224
};
225
Rect.prototype.intersects_rect_off = function (rc, ox, oy)
226
{
227
return !(rc.right + ox < this.left || rc.bottom + oy < this.top || rc.left + ox > this.right || rc.top + oy > this.bottom);
228
};
229
Rect.prototype.contains_pt = function (x, y)
230
{
231
return (x >= this.left && x <= this.right) && (y >= this.top && y <= this.bottom);
232
};
233
Rect.prototype.equals = function (r)
234
{
235
return this.left === r.left && this.top === r.top && this.right === r.right && this.bottom === r.bottom;
236
};
237
cr.rect = Rect;
238
function Quad()
239
{
240
this.tlx = 0;
241
this.tly = 0;
242
this.trx = 0;
243
this.try_ = 0; // is a keyword otherwise!
244
this.brx = 0;
245
this.bry = 0;
246
this.blx = 0;
247
this.bly = 0;
248
cr.seal(this);
249
};
250
Quad.prototype.set_from_rect = function (rc)
251
{
252
this.tlx = rc.left;
253
this.tly = rc.top;
254
this.trx = rc.right;
255
this.try_ = rc.top;
256
this.brx = rc.right;
257
this.bry = rc.bottom;
258
this.blx = rc.left;
259
this.bly = rc.bottom;
260
};
261
Quad.prototype.set_from_rotated_rect = function (rc, a)
262
{
263
if (a === 0)
264
{
265
this.set_from_rect(rc);
266
}
267
else
268
{
269
var sin_a = Math.sin(a);
270
var cos_a = Math.cos(a);
271
var left_sin_a = rc.left * sin_a;
272
var top_sin_a = rc.top * sin_a;
273
var right_sin_a = rc.right * sin_a;
274
var bottom_sin_a = rc.bottom * sin_a;
275
var left_cos_a = rc.left * cos_a;
276
var top_cos_a = rc.top * cos_a;
277
var right_cos_a = rc.right * cos_a;
278
var bottom_cos_a = rc.bottom * cos_a;
279
this.tlx = left_cos_a - top_sin_a;
280
this.tly = top_cos_a + left_sin_a;
281
this.trx = right_cos_a - top_sin_a;
282
this.try_ = top_cos_a + right_sin_a;
283
this.brx = right_cos_a - bottom_sin_a;
284
this.bry = bottom_cos_a + right_sin_a;
285
this.blx = left_cos_a - bottom_sin_a;
286
this.bly = bottom_cos_a + left_sin_a;
287
}
288
};
289
Quad.prototype.offset = function (px, py)
290
{
291
this.tlx += px;
292
this.tly += py;
293
this.trx += px;
294
this.try_ += py;
295
this.brx += px;
296
this.bry += py;
297
this.blx += px;
298
this.bly += py;
299
return this;
300
};
301
var minresult = 0;
302
var maxresult = 0;
303
function minmax4(a, b, c, d)
304
{
305
if (a < b)
306
{
307
if (c < d)
308
{
309
if (a < c)
310
minresult = a;
311
else
312
minresult = c;
313
if (b > d)
314
maxresult = b;
315
else
316
maxresult = d;
317
}
318
else
319
{
320
if (a < d)
321
minresult = a;
322
else
323
minresult = d;
324
if (b > c)
325
maxresult = b;
326
else
327
maxresult = c;
328
}
329
}
330
else
331
{
332
if (c < d)
333
{
334
if (b < c)
335
minresult = b;
336
else
337
minresult = c;
338
if (a > d)
339
maxresult = a;
340
else
341
maxresult = d;
342
}
343
else
344
{
345
if (b < d)
346
minresult = b;
347
else
348
minresult = d;
349
if (a > c)
350
maxresult = a;
351
else
352
maxresult = c;
353
}
354
}
355
};
356
Quad.prototype.bounding_box = function (rc)
357
{
358
minmax4(this.tlx, this.trx, this.brx, this.blx);
359
rc.left = minresult;
360
rc.right = maxresult;
361
minmax4(this.tly, this.try_, this.bry, this.bly);
362
rc.top = minresult;
363
rc.bottom = maxresult;
364
};
365
Quad.prototype.contains_pt = function (x, y)
366
{
367
var tlx = this.tlx;
368
var tly = this.tly;
369
var v0x = this.trx - tlx;
370
var v0y = this.try_ - tly;
371
var v1x = this.brx - tlx;
372
var v1y = this.bry - tly;
373
var v2x = x - tlx;
374
var v2y = y - tly;
375
var dot00 = v0x * v0x + v0y * v0y
376
var dot01 = v0x * v1x + v0y * v1y
377
var dot02 = v0x * v2x + v0y * v2y
378
var dot11 = v1x * v1x + v1y * v1y
379
var dot12 = v1x * v2x + v1y * v2y
380
var invDenom = 1.0 / (dot00 * dot11 - dot01 * dot01);
381
var u = (dot11 * dot02 - dot01 * dot12) * invDenom;
382
var v = (dot00 * dot12 - dot01 * dot02) * invDenom;
383
if ((u >= 0.0) && (v > 0.0) && (u + v < 1))
384
return true;
385
v0x = this.blx - tlx;
386
v0y = this.bly - tly;
387
var dot00 = v0x * v0x + v0y * v0y
388
var dot01 = v0x * v1x + v0y * v1y
389
var dot02 = v0x * v2x + v0y * v2y
390
invDenom = 1.0 / (dot00 * dot11 - dot01 * dot01);
391
u = (dot11 * dot02 - dot01 * dot12) * invDenom;
392
v = (dot00 * dot12 - dot01 * dot02) * invDenom;
393
return (u >= 0.0) && (v > 0.0) && (u + v < 1);
394
};
395
Quad.prototype.at = function (i, xory)
396
{
397
if (xory)
398
{
399
switch (i)
400
{
401
case 0: return this.tlx;
402
case 1: return this.trx;
403
case 2: return this.brx;
404
case 3: return this.blx;
405
case 4: return this.tlx;
406
default: return this.tlx;
407
}
408
}
409
else
410
{
411
switch (i)
412
{
413
case 0: return this.tly;
414
case 1: return this.try_;
415
case 2: return this.bry;
416
case 3: return this.bly;
417
case 4: return this.tly;
418
default: return this.tly;
419
}
420
}
421
};
422
Quad.prototype.midX = function ()
423
{
424
return (this.tlx + this.trx + this.brx + this.blx) / 4;
425
};
426
Quad.prototype.midY = function ()
427
{
428
return (this.tly + this.try_ + this.bry + this.bly) / 4;
429
};
430
Quad.prototype.intersects_segment = function (x1, y1, x2, y2)
431
{
432
if (this.contains_pt(x1, y1) || this.contains_pt(x2, y2))
433
return true;
434
var a1x, a1y, a2x, a2y;
435
var i;
436
for (i = 0; i < 4; i++)
437
{
438
a1x = this.at(i, true);
439
a1y = this.at(i, false);
440
a2x = this.at(i + 1, true);
441
a2y = this.at(i + 1, false);
442
if (cr.segments_intersect(x1, y1, x2, y2, a1x, a1y, a2x, a2y))
443
return true;
444
}
445
return false;
446
};
447
Quad.prototype.intersects_quad = function (rhs)
448
{
449
var midx = rhs.midX();
450
var midy = rhs.midY();
451
if (this.contains_pt(midx, midy))
452
return true;
453
midx = this.midX();
454
midy = this.midY();
455
if (rhs.contains_pt(midx, midy))
456
return true;
457
var a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y;
458
var i, j;
459
for (i = 0; i < 4; i++)
460
{
461
for (j = 0; j < 4; j++)
462
{
463
a1x = this.at(i, true);
464
a1y = this.at(i, false);
465
a2x = this.at(i + 1, true);
466
a2y = this.at(i + 1, false);
467
b1x = rhs.at(j, true);
468
b1y = rhs.at(j, false);
469
b2x = rhs.at(j + 1, true);
470
b2y = rhs.at(j + 1, false);
471
if (cr.segments_intersect(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y))
472
return true;
473
}
474
}
475
return false;
476
};
477
cr.quad = Quad;
478
cr.RGB = function (red, green, blue)
479
{
480
return Math.max(Math.min(red, 255), 0)
481
| (Math.max(Math.min(green, 255), 0) << 8)
482
| (Math.max(Math.min(blue, 255), 0) << 16);
483
};
484
cr.GetRValue = function (rgb)
485
{
486
return rgb & 0xFF;
487
};
488
cr.GetGValue = function (rgb)
489
{
490
return (rgb & 0xFF00) >> 8;
491
};
492
cr.GetBValue = function (rgb)
493
{
494
return (rgb & 0xFF0000) >> 16;
495
};
496
cr.shallowCopy = function (a, b, allowOverwrite)
497
{
498
var attr;
499
for (attr in b)
500
{
501
if (b.hasOwnProperty(attr))
502
{
503
;
504
a[attr] = b[attr];
505
}
506
}
507
return a;
508
};
509
cr.arrayRemove = function (arr, index)
510
{
511
var i, len;
512
index = cr.floor(index);
513
if (index < 0 || index >= arr.length)
514
return; // index out of bounds
515
for (i = index, len = arr.length - 1; i < len; i++)
516
arr[i] = arr[i + 1];
517
cr.truncateArray(arr, len);
518
};
519
cr.truncateArray = function (arr, index)
520
{
521
arr.length = index;
522
};
523
cr.clearArray = function (arr)
524
{
525
cr.truncateArray(arr, 0);
526
};
527
cr.shallowAssignArray = function (dest, src)
528
{
529
cr.clearArray(dest);
530
var i, len;
531
for (i = 0, len = src.length; i < len; ++i)
532
dest[i] = src[i];
533
};
534
cr.appendArray = function (a, b)
535
{
536
a.push.apply(a, b);
537
};
538
cr.fastIndexOf = function (arr, item)
539
{
540
var i, len;
541
for (i = 0, len = arr.length; i < len; ++i)
542
{
543
if (arr[i] === item)
544
return i;
545
}
546
return -1;
547
};
548
cr.arrayFindRemove = function (arr, item)
549
{
550
var index = cr.fastIndexOf(arr, item);
551
if (index !== -1)
552
cr.arrayRemove(arr, index);
553
};
554
cr.clamp = function(x, a, b)
555
{
556
if (x < a)
557
return a;
558
else if (x > b)
559
return b;
560
else
561
return x;
562
};
563
cr.to_radians = function(x)
564
{
565
return x / (180.0 / cr.PI);
566
};
567
cr.to_degrees = function(x)
568
{
569
return x * (180.0 / cr.PI);
570
};
571
cr.clamp_angle_degrees = function (a)
572
{
573
a %= 360; // now in (-360, 360) range
574
if (a < 0)
575
a += 360; // now in [0, 360) range
576
return a;
577
};
578
cr.clamp_angle = function (a)
579
{
580
a %= 2 * cr.PI; // now in (-2pi, 2pi) range
581
if (a < 0)
582
a += 2 * cr.PI; // now in [0, 2pi) range
583
return a;
584
};
585
cr.to_clamped_degrees = function (x)
586
{
587
return cr.clamp_angle_degrees(cr.to_degrees(x));
588
};
589
cr.to_clamped_radians = function (x)
590
{
591
return cr.clamp_angle(cr.to_radians(x));
592
};
593
cr.angleTo = function(x1, y1, x2, y2)
594
{
595
var dx = x2 - x1;
596
var dy = y2 - y1;
597
return Math.atan2(dy, dx);
598
};
599
cr.angleDiff = function (a1, a2)
600
{
601
if (a1 === a2)
602
return 0;
603
var s1 = Math.sin(a1);
604
var c1 = Math.cos(a1);
605
var s2 = Math.sin(a2);
606
var c2 = Math.cos(a2);
607
var n = s1 * s2 + c1 * c2;
608
if (n >= 1)
609
return 0;
610
if (n <= -1)
611
return cr.PI;
612
return Math.acos(n);
613
};
614
cr.angleRotate = function (start, end, step)
615
{
616
var ss = Math.sin(start);
617
var cs = Math.cos(start);
618
var se = Math.sin(end);
619
var ce = Math.cos(end);
620
if (Math.acos(ss * se + cs * ce) > step)
621
{
622
if (cs * se - ss * ce > 0)
623
return cr.clamp_angle(start + step);
624
else
625
return cr.clamp_angle(start - step);
626
}
627
else
628
return cr.clamp_angle(end);
629
};
630
cr.angleClockwise = function (a1, a2)
631
{
632
var s1 = Math.sin(a1);
633
var c1 = Math.cos(a1);
634
var s2 = Math.sin(a2);
635
var c2 = Math.cos(a2);
636
return c1 * s2 - s1 * c2 <= 0;
637
};
638
cr.rotatePtAround = function (px, py, a, ox, oy, getx)
639
{
640
if (a === 0)
641
return getx ? px : py;
642
var sin_a = Math.sin(a);
643
var cos_a = Math.cos(a);
644
px -= ox;
645
py -= oy;
646
var left_sin_a = px * sin_a;
647
var top_sin_a = py * sin_a;
648
var left_cos_a = px * cos_a;
649
var top_cos_a = py * cos_a;
650
px = left_cos_a - top_sin_a;
651
py = top_cos_a + left_sin_a;
652
px += ox;
653
py += oy;
654
return getx ? px : py;
655
}
656
cr.distanceTo = function(x1, y1, x2, y2)
657
{
658
var dx = x2 - x1;
659
var dy = y2 - y1;
660
return Math.sqrt(dx*dx + dy*dy);
661
};
662
cr.xor = function (x, y)
663
{
664
return !x !== !y;
665
};
666
cr.lerp = function (a, b, x)
667
{
668
return a + (b - a) * x;
669
};
670
cr.unlerp = function (a, b, c)
671
{
672
if (a === b)
673
return 0; // avoid divide by 0
674
return (c - a) / (b - a);
675
};
676
cr.anglelerp = function (a, b, x)
677
{
678
var diff = cr.angleDiff(a, b);
679
if (cr.angleClockwise(b, a))
680
{
681
return a + diff * x;
682
}
683
else
684
{
685
return a - diff * x;
686
}
687
};
688
cr.qarp = function (a, b, c, x)
689
{
690
return cr.lerp(cr.lerp(a, b, x), cr.lerp(b, c, x), x);
691
};
692
cr.cubic = function (a, b, c, d, x)
693
{
694
return cr.lerp(cr.qarp(a, b, c, x), cr.qarp(b, c, d, x), x);
695
};
696
cr.cosp = function (a, b, x)
697
{
698
return (a + b + (a - b) * Math.cos(x * Math.PI)) / 2;
699
};
700
cr.hasAnyOwnProperty = function (o)
701
{
702
var p;
703
for (p in o)
704
{
705
if (o.hasOwnProperty(p))
706
return true;
707
}
708
return false;
709
};
710
cr.wipe = function (obj)
711
{
712
var p;
713
for (p in obj)
714
{
715
if (obj.hasOwnProperty(p))
716
delete obj[p];
717
}
718
};
719
var startup_time = +(new Date());
720
cr.performance_now = function()
721
{
722
if (typeof window["performance"] !== "undefined")
723
{
724
var winperf = window["performance"];
725
if (typeof winperf.now !== "undefined")
726
return winperf.now();
727
else if (typeof winperf["webkitNow"] !== "undefined")
728
return winperf["webkitNow"]();
729
else if (typeof winperf["mozNow"] !== "undefined")
730
return winperf["mozNow"]();
731
else if (typeof winperf["msNow"] !== "undefined")
732
return winperf["msNow"]();
733
}
734
return Date.now() - startup_time;
735
};
736
var isChrome = false;
737
var isSafari = false;
738
var isiOS = false;
739
var isEjecta = false;
740
if (typeof window !== "undefined") // not c2 editor
741
{
742
isChrome = /chrome/i.test(navigator.userAgent) || /chromium/i.test(navigator.userAgent);
743
isSafari = !isChrome && /safari/i.test(navigator.userAgent);
744
isiOS = /(iphone|ipod|ipad)/i.test(navigator.userAgent);
745
isEjecta = window["c2ejecta"];
746
}
747
var supports_set = ((!isSafari && !isEjecta && !isiOS) && (typeof Set !== "undefined" && typeof Set.prototype["forEach"] !== "undefined"));
748
function ObjectSet_()
749
{
750
this.s = null;
751
this.items = null; // lazy allocated (hopefully results in better GC performance)
752
this.item_count = 0;
753
if (supports_set)
754
{
755
this.s = new Set();
756
}
757
this.values_cache = [];
758
this.cache_valid = true;
759
cr.seal(this);
760
};
761
ObjectSet_.prototype.contains = function (x)
762
{
763
if (this.isEmpty())
764
return false;
765
if (supports_set)
766
return this.s["has"](x);
767
else
768
return (this.items && this.items.hasOwnProperty(x));
769
};
770
ObjectSet_.prototype.add = function (x)
771
{
772
if (supports_set)
773
{
774
if (!this.s["has"](x))
775
{
776
this.s["add"](x);
777
this.cache_valid = false;
778
}
779
}
780
else
781
{
782
var str = x.toString();
783
var items = this.items;
784
if (!items)
785
{
786
this.items = {};
787
this.items[str] = x;
788
this.item_count = 1;
789
this.cache_valid = false;
790
}
791
else if (!items.hasOwnProperty(str))
792
{
793
items[str] = x;
794
this.item_count++;
795
this.cache_valid = false;
796
}
797
}
798
};
799
ObjectSet_.prototype.remove = function (x)
800
{
801
if (this.isEmpty())
802
return;
803
if (supports_set)
804
{
805
if (this.s["has"](x))
806
{
807
this.s["delete"](x);
808
this.cache_valid = false;
809
}
810
}
811
else if (this.items)
812
{
813
var str = x.toString();
814
var items = this.items;
815
if (items.hasOwnProperty(str))
816
{
817
delete items[str];
818
this.item_count--;
819
this.cache_valid = false;
820
}
821
}
822
};
823
ObjectSet_.prototype.clear = function (/*wipe_*/)
824
{
825
if (this.isEmpty())
826
return;
827
if (supports_set)
828
{
829
this.s["clear"](); // best!
830
}
831
else
832
{
833
this.items = null; // creates garbage; will lazy allocate on next add()
834
this.item_count = 0;
835
}
836
cr.clearArray(this.values_cache);
837
this.cache_valid = true;
838
};
839
ObjectSet_.prototype.isEmpty = function ()
840
{
841
return this.count() === 0;
842
};
843
ObjectSet_.prototype.count = function ()
844
{
845
if (supports_set)
846
return this.s["size"];
847
else
848
return this.item_count;
849
};
850
var current_arr = null;
851
var current_index = 0;
852
function set_append_to_arr(x)
853
{
854
current_arr[current_index++] = x;
855
};
856
ObjectSet_.prototype.update_cache = function ()
857
{
858
if (this.cache_valid)
859
return;
860
if (supports_set)
861
{
862
cr.clearArray(this.values_cache);
863
current_arr = this.values_cache;
864
current_index = 0;
865
this.s["forEach"](set_append_to_arr);
866
;
867
current_arr = null;
868
current_index = 0;
869
}
870
else
871
{
872
var values_cache = this.values_cache;
873
cr.clearArray(values_cache);
874
var p, n = 0, items = this.items;
875
if (items)
876
{
877
for (p in items)
878
{
879
if (items.hasOwnProperty(p))
880
values_cache[n++] = items[p];
881
}
882
}
883
;
884
}
885
this.cache_valid = true;
886
};
887
ObjectSet_.prototype.valuesRef = function ()
888
{
889
this.update_cache();
890
return this.values_cache;
891
};
892
cr.ObjectSet = ObjectSet_;
893
var tmpSet = new cr.ObjectSet();
894
cr.removeArrayDuplicates = function (arr)
895
{
896
var i, len;
897
for (i = 0, len = arr.length; i < len; ++i)
898
{
899
tmpSet.add(arr[i]);
900
}
901
cr.shallowAssignArray(arr, tmpSet.valuesRef());
902
tmpSet.clear();
903
};
904
cr.arrayRemoveAllFromObjectSet = function (arr, remset)
905
{
906
if (supports_set)
907
cr.arrayRemoveAll_set(arr, remset.s);
908
else
909
cr.arrayRemoveAll_arr(arr, remset.valuesRef());
910
};
911
cr.arrayRemoveAll_set = function (arr, s)
912
{
913
var i, j, len, item;
914
for (i = 0, j = 0, len = arr.length; i < len; ++i)
915
{
916
item = arr[i];
917
if (!s["has"](item)) // not an item to remove
918
arr[j++] = item; // keep it
919
}
920
cr.truncateArray(arr, j);
921
};
922
cr.arrayRemoveAll_arr = function (arr, rem)
923
{
924
var i, j, len, item;
925
for (i = 0, j = 0, len = arr.length; i < len; ++i)
926
{
927
item = arr[i];
928
if (cr.fastIndexOf(rem, item) === -1) // not an item to remove
929
arr[j++] = item; // keep it
930
}
931
cr.truncateArray(arr, j);
932
};
933
function KahanAdder_()
934
{
935
this.c = 0;
936
this.y = 0;
937
this.t = 0;
938
this.sum = 0;
939
cr.seal(this);
940
};
941
KahanAdder_.prototype.add = function (v)
942
{
943
this.y = v - this.c;
944
this.t = this.sum + this.y;
945
this.c = (this.t - this.sum) - this.y;
946
this.sum = this.t;
947
};
948
KahanAdder_.prototype.reset = function ()
949
{
950
this.c = 0;
951
this.y = 0;
952
this.t = 0;
953
this.sum = 0;
954
};
955
cr.KahanAdder = KahanAdder_;
956
cr.regexp_escape = function(text)
957
{
958
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
959
};
960
function CollisionPoly_(pts_array_)
961
{
962
this.pts_cache = [];
963
this.bboxLeft = 0;
964
this.bboxTop = 0;
965
this.bboxRight = 0;
966
this.bboxBottom = 0;
967
this.convexpolys = null; // for physics behavior to cache separated polys
968
this.set_pts(pts_array_);
969
cr.seal(this);
970
};
971
CollisionPoly_.prototype.set_pts = function(pts_array_)
972
{
973
this.pts_array = pts_array_;
974
this.pts_count = pts_array_.length / 2; // x, y, x, y... in array
975
this.pts_cache.length = pts_array_.length;
976
this.cache_width = -1;
977
this.cache_height = -1;
978
this.cache_angle = 0;
979
};
980
CollisionPoly_.prototype.is_empty = function()
981
{
982
return !this.pts_array.length;
983
};
984
CollisionPoly_.prototype.update_bbox = function ()
985
{
986
var myptscache = this.pts_cache;
987
var bboxLeft_ = myptscache[0];
988
var bboxRight_ = bboxLeft_;
989
var bboxTop_ = myptscache[1];
990
var bboxBottom_ = bboxTop_;
991
var x, y, i = 1, i2, len = this.pts_count;
992
for ( ; i < len; ++i)
993
{
994
i2 = i*2;
995
x = myptscache[i2];
996
y = myptscache[i2+1];
997
if (x < bboxLeft_)
998
bboxLeft_ = x;
999
if (x > bboxRight_)
1000
bboxRight_ = x;
1001
if (y < bboxTop_)
1002
bboxTop_ = y;
1003
if (y > bboxBottom_)
1004
bboxBottom_ = y;
1005
}
1006
this.bboxLeft = bboxLeft_;
1007
this.bboxRight = bboxRight_;
1008
this.bboxTop = bboxTop_;
1009
this.bboxBottom = bboxBottom_;
1010
};
1011
CollisionPoly_.prototype.set_from_rect = function(rc, offx, offy)
1012
{
1013
this.pts_cache.length = 8;
1014
this.pts_count = 4;
1015
var myptscache = this.pts_cache;
1016
myptscache[0] = rc.left - offx;
1017
myptscache[1] = rc.top - offy;
1018
myptscache[2] = rc.right - offx;
1019
myptscache[3] = rc.top - offy;
1020
myptscache[4] = rc.right - offx;
1021
myptscache[5] = rc.bottom - offy;
1022
myptscache[6] = rc.left - offx;
1023
myptscache[7] = rc.bottom - offy;
1024
this.cache_width = rc.right - rc.left;
1025
this.cache_height = rc.bottom - rc.top;
1026
this.update_bbox();
1027
};
1028
CollisionPoly_.prototype.set_from_quad = function(q, offx, offy, w, h)
1029
{
1030
this.pts_cache.length = 8;
1031
this.pts_count = 4;
1032
var myptscache = this.pts_cache;
1033
myptscache[0] = q.tlx - offx;
1034
myptscache[1] = q.tly - offy;
1035
myptscache[2] = q.trx - offx;
1036
myptscache[3] = q.try_ - offy;
1037
myptscache[4] = q.brx - offx;
1038
myptscache[5] = q.bry - offy;
1039
myptscache[6] = q.blx - offx;
1040
myptscache[7] = q.bly - offy;
1041
this.cache_width = w;
1042
this.cache_height = h;
1043
this.update_bbox();
1044
};
1045
CollisionPoly_.prototype.set_from_poly = function (r)
1046
{
1047
this.pts_count = r.pts_count;
1048
cr.shallowAssignArray(this.pts_cache, r.pts_cache);
1049
this.bboxLeft = r.bboxLeft;
1050
this.bboxTop - r.bboxTop;
1051
this.bboxRight = r.bboxRight;
1052
this.bboxBottom = r.bboxBottom;
1053
};
1054
CollisionPoly_.prototype.cache_poly = function(w, h, a)
1055
{
1056
if (this.cache_width === w && this.cache_height === h && this.cache_angle === a)
1057
return; // cache up-to-date
1058
this.cache_width = w;
1059
this.cache_height = h;
1060
this.cache_angle = a;
1061
var i, i2, i21, len, x, y;
1062
var sina = 0;
1063
var cosa = 1;
1064
var myptsarray = this.pts_array;
1065
var myptscache = this.pts_cache;
1066
if (a !== 0)
1067
{
1068
sina = Math.sin(a);
1069
cosa = Math.cos(a);
1070
}
1071
for (i = 0, len = this.pts_count; i < len; i++)
1072
{
1073
i2 = i*2;
1074
i21 = i2+1;
1075
x = myptsarray[i2] * w;
1076
y = myptsarray[i21] * h;
1077
myptscache[i2] = (x * cosa) - (y * sina);
1078
myptscache[i21] = (y * cosa) + (x * sina);
1079
}
1080
this.update_bbox();
1081
};
1082
CollisionPoly_.prototype.contains_pt = function (a2x, a2y)
1083
{
1084
var myptscache = this.pts_cache;
1085
if (a2x === myptscache[0] && a2y === myptscache[1])
1086
return true;
1087
var i, i2, imod, len = this.pts_count;
1088
var a1x = this.bboxLeft - 110;
1089
var a1y = this.bboxTop - 101;
1090
var a3x = this.bboxRight + 131
1091
var a3y = this.bboxBottom + 120;
1092
var b1x, b1y, b2x, b2y;
1093
var count1 = 0, count2 = 0;
1094
for (i = 0; i < len; i++)
1095
{
1096
i2 = i*2;
1097
imod = ((i+1)%len)*2;
1098
b1x = myptscache[i2];
1099
b1y = myptscache[i2+1];
1100
b2x = myptscache[imod];
1101
b2y = myptscache[imod+1];
1102
if (cr.segments_intersect(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y))
1103
count1++;
1104
if (cr.segments_intersect(a3x, a3y, a2x, a2y, b1x, b1y, b2x, b2y))
1105
count2++;
1106
}
1107
return (count1 % 2 === 1) || (count2 % 2 === 1);
1108
};
1109
CollisionPoly_.prototype.intersects_poly = function (rhs, offx, offy)
1110
{
1111
var rhspts = rhs.pts_cache;
1112
var mypts = this.pts_cache;
1113
if (this.contains_pt(rhspts[0] + offx, rhspts[1] + offy))
1114
return true;
1115
if (rhs.contains_pt(mypts[0] - offx, mypts[1] - offy))
1116
return true;
1117
var i, i2, imod, leni, j, j2, jmod, lenj;
1118
var a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y;
1119
for (i = 0, leni = this.pts_count; i < leni; i++)
1120
{
1121
i2 = i*2;
1122
imod = ((i+1)%leni)*2;
1123
a1x = mypts[i2];
1124
a1y = mypts[i2+1];
1125
a2x = mypts[imod];
1126
a2y = mypts[imod+1];
1127
for (j = 0, lenj = rhs.pts_count; j < lenj; j++)
1128
{
1129
j2 = j*2;
1130
jmod = ((j+1)%lenj)*2;
1131
b1x = rhspts[j2] + offx;
1132
b1y = rhspts[j2+1] + offy;
1133
b2x = rhspts[jmod] + offx;
1134
b2y = rhspts[jmod+1] + offy;
1135
if (cr.segments_intersect(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y))
1136
return true;
1137
}
1138
}
1139
return false;
1140
};
1141
CollisionPoly_.prototype.intersects_segment = function (offx, offy, x1, y1, x2, y2)
1142
{
1143
var mypts = this.pts_cache;
1144
if (this.contains_pt(x1 - offx, y1 - offy))
1145
return true;
1146
var i, leni, i2, imod;
1147
var a1x, a1y, a2x, a2y;
1148
for (i = 0, leni = this.pts_count; i < leni; i++)
1149
{
1150
i2 = i*2;
1151
imod = ((i+1)%leni)*2;
1152
a1x = mypts[i2] + offx;
1153
a1y = mypts[i2+1] + offy;
1154
a2x = mypts[imod] + offx;
1155
a2y = mypts[imod+1] + offy;
1156
if (cr.segments_intersect(x1, y1, x2, y2, a1x, a1y, a2x, a2y))
1157
return true;
1158
}
1159
return false;
1160
};
1161
CollisionPoly_.prototype.mirror = function (px)
1162
{
1163
var i, leni, i2;
1164
for (i = 0, leni = this.pts_count; i < leni; ++i)
1165
{
1166
i2 = i*2;
1167
this.pts_cache[i2] = px * 2 - this.pts_cache[i2];
1168
}
1169
};
1170
CollisionPoly_.prototype.flip = function (py)
1171
{
1172
var i, leni, i21;
1173
for (i = 0, leni = this.pts_count; i < leni; ++i)
1174
{
1175
i21 = i*2+1;
1176
this.pts_cache[i21] = py * 2 - this.pts_cache[i21];
1177
}
1178
};
1179
CollisionPoly_.prototype.diag = function ()
1180
{
1181
var i, leni, i2, i21, temp;
1182
for (i = 0, leni = this.pts_count; i < leni; ++i)
1183
{
1184
i2 = i*2;
1185
i21 = i2+1;
1186
temp = this.pts_cache[i2];
1187
this.pts_cache[i2] = this.pts_cache[i21];
1188
this.pts_cache[i21] = temp;
1189
}
1190
};
1191
cr.CollisionPoly = CollisionPoly_;
1192
function SparseGrid_(cellwidth_, cellheight_)
1193
{
1194
this.cellwidth = cellwidth_;
1195
this.cellheight = cellheight_;
1196
this.cells = {};
1197
};
1198
SparseGrid_.prototype.totalCellCount = 0;
1199
SparseGrid_.prototype.getCell = function (x_, y_, create_if_missing)
1200
{
1201
var ret;
1202
var col = this.cells[x_];
1203
if (!col)
1204
{
1205
if (create_if_missing)
1206
{
1207
ret = allocGridCell(this, x_, y_);
1208
this.cells[x_] = {};
1209
this.cells[x_][y_] = ret;
1210
return ret;
1211
}
1212
else
1213
return null;
1214
}
1215
ret = col[y_];
1216
if (ret)
1217
return ret;
1218
else if (create_if_missing)
1219
{
1220
ret = allocGridCell(this, x_, y_);
1221
this.cells[x_][y_] = ret;
1222
return ret;
1223
}
1224
else
1225
return null;
1226
};
1227
SparseGrid_.prototype.XToCell = function (x_)
1228
{
1229
return cr.floor(x_ / this.cellwidth);
1230
};
1231
SparseGrid_.prototype.YToCell = function (y_)
1232
{
1233
return cr.floor(y_ / this.cellheight);
1234
};
1235
SparseGrid_.prototype.update = function (inst, oldrange, newrange)
1236
{
1237
var x, lenx, y, leny, cell;
1238
if (oldrange)
1239
{
1240
for (x = oldrange.left, lenx = oldrange.right; x <= lenx; ++x)
1241
{
1242
for (y = oldrange.top, leny = oldrange.bottom; y <= leny; ++y)
1243
{
1244
if (newrange && newrange.contains_pt(x, y))
1245
continue; // is still in this cell
1246
cell = this.getCell(x, y, false); // don't create if missing
1247
if (!cell)
1248
continue; // cell does not exist yet
1249
cell.remove(inst);
1250
if (cell.isEmpty())
1251
{
1252
freeGridCell(cell);
1253
this.cells[x][y] = null;
1254
}
1255
}
1256
}
1257
}
1258
if (newrange)
1259
{
1260
for (x = newrange.left, lenx = newrange.right; x <= lenx; ++x)
1261
{
1262
for (y = newrange.top, leny = newrange.bottom; y <= leny; ++y)
1263
{
1264
if (oldrange && oldrange.contains_pt(x, y))
1265
continue; // is still in this cell
1266
this.getCell(x, y, true).insert(inst);
1267
}
1268
}
1269
}
1270
};
1271
SparseGrid_.prototype.queryRange = function (rc, result)
1272
{
1273
var x, lenx, ystart, y, leny, cell;
1274
x = this.XToCell(rc.left);
1275
ystart = this.YToCell(rc.top);
1276
lenx = this.XToCell(rc.right);
1277
leny = this.YToCell(rc.bottom);
1278
for ( ; x <= lenx; ++x)
1279
{
1280
for (y = ystart; y <= leny; ++y)
1281
{
1282
cell = this.getCell(x, y, false);
1283
if (!cell)
1284
continue;
1285
cell.dump(result);
1286
}
1287
}
1288
};
1289
cr.SparseGrid = SparseGrid_;
1290
function RenderGrid_(cellwidth_, cellheight_)
1291
{
1292
this.cellwidth = cellwidth_;
1293
this.cellheight = cellheight_;
1294
this.cells = {};
1295
};
1296
RenderGrid_.prototype.totalCellCount = 0;
1297
RenderGrid_.prototype.getCell = function (x_, y_, create_if_missing)
1298
{
1299
var ret;
1300
var col = this.cells[x_];
1301
if (!col)
1302
{
1303
if (create_if_missing)
1304
{
1305
ret = allocRenderCell(this, x_, y_);
1306
this.cells[x_] = {};
1307
this.cells[x_][y_] = ret;
1308
return ret;
1309
}
1310
else
1311
return null;
1312
}
1313
ret = col[y_];
1314
if (ret)
1315
return ret;
1316
else if (create_if_missing)
1317
{
1318
ret = allocRenderCell(this, x_, y_);
1319
this.cells[x_][y_] = ret;
1320
return ret;
1321
}
1322
else
1323
return null;
1324
};
1325
RenderGrid_.prototype.XToCell = function (x_)
1326
{
1327
return cr.floor(x_ / this.cellwidth);
1328
};
1329
RenderGrid_.prototype.YToCell = function (y_)
1330
{
1331
return cr.floor(y_ / this.cellheight);
1332
};
1333
RenderGrid_.prototype.update = function (inst, oldrange, newrange)
1334
{
1335
var x, lenx, y, leny, cell;
1336
if (oldrange)
1337
{
1338
for (x = oldrange.left, lenx = oldrange.right; x <= lenx; ++x)
1339
{
1340
for (y = oldrange.top, leny = oldrange.bottom; y <= leny; ++y)
1341
{
1342
if (newrange && newrange.contains_pt(x, y))
1343
continue; // is still in this cell
1344
cell = this.getCell(x, y, false); // don't create if missing
1345
if (!cell)
1346
continue; // cell does not exist yet
1347
cell.remove(inst);
1348
if (cell.isEmpty())
1349
{
1350
freeRenderCell(cell);
1351
this.cells[x][y] = null;
1352
}
1353
}
1354
}
1355
}
1356
if (newrange)
1357
{
1358
for (x = newrange.left, lenx = newrange.right; x <= lenx; ++x)
1359
{
1360
for (y = newrange.top, leny = newrange.bottom; y <= leny; ++y)
1361
{
1362
if (oldrange && oldrange.contains_pt(x, y))
1363
continue; // is still in this cell
1364
this.getCell(x, y, true).insert(inst);
1365
}
1366
}
1367
}
1368
};
1369
RenderGrid_.prototype.queryRange = function (left, top, right, bottom, result)
1370
{
1371
var x, lenx, ystart, y, leny, cell;
1372
x = this.XToCell(left);
1373
ystart = this.YToCell(top);
1374
lenx = this.XToCell(right);
1375
leny = this.YToCell(bottom);
1376
for ( ; x <= lenx; ++x)
1377
{
1378
for (y = ystart; y <= leny; ++y)
1379
{
1380
cell = this.getCell(x, y, false);
1381
if (!cell)
1382
continue;
1383
cell.dump(result);
1384
}
1385
}
1386
};
1387
RenderGrid_.prototype.markRangeChanged = function (rc)
1388
{
1389
var x, lenx, ystart, y, leny, cell;
1390
x = rc.left;
1391
ystart = rc.top;
1392
lenx = rc.right;
1393
leny = rc.bottom;
1394
for ( ; x <= lenx; ++x)
1395
{
1396
for (y = ystart; y <= leny; ++y)
1397
{
1398
cell = this.getCell(x, y, false);
1399
if (!cell)
1400
continue;
1401
cell.is_sorted = false;
1402
}
1403
}
1404
};
1405
cr.RenderGrid = RenderGrid_;
1406
var gridcellcache = [];
1407
function allocGridCell(grid_, x_, y_)
1408
{
1409
var ret;
1410
SparseGrid_.prototype.totalCellCount++;
1411
if (gridcellcache.length)
1412
{
1413
ret = gridcellcache.pop();
1414
ret.grid = grid_;
1415
ret.x = x_;
1416
ret.y = y_;
1417
return ret;
1418
}
1419
else
1420
return new cr.GridCell(grid_, x_, y_);
1421
};
1422
function freeGridCell(c)
1423
{
1424
SparseGrid_.prototype.totalCellCount--;
1425
c.objects.clear();
1426
if (gridcellcache.length < 1000)
1427
gridcellcache.push(c);
1428
};
1429
function GridCell_(grid_, x_, y_)
1430
{
1431
this.grid = grid_;
1432
this.x = x_;
1433
this.y = y_;
1434
this.objects = new cr.ObjectSet();
1435
};
1436
GridCell_.prototype.isEmpty = function ()
1437
{
1438
return this.objects.isEmpty();
1439
};
1440
GridCell_.prototype.insert = function (inst)
1441
{
1442
this.objects.add(inst);
1443
};
1444
GridCell_.prototype.remove = function (inst)
1445
{
1446
this.objects.remove(inst);
1447
};
1448
GridCell_.prototype.dump = function (result)
1449
{
1450
cr.appendArray(result, this.objects.valuesRef());
1451
};
1452
cr.GridCell = GridCell_;
1453
var rendercellcache = [];
1454
function allocRenderCell(grid_, x_, y_)
1455
{
1456
var ret;
1457
RenderGrid_.prototype.totalCellCount++;
1458
if (rendercellcache.length)
1459
{
1460
ret = rendercellcache.pop();
1461
ret.grid = grid_;
1462
ret.x = x_;
1463
ret.y = y_;
1464
return ret;
1465
}
1466
else
1467
return new cr.RenderCell(grid_, x_, y_);
1468
};
1469
function freeRenderCell(c)
1470
{
1471
RenderGrid_.prototype.totalCellCount--;
1472
c.reset();
1473
if (rendercellcache.length < 1000)
1474
rendercellcache.push(c);
1475
};
1476
function RenderCell_(grid_, x_, y_)
1477
{
1478
this.grid = grid_;
1479
this.x = x_;
1480
this.y = y_;
1481
this.objects = []; // array which needs to be sorted by Z order
1482
this.is_sorted = true; // whether array is in correct sort order or not
1483
this.pending_removal = new cr.ObjectSet();
1484
this.any_pending_removal = false;
1485
};
1486
RenderCell_.prototype.isEmpty = function ()
1487
{
1488
if (!this.objects.length)
1489
{
1490
;
1491
;
1492
return true;
1493
}
1494
if (this.objects.length > this.pending_removal.count())
1495
return false;
1496
;
1497
this.flush_pending(); // takes fast path and just resets state
1498
return true;
1499
};
1500
RenderCell_.prototype.insert = function (inst)
1501
{
1502
if (this.pending_removal.contains(inst))
1503
{
1504
this.pending_removal.remove(inst);
1505
if (this.pending_removal.isEmpty())
1506
this.any_pending_removal = false;
1507
return;
1508
}
1509
if (this.objects.length)
1510
{
1511
var top = this.objects[this.objects.length - 1];
1512
if (top.get_zindex() > inst.get_zindex())
1513
this.is_sorted = false; // 'inst' should be somewhere beneath 'top'
1514
this.objects.push(inst);
1515
}
1516
else
1517
{
1518
this.objects.push(inst);
1519
this.is_sorted = true;
1520
}
1521
;
1522
};
1523
RenderCell_.prototype.remove = function (inst)
1524
{
1525
this.pending_removal.add(inst);
1526
this.any_pending_removal = true;
1527
if (this.pending_removal.count() >= 30)
1528
this.flush_pending();
1529
};
1530
RenderCell_.prototype.flush_pending = function ()
1531
{
1532
;
1533
if (!this.any_pending_removal)
1534
return; // not changed
1535
if (this.pending_removal.count() === this.objects.length)
1536
{
1537
this.reset();
1538
return;
1539
}
1540
cr.arrayRemoveAllFromObjectSet(this.objects, this.pending_removal);
1541
this.pending_removal.clear();
1542
this.any_pending_removal = false;
1543
};
1544
function sortByInstanceZIndex(a, b)
1545
{
1546
return a.zindex - b.zindex;
1547
};
1548
RenderCell_.prototype.ensure_sorted = function ()
1549
{
1550
if (this.is_sorted)
1551
return; // already sorted
1552
this.objects.sort(sortByInstanceZIndex);
1553
this.is_sorted = true;
1554
};
1555
RenderCell_.prototype.reset = function ()
1556
{
1557
cr.clearArray(this.objects);
1558
this.is_sorted = true;
1559
this.pending_removal.clear();
1560
this.any_pending_removal = false;
1561
};
1562
RenderCell_.prototype.dump = function (result)
1563
{
1564
this.flush_pending();
1565
this.ensure_sorted();
1566
if (this.objects.length)
1567
result.push(this.objects);
1568
};
1569
cr.RenderCell = RenderCell_;
1570
var fxNames = [ "lighter",
1571
"xor",
1572
"copy",
1573
"destination-over",
1574
"source-in",
1575
"destination-in",
1576
"source-out",
1577
"destination-out",
1578
"source-atop",
1579
"destination-atop"];
1580
cr.effectToCompositeOp = function(effect)
1581
{
1582
if (effect <= 0 || effect >= 11)
1583
return "source-over";
1584
return fxNames[effect - 1]; // not including "none" so offset by 1
1585
};
1586
cr.setGLBlend = function(this_, effect, gl)
1587
{
1588
if (!gl)
1589
return;
1590
this_.srcBlend = gl.ONE;
1591
this_.destBlend = gl.ONE_MINUS_SRC_ALPHA;
1592
switch (effect) {
1593
case 1: // lighter (additive)
1594
this_.srcBlend = gl.ONE;
1595
this_.destBlend = gl.ONE;
1596
break;
1597
case 2: // xor
1598
break; // todo
1599
case 3: // copy
1600
this_.srcBlend = gl.ONE;
1601
this_.destBlend = gl.ZERO;
1602
break;
1603
case 4: // destination-over
1604
this_.srcBlend = gl.ONE_MINUS_DST_ALPHA;
1605
this_.destBlend = gl.ONE;
1606
break;
1607
case 5: // source-in
1608
this_.srcBlend = gl.DST_ALPHA;
1609
this_.destBlend = gl.ZERO;
1610
break;
1611
case 6: // destination-in
1612
this_.srcBlend = gl.ZERO;
1613
this_.destBlend = gl.SRC_ALPHA;
1614
break;
1615
case 7: // source-out
1616
this_.srcBlend = gl.ONE_MINUS_DST_ALPHA;
1617
this_.destBlend = gl.ZERO;
1618
break;
1619
case 8: // destination-out
1620
this_.srcBlend = gl.ZERO;
1621
this_.destBlend = gl.ONE_MINUS_SRC_ALPHA;
1622
break;
1623
case 9: // source-atop
1624
this_.srcBlend = gl.DST_ALPHA;
1625
this_.destBlend = gl.ONE_MINUS_SRC_ALPHA;
1626
break;
1627
case 10: // destination-atop
1628
this_.srcBlend = gl.ONE_MINUS_DST_ALPHA;
1629
this_.destBlend = gl.SRC_ALPHA;
1630
break;
1631
}
1632
};
1633
cr.round6dp = function (x)
1634
{
1635
return Math.round(x * 1000000) / 1000000;
1636
};
1637
/*
1638
var localeCompare_options = {
1639
"usage": "search",
1640
"sensitivity": "accent"
1641
};
1642
var has_localeCompare = !!"a".localeCompare;
1643
var localeCompare_works1 = (has_localeCompare && "a".localeCompare("A", undefined, localeCompare_options) === 0);
1644
var localeCompare_works2 = (has_localeCompare && "a".localeCompare("á", undefined, localeCompare_options) !== 0);
1645
var supports_localeCompare = (has_localeCompare && localeCompare_works1 && localeCompare_works2);
1646
*/
1647
cr.equals_nocase = function (a, b)
1648
{
1649
if (typeof a !== "string" || typeof b !== "string")
1650
return false;
1651
if (a.length !== b.length)
1652
return false;
1653
if (a === b)
1654
return true;
1655
/*
1656
if (supports_localeCompare)
1657
{
1658
return (a.localeCompare(b, undefined, localeCompare_options) === 0);
1659
}
1660
else
1661
{
1662
*/
1663
return a.toLowerCase() === b.toLowerCase();
1664
};
1665
cr.isCanvasInputEvent = function (e)
1666
{
1667
var target = e.target;
1668
if (!target)
1669
return true;
1670
if (target === document || target === window)
1671
return true;
1672
if (document && document.body && target === document.body)
1673
return true;
1674
if (cr.equals_nocase(target.tagName, "canvas"))
1675
return true;
1676
return false;
1677
};
1678
}());
1679
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};
1680
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};
1681
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]};
1682
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]+"]"};
1683
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};
1684
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};
1685
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};
1686
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};
1687
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};
1688
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};
1689
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;
1690
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};
1691
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};
1692
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*
1693
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};
1694
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};
1695
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];
1696
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};
1697
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*
1698
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};
1699
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};
1700
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};
1701
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)};
1702
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};
1703
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]=
1704
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};
1705
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};
1706
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)};
1707
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};
1708
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};
1709
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};
1710
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};
1711
quat4.str=function(a){return"["+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+"]"};
1712
(function()
1713
{
1714
var MAX_VERTICES = 8000; // equates to 2500 objects being drawn
1715
var MAX_INDICES = (MAX_VERTICES / 2) * 3; // 6 indices for every 4 vertices
1716
var MAX_POINTS = 8000;
1717
var MULTI_BUFFERS = 4; // cycle 4 buffers to try and avoid blocking
1718
var BATCH_NULL = 0;
1719
var BATCH_QUAD = 1;
1720
var BATCH_SETTEXTURE = 2;
1721
var BATCH_SETOPACITY = 3;
1722
var BATCH_SETBLEND = 4;
1723
var BATCH_UPDATEMODELVIEW = 5;
1724
var BATCH_RENDERTOTEXTURE = 6;
1725
var BATCH_CLEAR = 7;
1726
var BATCH_POINTS = 8;
1727
var BATCH_SETPROGRAM = 9;
1728
var BATCH_SETPROGRAMPARAMETERS = 10;
1729
var BATCH_SETTEXTURE1 = 11;
1730
var BATCH_SETCOLOR = 12;
1731
var BATCH_SETDEPTHTEST = 13;
1732
var BATCH_SETEARLYZMODE = 14;
1733
/*
1734
var lose_ext = null;
1735
window.lose_context = function ()
1736
{
1737
if (!lose_ext)
1738
{
1739
console.log("WEBGL_lose_context not supported");
1740
return;
1741
}
1742
lose_ext.loseContext();
1743
};
1744
window.restore_context = function ()
1745
{
1746
if (!lose_ext)
1747
{
1748
console.log("WEBGL_lose_context not supported");
1749
return;
1750
}
1751
lose_ext.restoreContext();
1752
};
1753
*/
1754
var tempMat4 = mat4.create();
1755
function GLWrap_(gl, isMobile, enableFrontToBack)
1756
{
1757
this.isIE = /msie/i.test(navigator.userAgent) || /trident/i.test(navigator.userAgent);
1758
this.width = 0; // not yet known, wait for call to setSize()
1759
this.height = 0;
1760
this.enableFrontToBack = !!enableFrontToBack;
1761
this.isEarlyZPass = false;
1762
this.isBatchInEarlyZPass = false;
1763
this.currentZ = 0;
1764
this.zNear = 1;
1765
this.zFar = 1000;
1766
this.zIncrement = ((this.zFar - this.zNear) / 32768);
1767
this.zA = this.zFar / (this.zFar - this.zNear);
1768
this.zB = this.zFar * this.zNear / (this.zNear - this.zFar);
1769
this.kzA = 65536 * this.zA;
1770
this.kzB = 65536 * this.zB;
1771
this.cam = vec3.create([0, 0, 100]); // camera position
1772
this.look = vec3.create([0, 0, 0]); // lookat position
1773
this.up = vec3.create([0, 1, 0]); // up vector
1774
this.worldScale = vec3.create([1, 1, 1]); // world scaling factor
1775
this.enable_mipmaps = true;
1776
this.matP = mat4.create(); // perspective matrix
1777
this.matMV = mat4.create(); // model view matrix
1778
this.lastMV = mat4.create();
1779
this.currentMV = mat4.create();
1780
this.gl = gl;
1781
this.version = (this.gl.getParameter(this.gl.VERSION).indexOf("WebGL 2") === 0 ? 2 : 1);
1782
this.initState();
1783
};
1784
GLWrap_.prototype.initState = function ()
1785
{
1786
var gl = this.gl;
1787
var i, len;
1788
this.lastOpacity = 1;
1789
this.lastTexture0 = null; // last bound to TEXTURE0
1790
this.lastTexture1 = null; // last bound to TEXTURE1
1791
this.currentOpacity = 1;
1792
gl.clearColor(0, 0, 0, 0);
1793
gl.clear(gl.COLOR_BUFFER_BIT);
1794
gl.enable(gl.BLEND);
1795
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
1796
gl.disable(gl.CULL_FACE);
1797
gl.disable(gl.STENCIL_TEST);
1798
gl.disable(gl.DITHER);
1799
if (this.enableFrontToBack)
1800
{
1801
gl.enable(gl.DEPTH_TEST);
1802
gl.depthFunc(gl.LEQUAL);
1803
}
1804
else
1805
{
1806
gl.disable(gl.DEPTH_TEST);
1807
}
1808
this.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);
1809
this.lastSrcBlend = gl.ONE;
1810
this.lastDestBlend = gl.ONE_MINUS_SRC_ALPHA;
1811
this.vertexData = new Float32Array(MAX_VERTICES * (this.enableFrontToBack ? 3 : 2));
1812
this.texcoordData = new Float32Array(MAX_VERTICES * 2);
1813
this.pointData = new Float32Array(MAX_POINTS * 4);
1814
this.pointBuffer = gl.createBuffer();
1815
gl.bindBuffer(gl.ARRAY_BUFFER, this.pointBuffer);
1816
gl.bufferData(gl.ARRAY_BUFFER, this.pointData.byteLength, gl.DYNAMIC_DRAW);
1817
this.vertexBuffers = new Array(MULTI_BUFFERS);
1818
this.texcoordBuffers = new Array(MULTI_BUFFERS);
1819
for (i = 0; i < MULTI_BUFFERS; i++)
1820
{
1821
this.vertexBuffers[i] = gl.createBuffer();
1822
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffers[i]);
1823
gl.bufferData(gl.ARRAY_BUFFER, this.vertexData.byteLength, gl.DYNAMIC_DRAW);
1824
this.texcoordBuffers[i] = gl.createBuffer();
1825
gl.bindBuffer(gl.ARRAY_BUFFER, this.texcoordBuffers[i]);
1826
gl.bufferData(gl.ARRAY_BUFFER, this.texcoordData.byteLength, gl.DYNAMIC_DRAW);
1827
}
1828
this.curBuffer = 0;
1829
this.indexBuffer = gl.createBuffer();
1830
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
1831
var indexData = new Uint16Array(MAX_INDICES);
1832
i = 0, len = MAX_INDICES;
1833
var fv = 0;
1834
while (i < len)
1835
{
1836
indexData[i++] = fv; // top left
1837
indexData[i++] = fv + 1; // top right
1838
indexData[i++] = fv + 2; // bottom right (first tri)
1839
indexData[i++] = fv; // top left
1840
indexData[i++] = fv + 2; // bottom right
1841
indexData[i++] = fv + 3; // bottom left
1842
fv += 4;
1843
}
1844
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indexData, gl.STATIC_DRAW);
1845
this.vertexPtr = 0;
1846
this.texPtr = 0;
1847
this.pointPtr = 0;
1848
var fsSource, vsSource;
1849
this.shaderPrograms = [];
1850
fsSource = [
1851
"varying mediump vec2 vTex;",
1852
"uniform lowp float opacity;",
1853
"uniform lowp sampler2D samplerFront;",
1854
"void main(void) {",
1855
" gl_FragColor = texture2D(samplerFront, vTex);",
1856
" gl_FragColor *= opacity;",
1857
"}"
1858
].join("\n");
1859
if (this.enableFrontToBack)
1860
{
1861
vsSource = [
1862
"attribute highp vec3 aPos;",
1863
"attribute mediump vec2 aTex;",
1864
"varying mediump vec2 vTex;",
1865
"uniform highp mat4 matP;",
1866
"uniform highp mat4 matMV;",
1867
"void main(void) {",
1868
" gl_Position = matP * matMV * vec4(aPos.x, aPos.y, aPos.z, 1.0);",
1869
" vTex = aTex;",
1870
"}"
1871
].join("\n");
1872
}
1873
else
1874
{
1875
vsSource = [
1876
"attribute highp vec2 aPos;",
1877
"attribute mediump vec2 aTex;",
1878
"varying mediump vec2 vTex;",
1879
"uniform highp mat4 matP;",
1880
"uniform highp mat4 matMV;",
1881
"void main(void) {",
1882
" gl_Position = matP * matMV * vec4(aPos.x, aPos.y, 0.0, 1.0);",
1883
" vTex = aTex;",
1884
"}"
1885
].join("\n");
1886
}
1887
var shaderProg = this.createShaderProgram({src: fsSource}, vsSource, "<default>");
1888
;
1889
this.shaderPrograms.push(shaderProg); // Default shader is always shader 0
1890
fsSource = [
1891
"uniform mediump sampler2D samplerFront;",
1892
"varying lowp float opacity;",
1893
"void main(void) {",
1894
" gl_FragColor = texture2D(samplerFront, gl_PointCoord);",
1895
" gl_FragColor *= opacity;",
1896
"}"
1897
].join("\n");
1898
var pointVsSource = [
1899
"attribute vec4 aPos;",
1900
"varying float opacity;",
1901
"uniform mat4 matP;",
1902
"uniform mat4 matMV;",
1903
"void main(void) {",
1904
" gl_Position = matP * matMV * vec4(aPos.x, aPos.y, 0.0, 1.0);",
1905
" gl_PointSize = aPos.z;",
1906
" opacity = aPos.w;",
1907
"}"
1908
].join("\n");
1909
shaderProg = this.createShaderProgram({src: fsSource}, pointVsSource, "<point>");
1910
;
1911
this.shaderPrograms.push(shaderProg); // Point shader is always shader 1
1912
fsSource = [
1913
"varying mediump vec2 vTex;",
1914
"uniform lowp sampler2D samplerFront;",
1915
"void main(void) {",
1916
" if (texture2D(samplerFront, vTex).a < 1.0)",
1917
" discard;", // discarding non-opaque fragments
1918
"}"
1919
].join("\n");
1920
var shaderProg = this.createShaderProgram({src: fsSource}, vsSource, "<earlyz>");
1921
;
1922
this.shaderPrograms.push(shaderProg); // Early-Z shader is always shader 2
1923
fsSource = [
1924
"uniform lowp vec4 colorFill;",
1925
"void main(void) {",
1926
" gl_FragColor = colorFill;",
1927
"}"
1928
].join("\n");
1929
var shaderProg = this.createShaderProgram({src: fsSource}, vsSource, "<fill>");
1930
;
1931
this.shaderPrograms.push(shaderProg); // Fill-color shader is always shader 3
1932
for (var shader_name in cr.shaders)
1933
{
1934
if (cr.shaders.hasOwnProperty(shader_name))
1935
this.shaderPrograms.push(this.createShaderProgram(cr.shaders[shader_name], vsSource, shader_name));
1936
}
1937
gl.activeTexture(gl.TEXTURE0);
1938
gl.bindTexture(gl.TEXTURE_2D, null);
1939
this.batch = [];
1940
this.batchPtr = 0;
1941
this.hasQuadBatchTop = false;
1942
this.hasPointBatchTop = false;
1943
this.lastProgram = -1; // start -1 so first switchProgram can do work
1944
this.currentProgram = -1; // current program during batch execution
1945
this.currentShader = null;
1946
this.fbo = gl.createFramebuffer();
1947
this.renderToTex = null;
1948
this.depthBuffer = null;
1949
this.attachedDepthBuffer = false; // wait until first size call to attach, otherwise it has no storage
1950
if (this.enableFrontToBack)
1951
{
1952
this.depthBuffer = gl.createRenderbuffer();
1953
}
1954
this.tmpVec3 = vec3.create([0, 0, 0]);
1955
;
1956
var pointsizes = gl.getParameter(gl.ALIASED_POINT_SIZE_RANGE);
1957
this.minPointSize = pointsizes[0];
1958
this.maxPointSize = pointsizes[1];
1959
if (this.maxPointSize > 2048)
1960
this.maxPointSize = 2048;
1961
;
1962
this.switchProgram(0);
1963
cr.seal(this);
1964
};
1965
function GLShaderProgram(gl, shaderProgram, name)
1966
{
1967
this.gl = gl;
1968
this.shaderProgram = shaderProgram;
1969
this.name = name;
1970
this.locAPos = gl.getAttribLocation(shaderProgram, "aPos");
1971
this.locATex = gl.getAttribLocation(shaderProgram, "aTex");
1972
this.locMatP = gl.getUniformLocation(shaderProgram, "matP");
1973
this.locMatMV = gl.getUniformLocation(shaderProgram, "matMV");
1974
this.locOpacity = gl.getUniformLocation(shaderProgram, "opacity");
1975
this.locColorFill = gl.getUniformLocation(shaderProgram, "colorFill");
1976
this.locSamplerFront = gl.getUniformLocation(shaderProgram, "samplerFront");
1977
this.locSamplerBack = gl.getUniformLocation(shaderProgram, "samplerBack");
1978
this.locDestStart = gl.getUniformLocation(shaderProgram, "destStart");
1979
this.locDestEnd = gl.getUniformLocation(shaderProgram, "destEnd");
1980
this.locSeconds = gl.getUniformLocation(shaderProgram, "seconds");
1981
this.locPixelWidth = gl.getUniformLocation(shaderProgram, "pixelWidth");
1982
this.locPixelHeight = gl.getUniformLocation(shaderProgram, "pixelHeight");
1983
this.locLayerScale = gl.getUniformLocation(shaderProgram, "layerScale");
1984
this.locLayerAngle = gl.getUniformLocation(shaderProgram, "layerAngle");
1985
this.locViewOrigin = gl.getUniformLocation(shaderProgram, "viewOrigin");
1986
this.locScrollPos = gl.getUniformLocation(shaderProgram, "scrollPos");
1987
this.hasAnyOptionalUniforms = !!(this.locPixelWidth || this.locPixelHeight || this.locSeconds || this.locSamplerBack || this.locDestStart || this.locDestEnd || this.locLayerScale || this.locLayerAngle || this.locViewOrigin || this.locScrollPos);
1988
this.lpPixelWidth = -999; // set to something unlikely so never counts as cached on first set
1989
this.lpPixelHeight = -999;
1990
this.lpOpacity = 1;
1991
this.lpDestStartX = 0.0;
1992
this.lpDestStartY = 0.0;
1993
this.lpDestEndX = 1.0;
1994
this.lpDestEndY = 1.0;
1995
this.lpLayerScale = 1.0;
1996
this.lpLayerAngle = 0.0;
1997
this.lpViewOriginX = 0.0;
1998
this.lpViewOriginY = 0.0;
1999
this.lpScrollPosX = 0.0;
2000
this.lpScrollPosY = 0.0;
2001
this.lpSeconds = 0.0;
2002
this.lastCustomParams = [];
2003
this.lpMatMV = mat4.create();
2004
if (this.locOpacity)
2005
gl.uniform1f(this.locOpacity, 1);
2006
if (this.locColorFill)
2007
gl.uniform4f(this.locColorFill, 1.0, 1.0, 1.0, 1.0);
2008
if (this.locSamplerFront)
2009
gl.uniform1i(this.locSamplerFront, 0);
2010
if (this.locSamplerBack)
2011
gl.uniform1i(this.locSamplerBack, 1);
2012
if (this.locDestStart)
2013
gl.uniform2f(this.locDestStart, 0.0, 0.0);
2014
if (this.locDestEnd)
2015
gl.uniform2f(this.locDestEnd, 1.0, 1.0);
2016
if (this.locLayerScale)
2017
gl.uniform1f(this.locLayerScale, 1.0);
2018
if (this.locLayerAngle)
2019
gl.uniform1f(this.locLayerAngle, 0.0);
2020
if (this.locViewOrigin)
2021
gl.uniform2f(this.locViewOrigin, 0.0, 0.0);
2022
if (this.locScrollPos)
2023
gl.uniform2f(this.locScrollPos, 0.0, 0.0);
2024
if (this.locSeconds)
2025
gl.uniform1f(this.locSeconds, 0.0);
2026
this.hasCurrentMatMV = false; // matMV needs updating
2027
};
2028
function areMat4sEqual(a, b)
2029
{
2030
return a[0]===b[0]&&a[1]===b[1]&&a[2]===b[2]&&a[3]===b[3]&&
2031
a[4]===b[4]&&a[5]===b[5]&&a[6]===b[6]&&a[7]===b[7]&&
2032
a[8]===b[8]&&a[9]===b[9]&&a[10]===b[10]&&a[11]===b[11]&&
2033
a[12]===b[12]&&a[13]===b[13]&&a[14]===b[14]&&a[15]===b[15];
2034
};
2035
GLShaderProgram.prototype.updateMatMV = function (mv)
2036
{
2037
if (areMat4sEqual(this.lpMatMV, mv))
2038
return; // no change, save the expensive GL call
2039
mat4.set(mv, this.lpMatMV);
2040
this.gl.uniformMatrix4fv(this.locMatMV, false, mv);
2041
};
2042
GLWrap_.prototype.createShaderProgram = function(shaderEntry, vsSource, name)
2043
{
2044
var gl = this.gl;
2045
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
2046
gl.shaderSource(fragmentShader, shaderEntry.src);
2047
gl.compileShader(fragmentShader);
2048
if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS))
2049
{
2050
var compilationlog = gl.getShaderInfoLog(fragmentShader);
2051
gl.deleteShader(fragmentShader);
2052
throw new Error("error compiling fragment shader: " + compilationlog);
2053
}
2054
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
2055
gl.shaderSource(vertexShader, vsSource);
2056
gl.compileShader(vertexShader);
2057
if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS))
2058
{
2059
var compilationlog = gl.getShaderInfoLog(vertexShader);
2060
gl.deleteShader(fragmentShader);
2061
gl.deleteShader(vertexShader);
2062
throw new Error("error compiling vertex shader: " + compilationlog);
2063
}
2064
var shaderProgram = gl.createProgram();
2065
gl.attachShader(shaderProgram, fragmentShader);
2066
gl.attachShader(shaderProgram, vertexShader);
2067
gl.linkProgram(shaderProgram);
2068
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS))
2069
{
2070
var compilationlog = gl.getProgramInfoLog(shaderProgram);
2071
gl.deleteShader(fragmentShader);
2072
gl.deleteShader(vertexShader);
2073
gl.deleteProgram(shaderProgram);
2074
throw new Error("error linking shader program: " + compilationlog);
2075
}
2076
gl.useProgram(shaderProgram);
2077
gl.deleteShader(fragmentShader);
2078
gl.deleteShader(vertexShader);
2079
var ret = new GLShaderProgram(gl, shaderProgram, name);
2080
ret.extendBoxHorizontal = shaderEntry.extendBoxHorizontal || 0;
2081
ret.extendBoxVertical = shaderEntry.extendBoxVertical || 0;
2082
ret.crossSampling = !!shaderEntry.crossSampling;
2083
ret.preservesOpaqueness = !!shaderEntry.preservesOpaqueness;
2084
ret.animated = !!shaderEntry.animated;
2085
ret.parameters = shaderEntry.parameters || [];
2086
var i, len;
2087
for (i = 0, len = ret.parameters.length; i < len; i++)
2088
{
2089
ret.parameters[i][1] = gl.getUniformLocation(shaderProgram, ret.parameters[i][0]);
2090
ret.lastCustomParams.push(0);
2091
gl.uniform1f(ret.parameters[i][1], 0);
2092
}
2093
cr.seal(ret);
2094
return ret;
2095
};
2096
GLWrap_.prototype.getShaderIndex = function(name_)
2097
{
2098
var i, len;
2099
for (i = 0, len = this.shaderPrograms.length; i < len; i++)
2100
{
2101
if (this.shaderPrograms[i].name === name_)
2102
return i;
2103
}
2104
return -1;
2105
};
2106
GLWrap_.prototype.project = function (x, y, out)
2107
{
2108
var mv = this.matMV;
2109
var proj = this.matP;
2110
var fTempo = [0, 0, 0, 0, 0, 0, 0, 0];
2111
fTempo[0] = mv[0]*x+mv[4]*y+mv[12];
2112
fTempo[1] = mv[1]*x+mv[5]*y+mv[13];
2113
fTempo[2] = mv[2]*x+mv[6]*y+mv[14];
2114
fTempo[3] = mv[3]*x+mv[7]*y+mv[15];
2115
fTempo[4] = proj[0]*fTempo[0]+proj[4]*fTempo[1]+proj[8]*fTempo[2]+proj[12]*fTempo[3];
2116
fTempo[5] = proj[1]*fTempo[0]+proj[5]*fTempo[1]+proj[9]*fTempo[2]+proj[13]*fTempo[3];
2117
fTempo[6] = proj[2]*fTempo[0]+proj[6]*fTempo[1]+proj[10]*fTempo[2]+proj[14]*fTempo[3];
2118
fTempo[7] = -fTempo[2];
2119
if(fTempo[7]===0.0) //The w value
2120
return;
2121
fTempo[7]=1.0/fTempo[7];
2122
fTempo[4]*=fTempo[7];
2123
fTempo[5]*=fTempo[7];
2124
fTempo[6]*=fTempo[7];
2125
out[0]=(fTempo[4]*0.5+0.5)*this.width;
2126
out[1]=(fTempo[5]*0.5+0.5)*this.height;
2127
};
2128
GLWrap_.prototype.setSize = function(w, h, force)
2129
{
2130
if (this.width === w && this.height === h && !force)
2131
return;
2132
this.endBatch();
2133
var gl = this.gl;
2134
this.width = w;
2135
this.height = h;
2136
gl.viewport(0, 0, w, h);
2137
mat4.lookAt(this.cam, this.look, this.up, this.matMV);
2138
if (this.enableFrontToBack)
2139
{
2140
mat4.ortho(-w/2, w/2, h/2, -h/2, this.zNear, this.zFar, this.matP);
2141
this.worldScale[0] = 1;
2142
this.worldScale[1] = 1;
2143
}
2144
else
2145
{
2146
mat4.perspective(45, w / h, this.zNear, this.zFar, this.matP);
2147
var tl = [0, 0];
2148
var br = [0, 0];
2149
this.project(0, 0, tl);
2150
this.project(1, 1, br);
2151
this.worldScale[0] = 1 / (br[0] - tl[0]);
2152
this.worldScale[1] = -1 / (br[1] - tl[1]);
2153
}
2154
var i, len, s;
2155
for (i = 0, len = this.shaderPrograms.length; i < len; i++)
2156
{
2157
s = this.shaderPrograms[i];
2158
s.hasCurrentMatMV = false;
2159
if (s.locMatP)
2160
{
2161
gl.useProgram(s.shaderProgram);
2162
gl.uniformMatrix4fv(s.locMatP, false, this.matP);
2163
}
2164
}
2165
gl.useProgram(this.shaderPrograms[this.lastProgram].shaderProgram);
2166
gl.bindTexture(gl.TEXTURE_2D, null);
2167
gl.activeTexture(gl.TEXTURE1);
2168
gl.bindTexture(gl.TEXTURE_2D, null);
2169
gl.activeTexture(gl.TEXTURE0);
2170
this.lastTexture0 = null;
2171
this.lastTexture1 = null;
2172
if (this.depthBuffer)
2173
{
2174
gl.bindFramebuffer(gl.FRAMEBUFFER, this.fbo);
2175
gl.bindRenderbuffer(gl.RENDERBUFFER, this.depthBuffer);
2176
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, this.width, this.height);
2177
if (!this.attachedDepthBuffer)
2178
{
2179
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this.depthBuffer);
2180
this.attachedDepthBuffer = true;
2181
}
2182
gl.bindRenderbuffer(gl.RENDERBUFFER, null);
2183
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
2184
this.renderToTex = null;
2185
}
2186
};
2187
GLWrap_.prototype.resetModelView = function ()
2188
{
2189
mat4.lookAt(this.cam, this.look, this.up, this.matMV);
2190
mat4.scale(this.matMV, this.worldScale);
2191
};
2192
GLWrap_.prototype.translate = function (x, y)
2193
{
2194
if (x === 0 && y === 0)
2195
return;
2196
this.tmpVec3[0] = x;// * this.worldScale[0];
2197
this.tmpVec3[1] = y;// * this.worldScale[1];
2198
this.tmpVec3[2] = 0;
2199
mat4.translate(this.matMV, this.tmpVec3);
2200
};
2201
GLWrap_.prototype.scale = function (x, y)
2202
{
2203
if (x === 1 && y === 1)
2204
return;
2205
this.tmpVec3[0] = x;
2206
this.tmpVec3[1] = y;
2207
this.tmpVec3[2] = 1;
2208
mat4.scale(this.matMV, this.tmpVec3);
2209
};
2210
GLWrap_.prototype.rotateZ = function (a)
2211
{
2212
if (a === 0)
2213
return;
2214
mat4.rotateZ(this.matMV, a);
2215
};
2216
GLWrap_.prototype.updateModelView = function()
2217
{
2218
if (areMat4sEqual(this.lastMV, this.matMV))
2219
return;
2220
var b = this.pushBatch();
2221
b.type = BATCH_UPDATEMODELVIEW;
2222
if (b.mat4param)
2223
mat4.set(this.matMV, b.mat4param);
2224
else
2225
b.mat4param = mat4.create(this.matMV);
2226
mat4.set(this.matMV, this.lastMV);
2227
this.hasQuadBatchTop = false;
2228
this.hasPointBatchTop = false;
2229
};
2230
/*
2231
var debugBatch = false;
2232
jQuery(document).mousedown(
2233
function(info) {
2234
if (info.which === 2)
2235
debugBatch = true;
2236
}
2237
);
2238
*/
2239
GLWrap_.prototype.setEarlyZIndex = function (i)
2240
{
2241
if (!this.enableFrontToBack)
2242
return;
2243
if (i > 32760)
2244
i = 32760;
2245
this.currentZ = this.cam[2] - this.zNear - i * this.zIncrement;
2246
};
2247
function GLBatchJob(type_, glwrap_)
2248
{
2249
this.type = type_;
2250
this.glwrap = glwrap_;
2251
this.gl = glwrap_.gl;
2252
this.opacityParam = 0; // for setOpacity()
2253
this.startIndex = 0; // for quad()
2254
this.indexCount = 0; // "
2255
this.texParam = null; // for setTexture()
2256
this.mat4param = null; // for updateModelView()
2257
this.shaderParams = []; // for user parameters
2258
cr.seal(this);
2259
};
2260
GLBatchJob.prototype.doSetEarlyZPass = function ()
2261
{
2262
var gl = this.gl;
2263
var glwrap = this.glwrap;
2264
if (this.startIndex !== 0) // enable
2265
{
2266
gl.depthMask(true); // enable depth writes
2267
gl.colorMask(false, false, false, false); // disable color writes
2268
gl.disable(gl.BLEND); // no color writes so disable blend
2269
gl.bindFramebuffer(gl.FRAMEBUFFER, glwrap.fbo);
2270
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 0);
2271
gl.clear(gl.DEPTH_BUFFER_BIT); // auto-clear depth buffer
2272
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
2273
glwrap.isBatchInEarlyZPass = true;
2274
}
2275
else
2276
{
2277
gl.depthMask(false); // disable depth writes, only test existing depth values
2278
gl.colorMask(true, true, true, true); // enable color writes
2279
gl.enable(gl.BLEND); // turn blending back on
2280
glwrap.isBatchInEarlyZPass = false;
2281
}
2282
};
2283
GLBatchJob.prototype.doSetTexture = function ()
2284
{
2285
this.gl.bindTexture(this.gl.TEXTURE_2D, this.texParam);
2286
};
2287
GLBatchJob.prototype.doSetTexture1 = function ()
2288
{
2289
var gl = this.gl;
2290
gl.activeTexture(gl.TEXTURE1);
2291
gl.bindTexture(gl.TEXTURE_2D, this.texParam);
2292
gl.activeTexture(gl.TEXTURE0);
2293
};
2294
GLBatchJob.prototype.doSetOpacity = function ()
2295
{
2296
var o = this.opacityParam;
2297
var glwrap = this.glwrap;
2298
glwrap.currentOpacity = o;
2299
var curProg = glwrap.currentShader;
2300
if (curProg.locOpacity && curProg.lpOpacity !== o)
2301
{
2302
curProg.lpOpacity = o;
2303
this.gl.uniform1f(curProg.locOpacity, o);
2304
}
2305
};
2306
GLBatchJob.prototype.doQuad = function ()
2307
{
2308
this.gl.drawElements(this.gl.TRIANGLES, this.indexCount, this.gl.UNSIGNED_SHORT, this.startIndex);
2309
};
2310
GLBatchJob.prototype.doSetBlend = function ()
2311
{
2312
this.gl.blendFunc(this.startIndex, this.indexCount);
2313
};
2314
GLBatchJob.prototype.doUpdateModelView = function ()
2315
{
2316
var i, len, s, shaderPrograms = this.glwrap.shaderPrograms, currentProgram = this.glwrap.currentProgram;
2317
for (i = 0, len = shaderPrograms.length; i < len; i++)
2318
{
2319
s = shaderPrograms[i];
2320
if (i === currentProgram && s.locMatMV)
2321
{
2322
s.updateMatMV(this.mat4param);
2323
s.hasCurrentMatMV = true;
2324
}
2325
else
2326
s.hasCurrentMatMV = false;
2327
}
2328
mat4.set(this.mat4param, this.glwrap.currentMV);
2329
};
2330
GLBatchJob.prototype.doRenderToTexture = function ()
2331
{
2332
var gl = this.gl;
2333
var glwrap = this.glwrap;
2334
if (this.texParam)
2335
{
2336
if (glwrap.lastTexture1 === this.texParam)
2337
{
2338
gl.activeTexture(gl.TEXTURE1);
2339
gl.bindTexture(gl.TEXTURE_2D, null);
2340
glwrap.lastTexture1 = null;
2341
gl.activeTexture(gl.TEXTURE0);
2342
}
2343
gl.bindFramebuffer(gl.FRAMEBUFFER, glwrap.fbo);
2344
if (!glwrap.isBatchInEarlyZPass)
2345
{
2346
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texParam, 0);
2347
}
2348
}
2349
else
2350
{
2351
if (!glwrap.enableFrontToBack)
2352
{
2353
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 0);
2354
}
2355
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
2356
}
2357
};
2358
GLBatchJob.prototype.doClear = function ()
2359
{
2360
var gl = this.gl;
2361
var mode = this.startIndex;
2362
if (mode === 0) // clear whole surface
2363
{
2364
gl.clearColor(this.mat4param[0], this.mat4param[1], this.mat4param[2], this.mat4param[3]);
2365
gl.clear(gl.COLOR_BUFFER_BIT);
2366
}
2367
else if (mode === 1) // clear rectangle
2368
{
2369
gl.enable(gl.SCISSOR_TEST);
2370
gl.scissor(this.mat4param[0], this.mat4param[1], this.mat4param[2], this.mat4param[3]);
2371
gl.clearColor(0, 0, 0, 0);
2372
gl.clear(gl.COLOR_BUFFER_BIT);
2373
gl.disable(gl.SCISSOR_TEST);
2374
}
2375
else // clear depth
2376
{
2377
gl.clear(gl.DEPTH_BUFFER_BIT);
2378
}
2379
};
2380
GLBatchJob.prototype.doSetDepthTestEnabled = function ()
2381
{
2382
var gl = this.gl;
2383
var enable = this.startIndex;
2384
if (enable !== 0)
2385
{
2386
gl.enable(gl.DEPTH_TEST);
2387
}
2388
else
2389
{
2390
gl.disable(gl.DEPTH_TEST);
2391
}
2392
};
2393
GLBatchJob.prototype.doPoints = function ()
2394
{
2395
var gl = this.gl;
2396
var glwrap = this.glwrap;
2397
if (glwrap.enableFrontToBack)
2398
gl.disable(gl.DEPTH_TEST);
2399
var s = glwrap.shaderPrograms[1];
2400
gl.useProgram(s.shaderProgram);
2401
if (!s.hasCurrentMatMV && s.locMatMV)
2402
{
2403
s.updateMatMV(glwrap.currentMV);
2404
s.hasCurrentMatMV = true;
2405
}
2406
gl.enableVertexAttribArray(s.locAPos);
2407
gl.bindBuffer(gl.ARRAY_BUFFER, glwrap.pointBuffer);
2408
gl.vertexAttribPointer(s.locAPos, 4, gl.FLOAT, false, 0, 0);
2409
gl.drawArrays(gl.POINTS, this.startIndex / 4, this.indexCount);
2410
s = glwrap.currentShader;
2411
gl.useProgram(s.shaderProgram);
2412
if (s.locAPos >= 0)
2413
{
2414
gl.enableVertexAttribArray(s.locAPos);
2415
gl.bindBuffer(gl.ARRAY_BUFFER, glwrap.vertexBuffers[glwrap.curBuffer]);
2416
gl.vertexAttribPointer(s.locAPos, glwrap.enableFrontToBack ? 3 : 2, gl.FLOAT, false, 0, 0);
2417
}
2418
if (s.locATex >= 0)
2419
{
2420
gl.enableVertexAttribArray(s.locATex);
2421
gl.bindBuffer(gl.ARRAY_BUFFER, glwrap.texcoordBuffers[glwrap.curBuffer]);
2422
gl.vertexAttribPointer(s.locATex, 2, gl.FLOAT, false, 0, 0);
2423
}
2424
if (glwrap.enableFrontToBack)
2425
gl.enable(gl.DEPTH_TEST);
2426
};
2427
GLBatchJob.prototype.doSetProgram = function ()
2428
{
2429
var gl = this.gl;
2430
var glwrap = this.glwrap;
2431
var s = glwrap.shaderPrograms[this.startIndex]; // recycled param to save memory
2432
glwrap.currentProgram = this.startIndex; // current batch program
2433
glwrap.currentShader = s;
2434
gl.useProgram(s.shaderProgram); // switch to
2435
if (!s.hasCurrentMatMV && s.locMatMV)
2436
{
2437
s.updateMatMV(glwrap.currentMV);
2438
s.hasCurrentMatMV = true;
2439
}
2440
if (s.locOpacity && s.lpOpacity !== glwrap.currentOpacity)
2441
{
2442
s.lpOpacity = glwrap.currentOpacity;
2443
gl.uniform1f(s.locOpacity, glwrap.currentOpacity);
2444
}
2445
if (s.locAPos >= 0)
2446
{
2447
gl.enableVertexAttribArray(s.locAPos);
2448
gl.bindBuffer(gl.ARRAY_BUFFER, glwrap.vertexBuffers[glwrap.curBuffer]);
2449
gl.vertexAttribPointer(s.locAPos, glwrap.enableFrontToBack ? 3 : 2, gl.FLOAT, false, 0, 0);
2450
}
2451
if (s.locATex >= 0)
2452
{
2453
gl.enableVertexAttribArray(s.locATex);
2454
gl.bindBuffer(gl.ARRAY_BUFFER, glwrap.texcoordBuffers[glwrap.curBuffer]);
2455
gl.vertexAttribPointer(s.locATex, 2, gl.FLOAT, false, 0, 0);
2456
}
2457
}
2458
GLBatchJob.prototype.doSetColor = function ()
2459
{
2460
var s = this.glwrap.currentShader;
2461
var mat4param = this.mat4param;
2462
this.gl.uniform4f(s.locColorFill, mat4param[0], mat4param[1], mat4param[2], mat4param[3]);
2463
};
2464
GLBatchJob.prototype.doSetProgramParameters = function ()
2465
{
2466
var i, len, s = this.glwrap.currentShader;
2467
var gl = this.gl;
2468
var mat4param = this.mat4param;
2469
if (s.locSamplerBack && this.glwrap.lastTexture1 !== this.texParam)
2470
{
2471
gl.activeTexture(gl.TEXTURE1);
2472
gl.bindTexture(gl.TEXTURE_2D, this.texParam);
2473
this.glwrap.lastTexture1 = this.texParam;
2474
gl.activeTexture(gl.TEXTURE0);
2475
}
2476
var v = mat4param[0];
2477
var v2;
2478
if (s.locPixelWidth && v !== s.lpPixelWidth)
2479
{
2480
s.lpPixelWidth = v;
2481
gl.uniform1f(s.locPixelWidth, v);
2482
}
2483
v = mat4param[1];
2484
if (s.locPixelHeight && v !== s.lpPixelHeight)
2485
{
2486
s.lpPixelHeight = v;
2487
gl.uniform1f(s.locPixelHeight, v);
2488
}
2489
v = mat4param[2];
2490
v2 = mat4param[3];
2491
if (s.locDestStart && (v !== s.lpDestStartX || v2 !== s.lpDestStartY))
2492
{
2493
s.lpDestStartX = v;
2494
s.lpDestStartY = v2;
2495
gl.uniform2f(s.locDestStart, v, v2);
2496
}
2497
v = mat4param[4];
2498
v2 = mat4param[5];
2499
if (s.locDestEnd && (v !== s.lpDestEndX || v2 !== s.lpDestEndY))
2500
{
2501
s.lpDestEndX = v;
2502
s.lpDestEndY = v2;
2503
gl.uniform2f(s.locDestEnd, v, v2);
2504
}
2505
v = mat4param[6];
2506
if (s.locLayerScale && v !== s.lpLayerScale)
2507
{
2508
s.lpLayerScale = v;
2509
gl.uniform1f(s.locLayerScale, v);
2510
}
2511
v = mat4param[7];
2512
if (s.locLayerAngle && v !== s.lpLayerAngle)
2513
{
2514
s.lpLayerAngle = v;
2515
gl.uniform1f(s.locLayerAngle, v);
2516
}
2517
v = mat4param[8];
2518
v2 = mat4param[9];
2519
if (s.locViewOrigin && (v !== s.lpViewOriginX || v2 !== s.lpViewOriginY))
2520
{
2521
s.lpViewOriginX = v;
2522
s.lpViewOriginY = v2;
2523
gl.uniform2f(s.locViewOrigin, v, v2);
2524
}
2525
v = mat4param[10];
2526
v2 = mat4param[11];
2527
if (s.locScrollPos && (v !== s.lpScrollPosX || v2 !== s.lpScrollPosY))
2528
{
2529
s.lpScrollPosX = v;
2530
s.lpScrollPosY = v2;
2531
gl.uniform2f(s.locScrollPos, v, v2);
2532
}
2533
v = mat4param[12];
2534
if (s.locSeconds && v !== s.lpSeconds)
2535
{
2536
s.lpSeconds = v;
2537
gl.uniform1f(s.locSeconds, v);
2538
}
2539
if (s.parameters.length)
2540
{
2541
for (i = 0, len = s.parameters.length; i < len; i++)
2542
{
2543
v = this.shaderParams[i];
2544
if (v !== s.lastCustomParams[i])
2545
{
2546
s.lastCustomParams[i] = v;
2547
gl.uniform1f(s.parameters[i][1], v);
2548
}
2549
}
2550
}
2551
};
2552
GLWrap_.prototype.pushBatch = function ()
2553
{
2554
if (this.batchPtr === this.batch.length)
2555
this.batch.push(new GLBatchJob(BATCH_NULL, this));
2556
return this.batch[this.batchPtr++];
2557
};
2558
GLWrap_.prototype.endBatch = function ()
2559
{
2560
if (this.batchPtr === 0)
2561
return;
2562
if (this.gl.isContextLost())
2563
return;
2564
var gl = this.gl;
2565
if (this.pointPtr > 0)
2566
{
2567
gl.bindBuffer(gl.ARRAY_BUFFER, this.pointBuffer);
2568
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.pointData.subarray(0, this.pointPtr));
2569
if (s && s.locAPos >= 0 && s.name === "<point>")
2570
gl.vertexAttribPointer(s.locAPos, 4, gl.FLOAT, false, 0, 0);
2571
}
2572
if (this.vertexPtr > 0)
2573
{
2574
var s = this.currentShader;
2575
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffers[this.curBuffer]);
2576
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexData.subarray(0, this.vertexPtr));
2577
if (s && s.locAPos >= 0 && s.name !== "<point>")
2578
gl.vertexAttribPointer(s.locAPos, this.enableFrontToBack ? 3 : 2, gl.FLOAT, false, 0, 0);
2579
gl.bindBuffer(gl.ARRAY_BUFFER, this.texcoordBuffers[this.curBuffer]);
2580
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.texcoordData.subarray(0, this.texPtr));
2581
if (s && s.locATex >= 0 && s.name !== "<point>")
2582
gl.vertexAttribPointer(s.locATex, 2, gl.FLOAT, false, 0, 0);
2583
}
2584
var i, len, b;
2585
for (i = 0, len = this.batchPtr; i < len; i++)
2586
{
2587
b = this.batch[i];
2588
switch (b.type) {
2589
case 1:
2590
b.doQuad();
2591
break;
2592
case 2:
2593
b.doSetTexture();
2594
break;
2595
case 3:
2596
b.doSetOpacity();
2597
break;
2598
case 4:
2599
b.doSetBlend();
2600
break;
2601
case 5:
2602
b.doUpdateModelView();
2603
break;
2604
case 6:
2605
b.doRenderToTexture();
2606
break;
2607
case 7:
2608
b.doClear();
2609
break;
2610
case 8:
2611
b.doPoints();
2612
break;
2613
case 9:
2614
b.doSetProgram();
2615
break;
2616
case 10:
2617
b.doSetProgramParameters();
2618
break;
2619
case 11:
2620
b.doSetTexture1();
2621
break;
2622
case 12:
2623
b.doSetColor();
2624
break;
2625
case 13:
2626
b.doSetDepthTestEnabled();
2627
break;
2628
case 14:
2629
b.doSetEarlyZPass();
2630
break;
2631
}
2632
}
2633
this.batchPtr = 0;
2634
this.vertexPtr = 0;
2635
this.texPtr = 0;
2636
this.pointPtr = 0;
2637
this.hasQuadBatchTop = false;
2638
this.hasPointBatchTop = false;
2639
this.isBatchInEarlyZPass = false;
2640
this.curBuffer++;
2641
if (this.curBuffer >= MULTI_BUFFERS)
2642
this.curBuffer = 0;
2643
};
2644
GLWrap_.prototype.setOpacity = function (op)
2645
{
2646
if (op === this.lastOpacity)
2647
return;
2648
if (this.isEarlyZPass)
2649
return; // ignore
2650
var b = this.pushBatch();
2651
b.type = BATCH_SETOPACITY;
2652
b.opacityParam = op;
2653
this.lastOpacity = op;
2654
this.hasQuadBatchTop = false;
2655
this.hasPointBatchTop = false;
2656
};
2657
GLWrap_.prototype.setTexture = function (tex)
2658
{
2659
if (tex === this.lastTexture0)
2660
return;
2661
;
2662
var b = this.pushBatch();
2663
b.type = BATCH_SETTEXTURE;
2664
b.texParam = tex;
2665
this.lastTexture0 = tex;
2666
this.hasQuadBatchTop = false;
2667
this.hasPointBatchTop = false;
2668
};
2669
GLWrap_.prototype.setBlend = function (s, d)
2670
{
2671
if (s === this.lastSrcBlend && d === this.lastDestBlend)
2672
return;
2673
if (this.isEarlyZPass)
2674
return; // ignore
2675
var b = this.pushBatch();
2676
b.type = BATCH_SETBLEND;
2677
b.startIndex = s; // recycle params to save memory
2678
b.indexCount = d;
2679
this.lastSrcBlend = s;
2680
this.lastDestBlend = d;
2681
this.hasQuadBatchTop = false;
2682
this.hasPointBatchTop = false;
2683
};
2684
GLWrap_.prototype.isPremultipliedAlphaBlend = function ()
2685
{
2686
return (this.lastSrcBlend === this.gl.ONE && this.lastDestBlend === this.gl.ONE_MINUS_SRC_ALPHA);
2687
};
2688
GLWrap_.prototype.setAlphaBlend = function ()
2689
{
2690
this.setBlend(this.gl.ONE, this.gl.ONE_MINUS_SRC_ALPHA);
2691
};
2692
GLWrap_.prototype.setNoPremultiplyAlphaBlend = function ()
2693
{
2694
this.setBlend(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
2695
};
2696
var LAST_VERTEX = MAX_VERTICES * 2 - 8;
2697
GLWrap_.prototype.quad = function(tlx, tly, trx, try_, brx, bry, blx, bly)
2698
{
2699
if (this.vertexPtr >= LAST_VERTEX)
2700
this.endBatch();
2701
var v = this.vertexPtr; // vertex cursor
2702
var t = this.texPtr;
2703
var vd = this.vertexData; // vertex data array
2704
var td = this.texcoordData; // texture coord data array
2705
var currentZ = this.currentZ;
2706
if (this.hasQuadBatchTop)
2707
{
2708
this.batch[this.batchPtr - 1].indexCount += 6;
2709
}
2710
else
2711
{
2712
var b = this.pushBatch();
2713
b.type = BATCH_QUAD;
2714
b.startIndex = this.enableFrontToBack ? v : (v / 2) * 3;
2715
b.indexCount = 6;
2716
this.hasQuadBatchTop = true;
2717
this.hasPointBatchTop = false;
2718
}
2719
if (this.enableFrontToBack)
2720
{
2721
vd[v++] = tlx;
2722
vd[v++] = tly;
2723
vd[v++] = currentZ;
2724
vd[v++] = trx;
2725
vd[v++] = try_;
2726
vd[v++] = currentZ;
2727
vd[v++] = brx;
2728
vd[v++] = bry;
2729
vd[v++] = currentZ;
2730
vd[v++] = blx;
2731
vd[v++] = bly;
2732
vd[v++] = currentZ;
2733
}
2734
else
2735
{
2736
vd[v++] = tlx;
2737
vd[v++] = tly;
2738
vd[v++] = trx;
2739
vd[v++] = try_;
2740
vd[v++] = brx;
2741
vd[v++] = bry;
2742
vd[v++] = blx;
2743
vd[v++] = bly;
2744
}
2745
td[t++] = 0;
2746
td[t++] = 0;
2747
td[t++] = 1;
2748
td[t++] = 0;
2749
td[t++] = 1;
2750
td[t++] = 1;
2751
td[t++] = 0;
2752
td[t++] = 1;
2753
this.vertexPtr = v;
2754
this.texPtr = t;
2755
};
2756
GLWrap_.prototype.quadTex = function(tlx, tly, trx, try_, brx, bry, blx, bly, rcTex)
2757
{
2758
if (this.vertexPtr >= LAST_VERTEX)
2759
this.endBatch();
2760
var v = this.vertexPtr; // vertex cursor
2761
var t = this.texPtr;
2762
var vd = this.vertexData; // vertex data array
2763
var td = this.texcoordData; // texture coord data array
2764
var currentZ = this.currentZ;
2765
if (this.hasQuadBatchTop)
2766
{
2767
this.batch[this.batchPtr - 1].indexCount += 6;
2768
}
2769
else
2770
{
2771
var b = this.pushBatch();
2772
b.type = BATCH_QUAD;
2773
b.startIndex = this.enableFrontToBack ? v : (v / 2) * 3;
2774
b.indexCount = 6;
2775
this.hasQuadBatchTop = true;
2776
this.hasPointBatchTop = false;
2777
}
2778
var rc_left = rcTex.left;
2779
var rc_top = rcTex.top;
2780
var rc_right = rcTex.right;
2781
var rc_bottom = rcTex.bottom;
2782
if (this.enableFrontToBack)
2783
{
2784
vd[v++] = tlx;
2785
vd[v++] = tly;
2786
vd[v++] = currentZ;
2787
vd[v++] = trx;
2788
vd[v++] = try_;
2789
vd[v++] = currentZ;
2790
vd[v++] = brx;
2791
vd[v++] = bry;
2792
vd[v++] = currentZ;
2793
vd[v++] = blx;
2794
vd[v++] = bly;
2795
vd[v++] = currentZ;
2796
}
2797
else
2798
{
2799
vd[v++] = tlx;
2800
vd[v++] = tly;
2801
vd[v++] = trx;
2802
vd[v++] = try_;
2803
vd[v++] = brx;
2804
vd[v++] = bry;
2805
vd[v++] = blx;
2806
vd[v++] = bly;
2807
}
2808
td[t++] = rc_left;
2809
td[t++] = rc_top;
2810
td[t++] = rc_right;
2811
td[t++] = rc_top;
2812
td[t++] = rc_right;
2813
td[t++] = rc_bottom;
2814
td[t++] = rc_left;
2815
td[t++] = rc_bottom;
2816
this.vertexPtr = v;
2817
this.texPtr = t;
2818
};
2819
GLWrap_.prototype.quadTexUV = function(tlx, tly, trx, try_, brx, bry, blx, bly, tlu, tlv, tru, trv, bru, brv, blu, blv)
2820
{
2821
if (this.vertexPtr >= LAST_VERTEX)
2822
this.endBatch();
2823
var v = this.vertexPtr; // vertex cursor
2824
var t = this.texPtr;
2825
var vd = this.vertexData; // vertex data array
2826
var td = this.texcoordData; // texture coord data array
2827
var currentZ = this.currentZ;
2828
if (this.hasQuadBatchTop)
2829
{
2830
this.batch[this.batchPtr - 1].indexCount += 6;
2831
}
2832
else
2833
{
2834
var b = this.pushBatch();
2835
b.type = BATCH_QUAD;
2836
b.startIndex = this.enableFrontToBack ? v : (v / 2) * 3;
2837
b.indexCount = 6;
2838
this.hasQuadBatchTop = true;
2839
this.hasPointBatchTop = false;
2840
}
2841
if (this.enableFrontToBack)
2842
{
2843
vd[v++] = tlx;
2844
vd[v++] = tly;
2845
vd[v++] = currentZ;
2846
vd[v++] = trx;
2847
vd[v++] = try_;
2848
vd[v++] = currentZ;
2849
vd[v++] = brx;
2850
vd[v++] = bry;
2851
vd[v++] = currentZ;
2852
vd[v++] = blx;
2853
vd[v++] = bly;
2854
vd[v++] = currentZ;
2855
}
2856
else
2857
{
2858
vd[v++] = tlx;
2859
vd[v++] = tly;
2860
vd[v++] = trx;
2861
vd[v++] = try_;
2862
vd[v++] = brx;
2863
vd[v++] = bry;
2864
vd[v++] = blx;
2865
vd[v++] = bly;
2866
}
2867
td[t++] = tlu;
2868
td[t++] = tlv;
2869
td[t++] = tru;
2870
td[t++] = trv;
2871
td[t++] = bru;
2872
td[t++] = brv;
2873
td[t++] = blu;
2874
td[t++] = blv;
2875
this.vertexPtr = v;
2876
this.texPtr = t;
2877
};
2878
GLWrap_.prototype.convexPoly = function(pts)
2879
{
2880
var pts_count = pts.length / 2;
2881
;
2882
var tris = pts_count - 2; // 3 points = 1 tri, 4 points = 2 tris, 5 points = 3 tris etc.
2883
var last_tri = tris - 1;
2884
var p0x = pts[0];
2885
var p0y = pts[1];
2886
var i, i2, p1x, p1y, p2x, p2y, p3x, p3y;
2887
for (i = 0; i < tris; i += 2) // draw 2 triangles at a time
2888
{
2889
i2 = i * 2;
2890
p1x = pts[i2 + 2];
2891
p1y = pts[i2 + 3];
2892
p2x = pts[i2 + 4];
2893
p2y = pts[i2 + 5];
2894
if (i === last_tri)
2895
{
2896
this.quad(p0x, p0y, p1x, p1y, p2x, p2y, p2x, p2y);
2897
}
2898
else
2899
{
2900
p3x = pts[i2 + 6];
2901
p3y = pts[i2 + 7];
2902
this.quad(p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y);
2903
}
2904
}
2905
};
2906
var LAST_POINT = MAX_POINTS - 4;
2907
GLWrap_.prototype.point = function(x_, y_, size_, opacity_)
2908
{
2909
if (this.pointPtr >= LAST_POINT)
2910
this.endBatch();
2911
var p = this.pointPtr; // point cursor
2912
var pd = this.pointData; // point data array
2913
if (this.hasPointBatchTop)
2914
{
2915
this.batch[this.batchPtr - 1].indexCount++;
2916
}
2917
else
2918
{
2919
var b = this.pushBatch();
2920
b.type = BATCH_POINTS;
2921
b.startIndex = p;
2922
b.indexCount = 1;
2923
this.hasPointBatchTop = true;
2924
this.hasQuadBatchTop = false;
2925
}
2926
pd[p++] = x_;
2927
pd[p++] = y_;
2928
pd[p++] = size_;
2929
pd[p++] = opacity_;
2930
this.pointPtr = p;
2931
};
2932
GLWrap_.prototype.switchProgram = function (progIndex)
2933
{
2934
if (this.lastProgram === progIndex)
2935
return; // no change
2936
var shaderProg = this.shaderPrograms[progIndex];
2937
if (!shaderProg)
2938
{
2939
if (this.lastProgram === 0)
2940
return; // already on default shader
2941
progIndex = 0;
2942
shaderProg = this.shaderPrograms[0];
2943
}
2944
var b = this.pushBatch();
2945
b.type = BATCH_SETPROGRAM;
2946
b.startIndex = progIndex;
2947
this.lastProgram = progIndex;
2948
this.hasQuadBatchTop = false;
2949
this.hasPointBatchTop = false;
2950
};
2951
GLWrap_.prototype.programUsesDest = function (progIndex)
2952
{
2953
var s = this.shaderPrograms[progIndex];
2954
return !!(s.locDestStart || s.locDestEnd);
2955
};
2956
GLWrap_.prototype.programUsesCrossSampling = function (progIndex)
2957
{
2958
var s = this.shaderPrograms[progIndex];
2959
return !!(s.locDestStart || s.locDestEnd || s.crossSampling);
2960
};
2961
GLWrap_.prototype.programPreservesOpaqueness = function (progIndex)
2962
{
2963
return this.shaderPrograms[progIndex].preservesOpaqueness;
2964
};
2965
GLWrap_.prototype.programExtendsBox = function (progIndex)
2966
{
2967
var s = this.shaderPrograms[progIndex];
2968
return s.extendBoxHorizontal !== 0 || s.extendBoxVertical !== 0;
2969
};
2970
GLWrap_.prototype.getProgramBoxExtendHorizontal = function (progIndex)
2971
{
2972
return this.shaderPrograms[progIndex].extendBoxHorizontal;
2973
};
2974
GLWrap_.prototype.getProgramBoxExtendVertical = function (progIndex)
2975
{
2976
return this.shaderPrograms[progIndex].extendBoxVertical;
2977
};
2978
GLWrap_.prototype.getProgramParameterType = function (progIndex, paramIndex)
2979
{
2980
return this.shaderPrograms[progIndex].parameters[paramIndex][2];
2981
};
2982
GLWrap_.prototype.programIsAnimated = function (progIndex)
2983
{
2984
return this.shaderPrograms[progIndex].animated;
2985
};
2986
GLWrap_.prototype.setProgramParameters = function (backTex, pixelWidth, pixelHeight, destStartX, destStartY, destEndX, destEndY, layerScale, layerAngle, viewOriginLeft, viewOriginTop, scrollPosX, scrollPosY, seconds, params)
2987
{
2988
var i, len;
2989
var s = this.shaderPrograms[this.lastProgram];
2990
var b, mat4param, shaderParams;
2991
if (s.hasAnyOptionalUniforms || params.length)
2992
{
2993
b = this.pushBatch();
2994
b.type = BATCH_SETPROGRAMPARAMETERS;
2995
if (b.mat4param)
2996
mat4.set(this.matMV, b.mat4param);
2997
else
2998
b.mat4param = mat4.create();
2999
mat4param = b.mat4param;
3000
mat4param[0] = pixelWidth;
3001
mat4param[1] = pixelHeight;
3002
mat4param[2] = destStartX;
3003
mat4param[3] = destStartY;
3004
mat4param[4] = destEndX;
3005
mat4param[5] = destEndY;
3006
mat4param[6] = layerScale;
3007
mat4param[7] = layerAngle;
3008
mat4param[8] = viewOriginLeft;
3009
mat4param[9] = viewOriginTop;
3010
mat4param[10] = scrollPosX;
3011
mat4param[11] = scrollPosY;
3012
mat4param[12] = seconds;
3013
if (s.locSamplerBack)
3014
{
3015
;
3016
b.texParam = backTex;
3017
}
3018
else
3019
b.texParam = null;
3020
if (params.length)
3021
{
3022
shaderParams = b.shaderParams;
3023
shaderParams.length = params.length;
3024
for (i = 0, len = params.length; i < len; i++)
3025
shaderParams[i] = params[i];
3026
}
3027
this.hasQuadBatchTop = false;
3028
this.hasPointBatchTop = false;
3029
}
3030
};
3031
GLWrap_.prototype.clear = function (r, g, b_, a)
3032
{
3033
var b = this.pushBatch();
3034
b.type = BATCH_CLEAR;
3035
b.startIndex = 0; // clear all mode
3036
if (!b.mat4param)
3037
b.mat4param = mat4.create();
3038
b.mat4param[0] = r;
3039
b.mat4param[1] = g;
3040
b.mat4param[2] = b_;
3041
b.mat4param[3] = a;
3042
this.hasQuadBatchTop = false;
3043
this.hasPointBatchTop = false;
3044
};
3045
GLWrap_.prototype.clearRect = function (x, y, w, h)
3046
{
3047
if (w < 0 || h < 0)
3048
return; // invalid clear area
3049
var b = this.pushBatch();
3050
b.type = BATCH_CLEAR;
3051
b.startIndex = 1; // clear rect mode
3052
if (!b.mat4param)
3053
b.mat4param = mat4.create();
3054
b.mat4param[0] = x;
3055
b.mat4param[1] = y;
3056
b.mat4param[2] = w;
3057
b.mat4param[3] = h;
3058
this.hasQuadBatchTop = false;
3059
this.hasPointBatchTop = false;
3060
};
3061
GLWrap_.prototype.clearDepth = function ()
3062
{
3063
var b = this.pushBatch();
3064
b.type = BATCH_CLEAR;
3065
b.startIndex = 2; // clear depth mode
3066
this.hasQuadBatchTop = false;
3067
this.hasPointBatchTop = false;
3068
};
3069
GLWrap_.prototype.setEarlyZPass = function (e)
3070
{
3071
if (!this.enableFrontToBack)
3072
return; // no depth buffer in use
3073
e = !!e;
3074
if (this.isEarlyZPass === e)
3075
return; // no change
3076
var b = this.pushBatch();
3077
b.type = BATCH_SETEARLYZMODE;
3078
b.startIndex = (e ? 1 : 0);
3079
this.hasQuadBatchTop = false;
3080
this.hasPointBatchTop = false;
3081
this.isEarlyZPass = e;
3082
this.renderToTex = null;
3083
if (this.isEarlyZPass)
3084
{
3085
this.switchProgram(2); // early Z program
3086
}
3087
else
3088
{
3089
this.switchProgram(0); // normal rendering
3090
}
3091
};
3092
GLWrap_.prototype.setDepthTestEnabled = function (e)
3093
{
3094
if (!this.enableFrontToBack)
3095
return; // no depth buffer in use
3096
var b = this.pushBatch();
3097
b.type = BATCH_SETDEPTHTEST;
3098
b.startIndex = (e ? 1 : 0);
3099
this.hasQuadBatchTop = false;
3100
this.hasPointBatchTop = false;
3101
};
3102
GLWrap_.prototype.fullscreenQuad = function ()
3103
{
3104
mat4.set(this.lastMV, tempMat4);
3105
this.resetModelView();
3106
this.updateModelView();
3107
var halfw = this.width / 2;
3108
var halfh = this.height / 2;
3109
this.quad(-halfw, halfh, halfw, halfh, halfw, -halfh, -halfw, -halfh);
3110
mat4.set(tempMat4, this.matMV);
3111
this.updateModelView();
3112
};
3113
GLWrap_.prototype.setColorFillMode = function (r_, g_, b_, a_)
3114
{
3115
this.switchProgram(3);
3116
var b = this.pushBatch();
3117
b.type = BATCH_SETCOLOR;
3118
if (!b.mat4param)
3119
b.mat4param = mat4.create();
3120
b.mat4param[0] = r_;
3121
b.mat4param[1] = g_;
3122
b.mat4param[2] = b_;
3123
b.mat4param[3] = a_;
3124
this.hasQuadBatchTop = false;
3125
this.hasPointBatchTop = false;
3126
};
3127
GLWrap_.prototype.setTextureFillMode = function ()
3128
{
3129
;
3130
this.switchProgram(0);
3131
};
3132
GLWrap_.prototype.restoreEarlyZMode = function ()
3133
{
3134
;
3135
this.switchProgram(2);
3136
};
3137
GLWrap_.prototype.present = function ()
3138
{
3139
this.endBatch();
3140
this.gl.flush();
3141
/*
3142
if (debugBatch)
3143
{
3144
;
3145
debugBatch = false;
3146
}
3147
*/
3148
};
3149
function nextHighestPowerOfTwo(x) {
3150
--x;
3151
for (var i = 1; i < 32; i <<= 1) {
3152
x = x | x >> i;
3153
}
3154
return x + 1;
3155
}
3156
var all_textures = [];
3157
var textures_by_src = {};
3158
GLWrap_.prototype.contextLost = function ()
3159
{
3160
cr.clearArray(all_textures);
3161
textures_by_src = {};
3162
};
3163
var BF_RGBA8 = 0;
3164
var BF_RGB8 = 1;
3165
var BF_RGBA4 = 2;
3166
var BF_RGB5_A1 = 3;
3167
var BF_RGB565 = 4;
3168
GLWrap_.prototype.loadTexture = function (img, tiling, linearsampling, pixelformat, tiletype, nomip)
3169
{
3170
tiling = !!tiling;
3171
linearsampling = !!linearsampling;
3172
var tex_key = img.src + "," + tiling + "," + linearsampling + (tiling ? ("," + tiletype) : "");
3173
var webGL_texture = null;
3174
if (typeof img.src !== "undefined" && textures_by_src.hasOwnProperty(tex_key))
3175
{
3176
webGL_texture = textures_by_src[tex_key];
3177
webGL_texture.c2refcount++;
3178
return webGL_texture;
3179
}
3180
this.endBatch();
3181
;
3182
var gl = this.gl;
3183
var isPOT = (cr.isPOT(img.width) && cr.isPOT(img.height));
3184
webGL_texture = gl.createTexture();
3185
gl.bindTexture(gl.TEXTURE_2D, webGL_texture);
3186
gl.pixelStorei(gl["UNPACK_PREMULTIPLY_ALPHA_WEBGL"], true);
3187
var internalformat = gl.RGBA;
3188
var format = gl.RGBA;
3189
var type = gl.UNSIGNED_BYTE;
3190
if (pixelformat && !this.isIE)
3191
{
3192
switch (pixelformat) {
3193
case BF_RGB8:
3194
internalformat = gl.RGB;
3195
format = gl.RGB;
3196
break;
3197
case BF_RGBA4:
3198
type = gl.UNSIGNED_SHORT_4_4_4_4;
3199
break;
3200
case BF_RGB5_A1:
3201
type = gl.UNSIGNED_SHORT_5_5_5_1;
3202
break;
3203
case BF_RGB565:
3204
internalformat = gl.RGB;
3205
format = gl.RGB;
3206
type = gl.UNSIGNED_SHORT_5_6_5;
3207
break;
3208
}
3209
}
3210
if (this.version === 1 && !isPOT && tiling)
3211
{
3212
var canvas = document.createElement("canvas");
3213
canvas.width = cr.nextHighestPowerOfTwo(img.width);
3214
canvas.height = cr.nextHighestPowerOfTwo(img.height);
3215
var ctx = canvas.getContext("2d");
3216
if (typeof ctx["imageSmoothingEnabled"] !== "undefined")
3217
{
3218
ctx["imageSmoothingEnabled"] = linearsampling;
3219
}
3220
else
3221
{
3222
ctx["webkitImageSmoothingEnabled"] = linearsampling;
3223
ctx["mozImageSmoothingEnabled"] = linearsampling;
3224
ctx["msImageSmoothingEnabled"] = linearsampling;
3225
}
3226
ctx.drawImage(img,
3227
0, 0, img.width, img.height,
3228
0, 0, canvas.width, canvas.height);
3229
gl.texImage2D(gl.TEXTURE_2D, 0, internalformat, format, type, canvas);
3230
}
3231
else
3232
gl.texImage2D(gl.TEXTURE_2D, 0, internalformat, format, type, img);
3233
if (tiling)
3234
{
3235
if (tiletype === "repeat-x")
3236
{
3237
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
3238
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
3239
}
3240
else if (tiletype === "repeat-y")
3241
{
3242
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
3243
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
3244
}
3245
else
3246
{
3247
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
3248
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
3249
}
3250
}
3251
else
3252
{
3253
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
3254
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
3255
}
3256
if (linearsampling)
3257
{
3258
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
3259
if ((isPOT || this.version >= 2) && this.enable_mipmaps && !nomip)
3260
{
3261
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
3262
gl.generateMipmap(gl.TEXTURE_2D);
3263
}
3264
else
3265
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
3266
}
3267
else
3268
{
3269
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
3270
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
3271
}
3272
gl.bindTexture(gl.TEXTURE_2D, null);
3273
this.lastTexture0 = null;
3274
webGL_texture.c2width = img.width;
3275
webGL_texture.c2height = img.height;
3276
webGL_texture.c2refcount = 1;
3277
webGL_texture.c2texkey = tex_key;
3278
all_textures.push(webGL_texture);
3279
textures_by_src[tex_key] = webGL_texture;
3280
return webGL_texture;
3281
};
3282
GLWrap_.prototype.createEmptyTexture = function (w, h, linearsampling, _16bit, tiling)
3283
{
3284
this.endBatch();
3285
var gl = this.gl;
3286
if (this.isIE)
3287
_16bit = false;
3288
var webGL_texture = gl.createTexture();
3289
gl.bindTexture(gl.TEXTURE_2D, webGL_texture);
3290
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);
3291
if (tiling)
3292
{
3293
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
3294
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
3295
}
3296
else
3297
{
3298
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
3299
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
3300
}
3301
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, linearsampling ? gl.LINEAR : gl.NEAREST);
3302
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, linearsampling ? gl.LINEAR : gl.NEAREST);
3303
gl.bindTexture(gl.TEXTURE_2D, null);
3304
this.lastTexture0 = null;
3305
webGL_texture.c2width = w;
3306
webGL_texture.c2height = h;
3307
all_textures.push(webGL_texture);
3308
return webGL_texture;
3309
};
3310
GLWrap_.prototype.videoToTexture = function (video_, texture_, _16bit)
3311
{
3312
this.endBatch();
3313
var gl = this.gl;
3314
if (this.isIE)
3315
_16bit = false;
3316
gl.bindTexture(gl.TEXTURE_2D, texture_);
3317
gl.pixelStorei(gl["UNPACK_PREMULTIPLY_ALPHA_WEBGL"], true);
3318
try {
3319
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, _16bit ? gl.UNSIGNED_SHORT_4_4_4_4 : gl.UNSIGNED_BYTE, video_);
3320
}
3321
catch (e)
3322
{
3323
if (console && console.error)
3324
console.error("Error updating WebGL texture: ", e);
3325
}
3326
gl.bindTexture(gl.TEXTURE_2D, null);
3327
this.lastTexture0 = null;
3328
};
3329
GLWrap_.prototype.deleteTexture = function (tex)
3330
{
3331
if (!tex)
3332
return;
3333
if (typeof tex.c2refcount !== "undefined" && tex.c2refcount > 1)
3334
{
3335
tex.c2refcount--;
3336
return;
3337
}
3338
this.endBatch();
3339
if (tex === this.lastTexture0)
3340
{
3341
this.gl.bindTexture(this.gl.TEXTURE_2D, null);
3342
this.lastTexture0 = null;
3343
}
3344
if (tex === this.lastTexture1)
3345
{
3346
this.gl.activeTexture(this.gl.TEXTURE1);
3347
this.gl.bindTexture(this.gl.TEXTURE_2D, null);
3348
this.gl.activeTexture(this.gl.TEXTURE0);
3349
this.lastTexture1 = null;
3350
}
3351
cr.arrayFindRemove(all_textures, tex);
3352
if (typeof tex.c2texkey !== "undefined")
3353
delete textures_by_src[tex.c2texkey];
3354
this.gl.deleteTexture(tex);
3355
};
3356
GLWrap_.prototype.estimateVRAM = function ()
3357
{
3358
var total = this.width * this.height * 4 * 2;
3359
var i, len, t;
3360
for (i = 0, len = all_textures.length; i < len; i++)
3361
{
3362
t = all_textures[i];
3363
total += (t.c2width * t.c2height * 4);
3364
}
3365
return total;
3366
};
3367
GLWrap_.prototype.textureCount = function ()
3368
{
3369
return all_textures.length;
3370
};
3371
GLWrap_.prototype.setRenderingToTexture = function (tex)
3372
{
3373
if (tex === this.renderToTex)
3374
return;
3375
;
3376
var b = this.pushBatch();
3377
b.type = BATCH_RENDERTOTEXTURE;
3378
b.texParam = tex;
3379
this.renderToTex = tex;
3380
this.hasQuadBatchTop = false;
3381
this.hasPointBatchTop = false;
3382
};
3383
cr.GLWrap = GLWrap_;
3384
}());
3385
;
3386
(function()
3387
{
3388
var raf = window["requestAnimationFrame"] ||
3389
window["mozRequestAnimationFrame"] ||
3390
window["webkitRequestAnimationFrame"] ||
3391
window["msRequestAnimationFrame"] ||
3392
window["oRequestAnimationFrame"];
3393
function Runtime(canvas)
3394
{
3395
if (!canvas || (!canvas.getContext && !canvas["dc"]))
3396
return;
3397
if (canvas["c2runtime"])
3398
return;
3399
else
3400
canvas["c2runtime"] = this;
3401
var self = this;
3402
this.isCrosswalk = /crosswalk/i.test(navigator.userAgent) || /xwalk/i.test(navigator.userAgent) || !!(typeof window["c2isCrosswalk"] !== "undefined" && window["c2isCrosswalk"]);
3403
this.isCordova = this.isCrosswalk || (typeof window["device"] !== "undefined" && (typeof window["device"]["cordova"] !== "undefined" || typeof window["device"]["phonegap"] !== "undefined")) || (typeof window["c2iscordova"] !== "undefined" && window["c2iscordova"]);
3404
this.isPhoneGap = this.isCordova;
3405
this.isDirectCanvas = !!canvas["dc"];
3406
this.isAppMobi = (typeof window["AppMobi"] !== "undefined" || this.isDirectCanvas);
3407
this.isCocoonJs = !!window["c2cocoonjs"];
3408
this.isEjecta = !!window["c2ejecta"];
3409
if (this.isCocoonJs)
3410
{
3411
CocoonJS["App"]["onSuspended"].addEventListener(function() {
3412
self["setSuspended"](true);
3413
});
3414
CocoonJS["App"]["onActivated"].addEventListener(function () {
3415
self["setSuspended"](false);
3416
});
3417
}
3418
if (this.isEjecta)
3419
{
3420
document.addEventListener("pagehide", function() {
3421
self["setSuspended"](true);
3422
});
3423
document.addEventListener("pageshow", function() {
3424
self["setSuspended"](false);
3425
});
3426
document.addEventListener("resize", function () {
3427
self["setSize"](window.innerWidth, window.innerHeight);
3428
});
3429
}
3430
this.isDomFree = (this.isDirectCanvas || this.isCocoonJs || this.isEjecta);
3431
this.isMicrosoftEdge = /edge\//i.test(navigator.userAgent);
3432
this.isIE = (/msie/i.test(navigator.userAgent) || /trident/i.test(navigator.userAgent) || /iemobile/i.test(navigator.userAgent)) && !this.isMicrosoftEdge;
3433
this.isTizen = /tizen/i.test(navigator.userAgent);
3434
this.isAndroid = /android/i.test(navigator.userAgent) && !this.isTizen && !this.isIE && !this.isMicrosoftEdge; // IE mobile and Tizen masquerade as Android
3435
this.isiPhone = (/iphone/i.test(navigator.userAgent) || /ipod/i.test(navigator.userAgent)) && !this.isIE && !this.isMicrosoftEdge; // treat ipod as an iphone; IE mobile masquerades as iPhone
3436
this.isiPad = /ipad/i.test(navigator.userAgent);
3437
this.isiOS = this.isiPhone || this.isiPad || this.isEjecta;
3438
this.isiPhoneiOS6 = (this.isiPhone && /os\s6/i.test(navigator.userAgent));
3439
this.isChrome = (/chrome/i.test(navigator.userAgent) || /chromium/i.test(navigator.userAgent)) && !this.isIE && !this.isMicrosoftEdge; // note true on Chromium-based webview on Android 4.4+; IE 'Edge' mode also pretends to be Chrome
3440
this.isAmazonWebApp = /amazonwebappplatform/i.test(navigator.userAgent);
3441
this.isFirefox = /firefox/i.test(navigator.userAgent);
3442
this.isSafari = /safari/i.test(navigator.userAgent) && !this.isChrome && !this.isIE && !this.isMicrosoftEdge; // Chrome and IE Mobile masquerade as Safari
3443
this.isWindows = /windows/i.test(navigator.userAgent);
3444
this.isNWjs = (typeof window["c2nodewebkit"] !== "undefined" || typeof window["c2nwjs"] !== "undefined" || /nodewebkit/i.test(navigator.userAgent) || /nwjs/i.test(navigator.userAgent));
3445
this.isNodeWebkit = this.isNWjs; // old name for backwards compat
3446
this.isArcade = (typeof window["is_scirra_arcade"] !== "undefined");
3447
this.isWindows8App = !!(typeof window["c2isWindows8"] !== "undefined" && window["c2isWindows8"]);
3448
this.isWindows8Capable = !!(typeof window["c2isWindows8Capable"] !== "undefined" && window["c2isWindows8Capable"]);
3449
this.isWindowsPhone8 = !!(typeof window["c2isWindowsPhone8"] !== "undefined" && window["c2isWindowsPhone8"]);
3450
this.isWindowsPhone81 = !!(typeof window["c2isWindowsPhone81"] !== "undefined" && window["c2isWindowsPhone81"]);
3451
this.isWindows10 = !!window["cr_windows10"];
3452
this.isWinJS = (this.isWindows8App || this.isWindows8Capable || this.isWindowsPhone81 || this.isWindows10); // note not WP8.0
3453
this.isBlackberry10 = !!(typeof window["c2isBlackberry10"] !== "undefined" && window["c2isBlackberry10"]);
3454
this.isAndroidStockBrowser = (this.isAndroid && !this.isChrome && !this.isCrosswalk && !this.isFirefox && !this.isAmazonWebApp && !this.isDomFree);
3455
this.devicePixelRatio = 1;
3456
this.isMobile = (this.isCordova || this.isCrosswalk || this.isAppMobi || this.isCocoonJs || this.isAndroid || this.isiOS || this.isWindowsPhone8 || this.isWindowsPhone81 || this.isBlackberry10 || this.isTizen || this.isEjecta);
3457
if (!this.isMobile)
3458
{
3459
this.isMobile = /(blackberry|bb10|playbook|palm|symbian|nokia|windows\s+ce|phone|mobile|tablet|kindle|silk)/i.test(navigator.userAgent);
3460
}
3461
this.isWKWebView = !!(this.isiOS && this.isCordova && window["webkit"]);
3462
if (typeof cr_is_preview !== "undefined" && !this.isNWjs && (window.location.search === "?nw" || /nodewebkit/i.test(navigator.userAgent) || /nwjs/i.test(navigator.userAgent)))
3463
{
3464
this.isNWjs = true;
3465
}
3466
this.isDebug = (typeof cr_is_preview !== "undefined" && window.location.search.indexOf("debug") > -1);
3467
this.canvas = canvas;
3468
this.canvasdiv = document.getElementById("c2canvasdiv");
3469
this.gl = null;
3470
this.glwrap = null;
3471
this.glUnmaskedRenderer = "(unavailable)";
3472
this.enableFrontToBack = false;
3473
this.earlyz_index = 0;
3474
this.ctx = null;
3475
this.firstInFullscreen = false;
3476
this.oldWidth = 0; // for restoring non-fullscreen canvas after fullscreen
3477
this.oldHeight = 0;
3478
this.canvas.oncontextmenu = function (e) { if (e.preventDefault) e.preventDefault(); return false; };
3479
this.canvas.onselectstart = function (e) { if (e.preventDefault) e.preventDefault(); return false; };
3480
this.canvas.ontouchstart = function (e) { if(e.preventDefault) e.preventDefault(); return false; };
3481
if (this.isDirectCanvas)
3482
window["c2runtime"] = this;
3483
if (this.isNWjs)
3484
{
3485
window["ondragover"] = function(e) { e.preventDefault(); return false; };
3486
window["ondrop"] = function(e) { e.preventDefault(); return false; };
3487
if (window["nwgui"] && window["nwgui"]["App"]["clearCache"])
3488
window["nwgui"]["App"]["clearCache"]();
3489
}
3490
if (this.isAndroidStockBrowser && typeof jQuery !== "undefined")
3491
{
3492
jQuery("canvas").parents("*").css("overflow", "visible");
3493
}
3494
this.width = canvas.width;
3495
this.height = canvas.height;
3496
this.draw_width = this.width;
3497
this.draw_height = this.height;
3498
this.cssWidth = this.width;
3499
this.cssHeight = this.height;
3500
this.lastWindowWidth = window.innerWidth;
3501
this.lastWindowHeight = window.innerHeight;
3502
this.forceCanvasAlpha = false; // note: now unused, left for backwards compat since plugins could modify it
3503
this.redraw = true;
3504
this.isSuspended = false;
3505
if (!Date.now) {
3506
Date.now = function now() {
3507
return +new Date();
3508
};
3509
}
3510
this.plugins = [];
3511
this.types = {};
3512
this.types_by_index = [];
3513
this.behaviors = [];
3514
this.layouts = {};
3515
this.layouts_by_index = [];
3516
this.eventsheets = {};
3517
this.eventsheets_by_index = [];
3518
this.wait_for_textures = []; // for blocking until textures loaded
3519
this.triggers_to_postinit = [];
3520
this.all_global_vars = [];
3521
this.all_local_vars = [];
3522
this.solidBehavior = null;
3523
this.jumpthruBehavior = null;
3524
this.shadowcasterBehavior = null;
3525
this.deathRow = {};
3526
this.hasPendingInstances = false; // true if anything exists in create row or death row
3527
this.isInClearDeathRow = false;
3528
this.isInOnDestroy = 0; // needs to support recursion so increments and decrements and is true if > 0
3529
this.isRunningEvents = false;
3530
this.isEndingLayout = false;
3531
this.createRow = [];
3532
this.isLoadingState = false;
3533
this.saveToSlot = "";
3534
this.loadFromSlot = "";
3535
this.loadFromJson = null; // set to string when there is something to try to load
3536
this.lastSaveJson = "";
3537
this.signalledContinuousPreview = false;
3538
this.suspendDrawing = false; // for hiding display until continuous preview loads
3539
this.fireOnCreateAfterLoad = []; // for delaying "On create" triggers until loading complete
3540
this.dt = 0;
3541
this.dt1 = 0;
3542
this.minimumFramerate = 30;
3543
this.logictime = 0; // used to calculate CPUUtilisation
3544
this.cpuutilisation = 0;
3545
this.timescale = 1.0;
3546
this.kahanTime = new cr.KahanAdder();
3547
this.wallTime = new cr.KahanAdder();
3548
this.last_tick_time = 0;
3549
this.fps = 0;
3550
this.last_fps_time = 0;
3551
this.tickcount = 0;
3552
this.tickcount_nosave = 0; // same as tickcount but never saved/loaded
3553
this.execcount = 0;
3554
this.framecount = 0; // for fps
3555
this.objectcount = 0;
3556
this.changelayout = null;
3557
this.destroycallbacks = [];
3558
this.event_stack = [];
3559
this.event_stack_index = -1;
3560
this.localvar_stack = [[]];
3561
this.localvar_stack_index = 0;
3562
this.trigger_depth = 0; // recursion depth for triggers
3563
this.pushEventStack(null);
3564
this.loop_stack = [];
3565
this.loop_stack_index = -1;
3566
this.next_uid = 0;
3567
this.next_puid = 0; // permanent unique ids
3568
this.layout_first_tick = true;
3569
this.family_count = 0;
3570
this.suspend_events = [];
3571
this.raf_id = -1;
3572
this.timeout_id = -1;
3573
this.isloading = true;
3574
this.loadingprogress = 0;
3575
this.isNodeFullscreen = false;
3576
this.stackLocalCount = 0; // number of stack-based local vars for recursion
3577
this.audioInstance = null;
3578
this.had_a_click = false;
3579
this.isInUserInputEvent = false;
3580
this.objects_to_pretick = new cr.ObjectSet();
3581
this.objects_to_tick = new cr.ObjectSet();
3582
this.objects_to_tick2 = new cr.ObjectSet();
3583
this.registered_collisions = [];
3584
this.temp_poly = new cr.CollisionPoly([]);
3585
this.temp_poly2 = new cr.CollisionPoly([]);
3586
this.allGroups = []; // array of all event groups
3587
this.groups_by_name = {};
3588
this.cndsBySid = {};
3589
this.actsBySid = {};
3590
this.varsBySid = {};
3591
this.blocksBySid = {};
3592
this.running_layout = null; // currently running layout
3593
this.layer_canvas = null; // for layers "render-to-texture"
3594
this.layer_ctx = null;
3595
this.layer_tex = null;
3596
this.layout_tex = null;
3597
this.layout_canvas = null;
3598
this.layout_ctx = null;
3599
this.is_WebGL_context_lost = false;
3600
this.uses_background_blending = false; // if any shader uses background blending, so entire layout renders to texture
3601
this.fx_tex = [null, null];
3602
this.fullscreen_scaling = 0;
3603
this.files_subfolder = ""; // path with project files
3604
this.objectsByUid = {}; // maps every in-use UID (as a string) to its instance
3605
this.loaderlogos = null;
3606
this.snapshotCanvas = null;
3607
this.snapshotData = "";
3608
this.objectRefTable = [];
3609
this.requestProjectData();
3610
};
3611
Runtime.prototype.requestProjectData = function ()
3612
{
3613
var self = this;
3614
if (this.isWKWebView)
3615
{
3616
this.fetchLocalFileViaCordovaAsText("data.js", function (str)
3617
{
3618
self.loadProject(JSON.parse(str));
3619
}, function (err)
3620
{
3621
alert("Error fetching data.js");
3622
});
3623
return;
3624
}
3625
var xhr;
3626
if (this.isWindowsPhone8)
3627
xhr = new ActiveXObject("Microsoft.XMLHTTP");
3628
else
3629
xhr = new XMLHttpRequest();
3630
var datajs_filename = "data.js";
3631
if (this.isWindows8App || this.isWindowsPhone8 || this.isWindowsPhone81 || this.isWindows10)
3632
datajs_filename = "data.json";
3633
xhr.open("GET", datajs_filename, true);
3634
var supportsJsonResponse = false;
3635
if (!this.isDomFree && ("response" in xhr) && ("responseType" in xhr))
3636
{
3637
try {
3638
xhr["responseType"] = "json";
3639
supportsJsonResponse = (xhr["responseType"] === "json");
3640
}
3641
catch (e) {
3642
supportsJsonResponse = false;
3643
}
3644
}
3645
if (!supportsJsonResponse && ("responseType" in xhr))
3646
{
3647
try {
3648
xhr["responseType"] = "text";
3649
}
3650
catch (e) {}
3651
}
3652
if ("overrideMimeType" in xhr)
3653
{
3654
try {
3655
xhr["overrideMimeType"]("application/json; charset=utf-8");
3656
}
3657
catch (e) {}
3658
}
3659
if (this.isWindowsPhone8)
3660
{
3661
xhr.onreadystatechange = function ()
3662
{
3663
if (xhr.readyState !== 4)
3664
return;
3665
self.loadProject(JSON.parse(xhr["responseText"]));
3666
};
3667
}
3668
else
3669
{
3670
xhr.onload = function ()
3671
{
3672
if (supportsJsonResponse)
3673
{
3674
self.loadProject(xhr["response"]); // already parsed by browser
3675
}
3676
else
3677
{
3678
if (self.isEjecta)
3679
{
3680
var str = xhr["responseText"];
3681
str = str.substr(str.indexOf("{")); // trim any BOM
3682
self.loadProject(JSON.parse(str));
3683
}
3684
else
3685
{
3686
self.loadProject(JSON.parse(xhr["responseText"])); // forced to sync parse JSON
3687
}
3688
}
3689
};
3690
xhr.onerror = function (e)
3691
{
3692
cr.logerror("Error requesting " + datajs_filename + ":");
3693
cr.logerror(e);
3694
};
3695
}
3696
xhr.send();
3697
};
3698
Runtime.prototype.initRendererAndLoader = function ()
3699
{
3700
var self = this;
3701
var i, len, j, lenj, k, lenk, t, s, l, y;
3702
this.isRetina = ((!this.isDomFree || this.isEjecta || this.isCordova) && this.useHighDpi && !this.isAndroidStockBrowser);
3703
if (this.fullscreen_mode === 0 && this.isiOS)
3704
this.isRetina = false;
3705
this.devicePixelRatio = (this.isRetina ? (window["devicePixelRatio"] || window["webkitDevicePixelRatio"] || window["mozDevicePixelRatio"] || window["msDevicePixelRatio"] || 1) : 1);
3706
if (typeof window["StatusBar"] === "object")
3707
window["StatusBar"]["hide"]();
3708
this.ClearDeathRow();
3709
var attribs;
3710
if (this.fullscreen_mode > 0)
3711
this["setSize"](window.innerWidth, window.innerHeight, true);
3712
this.canvas.addEventListener("webglcontextlost", function (ev) {
3713
ev.preventDefault();
3714
self.onContextLost();
3715
cr.logexport("[Construct 2] WebGL context lost");
3716
window["cr_setSuspended"](true); // stop rendering
3717
}, false);
3718
this.canvas.addEventListener("webglcontextrestored", function (ev) {
3719
self.glwrap.initState();
3720
self.glwrap.setSize(self.glwrap.width, self.glwrap.height, true);
3721
self.layer_tex = null;
3722
self.layout_tex = null;
3723
self.fx_tex[0] = null;
3724
self.fx_tex[1] = null;
3725
self.onContextRestored();
3726
self.redraw = true;
3727
cr.logexport("[Construct 2] WebGL context restored");
3728
window["cr_setSuspended"](false); // resume rendering
3729
}, false);
3730
try {
3731
if (this.enableWebGL && (this.isCocoonJs || this.isEjecta || !this.isDomFree))
3732
{
3733
attribs = {
3734
"alpha": true,
3735
"depth": false,
3736
"antialias": false,
3737
"powerPreference": "high-performance",
3738
"failIfMajorPerformanceCaveat": true
3739
};
3740
if (!this.isAndroid)
3741
this.gl = this.canvas.getContext("webgl2", attribs);
3742
if (!this.gl)
3743
{
3744
this.gl = (this.canvas.getContext("webgl", attribs) ||
3745
this.canvas.getContext("experimental-webgl", attribs));
3746
}
3747
}
3748
}
3749
catch (e) {
3750
}
3751
if (this.gl)
3752
{
3753
var isWebGL2 = (this.gl.getParameter(this.gl.VERSION).indexOf("WebGL 2") === 0);
3754
var debug_ext = this.gl.getExtension("WEBGL_debug_renderer_info");
3755
if (debug_ext)
3756
{
3757
var unmasked_vendor = this.gl.getParameter(debug_ext.UNMASKED_VENDOR_WEBGL);
3758
var unmasked_renderer = this.gl.getParameter(debug_ext.UNMASKED_RENDERER_WEBGL);
3759
this.glUnmaskedRenderer = unmasked_renderer + " [" + unmasked_vendor + "]";
3760
}
3761
if (this.enableFrontToBack)
3762
this.glUnmaskedRenderer += " [front-to-back enabled]";
3763
;
3764
if (!this.isDomFree)
3765
{
3766
this.overlay_canvas = document.createElement("canvas");
3767
jQuery(this.overlay_canvas).appendTo(this.canvas.parentNode);
3768
this.overlay_canvas.oncontextmenu = function (e) { return false; };
3769
this.overlay_canvas.onselectstart = function (e) { return false; };
3770
this.overlay_canvas.width = Math.round(this.cssWidth * this.devicePixelRatio);
3771
this.overlay_canvas.height = Math.round(this.cssHeight * this.devicePixelRatio);
3772
jQuery(this.overlay_canvas).css({"width": this.cssWidth + "px",
3773
"height": this.cssHeight + "px"});
3774
this.positionOverlayCanvas();
3775
this.overlay_ctx = this.overlay_canvas.getContext("2d");
3776
}
3777
this.glwrap = new cr.GLWrap(this.gl, this.isMobile, this.enableFrontToBack);
3778
this.glwrap.setSize(this.canvas.width, this.canvas.height);
3779
this.glwrap.enable_mipmaps = (this.downscalingQuality !== 0);
3780
this.ctx = null;
3781
for (i = 0, len = this.types_by_index.length; i < len; i++)
3782
{
3783
t = this.types_by_index[i];
3784
for (j = 0, lenj = t.effect_types.length; j < lenj; j++)
3785
{
3786
s = t.effect_types[j];
3787
s.shaderindex = this.glwrap.getShaderIndex(s.id);
3788
s.preservesOpaqueness = this.glwrap.programPreservesOpaqueness(s.shaderindex);
3789
this.uses_background_blending = this.uses_background_blending || this.glwrap.programUsesDest(s.shaderindex);
3790
}
3791
}
3792
for (i = 0, len = this.layouts_by_index.length; i < len; i++)
3793
{
3794
l = this.layouts_by_index[i];
3795
for (j = 0, lenj = l.effect_types.length; j < lenj; j++)
3796
{
3797
s = l.effect_types[j];
3798
s.shaderindex = this.glwrap.getShaderIndex(s.id);
3799
s.preservesOpaqueness = this.glwrap.programPreservesOpaqueness(s.shaderindex);
3800
}
3801
l.updateActiveEffects(); // update preserves opaqueness flag
3802
for (j = 0, lenj = l.layers.length; j < lenj; j++)
3803
{
3804
y = l.layers[j];
3805
for (k = 0, lenk = y.effect_types.length; k < lenk; k++)
3806
{
3807
s = y.effect_types[k];
3808
s.shaderindex = this.glwrap.getShaderIndex(s.id);
3809
s.preservesOpaqueness = this.glwrap.programPreservesOpaqueness(s.shaderindex);
3810
this.uses_background_blending = this.uses_background_blending || this.glwrap.programUsesDest(s.shaderindex);
3811
}
3812
y.updateActiveEffects(); // update preserves opaqueness flag
3813
}
3814
}
3815
}
3816
else
3817
{
3818
if (this.fullscreen_mode > 0 && this.isDirectCanvas)
3819
{
3820
;
3821
this.canvas = null;
3822
document.oncontextmenu = function (e) { return false; };
3823
document.onselectstart = function (e) { return false; };
3824
this.ctx = AppMobi["canvas"]["getContext"]("2d");
3825
try {
3826
this.ctx["samplingMode"] = this.linearSampling ? "smooth" : "sharp";
3827
this.ctx["globalScale"] = 1;
3828
this.ctx["HTML5CompatibilityMode"] = true;
3829
this.ctx["imageSmoothingEnabled"] = this.linearSampling;
3830
} catch(e){}
3831
if (this.width !== 0 && this.height !== 0)
3832
{
3833
this.ctx.width = this.width;
3834
this.ctx.height = this.height;
3835
}
3836
}
3837
if (!this.ctx)
3838
{
3839
;
3840
if (this.isCocoonJs)
3841
{
3842
attribs = {
3843
"antialias": !!this.linearSampling,
3844
"alpha": true
3845
};
3846
this.ctx = this.canvas.getContext("2d", attribs);
3847
}
3848
else
3849
{
3850
attribs = {
3851
"alpha": true
3852
};
3853
this.ctx = this.canvas.getContext("2d", attribs);
3854
}
3855
this.setCtxImageSmoothingEnabled(this.ctx, this.linearSampling);
3856
}
3857
this.overlay_canvas = null;
3858
this.overlay_ctx = null;
3859
}
3860
this.tickFunc = function (timestamp) { self.tick(false, timestamp); };
3861
if (window != window.top && !this.isDomFree && !this.isWinJS && !this.isWindowsPhone8)
3862
{
3863
document.addEventListener("mousedown", function () {
3864
window.focus();
3865
}, true);
3866
document.addEventListener("touchstart", function () {
3867
window.focus();
3868
}, true);
3869
}
3870
if (typeof cr_is_preview !== "undefined")
3871
{
3872
if (this.isCocoonJs)
3873
console.log("[Construct 2] In preview-over-wifi via CocoonJS mode");
3874
if (window.location.search.indexOf("continuous") > -1)
3875
{
3876
cr.logexport("Reloading for continuous preview");
3877
this.loadFromSlot = "__c2_continuouspreview";
3878
this.suspendDrawing = true;
3879
}
3880
if (this.pauseOnBlur && !this.isMobile)
3881
{
3882
jQuery(window).focus(function ()
3883
{
3884
self["setSuspended"](false);
3885
});
3886
jQuery(window).blur(function ()
3887
{
3888
var parent = window.parent;
3889
if (!parent || !parent.document.hasFocus())
3890
self["setSuspended"](true);
3891
});
3892
}
3893
}
3894
window.addEventListener("blur", function () {
3895
self.onWindowBlur();
3896
});
3897
if (!this.isDomFree)
3898
{
3899
var unfocusFormControlFunc = function (e) {
3900
if (cr.isCanvasInputEvent(e) && document["activeElement"] && document["activeElement"] !== document.getElementsByTagName("body")[0] && document["activeElement"].blur)
3901
{
3902
try {
3903
document["activeElement"].blur();
3904
}
3905
catch (e) {}
3906
}
3907
}
3908
if (typeof PointerEvent !== "undefined")
3909
{
3910
document.addEventListener("pointerdown", unfocusFormControlFunc);
3911
}
3912
else if (window.navigator["msPointerEnabled"])
3913
{
3914
document.addEventListener("MSPointerDown", unfocusFormControlFunc);
3915
}
3916
else
3917
{
3918
document.addEventListener("touchstart", unfocusFormControlFunc);
3919
}
3920
document.addEventListener("mousedown", unfocusFormControlFunc);
3921
}
3922
if (this.fullscreen_mode === 0 && this.isRetina && this.devicePixelRatio > 1)
3923
{
3924
this["setSize"](this.original_width, this.original_height, true);
3925
}
3926
this.tryLockOrientation();
3927
this.getready(); // determine things to preload
3928
this.go(); // run loading screen
3929
this.extra = {};
3930
cr.seal(this);
3931
};
3932
var webkitRepaintFlag = false;
3933
Runtime.prototype["setSize"] = function (w, h, force)
3934
{
3935
var offx = 0, offy = 0;
3936
var neww = 0, newh = 0, intscale = 0;
3937
if (this.lastWindowWidth === w && this.lastWindowHeight === h && !force)
3938
return;
3939
this.lastWindowWidth = w;
3940
this.lastWindowHeight = h;
3941
var mode = this.fullscreen_mode;
3942
var orig_aspect, cur_aspect;
3943
var isfullscreen = (document["mozFullScreen"] || document["webkitIsFullScreen"] || !!document["msFullscreenElement"] || document["fullScreen"] || this.isNodeFullscreen) && !this.isCordova;
3944
if (!isfullscreen && this.fullscreen_mode === 0 && !force)
3945
return; // ignore size events when not fullscreen and not using a fullscreen-in-browser mode
3946
if (isfullscreen)
3947
mode = this.fullscreen_scaling;
3948
var dpr = this.devicePixelRatio;
3949
if (mode >= 4)
3950
{
3951
if (mode === 5 && dpr !== 1) // integer scaling
3952
{
3953
w += 1;
3954
h += 1;
3955
}
3956
orig_aspect = this.original_width / this.original_height;
3957
cur_aspect = w / h;
3958
if (cur_aspect > orig_aspect)
3959
{
3960
neww = h * orig_aspect;
3961
if (mode === 5) // integer scaling
3962
{
3963
intscale = (neww * dpr) / this.original_width;
3964
if (intscale > 1)
3965
intscale = Math.floor(intscale);
3966
else if (intscale < 1)
3967
intscale = 1 / Math.ceil(1 / intscale);
3968
neww = this.original_width * intscale / dpr;
3969
newh = this.original_height * intscale / dpr;
3970
offx = (w - neww) / 2;
3971
offy = (h - newh) / 2;
3972
w = neww;
3973
h = newh;
3974
}
3975
else
3976
{
3977
offx = (w - neww) / 2;
3978
w = neww;
3979
}
3980
}
3981
else
3982
{
3983
newh = w / orig_aspect;
3984
if (mode === 5) // integer scaling
3985
{
3986
intscale = (newh * dpr) / this.original_height;
3987
if (intscale > 1)
3988
intscale = Math.floor(intscale);
3989
else if (intscale < 1)
3990
intscale = 1 / Math.ceil(1 / intscale);
3991
neww = this.original_width * intscale / dpr;
3992
newh = this.original_height * intscale / dpr;
3993
offx = (w - neww) / 2;
3994
offy = (h - newh) / 2;
3995
w = neww;
3996
h = newh;
3997
}
3998
else
3999
{
4000
offy = (h - newh) / 2;
4001
h = newh;
4002
}
4003
}
4004
}
4005
else if (isfullscreen && mode === 0)
4006
{
4007
offx = Math.floor((w - this.original_width) / 2);
4008
offy = Math.floor((h - this.original_height) / 2);
4009
w = this.original_width;
4010
h = this.original_height;
4011
}
4012
if (mode < 2)
4013
this.aspect_scale = dpr;
4014
this.cssWidth = Math.round(w);
4015
this.cssHeight = Math.round(h);
4016
this.width = Math.round(w * dpr);
4017
this.height = Math.round(h * dpr);
4018
this.redraw = true;
4019
if (this.wantFullscreenScalingQuality)
4020
{
4021
this.draw_width = this.width;
4022
this.draw_height = this.height;
4023
this.fullscreenScalingQuality = true;
4024
}
4025
else
4026
{
4027
if ((this.width < this.original_width && this.height < this.original_height) || mode === 1)
4028
{
4029
this.draw_width = this.width;
4030
this.draw_height = this.height;
4031
this.fullscreenScalingQuality = true;
4032
}
4033
else
4034
{
4035
this.draw_width = this.original_width;
4036
this.draw_height = this.original_height;
4037
this.fullscreenScalingQuality = false;
4038
/*var orig_aspect = this.original_width / this.original_height;
4039
var cur_aspect = this.width / this.height;
4040
if ((this.fullscreen_mode !== 2 && cur_aspect > orig_aspect) || (this.fullscreen_mode === 2 && cur_aspect < orig_aspect))
4041
this.aspect_scale = this.height / this.original_height;
4042
else
4043
this.aspect_scale = this.width / this.original_width;*/
4044
if (mode === 2) // scale inner
4045
{
4046
orig_aspect = this.original_width / this.original_height;
4047
cur_aspect = this.lastWindowWidth / this.lastWindowHeight;
4048
if (cur_aspect < orig_aspect)
4049
this.draw_width = this.draw_height * cur_aspect;
4050
else if (cur_aspect > orig_aspect)
4051
this.draw_height = this.draw_width / cur_aspect;
4052
}
4053
else if (mode === 3)
4054
{
4055
orig_aspect = this.original_width / this.original_height;
4056
cur_aspect = this.lastWindowWidth / this.lastWindowHeight;
4057
if (cur_aspect > orig_aspect)
4058
this.draw_width = this.draw_height * cur_aspect;
4059
else if (cur_aspect < orig_aspect)
4060
this.draw_height = this.draw_width / cur_aspect;
4061
}
4062
}
4063
}
4064
if (this.canvasdiv && !this.isDomFree)
4065
{
4066
jQuery(this.canvasdiv).css({"width": Math.round(w) + "px",
4067
"height": Math.round(h) + "px",
4068
"margin-left": Math.floor(offx) + "px",
4069
"margin-top": Math.floor(offy) + "px"});
4070
if (typeof cr_is_preview !== "undefined")
4071
{
4072
jQuery("#borderwrap").css({"width": Math.round(w) + "px",
4073
"height": Math.round(h) + "px"});
4074
}
4075
}
4076
if (this.canvas)
4077
{
4078
this.canvas.width = Math.round(w * dpr);
4079
this.canvas.height = Math.round(h * dpr);
4080
if (this.isEjecta)
4081
{
4082
this.canvas.style.left = Math.floor(offx) + "px";
4083
this.canvas.style.top = Math.floor(offy) + "px";
4084
this.canvas.style.width = Math.round(w) + "px";
4085
this.canvas.style.height = Math.round(h) + "px";
4086
}
4087
else if (this.isRetina && !this.isDomFree)
4088
{
4089
this.canvas.style.width = Math.round(w) + "px";
4090
this.canvas.style.height = Math.round(h) + "px";
4091
}
4092
}
4093
if (this.overlay_canvas)
4094
{
4095
this.overlay_canvas.width = Math.round(w * dpr);
4096
this.overlay_canvas.height = Math.round(h * dpr);
4097
this.overlay_canvas.style.width = this.cssWidth + "px";
4098
this.overlay_canvas.style.height = this.cssHeight + "px";
4099
}
4100
if (this.glwrap)
4101
{
4102
this.glwrap.setSize(Math.round(w * dpr), Math.round(h * dpr));
4103
}
4104
if (this.isDirectCanvas && this.ctx)
4105
{
4106
this.ctx.width = Math.round(w);
4107
this.ctx.height = Math.round(h);
4108
}
4109
if (this.ctx)
4110
{
4111
this.setCtxImageSmoothingEnabled(this.ctx, this.linearSampling);
4112
}
4113
this.tryLockOrientation();
4114
if (this.isiPhone && !this.isCordova)
4115
{
4116
window.scrollTo(0, 0);
4117
}
4118
};
4119
Runtime.prototype.tryLockOrientation = function ()
4120
{
4121
if (!this.autoLockOrientation || this.orientations === 0)
4122
return;
4123
var orientation = "portrait";
4124
if (this.orientations === 2)
4125
orientation = "landscape";
4126
try {
4127
if (screen["orientation"] && screen["orientation"]["lock"])
4128
screen["orientation"]["lock"](orientation).catch(function(){});
4129
else if (screen["lockOrientation"])
4130
screen["lockOrientation"](orientation);
4131
else if (screen["webkitLockOrientation"])
4132
screen["webkitLockOrientation"](orientation);
4133
else if (screen["mozLockOrientation"])
4134
screen["mozLockOrientation"](orientation);
4135
else if (screen["msLockOrientation"])
4136
screen["msLockOrientation"](orientation);
4137
}
4138
catch (e)
4139
{
4140
if (console && console.warn)
4141
console.warn("Failed to lock orientation: ", e);
4142
}
4143
};
4144
Runtime.prototype.onContextLost = function ()
4145
{
4146
this.glwrap.contextLost();
4147
this.is_WebGL_context_lost = true;
4148
var i, len, t;
4149
for (i = 0, len = this.types_by_index.length; i < len; i++)
4150
{
4151
t = this.types_by_index[i];
4152
if (t.onLostWebGLContext)
4153
t.onLostWebGLContext();
4154
}
4155
};
4156
Runtime.prototype.onContextRestored = function ()
4157
{
4158
this.is_WebGL_context_lost = false;
4159
var i, len, t;
4160
for (i = 0, len = this.types_by_index.length; i < len; i++)
4161
{
4162
t = this.types_by_index[i];
4163
if (t.onRestoreWebGLContext)
4164
t.onRestoreWebGLContext();
4165
}
4166
};
4167
Runtime.prototype.positionOverlayCanvas = function()
4168
{
4169
if (this.isDomFree)
4170
return;
4171
var isfullscreen = (document["mozFullScreen"] || document["webkitIsFullScreen"] || document["fullScreen"] || !!document["msFullscreenElement"] || this.isNodeFullscreen) && !this.isCordova;
4172
var overlay_position = isfullscreen ? jQuery(this.canvas).offset() : jQuery(this.canvas).position();
4173
overlay_position.position = "absolute";
4174
jQuery(this.overlay_canvas).css(overlay_position);
4175
};
4176
var caf = window["cancelAnimationFrame"] ||
4177
window["mozCancelAnimationFrame"] ||
4178
window["webkitCancelAnimationFrame"] ||
4179
window["msCancelAnimationFrame"] ||
4180
window["oCancelAnimationFrame"];
4181
Runtime.prototype["setSuspended"] = function (s)
4182
{
4183
var i, len;
4184
var self = this;
4185
if (s && !this.isSuspended)
4186
{
4187
cr.logexport("[Construct 2] Suspending");
4188
this.isSuspended = true; // next tick will be last
4189
if (this.raf_id !== -1 && caf) // note: CocoonJS does not implement cancelAnimationFrame
4190
caf(this.raf_id);
4191
if (this.timeout_id !== -1)
4192
clearTimeout(this.timeout_id);
4193
for (i = 0, len = this.suspend_events.length; i < len; i++)
4194
this.suspend_events[i](true);
4195
}
4196
else if (!s && this.isSuspended)
4197
{
4198
cr.logexport("[Construct 2] Resuming");
4199
this.isSuspended = false;
4200
this.last_tick_time = cr.performance_now(); // ensure first tick is a zero-dt one
4201
this.last_fps_time = cr.performance_now(); // reset FPS counter
4202
this.framecount = 0;
4203
this.logictime = 0;
4204
for (i = 0, len = this.suspend_events.length; i < len; i++)
4205
this.suspend_events[i](false);
4206
this.tick(false); // kick off runtime again
4207
}
4208
};
4209
Runtime.prototype.addSuspendCallback = function (f)
4210
{
4211
this.suspend_events.push(f);
4212
};
4213
Runtime.prototype.GetObjectReference = function (i)
4214
{
4215
;
4216
return this.objectRefTable[i];
4217
};
4218
Runtime.prototype.loadProject = function (data_response)
4219
{
4220
;
4221
if (!data_response || !data_response["project"])
4222
cr.logerror("Project model unavailable");
4223
var pm = data_response["project"];
4224
this.name = pm[0];
4225
this.first_layout = pm[1];
4226
this.fullscreen_mode = pm[12]; // 0 = off, 1 = crop, 2 = scale inner, 3 = scale outer, 4 = letterbox scale, 5 = integer letterbox scale
4227
this.fullscreen_mode_set = pm[12];
4228
this.original_width = pm[10];
4229
this.original_height = pm[11];
4230
this.parallax_x_origin = this.original_width / 2;
4231
this.parallax_y_origin = this.original_height / 2;
4232
if (this.isDomFree && !this.isEjecta && (pm[12] >= 4 || pm[12] === 0))
4233
{
4234
cr.logexport("[Construct 2] Letterbox scale fullscreen modes are not supported on this platform - falling back to 'Scale outer'");
4235
this.fullscreen_mode = 3;
4236
this.fullscreen_mode_set = 3;
4237
}
4238
this.uses_loader_layout = pm[18];
4239
this.loaderstyle = pm[19];
4240
if (this.loaderstyle === 0)
4241
{
4242
var loaderImage = new Image();
4243
loaderImage.crossOrigin = "anonymous";
4244
this.setImageSrc(loaderImage, "loading-logo.png");
4245
this.loaderlogos = {
4246
logo: loaderImage
4247
};
4248
}
4249
else if (this.loaderstyle === 4) // c2 splash
4250
{
4251
var loaderC2logo_1024 = new Image();
4252
loaderC2logo_1024.src = "";
4253
var loaderC2logo_512 = new Image();
4254
loaderC2logo_512.src = "";
4255
var loaderC2logo_256 = new Image();
4256
loaderC2logo_256.src = "";
4257
var loaderC2logo_128 = new Image();
4258
loaderC2logo_128.src = "";
4259
var loaderPowered_1024 = new Image();
4260
loaderPowered_1024.src = "";
4261
var loaderPowered_512 = new Image();
4262
loaderPowered_512.src = "";
4263
var loaderPowered_256 = new Image();
4264
loaderPowered_256.src = "";
4265
var loaderPowered_128 = new Image();
4266
loaderPowered_128.src = "";
4267
var loaderWebsite_1024 = new Image();
4268
loaderWebsite_1024.src = "";
4269
var loaderWebsite_512 = new Image();
4270
loaderWebsite_512.src = "";
4271
var loaderWebsite_256 = new Image();
4272
loaderWebsite_256.src = "";
4273
var loaderWebsite_128 = new Image();
4274
loaderWebsite_128.src = "";
4275
this.loaderlogos = {
4276
logo: [loaderC2logo_1024, loaderC2logo_512, loaderC2logo_256, loaderC2logo_128],
4277
powered: [loaderPowered_1024, loaderPowered_512, loaderPowered_256, loaderPowered_128],
4278
website: [loaderWebsite_1024, loaderWebsite_512, loaderWebsite_256, loaderWebsite_128]
4279
};
4280
}
4281
this.next_uid = pm[21];
4282
this.objectRefTable = cr.getObjectRefTable();
4283
this.system = new cr.system_object(this);
4284
var i, len, j, lenj, k, lenk, idstr, m, b, t, f, p;
4285
var plugin, plugin_ctor;
4286
for (i = 0, len = pm[2].length; i < len; i++)
4287
{
4288
m = pm[2][i];
4289
p = this.GetObjectReference(m[0]);
4290
;
4291
cr.add_common_aces(m, p.prototype);
4292
plugin = new p(this);
4293
plugin.singleglobal = m[1];
4294
plugin.is_world = m[2];
4295
plugin.is_rotatable = m[5];
4296
plugin.must_predraw = m[9];
4297
if (plugin.onCreate)
4298
plugin.onCreate(); // opportunity to override default ACEs
4299
cr.seal(plugin);
4300
this.plugins.push(plugin);
4301
}
4302
this.objectRefTable = cr.getObjectRefTable();
4303
for (i = 0, len = pm[3].length; i < len; i++)
4304
{
4305
m = pm[3][i];
4306
plugin_ctor = this.GetObjectReference(m[1]);
4307
;
4308
plugin = null;
4309
for (j = 0, lenj = this.plugins.length; j < lenj; j++)
4310
{
4311
if (this.plugins[j] instanceof plugin_ctor)
4312
{
4313
plugin = this.plugins[j];
4314
break;
4315
}
4316
}
4317
;
4318
;
4319
var type_inst = new plugin.Type(plugin);
4320
;
4321
type_inst.name = m[0];
4322
type_inst.is_family = m[2];
4323
type_inst.instvar_sids = m[3].slice(0);
4324
type_inst.vars_count = m[3].length;
4325
type_inst.behs_count = m[4];
4326
type_inst.fx_count = m[5];
4327
type_inst.sid = m[11];
4328
if (type_inst.is_family)
4329
{
4330
type_inst.members = []; // types in this family
4331
type_inst.family_index = this.family_count++;
4332
type_inst.families = null;
4333
}
4334
else
4335
{
4336
type_inst.members = null;
4337
type_inst.family_index = -1;
4338
type_inst.families = []; // families this type belongs to
4339
}
4340
type_inst.family_var_map = null;
4341
type_inst.family_beh_map = null;
4342
type_inst.family_fx_map = null;
4343
type_inst.is_contained = false;
4344
type_inst.container = null;
4345
if (m[6])
4346
{
4347
type_inst.texture_file = m[6][0];
4348
type_inst.texture_filesize = m[6][1];
4349
type_inst.texture_pixelformat = m[6][2];
4350
}
4351
else
4352
{
4353
type_inst.texture_file = null;
4354
type_inst.texture_filesize = 0;
4355
type_inst.texture_pixelformat = 0; // rgba8
4356
}
4357
if (m[7])
4358
{
4359
type_inst.animations = m[7];
4360
}
4361
else
4362
{
4363
type_inst.animations = null;
4364
}
4365
type_inst.index = i; // save index in to types array in type
4366
type_inst.instances = []; // all instances of this type
4367
type_inst.deadCache = []; // destroyed instances to recycle next create
4368
type_inst.solstack = [new cr.selection(type_inst)]; // initialise SOL stack with one empty SOL
4369
type_inst.cur_sol = 0;
4370
type_inst.default_instance = null;
4371
type_inst.default_layerindex = 0;
4372
type_inst.stale_iids = true;
4373
type_inst.updateIIDs = cr.type_updateIIDs;
4374
type_inst.getFirstPicked = cr.type_getFirstPicked;
4375
type_inst.getPairedInstance = cr.type_getPairedInstance;
4376
type_inst.getCurrentSol = cr.type_getCurrentSol;
4377
type_inst.pushCleanSol = cr.type_pushCleanSol;
4378
type_inst.pushCopySol = cr.type_pushCopySol;
4379
type_inst.popSol = cr.type_popSol;
4380
type_inst.getBehaviorByName = cr.type_getBehaviorByName;
4381
type_inst.getBehaviorIndexByName = cr.type_getBehaviorIndexByName;
4382
type_inst.getEffectIndexByName = cr.type_getEffectIndexByName;
4383
type_inst.applySolToContainer = cr.type_applySolToContainer;
4384
type_inst.getInstanceByIID = cr.type_getInstanceByIID;
4385
type_inst.collision_grid = new cr.SparseGrid(this.original_width, this.original_height);
4386
type_inst.any_cell_changed = true;
4387
type_inst.any_instance_parallaxed = false;
4388
type_inst.extra = {};
4389
type_inst.toString = cr.type_toString;
4390
type_inst.behaviors = [];
4391
for (j = 0, lenj = m[8].length; j < lenj; j++)
4392
{
4393
b = m[8][j];
4394
var behavior_ctor = this.GetObjectReference(b[1]);
4395
var behavior_plugin = null;
4396
for (k = 0, lenk = this.behaviors.length; k < lenk; k++)
4397
{
4398
if (this.behaviors[k] instanceof behavior_ctor)
4399
{
4400
behavior_plugin = this.behaviors[k];
4401
break;
4402
}
4403
}
4404
if (!behavior_plugin)
4405
{
4406
behavior_plugin = new behavior_ctor(this);
4407
behavior_plugin.my_types = []; // types using this behavior
4408
behavior_plugin.my_instances = new cr.ObjectSet(); // instances of this behavior
4409
if (behavior_plugin.onCreate)
4410
behavior_plugin.onCreate();
4411
cr.seal(behavior_plugin);
4412
this.behaviors.push(behavior_plugin);
4413
if (cr.behaviors.solid && behavior_plugin instanceof cr.behaviors.solid)
4414
this.solidBehavior = behavior_plugin;
4415
if (cr.behaviors.jumpthru && behavior_plugin instanceof cr.behaviors.jumpthru)
4416
this.jumpthruBehavior = behavior_plugin;
4417
if (cr.behaviors.shadowcaster && behavior_plugin instanceof cr.behaviors.shadowcaster)
4418
this.shadowcasterBehavior = behavior_plugin;
4419
}
4420
if (behavior_plugin.my_types.indexOf(type_inst) === -1)
4421
behavior_plugin.my_types.push(type_inst);
4422
var behavior_type = new behavior_plugin.Type(behavior_plugin, type_inst);
4423
behavior_type.name = b[0];
4424
behavior_type.sid = b[2];
4425
behavior_type.onCreate();
4426
cr.seal(behavior_type);
4427
type_inst.behaviors.push(behavior_type);
4428
}
4429
type_inst.global = m[9];
4430
type_inst.isOnLoaderLayout = m[10];
4431
type_inst.effect_types = [];
4432
for (j = 0, lenj = m[12].length; j < lenj; j++)
4433
{
4434
type_inst.effect_types.push({
4435
id: m[12][j][0],
4436
name: m[12][j][1],
4437
shaderindex: -1,
4438
preservesOpaqueness: false,
4439
active: true,
4440
index: j
4441
});
4442
}
4443
type_inst.tile_poly_data = m[13];
4444
if (!this.uses_loader_layout || type_inst.is_family || type_inst.isOnLoaderLayout || !plugin.is_world)
4445
{
4446
type_inst.onCreate();
4447
cr.seal(type_inst);
4448
}
4449
if (type_inst.name)
4450
this.types[type_inst.name] = type_inst;
4451
this.types_by_index.push(type_inst);
4452
if (plugin.singleglobal)
4453
{
4454
var instance = new plugin.Instance(type_inst);
4455
instance.uid = this.next_uid++;
4456
instance.puid = this.next_puid++;
4457
instance.iid = 0;
4458
instance.get_iid = cr.inst_get_iid;
4459
instance.toString = cr.inst_toString;
4460
instance.properties = m[14];
4461
instance.onCreate();
4462
cr.seal(instance);
4463
type_inst.instances.push(instance);
4464
this.objectsByUid[instance.uid.toString()] = instance;
4465
}
4466
}
4467
for (i = 0, len = pm[4].length; i < len; i++)
4468
{
4469
var familydata = pm[4][i];
4470
var familytype = this.types_by_index[familydata[0]];
4471
var familymember;
4472
for (j = 1, lenj = familydata.length; j < lenj; j++)
4473
{
4474
familymember = this.types_by_index[familydata[j]];
4475
familymember.families.push(familytype);
4476
familytype.members.push(familymember);
4477
}
4478
}
4479
for (i = 0, len = pm[28].length; i < len; i++)
4480
{
4481
var containerdata = pm[28][i];
4482
var containertypes = [];
4483
for (j = 0, lenj = containerdata.length; j < lenj; j++)
4484
containertypes.push(this.types_by_index[containerdata[j]]);
4485
for (j = 0, lenj = containertypes.length; j < lenj; j++)
4486
{
4487
containertypes[j].is_contained = true;
4488
containertypes[j].container = containertypes;
4489
}
4490
}
4491
if (this.family_count > 0)
4492
{
4493
for (i = 0, len = this.types_by_index.length; i < len; i++)
4494
{
4495
t = this.types_by_index[i];
4496
if (t.is_family || !t.families.length)
4497
continue;
4498
t.family_var_map = new Array(this.family_count);
4499
t.family_beh_map = new Array(this.family_count);
4500
t.family_fx_map = new Array(this.family_count);
4501
var all_fx = [];
4502
var varsum = 0;
4503
var behsum = 0;
4504
var fxsum = 0;
4505
for (j = 0, lenj = t.families.length; j < lenj; j++)
4506
{
4507
f = t.families[j];
4508
t.family_var_map[f.family_index] = varsum;
4509
varsum += f.vars_count;
4510
t.family_beh_map[f.family_index] = behsum;
4511
behsum += f.behs_count;
4512
t.family_fx_map[f.family_index] = fxsum;
4513
fxsum += f.fx_count;
4514
for (k = 0, lenk = f.effect_types.length; k < lenk; k++)
4515
all_fx.push(cr.shallowCopy({}, f.effect_types[k]));
4516
}
4517
t.effect_types = all_fx.concat(t.effect_types);
4518
for (j = 0, lenj = t.effect_types.length; j < lenj; j++)
4519
t.effect_types[j].index = j;
4520
}
4521
}
4522
for (i = 0, len = pm[5].length; i < len; i++)
4523
{
4524
m = pm[5][i];
4525
var layout = new cr.layout(this, m);
4526
cr.seal(layout);
4527
this.layouts[layout.name] = layout;
4528
this.layouts_by_index.push(layout);
4529
}
4530
for (i = 0, len = pm[6].length; i < len; i++)
4531
{
4532
m = pm[6][i];
4533
var sheet = new cr.eventsheet(this, m);
4534
cr.seal(sheet);
4535
this.eventsheets[sheet.name] = sheet;
4536
this.eventsheets_by_index.push(sheet);
4537
}
4538
for (i = 0, len = this.eventsheets_by_index.length; i < len; i++)
4539
this.eventsheets_by_index[i].postInit();
4540
for (i = 0, len = this.eventsheets_by_index.length; i < len; i++)
4541
this.eventsheets_by_index[i].updateDeepIncludes();
4542
for (i = 0, len = this.triggers_to_postinit.length; i < len; i++)
4543
this.triggers_to_postinit[i].postInit();
4544
cr.clearArray(this.triggers_to_postinit)
4545
this.audio_to_preload = pm[7];
4546
this.files_subfolder = pm[8];
4547
this.pixel_rounding = pm[9];
4548
this.aspect_scale = 1.0;
4549
this.enableWebGL = pm[13];
4550
this.linearSampling = pm[14];
4551
this.clearBackground = pm[15];
4552
this.versionstr = pm[16];
4553
this.useHighDpi = pm[17];
4554
this.orientations = pm[20]; // 0 = any, 1 = portrait, 2 = landscape
4555
this.autoLockOrientation = (this.orientations > 0);
4556
this.pauseOnBlur = pm[22];
4557
this.wantFullscreenScalingQuality = pm[23]; // false = low quality, true = high quality
4558
this.fullscreenScalingQuality = this.wantFullscreenScalingQuality;
4559
this.downscalingQuality = pm[24]; // 0 = low (mips off), 1 = medium (mips on, dense spritesheet), 2 = high (mips on, sparse spritesheet)
4560
this.preloadSounds = pm[25]; // 0 = no, 1 = yes
4561
this.projectName = pm[26];
4562
this.enableFrontToBack = pm[27] && !this.isIE; // front-to-back renderer disabled in IE (but not Edge)
4563
this.start_time = Date.now();
4564
cr.clearArray(this.objectRefTable);
4565
this.initRendererAndLoader();
4566
};
4567
var anyImageHadError = false;
4568
var MAX_PARALLEL_IMAGE_LOADS = 100;
4569
var currentlyActiveImageLoads = 0;
4570
var imageLoadQueue = []; // array of [img, srcToSet]
4571
Runtime.prototype.queueImageLoad = function (img_, src_)
4572
{
4573
var self = this;
4574
var doneFunc = function ()
4575
{
4576
currentlyActiveImageLoads--;
4577
self.maybeLoadNextImages();
4578
};
4579
img_.addEventListener("load", doneFunc);
4580
img_.addEventListener("error", doneFunc);
4581
imageLoadQueue.push([img_, src_]);
4582
this.maybeLoadNextImages();
4583
};
4584
Runtime.prototype.maybeLoadNextImages = function ()
4585
{
4586
var next;
4587
while (imageLoadQueue.length && currentlyActiveImageLoads < MAX_PARALLEL_IMAGE_LOADS)
4588
{
4589
currentlyActiveImageLoads++;
4590
next = imageLoadQueue.shift();
4591
this.setImageSrc(next[0], next[1]);
4592
}
4593
};
4594
Runtime.prototype.waitForImageLoad = function (img_, src_)
4595
{
4596
img_["cocoonLazyLoad"] = true;
4597
img_.onerror = function (e)
4598
{
4599
img_.c2error = true;
4600
anyImageHadError = true;
4601
if (console && console.error)
4602
console.error("Error loading image '" + img_.src + "': ", e);
4603
};
4604
if (this.isEjecta)
4605
{
4606
img_.src = src_;
4607
}
4608
else if (!img_.src)
4609
{
4610
if (typeof XAPKReader !== "undefined")
4611
{
4612
XAPKReader.get(src_, function (expanded_url)
4613
{
4614
img_.src = expanded_url;
4615
}, function (e)
4616
{
4617
img_.c2error = true;
4618
anyImageHadError = true;
4619
if (console && console.error)
4620
console.error("Error extracting image '" + src_ + "' from expansion file: ", e);
4621
});
4622
}
4623
else
4624
{
4625
img_.crossOrigin = "anonymous"; // required for Arcade sandbox compatibility
4626
this.queueImageLoad(img_, src_); // use a queue to avoid requesting all images simultaneously
4627
}
4628
}
4629
this.wait_for_textures.push(img_);
4630
};
4631
Runtime.prototype.findWaitingTexture = function (src_)
4632
{
4633
var i, len;
4634
for (i = 0, len = this.wait_for_textures.length; i < len; i++)
4635
{
4636
if (this.wait_for_textures[i].cr_src === src_)
4637
return this.wait_for_textures[i];
4638
}
4639
return null;
4640
};
4641
var audio_preload_totalsize = 0;
4642
var audio_preload_started = false;
4643
Runtime.prototype.getready = function ()
4644
{
4645
if (!this.audioInstance)
4646
return;
4647
audio_preload_totalsize = this.audioInstance.setPreloadList(this.audio_to_preload);
4648
};
4649
Runtime.prototype.areAllTexturesAndSoundsLoaded = function ()
4650
{
4651
var totalsize = audio_preload_totalsize;
4652
var completedsize = 0;
4653
var audiocompletedsize = 0;
4654
var ret = true;
4655
var i, len, img;
4656
for (i = 0, len = this.wait_for_textures.length; i < len; i++)
4657
{
4658
img = this.wait_for_textures[i];
4659
var filesize = img.cr_filesize;
4660
if (!filesize || filesize <= 0)
4661
filesize = 50000;
4662
totalsize += filesize;
4663
if (!!img.src && (img.complete || img["loaded"]) && !img.c2error)
4664
completedsize += filesize;
4665
else
4666
ret = false; // not all textures loaded
4667
}
4668
if (ret && this.preloadSounds && this.audioInstance)
4669
{
4670
if (!audio_preload_started)
4671
{
4672
this.audioInstance.startPreloads();
4673
audio_preload_started = true;
4674
}
4675
audiocompletedsize = this.audioInstance.getPreloadedSize();
4676
completedsize += audiocompletedsize;
4677
if (audiocompletedsize < audio_preload_totalsize)
4678
ret = false; // not done yet
4679
}
4680
if (totalsize == 0)
4681
this.progress = 1; // indicate to C2 splash loader that it can finish now
4682
else
4683
this.progress = (completedsize / totalsize);
4684
return ret;
4685
};
4686
var isC2SplashDone = false;
4687
Runtime.prototype.go = function ()
4688
{
4689
if (!this.ctx && !this.glwrap)
4690
return;
4691
var ctx = this.ctx || this.overlay_ctx;
4692
if (this.overlay_canvas)
4693
this.positionOverlayCanvas();
4694
var curwidth = window.innerWidth;
4695
var curheight = window.innerHeight;
4696
if (this.lastWindowWidth !== curwidth || this.lastWindowHeight !== curheight)
4697
{
4698
this["setSize"](curwidth, curheight);
4699
}
4700
this.progress = 0;
4701
this.last_progress = -1;
4702
var self = this;
4703
if (this.areAllTexturesAndSoundsLoaded() && (this.loaderstyle !== 4 || isC2SplashDone))
4704
{
4705
this.go_loading_finished();
4706
}
4707
else
4708
{
4709
var ms_elapsed = Date.now() - this.start_time;
4710
if (ctx)
4711
{
4712
var overlay_width = this.width;
4713
var overlay_height = this.height;
4714
var dpr = this.devicePixelRatio;
4715
if (this.loaderstyle < 3 && (this.isCocoonJs || (ms_elapsed >= 500 && this.last_progress != this.progress)))
4716
{
4717
ctx.clearRect(0, 0, overlay_width, overlay_height);
4718
var mx = overlay_width / 2;
4719
var my = overlay_height / 2;
4720
var haslogo = (this.loaderstyle === 0 && this.loaderlogos.logo.complete);
4721
var hlw = 40 * dpr;
4722
var hlh = 0;
4723
var logowidth = 80 * dpr;
4724
var logoheight;
4725
if (haslogo)
4726
{
4727
var loaderLogoImage = this.loaderlogos.logo;
4728
logowidth = loaderLogoImage.width * dpr;
4729
logoheight = loaderLogoImage.height * dpr;
4730
hlw = logowidth / 2;
4731
hlh = logoheight / 2;
4732
ctx.drawImage(loaderLogoImage, cr.floor(mx - hlw), cr.floor(my - hlh), logowidth, logoheight);
4733
}
4734
if (this.loaderstyle <= 1)
4735
{
4736
my += hlh + (haslogo ? 12 * dpr : 0);
4737
mx -= hlw;
4738
mx = cr.floor(mx) + 0.5;
4739
my = cr.floor(my) + 0.5;
4740
ctx.fillStyle = anyImageHadError ? "red" : "DodgerBlue";
4741
ctx.fillRect(mx, my, Math.floor(logowidth * this.progress), 6 * dpr);
4742
ctx.strokeStyle = "black";
4743
ctx.strokeRect(mx, my, logowidth, 6 * dpr);
4744
ctx.strokeStyle = "white";
4745
ctx.strokeRect(mx - 1 * dpr, my - 1 * dpr, logowidth + 2 * dpr, 8 * dpr);
4746
}
4747
else if (this.loaderstyle === 2)
4748
{
4749
ctx.font = (this.isEjecta ? "12pt ArialMT" : "12pt Arial");
4750
ctx.fillStyle = anyImageHadError ? "#f00" : "#999";
4751
ctx.textBaseLine = "middle";
4752
var percent_text = Math.round(this.progress * 100) + "%";
4753
var text_dim = ctx.measureText ? ctx.measureText(percent_text) : null;
4754
var text_width = text_dim ? text_dim.width : 0;
4755
ctx.fillText(percent_text, mx - (text_width / 2), my);
4756
}
4757
this.last_progress = this.progress;
4758
}
4759
else if (this.loaderstyle === 4)
4760
{
4761
this.draw_c2_splash_loader(ctx);
4762
if (raf)
4763
raf(function() { self.go(); });
4764
else
4765
setTimeout(function() { self.go(); }, 16);
4766
return;
4767
}
4768
}
4769
setTimeout(function() { self.go(); }, (this.isCocoonJs ? 10 : 100));
4770
}
4771
};
4772
var splashStartTime = -1;
4773
var splashFadeInDuration = 300;
4774
var splashFadeOutDuration = 300;
4775
var splashAfterFadeOutWait = (typeof cr_is_preview === "undefined" ? 200 : 0);
4776
var splashIsFadeIn = true;
4777
var splashIsFadeOut = false;
4778
var splashFadeInFinish = 0;
4779
var splashFadeOutStart = 0;
4780
var splashMinDisplayTime = (typeof cr_is_preview === "undefined" ? 3000 : 0);
4781
var renderViaCanvas = null;
4782
var renderViaCtx = null;
4783
var splashFrameNumber = 0;
4784
function maybeCreateRenderViaCanvas(w, h)
4785
{
4786
if (!renderViaCanvas || renderViaCanvas.width !== w || renderViaCanvas.height !== h)
4787
{
4788
renderViaCanvas = document.createElement("canvas");
4789
renderViaCanvas.width = w;
4790
renderViaCanvas.height = h;
4791
renderViaCtx = renderViaCanvas.getContext("2d");
4792
}
4793
};
4794
function mipImage(arr, size)
4795
{
4796
if (size <= 128)
4797
return arr[3];
4798
else if (size <= 256)
4799
return arr[2];
4800
else if (size <= 512)
4801
return arr[1];
4802
else
4803
return arr[0];
4804
};
4805
Runtime.prototype.draw_c2_splash_loader = function(ctx)
4806
{
4807
if (isC2SplashDone)
4808
return;
4809
var w = Math.ceil(this.width);
4810
var h = Math.ceil(this.height);
4811
var dpr = this.devicePixelRatio;
4812
var logoimages = this.loaderlogos.logo;
4813
var poweredimages = this.loaderlogos.powered;
4814
var websiteimages = this.loaderlogos.website;
4815
for (var i = 0; i < 4; ++i)
4816
{
4817
if (!logoimages[i].complete || !poweredimages[i].complete || !websiteimages[i].complete)
4818
return;
4819
}
4820
if (splashFrameNumber === 0)
4821
splashStartTime = Date.now();
4822
var nowTime = Date.now();
4823
var isRenderingVia = false;
4824
var renderToCtx = ctx;
4825
var drawW, drawH;
4826
if (splashIsFadeIn || splashIsFadeOut)
4827
{
4828
ctx.clearRect(0, 0, w, h);
4829
maybeCreateRenderViaCanvas(w, h);
4830
renderToCtx = renderViaCtx;
4831
isRenderingVia = true;
4832
if (splashIsFadeIn && splashFrameNumber === 1)
4833
splashStartTime = Date.now();
4834
}
4835
else
4836
{
4837
ctx.globalAlpha = 1;
4838
}
4839
renderToCtx.fillStyle = "#333333";
4840
renderToCtx.fillRect(0, 0, w, h);
4841
if (this.cssHeight > 256)
4842
{
4843
drawW = cr.clamp(h * 0.22, 105, w * 0.6);
4844
drawH = drawW * 0.25;
4845
renderToCtx.drawImage(mipImage(poweredimages, drawW), w * 0.5 - drawW/2, h * 0.2 - drawH/2, drawW, drawH);
4846
drawW = Math.min(h * 0.395, w * 0.95);
4847
drawH = drawW;
4848
renderToCtx.drawImage(mipImage(logoimages, drawW), w * 0.5 - drawW/2, h * 0.485 - drawH/2, drawW, drawH);
4849
drawW = cr.clamp(h * 0.22, 105, w * 0.6);
4850
drawH = drawW * 0.25;
4851
renderToCtx.drawImage(mipImage(websiteimages, drawW), w * 0.5 - drawW/2, h * 0.868 - drawH/2, drawW, drawH);
4852
renderToCtx.fillStyle = "#3C3C3C";
4853
drawW = w;
4854
drawH = Math.max(h * 0.005, 2);
4855
renderToCtx.fillRect(0, h * 0.8 - drawH/2, drawW, drawH);
4856
renderToCtx.fillStyle = anyImageHadError ? "red" : "#E0FF65";
4857
drawW = w * this.progress;
4858
renderToCtx.fillRect(w * 0.5 - drawW/2, h * 0.8 - drawH/2, drawW, drawH);
4859
}
4860
else
4861
{
4862
drawW = h * 0.55;
4863
drawH = drawW;
4864
renderToCtx.drawImage(mipImage(logoimages, drawW), w * 0.5 - drawW/2, h * 0.45 - drawH/2, drawW, drawH);
4865
renderToCtx.fillStyle = "#3C3C3C";
4866
drawW = w;
4867
drawH = Math.max(h * 0.005, 2);
4868
renderToCtx.fillRect(0, h * 0.85 - drawH/2, drawW, drawH);
4869
renderToCtx.fillStyle = anyImageHadError ? "red" : "#E0FF65";
4870
drawW = w * this.progress;
4871
renderToCtx.fillRect(w * 0.5 - drawW/2, h * 0.85 - drawH/2, drawW, drawH);
4872
}
4873
if (isRenderingVia)
4874
{
4875
if (splashIsFadeIn)
4876
{
4877
if (splashFrameNumber === 0)
4878
ctx.globalAlpha = 0;
4879
else
4880
ctx.globalAlpha = Math.min((nowTime - splashStartTime) / splashFadeInDuration, 1);
4881
}
4882
else if (splashIsFadeOut)
4883
{
4884
ctx.globalAlpha = Math.max(1 - (nowTime - splashFadeOutStart) / splashFadeOutDuration, 0);
4885
}
4886
ctx.drawImage(renderViaCanvas, 0, 0, w, h);
4887
}
4888
if (splashIsFadeIn && nowTime - splashStartTime >= splashFadeInDuration && splashFrameNumber >= 2)
4889
{
4890
splashIsFadeIn = false;
4891
splashFadeInFinish = nowTime;
4892
}
4893
if (!splashIsFadeIn && nowTime - splashFadeInFinish >= splashMinDisplayTime && !splashIsFadeOut && this.progress >= 1)
4894
{
4895
splashIsFadeOut = true;
4896
splashFadeOutStart = nowTime;
4897
}
4898
if ((splashIsFadeOut && nowTime - splashFadeOutStart >= splashFadeOutDuration + splashAfterFadeOutWait) ||
4899
(typeof cr_is_preview !== "undefined" && this.progress >= 1 && Date.now() - splashStartTime < 500))
4900
{
4901
isC2SplashDone = true;
4902
splashIsFadeIn = false;
4903
splashIsFadeOut = false;
4904
renderViaCanvas = null;
4905
renderViaCtx = null;
4906
this.loaderlogos = null;
4907
}
4908
++splashFrameNumber;
4909
};
4910
Runtime.prototype.go_loading_finished = function ()
4911
{
4912
if (this.overlay_canvas)
4913
{
4914
this.canvas.parentNode.removeChild(this.overlay_canvas);
4915
this.overlay_ctx = null;
4916
this.overlay_canvas = null;
4917
}
4918
this.start_time = Date.now();
4919
this.last_fps_time = cr.performance_now(); // for counting framerate
4920
var i, len, t;
4921
if (this.uses_loader_layout)
4922
{
4923
for (i = 0, len = this.types_by_index.length; i < len; i++)
4924
{
4925
t = this.types_by_index[i];
4926
if (!t.is_family && !t.isOnLoaderLayout && t.plugin.is_world)
4927
{
4928
t.onCreate();
4929
cr.seal(t);
4930
}
4931
}
4932
}
4933
else
4934
this.isloading = false;
4935
for (i = 0, len = this.layouts_by_index.length; i < len; i++)
4936
{
4937
this.layouts_by_index[i].createGlobalNonWorlds();
4938
}
4939
if (this.fullscreen_mode >= 2)
4940
{
4941
var orig_aspect = this.original_width / this.original_height;
4942
var cur_aspect = this.width / this.height;
4943
if ((this.fullscreen_mode !== 2 && cur_aspect > orig_aspect) || (this.fullscreen_mode === 2 && cur_aspect < orig_aspect))
4944
this.aspect_scale = this.height / this.original_height;
4945
else
4946
this.aspect_scale = this.width / this.original_width;
4947
}
4948
if (this.first_layout)
4949
this.layouts[this.first_layout].startRunning();
4950
else
4951
this.layouts_by_index[0].startRunning();
4952
;
4953
if (!this.uses_loader_layout)
4954
{
4955
this.loadingprogress = 1;
4956
this.trigger(cr.system_object.prototype.cnds.OnLoadFinished, null);
4957
if (window["C2_RegisterSW"]) // note not all platforms use SW
4958
window["C2_RegisterSW"]();
4959
}
4960
if (navigator["splashscreen"] && navigator["splashscreen"]["hide"])
4961
navigator["splashscreen"]["hide"]();
4962
for (i = 0, len = this.types_by_index.length; i < len; i++)
4963
{
4964
t = this.types_by_index[i];
4965
if (t.onAppBegin)
4966
t.onAppBegin();
4967
}
4968
if (document["hidden"] || document["webkitHidden"] || document["mozHidden"] || document["msHidden"])
4969
{
4970
window["cr_setSuspended"](true); // stop rendering
4971
}
4972
else
4973
{
4974
this.tick(false);
4975
}
4976
if (this.isDirectCanvas)
4977
AppMobi["webview"]["execute"]("onGameReady();");
4978
};
4979
Runtime.prototype.tick = function (background_wake, timestamp, debug_step)
4980
{
4981
if (!this.running_layout)
4982
return;
4983
var nowtime = cr.performance_now();
4984
var logic_start = nowtime;
4985
if (!debug_step && this.isSuspended && !background_wake)
4986
return;
4987
if (!background_wake)
4988
{
4989
if (raf)
4990
this.raf_id = raf(this.tickFunc);
4991
else
4992
{
4993
this.timeout_id = setTimeout(this.tickFunc, this.isMobile ? 1 : 16);
4994
}
4995
}
4996
var raf_time = timestamp || nowtime;
4997
var fsmode = this.fullscreen_mode;
4998
var isfullscreen = (document["mozFullScreen"] || document["webkitIsFullScreen"] || document["fullScreen"] || !!document["msFullscreenElement"]) && !this.isCordova;
4999
if ((isfullscreen || this.isNodeFullscreen) && this.fullscreen_scaling > 0)
5000
fsmode = this.fullscreen_scaling;
5001
if (fsmode > 0) // r222: experimentally enabling this workaround for all platforms
5002
{
5003
var curwidth = window.innerWidth;
5004
var curheight = window.innerHeight;
5005
if (this.lastWindowWidth !== curwidth || this.lastWindowHeight !== curheight)
5006
{
5007
this["setSize"](curwidth, curheight);
5008
}
5009
}
5010
if (!this.isDomFree)
5011
{
5012
if (isfullscreen)
5013
{
5014
if (!this.firstInFullscreen)
5015
this.firstInFullscreen = true;
5016
}
5017
else
5018
{
5019
if (this.firstInFullscreen)
5020
{
5021
this.firstInFullscreen = false;
5022
if (this.fullscreen_mode === 0)
5023
{
5024
this["setSize"](Math.round(this.oldWidth / this.devicePixelRatio), Math.round(this.oldHeight / this.devicePixelRatio), true);
5025
}
5026
}
5027
else
5028
{
5029
this.oldWidth = this.width;
5030
this.oldHeight = this.height;
5031
}
5032
}
5033
}
5034
if (this.isloading)
5035
{
5036
var done = this.areAllTexturesAndSoundsLoaded(); // updates this.progress
5037
this.loadingprogress = this.progress;
5038
if (done)
5039
{
5040
this.isloading = false;
5041
this.progress = 1;
5042
this.trigger(cr.system_object.prototype.cnds.OnLoadFinished, null);
5043
if (window["C2_RegisterSW"])
5044
window["C2_RegisterSW"]();
5045
}
5046
}
5047
this.logic(raf_time);
5048
if ((this.redraw || this.isCocoonJs) && !this.is_WebGL_context_lost && !this.suspendDrawing && !background_wake)
5049
{
5050
this.redraw = false;
5051
if (this.glwrap)
5052
this.drawGL();
5053
else
5054
this.draw();
5055
if (this.snapshotCanvas)
5056
{
5057
if (this.canvas && this.canvas.toDataURL)
5058
{
5059
this.snapshotData = this.canvas.toDataURL(this.snapshotCanvas[0], this.snapshotCanvas[1]);
5060
if (window["cr_onSnapshot"])
5061
window["cr_onSnapshot"](this.snapshotData);
5062
this.trigger(cr.system_object.prototype.cnds.OnCanvasSnapshot, null);
5063
}
5064
this.snapshotCanvas = null;
5065
}
5066
}
5067
if (!this.hit_breakpoint)
5068
{
5069
this.tickcount++;
5070
this.tickcount_nosave++;
5071
this.execcount++;
5072
this.framecount++;
5073
}
5074
this.logictime += cr.performance_now() - logic_start;
5075
};
5076
Runtime.prototype.logic = function (cur_time)
5077
{
5078
var i, leni, j, lenj, k, lenk, type, inst, binst;
5079
if (cur_time - this.last_fps_time >= 1000) // every 1 second
5080
{
5081
this.last_fps_time += 1000;
5082
if (cur_time - this.last_fps_time >= 1000)
5083
this.last_fps_time = cur_time;
5084
this.fps = this.framecount;
5085
this.framecount = 0;
5086
this.cpuutilisation = this.logictime;
5087
this.logictime = 0;
5088
}
5089
var wallDt = 0;
5090
if (this.last_tick_time !== 0)
5091
{
5092
var ms_diff = cur_time - this.last_tick_time;
5093
if (ms_diff < 0)
5094
ms_diff = 0;
5095
wallDt = ms_diff / 1000.0; // dt measured in seconds
5096
this.dt1 = wallDt;
5097
if (this.dt1 > 0.5)
5098
this.dt1 = 0;
5099
else if (this.dt1 > 1 / this.minimumFramerate)
5100
this.dt1 = 1 / this.minimumFramerate;
5101
}
5102
this.last_tick_time = cur_time;
5103
this.dt = this.dt1 * this.timescale;
5104
this.kahanTime.add(this.dt);
5105
this.wallTime.add(wallDt); // prevent min/max framerate affecting wall clock
5106
var isfullscreen = (document["mozFullScreen"] || document["webkitIsFullScreen"] || document["fullScreen"] || !!document["msFullscreenElement"] || this.isNodeFullscreen) && !this.isCordova;
5107
if (this.fullscreen_mode >= 2 /* scale */ || (isfullscreen && this.fullscreen_scaling > 0))
5108
{
5109
var orig_aspect = this.original_width / this.original_height;
5110
var cur_aspect = this.width / this.height;
5111
var mode = this.fullscreen_mode;
5112
if (isfullscreen && this.fullscreen_scaling > 0)
5113
mode = this.fullscreen_scaling;
5114
if ((mode !== 2 && cur_aspect > orig_aspect) || (mode === 2 && cur_aspect < orig_aspect))
5115
{
5116
this.aspect_scale = this.height / this.original_height;
5117
}
5118
else
5119
{
5120
this.aspect_scale = this.width / this.original_width;
5121
}
5122
if (this.running_layout)
5123
{
5124
this.running_layout.scrollToX(this.running_layout.scrollX);
5125
this.running_layout.scrollToY(this.running_layout.scrollY);
5126
}
5127
}
5128
else
5129
this.aspect_scale = (this.isRetina ? this.devicePixelRatio : 1);
5130
this.ClearDeathRow();
5131
this.isInOnDestroy++;
5132
this.system.runWaits(); // prevent instance list changing
5133
this.isInOnDestroy--;
5134
this.ClearDeathRow(); // allow instance list changing
5135
this.isInOnDestroy++;
5136
var tickarr = this.objects_to_pretick.valuesRef();
5137
for (i = 0, leni = tickarr.length; i < leni; i++)
5138
tickarr[i].pretick();
5139
for (i = 0, leni = this.types_by_index.length; i < leni; i++)
5140
{
5141
type = this.types_by_index[i];
5142
if (type.is_family || (!type.behaviors.length && !type.families.length))
5143
continue;
5144
for (j = 0, lenj = type.instances.length; j < lenj; j++)
5145
{
5146
inst = type.instances[j];
5147
for (k = 0, lenk = inst.behavior_insts.length; k < lenk; k++)
5148
{
5149
inst.behavior_insts[k].tick();
5150
}
5151
}
5152
}
5153
for (i = 0, leni = this.types_by_index.length; i < leni; i++)
5154
{
5155
type = this.types_by_index[i];
5156
if (type.is_family || (!type.behaviors.length && !type.families.length))
5157
continue; // type doesn't have any behaviors
5158
for (j = 0, lenj = type.instances.length; j < lenj; j++)
5159
{
5160
inst = type.instances[j];
5161
for (k = 0, lenk = inst.behavior_insts.length; k < lenk; k++)
5162
{
5163
binst = inst.behavior_insts[k];
5164
if (binst.posttick)
5165
binst.posttick();
5166
}
5167
}
5168
}
5169
tickarr = this.objects_to_tick.valuesRef();
5170
for (i = 0, leni = tickarr.length; i < leni; i++)
5171
tickarr[i].tick();
5172
this.isInOnDestroy--; // end preventing instance lists from being changed
5173
this.handleSaveLoad(); // save/load now if queued
5174
i = 0;
5175
while (this.changelayout && i++ < 10)
5176
{
5177
this.doChangeLayout(this.changelayout);
5178
}
5179
for (i = 0, leni = this.eventsheets_by_index.length; i < leni; i++)
5180
this.eventsheets_by_index[i].hasRun = false;
5181
if (this.running_layout.event_sheet)
5182
this.running_layout.event_sheet.run();
5183
cr.clearArray(this.registered_collisions);
5184
this.layout_first_tick = false;
5185
this.isInOnDestroy++; // prevent instance lists from being changed
5186
for (i = 0, leni = this.types_by_index.length; i < leni; i++)
5187
{
5188
type = this.types_by_index[i];
5189
if (type.is_family || (!type.behaviors.length && !type.families.length))
5190
continue; // type doesn't have any behaviors
5191
for (j = 0, lenj = type.instances.length; j < lenj; j++)
5192
{
5193
var inst = type.instances[j];
5194
for (k = 0, lenk = inst.behavior_insts.length; k < lenk; k++)
5195
{
5196
binst = inst.behavior_insts[k];
5197
if (binst.tick2)
5198
binst.tick2();
5199
}
5200
}
5201
}
5202
tickarr = this.objects_to_tick2.valuesRef();
5203
for (i = 0, leni = tickarr.length; i < leni; i++)
5204
tickarr[i].tick2();
5205
this.isInOnDestroy--; // end preventing instance lists from being changed
5206
};
5207
Runtime.prototype.onWindowBlur = function ()
5208
{
5209
var i, leni, j, lenj, k, lenk, type, inst, binst;
5210
for (i = 0, leni = this.types_by_index.length; i < leni; i++)
5211
{
5212
type = this.types_by_index[i];
5213
if (type.is_family)
5214
continue;
5215
for (j = 0, lenj = type.instances.length; j < lenj; j++)
5216
{
5217
inst = type.instances[j];
5218
if (inst.onWindowBlur)
5219
inst.onWindowBlur();
5220
if (!inst.behavior_insts)
5221
continue; // single-globals don't have behavior_insts
5222
for (k = 0, lenk = inst.behavior_insts.length; k < lenk; k++)
5223
{
5224
binst = inst.behavior_insts[k];
5225
if (binst.onWindowBlur)
5226
binst.onWindowBlur();
5227
}
5228
}
5229
}
5230
};
5231
Runtime.prototype.doChangeLayout = function (changeToLayout)
5232
{
5233
var prev_layout = this.running_layout;
5234
this.running_layout.stopRunning();
5235
var i, len, j, lenj, k, lenk, type, inst, binst;
5236
if (this.glwrap)
5237
{
5238
for (i = 0, len = this.types_by_index.length; i < len; i++)
5239
{
5240
type = this.types_by_index[i];
5241
if (type.is_family)
5242
continue;
5243
if (type.unloadTextures && (!type.global || type.instances.length === 0) && changeToLayout.initial_types.indexOf(type) === -1)
5244
{
5245
type.unloadTextures();
5246
}
5247
}
5248
}
5249
if (prev_layout == changeToLayout)
5250
cr.clearArray(this.system.waits);
5251
cr.clearArray(this.registered_collisions);
5252
this.runLayoutChangeMethods(true);
5253
changeToLayout.startRunning();
5254
this.runLayoutChangeMethods(false);
5255
this.redraw = true;
5256
this.layout_first_tick = true;
5257
this.ClearDeathRow();
5258
};
5259
Runtime.prototype.runLayoutChangeMethods = function (isBeforeChange)
5260
{
5261
var i, len, beh, type, j, lenj, inst, k, lenk, binst;
5262
for (i = 0, len = this.behaviors.length; i < len; i++)
5263
{
5264
beh = this.behaviors[i];
5265
if (isBeforeChange)
5266
{
5267
if (beh.onBeforeLayoutChange)
5268
beh.onBeforeLayoutChange();
5269
}
5270
else
5271
{
5272
if (beh.onLayoutChange)
5273
beh.onLayoutChange();
5274
}
5275
}
5276
for (i = 0, len = this.types_by_index.length; i < len; i++)
5277
{
5278
type = this.types_by_index[i];
5279
if (!type.global && !type.plugin.singleglobal)
5280
continue;
5281
for (j = 0, lenj = type.instances.length; j < lenj; j++)
5282
{
5283
inst = type.instances[j];
5284
if (isBeforeChange)
5285
{
5286
if (inst.onBeforeLayoutChange)
5287
inst.onBeforeLayoutChange();
5288
}
5289
else
5290
{
5291
if (inst.onLayoutChange)
5292
inst.onLayoutChange();
5293
}
5294
if (inst.behavior_insts)
5295
{
5296
for (k = 0, lenk = inst.behavior_insts.length; k < lenk; k++)
5297
{
5298
binst = inst.behavior_insts[k];
5299
if (isBeforeChange)
5300
{
5301
if (binst.onBeforeLayoutChange)
5302
binst.onBeforeLayoutChange();
5303
}
5304
else
5305
{
5306
if (binst.onLayoutChange)
5307
binst.onLayoutChange();
5308
}
5309
}
5310
}
5311
}
5312
}
5313
};
5314
Runtime.prototype.pretickMe = function (inst)
5315
{
5316
this.objects_to_pretick.add(inst);
5317
};
5318
Runtime.prototype.unpretickMe = function (inst)
5319
{
5320
this.objects_to_pretick.remove(inst);
5321
};
5322
Runtime.prototype.tickMe = function (inst)
5323
{
5324
this.objects_to_tick.add(inst);
5325
};
5326
Runtime.prototype.untickMe = function (inst)
5327
{
5328
this.objects_to_tick.remove(inst);
5329
};
5330
Runtime.prototype.tick2Me = function (inst)
5331
{
5332
this.objects_to_tick2.add(inst);
5333
};
5334
Runtime.prototype.untick2Me = function (inst)
5335
{
5336
this.objects_to_tick2.remove(inst);
5337
};
5338
Runtime.prototype.getDt = function (inst)
5339
{
5340
if (!inst || inst.my_timescale === -1.0)
5341
return this.dt;
5342
return this.dt1 * inst.my_timescale;
5343
};
5344
Runtime.prototype.draw = function ()
5345
{
5346
this.running_layout.draw(this.ctx);
5347
if (this.isDirectCanvas)
5348
this.ctx["present"]();
5349
};
5350
Runtime.prototype.drawGL = function ()
5351
{
5352
if (this.enableFrontToBack)
5353
{
5354
this.earlyz_index = 1; // start from front, 1-based to avoid exactly equalling near plane Z value
5355
this.running_layout.drawGL_earlyZPass(this.glwrap);
5356
}
5357
this.running_layout.drawGL(this.glwrap);
5358
this.glwrap.present();
5359
};
5360
Runtime.prototype.addDestroyCallback = function (f)
5361
{
5362
if (f)
5363
this.destroycallbacks.push(f);
5364
};
5365
Runtime.prototype.removeDestroyCallback = function (f)
5366
{
5367
cr.arrayFindRemove(this.destroycallbacks, f);
5368
};
5369
Runtime.prototype.getObjectByUID = function (uid_)
5370
{
5371
;
5372
var uidstr = uid_.toString();
5373
if (this.objectsByUid.hasOwnProperty(uidstr))
5374
return this.objectsByUid[uidstr];
5375
else
5376
return null;
5377
};
5378
var objectset_cache = [];
5379
function alloc_objectset()
5380
{
5381
if (objectset_cache.length)
5382
return objectset_cache.pop();
5383
else
5384
return new cr.ObjectSet();
5385
};
5386
function free_objectset(s)
5387
{
5388
s.clear();
5389
objectset_cache.push(s);
5390
};
5391
Runtime.prototype.DestroyInstance = function (inst)
5392
{
5393
var i, len;
5394
var type = inst.type;
5395
var typename = type.name;
5396
var has_typename = this.deathRow.hasOwnProperty(typename);
5397
var obj_set = null;
5398
if (has_typename)
5399
{
5400
obj_set = this.deathRow[typename];
5401
if (obj_set.contains(inst))
5402
return; // already had DestroyInstance called
5403
}
5404
else
5405
{
5406
obj_set = alloc_objectset();
5407
this.deathRow[typename] = obj_set;
5408
}
5409
obj_set.add(inst);
5410
this.hasPendingInstances = true;
5411
if (inst.is_contained)
5412
{
5413
for (i = 0, len = inst.siblings.length; i < len; i++)
5414
{
5415
this.DestroyInstance(inst.siblings[i]);
5416
}
5417
}
5418
if (this.isInClearDeathRow)
5419
obj_set.values_cache.push(inst);
5420
if (!this.isEndingLayout)
5421
{
5422
this.isInOnDestroy++; // support recursion
5423
this.trigger(Object.getPrototypeOf(inst.type.plugin).cnds.OnDestroyed, inst);
5424
this.isInOnDestroy--;
5425
}
5426
};
5427
Runtime.prototype.ClearDeathRow = function ()
5428
{
5429
if (!this.hasPendingInstances)
5430
return;
5431
var inst, type, instances;
5432
var i, j, leni, lenj, obj_set;
5433
this.isInClearDeathRow = true;
5434
for (i = 0, leni = this.createRow.length; i < leni; ++i)
5435
{
5436
inst = this.createRow[i];
5437
type = inst.type;
5438
type.instances.push(inst);
5439
for (j = 0, lenj = type.families.length; j < lenj; ++j)
5440
{
5441
type.families[j].instances.push(inst);
5442
type.families[j].stale_iids = true;
5443
}
5444
}
5445
cr.clearArray(this.createRow);
5446
this.IterateDeathRow(); // moved to separate function so for-in performance doesn't hobble entire function
5447
cr.wipe(this.deathRow); // all objectsets have already been recycled
5448
this.isInClearDeathRow = false;
5449
this.hasPendingInstances = false;
5450
};
5451
Runtime.prototype.IterateDeathRow = function ()
5452
{
5453
for (var p in this.deathRow)
5454
{
5455
if (this.deathRow.hasOwnProperty(p))
5456
{
5457
this.ClearDeathRowForType(this.deathRow[p]);
5458
}
5459
}
5460
};
5461
Runtime.prototype.ClearDeathRowForType = function (obj_set)
5462
{
5463
var arr = obj_set.valuesRef(); // get array of items from set
5464
;
5465
var type = arr[0].type;
5466
;
5467
;
5468
var i, len, j, lenj, w, f, layer_instances, inst;
5469
cr.arrayRemoveAllFromObjectSet(type.instances, obj_set);
5470
type.stale_iids = true;
5471
if (type.instances.length === 0)
5472
type.any_instance_parallaxed = false;
5473
for (i = 0, len = type.families.length; i < len; ++i)
5474
{
5475
f = type.families[i];
5476
cr.arrayRemoveAllFromObjectSet(f.instances, obj_set);
5477
f.stale_iids = true;
5478
}
5479
for (i = 0, len = this.system.waits.length; i < len; ++i)
5480
{
5481
w = this.system.waits[i];
5482
if (w.sols.hasOwnProperty(type.index))
5483
cr.arrayRemoveAllFromObjectSet(w.sols[type.index].insts, obj_set);
5484
if (!type.is_family)
5485
{
5486
for (j = 0, lenj = type.families.length; j < lenj; ++j)
5487
{
5488
f = type.families[j];
5489
if (w.sols.hasOwnProperty(f.index))
5490
cr.arrayRemoveAllFromObjectSet(w.sols[f.index].insts, obj_set);
5491
}
5492
}
5493
}
5494
var first_layer = arr[0].layer;
5495
if (first_layer)
5496
{
5497
if (first_layer.useRenderCells)
5498
{
5499
layer_instances = first_layer.instances;
5500
for (i = 0, len = layer_instances.length; i < len; ++i)
5501
{
5502
inst = layer_instances[i];
5503
if (!obj_set.contains(inst))
5504
continue; // not destroying this instance
5505
inst.update_bbox();
5506
first_layer.render_grid.update(inst, inst.rendercells, null);
5507
inst.rendercells.set(0, 0, -1, -1);
5508
}
5509
}
5510
cr.arrayRemoveAllFromObjectSet(first_layer.instances, obj_set);
5511
first_layer.setZIndicesStaleFrom(0);
5512
}
5513
for (i = 0; i < arr.length; ++i) // check array length every time in case it changes
5514
{
5515
this.ClearDeathRowForSingleInstance(arr[i], type);
5516
}
5517
free_objectset(obj_set);
5518
this.redraw = true;
5519
};
5520
Runtime.prototype.ClearDeathRowForSingleInstance = function (inst, type)
5521
{
5522
var i, len, binst;
5523
for (i = 0, len = this.destroycallbacks.length; i < len; ++i)
5524
this.destroycallbacks[i](inst);
5525
if (inst.collcells)
5526
{
5527
type.collision_grid.update(inst, inst.collcells, null);
5528
}
5529
var layer = inst.layer;
5530
if (layer)
5531
{
5532
layer.removeFromInstanceList(inst, true); // remove from both instance list and render grid
5533
}
5534
if (inst.behavior_insts)
5535
{
5536
for (i = 0, len = inst.behavior_insts.length; i < len; ++i)
5537
{
5538
binst = inst.behavior_insts[i];
5539
if (binst.onDestroy)
5540
binst.onDestroy();
5541
binst.behavior.my_instances.remove(inst);
5542
}
5543
}
5544
this.objects_to_pretick.remove(inst);
5545
this.objects_to_tick.remove(inst);
5546
this.objects_to_tick2.remove(inst);
5547
if (inst.onDestroy)
5548
inst.onDestroy();
5549
if (this.objectsByUid.hasOwnProperty(inst.uid.toString()))
5550
delete this.objectsByUid[inst.uid.toString()];
5551
this.objectcount--;
5552
if (type.deadCache.length < 100)
5553
type.deadCache.push(inst);
5554
};
5555
Runtime.prototype.createInstance = function (type, layer, sx, sy)
5556
{
5557
if (type.is_family)
5558
{
5559
var i = cr.floor(Math.random() * type.members.length);
5560
return this.createInstance(type.members[i], layer, sx, sy);
5561
}
5562
if (!type.default_instance)
5563
{
5564
return null;
5565
}
5566
return this.createInstanceFromInit(type.default_instance, layer, false, sx, sy, false);
5567
};
5568
var all_behaviors = [];
5569
Runtime.prototype.createInstanceFromInit = function (initial_inst, layer, is_startup_instance, sx, sy, skip_siblings)
5570
{
5571
var i, len, j, lenj, p, effect_fallback, x, y;
5572
if (!initial_inst)
5573
return null;
5574
var type = this.types_by_index[initial_inst[1]];
5575
;
5576
;
5577
var is_world = type.plugin.is_world;
5578
;
5579
if (this.isloading && is_world && !type.isOnLoaderLayout)
5580
return null;
5581
if (is_world && !this.glwrap && initial_inst[0][11] === 11)
5582
return null;
5583
var original_layer = layer;
5584
if (!is_world)
5585
layer = null;
5586
var inst;
5587
if (type.deadCache.length)
5588
{
5589
inst = type.deadCache.pop();
5590
inst.recycled = true;
5591
type.plugin.Instance.call(inst, type);
5592
}
5593
else
5594
{
5595
inst = new type.plugin.Instance(type);
5596
inst.recycled = false;
5597
}
5598
if (is_startup_instance && !skip_siblings && !this.objectsByUid.hasOwnProperty(initial_inst[2].toString()))
5599
inst.uid = initial_inst[2];
5600
else
5601
inst.uid = this.next_uid++;
5602
this.objectsByUid[inst.uid.toString()] = inst;
5603
inst.puid = this.next_puid++;
5604
inst.iid = type.instances.length;
5605
for (i = 0, len = this.createRow.length; i < len; ++i)
5606
{
5607
if (this.createRow[i].type === type)
5608
inst.iid++;
5609
}
5610
inst.get_iid = cr.inst_get_iid;
5611
inst.toString = cr.inst_toString;
5612
var initial_vars = initial_inst[3];
5613
if (inst.recycled)
5614
{
5615
cr.wipe(inst.extra);
5616
}
5617
else
5618
{
5619
inst.extra = {};
5620
if (typeof cr_is_preview !== "undefined")
5621
{
5622
inst.instance_var_names = [];
5623
inst.instance_var_names.length = initial_vars.length;
5624
for (i = 0, len = initial_vars.length; i < len; i++)
5625
inst.instance_var_names[i] = initial_vars[i][1];
5626
}
5627
inst.instance_vars = [];
5628
inst.instance_vars.length = initial_vars.length;
5629
}
5630
for (i = 0, len = initial_vars.length; i < len; i++)
5631
inst.instance_vars[i] = initial_vars[i][0];
5632
if (is_world)
5633
{
5634
var wm = initial_inst[0];
5635
;
5636
inst.x = cr.is_undefined(sx) ? wm[0] : sx;
5637
inst.y = cr.is_undefined(sy) ? wm[1] : sy;
5638
inst.z = wm[2];
5639
inst.width = wm[3];
5640
inst.height = wm[4];
5641
inst.depth = wm[5];
5642
inst.angle = wm[6];
5643
inst.opacity = wm[7];
5644
inst.hotspotX = wm[8];
5645
inst.hotspotY = wm[9];
5646
inst.blend_mode = wm[10];
5647
effect_fallback = wm[11];
5648
if (!this.glwrap && type.effect_types.length) // no WebGL renderer and shaders used
5649
inst.blend_mode = effect_fallback; // use fallback blend mode - destroy mode was handled above
5650
inst.compositeOp = cr.effectToCompositeOp(inst.blend_mode);
5651
if (this.gl)
5652
cr.setGLBlend(inst, inst.blend_mode, this.gl);
5653
if (inst.recycled)
5654
{
5655
for (i = 0, len = wm[12].length; i < len; i++)
5656
{
5657
for (j = 0, lenj = wm[12][i].length; j < lenj; j++)
5658
inst.effect_params[i][j] = wm[12][i][j];
5659
}
5660
inst.bbox.set(0, 0, 0, 0);
5661
inst.collcells.set(0, 0, -1, -1);
5662
inst.rendercells.set(0, 0, -1, -1);
5663
inst.bquad.set_from_rect(inst.bbox);
5664
cr.clearArray(inst.bbox_changed_callbacks);
5665
}
5666
else
5667
{
5668
inst.effect_params = wm[12].slice(0);
5669
for (i = 0, len = inst.effect_params.length; i < len; i++)
5670
inst.effect_params[i] = wm[12][i].slice(0);
5671
inst.active_effect_types = [];
5672
inst.active_effect_flags = [];
5673
inst.active_effect_flags.length = type.effect_types.length;
5674
inst.bbox = new cr.rect(0, 0, 0, 0);
5675
inst.collcells = new cr.rect(0, 0, -1, -1);
5676
inst.rendercells = new cr.rect(0, 0, -1, -1);
5677
inst.bquad = new cr.quad();
5678
inst.bbox_changed_callbacks = [];
5679
inst.set_bbox_changed = cr.set_bbox_changed;
5680
inst.add_bbox_changed_callback = cr.add_bbox_changed_callback;
5681
inst.contains_pt = cr.inst_contains_pt;
5682
inst.update_bbox = cr.update_bbox;
5683
inst.update_render_cell = cr.update_render_cell;
5684
inst.update_collision_cell = cr.update_collision_cell;
5685
inst.get_zindex = cr.inst_get_zindex;
5686
}
5687
inst.tilemap_exists = false;
5688
inst.tilemap_width = 0;
5689
inst.tilemap_height = 0;
5690
inst.tilemap_data = null;
5691
if (wm.length === 14)
5692
{
5693
inst.tilemap_exists = true;
5694
inst.tilemap_width = wm[13][0];
5695
inst.tilemap_height = wm[13][1];
5696
inst.tilemap_data = wm[13][2];
5697
}
5698
for (i = 0, len = type.effect_types.length; i < len; i++)
5699
inst.active_effect_flags[i] = true;
5700
inst.shaders_preserve_opaqueness = true;
5701
inst.updateActiveEffects = cr.inst_updateActiveEffects;
5702
inst.updateActiveEffects();
5703
inst.uses_shaders = !!inst.active_effect_types.length;
5704
inst.bbox_changed = true;
5705
inst.cell_changed = true;
5706
type.any_cell_changed = true;
5707
inst.visible = true;
5708
inst.my_timescale = -1.0;
5709
inst.layer = layer;
5710
inst.zindex = layer.instances.length; // will be placed at top of current layer
5711
inst.earlyz_index = 0;
5712
if (typeof inst.collision_poly === "undefined")
5713
inst.collision_poly = null;
5714
inst.collisionsEnabled = true;
5715
this.redraw = true;
5716
}
5717
var initial_props, binst;
5718
cr.clearArray(all_behaviors);
5719
for (i = 0, len = type.families.length; i < len; i++)
5720
{
5721
all_behaviors.push.apply(all_behaviors, type.families[i].behaviors);
5722
}
5723
all_behaviors.push.apply(all_behaviors, type.behaviors);
5724
if (inst.recycled)
5725
{
5726
for (i = 0, len = all_behaviors.length; i < len; i++)
5727
{
5728
var btype = all_behaviors[i];
5729
binst = inst.behavior_insts[i];
5730
binst.recycled = true;
5731
btype.behavior.Instance.call(binst, btype, inst);
5732
initial_props = initial_inst[4][i];
5733
for (j = 0, lenj = initial_props.length; j < lenj; j++)
5734
binst.properties[j] = initial_props[j];
5735
binst.onCreate();
5736
btype.behavior.my_instances.add(inst);
5737
}
5738
}
5739
else
5740
{
5741
inst.behavior_insts = [];
5742
for (i = 0, len = all_behaviors.length; i < len; i++)
5743
{
5744
var btype = all_behaviors[i];
5745
var binst = new btype.behavior.Instance(btype, inst);
5746
binst.recycled = false;
5747
binst.properties = initial_inst[4][i].slice(0);
5748
binst.onCreate();
5749
cr.seal(binst);
5750
inst.behavior_insts.push(binst);
5751
btype.behavior.my_instances.add(inst);
5752
}
5753
}
5754
initial_props = initial_inst[5];
5755
if (inst.recycled)
5756
{
5757
for (i = 0, len = initial_props.length; i < len; i++)
5758
inst.properties[i] = initial_props[i];
5759
}
5760
else
5761
inst.properties = initial_props.slice(0);
5762
this.createRow.push(inst);
5763
this.hasPendingInstances = true;
5764
if (layer)
5765
{
5766
;
5767
layer.appendToInstanceList(inst, true);
5768
if (layer.parallaxX !== 1 || layer.parallaxY !== 1)
5769
type.any_instance_parallaxed = true;
5770
}
5771
this.objectcount++;
5772
if (type.is_contained)
5773
{
5774
inst.is_contained = true;
5775
if (inst.recycled)
5776
cr.clearArray(inst.siblings);
5777
else
5778
inst.siblings = []; // note: should not include self in siblings
5779
if (!is_startup_instance && !skip_siblings) // layout links initial instances
5780
{
5781
for (i = 0, len = type.container.length; i < len; i++)
5782
{
5783
if (type.container[i] === type)
5784
continue;
5785
if (!type.container[i].default_instance)
5786
{
5787
return null;
5788
}
5789
inst.siblings.push(this.createInstanceFromInit(type.container[i].default_instance, original_layer, false, is_world ? inst.x : sx, is_world ? inst.y : sy, true));
5790
}
5791
for (i = 0, len = inst.siblings.length; i < len; i++)
5792
{
5793
inst.siblings[i].siblings.push(inst);
5794
for (j = 0; j < len; j++)
5795
{
5796
if (i !== j)
5797
inst.siblings[i].siblings.push(inst.siblings[j]);
5798
}
5799
}
5800
}
5801
}
5802
else
5803
{
5804
inst.is_contained = false;
5805
inst.siblings = null;
5806
}
5807
inst.onCreate();
5808
if (!inst.recycled)
5809
cr.seal(inst);
5810
for (i = 0, len = inst.behavior_insts.length; i < len; i++)
5811
{
5812
if (inst.behavior_insts[i].postCreate)
5813
inst.behavior_insts[i].postCreate();
5814
}
5815
return inst;
5816
};
5817
Runtime.prototype.getLayerByName = function (layer_name)
5818
{
5819
var i, len;
5820
for (i = 0, len = this.running_layout.layers.length; i < len; i++)
5821
{
5822
var layer = this.running_layout.layers[i];
5823
if (cr.equals_nocase(layer.name, layer_name))
5824
return layer;
5825
}
5826
return null;
5827
};
5828
Runtime.prototype.getLayerByNumber = function (index)
5829
{
5830
index = cr.floor(index);
5831
if (index < 0)
5832
index = 0;
5833
if (index >= this.running_layout.layers.length)
5834
index = this.running_layout.layers.length - 1;
5835
return this.running_layout.layers[index];
5836
};
5837
Runtime.prototype.getLayer = function (l)
5838
{
5839
if (cr.is_number(l))
5840
return this.getLayerByNumber(l);
5841
else
5842
return this.getLayerByName(l.toString());
5843
};
5844
Runtime.prototype.clearSol = function (solModifiers)
5845
{
5846
var i, len;
5847
for (i = 0, len = solModifiers.length; i < len; i++)
5848
{
5849
solModifiers[i].getCurrentSol().select_all = true;
5850
}
5851
};
5852
Runtime.prototype.pushCleanSol = function (solModifiers)
5853
{
5854
var i, len;
5855
for (i = 0, len = solModifiers.length; i < len; i++)
5856
{
5857
solModifiers[i].pushCleanSol();
5858
}
5859
};
5860
Runtime.prototype.pushCopySol = function (solModifiers)
5861
{
5862
var i, len;
5863
for (i = 0, len = solModifiers.length; i < len; i++)
5864
{
5865
solModifiers[i].pushCopySol();
5866
}
5867
};
5868
Runtime.prototype.popSol = function (solModifiers)
5869
{
5870
var i, len;
5871
for (i = 0, len = solModifiers.length; i < len; i++)
5872
{
5873
solModifiers[i].popSol();
5874
}
5875
};
5876
Runtime.prototype.updateAllCells = function (type)
5877
{
5878
if (!type.any_cell_changed)
5879
return; // all instances must already be up-to-date
5880
var i, len, instances = type.instances;
5881
for (i = 0, len = instances.length; i < len; ++i)
5882
{
5883
instances[i].update_collision_cell();
5884
}
5885
var createRow = this.createRow;
5886
for (i = 0, len = createRow.length; i < len; ++i)
5887
{
5888
if (createRow[i].type === type)
5889
createRow[i].update_collision_cell();
5890
}
5891
type.any_cell_changed = false;
5892
};
5893
Runtime.prototype.getCollisionCandidates = function (layer, rtype, bbox, candidates)
5894
{
5895
var i, len, t;
5896
var is_parallaxed = (layer ? (layer.parallaxX !== 1 || layer.parallaxY !== 1) : false);
5897
if (rtype.is_family)
5898
{
5899
for (i = 0, len = rtype.members.length; i < len; ++i)
5900
{
5901
t = rtype.members[i];
5902
if (is_parallaxed || t.any_instance_parallaxed)
5903
{
5904
cr.appendArray(candidates, t.instances);
5905
}
5906
else
5907
{
5908
this.updateAllCells(t);
5909
t.collision_grid.queryRange(bbox, candidates);
5910
}
5911
}
5912
}
5913
else
5914
{
5915
if (is_parallaxed || rtype.any_instance_parallaxed)
5916
{
5917
cr.appendArray(candidates, rtype.instances);
5918
}
5919
else
5920
{
5921
this.updateAllCells(rtype);
5922
rtype.collision_grid.queryRange(bbox, candidates);
5923
}
5924
}
5925
};
5926
Runtime.prototype.getTypesCollisionCandidates = function (layer, types, bbox, candidates)
5927
{
5928
var i, len;
5929
for (i = 0, len = types.length; i < len; ++i)
5930
{
5931
this.getCollisionCandidates(layer, types[i], bbox, candidates);
5932
}
5933
};
5934
Runtime.prototype.getSolidCollisionCandidates = function (layer, bbox, candidates)
5935
{
5936
var solid = this.getSolidBehavior();
5937
if (!solid)
5938
return null;
5939
this.getTypesCollisionCandidates(layer, solid.my_types, bbox, candidates);
5940
};
5941
Runtime.prototype.getJumpthruCollisionCandidates = function (layer, bbox, candidates)
5942
{
5943
var jumpthru = this.getJumpthruBehavior();
5944
if (!jumpthru)
5945
return null;
5946
this.getTypesCollisionCandidates(layer, jumpthru.my_types, bbox, candidates);
5947
};
5948
Runtime.prototype.testAndSelectCanvasPointOverlap = function (type, ptx, pty, inverted)
5949
{
5950
var sol = type.getCurrentSol();
5951
var i, j, inst, len;
5952
var orblock = this.getCurrentEventStack().current_event.orblock;
5953
var lx, ly, arr;
5954
if (sol.select_all)
5955
{
5956
if (!inverted)
5957
{
5958
sol.select_all = false;
5959
cr.clearArray(sol.instances); // clear contents
5960
}
5961
for (i = 0, len = type.instances.length; i < len; i++)
5962
{
5963
inst = type.instances[i];
5964
inst.update_bbox();
5965
lx = inst.layer.canvasToLayer(ptx, pty, true);
5966
ly = inst.layer.canvasToLayer(ptx, pty, false);
5967
if (inst.contains_pt(lx, ly))
5968
{
5969
if (inverted)
5970
return false;
5971
else
5972
sol.instances.push(inst);
5973
}
5974
else if (orblock)
5975
sol.else_instances.push(inst);
5976
}
5977
}
5978
else
5979
{
5980
j = 0;
5981
arr = (orblock ? sol.else_instances : sol.instances);
5982
for (i = 0, len = arr.length; i < len; i++)
5983
{
5984
inst = arr[i];
5985
inst.update_bbox();
5986
lx = inst.layer.canvasToLayer(ptx, pty, true);
5987
ly = inst.layer.canvasToLayer(ptx, pty, false);
5988
if (inst.contains_pt(lx, ly))
5989
{
5990
if (inverted)
5991
return false;
5992
else if (orblock)
5993
sol.instances.push(inst);
5994
else
5995
{
5996
sol.instances[j] = sol.instances[i];
5997
j++;
5998
}
5999
}
6000
}
6001
if (!inverted)
6002
arr.length = j;
6003
}
6004
type.applySolToContainer();
6005
if (inverted)
6006
return true; // did not find anything overlapping
6007
else
6008
return sol.hasObjects();
6009
};
6010
Runtime.prototype.testOverlap = function (a, b)
6011
{
6012
if (!a || !b || a === b || !a.collisionsEnabled || !b.collisionsEnabled)
6013
return false;
6014
a.update_bbox();
6015
b.update_bbox();
6016
var layera = a.layer;
6017
var layerb = b.layer;
6018
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));
6019
var i, len, i2, i21, x, y, haspolya, haspolyb, polya, polyb;
6020
if (!different_layers) // same layers: easy check
6021
{
6022
if (!a.bbox.intersects_rect(b.bbox))
6023
return false;
6024
if (!a.bquad.intersects_quad(b.bquad))
6025
return false;
6026
if (a.tilemap_exists && b.tilemap_exists)
6027
return false;
6028
if (a.tilemap_exists)
6029
return this.testTilemapOverlap(a, b);
6030
if (b.tilemap_exists)
6031
return this.testTilemapOverlap(b, a);
6032
haspolya = (a.collision_poly && !a.collision_poly.is_empty());
6033
haspolyb = (b.collision_poly && !b.collision_poly.is_empty());
6034
if (!haspolya && !haspolyb)
6035
return true;
6036
if (haspolya)
6037
{
6038
a.collision_poly.cache_poly(a.width, a.height, a.angle);
6039
polya = a.collision_poly;
6040
}
6041
else
6042
{
6043
this.temp_poly.set_from_quad(a.bquad, a.x, a.y, a.width, a.height);
6044
polya = this.temp_poly;
6045
}
6046
if (haspolyb)
6047
{
6048
b.collision_poly.cache_poly(b.width, b.height, b.angle);
6049
polyb = b.collision_poly;
6050
}
6051
else
6052
{
6053
this.temp_poly.set_from_quad(b.bquad, b.x, b.y, b.width, b.height);
6054
polyb = this.temp_poly;
6055
}
6056
return polya.intersects_poly(polyb, b.x - a.x, b.y - a.y);
6057
}
6058
else // different layers: need to do full translated check
6059
{
6060
haspolya = (a.collision_poly && !a.collision_poly.is_empty());
6061
haspolyb = (b.collision_poly && !b.collision_poly.is_empty());
6062
if (haspolya)
6063
{
6064
a.collision_poly.cache_poly(a.width, a.height, a.angle);
6065
this.temp_poly.set_from_poly(a.collision_poly);
6066
}
6067
else
6068
{
6069
this.temp_poly.set_from_quad(a.bquad, a.x, a.y, a.width, a.height);
6070
}
6071
polya = this.temp_poly;
6072
if (haspolyb)
6073
{
6074
b.collision_poly.cache_poly(b.width, b.height, b.angle);
6075
this.temp_poly2.set_from_poly(b.collision_poly);
6076
}
6077
else
6078
{
6079
this.temp_poly2.set_from_quad(b.bquad, b.x, b.y, b.width, b.height);
6080
}
6081
polyb = this.temp_poly2;
6082
for (i = 0, len = polya.pts_count; i < len; i++)
6083
{
6084
i2 = i * 2;
6085
i21 = i2 + 1;
6086
x = polya.pts_cache[i2];
6087
y = polya.pts_cache[i21];
6088
polya.pts_cache[i2] = layera.layerToCanvas(x + a.x, y + a.y, true);
6089
polya.pts_cache[i21] = layera.layerToCanvas(x + a.x, y + a.y, false);
6090
}
6091
polya.update_bbox();
6092
for (i = 0, len = polyb.pts_count; i < len; i++)
6093
{
6094
i2 = i * 2;
6095
i21 = i2 + 1;
6096
x = polyb.pts_cache[i2];
6097
y = polyb.pts_cache[i21];
6098
polyb.pts_cache[i2] = layerb.layerToCanvas(x + b.x, y + b.y, true);
6099
polyb.pts_cache[i21] = layerb.layerToCanvas(x + b.x, y + b.y, false);
6100
}
6101
polyb.update_bbox();
6102
return polya.intersects_poly(polyb, 0, 0);
6103
}
6104
};
6105
var tmpQuad = new cr.quad();
6106
var tmpRect = new cr.rect(0, 0, 0, 0);
6107
var collrect_candidates = [];
6108
Runtime.prototype.testTilemapOverlap = function (tm, a)
6109
{
6110
var i, len, c, rc;
6111
var bbox = a.bbox;
6112
var tmx = tm.x;
6113
var tmy = tm.y;
6114
tm.getCollisionRectCandidates(bbox, collrect_candidates);
6115
var collrects = collrect_candidates;
6116
var haspolya = (a.collision_poly && !a.collision_poly.is_empty());
6117
for (i = 0, len = collrects.length; i < len; ++i)
6118
{
6119
c = collrects[i];
6120
rc = c.rc;
6121
if (bbox.intersects_rect_off(rc, tmx, tmy))
6122
{
6123
tmpQuad.set_from_rect(rc);
6124
tmpQuad.offset(tmx, tmy);
6125
if (tmpQuad.intersects_quad(a.bquad))
6126
{
6127
if (haspolya)
6128
{
6129
a.collision_poly.cache_poly(a.width, a.height, a.angle);
6130
if (c.poly)
6131
{
6132
if (c.poly.intersects_poly(a.collision_poly, a.x - (tmx + rc.left), a.y - (tmy + rc.top)))
6133
{
6134
cr.clearArray(collrect_candidates);
6135
return true;
6136
}
6137
}
6138
else
6139
{
6140
this.temp_poly.set_from_quad(tmpQuad, 0, 0, rc.right - rc.left, rc.bottom - rc.top);
6141
if (this.temp_poly.intersects_poly(a.collision_poly, a.x, a.y))
6142
{
6143
cr.clearArray(collrect_candidates);
6144
return true;
6145
}
6146
}
6147
}
6148
else
6149
{
6150
if (c.poly)
6151
{
6152
this.temp_poly.set_from_quad(a.bquad, 0, 0, a.width, a.height);
6153
if (c.poly.intersects_poly(this.temp_poly, -(tmx + rc.left), -(tmy + rc.top)))
6154
{
6155
cr.clearArray(collrect_candidates);
6156
return true;
6157
}
6158
}
6159
else
6160
{
6161
cr.clearArray(collrect_candidates);
6162
return true;
6163
}
6164
}
6165
}
6166
}
6167
}
6168
cr.clearArray(collrect_candidates);
6169
return false;
6170
};
6171
Runtime.prototype.testRectOverlap = function (r, b)
6172
{
6173
if (!b || !b.collisionsEnabled)
6174
return false;
6175
b.update_bbox();
6176
var layerb = b.layer;
6177
var haspolyb, polyb;
6178
if (!b.bbox.intersects_rect(r))
6179
return false;
6180
if (b.tilemap_exists)
6181
{
6182
b.getCollisionRectCandidates(r, collrect_candidates);
6183
var collrects = collrect_candidates;
6184
var i, len, c, tilerc;
6185
var tmx = b.x;
6186
var tmy = b.y;
6187
for (i = 0, len = collrects.length; i < len; ++i)
6188
{
6189
c = collrects[i];
6190
tilerc = c.rc;
6191
if (r.intersects_rect_off(tilerc, tmx, tmy))
6192
{
6193
if (c.poly)
6194
{
6195
this.temp_poly.set_from_rect(r, 0, 0);
6196
if (c.poly.intersects_poly(this.temp_poly, -(tmx + tilerc.left), -(tmy + tilerc.top)))
6197
{
6198
cr.clearArray(collrect_candidates);
6199
return true;
6200
}
6201
}
6202
else
6203
{
6204
cr.clearArray(collrect_candidates);
6205
return true;
6206
}
6207
}
6208
}
6209
cr.clearArray(collrect_candidates);
6210
return false;
6211
}
6212
else
6213
{
6214
tmpQuad.set_from_rect(r);
6215
if (!b.bquad.intersects_quad(tmpQuad))
6216
return false;
6217
haspolyb = (b.collision_poly && !b.collision_poly.is_empty());
6218
if (!haspolyb)
6219
return true;
6220
b.collision_poly.cache_poly(b.width, b.height, b.angle);
6221
tmpQuad.offset(-r.left, -r.top);
6222
this.temp_poly.set_from_quad(tmpQuad, 0, 0, 1, 1);
6223
return b.collision_poly.intersects_poly(this.temp_poly, r.left - b.x, r.top - b.y);
6224
}
6225
};
6226
Runtime.prototype.testSegmentOverlap = function (x1, y1, x2, y2, b)
6227
{
6228
if (!b || !b.collisionsEnabled)
6229
return false;
6230
b.update_bbox();
6231
var layerb = b.layer;
6232
var haspolyb, polyb;
6233
tmpRect.set(cr.min(x1, x2), cr.min(y1, y2), cr.max(x1, x2), cr.max(y1, y2));
6234
if (!b.bbox.intersects_rect(tmpRect))
6235
return false;
6236
if (b.tilemap_exists)
6237
{
6238
b.getCollisionRectCandidates(tmpRect, collrect_candidates);
6239
var collrects = collrect_candidates;
6240
var i, len, c, tilerc;
6241
var tmx = b.x;
6242
var tmy = b.y;
6243
for (i = 0, len = collrects.length; i < len; ++i)
6244
{
6245
c = collrects[i];
6246
tilerc = c.rc;
6247
if (tmpRect.intersects_rect_off(tilerc, tmx, tmy))
6248
{
6249
tmpQuad.set_from_rect(tilerc);
6250
tmpQuad.offset(tmx, tmy);
6251
if (tmpQuad.intersects_segment(x1, y1, x2, y2))
6252
{
6253
if (c.poly)
6254
{
6255
if (c.poly.intersects_segment(tmx + tilerc.left, tmy + tilerc.top, x1, y1, x2, y2))
6256
{
6257
cr.clearArray(collrect_candidates);
6258
return true;
6259
}
6260
}
6261
else
6262
{
6263
cr.clearArray(collrect_candidates);
6264
return true;
6265
}
6266
}
6267
}
6268
}
6269
cr.clearArray(collrect_candidates);
6270
return false;
6271
}
6272
else
6273
{
6274
if (!b.bquad.intersects_segment(x1, y1, x2, y2))
6275
return false;
6276
haspolyb = (b.collision_poly && !b.collision_poly.is_empty());
6277
if (!haspolyb)
6278
return true;
6279
b.collision_poly.cache_poly(b.width, b.height, b.angle);
6280
return b.collision_poly.intersects_segment(b.x, b.y, x1, y1, x2, y2);
6281
}
6282
};
6283
Runtime.prototype.typeHasBehavior = function (t, b)
6284
{
6285
if (!b)
6286
return false;
6287
var i, len, j, lenj, f;
6288
for (i = 0, len = t.behaviors.length; i < len; i++)
6289
{
6290
if (t.behaviors[i].behavior instanceof b)
6291
return true;
6292
}
6293
if (!t.is_family)
6294
{
6295
for (i = 0, len = t.families.length; i < len; i++)
6296
{
6297
f = t.families[i];
6298
for (j = 0, lenj = f.behaviors.length; j < lenj; j++)
6299
{
6300
if (f.behaviors[j].behavior instanceof b)
6301
return true;
6302
}
6303
}
6304
}
6305
return false;
6306
};
6307
Runtime.prototype.typeHasNoSaveBehavior = function (t)
6308
{
6309
return this.typeHasBehavior(t, cr.behaviors.NoSave);
6310
};
6311
Runtime.prototype.typeHasPersistBehavior = function (t)
6312
{
6313
return this.typeHasBehavior(t, cr.behaviors.Persist);
6314
};
6315
Runtime.prototype.getSolidBehavior = function ()
6316
{
6317
return this.solidBehavior;
6318
};
6319
Runtime.prototype.getJumpthruBehavior = function ()
6320
{
6321
return this.jumpthruBehavior;
6322
};
6323
var candidates = [];
6324
Runtime.prototype.testOverlapSolid = function (inst)
6325
{
6326
var i, len, s;
6327
inst.update_bbox();
6328
this.getSolidCollisionCandidates(inst.layer, inst.bbox, candidates);
6329
for (i = 0, len = candidates.length; i < len; ++i)
6330
{
6331
s = candidates[i];
6332
if (!s.extra["solidEnabled"])
6333
continue;
6334
if (this.testOverlap(inst, s))
6335
{
6336
cr.clearArray(candidates);
6337
return s;
6338
}
6339
}
6340
cr.clearArray(candidates);
6341
return null;
6342
};
6343
Runtime.prototype.testRectOverlapSolid = function (r)
6344
{
6345
var i, len, s;
6346
this.getSolidCollisionCandidates(null, r, candidates);
6347
for (i = 0, len = candidates.length; i < len; ++i)
6348
{
6349
s = candidates[i];
6350
if (!s.extra["solidEnabled"])
6351
continue;
6352
if (this.testRectOverlap(r, s))
6353
{
6354
cr.clearArray(candidates);
6355
return s;
6356
}
6357
}
6358
cr.clearArray(candidates);
6359
return null;
6360
};
6361
var jumpthru_array_ret = [];
6362
Runtime.prototype.testOverlapJumpThru = function (inst, all)
6363
{
6364
var ret = null;
6365
if (all)
6366
{
6367
ret = jumpthru_array_ret;
6368
cr.clearArray(ret);
6369
}
6370
inst.update_bbox();
6371
this.getJumpthruCollisionCandidates(inst.layer, inst.bbox, candidates);
6372
var i, len, j;
6373
for (i = 0, len = candidates.length; i < len; ++i)
6374
{
6375
j = candidates[i];
6376
if (!j.extra["jumpthruEnabled"])
6377
continue;
6378
if (this.testOverlap(inst, j))
6379
{
6380
if (all)
6381
ret.push(j);
6382
else
6383
{
6384
cr.clearArray(candidates);
6385
return j;
6386
}
6387
}
6388
}
6389
cr.clearArray(candidates);
6390
return ret;
6391
};
6392
Runtime.prototype.pushOutSolid = function (inst, xdir, ydir, dist, include_jumpthrus, specific_jumpthru)
6393
{
6394
var push_dist = dist || 50;
6395
var oldx = inst.x
6396
var oldy = inst.y;
6397
var i;
6398
var last_overlapped = null, secondlast_overlapped = null;
6399
for (i = 0; i < push_dist; i++)
6400
{
6401
inst.x = (oldx + (xdir * i));
6402
inst.y = (oldy + (ydir * i));
6403
inst.set_bbox_changed();
6404
if (!this.testOverlap(inst, last_overlapped))
6405
{
6406
last_overlapped = this.testOverlapSolid(inst);
6407
if (last_overlapped)
6408
secondlast_overlapped = last_overlapped;
6409
if (!last_overlapped)
6410
{
6411
if (include_jumpthrus)
6412
{
6413
if (specific_jumpthru)
6414
last_overlapped = (this.testOverlap(inst, specific_jumpthru) ? specific_jumpthru : null);
6415
else
6416
last_overlapped = this.testOverlapJumpThru(inst);
6417
if (last_overlapped)
6418
secondlast_overlapped = last_overlapped;
6419
}
6420
if (!last_overlapped)
6421
{
6422
if (secondlast_overlapped)
6423
this.pushInFractional(inst, xdir, ydir, secondlast_overlapped, 16);
6424
return true;
6425
}
6426
}
6427
}
6428
}
6429
inst.x = oldx;
6430
inst.y = oldy;
6431
inst.set_bbox_changed();
6432
return false;
6433
};
6434
Runtime.prototype.pushOutSolidAxis = function(inst, xdir, ydir, dist)
6435
{
6436
dist = dist || 50;
6437
var oldX = inst.x;
6438
var oldY = inst.y;
6439
var lastOverlapped = null;
6440
var secondLastOverlapped = null;
6441
var i, which, sign;
6442
for (i = 0; i < dist; ++i)
6443
{
6444
for (which = 0; which < 2; ++which)
6445
{
6446
sign = which * 2 - 1; // -1 or 1
6447
inst.x = oldX + (xdir * i * sign);
6448
inst.y = oldY + (ydir * i * sign);
6449
inst.set_bbox_changed();
6450
if (!this.testOverlap(inst, lastOverlapped))
6451
{
6452
lastOverlapped = this.testOverlapSolid(inst);
6453
if (lastOverlapped)
6454
{
6455
secondLastOverlapped = lastOverlapped;
6456
}
6457
else
6458
{
6459
if (secondLastOverlapped)
6460
this.pushInFractional(inst, xdir * sign, ydir * sign, secondLastOverlapped, 16);
6461
return true;
6462
}
6463
}
6464
}
6465
}
6466
inst.x = oldX;
6467
inst.y = oldY;
6468
inst.set_bbox_changed();
6469
return false;
6470
};
6471
Runtime.prototype.pushOut = function (inst, xdir, ydir, dist, otherinst)
6472
{
6473
var push_dist = dist || 50;
6474
var oldx = inst.x
6475
var oldy = inst.y;
6476
var i;
6477
for (i = 0; i < push_dist; i++)
6478
{
6479
inst.x = (oldx + (xdir * i));
6480
inst.y = (oldy + (ydir * i));
6481
inst.set_bbox_changed();
6482
if (!this.testOverlap(inst, otherinst))
6483
return true;
6484
}
6485
inst.x = oldx;
6486
inst.y = oldy;
6487
inst.set_bbox_changed();
6488
return false;
6489
};
6490
Runtime.prototype.pushInFractional = function (inst, xdir, ydir, obj, limit)
6491
{
6492
var divisor = 2;
6493
var frac;
6494
var forward = false;
6495
var overlapping = false;
6496
var bestx = inst.x;
6497
var besty = inst.y;
6498
while (divisor <= limit)
6499
{
6500
frac = 1 / divisor;
6501
divisor *= 2;
6502
inst.x += xdir * frac * (forward ? 1 : -1);
6503
inst.y += ydir * frac * (forward ? 1 : -1);
6504
inst.set_bbox_changed();
6505
if (this.testOverlap(inst, obj))
6506
{
6507
forward = true;
6508
overlapping = true;
6509
}
6510
else
6511
{
6512
forward = false;
6513
overlapping = false;
6514
bestx = inst.x;
6515
besty = inst.y;
6516
}
6517
}
6518
if (overlapping)
6519
{
6520
inst.x = bestx;
6521
inst.y = besty;
6522
inst.set_bbox_changed();
6523
}
6524
};
6525
Runtime.prototype.pushOutSolidNearest = function (inst, max_dist_)
6526
{
6527
var max_dist = (cr.is_undefined(max_dist_) ? 100 : max_dist_);
6528
var dist = 0;
6529
var oldx = inst.x
6530
var oldy = inst.y;
6531
var dir = 0;
6532
var dx = 0, dy = 0;
6533
var last_overlapped = this.testOverlapSolid(inst);
6534
if (!last_overlapped)
6535
return true; // already clear of solids
6536
while (dist <= max_dist)
6537
{
6538
switch (dir) {
6539
case 0: dx = 0; dy = -1; dist++; break;
6540
case 1: dx = 1; dy = -1; break;
6541
case 2: dx = 1; dy = 0; break;
6542
case 3: dx = 1; dy = 1; break;
6543
case 4: dx = 0; dy = 1; break;
6544
case 5: dx = -1; dy = 1; break;
6545
case 6: dx = -1; dy = 0; break;
6546
case 7: dx = -1; dy = -1; break;
6547
}
6548
dir = (dir + 1) % 8;
6549
inst.x = cr.floor(oldx + (dx * dist));
6550
inst.y = cr.floor(oldy + (dy * dist));
6551
inst.set_bbox_changed();
6552
if (!this.testOverlap(inst, last_overlapped))
6553
{
6554
last_overlapped = this.testOverlapSolid(inst);
6555
if (!last_overlapped)
6556
return true;
6557
}
6558
}
6559
inst.x = oldx;
6560
inst.y = oldy;
6561
inst.set_bbox_changed();
6562
return false;
6563
};
6564
Runtime.prototype.registerCollision = function (a, b)
6565
{
6566
if (!a.collisionsEnabled || !b.collisionsEnabled)
6567
return;
6568
this.registered_collisions.push([a, b]);
6569
};
6570
Runtime.prototype.addRegisteredCollisionCandidates = function (inst, otherType, arr)
6571
{
6572
var i, len, r, otherInst;
6573
for (i = 0, len = this.registered_collisions.length; i < len; ++i)
6574
{
6575
r = this.registered_collisions[i];
6576
if (r[0] === inst)
6577
otherInst = r[1];
6578
else if (r[1] === inst)
6579
otherInst = r[0];
6580
else
6581
continue;
6582
if (otherType.is_family)
6583
{
6584
if (otherType.members.indexOf(otherType) === -1)
6585
continue;
6586
}
6587
else
6588
{
6589
if (otherInst.type !== otherType)
6590
continue;
6591
}
6592
if (arr.indexOf(otherInst) === -1)
6593
arr.push(otherInst);
6594
}
6595
};
6596
Runtime.prototype.checkRegisteredCollision = function (a, b)
6597
{
6598
var i, len, x;
6599
for (i = 0, len = this.registered_collisions.length; i < len; i++)
6600
{
6601
x = this.registered_collisions[i];
6602
if ((x[0] === a && x[1] === b) || (x[0] === b && x[1] === a))
6603
return true;
6604
}
6605
return false;
6606
};
6607
Runtime.prototype.calculateSolidBounceAngle = function(inst, startx, starty, obj)
6608
{
6609
var objx = inst.x;
6610
var objy = inst.y;
6611
var radius = cr.max(10, cr.distanceTo(startx, starty, objx, objy));
6612
var startangle = cr.angleTo(startx, starty, objx, objy);
6613
var firstsolid = obj || this.testOverlapSolid(inst);
6614
if (!firstsolid)
6615
return cr.clamp_angle(startangle + cr.PI);
6616
var cursolid = firstsolid;
6617
var i, curangle, anticlockwise_free_angle, clockwise_free_angle;
6618
var increment = cr.to_radians(5); // 5 degree increments
6619
for (i = 1; i < 36; i++)
6620
{
6621
curangle = startangle - i * increment;
6622
inst.x = startx + Math.cos(curangle) * radius;
6623
inst.y = starty + Math.sin(curangle) * radius;
6624
inst.set_bbox_changed();
6625
if (!this.testOverlap(inst, cursolid))
6626
{
6627
cursolid = obj ? null : this.testOverlapSolid(inst);
6628
if (!cursolid)
6629
{
6630
anticlockwise_free_angle = curangle;
6631
break;
6632
}
6633
}
6634
}
6635
if (i === 36)
6636
anticlockwise_free_angle = cr.clamp_angle(startangle + cr.PI);
6637
var cursolid = firstsolid;
6638
for (i = 1; i < 36; i++)
6639
{
6640
curangle = startangle + i * increment;
6641
inst.x = startx + Math.cos(curangle) * radius;
6642
inst.y = starty + Math.sin(curangle) * radius;
6643
inst.set_bbox_changed();
6644
if (!this.testOverlap(inst, cursolid))
6645
{
6646
cursolid = obj ? null : this.testOverlapSolid(inst);
6647
if (!cursolid)
6648
{
6649
clockwise_free_angle = curangle;
6650
break;
6651
}
6652
}
6653
}
6654
if (i === 36)
6655
clockwise_free_angle = cr.clamp_angle(startangle + cr.PI);
6656
inst.x = objx;
6657
inst.y = objy;
6658
inst.set_bbox_changed();
6659
if (clockwise_free_angle === anticlockwise_free_angle)
6660
return clockwise_free_angle;
6661
var half_diff = cr.angleDiff(clockwise_free_angle, anticlockwise_free_angle) / 2;
6662
var normal;
6663
if (cr.angleClockwise(clockwise_free_angle, anticlockwise_free_angle))
6664
{
6665
normal = cr.clamp_angle(anticlockwise_free_angle + half_diff + cr.PI);
6666
}
6667
else
6668
{
6669
normal = cr.clamp_angle(clockwise_free_angle + half_diff);
6670
}
6671
;
6672
var vx = Math.cos(startangle);
6673
var vy = Math.sin(startangle);
6674
var nx = Math.cos(normal);
6675
var ny = Math.sin(normal);
6676
var v_dot_n = vx * nx + vy * ny;
6677
var rx = vx - 2 * v_dot_n * nx;
6678
var ry = vy - 2 * v_dot_n * ny;
6679
return cr.angleTo(0, 0, rx, ry);
6680
};
6681
var triggerSheetIndex = -1;
6682
Runtime.prototype.trigger = function (method, inst, value /* for fast triggers */)
6683
{
6684
;
6685
if (!this.running_layout)
6686
return false;
6687
var sheet = this.running_layout.event_sheet;
6688
if (!sheet)
6689
return false; // no event sheet active; nothing to trigger
6690
var ret = false;
6691
var r, i, len;
6692
triggerSheetIndex++;
6693
var deep_includes = sheet.deep_includes;
6694
for (i = 0, len = deep_includes.length; i < len; ++i)
6695
{
6696
r = this.triggerOnSheet(method, inst, deep_includes[i], value);
6697
ret = ret || r;
6698
}
6699
r = this.triggerOnSheet(method, inst, sheet, value);
6700
ret = ret || r;
6701
triggerSheetIndex--;
6702
return ret;
6703
};
6704
Runtime.prototype.triggerOnSheet = function (method, inst, sheet, value)
6705
{
6706
var ret = false;
6707
var i, leni, r, families;
6708
if (!inst)
6709
{
6710
r = this.triggerOnSheetForTypeName(method, inst, "system", sheet, value);
6711
ret = ret || r;
6712
}
6713
else
6714
{
6715
r = this.triggerOnSheetForTypeName(method, inst, inst.type.name, sheet, value);
6716
ret = ret || r;
6717
families = inst.type.families;
6718
for (i = 0, leni = families.length; i < leni; ++i)
6719
{
6720
r = this.triggerOnSheetForTypeName(method, inst, families[i].name, sheet, value);
6721
ret = ret || r;
6722
}
6723
}
6724
return ret; // true if anything got triggered
6725
};
6726
Runtime.prototype.triggerOnSheetForTypeName = function (method, inst, type_name, sheet, value)
6727
{
6728
var i, leni;
6729
var ret = false, ret2 = false;
6730
var trig, index;
6731
var fasttrigger = (typeof value !== "undefined");
6732
var triggers = (fasttrigger ? sheet.fasttriggers : sheet.triggers);
6733
var obj_entry = triggers[type_name];
6734
if (!obj_entry)
6735
return ret;
6736
var triggers_list = null;
6737
for (i = 0, leni = obj_entry.length; i < leni; ++i)
6738
{
6739
if (obj_entry[i].method == method)
6740
{
6741
triggers_list = obj_entry[i].evs;
6742
break;
6743
}
6744
}
6745
if (!triggers_list)
6746
return ret;
6747
var triggers_to_fire;
6748
if (fasttrigger)
6749
{
6750
triggers_to_fire = triggers_list[value];
6751
}
6752
else
6753
{
6754
triggers_to_fire = triggers_list;
6755
}
6756
if (!triggers_to_fire)
6757
return null;
6758
for (i = 0, leni = triggers_to_fire.length; i < leni; i++)
6759
{
6760
trig = triggers_to_fire[i][0];
6761
index = triggers_to_fire[i][1];
6762
ret2 = this.executeSingleTrigger(inst, type_name, trig, index);
6763
ret = ret || ret2;
6764
}
6765
return ret;
6766
};
6767
Runtime.prototype.executeSingleTrigger = function (inst, type_name, trig, index)
6768
{
6769
var i, leni;
6770
var ret = false;
6771
this.trigger_depth++;
6772
var current_event = this.getCurrentEventStack().current_event;
6773
if (current_event)
6774
this.pushCleanSol(current_event.solModifiersIncludingParents);
6775
var isrecursive = (this.trigger_depth > 1); // calling trigger from inside another trigger
6776
this.pushCleanSol(trig.solModifiersIncludingParents);
6777
if (isrecursive)
6778
this.pushLocalVarStack();
6779
var event_stack = this.pushEventStack(trig);
6780
event_stack.current_event = trig;
6781
if (inst)
6782
{
6783
var sol = this.types[type_name].getCurrentSol();
6784
sol.select_all = false;
6785
cr.clearArray(sol.instances);
6786
sol.instances[0] = inst;
6787
this.types[type_name].applySolToContainer();
6788
}
6789
var ok_to_run = true;
6790
if (trig.parent)
6791
{
6792
var temp_parents_arr = event_stack.temp_parents_arr;
6793
var cur_parent = trig.parent;
6794
while (cur_parent)
6795
{
6796
temp_parents_arr.push(cur_parent);
6797
cur_parent = cur_parent.parent;
6798
}
6799
temp_parents_arr.reverse();
6800
for (i = 0, leni = temp_parents_arr.length; i < leni; i++)
6801
{
6802
if (!temp_parents_arr[i].run_pretrigger()) // parent event failed
6803
{
6804
ok_to_run = false;
6805
break;
6806
}
6807
}
6808
}
6809
if (ok_to_run)
6810
{
6811
this.execcount++;
6812
if (trig.orblock)
6813
trig.run_orblocktrigger(index);
6814
else
6815
trig.run();
6816
ret = ret || event_stack.last_event_true;
6817
}
6818
this.popEventStack();
6819
if (isrecursive)
6820
this.popLocalVarStack();
6821
this.popSol(trig.solModifiersIncludingParents);
6822
if (current_event)
6823
this.popSol(current_event.solModifiersIncludingParents);
6824
if (this.hasPendingInstances && this.isInOnDestroy === 0 && triggerSheetIndex === 0 && !this.isRunningEvents)
6825
{
6826
this.ClearDeathRow();
6827
}
6828
this.trigger_depth--;
6829
return ret;
6830
};
6831
Runtime.prototype.getCurrentCondition = function ()
6832
{
6833
var evinfo = this.getCurrentEventStack();
6834
return evinfo.current_event.conditions[evinfo.cndindex];
6835
};
6836
Runtime.prototype.getCurrentConditionObjectType = function ()
6837
{
6838
var cnd = this.getCurrentCondition();
6839
return cnd.type;
6840
};
6841
Runtime.prototype.isCurrentConditionFirst = function ()
6842
{
6843
var evinfo = this.getCurrentEventStack();
6844
return evinfo.cndindex === 0;
6845
};
6846
Runtime.prototype.getCurrentAction = function ()
6847
{
6848
var evinfo = this.getCurrentEventStack();
6849
return evinfo.current_event.actions[evinfo.actindex];
6850
};
6851
Runtime.prototype.pushLocalVarStack = function ()
6852
{
6853
this.localvar_stack_index++;
6854
if (this.localvar_stack_index >= this.localvar_stack.length)
6855
this.localvar_stack.push([]);
6856
};
6857
Runtime.prototype.popLocalVarStack = function ()
6858
{
6859
;
6860
this.localvar_stack_index--;
6861
};
6862
Runtime.prototype.getCurrentLocalVarStack = function ()
6863
{
6864
return this.localvar_stack[this.localvar_stack_index];
6865
};
6866
Runtime.prototype.pushEventStack = function (cur_event)
6867
{
6868
this.event_stack_index++;
6869
if (this.event_stack_index >= this.event_stack.length)
6870
this.event_stack.push(new cr.eventStackFrame());
6871
var ret = this.getCurrentEventStack();
6872
ret.reset(cur_event);
6873
return ret;
6874
};
6875
Runtime.prototype.popEventStack = function ()
6876
{
6877
;
6878
this.event_stack_index--;
6879
};
6880
Runtime.prototype.getCurrentEventStack = function ()
6881
{
6882
return this.event_stack[this.event_stack_index];
6883
};
6884
Runtime.prototype.pushLoopStack = function (name_)
6885
{
6886
this.loop_stack_index++;
6887
if (this.loop_stack_index >= this.loop_stack.length)
6888
{
6889
this.loop_stack.push(cr.seal({ name: name_, index: 0, stopped: false }));
6890
}
6891
var ret = this.getCurrentLoop();
6892
ret.name = name_;
6893
ret.index = 0;
6894
ret.stopped = false;
6895
return ret;
6896
};
6897
Runtime.prototype.popLoopStack = function ()
6898
{
6899
;
6900
this.loop_stack_index--;
6901
};
6902
Runtime.prototype.getCurrentLoop = function ()
6903
{
6904
return this.loop_stack[this.loop_stack_index];
6905
};
6906
Runtime.prototype.getEventVariableByName = function (name, scope)
6907
{
6908
var i, leni, j, lenj, sheet, e;
6909
while (scope)
6910
{
6911
for (i = 0, leni = scope.subevents.length; i < leni; i++)
6912
{
6913
e = scope.subevents[i];
6914
if (e instanceof cr.eventvariable && cr.equals_nocase(name, e.name))
6915
return e;
6916
}
6917
scope = scope.parent;
6918
}
6919
for (i = 0, leni = this.eventsheets_by_index.length; i < leni; i++)
6920
{
6921
sheet = this.eventsheets_by_index[i];
6922
for (j = 0, lenj = sheet.events.length; j < lenj; j++)
6923
{
6924
e = sheet.events[j];
6925
if (e instanceof cr.eventvariable && cr.equals_nocase(name, e.name))
6926
return e;
6927
}
6928
}
6929
return null;
6930
};
6931
Runtime.prototype.getLayoutBySid = function (sid_)
6932
{
6933
var i, len;
6934
for (i = 0, len = this.layouts_by_index.length; i < len; i++)
6935
{
6936
if (this.layouts_by_index[i].sid === sid_)
6937
return this.layouts_by_index[i];
6938
}
6939
return null;
6940
};
6941
Runtime.prototype.getObjectTypeBySid = function (sid_)
6942
{
6943
var i, len;
6944
for (i = 0, len = this.types_by_index.length; i < len; i++)
6945
{
6946
if (this.types_by_index[i].sid === sid_)
6947
return this.types_by_index[i];
6948
}
6949
return null;
6950
};
6951
Runtime.prototype.getGroupBySid = function (sid_)
6952
{
6953
var i, len;
6954
for (i = 0, len = this.allGroups.length; i < len; i++)
6955
{
6956
if (this.allGroups[i].sid === sid_)
6957
return this.allGroups[i];
6958
}
6959
return null;
6960
};
6961
Runtime.prototype.doCanvasSnapshot = function (format_, quality_)
6962
{
6963
this.snapshotCanvas = [format_, quality_];
6964
this.redraw = true; // force redraw so snapshot is always taken
6965
};
6966
function IsIndexedDBAvailable()
6967
{
6968
try {
6969
return !!window.indexedDB;
6970
}
6971
catch (e)
6972
{
6973
return false;
6974
}
6975
};
6976
function makeSaveDb(e)
6977
{
6978
var db = e.target.result;
6979
db.createObjectStore("saves", { keyPath: "slot" });
6980
};
6981
function IndexedDB_WriteSlot(slot_, data_, oncomplete_, onerror_)
6982
{
6983
try {
6984
var request = indexedDB.open("_C2SaveStates");
6985
request.onupgradeneeded = makeSaveDb;
6986
request.onerror = onerror_;
6987
request.onsuccess = function (e)
6988
{
6989
var db = e.target.result;
6990
db.onerror = onerror_;
6991
var transaction = db.transaction(["saves"], "readwrite");
6992
var objectStore = transaction.objectStore("saves");
6993
var putReq = objectStore.put({"slot": slot_, "data": data_ });
6994
putReq.onsuccess = oncomplete_;
6995
};
6996
}
6997
catch (err)
6998
{
6999
onerror_(err);
7000
}
7001
};
7002
function IndexedDB_ReadSlot(slot_, oncomplete_, onerror_)
7003
{
7004
try {
7005
var request = indexedDB.open("_C2SaveStates");
7006
request.onupgradeneeded = makeSaveDb;
7007
request.onerror = onerror_;
7008
request.onsuccess = function (e)
7009
{
7010
var db = e.target.result;
7011
db.onerror = onerror_;
7012
var transaction = db.transaction(["saves"]);
7013
var objectStore = transaction.objectStore("saves");
7014
var readReq = objectStore.get(slot_);
7015
readReq.onsuccess = function (e)
7016
{
7017
if (readReq.result)
7018
oncomplete_(readReq.result["data"]);
7019
else
7020
oncomplete_(null);
7021
};
7022
};
7023
}
7024
catch (err)
7025
{
7026
onerror_(err);
7027
}
7028
};
7029
Runtime.prototype.signalContinuousPreview = function ()
7030
{
7031
this.signalledContinuousPreview = true;
7032
};
7033
function doContinuousPreviewReload()
7034
{
7035
cr.logexport("Reloading for continuous preview");
7036
if (!!window["c2cocoonjs"])
7037
{
7038
CocoonJS["App"]["reload"]();
7039
}
7040
else
7041
{
7042
if (window.location.search.indexOf("continuous") > -1)
7043
window.location.reload(true);
7044
else
7045
window.location = window.location + "?continuous";
7046
}
7047
};
7048
Runtime.prototype.handleSaveLoad = function ()
7049
{
7050
var self = this;
7051
var savingToSlot = this.saveToSlot;
7052
var savingJson = this.lastSaveJson;
7053
var loadingFromSlot = this.loadFromSlot;
7054
var continuous = false;
7055
if (this.signalledContinuousPreview)
7056
{
7057
continuous = true;
7058
savingToSlot = "__c2_continuouspreview";
7059
this.signalledContinuousPreview = false;
7060
}
7061
if (savingToSlot.length)
7062
{
7063
this.ClearDeathRow();
7064
savingJson = this.saveToJSONString();
7065
if (IsIndexedDBAvailable() && !this.isCocoonJs)
7066
{
7067
IndexedDB_WriteSlot(savingToSlot, savingJson, function ()
7068
{
7069
cr.logexport("Saved state to IndexedDB storage (" + savingJson.length + " bytes)");
7070
self.lastSaveJson = savingJson;
7071
self.trigger(cr.system_object.prototype.cnds.OnSaveComplete, null);
7072
self.lastSaveJson = "";
7073
savingJson = "";
7074
if (continuous)
7075
doContinuousPreviewReload();
7076
}, function (e)
7077
{
7078
try {
7079
localStorage.setItem("__c2save_" + savingToSlot, savingJson);
7080
cr.logexport("Saved state to WebStorage (" + savingJson.length + " bytes)");
7081
self.lastSaveJson = savingJson;
7082
self.trigger(cr.system_object.prototype.cnds.OnSaveComplete, null);
7083
self.lastSaveJson = "";
7084
savingJson = "";
7085
if (continuous)
7086
doContinuousPreviewReload();
7087
}
7088
catch (f)
7089
{
7090
cr.logexport("Failed to save game state: " + e + "; " + f);
7091
self.trigger(cr.system_object.prototype.cnds.OnSaveFailed, null);
7092
}
7093
});
7094
}
7095
else
7096
{
7097
try {
7098
localStorage.setItem("__c2save_" + savingToSlot, savingJson);
7099
cr.logexport("Saved state to WebStorage (" + savingJson.length + " bytes)");
7100
self.lastSaveJson = savingJson;
7101
this.trigger(cr.system_object.prototype.cnds.OnSaveComplete, null);
7102
self.lastSaveJson = "";
7103
savingJson = "";
7104
if (continuous)
7105
doContinuousPreviewReload();
7106
}
7107
catch (e)
7108
{
7109
cr.logexport("Error saving to WebStorage: " + e);
7110
self.trigger(cr.system_object.prototype.cnds.OnSaveFailed, null);
7111
}
7112
}
7113
this.saveToSlot = "";
7114
this.loadFromSlot = "";
7115
this.loadFromJson = null;
7116
}
7117
if (loadingFromSlot.length)
7118
{
7119
if (IsIndexedDBAvailable() && !this.isCocoonJs)
7120
{
7121
IndexedDB_ReadSlot(loadingFromSlot, function (result_)
7122
{
7123
if (result_)
7124
{
7125
self.loadFromJson = result_;
7126
cr.logexport("Loaded state from IndexedDB storage (" + self.loadFromJson.length + " bytes)");
7127
}
7128
else
7129
{
7130
self.loadFromJson = localStorage.getItem("__c2save_" + loadingFromSlot) || "";
7131
cr.logexport("Loaded state from WebStorage (" + self.loadFromJson.length + " bytes)");
7132
}
7133
self.suspendDrawing = false;
7134
if (!self.loadFromJson)
7135
{
7136
self.loadFromJson = null;
7137
self.trigger(cr.system_object.prototype.cnds.OnLoadFailed, null);
7138
}
7139
}, function (e)
7140
{
7141
self.loadFromJson = localStorage.getItem("__c2save_" + loadingFromSlot) || "";
7142
cr.logexport("Loaded state from WebStorage (" + self.loadFromJson.length + " bytes)");
7143
self.suspendDrawing = false;
7144
if (!self.loadFromJson)
7145
{
7146
self.loadFromJson = null;
7147
self.trigger(cr.system_object.prototype.cnds.OnLoadFailed, null);
7148
}
7149
});
7150
}
7151
else
7152
{
7153
try {
7154
this.loadFromJson = localStorage.getItem("__c2save_" + loadingFromSlot) || "";
7155
cr.logexport("Loaded state from WebStorage (" + this.loadFromJson.length + " bytes)");
7156
}
7157
catch (e)
7158
{
7159
this.loadFromJson = null;
7160
}
7161
this.suspendDrawing = false;
7162
if (!self.loadFromJson)
7163
{
7164
self.loadFromJson = null;
7165
self.trigger(cr.system_object.prototype.cnds.OnLoadFailed, null);
7166
}
7167
}
7168
this.loadFromSlot = "";
7169
this.saveToSlot = "";
7170
}
7171
if (this.loadFromJson !== null)
7172
{
7173
this.ClearDeathRow();
7174
var ok = this.loadFromJSONString(this.loadFromJson);
7175
if (ok)
7176
{
7177
this.lastSaveJson = this.loadFromJson;
7178
this.trigger(cr.system_object.prototype.cnds.OnLoadComplete, null);
7179
this.lastSaveJson = "";
7180
}
7181
else
7182
{
7183
self.trigger(cr.system_object.prototype.cnds.OnLoadFailed, null);
7184
}
7185
this.loadFromJson = null;
7186
}
7187
};
7188
function CopyExtraObject(extra)
7189
{
7190
var p, ret = {};
7191
for (p in extra)
7192
{
7193
if (extra.hasOwnProperty(p))
7194
{
7195
if (extra[p] instanceof cr.ObjectSet)
7196
continue;
7197
if (extra[p] && typeof extra[p].c2userdata !== "undefined")
7198
continue;
7199
if (p === "spriteCreatedDestroyCallback")
7200
continue;
7201
ret[p] = extra[p];
7202
}
7203
}
7204
return ret;
7205
};
7206
Runtime.prototype.saveToJSONString = function()
7207
{
7208
var i, len, j, lenj, type, layout, typeobj, g, c, a, v, p;
7209
var o = {
7210
"c2save": true,
7211
"version": 1,
7212
"rt": {
7213
"time": this.kahanTime.sum,
7214
"walltime": this.wallTime.sum,
7215
"timescale": this.timescale,
7216
"tickcount": this.tickcount,
7217
"execcount": this.execcount,
7218
"next_uid": this.next_uid,
7219
"running_layout": this.running_layout.sid,
7220
"start_time_offset": (Date.now() - this.start_time)
7221
},
7222
"types": {},
7223
"layouts": {},
7224
"events": {
7225
"groups": {},
7226
"cnds": {},
7227
"acts": {},
7228
"vars": {}
7229
}
7230
};
7231
for (i = 0, len = this.types_by_index.length; i < len; i++)
7232
{
7233
type = this.types_by_index[i];
7234
if (type.is_family || this.typeHasNoSaveBehavior(type))
7235
continue;
7236
typeobj = {
7237
"instances": []
7238
};
7239
if (cr.hasAnyOwnProperty(type.extra))
7240
typeobj["ex"] = CopyExtraObject(type.extra);
7241
for (j = 0, lenj = type.instances.length; j < lenj; j++)
7242
{
7243
typeobj["instances"].push(this.saveInstanceToJSON(type.instances[j]));
7244
}
7245
o["types"][type.sid.toString()] = typeobj;
7246
}
7247
for (i = 0, len = this.layouts_by_index.length; i < len; i++)
7248
{
7249
layout = this.layouts_by_index[i];
7250
o["layouts"][layout.sid.toString()] = layout.saveToJSON();
7251
}
7252
var ogroups = o["events"]["groups"];
7253
for (i = 0, len = this.allGroups.length; i < len; i++)
7254
{
7255
g = this.allGroups[i];
7256
ogroups[g.sid.toString()] = this.groups_by_name[g.group_name].group_active;
7257
}
7258
var ocnds = o["events"]["cnds"];
7259
for (p in this.cndsBySid)
7260
{
7261
if (this.cndsBySid.hasOwnProperty(p))
7262
{
7263
c = this.cndsBySid[p];
7264
if (cr.hasAnyOwnProperty(c.extra))
7265
ocnds[p] = { "ex": CopyExtraObject(c.extra) };
7266
}
7267
}
7268
var oacts = o["events"]["acts"];
7269
for (p in this.actsBySid)
7270
{
7271
if (this.actsBySid.hasOwnProperty(p))
7272
{
7273
a = this.actsBySid[p];
7274
if (cr.hasAnyOwnProperty(a.extra))
7275
oacts[p] = { "ex": CopyExtraObject(a.extra) };
7276
}
7277
}
7278
var ovars = o["events"]["vars"];
7279
for (p in this.varsBySid)
7280
{
7281
if (this.varsBySid.hasOwnProperty(p))
7282
{
7283
v = this.varsBySid[p];
7284
if (!v.is_constant && (!v.parent || v.is_static))
7285
ovars[p] = v.data;
7286
}
7287
}
7288
o["system"] = this.system.saveToJSON();
7289
return JSON.stringify(o);
7290
};
7291
Runtime.prototype.refreshUidMap = function ()
7292
{
7293
var i, len, type, j, lenj, inst;
7294
this.objectsByUid = {};
7295
for (i = 0, len = this.types_by_index.length; i < len; i++)
7296
{
7297
type = this.types_by_index[i];
7298
if (type.is_family)
7299
continue;
7300
for (j = 0, lenj = type.instances.length; j < lenj; j++)
7301
{
7302
inst = type.instances[j];
7303
this.objectsByUid[inst.uid.toString()] = inst;
7304
}
7305
}
7306
};
7307
Runtime.prototype.loadFromJSONString = function (str)
7308
{
7309
var o;
7310
try {
7311
o = JSON.parse(str);
7312
}
7313
catch (e) {
7314
return false;
7315
}
7316
if (!o["c2save"])
7317
return false; // probably not a c2 save state
7318
if (o["version"] > 1)
7319
return false; // from future version of c2; assume not compatible
7320
this.isLoadingState = true;
7321
var rt = o["rt"];
7322
this.kahanTime.reset();
7323
this.kahanTime.sum = rt["time"];
7324
this.wallTime.reset();
7325
this.wallTime.sum = rt["walltime"] || 0;
7326
this.timescale = rt["timescale"];
7327
this.tickcount = rt["tickcount"];
7328
this.execcount = rt["execcount"];
7329
this.start_time = Date.now() - rt["start_time_offset"];
7330
var layout_sid = rt["running_layout"];
7331
if (layout_sid !== this.running_layout.sid)
7332
{
7333
var changeToLayout = this.getLayoutBySid(layout_sid);
7334
if (changeToLayout)
7335
this.doChangeLayout(changeToLayout);
7336
else
7337
return; // layout that was saved on has gone missing (deleted?)
7338
}
7339
var i, len, j, lenj, k, lenk, p, type, existing_insts, load_insts, inst, binst, layout, layer, g, iid, t;
7340
var otypes = o["types"];
7341
for (p in otypes)
7342
{
7343
if (otypes.hasOwnProperty(p))
7344
{
7345
type = this.getObjectTypeBySid(parseInt(p, 10));
7346
if (!type || type.is_family || this.typeHasNoSaveBehavior(type))
7347
continue;
7348
if (otypes[p]["ex"])
7349
type.extra = otypes[p]["ex"];
7350
else
7351
cr.wipe(type.extra);
7352
existing_insts = type.instances;
7353
load_insts = otypes[p]["instances"];
7354
for (i = 0, len = cr.min(existing_insts.length, load_insts.length); i < len; i++)
7355
{
7356
this.loadInstanceFromJSON(existing_insts[i], load_insts[i]);
7357
}
7358
for (i = load_insts.length, len = existing_insts.length; i < len; i++)
7359
this.DestroyInstance(existing_insts[i]);
7360
for (i = existing_insts.length, len = load_insts.length; i < len; i++)
7361
{
7362
layer = null;
7363
if (type.plugin.is_world)
7364
{
7365
layer = this.running_layout.getLayerBySid(load_insts[i]["w"]["l"]);
7366
if (!layer)
7367
continue;
7368
}
7369
inst = this.createInstanceFromInit(type.default_instance, layer, false, 0, 0, true);
7370
this.loadInstanceFromJSON(inst, load_insts[i]);
7371
}
7372
type.stale_iids = true;
7373
}
7374
}
7375
this.ClearDeathRow();
7376
this.refreshUidMap();
7377
var olayouts = o["layouts"];
7378
for (p in olayouts)
7379
{
7380
if (olayouts.hasOwnProperty(p))
7381
{
7382
layout = this.getLayoutBySid(parseInt(p, 10));
7383
if (!layout)
7384
continue; // must've gone missing
7385
layout.loadFromJSON(olayouts[p]);
7386
}
7387
}
7388
var ogroups = o["events"]["groups"];
7389
for (p in ogroups)
7390
{
7391
if (ogroups.hasOwnProperty(p))
7392
{
7393
g = this.getGroupBySid(parseInt(p, 10));
7394
if (g && this.groups_by_name[g.group_name])
7395
this.groups_by_name[g.group_name].setGroupActive(ogroups[p]);
7396
}
7397
}
7398
var ocnds = o["events"]["cnds"];
7399
for (p in this.cndsBySid)
7400
{
7401
if (this.cndsBySid.hasOwnProperty(p))
7402
{
7403
if (ocnds.hasOwnProperty(p))
7404
{
7405
this.cndsBySid[p].extra = ocnds[p]["ex"];
7406
}
7407
else
7408
{
7409
this.cndsBySid[p].extra = {};
7410
}
7411
}
7412
}
7413
var oacts = o["events"]["acts"];
7414
for (p in this.actsBySid)
7415
{
7416
if (this.actsBySid.hasOwnProperty(p))
7417
{
7418
if (oacts.hasOwnProperty(p))
7419
{
7420
this.actsBySid[p].extra = oacts[p]["ex"];
7421
}
7422
else
7423
{
7424
this.actsBySid[p].extra = {};
7425
}
7426
}
7427
}
7428
var ovars = o["events"]["vars"];
7429
for (p in ovars)
7430
{
7431
if (ovars.hasOwnProperty(p) && this.varsBySid.hasOwnProperty(p))
7432
{
7433
this.varsBySid[p].data = ovars[p];
7434
}
7435
}
7436
this.next_uid = rt["next_uid"];
7437
this.isLoadingState = false;
7438
for (i = 0, len = this.fireOnCreateAfterLoad.length; i < len; ++i)
7439
{
7440
inst = this.fireOnCreateAfterLoad[i];
7441
this.trigger(Object.getPrototypeOf(inst.type.plugin).cnds.OnCreated, inst);
7442
}
7443
cr.clearArray(this.fireOnCreateAfterLoad);
7444
this.system.loadFromJSON(o["system"]);
7445
for (i = 0, len = this.types_by_index.length; i < len; i++)
7446
{
7447
type = this.types_by_index[i];
7448
if (type.is_family || this.typeHasNoSaveBehavior(type))
7449
continue;
7450
for (j = 0, lenj = type.instances.length; j < lenj; j++)
7451
{
7452
inst = type.instances[j];
7453
if (type.is_contained)
7454
{
7455
iid = inst.get_iid();
7456
cr.clearArray(inst.siblings);
7457
for (k = 0, lenk = type.container.length; k < lenk; k++)
7458
{
7459
t = type.container[k];
7460
if (type === t)
7461
continue;
7462
;
7463
inst.siblings.push(t.instances[iid]);
7464
}
7465
}
7466
if (inst.afterLoad)
7467
inst.afterLoad();
7468
if (inst.behavior_insts)
7469
{
7470
for (k = 0, lenk = inst.behavior_insts.length; k < lenk; k++)
7471
{
7472
binst = inst.behavior_insts[k];
7473
if (binst.afterLoad)
7474
binst.afterLoad();
7475
}
7476
}
7477
}
7478
}
7479
this.redraw = true;
7480
return true;
7481
};
7482
Runtime.prototype.saveInstanceToJSON = function(inst, state_only)
7483
{
7484
var i, len, world, behinst, et;
7485
var type = inst.type;
7486
var plugin = type.plugin;
7487
var o = {};
7488
if (state_only)
7489
o["c2"] = true; // mark as known json data from Construct 2
7490
else
7491
o["uid"] = inst.uid;
7492
if (cr.hasAnyOwnProperty(inst.extra))
7493
o["ex"] = CopyExtraObject(inst.extra);
7494
if (inst.instance_vars && inst.instance_vars.length)
7495
{
7496
o["ivs"] = {};
7497
for (i = 0, len = inst.instance_vars.length; i < len; i++)
7498
{
7499
o["ivs"][inst.type.instvar_sids[i].toString()] = inst.instance_vars[i];
7500
}
7501
}
7502
if (plugin.is_world)
7503
{
7504
world = {
7505
"x": inst.x,
7506
"y": inst.y,
7507
"w": inst.width,
7508
"h": inst.height,
7509
"l": inst.layer.sid,
7510
"zi": inst.get_zindex()
7511
};
7512
if (inst.angle !== 0)
7513
world["a"] = inst.angle;
7514
if (inst.opacity !== 1)
7515
world["o"] = inst.opacity;
7516
if (inst.hotspotX !== 0.5)
7517
world["hX"] = inst.hotspotX;
7518
if (inst.hotspotY !== 0.5)
7519
world["hY"] = inst.hotspotY;
7520
if (inst.blend_mode !== 0)
7521
world["bm"] = inst.blend_mode;
7522
if (!inst.visible)
7523
world["v"] = inst.visible;
7524
if (!inst.collisionsEnabled)
7525
world["ce"] = inst.collisionsEnabled;
7526
if (inst.my_timescale !== -1)
7527
world["mts"] = inst.my_timescale;
7528
if (type.effect_types.length)
7529
{
7530
world["fx"] = [];
7531
for (i = 0, len = type.effect_types.length; i < len; i++)
7532
{
7533
et = type.effect_types[i];
7534
world["fx"].push({"name": et.name,
7535
"active": inst.active_effect_flags[et.index],
7536
"params": inst.effect_params[et.index] });
7537
}
7538
}
7539
o["w"] = world;
7540
}
7541
if (inst.behavior_insts && inst.behavior_insts.length)
7542
{
7543
o["behs"] = {};
7544
for (i = 0, len = inst.behavior_insts.length; i < len; i++)
7545
{
7546
behinst = inst.behavior_insts[i];
7547
if (behinst.saveToJSON)
7548
o["behs"][behinst.type.sid.toString()] = behinst.saveToJSON();
7549
}
7550
}
7551
if (inst.saveToJSON)
7552
o["data"] = inst.saveToJSON();
7553
return o;
7554
};
7555
Runtime.prototype.getInstanceVarIndexBySid = function (type, sid_)
7556
{
7557
var i, len;
7558
for (i = 0, len = type.instvar_sids.length; i < len; i++)
7559
{
7560
if (type.instvar_sids[i] === sid_)
7561
return i;
7562
}
7563
return -1;
7564
};
7565
Runtime.prototype.getBehaviorIndexBySid = function (inst, sid_)
7566
{
7567
var i, len;
7568
for (i = 0, len = inst.behavior_insts.length; i < len; i++)
7569
{
7570
if (inst.behavior_insts[i].type.sid === sid_)
7571
return i;
7572
}
7573
return -1;
7574
};
7575
Runtime.prototype.loadInstanceFromJSON = function(inst, o, state_only)
7576
{
7577
var p, i, len, iv, oivs, world, fxindex, obehs, behindex, value;
7578
var oldlayer;
7579
var type = inst.type;
7580
var plugin = type.plugin;
7581
if (state_only)
7582
{
7583
if (!o["c2"])
7584
return;
7585
}
7586
else
7587
inst.uid = o["uid"];
7588
if (o["ex"])
7589
inst.extra = o["ex"];
7590
else
7591
cr.wipe(inst.extra);
7592
oivs = o["ivs"];
7593
if (oivs)
7594
{
7595
for (p in oivs)
7596
{
7597
if (oivs.hasOwnProperty(p))
7598
{
7599
iv = this.getInstanceVarIndexBySid(type, parseInt(p, 10));
7600
if (iv < 0 || iv >= inst.instance_vars.length)
7601
continue; // must've gone missing
7602
value = oivs[p];
7603
if (value === null)
7604
value = NaN;
7605
inst.instance_vars[iv] = value;
7606
}
7607
}
7608
}
7609
if (plugin.is_world)
7610
{
7611
world = o["w"];
7612
if (inst.layer.sid !== world["l"])
7613
{
7614
oldlayer = inst.layer;
7615
inst.layer = this.running_layout.getLayerBySid(world["l"]);
7616
if (inst.layer)
7617
{
7618
oldlayer.removeFromInstanceList(inst, true);
7619
inst.layer.appendToInstanceList(inst, true);
7620
inst.set_bbox_changed();
7621
inst.layer.setZIndicesStaleFrom(0);
7622
}
7623
else
7624
{
7625
inst.layer = oldlayer;
7626
if (!state_only)
7627
this.DestroyInstance(inst);
7628
}
7629
}
7630
inst.x = world["x"];
7631
inst.y = world["y"];
7632
inst.width = world["w"];
7633
inst.height = world["h"];
7634
inst.zindex = world["zi"];
7635
inst.angle = world.hasOwnProperty("a") ? world["a"] : 0;
7636
inst.opacity = world.hasOwnProperty("o") ? world["o"] : 1;
7637
inst.hotspotX = world.hasOwnProperty("hX") ? world["hX"] : 0.5;
7638
inst.hotspotY = world.hasOwnProperty("hY") ? world["hY"] : 0.5;
7639
inst.visible = world.hasOwnProperty("v") ? world["v"] : true;
7640
inst.collisionsEnabled = world.hasOwnProperty("ce") ? world["ce"] : true;
7641
inst.my_timescale = world.hasOwnProperty("mts") ? world["mts"] : -1;
7642
inst.blend_mode = world.hasOwnProperty("bm") ? world["bm"] : 0;;
7643
inst.compositeOp = cr.effectToCompositeOp(inst.blend_mode);
7644
if (this.gl)
7645
cr.setGLBlend(inst, inst.blend_mode, this.gl);
7646
inst.set_bbox_changed();
7647
if (world.hasOwnProperty("fx"))
7648
{
7649
for (i = 0, len = world["fx"].length; i < len; i++)
7650
{
7651
fxindex = type.getEffectIndexByName(world["fx"][i]["name"]);
7652
if (fxindex < 0)
7653
continue; // must've gone missing
7654
inst.active_effect_flags[fxindex] = world["fx"][i]["active"];
7655
inst.effect_params[fxindex] = world["fx"][i]["params"];
7656
}
7657
}
7658
inst.updateActiveEffects();
7659
}
7660
obehs = o["behs"];
7661
if (obehs)
7662
{
7663
for (p in obehs)
7664
{
7665
if (obehs.hasOwnProperty(p))
7666
{
7667
behindex = this.getBehaviorIndexBySid(inst, parseInt(p, 10));
7668
if (behindex < 0)
7669
continue; // must've gone missing
7670
inst.behavior_insts[behindex].loadFromJSON(obehs[p]);
7671
}
7672
}
7673
}
7674
if (o["data"])
7675
inst.loadFromJSON(o["data"]);
7676
};
7677
Runtime.prototype.fetchLocalFileViaCordova = function (filename, successCallback, errorCallback)
7678
{
7679
var path = cordova["file"]["applicationDirectory"] + "www/" + filename;
7680
window["resolveLocalFileSystemURL"](path, function (entry)
7681
{
7682
entry.file(successCallback, errorCallback);
7683
}, errorCallback);
7684
};
7685
Runtime.prototype.fetchLocalFileViaCordovaAsText = function (filename, successCallback, errorCallback)
7686
{
7687
this.fetchLocalFileViaCordova(filename, function (file)
7688
{
7689
var reader = new FileReader();
7690
reader.onload = function (e)
7691
{
7692
successCallback(e.target.result);
7693
};
7694
reader.onerror = errorCallback;
7695
reader.readAsText(file);
7696
}, errorCallback);
7697
};
7698
var queuedArrayBufferReads = [];
7699
var activeArrayBufferReads = 0;
7700
var MAX_ARRAYBUFFER_READS = 8;
7701
Runtime.prototype.maybeStartNextArrayBufferRead = function()
7702
{
7703
if (!queuedArrayBufferReads.length)
7704
return; // none left
7705
if (activeArrayBufferReads >= MAX_ARRAYBUFFER_READS)
7706
return; // already got maximum number in-flight
7707
activeArrayBufferReads++;
7708
var job = queuedArrayBufferReads.shift();
7709
this.doFetchLocalFileViaCordovaAsArrayBuffer(job.filename, job.successCallback, job.errorCallback);
7710
};
7711
Runtime.prototype.fetchLocalFileViaCordovaAsArrayBuffer = function (filename, successCallback_, errorCallback_)
7712
{
7713
var self = this;
7714
queuedArrayBufferReads.push({
7715
filename: filename,
7716
successCallback: function (result)
7717
{
7718
activeArrayBufferReads--;
7719
self.maybeStartNextArrayBufferRead();
7720
successCallback_(result);
7721
},
7722
errorCallback: function (err)
7723
{
7724
activeArrayBufferReads--;
7725
self.maybeStartNextArrayBufferRead();
7726
errorCallback_(err);
7727
}
7728
});
7729
this.maybeStartNextArrayBufferRead();
7730
};
7731
Runtime.prototype.doFetchLocalFileViaCordovaAsArrayBuffer = function (filename, successCallback, errorCallback)
7732
{
7733
this.fetchLocalFileViaCordova(filename, function (file)
7734
{
7735
var reader = new FileReader();
7736
reader.onload = function (e)
7737
{
7738
successCallback(e.target.result);
7739
};
7740
reader.readAsArrayBuffer(file);
7741
}, errorCallback);
7742
};
7743
Runtime.prototype.fetchLocalFileViaCordovaAsURL = function (filename, successCallback, errorCallback)
7744
{
7745
var blobType = "";
7746
var lowername = filename.toLowerCase();
7747
var ext3 = lowername.substr(lowername.length - 4);
7748
var ext4 = lowername.substr(lowername.length - 5);
7749
if (ext3 === ".mp4")
7750
blobType = "video/mp4";
7751
else if (ext4 === ".webm")
7752
blobType = "video/webm"; // use video type but hopefully works with audio too
7753
else if (ext3 === ".m4a")
7754
blobType = "audio/mp4";
7755
else if (ext3 === ".mp3")
7756
blobType = "audio/mpeg";
7757
this.fetchLocalFileViaCordovaAsArrayBuffer(filename, function (arrayBuffer)
7758
{
7759
var blob = new Blob([arrayBuffer], { type: blobType });
7760
var url = URL.createObjectURL(blob);
7761
successCallback(url);
7762
}, errorCallback);
7763
};
7764
Runtime.prototype.isAbsoluteUrl = function (url)
7765
{
7766
return /^(?:[a-z]+:)?\/\//.test(url) || url.substr(0, 5) === "data:" || url.substr(0, 5) === "blob:";
7767
};
7768
Runtime.prototype.setImageSrc = function (img, src)
7769
{
7770
if (this.isWKWebView && !this.isAbsoluteUrl(src))
7771
{
7772
this.fetchLocalFileViaCordovaAsURL(src, function (url)
7773
{
7774
img.src = url;
7775
}, function (err)
7776
{
7777
alert("Failed to load image: " + err);
7778
});
7779
}
7780
else
7781
{
7782
img.src = src;
7783
}
7784
};
7785
Runtime.prototype.setCtxImageSmoothingEnabled = function (ctx, e)
7786
{
7787
if (typeof ctx["imageSmoothingEnabled"] !== "undefined")
7788
{
7789
ctx["imageSmoothingEnabled"] = e;
7790
}
7791
else
7792
{
7793
ctx["webkitImageSmoothingEnabled"] = e;
7794
ctx["mozImageSmoothingEnabled"] = e;
7795
ctx["msImageSmoothingEnabled"] = e;
7796
}
7797
};
7798
cr.runtime = Runtime;
7799
cr.createRuntime = function (canvasid)
7800
{
7801
return new Runtime(document.getElementById(canvasid));
7802
};
7803
cr.createDCRuntime = function (w, h)
7804
{
7805
return new Runtime({ "dc": true, "width": w, "height": h });
7806
};
7807
window["cr_createRuntime"] = cr.createRuntime;
7808
window["cr_createDCRuntime"] = cr.createDCRuntime;
7809
window["createCocoonJSRuntime"] = function ()
7810
{
7811
window["c2cocoonjs"] = true;
7812
var canvas = document.createElement("screencanvas") || document.createElement("canvas");
7813
canvas.screencanvas = true;
7814
document.body.appendChild(canvas);
7815
var rt = new Runtime(canvas);
7816
window["c2runtime"] = rt;
7817
window.addEventListener("orientationchange", function () {
7818
window["c2runtime"]["setSize"](window.innerWidth, window.innerHeight);
7819
});
7820
window["c2runtime"]["setSize"](window.innerWidth, window.innerHeight);
7821
return rt;
7822
};
7823
window["createEjectaRuntime"] = function ()
7824
{
7825
var canvas = document.getElementById("canvas");
7826
var rt = new Runtime(canvas);
7827
window["c2runtime"] = rt;
7828
window["c2runtime"]["setSize"](window.innerWidth, window.innerHeight);
7829
return rt;
7830
};
7831
}());
7832
window["cr_getC2Runtime"] = function()
7833
{
7834
var canvas = document.getElementById("c2canvas");
7835
if (canvas)
7836
return canvas["c2runtime"];
7837
else if (window["c2runtime"])
7838
return window["c2runtime"];
7839
else
7840
return null;
7841
}
7842
window["cr_getSnapshot"] = function (format_, quality_)
7843
{
7844
var runtime = window["cr_getC2Runtime"]();
7845
if (runtime)
7846
runtime.doCanvasSnapshot(format_, quality_);
7847
}
7848
window["cr_sizeCanvas"] = function(w, h)
7849
{
7850
if (w === 0 || h === 0)
7851
return;
7852
var runtime = window["cr_getC2Runtime"]();
7853
if (runtime)
7854
runtime["setSize"](w, h);
7855
}
7856
window["cr_setSuspended"] = function(s)
7857
{
7858
var runtime = window["cr_getC2Runtime"]();
7859
if (runtime)
7860
runtime["setSuspended"](s);
7861
}
7862
;
7863
(function()
7864
{
7865
function Layout(runtime, m)
7866
{
7867
this.runtime = runtime;
7868
this.event_sheet = null;
7869
this.scrollX = (this.runtime.original_width / 2);
7870
this.scrollY = (this.runtime.original_height / 2);
7871
this.scale = 1.0;
7872
this.angle = 0;
7873
this.first_visit = true;
7874
this.name = m[0];
7875
this.originalWidth = m[1];
7876
this.originalHeight = m[2];
7877
this.width = m[1];
7878
this.height = m[2];
7879
this.unbounded_scrolling = m[3];
7880
this.sheetname = m[4];
7881
this.sid = m[5];
7882
var lm = m[6];
7883
var i, len;
7884
this.layers = [];
7885
this.initial_types = [];
7886
for (i = 0, len = lm.length; i < len; i++)
7887
{
7888
var layer = new cr.layer(this, lm[i]);
7889
layer.number = i;
7890
cr.seal(layer);
7891
this.layers.push(layer);
7892
}
7893
var im = m[7];
7894
this.initial_nonworld = [];
7895
for (i = 0, len = im.length; i < len; i++)
7896
{
7897
var inst = im[i];
7898
var type = this.runtime.types_by_index[inst[1]];
7899
;
7900
if (!type.default_instance)
7901
type.default_instance = inst;
7902
this.initial_nonworld.push(inst);
7903
if (this.initial_types.indexOf(type) === -1)
7904
this.initial_types.push(type);
7905
}
7906
this.effect_types = [];
7907
this.active_effect_types = [];
7908
this.shaders_preserve_opaqueness = true;
7909
this.effect_params = [];
7910
for (i = 0, len = m[8].length; i < len; i++)
7911
{
7912
this.effect_types.push({
7913
id: m[8][i][0],
7914
name: m[8][i][1],
7915
shaderindex: -1,
7916
preservesOpaqueness: false,
7917
active: true,
7918
index: i
7919
});
7920
this.effect_params.push(m[8][i][2].slice(0));
7921
}
7922
this.updateActiveEffects();
7923
this.rcTex = new cr.rect(0, 0, 1, 1);
7924
this.rcTex2 = new cr.rect(0, 0, 1, 1);
7925
this.persist_data = {};
7926
};
7927
Layout.prototype.saveObjectToPersist = function (inst)
7928
{
7929
var sidStr = inst.type.sid.toString();
7930
if (!this.persist_data.hasOwnProperty(sidStr))
7931
this.persist_data[sidStr] = [];
7932
var type_persist = this.persist_data[sidStr];
7933
type_persist.push(this.runtime.saveInstanceToJSON(inst));
7934
};
7935
Layout.prototype.hasOpaqueBottomLayer = function ()
7936
{
7937
var layer = this.layers[0];
7938
return !layer.transparent && layer.opacity === 1.0 && !layer.forceOwnTexture && layer.visible;
7939
};
7940
Layout.prototype.updateActiveEffects = function ()
7941
{
7942
cr.clearArray(this.active_effect_types);
7943
this.shaders_preserve_opaqueness = true;
7944
var i, len, et;
7945
for (i = 0, len = this.effect_types.length; i < len; i++)
7946
{
7947
et = this.effect_types[i];
7948
if (et.active)
7949
{
7950
this.active_effect_types.push(et);
7951
if (!et.preservesOpaqueness)
7952
this.shaders_preserve_opaqueness = false;
7953
}
7954
}
7955
};
7956
Layout.prototype.getEffectByName = function (name_)
7957
{
7958
var i, len, et;
7959
for (i = 0, len = this.effect_types.length; i < len; i++)
7960
{
7961
et = this.effect_types[i];
7962
if (et.name === name_)
7963
return et;
7964
}
7965
return null;
7966
};
7967
var created_instances = [];
7968
function sort_by_zindex(a, b)
7969
{
7970
return a.zindex - b.zindex;
7971
};
7972
var first_layout = true;
7973
Layout.prototype.startRunning = function ()
7974
{
7975
if (this.sheetname)
7976
{
7977
this.event_sheet = this.runtime.eventsheets[this.sheetname];
7978
;
7979
this.event_sheet.updateDeepIncludes();
7980
}
7981
this.runtime.running_layout = this;
7982
this.width = this.originalWidth;
7983
this.height = this.originalHeight;
7984
this.scrollX = (this.runtime.original_width / 2);
7985
this.scrollY = (this.runtime.original_height / 2);
7986
var i, k, len, lenk, type, type_instances, initial_inst, inst, iid, t, s, p, q, type_data, layer;
7987
for (i = 0, len = this.runtime.types_by_index.length; i < len; i++)
7988
{
7989
type = this.runtime.types_by_index[i];
7990
if (type.is_family)
7991
continue; // instances are only transferred for their real type
7992
type_instances = type.instances;
7993
for (k = 0, lenk = type_instances.length; k < lenk; k++)
7994
{
7995
inst = type_instances[k];
7996
if (inst.layer)
7997
{
7998
var num = inst.layer.number;
7999
if (num >= this.layers.length)
8000
num = this.layers.length - 1;
8001
inst.layer = this.layers[num];
8002
if (inst.layer.instances.indexOf(inst) === -1)
8003
inst.layer.instances.push(inst);
8004
inst.layer.zindices_stale = true;
8005
}
8006
}
8007
}
8008
if (!first_layout)
8009
{
8010
for (i = 0, len = this.layers.length; i < len; ++i)
8011
{
8012
this.layers[i].instances.sort(sort_by_zindex);
8013
}
8014
}
8015
var layer;
8016
cr.clearArray(created_instances);
8017
this.boundScrolling();
8018
for (i = 0, len = this.layers.length; i < len; i++)
8019
{
8020
layer = this.layers[i];
8021
layer.createInitialInstances(); // fills created_instances
8022
layer.updateViewport(null);
8023
}
8024
var uids_changed = false;
8025
if (!this.first_visit)
8026
{
8027
for (p in this.persist_data)
8028
{
8029
if (this.persist_data.hasOwnProperty(p))
8030
{
8031
type = this.runtime.getObjectTypeBySid(parseInt(p, 10));
8032
if (!type || type.is_family || !this.runtime.typeHasPersistBehavior(type))
8033
continue;
8034
type_data = this.persist_data[p];
8035
for (i = 0, len = type_data.length; i < len; i++)
8036
{
8037
layer = null;
8038
if (type.plugin.is_world)
8039
{
8040
layer = this.getLayerBySid(type_data[i]["w"]["l"]);
8041
if (!layer)
8042
continue;
8043
}
8044
inst = this.runtime.createInstanceFromInit(type.default_instance, layer, false, 0, 0, true);
8045
this.runtime.loadInstanceFromJSON(inst, type_data[i]);
8046
uids_changed = true;
8047
created_instances.push(inst);
8048
}
8049
cr.clearArray(type_data);
8050
}
8051
}
8052
for (i = 0, len = this.layers.length; i < len; i++)
8053
{
8054
this.layers[i].instances.sort(sort_by_zindex);
8055
this.layers[i].zindices_stale = true; // in case of duplicates/holes
8056
}
8057
}
8058
if (uids_changed)
8059
{
8060
this.runtime.ClearDeathRow();
8061
this.runtime.refreshUidMap();
8062
}
8063
for (i = 0; i < created_instances.length; i++)
8064
{
8065
inst = created_instances[i];
8066
if (!inst.type.is_contained)
8067
continue;
8068
iid = inst.get_iid();
8069
for (k = 0, lenk = inst.type.container.length; k < lenk; k++)
8070
{
8071
t = inst.type.container[k];
8072
if (inst.type === t)
8073
continue;
8074
if (t.instances.length > iid)
8075
inst.siblings.push(t.instances[iid]);
8076
else
8077
{
8078
if (!t.default_instance)
8079
{
8080
}
8081
else
8082
{
8083
s = this.runtime.createInstanceFromInit(t.default_instance, inst.layer, true, inst.x, inst.y, true);
8084
this.runtime.ClearDeathRow();
8085
t.updateIIDs();
8086
inst.siblings.push(s);
8087
created_instances.push(s); // come back around and link up its own instances too
8088
}
8089
}
8090
}
8091
}
8092
for (i = 0, len = this.initial_nonworld.length; i < len; i++)
8093
{
8094
initial_inst = this.initial_nonworld[i];
8095
type = this.runtime.types_by_index[initial_inst[1]];
8096
if (!type.is_contained)
8097
{
8098
inst = this.runtime.createInstanceFromInit(this.initial_nonworld[i], null, true);
8099
}
8100
;
8101
}
8102
this.runtime.changelayout = null;
8103
this.runtime.ClearDeathRow();
8104
if (this.runtime.ctx && !this.runtime.isDomFree)
8105
{
8106
for (i = 0, len = this.runtime.types_by_index.length; i < len; i++)
8107
{
8108
t = this.runtime.types_by_index[i];
8109
if (t.is_family || !t.instances.length || !t.preloadCanvas2D)
8110
continue;
8111
t.preloadCanvas2D(this.runtime.ctx);
8112
}
8113
}
8114
/*
8115
if (this.runtime.glwrap)
8116
{
8117
console.log("Estimated VRAM at layout start: " + this.runtime.glwrap.textureCount() + " textures, approx. " + Math.round(this.runtime.glwrap.estimateVRAM() / 1024) + " kb");
8118
}
8119
*/
8120
if (this.runtime.isLoadingState)
8121
{
8122
cr.shallowAssignArray(this.runtime.fireOnCreateAfterLoad, created_instances);
8123
}
8124
else
8125
{
8126
for (i = 0, len = created_instances.length; i < len; i++)
8127
{
8128
inst = created_instances[i];
8129
this.runtime.trigger(Object.getPrototypeOf(inst.type.plugin).cnds.OnCreated, inst);
8130
}
8131
}
8132
cr.clearArray(created_instances);
8133
if (!this.runtime.isLoadingState)
8134
{
8135
this.runtime.trigger(cr.system_object.prototype.cnds.OnLayoutStart, null);
8136
}
8137
this.first_visit = false;
8138
};
8139
Layout.prototype.createGlobalNonWorlds = function ()
8140
{
8141
var i, k, len, initial_inst, inst, type;
8142
for (i = 0, k = 0, len = this.initial_nonworld.length; i < len; i++)
8143
{
8144
initial_inst = this.initial_nonworld[i];
8145
type = this.runtime.types_by_index[initial_inst[1]];
8146
if (type.global)
8147
{
8148
if (!type.is_contained)
8149
{
8150
inst = this.runtime.createInstanceFromInit(initial_inst, null, true);
8151
}
8152
}
8153
else
8154
{
8155
this.initial_nonworld[k] = initial_inst;
8156
k++;
8157
}
8158
}
8159
cr.truncateArray(this.initial_nonworld, k);
8160
};
8161
Layout.prototype.stopRunning = function ()
8162
{
8163
;
8164
/*
8165
if (this.runtime.glwrap)
8166
{
8167
console.log("Estimated VRAM at layout end: " + this.runtime.glwrap.textureCount() + " textures, approx. " + Math.round(this.runtime.glwrap.estimateVRAM() / 1024) + " kb");
8168
}
8169
*/
8170
if (!this.runtime.isLoadingState)
8171
{
8172
this.runtime.trigger(cr.system_object.prototype.cnds.OnLayoutEnd, null);
8173
}
8174
this.runtime.isEndingLayout = true;
8175
cr.clearArray(this.runtime.system.waits);
8176
var i, leni, j, lenj;
8177
var layer_instances, inst, type;
8178
if (!this.first_visit)
8179
{
8180
for (i = 0, leni = this.layers.length; i < leni; i++)
8181
{
8182
this.layers[i].updateZIndices();
8183
layer_instances = this.layers[i].instances;
8184
for (j = 0, lenj = layer_instances.length; j < lenj; j++)
8185
{
8186
inst = layer_instances[j];
8187
if (!inst.type.global)
8188
{
8189
if (this.runtime.typeHasPersistBehavior(inst.type))
8190
this.saveObjectToPersist(inst);
8191
}
8192
}
8193
}
8194
}
8195
for (i = 0, leni = this.layers.length; i < leni; i++)
8196
{
8197
layer_instances = this.layers[i].instances;
8198
for (j = 0, lenj = layer_instances.length; j < lenj; j++)
8199
{
8200
inst = layer_instances[j];
8201
if (!inst.type.global)
8202
{
8203
this.runtime.DestroyInstance(inst);
8204
}
8205
}
8206
this.runtime.ClearDeathRow();
8207
cr.clearArray(layer_instances);
8208
this.layers[i].zindices_stale = true;
8209
}
8210
for (i = 0, leni = this.runtime.types_by_index.length; i < leni; i++)
8211
{
8212
type = this.runtime.types_by_index[i];
8213
if (type.global || type.plugin.is_world || type.plugin.singleglobal || type.is_family)
8214
continue;
8215
for (j = 0, lenj = type.instances.length; j < lenj; j++)
8216
this.runtime.DestroyInstance(type.instances[j]);
8217
this.runtime.ClearDeathRow();
8218
}
8219
first_layout = false;
8220
this.runtime.isEndingLayout = false;
8221
};
8222
var temp_rect = new cr.rect(0, 0, 0, 0);
8223
Layout.prototype.recreateInitialObjects = function (type, x1, y1, x2, y2)
8224
{
8225
temp_rect.set(x1, y1, x2, y2);
8226
var i, len;
8227
for (i = 0, len = this.layers.length; i < len; i++)
8228
{
8229
this.layers[i].recreateInitialObjects(type, temp_rect);
8230
}
8231
};
8232
Layout.prototype.draw = function (ctx)
8233
{
8234
var layout_canvas;
8235
var layout_ctx = ctx;
8236
var ctx_changed = false;
8237
var render_offscreen = !this.runtime.fullscreenScalingQuality;
8238
if (render_offscreen)
8239
{
8240
if (!this.runtime.layout_canvas)
8241
{
8242
this.runtime.layout_canvas = document.createElement("canvas");
8243
layout_canvas = this.runtime.layout_canvas;
8244
layout_canvas.width = this.runtime.draw_width;
8245
layout_canvas.height = this.runtime.draw_height;
8246
this.runtime.layout_ctx = layout_canvas.getContext("2d");
8247
ctx_changed = true;
8248
}
8249
layout_canvas = this.runtime.layout_canvas;
8250
layout_ctx = this.runtime.layout_ctx;
8251
if (layout_canvas.width !== this.runtime.draw_width)
8252
{
8253
layout_canvas.width = this.runtime.draw_width;
8254
ctx_changed = true;
8255
}
8256
if (layout_canvas.height !== this.runtime.draw_height)
8257
{
8258
layout_canvas.height = this.runtime.draw_height;
8259
ctx_changed = true;
8260
}
8261
if (ctx_changed)
8262
{
8263
this.runtime.setCtxImageSmoothingEnabled(layout_ctx, this.runtime.linearSampling);
8264
}
8265
}
8266
layout_ctx.globalAlpha = 1;
8267
layout_ctx.globalCompositeOperation = "source-over";
8268
if (this.runtime.clearBackground && !this.hasOpaqueBottomLayer())
8269
layout_ctx.clearRect(0, 0, this.runtime.draw_width, this.runtime.draw_height);
8270
var i, len, l;
8271
for (i = 0, len = this.layers.length; i < len; i++)
8272
{
8273
l = this.layers[i];
8274
if (l.visible && l.opacity > 0 && l.blend_mode !== 11 && (l.instances.length || !l.transparent))
8275
l.draw(layout_ctx);
8276
else
8277
l.updateViewport(null); // even if not drawing, keep viewport up to date
8278
}
8279
if (render_offscreen)
8280
{
8281
ctx.drawImage(layout_canvas, 0, 0, this.runtime.width, this.runtime.height);
8282
}
8283
};
8284
Layout.prototype.drawGL_earlyZPass = function (glw)
8285
{
8286
glw.setEarlyZPass(true);
8287
if (!this.runtime.layout_tex)
8288
{
8289
this.runtime.layout_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.linearSampling);
8290
}
8291
if (this.runtime.layout_tex.c2width !== this.runtime.draw_width || this.runtime.layout_tex.c2height !== this.runtime.draw_height)
8292
{
8293
glw.deleteTexture(this.runtime.layout_tex);
8294
this.runtime.layout_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.linearSampling);
8295
}
8296
glw.setRenderingToTexture(this.runtime.layout_tex);
8297
if (!this.runtime.fullscreenScalingQuality)
8298
{
8299
glw.setSize(this.runtime.draw_width, this.runtime.draw_height);
8300
}
8301
var i, l;
8302
for (i = this.layers.length - 1; i >= 0; --i)
8303
{
8304
l = this.layers[i];
8305
if (l.visible && l.opacity === 1 && l.shaders_preserve_opaqueness &&
8306
l.blend_mode === 0 && (l.instances.length || !l.transparent))
8307
{
8308
l.drawGL_earlyZPass(glw);
8309
}
8310
else
8311
{
8312
l.updateViewport(null); // even if not drawing, keep viewport up to date
8313
}
8314
}
8315
glw.setEarlyZPass(false);
8316
};
8317
Layout.prototype.drawGL = function (glw)
8318
{
8319
var render_to_texture = (this.active_effect_types.length > 0 ||
8320
this.runtime.uses_background_blending ||
8321
!this.runtime.fullscreenScalingQuality ||
8322
this.runtime.enableFrontToBack);
8323
if (render_to_texture)
8324
{
8325
if (!this.runtime.layout_tex)
8326
{
8327
this.runtime.layout_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.linearSampling);
8328
}
8329
if (this.runtime.layout_tex.c2width !== this.runtime.draw_width || this.runtime.layout_tex.c2height !== this.runtime.draw_height)
8330
{
8331
glw.deleteTexture(this.runtime.layout_tex);
8332
this.runtime.layout_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.linearSampling);
8333
}
8334
glw.setRenderingToTexture(this.runtime.layout_tex);
8335
if (!this.runtime.fullscreenScalingQuality)
8336
{
8337
glw.setSize(this.runtime.draw_width, this.runtime.draw_height);
8338
}
8339
}
8340
else
8341
{
8342
if (this.runtime.layout_tex)
8343
{
8344
glw.setRenderingToTexture(null);
8345
glw.deleteTexture(this.runtime.layout_tex);
8346
this.runtime.layout_tex = null;
8347
}
8348
}
8349
if (this.runtime.clearBackground && !this.hasOpaqueBottomLayer())
8350
glw.clear(0, 0, 0, 0);
8351
var i, len, l;
8352
for (i = 0, len = this.layers.length; i < len; i++)
8353
{
8354
l = this.layers[i];
8355
if (l.visible && l.opacity > 0 && (l.instances.length || !l.transparent))
8356
l.drawGL(glw);
8357
else
8358
l.updateViewport(null); // even if not drawing, keep viewport up to date
8359
}
8360
if (render_to_texture)
8361
{
8362
if (this.active_effect_types.length === 0 ||
8363
(this.active_effect_types.length === 1 && this.runtime.fullscreenScalingQuality))
8364
{
8365
if (this.active_effect_types.length === 1)
8366
{
8367
var etindex = this.active_effect_types[0].index;
8368
glw.switchProgram(this.active_effect_types[0].shaderindex);
8369
glw.setProgramParameters(null, // backTex
8370
1.0 / this.runtime.draw_width, // pixelWidth
8371
1.0 / this.runtime.draw_height, // pixelHeight
8372
0.0, 0.0, // destStart
8373
1.0, 1.0, // destEnd
8374
this.scale, // layerScale
8375
this.angle, // layerAngle
8376
0.0, 0.0, // viewOrigin
8377
this.runtime.draw_width / 2, this.runtime.draw_height / 2, // scrollPos
8378
this.runtime.kahanTime.sum, // seconds
8379
this.effect_params[etindex]); // fx parameters
8380
if (glw.programIsAnimated(this.active_effect_types[0].shaderindex))
8381
this.runtime.redraw = true;
8382
}
8383
else
8384
glw.switchProgram(0);
8385
if (!this.runtime.fullscreenScalingQuality)
8386
{
8387
glw.setSize(this.runtime.width, this.runtime.height);
8388
}
8389
glw.setRenderingToTexture(null); // to backbuffer
8390
glw.setDepthTestEnabled(false); // ignore depth buffer, copy full texture
8391
glw.setOpacity(1);
8392
glw.setTexture(this.runtime.layout_tex);
8393
glw.setAlphaBlend();
8394
glw.resetModelView();
8395
glw.updateModelView();
8396
var halfw = this.runtime.width / 2;
8397
var halfh = this.runtime.height / 2;
8398
glw.quad(-halfw, halfh, halfw, halfh, halfw, -halfh, -halfw, -halfh);
8399
glw.setTexture(null);
8400
glw.setDepthTestEnabled(true); // turn depth test back on
8401
}
8402
else
8403
{
8404
this.renderEffectChain(glw, null, null, null);
8405
}
8406
}
8407
};
8408
Layout.prototype.getRenderTarget = function()
8409
{
8410
if (this.active_effect_types.length > 0 ||
8411
this.runtime.uses_background_blending ||
8412
!this.runtime.fullscreenScalingQuality ||
8413
this.runtime.enableFrontToBack)
8414
{
8415
return this.runtime.layout_tex;
8416
}
8417
else
8418
{
8419
return null;
8420
}
8421
};
8422
Layout.prototype.getMinLayerScale = function ()
8423
{
8424
var m = this.layers[0].getScale();
8425
var i, len, l;
8426
for (i = 1, len = this.layers.length; i < len; i++)
8427
{
8428
l = this.layers[i];
8429
if (l.parallaxX === 0 && l.parallaxY === 0)
8430
continue;
8431
if (l.getScale() < m)
8432
m = l.getScale();
8433
}
8434
return m;
8435
};
8436
Layout.prototype.scrollToX = function (x)
8437
{
8438
if (!this.unbounded_scrolling)
8439
{
8440
var widthBoundary = (this.runtime.draw_width * (1 / this.getMinLayerScale()) / 2);
8441
if (x > this.width - widthBoundary)
8442
x = this.width - widthBoundary;
8443
if (x < widthBoundary)
8444
x = widthBoundary;
8445
}
8446
if (this.scrollX !== x)
8447
{
8448
this.scrollX = x;
8449
this.runtime.redraw = true;
8450
}
8451
};
8452
Layout.prototype.scrollToY = function (y)
8453
{
8454
if (!this.unbounded_scrolling)
8455
{
8456
var heightBoundary = (this.runtime.draw_height * (1 / this.getMinLayerScale()) / 2);
8457
if (y > this.height - heightBoundary)
8458
y = this.height - heightBoundary;
8459
if (y < heightBoundary)
8460
y = heightBoundary;
8461
}
8462
if (this.scrollY !== y)
8463
{
8464
this.scrollY = y;
8465
this.runtime.redraw = true;
8466
}
8467
};
8468
Layout.prototype.boundScrolling = function ()
8469
{
8470
this.scrollToX(this.scrollX);
8471
this.scrollToY(this.scrollY);
8472
};
8473
Layout.prototype.renderEffectChain = function (glw, layer, inst, rendertarget)
8474
{
8475
var active_effect_types = inst ?
8476
inst.active_effect_types :
8477
layer ?
8478
layer.active_effect_types :
8479
this.active_effect_types;
8480
var layerScale = 1, layerAngle = 0, viewOriginLeft = 0, viewOriginTop = 0, viewOriginRight = this.runtime.draw_width, viewOriginBottom = this.runtime.draw_height;
8481
if (inst)
8482
{
8483
layerScale = inst.layer.getScale();
8484
layerAngle = inst.layer.getAngle();
8485
viewOriginLeft = inst.layer.viewLeft;
8486
viewOriginTop = inst.layer.viewTop;
8487
viewOriginRight = inst.layer.viewRight;
8488
viewOriginBottom = inst.layer.viewBottom;
8489
}
8490
else if (layer)
8491
{
8492
layerScale = layer.getScale();
8493
layerAngle = layer.getAngle();
8494
viewOriginLeft = layer.viewLeft;
8495
viewOriginTop = layer.viewTop;
8496
viewOriginRight = layer.viewRight;
8497
viewOriginBottom = layer.viewBottom;
8498
}
8499
var fx_tex = this.runtime.fx_tex;
8500
var i, len, last, temp, fx_index = 0, other_fx_index = 1;
8501
var y, h;
8502
var windowWidth = this.runtime.draw_width;
8503
var windowHeight = this.runtime.draw_height;
8504
var halfw = windowWidth / 2;
8505
var halfh = windowHeight / 2;
8506
var rcTex = layer ? layer.rcTex : this.rcTex;
8507
var rcTex2 = layer ? layer.rcTex2 : this.rcTex2;
8508
var screenleft = 0, clearleft = 0;
8509
var screentop = 0, cleartop = 0;
8510
var screenright = windowWidth, clearright = windowWidth;
8511
var screenbottom = windowHeight, clearbottom = windowHeight;
8512
var boxExtendHorizontal = 0;
8513
var boxExtendVertical = 0;
8514
var inst_layer_angle = inst ? inst.layer.getAngle() : 0;
8515
if (inst)
8516
{
8517
for (i = 0, len = active_effect_types.length; i < len; i++)
8518
{
8519
boxExtendHorizontal += glw.getProgramBoxExtendHorizontal(active_effect_types[i].shaderindex);
8520
boxExtendVertical += glw.getProgramBoxExtendVertical(active_effect_types[i].shaderindex);
8521
}
8522
var bbox = inst.bbox;
8523
screenleft = layer.layerToCanvas(bbox.left, bbox.top, true, true);
8524
screentop = layer.layerToCanvas(bbox.left, bbox.top, false, true);
8525
screenright = layer.layerToCanvas(bbox.right, bbox.bottom, true, true);
8526
screenbottom = layer.layerToCanvas(bbox.right, bbox.bottom, false, true);
8527
if (inst_layer_angle !== 0)
8528
{
8529
var screentrx = layer.layerToCanvas(bbox.right, bbox.top, true, true);
8530
var screentry = layer.layerToCanvas(bbox.right, bbox.top, false, true);
8531
var screenblx = layer.layerToCanvas(bbox.left, bbox.bottom, true, true);
8532
var screenbly = layer.layerToCanvas(bbox.left, bbox.bottom, false, true);
8533
temp = Math.min(screenleft, screenright, screentrx, screenblx);
8534
screenright = Math.max(screenleft, screenright, screentrx, screenblx);
8535
screenleft = temp;
8536
temp = Math.min(screentop, screenbottom, screentry, screenbly);
8537
screenbottom = Math.max(screentop, screenbottom, screentry, screenbly);
8538
screentop = temp;
8539
}
8540
screenleft -= boxExtendHorizontal;
8541
screentop -= boxExtendVertical;
8542
screenright += boxExtendHorizontal;
8543
screenbottom += boxExtendVertical;
8544
rcTex2.left = screenleft / windowWidth;
8545
rcTex2.top = 1 - screentop / windowHeight;
8546
rcTex2.right = screenright / windowWidth;
8547
rcTex2.bottom = 1 - screenbottom / windowHeight;
8548
clearleft = screenleft = cr.floor(screenleft);
8549
cleartop = screentop = cr.floor(screentop);
8550
clearright = screenright = cr.ceil(screenright);
8551
clearbottom = screenbottom = cr.ceil(screenbottom);
8552
clearleft -= boxExtendHorizontal;
8553
cleartop -= boxExtendVertical;
8554
clearright += boxExtendHorizontal;
8555
clearbottom += boxExtendVertical;
8556
if (screenleft < 0) screenleft = 0;
8557
if (screentop < 0) screentop = 0;
8558
if (screenright > windowWidth) screenright = windowWidth;
8559
if (screenbottom > windowHeight) screenbottom = windowHeight;
8560
if (clearleft < 0) clearleft = 0;
8561
if (cleartop < 0) cleartop = 0;
8562
if (clearright > windowWidth) clearright = windowWidth;
8563
if (clearbottom > windowHeight) clearbottom = windowHeight;
8564
rcTex.left = screenleft / windowWidth;
8565
rcTex.top = 1 - screentop / windowHeight;
8566
rcTex.right = screenright / windowWidth;
8567
rcTex.bottom = 1 - screenbottom / windowHeight;
8568
}
8569
else
8570
{
8571
rcTex.left = rcTex2.left = 0;
8572
rcTex.top = rcTex2.top = 0;
8573
rcTex.right = rcTex2.right = 1;
8574
rcTex.bottom = rcTex2.bottom = 1;
8575
}
8576
var pre_draw = (inst && (glw.programUsesDest(active_effect_types[0].shaderindex) || boxExtendHorizontal !== 0 || boxExtendVertical !== 0 || inst.opacity !== 1 || inst.type.plugin.must_predraw)) || (layer && !inst && layer.opacity !== 1);
8577
glw.setAlphaBlend();
8578
if (pre_draw)
8579
{
8580
if (!fx_tex[fx_index])
8581
{
8582
fx_tex[fx_index] = glw.createEmptyTexture(windowWidth, windowHeight, this.runtime.linearSampling);
8583
}
8584
if (fx_tex[fx_index].c2width !== windowWidth || fx_tex[fx_index].c2height !== windowHeight)
8585
{
8586
glw.deleteTexture(fx_tex[fx_index]);
8587
fx_tex[fx_index] = glw.createEmptyTexture(windowWidth, windowHeight, this.runtime.linearSampling);
8588
}
8589
glw.switchProgram(0);
8590
glw.setRenderingToTexture(fx_tex[fx_index]);
8591
h = clearbottom - cleartop;
8592
y = (windowHeight - cleartop) - h;
8593
glw.clearRect(clearleft, y, clearright - clearleft, h);
8594
if (inst)
8595
{
8596
inst.drawGL(glw);
8597
}
8598
else
8599
{
8600
glw.setTexture(this.runtime.layer_tex);
8601
glw.setOpacity(layer.opacity);
8602
glw.resetModelView();
8603
glw.translate(-halfw, -halfh);
8604
glw.updateModelView();
8605
glw.quadTex(screenleft, screenbottom, screenright, screenbottom, screenright, screentop, screenleft, screentop, rcTex);
8606
}
8607
rcTex2.left = rcTex2.top = 0;
8608
rcTex2.right = rcTex2.bottom = 1;
8609
if (inst)
8610
{
8611
temp = rcTex.top;
8612
rcTex.top = rcTex.bottom;
8613
rcTex.bottom = temp;
8614
}
8615
fx_index = 1;
8616
other_fx_index = 0;
8617
}
8618
glw.setOpacity(1);
8619
var last = active_effect_types.length - 1;
8620
var post_draw = glw.programUsesCrossSampling(active_effect_types[last].shaderindex) ||
8621
(!layer && !inst && !this.runtime.fullscreenScalingQuality);
8622
var etindex = 0;
8623
for (i = 0, len = active_effect_types.length; i < len; i++)
8624
{
8625
if (!fx_tex[fx_index])
8626
{
8627
fx_tex[fx_index] = glw.createEmptyTexture(windowWidth, windowHeight, this.runtime.linearSampling);
8628
}
8629
if (fx_tex[fx_index].c2width !== windowWidth || fx_tex[fx_index].c2height !== windowHeight)
8630
{
8631
glw.deleteTexture(fx_tex[fx_index]);
8632
fx_tex[fx_index] = glw.createEmptyTexture(windowWidth, windowHeight, this.runtime.linearSampling);
8633
}
8634
glw.switchProgram(active_effect_types[i].shaderindex);
8635
etindex = active_effect_types[i].index;
8636
if (glw.programIsAnimated(active_effect_types[i].shaderindex))
8637
this.runtime.redraw = true;
8638
if (i == 0 && !pre_draw)
8639
{
8640
glw.setRenderingToTexture(fx_tex[fx_index]);
8641
h = clearbottom - cleartop;
8642
y = (windowHeight - cleartop) - h;
8643
glw.clearRect(clearleft, y, clearright - clearleft, h);
8644
if (inst)
8645
{
8646
var pixelWidth;
8647
var pixelHeight;
8648
if (inst.curFrame && inst.curFrame.texture_img)
8649
{
8650
var img = inst.curFrame.texture_img;
8651
pixelWidth = 1.0 / img.width;
8652
pixelHeight = 1.0 / img.height;
8653
}
8654
else
8655
{
8656
pixelWidth = 1.0 / inst.width;
8657
pixelHeight = 1.0 / inst.height;
8658
}
8659
glw.setProgramParameters(rendertarget, // backTex
8660
pixelWidth,
8661
pixelHeight,
8662
rcTex2.left, rcTex2.top, // destStart
8663
rcTex2.right, rcTex2.bottom, // destEnd
8664
layerScale,
8665
layerAngle,
8666
viewOriginLeft, viewOriginTop,
8667
(viewOriginLeft + viewOriginRight) / 2, (viewOriginTop + viewOriginBottom) / 2,
8668
this.runtime.kahanTime.sum,
8669
inst.effect_params[etindex]); // fx params
8670
inst.drawGL(glw);
8671
}
8672
else
8673
{
8674
glw.setProgramParameters(rendertarget, // backTex
8675
1.0 / windowWidth, // pixelWidth
8676
1.0 / windowHeight, // pixelHeight
8677
0.0, 0.0, // destStart
8678
1.0, 1.0, // destEnd
8679
layerScale,
8680
layerAngle,
8681
viewOriginLeft, viewOriginTop,
8682
(viewOriginLeft + viewOriginRight) / 2, (viewOriginTop + viewOriginBottom) / 2,
8683
this.runtime.kahanTime.sum,
8684
layer ? // fx params
8685
layer.effect_params[etindex] :
8686
this.effect_params[etindex]);
8687
glw.setTexture(layer ? this.runtime.layer_tex : this.runtime.layout_tex);
8688
glw.resetModelView();
8689
glw.translate(-halfw, -halfh);
8690
glw.updateModelView();
8691
glw.quadTex(screenleft, screenbottom, screenright, screenbottom, screenright, screentop, screenleft, screentop, rcTex);
8692
}
8693
rcTex2.left = rcTex2.top = 0;
8694
rcTex2.right = rcTex2.bottom = 1;
8695
if (inst && !post_draw)
8696
{
8697
temp = screenbottom;
8698
screenbottom = screentop;
8699
screentop = temp;
8700
}
8701
}
8702
else
8703
{
8704
glw.setProgramParameters(rendertarget, // backTex
8705
1.0 / windowWidth, // pixelWidth
8706
1.0 / windowHeight, // pixelHeight
8707
rcTex2.left, rcTex2.top, // destStart
8708
rcTex2.right, rcTex2.bottom, // destEnd
8709
layerScale,
8710
layerAngle,
8711
viewOriginLeft, viewOriginTop,
8712
(viewOriginLeft + viewOriginRight) / 2, (viewOriginTop + viewOriginBottom) / 2,
8713
this.runtime.kahanTime.sum,
8714
inst ? // fx params
8715
inst.effect_params[etindex] :
8716
layer ?
8717
layer.effect_params[etindex] :
8718
this.effect_params[etindex]);
8719
glw.setTexture(null);
8720
if (i === last && !post_draw)
8721
{
8722
if (inst)
8723
glw.setBlend(inst.srcBlend, inst.destBlend);
8724
else if (layer)
8725
glw.setBlend(layer.srcBlend, layer.destBlend);
8726
glw.setRenderingToTexture(rendertarget);
8727
}
8728
else
8729
{
8730
glw.setRenderingToTexture(fx_tex[fx_index]);
8731
h = clearbottom - cleartop;
8732
y = (windowHeight - cleartop) - h;
8733
glw.clearRect(clearleft, y, clearright - clearleft, h);
8734
}
8735
glw.setTexture(fx_tex[other_fx_index]);
8736
glw.resetModelView();
8737
glw.translate(-halfw, -halfh);
8738
glw.updateModelView();
8739
glw.quadTex(screenleft, screenbottom, screenright, screenbottom, screenright, screentop, screenleft, screentop, rcTex);
8740
if (i === last && !post_draw)
8741
glw.setTexture(null);
8742
}
8743
fx_index = (fx_index === 0 ? 1 : 0);
8744
other_fx_index = (fx_index === 0 ? 1 : 0); // will be opposite to fx_index since it was just assigned
8745
}
8746
if (post_draw)
8747
{
8748
glw.switchProgram(0);
8749
if (inst)
8750
glw.setBlend(inst.srcBlend, inst.destBlend);
8751
else if (layer)
8752
glw.setBlend(layer.srcBlend, layer.destBlend);
8753
else
8754
{
8755
if (!this.runtime.fullscreenScalingQuality)
8756
{
8757
glw.setSize(this.runtime.width, this.runtime.height);
8758
halfw = this.runtime.width / 2;
8759
halfh = this.runtime.height / 2;
8760
screenleft = 0;
8761
screentop = 0;
8762
screenright = this.runtime.width;
8763
screenbottom = this.runtime.height;
8764
}
8765
}
8766
glw.setRenderingToTexture(rendertarget);
8767
glw.setTexture(fx_tex[other_fx_index]);
8768
glw.resetModelView();
8769
glw.translate(-halfw, -halfh);
8770
glw.updateModelView();
8771
if (inst && active_effect_types.length === 1 && !pre_draw)
8772
glw.quadTex(screenleft, screentop, screenright, screentop, screenright, screenbottom, screenleft, screenbottom, rcTex);
8773
else
8774
glw.quadTex(screenleft, screenbottom, screenright, screenbottom, screenright, screentop, screenleft, screentop, rcTex);
8775
glw.setTexture(null);
8776
}
8777
};
8778
Layout.prototype.getLayerBySid = function (sid_)
8779
{
8780
var i, len;
8781
for (i = 0, len = this.layers.length; i < len; i++)
8782
{
8783
if (this.layers[i].sid === sid_)
8784
return this.layers[i];
8785
}
8786
return null;
8787
};
8788
Layout.prototype.saveToJSON = function ()
8789
{
8790
var i, len, layer, et;
8791
var o = {
8792
"sx": this.scrollX,
8793
"sy": this.scrollY,
8794
"s": this.scale,
8795
"a": this.angle,
8796
"w": this.width,
8797
"h": this.height,
8798
"fv": this.first_visit, // added r127
8799
"persist": this.persist_data,
8800
"fx": [],
8801
"layers": {}
8802
};
8803
for (i = 0, len = this.effect_types.length; i < len; i++)
8804
{
8805
et = this.effect_types[i];
8806
o["fx"].push({"name": et.name, "active": et.active, "params": this.effect_params[et.index] });
8807
}
8808
for (i = 0, len = this.layers.length; i < len; i++)
8809
{
8810
layer = this.layers[i];
8811
o["layers"][layer.sid.toString()] = layer.saveToJSON();
8812
}
8813
return o;
8814
};
8815
Layout.prototype.loadFromJSON = function (o)
8816
{
8817
var i, j, len, fx, p, layer;
8818
this.scrollX = o["sx"];
8819
this.scrollY = o["sy"];
8820
this.scale = o["s"];
8821
this.angle = o["a"];
8822
this.width = o["w"];
8823
this.height = o["h"];
8824
this.persist_data = o["persist"];
8825
if (typeof o["fv"] !== "undefined")
8826
this.first_visit = o["fv"];
8827
var ofx = o["fx"];
8828
for (i = 0, len = ofx.length; i < len; i++)
8829
{
8830
fx = this.getEffectByName(ofx[i]["name"]);
8831
if (!fx)
8832
continue; // must've gone missing
8833
fx.active = ofx[i]["active"];
8834
this.effect_params[fx.index] = ofx[i]["params"];
8835
}
8836
this.updateActiveEffects();
8837
var olayers = o["layers"];
8838
for (p in olayers)
8839
{
8840
if (olayers.hasOwnProperty(p))
8841
{
8842
layer = this.getLayerBySid(parseInt(p, 10));
8843
if (!layer)
8844
continue; // must've gone missing
8845
layer.loadFromJSON(olayers[p]);
8846
}
8847
}
8848
};
8849
cr.layout = Layout;
8850
function Layer(layout, m)
8851
{
8852
this.layout = layout;
8853
this.runtime = layout.runtime;
8854
this.instances = []; // running instances
8855
this.scale = 1.0;
8856
this.angle = 0;
8857
this.disableAngle = false;
8858
this.tmprect = new cr.rect(0, 0, 0, 0);
8859
this.tmpquad = new cr.quad();
8860
this.viewLeft = 0;
8861
this.viewRight = 0;
8862
this.viewTop = 0;
8863
this.viewBottom = 0;
8864
this.zindices_stale = false;
8865
this.zindices_stale_from = -1; // first index that has changed, or -1 if no bound
8866
this.clear_earlyz_index = 0;
8867
this.name = m[0];
8868
this.index = m[1];
8869
this.sid = m[2];
8870
this.visible = m[3]; // initially visible
8871
this.background_color = m[4];
8872
this.transparent = m[5];
8873
this.parallaxX = m[6];
8874
this.parallaxY = m[7];
8875
this.opacity = m[8];
8876
this.forceOwnTexture = m[9];
8877
this.useRenderCells = m[10];
8878
this.zoomRate = m[11];
8879
this.blend_mode = m[12];
8880
this.effect_fallback = m[13];
8881
this.compositeOp = "source-over";
8882
this.srcBlend = 0;
8883
this.destBlend = 0;
8884
this.render_grid = null;
8885
this.last_render_list = alloc_arr();
8886
this.render_list_stale = true;
8887
this.last_render_cells = new cr.rect(0, 0, -1, -1);
8888
this.cur_render_cells = new cr.rect(0, 0, -1, -1);
8889
if (this.useRenderCells)
8890
{
8891
this.render_grid = new cr.RenderGrid(this.runtime.original_width, this.runtime.original_height);
8892
}
8893
this.render_offscreen = false;
8894
var im = m[14];
8895
var i, len;
8896
this.startup_initial_instances = []; // for restoring initial_instances after load
8897
this.initial_instances = [];
8898
this.created_globals = []; // global object UIDs already created - for save/load to avoid recreating
8899
for (i = 0, len = im.length; i < len; i++)
8900
{
8901
var inst = im[i];
8902
var type = this.runtime.types_by_index[inst[1]];
8903
;
8904
if (!type.default_instance)
8905
{
8906
type.default_instance = inst;
8907
type.default_layerindex = this.index;
8908
}
8909
this.initial_instances.push(inst);
8910
if (this.layout.initial_types.indexOf(type) === -1)
8911
this.layout.initial_types.push(type);
8912
}
8913
cr.shallowAssignArray(this.startup_initial_instances, this.initial_instances);
8914
this.effect_types = [];
8915
this.active_effect_types = [];
8916
this.shaders_preserve_opaqueness = true;
8917
this.effect_params = [];
8918
for (i = 0, len = m[15].length; i < len; i++)
8919
{
8920
this.effect_types.push({
8921
id: m[15][i][0],
8922
name: m[15][i][1],
8923
shaderindex: -1,
8924
preservesOpaqueness: false,
8925
active: true,
8926
index: i
8927
});
8928
this.effect_params.push(m[15][i][2].slice(0));
8929
}
8930
this.updateActiveEffects();
8931
this.rcTex = new cr.rect(0, 0, 1, 1);
8932
this.rcTex2 = new cr.rect(0, 0, 1, 1);
8933
};
8934
Layer.prototype.updateActiveEffects = function ()
8935
{
8936
cr.clearArray(this.active_effect_types);
8937
this.shaders_preserve_opaqueness = true;
8938
var i, len, et;
8939
for (i = 0, len = this.effect_types.length; i < len; i++)
8940
{
8941
et = this.effect_types[i];
8942
if (et.active)
8943
{
8944
this.active_effect_types.push(et);
8945
if (!et.preservesOpaqueness)
8946
this.shaders_preserve_opaqueness = false;
8947
}
8948
}
8949
};
8950
Layer.prototype.getEffectByName = function (name_)
8951
{
8952
var i, len, et;
8953
for (i = 0, len = this.effect_types.length; i < len; i++)
8954
{
8955
et = this.effect_types[i];
8956
if (et.name === name_)
8957
return et;
8958
}
8959
return null;
8960
};
8961
Layer.prototype.createInitialInstances = function ()
8962
{
8963
var i, k, len, inst, initial_inst, type, keep, hasPersistBehavior;
8964
for (i = 0, k = 0, len = this.initial_instances.length; i < len; i++)
8965
{
8966
initial_inst = this.initial_instances[i];
8967
type = this.runtime.types_by_index[initial_inst[1]];
8968
;
8969
hasPersistBehavior = this.runtime.typeHasPersistBehavior(type);
8970
keep = true;
8971
if (!hasPersistBehavior || this.layout.first_visit)
8972
{
8973
inst = this.runtime.createInstanceFromInit(initial_inst, this, true);
8974
if (!inst)
8975
continue; // may have skipped creation due to fallback effect "destroy"
8976
created_instances.push(inst);
8977
if (inst.type.global)
8978
{
8979
keep = false;
8980
this.created_globals.push(inst.uid);
8981
}
8982
}
8983
if (keep)
8984
{
8985
this.initial_instances[k] = this.initial_instances[i];
8986
k++;
8987
}
8988
}
8989
this.initial_instances.length = k;
8990
this.runtime.ClearDeathRow(); // flushes creation row so IIDs will be correct
8991
if (!this.runtime.glwrap && this.effect_types.length) // no WebGL renderer and shaders used
8992
this.blend_mode = this.effect_fallback; // use fallback blend mode
8993
this.compositeOp = cr.effectToCompositeOp(this.blend_mode);
8994
if (this.runtime.gl)
8995
cr.setGLBlend(this, this.blend_mode, this.runtime.gl);
8996
this.render_list_stale = true;
8997
};
8998
Layer.prototype.recreateInitialObjects = function (only_type, rc)
8999
{
9000
var i, len, initial_inst, type, wm, x, y, inst, j, lenj, s;
9001
var types_by_index = this.runtime.types_by_index;
9002
var only_type_is_family = only_type.is_family;
9003
var only_type_members = only_type.members;
9004
for (i = 0, len = this.initial_instances.length; i < len; ++i)
9005
{
9006
initial_inst = this.initial_instances[i];
9007
wm = initial_inst[0];
9008
x = wm[0];
9009
y = wm[1];
9010
if (!rc.contains_pt(x, y))
9011
continue; // not in the given area
9012
type = types_by_index[initial_inst[1]];
9013
if (type !== only_type)
9014
{
9015
if (only_type_is_family)
9016
{
9017
if (only_type_members.indexOf(type) < 0)
9018
continue;
9019
}
9020
else
9021
continue; // only_type is not a family, and the initial inst type does not match
9022
}
9023
inst = this.runtime.createInstanceFromInit(initial_inst, this, false);
9024
this.runtime.isInOnDestroy++;
9025
this.runtime.trigger(Object.getPrototypeOf(type.plugin).cnds.OnCreated, inst);
9026
if (inst.is_contained)
9027
{
9028
for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
9029
{
9030
s = inst.siblings[i];
9031
this.runtime.trigger(Object.getPrototypeOf(s.type.plugin).cnds.OnCreated, s);
9032
}
9033
}
9034
this.runtime.isInOnDestroy--;
9035
}
9036
};
9037
Layer.prototype.removeFromInstanceList = function (inst, remove_from_grid)
9038
{
9039
var index = cr.fastIndexOf(this.instances, inst);
9040
if (index < 0)
9041
return; // not found
9042
if (remove_from_grid && this.useRenderCells && inst.rendercells && inst.rendercells.right >= inst.rendercells.left)
9043
{
9044
inst.update_bbox(); // make sure actually in its current rendercells
9045
this.render_grid.update(inst, inst.rendercells, null); // no new range provided - remove only
9046
inst.rendercells.set(0, 0, -1, -1); // set to invalid state to indicate not inserted
9047
}
9048
if (index === this.instances.length - 1)
9049
this.instances.pop();
9050
else
9051
{
9052
cr.arrayRemove(this.instances, index);
9053
this.setZIndicesStaleFrom(index);
9054
}
9055
this.render_list_stale = true;
9056
};
9057
Layer.prototype.appendToInstanceList = function (inst, add_to_grid)
9058
{
9059
;
9060
inst.zindex = this.instances.length;
9061
this.instances.push(inst);
9062
if (add_to_grid && this.useRenderCells && inst.rendercells)
9063
{
9064
inst.set_bbox_changed(); // will cause immediate update and new insertion to grid
9065
}
9066
this.render_list_stale = true;
9067
};
9068
Layer.prototype.prependToInstanceList = function (inst, add_to_grid)
9069
{
9070
;
9071
this.instances.unshift(inst);
9072
this.setZIndicesStaleFrom(0);
9073
if (add_to_grid && this.useRenderCells && inst.rendercells)
9074
{
9075
inst.set_bbox_changed(); // will cause immediate update and new insertion to grid
9076
}
9077
};
9078
Layer.prototype.moveInstanceAdjacent = function (inst, other, isafter)
9079
{
9080
;
9081
var myZ = inst.get_zindex();
9082
var insertZ = other.get_zindex();
9083
cr.arrayRemove(this.instances, myZ);
9084
if (myZ < insertZ)
9085
insertZ--;
9086
if (isafter)
9087
insertZ++;
9088
if (insertZ === this.instances.length)
9089
this.instances.push(inst);
9090
else
9091
this.instances.splice(insertZ, 0, inst);
9092
this.setZIndicesStaleFrom(myZ < insertZ ? myZ : insertZ);
9093
};
9094
Layer.prototype.setZIndicesStaleFrom = function (index)
9095
{
9096
if (this.zindices_stale_from === -1) // not yet set
9097
this.zindices_stale_from = index;
9098
else if (index < this.zindices_stale_from) // determine minimum z index affected
9099
this.zindices_stale_from = index;
9100
this.zindices_stale = true;
9101
this.render_list_stale = true;
9102
};
9103
Layer.prototype.updateZIndices = function ()
9104
{
9105
if (!this.zindices_stale)
9106
return;
9107
if (this.zindices_stale_from === -1)
9108
this.zindices_stale_from = 0;
9109
var i, len, inst;
9110
if (this.useRenderCells)
9111
{
9112
for (i = this.zindices_stale_from, len = this.instances.length; i < len; ++i)
9113
{
9114
inst = this.instances[i];
9115
inst.zindex = i;
9116
this.render_grid.markRangeChanged(inst.rendercells);
9117
}
9118
}
9119
else
9120
{
9121
for (i = this.zindices_stale_from, len = this.instances.length; i < len; ++i)
9122
{
9123
this.instances[i].zindex = i;
9124
}
9125
}
9126
this.zindices_stale = false;
9127
this.zindices_stale_from = -1;
9128
};
9129
Layer.prototype.getScale = function (include_aspect)
9130
{
9131
return this.getNormalScale() * (this.runtime.fullscreenScalingQuality || include_aspect ? this.runtime.aspect_scale : 1);
9132
};
9133
Layer.prototype.getNormalScale = function ()
9134
{
9135
return ((this.scale * this.layout.scale) - 1) * this.zoomRate + 1;
9136
};
9137
Layer.prototype.getAngle = function ()
9138
{
9139
if (this.disableAngle)
9140
return 0;
9141
return cr.clamp_angle(this.layout.angle + this.angle);
9142
};
9143
var arr_cache = [];
9144
function alloc_arr()
9145
{
9146
if (arr_cache.length)
9147
return arr_cache.pop();
9148
else
9149
return [];
9150
}
9151
function free_arr(a)
9152
{
9153
cr.clearArray(a);
9154
arr_cache.push(a);
9155
};
9156
function mergeSortedZArrays(a, b, out)
9157
{
9158
var i = 0, j = 0, k = 0, lena = a.length, lenb = b.length, ai, bj;
9159
out.length = lena + lenb;
9160
for ( ; i < lena && j < lenb; ++k)
9161
{
9162
ai = a[i];
9163
bj = b[j];
9164
if (ai.zindex < bj.zindex)
9165
{
9166
out[k] = ai;
9167
++i;
9168
}
9169
else
9170
{
9171
out[k] = bj;
9172
++j;
9173
}
9174
}
9175
for ( ; i < lena; ++i, ++k)
9176
out[k] = a[i];
9177
for ( ; j < lenb; ++j, ++k)
9178
out[k] = b[j];
9179
};
9180
var next_arr = [];
9181
function mergeAllSortedZArrays_pass(arr, first_pass)
9182
{
9183
var i, len, arr1, arr2, out;
9184
for (i = 0, len = arr.length; i < len - 1; i += 2)
9185
{
9186
arr1 = arr[i];
9187
arr2 = arr[i+1];
9188
out = alloc_arr();
9189
mergeSortedZArrays(arr1, arr2, out);
9190
if (!first_pass)
9191
{
9192
free_arr(arr1);
9193
free_arr(arr2);
9194
}
9195
next_arr.push(out);
9196
}
9197
if (len % 2 === 1)
9198
{
9199
if (first_pass)
9200
{
9201
arr1 = alloc_arr();
9202
cr.shallowAssignArray(arr1, arr[len - 1]);
9203
next_arr.push(arr1);
9204
}
9205
else
9206
{
9207
next_arr.push(arr[len - 1]);
9208
}
9209
}
9210
cr.shallowAssignArray(arr, next_arr);
9211
cr.clearArray(next_arr);
9212
};
9213
function mergeAllSortedZArrays(arr)
9214
{
9215
var first_pass = true;
9216
while (arr.length > 1)
9217
{
9218
mergeAllSortedZArrays_pass(arr, first_pass);
9219
first_pass = false;
9220
}
9221
return arr[0];
9222
};
9223
var render_arr = [];
9224
Layer.prototype.getRenderCellInstancesToDraw = function ()
9225
{
9226
;
9227
this.updateZIndices();
9228
this.render_grid.queryRange(this.viewLeft, this.viewTop, this.viewRight, this.viewBottom, render_arr);
9229
if (!render_arr.length)
9230
return alloc_arr();
9231
if (render_arr.length === 1)
9232
{
9233
var a = alloc_arr();
9234
cr.shallowAssignArray(a, render_arr[0]);
9235
cr.clearArray(render_arr);
9236
return a;
9237
}
9238
var draw_list = mergeAllSortedZArrays(render_arr);
9239
cr.clearArray(render_arr);
9240
return draw_list;
9241
};
9242
Layer.prototype.draw = function (ctx)
9243
{
9244
this.render_offscreen = (this.forceOwnTexture || this.opacity !== 1.0 || this.blend_mode !== 0);
9245
var layer_canvas = this.runtime.canvas;
9246
var layer_ctx = ctx;
9247
var ctx_changed = false;
9248
if (this.render_offscreen)
9249
{
9250
if (!this.runtime.layer_canvas)
9251
{
9252
this.runtime.layer_canvas = document.createElement("canvas");
9253
;
9254
layer_canvas = this.runtime.layer_canvas;
9255
layer_canvas.width = this.runtime.draw_width;
9256
layer_canvas.height = this.runtime.draw_height;
9257
this.runtime.layer_ctx = layer_canvas.getContext("2d");
9258
;
9259
ctx_changed = true;
9260
}
9261
layer_canvas = this.runtime.layer_canvas;
9262
layer_ctx = this.runtime.layer_ctx;
9263
if (layer_canvas.width !== this.runtime.draw_width)
9264
{
9265
layer_canvas.width = this.runtime.draw_width;
9266
ctx_changed = true;
9267
}
9268
if (layer_canvas.height !== this.runtime.draw_height)
9269
{
9270
layer_canvas.height = this.runtime.draw_height;
9271
ctx_changed = true;
9272
}
9273
if (ctx_changed)
9274
{
9275
this.runtime.setCtxImageSmoothingEnabled(layer_ctx, this.runtime.linearSampling);
9276
}
9277
if (this.transparent)
9278
layer_ctx.clearRect(0, 0, this.runtime.draw_width, this.runtime.draw_height);
9279
}
9280
layer_ctx.globalAlpha = 1;
9281
layer_ctx.globalCompositeOperation = "source-over";
9282
if (!this.transparent)
9283
{
9284
layer_ctx.fillStyle = "rgb(" + this.background_color[0] + "," + this.background_color[1] + "," + this.background_color[2] + ")";
9285
layer_ctx.fillRect(0, 0, this.runtime.draw_width, this.runtime.draw_height);
9286
}
9287
layer_ctx.save();
9288
this.disableAngle = true;
9289
var px = this.canvasToLayer(0, 0, true, true);
9290
var py = this.canvasToLayer(0, 0, false, true);
9291
this.disableAngle = false;
9292
if (this.runtime.pixel_rounding)
9293
{
9294
px = Math.round(px);
9295
py = Math.round(py);
9296
}
9297
this.rotateViewport(px, py, layer_ctx);
9298
var myscale = this.getScale();
9299
layer_ctx.scale(myscale, myscale);
9300
layer_ctx.translate(-px, -py);
9301
var instances_to_draw;
9302
if (this.useRenderCells)
9303
{
9304
this.cur_render_cells.left = this.render_grid.XToCell(this.viewLeft);
9305
this.cur_render_cells.top = this.render_grid.YToCell(this.viewTop);
9306
this.cur_render_cells.right = this.render_grid.XToCell(this.viewRight);
9307
this.cur_render_cells.bottom = this.render_grid.YToCell(this.viewBottom);
9308
if (this.render_list_stale || !this.cur_render_cells.equals(this.last_render_cells))
9309
{
9310
free_arr(this.last_render_list);
9311
instances_to_draw = this.getRenderCellInstancesToDraw();
9312
this.render_list_stale = false;
9313
this.last_render_cells.copy(this.cur_render_cells);
9314
}
9315
else
9316
instances_to_draw = this.last_render_list;
9317
}
9318
else
9319
instances_to_draw = this.instances;
9320
var i, len, inst, last_inst = null;
9321
for (i = 0, len = instances_to_draw.length; i < len; ++i)
9322
{
9323
inst = instances_to_draw[i];
9324
if (inst === last_inst)
9325
continue;
9326
this.drawInstance(inst, layer_ctx);
9327
last_inst = inst;
9328
}
9329
if (this.useRenderCells)
9330
this.last_render_list = instances_to_draw;
9331
layer_ctx.restore();
9332
if (this.render_offscreen)
9333
{
9334
ctx.globalCompositeOperation = this.compositeOp;
9335
ctx.globalAlpha = this.opacity;
9336
ctx.drawImage(layer_canvas, 0, 0);
9337
}
9338
};
9339
Layer.prototype.drawInstance = function(inst, layer_ctx)
9340
{
9341
if (!inst.visible || inst.width === 0 || inst.height === 0)
9342
return;
9343
inst.update_bbox();
9344
var bbox = inst.bbox;
9345
if (bbox.right < this.viewLeft || bbox.bottom < this.viewTop || bbox.left > this.viewRight || bbox.top > this.viewBottom)
9346
return;
9347
layer_ctx.globalCompositeOperation = inst.compositeOp;
9348
inst.draw(layer_ctx);
9349
};
9350
Layer.prototype.updateViewport = function (ctx)
9351
{
9352
this.disableAngle = true;
9353
var px = this.canvasToLayer(0, 0, true, true);
9354
var py = this.canvasToLayer(0, 0, false, true);
9355
this.disableAngle = false;
9356
if (this.runtime.pixel_rounding)
9357
{
9358
px = Math.round(px);
9359
py = Math.round(py);
9360
}
9361
this.rotateViewport(px, py, ctx);
9362
};
9363
Layer.prototype.rotateViewport = function (px, py, ctx)
9364
{
9365
var myscale = this.getScale();
9366
this.viewLeft = px;
9367
this.viewTop = py;
9368
this.viewRight = px + (this.runtime.draw_width * (1 / myscale));
9369
this.viewBottom = py + (this.runtime.draw_height * (1 / myscale));
9370
var temp;
9371
if (this.viewLeft > this.viewRight)
9372
{
9373
temp = this.viewLeft;
9374
this.viewLeft = this.viewRight;
9375
this.viewRight = temp;
9376
}
9377
if (this.viewTop > this.viewBottom)
9378
{
9379
temp = this.viewTop;
9380
this.viewTop = this.viewBottom;
9381
this.viewBottom = temp;
9382
}
9383
var myAngle = this.getAngle();
9384
if (myAngle !== 0)
9385
{
9386
if (ctx)
9387
{
9388
ctx.translate(this.runtime.draw_width / 2, this.runtime.draw_height / 2);
9389
ctx.rotate(-myAngle);
9390
ctx.translate(this.runtime.draw_width / -2, this.runtime.draw_height / -2);
9391
}
9392
this.tmprect.set(this.viewLeft, this.viewTop, this.viewRight, this.viewBottom);
9393
this.tmprect.offset((this.viewLeft + this.viewRight) / -2, (this.viewTop + this.viewBottom) / -2);
9394
this.tmpquad.set_from_rotated_rect(this.tmprect, myAngle);
9395
this.tmpquad.bounding_box(this.tmprect);
9396
this.tmprect.offset((this.viewLeft + this.viewRight) / 2, (this.viewTop + this.viewBottom) / 2);
9397
this.viewLeft = this.tmprect.left;
9398
this.viewTop = this.tmprect.top;
9399
this.viewRight = this.tmprect.right;
9400
this.viewBottom = this.tmprect.bottom;
9401
}
9402
}
9403
Layer.prototype.drawGL_earlyZPass = function (glw)
9404
{
9405
var windowWidth = this.runtime.draw_width;
9406
var windowHeight = this.runtime.draw_height;
9407
var shaderindex = 0;
9408
var etindex = 0;
9409
this.render_offscreen = this.forceOwnTexture;
9410
if (this.render_offscreen)
9411
{
9412
if (!this.runtime.layer_tex)
9413
{
9414
this.runtime.layer_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.linearSampling);
9415
}
9416
if (this.runtime.layer_tex.c2width !== this.runtime.draw_width || this.runtime.layer_tex.c2height !== this.runtime.draw_height)
9417
{
9418
glw.deleteTexture(this.runtime.layer_tex);
9419
this.runtime.layer_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.linearSampling);
9420
}
9421
glw.setRenderingToTexture(this.runtime.layer_tex);
9422
}
9423
this.disableAngle = true;
9424
var px = this.canvasToLayer(0, 0, true, true);
9425
var py = this.canvasToLayer(0, 0, false, true);
9426
this.disableAngle = false;
9427
if (this.runtime.pixel_rounding)
9428
{
9429
px = Math.round(px);
9430
py = Math.round(py);
9431
}
9432
this.rotateViewport(px, py, null);
9433
var myscale = this.getScale();
9434
glw.resetModelView();
9435
glw.scale(myscale, myscale);
9436
glw.rotateZ(-this.getAngle());
9437
glw.translate((this.viewLeft + this.viewRight) / -2, (this.viewTop + this.viewBottom) / -2);
9438
glw.updateModelView();
9439
var instances_to_draw;
9440
if (this.useRenderCells)
9441
{
9442
this.cur_render_cells.left = this.render_grid.XToCell(this.viewLeft);
9443
this.cur_render_cells.top = this.render_grid.YToCell(this.viewTop);
9444
this.cur_render_cells.right = this.render_grid.XToCell(this.viewRight);
9445
this.cur_render_cells.bottom = this.render_grid.YToCell(this.viewBottom);
9446
if (this.render_list_stale || !this.cur_render_cells.equals(this.last_render_cells))
9447
{
9448
free_arr(this.last_render_list);
9449
instances_to_draw = this.getRenderCellInstancesToDraw();
9450
this.render_list_stale = false;
9451
this.last_render_cells.copy(this.cur_render_cells);
9452
}
9453
else
9454
instances_to_draw = this.last_render_list;
9455
}
9456
else
9457
instances_to_draw = this.instances;
9458
var i, inst, last_inst = null;
9459
for (i = instances_to_draw.length - 1; i >= 0; --i)
9460
{
9461
inst = instances_to_draw[i];
9462
if (inst === last_inst)
9463
continue;
9464
this.drawInstanceGL_earlyZPass(instances_to_draw[i], glw);
9465
last_inst = inst;
9466
}
9467
if (this.useRenderCells)
9468
this.last_render_list = instances_to_draw;
9469
if (!this.transparent)
9470
{
9471
this.clear_earlyz_index = this.runtime.earlyz_index++;
9472
glw.setEarlyZIndex(this.clear_earlyz_index);
9473
glw.setColorFillMode(1, 1, 1, 1);
9474
glw.fullscreenQuad(); // fill remaining space in depth buffer with current Z value
9475
glw.restoreEarlyZMode();
9476
}
9477
};
9478
Layer.prototype.drawGL = function (glw)
9479
{
9480
var windowWidth = this.runtime.draw_width;
9481
var windowHeight = this.runtime.draw_height;
9482
var shaderindex = 0;
9483
var etindex = 0;
9484
this.render_offscreen = (this.forceOwnTexture || this.opacity !== 1.0 || this.active_effect_types.length > 0 || this.blend_mode !== 0);
9485
if (this.render_offscreen)
9486
{
9487
if (!this.runtime.layer_tex)
9488
{
9489
this.runtime.layer_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.linearSampling);
9490
}
9491
if (this.runtime.layer_tex.c2width !== this.runtime.draw_width || this.runtime.layer_tex.c2height !== this.runtime.draw_height)
9492
{
9493
glw.deleteTexture(this.runtime.layer_tex);
9494
this.runtime.layer_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.linearSampling);
9495
}
9496
glw.setRenderingToTexture(this.runtime.layer_tex);
9497
if (this.transparent)
9498
glw.clear(0, 0, 0, 0);
9499
}
9500
if (!this.transparent)
9501
{
9502
if (this.runtime.enableFrontToBack)
9503
{
9504
glw.setEarlyZIndex(this.clear_earlyz_index);
9505
glw.setColorFillMode(this.background_color[0] / 255, this.background_color[1] / 255, this.background_color[2] / 255, 1);
9506
glw.fullscreenQuad();
9507
glw.setTextureFillMode();
9508
}
9509
else
9510
{
9511
glw.clear(this.background_color[0] / 255, this.background_color[1] / 255, this.background_color[2] / 255, 1);
9512
}
9513
}
9514
this.disableAngle = true;
9515
var px = this.canvasToLayer(0, 0, true, true);
9516
var py = this.canvasToLayer(0, 0, false, true);
9517
this.disableAngle = false;
9518
if (this.runtime.pixel_rounding)
9519
{
9520
px = Math.round(px);
9521
py = Math.round(py);
9522
}
9523
this.rotateViewport(px, py, null);
9524
var myscale = this.getScale();
9525
glw.resetModelView();
9526
glw.scale(myscale, myscale);
9527
glw.rotateZ(-this.getAngle());
9528
glw.translate((this.viewLeft + this.viewRight) / -2, (this.viewTop + this.viewBottom) / -2);
9529
glw.updateModelView();
9530
var instances_to_draw;
9531
if (this.useRenderCells)
9532
{
9533
this.cur_render_cells.left = this.render_grid.XToCell(this.viewLeft);
9534
this.cur_render_cells.top = this.render_grid.YToCell(this.viewTop);
9535
this.cur_render_cells.right = this.render_grid.XToCell(this.viewRight);
9536
this.cur_render_cells.bottom = this.render_grid.YToCell(this.viewBottom);
9537
if (this.render_list_stale || !this.cur_render_cells.equals(this.last_render_cells))
9538
{
9539
free_arr(this.last_render_list);
9540
instances_to_draw = this.getRenderCellInstancesToDraw();
9541
this.render_list_stale = false;
9542
this.last_render_cells.copy(this.cur_render_cells);
9543
}
9544
else
9545
instances_to_draw = this.last_render_list;
9546
}
9547
else
9548
instances_to_draw = this.instances;
9549
var i, len, inst, last_inst = null;
9550
for (i = 0, len = instances_to_draw.length; i < len; ++i)
9551
{
9552
inst = instances_to_draw[i];
9553
if (inst === last_inst)
9554
continue;
9555
this.drawInstanceGL(instances_to_draw[i], glw);
9556
last_inst = inst;
9557
}
9558
if (this.useRenderCells)
9559
this.last_render_list = instances_to_draw;
9560
if (this.render_offscreen)
9561
{
9562
shaderindex = this.active_effect_types.length ? this.active_effect_types[0].shaderindex : 0;
9563
etindex = this.active_effect_types.length ? this.active_effect_types[0].index : 0;
9564
if (this.active_effect_types.length === 0 || (this.active_effect_types.length === 1 &&
9565
!glw.programUsesCrossSampling(shaderindex) && this.opacity === 1))
9566
{
9567
if (this.active_effect_types.length === 1)
9568
{
9569
glw.switchProgram(shaderindex);
9570
glw.setProgramParameters(this.layout.getRenderTarget(), // backTex
9571
1.0 / this.runtime.draw_width, // pixelWidth
9572
1.0 / this.runtime.draw_height, // pixelHeight
9573
0.0, 0.0, // destStart
9574
1.0, 1.0, // destEnd
9575
myscale, // layerScale
9576
this.getAngle(),
9577
this.viewLeft, this.viewTop,
9578
(this.viewLeft + this.viewRight) / 2, (this.viewTop + this.viewBottom) / 2,
9579
this.runtime.kahanTime.sum,
9580
this.effect_params[etindex]); // fx parameters
9581
if (glw.programIsAnimated(shaderindex))
9582
this.runtime.redraw = true;
9583
}
9584
else
9585
glw.switchProgram(0);
9586
glw.setRenderingToTexture(this.layout.getRenderTarget());
9587
glw.setOpacity(this.opacity);
9588
glw.setTexture(this.runtime.layer_tex);
9589
glw.setBlend(this.srcBlend, this.destBlend);
9590
glw.resetModelView();
9591
glw.updateModelView();
9592
var halfw = this.runtime.draw_width / 2;
9593
var halfh = this.runtime.draw_height / 2;
9594
glw.quad(-halfw, halfh, halfw, halfh, halfw, -halfh, -halfw, -halfh);
9595
glw.setTexture(null);
9596
}
9597
else
9598
{
9599
this.layout.renderEffectChain(glw, this, null, this.layout.getRenderTarget());
9600
}
9601
}
9602
};
9603
Layer.prototype.drawInstanceGL = function (inst, glw)
9604
{
9605
;
9606
if (!inst.visible || inst.width === 0 || inst.height === 0)
9607
return;
9608
inst.update_bbox();
9609
var bbox = inst.bbox;
9610
if (bbox.right < this.viewLeft || bbox.bottom < this.viewTop || bbox.left > this.viewRight || bbox.top > this.viewBottom)
9611
return;
9612
glw.setEarlyZIndex(inst.earlyz_index);
9613
if (inst.uses_shaders)
9614
{
9615
this.drawInstanceWithShadersGL(inst, glw);
9616
}
9617
else
9618
{
9619
glw.switchProgram(0); // un-set any previously set shader
9620
glw.setBlend(inst.srcBlend, inst.destBlend);
9621
inst.drawGL(glw);
9622
}
9623
};
9624
Layer.prototype.drawInstanceGL_earlyZPass = function (inst, glw)
9625
{
9626
;
9627
if (!inst.visible || inst.width === 0 || inst.height === 0)
9628
return;
9629
inst.update_bbox();
9630
var bbox = inst.bbox;
9631
if (bbox.right < this.viewLeft || bbox.bottom < this.viewTop || bbox.left > this.viewRight || bbox.top > this.viewBottom)
9632
return;
9633
inst.earlyz_index = this.runtime.earlyz_index++;
9634
if (inst.blend_mode !== 0 || inst.opacity !== 1 || !inst.shaders_preserve_opaqueness || !inst.drawGL_earlyZPass)
9635
return;
9636
glw.setEarlyZIndex(inst.earlyz_index);
9637
inst.drawGL_earlyZPass(glw);
9638
};
9639
Layer.prototype.drawInstanceWithShadersGL = function (inst, glw)
9640
{
9641
var shaderindex = inst.active_effect_types[0].shaderindex;
9642
var etindex = inst.active_effect_types[0].index;
9643
var myscale = this.getScale();
9644
if (inst.active_effect_types.length === 1 && !glw.programUsesCrossSampling(shaderindex) &&
9645
!glw.programExtendsBox(shaderindex) && ((!inst.angle && !inst.layer.getAngle()) || !glw.programUsesDest(shaderindex)) &&
9646
inst.opacity === 1 && !inst.type.plugin.must_predraw)
9647
{
9648
glw.switchProgram(shaderindex);
9649
glw.setBlend(inst.srcBlend, inst.destBlend);
9650
if (glw.programIsAnimated(shaderindex))
9651
this.runtime.redraw = true;
9652
var destStartX = 0, destStartY = 0, destEndX = 0, destEndY = 0;
9653
if (glw.programUsesDest(shaderindex))
9654
{
9655
var bbox = inst.bbox;
9656
var screenleft = this.layerToCanvas(bbox.left, bbox.top, true, true);
9657
var screentop = this.layerToCanvas(bbox.left, bbox.top, false, true);
9658
var screenright = this.layerToCanvas(bbox.right, bbox.bottom, true, true);
9659
var screenbottom = this.layerToCanvas(bbox.right, bbox.bottom, false, true);
9660
destStartX = screenleft / windowWidth;
9661
destStartY = 1 - screentop / windowHeight;
9662
destEndX = screenright / windowWidth;
9663
destEndY = 1 - screenbottom / windowHeight;
9664
}
9665
var pixelWidth;
9666
var pixelHeight;
9667
if (inst.curFrame && inst.curFrame.texture_img)
9668
{
9669
var img = inst.curFrame.texture_img;
9670
pixelWidth = 1.0 / img.width;
9671
pixelHeight = 1.0 / img.height;
9672
}
9673
else
9674
{
9675
pixelWidth = 1.0 / inst.width;
9676
pixelHeight = 1.0 / inst.height;
9677
}
9678
glw.setProgramParameters(this.render_offscreen ? this.runtime.layer_tex : this.layout.getRenderTarget(), // backTex
9679
pixelWidth,
9680
pixelHeight,
9681
destStartX, destStartY,
9682
destEndX, destEndY,
9683
myscale,
9684
this.getAngle(),
9685
this.viewLeft, this.viewTop,
9686
(this.viewLeft + this.viewRight) / 2, (this.viewTop + this.viewBottom) / 2,
9687
this.runtime.kahanTime.sum,
9688
inst.effect_params[etindex]);
9689
inst.drawGL(glw);
9690
}
9691
else
9692
{
9693
this.layout.renderEffectChain(glw, this, inst, this.render_offscreen ? this.runtime.layer_tex : this.layout.getRenderTarget());
9694
glw.resetModelView();
9695
glw.scale(myscale, myscale);
9696
glw.rotateZ(-this.getAngle());
9697
glw.translate((this.viewLeft + this.viewRight) / -2, (this.viewTop + this.viewBottom) / -2);
9698
glw.updateModelView();
9699
}
9700
};
9701
Layer.prototype.canvasToLayer = function (ptx, pty, getx, using_draw_area)
9702
{
9703
var multiplier = this.runtime.devicePixelRatio;
9704
if (this.runtime.isRetina)
9705
{
9706
ptx *= multiplier;
9707
pty *= multiplier;
9708
}
9709
var ox = this.runtime.parallax_x_origin;
9710
var oy = this.runtime.parallax_y_origin;
9711
var par_x = ((this.layout.scrollX - ox) * this.parallaxX) + ox;
9712
var par_y = ((this.layout.scrollY - oy) * this.parallaxY) + oy;
9713
var x = par_x;
9714
var y = par_y;
9715
var invScale = 1 / this.getScale(!using_draw_area);
9716
if (using_draw_area)
9717
{
9718
x -= (this.runtime.draw_width * invScale) / 2;
9719
y -= (this.runtime.draw_height * invScale) / 2;
9720
}
9721
else
9722
{
9723
x -= (this.runtime.width * invScale) / 2;
9724
y -= (this.runtime.height * invScale) / 2;
9725
}
9726
x += ptx * invScale;
9727
y += pty * invScale;
9728
var a = this.getAngle();
9729
if (a !== 0)
9730
{
9731
x -= par_x;
9732
y -= par_y;
9733
var cosa = Math.cos(a);
9734
var sina = Math.sin(a);
9735
var x_temp = (x * cosa) - (y * sina);
9736
y = (y * cosa) + (x * sina);
9737
x = x_temp;
9738
x += par_x;
9739
y += par_y;
9740
}
9741
return getx ? x : y;
9742
};
9743
Layer.prototype.layerToCanvas = function (ptx, pty, getx, using_draw_area)
9744
{
9745
var ox = this.runtime.parallax_x_origin;
9746
var oy = this.runtime.parallax_y_origin;
9747
var par_x = ((this.layout.scrollX - ox) * this.parallaxX) + ox;
9748
var par_y = ((this.layout.scrollY - oy) * this.parallaxY) + oy;
9749
var x = par_x;
9750
var y = par_y;
9751
var a = this.getAngle();
9752
if (a !== 0)
9753
{
9754
ptx -= par_x;
9755
pty -= par_y;
9756
var cosa = Math.cos(-a);
9757
var sina = Math.sin(-a);
9758
var x_temp = (ptx * cosa) - (pty * sina);
9759
pty = (pty * cosa) + (ptx * sina);
9760
ptx = x_temp;
9761
ptx += par_x;
9762
pty += par_y;
9763
}
9764
var invScale = 1 / this.getScale(!using_draw_area);
9765
if (using_draw_area)
9766
{
9767
x -= (this.runtime.draw_width * invScale) / 2;
9768
y -= (this.runtime.draw_height * invScale) / 2;
9769
}
9770
else
9771
{
9772
x -= (this.runtime.width * invScale) / 2;
9773
y -= (this.runtime.height * invScale) / 2;
9774
}
9775
x = (ptx - x) / invScale;
9776
y = (pty - y) / invScale;
9777
var multiplier = this.runtime.devicePixelRatio;
9778
if (this.runtime.isRetina && !using_draw_area)
9779
{
9780
x /= multiplier;
9781
y /= multiplier;
9782
}
9783
return getx ? x : y;
9784
};
9785
Layer.prototype.rotatePt = function (x_, y_, getx)
9786
{
9787
if (this.getAngle() === 0)
9788
return getx ? x_ : y_;
9789
var nx = this.layerToCanvas(x_, y_, true);
9790
var ny = this.layerToCanvas(x_, y_, false);
9791
this.disableAngle = true;
9792
var px = this.canvasToLayer(nx, ny, true);
9793
var py = this.canvasToLayer(nx, ny, true);
9794
this.disableAngle = false;
9795
return getx ? px : py;
9796
};
9797
Layer.prototype.saveToJSON = function ()
9798
{
9799
var i, len, et;
9800
var o = {
9801
"s": this.scale,
9802
"a": this.angle,
9803
"vl": this.viewLeft,
9804
"vt": this.viewTop,
9805
"vr": this.viewRight,
9806
"vb": this.viewBottom,
9807
"v": this.visible,
9808
"bc": this.background_color,
9809
"t": this.transparent,
9810
"px": this.parallaxX,
9811
"py": this.parallaxY,
9812
"o": this.opacity,
9813
"zr": this.zoomRate,
9814
"fx": [],
9815
"cg": this.created_globals, // added r197; list of global UIDs already created
9816
"instances": []
9817
};
9818
for (i = 0, len = this.effect_types.length; i < len; i++)
9819
{
9820
et = this.effect_types[i];
9821
o["fx"].push({"name": et.name, "active": et.active, "params": this.effect_params[et.index] });
9822
}
9823
return o;
9824
};
9825
Layer.prototype.loadFromJSON = function (o)
9826
{
9827
var i, j, len, p, inst, fx;
9828
this.scale = o["s"];
9829
this.angle = o["a"];
9830
this.viewLeft = o["vl"];
9831
this.viewTop = o["vt"];
9832
this.viewRight = o["vr"];
9833
this.viewBottom = o["vb"];
9834
this.visible = o["v"];
9835
this.background_color = o["bc"];
9836
this.transparent = o["t"];
9837
this.parallaxX = o["px"];
9838
this.parallaxY = o["py"];
9839
this.opacity = o["o"];
9840
this.zoomRate = o["zr"];
9841
this.created_globals = o["cg"] || []; // added r197
9842
cr.shallowAssignArray(this.initial_instances, this.startup_initial_instances);
9843
var temp_set = new cr.ObjectSet();
9844
for (i = 0, len = this.created_globals.length; i < len; ++i)
9845
temp_set.add(this.created_globals[i]);
9846
for (i = 0, j = 0, len = this.initial_instances.length; i < len; ++i)
9847
{
9848
if (!temp_set.contains(this.initial_instances[i][2])) // UID in element 2
9849
{
9850
this.initial_instances[j] = this.initial_instances[i];
9851
++j;
9852
}
9853
}
9854
cr.truncateArray(this.initial_instances, j);
9855
var ofx = o["fx"];
9856
for (i = 0, len = ofx.length; i < len; i++)
9857
{
9858
fx = this.getEffectByName(ofx[i]["name"]);
9859
if (!fx)
9860
continue; // must've gone missing
9861
fx.active = ofx[i]["active"];
9862
this.effect_params[fx.index] = ofx[i]["params"];
9863
}
9864
this.updateActiveEffects();
9865
this.instances.sort(sort_by_zindex);
9866
this.zindices_stale = true;
9867
};
9868
cr.layer = Layer;
9869
}());
9870
;
9871
(function()
9872
{
9873
var allUniqueSolModifiers = [];
9874
function testSolsMatch(arr1, arr2)
9875
{
9876
var i, len = arr1.length;
9877
switch (len) {
9878
case 0:
9879
return true;
9880
case 1:
9881
return arr1[0] === arr2[0];
9882
case 2:
9883
return arr1[0] === arr2[0] && arr1[1] === arr2[1];
9884
default:
9885
for (i = 0; i < len; i++)
9886
{
9887
if (arr1[i] !== arr2[i])
9888
return false;
9889
}
9890
return true;
9891
}
9892
};
9893
function solArraySorter(t1, t2)
9894
{
9895
return t1.index - t2.index;
9896
};
9897
function findMatchingSolModifier(arr)
9898
{
9899
var i, len, u, temp, subarr;
9900
if (arr.length === 2)
9901
{
9902
if (arr[0].index > arr[1].index)
9903
{
9904
temp = arr[0];
9905
arr[0] = arr[1];
9906
arr[1] = temp;
9907
}
9908
}
9909
else if (arr.length > 2)
9910
arr.sort(solArraySorter); // so testSolsMatch compares in same order
9911
if (arr.length >= allUniqueSolModifiers.length)
9912
allUniqueSolModifiers.length = arr.length + 1;
9913
if (!allUniqueSolModifiers[arr.length])
9914
allUniqueSolModifiers[arr.length] = [];
9915
subarr = allUniqueSolModifiers[arr.length];
9916
for (i = 0, len = subarr.length; i < len; i++)
9917
{
9918
u = subarr[i];
9919
if (testSolsMatch(arr, u))
9920
return u;
9921
}
9922
subarr.push(arr);
9923
return arr;
9924
};
9925
function EventSheet(runtime, m)
9926
{
9927
this.runtime = runtime;
9928
this.triggers = {};
9929
this.fasttriggers = {};
9930
this.hasRun = false;
9931
this.includes = new cr.ObjectSet(); // all event sheets included by this sheet, at first-level indirection only
9932
this.deep_includes = []; // all includes from this sheet recursively, in trigger order
9933
this.already_included_sheets = []; // used while building deep_includes
9934
this.name = m[0];
9935
var em = m[1]; // events model
9936
this.events = []; // triggers won't make it to this array
9937
var i, len;
9938
for (i = 0, len = em.length; i < len; i++)
9939
this.init_event(em[i], null, this.events);
9940
};
9941
EventSheet.prototype.toString = function ()
9942
{
9943
return this.name;
9944
};
9945
EventSheet.prototype.init_event = function (m, parent, nontriggers)
9946
{
9947
switch (m[0]) {
9948
case 0: // event block
9949
{
9950
var block = new cr.eventblock(this, parent, m);
9951
cr.seal(block);
9952
if (block.orblock)
9953
{
9954
nontriggers.push(block);
9955
var i, len;
9956
for (i = 0, len = block.conditions.length; i < len; i++)
9957
{
9958
if (block.conditions[i].trigger)
9959
this.init_trigger(block, i);
9960
}
9961
}
9962
else
9963
{
9964
if (block.is_trigger())
9965
this.init_trigger(block, 0);
9966
else
9967
nontriggers.push(block);
9968
}
9969
break;
9970
}
9971
case 1: // variable
9972
{
9973
var v = new cr.eventvariable(this, parent, m);
9974
cr.seal(v);
9975
nontriggers.push(v);
9976
break;
9977
}
9978
case 2: // include
9979
{
9980
var inc = new cr.eventinclude(this, parent, m);
9981
cr.seal(inc);
9982
nontriggers.push(inc);
9983
break;
9984
}
9985
default:
9986
;
9987
}
9988
};
9989
EventSheet.prototype.postInit = function ()
9990
{
9991
var i, len;
9992
for (i = 0, len = this.events.length; i < len; i++)
9993
{
9994
this.events[i].postInit(i < len - 1 && this.events[i + 1].is_else_block);
9995
}
9996
};
9997
EventSheet.prototype.updateDeepIncludes = function ()
9998
{
9999
cr.clearArray(this.deep_includes);
10000
cr.clearArray(this.already_included_sheets);
10001
this.addDeepIncludes(this);
10002
cr.clearArray(this.already_included_sheets);
10003
};
10004
EventSheet.prototype.addDeepIncludes = function (root_sheet)
10005
{
10006
var i, len, inc, sheet;
10007
var deep_includes = root_sheet.deep_includes;
10008
var already_included_sheets = root_sheet.already_included_sheets;
10009
var arr = this.includes.valuesRef();
10010
for (i = 0, len = arr.length; i < len; ++i)
10011
{
10012
inc = arr[i];
10013
sheet = inc.include_sheet;
10014
if (!inc.isActive() || root_sheet === sheet || already_included_sheets.indexOf(sheet) > -1)
10015
continue;
10016
already_included_sheets.push(sheet);
10017
sheet.addDeepIncludes(root_sheet);
10018
deep_includes.push(sheet);
10019
}
10020
};
10021
EventSheet.prototype.run = function (from_include)
10022
{
10023
if (!this.runtime.resuming_breakpoint)
10024
{
10025
this.hasRun = true;
10026
if (!from_include)
10027
this.runtime.isRunningEvents = true;
10028
}
10029
var i, len;
10030
for (i = 0, len = this.events.length; i < len; i++)
10031
{
10032
var ev = this.events[i];
10033
ev.run();
10034
this.runtime.clearSol(ev.solModifiers);
10035
if (this.runtime.hasPendingInstances)
10036
this.runtime.ClearDeathRow();
10037
}
10038
if (!from_include)
10039
this.runtime.isRunningEvents = false;
10040
};
10041
function isPerformanceSensitiveTrigger(method)
10042
{
10043
if (cr.plugins_.Sprite && method === cr.plugins_.Sprite.prototype.cnds.OnFrameChanged)
10044
{
10045
return true;
10046
}
10047
return false;
10048
};
10049
EventSheet.prototype.init_trigger = function (trig, index)
10050
{
10051
if (!trig.orblock)
10052
this.runtime.triggers_to_postinit.push(trig); // needs to be postInit'd later
10053
var i, len;
10054
var cnd = trig.conditions[index];
10055
var type_name;
10056
if (cnd.type)
10057
type_name = cnd.type.name;
10058
else
10059
type_name = "system";
10060
var fasttrigger = cnd.fasttrigger;
10061
var triggers = (fasttrigger ? this.fasttriggers : this.triggers);
10062
if (!triggers[type_name])
10063
triggers[type_name] = [];
10064
var obj_entry = triggers[type_name];
10065
var method = cnd.func;
10066
if (fasttrigger)
10067
{
10068
if (!cnd.parameters.length) // no parameters
10069
return;
10070
var firstparam = cnd.parameters[0];
10071
if (firstparam.type !== 1 || // not a string param
10072
firstparam.expression.type !== 2) // not a string literal node
10073
{
10074
return;
10075
}
10076
var fastevs;
10077
var firstvalue = firstparam.expression.value.toLowerCase();
10078
var i, len;
10079
for (i = 0, len = obj_entry.length; i < len; i++)
10080
{
10081
if (obj_entry[i].method == method)
10082
{
10083
fastevs = obj_entry[i].evs;
10084
if (!fastevs[firstvalue])
10085
fastevs[firstvalue] = [[trig, index]];
10086
else
10087
fastevs[firstvalue].push([trig, index]);
10088
return;
10089
}
10090
}
10091
fastevs = {};
10092
fastevs[firstvalue] = [[trig, index]];
10093
obj_entry.push({ method: method, evs: fastevs });
10094
}
10095
else
10096
{
10097
for (i = 0, len = obj_entry.length; i < len; i++)
10098
{
10099
if (obj_entry[i].method == method)
10100
{
10101
obj_entry[i].evs.push([trig, index]);
10102
return;
10103
}
10104
}
10105
if (isPerformanceSensitiveTrigger(method))
10106
obj_entry.unshift({ method: method, evs: [[trig, index]]});
10107
else
10108
obj_entry.push({ method: method, evs: [[trig, index]]});
10109
}
10110
};
10111
cr.eventsheet = EventSheet;
10112
function Selection(type)
10113
{
10114
this.type = type;
10115
this.instances = []; // subset of picked instances
10116
this.else_instances = []; // subset of unpicked instances
10117
this.select_all = true;
10118
};
10119
Selection.prototype.hasObjects = function ()
10120
{
10121
if (this.select_all)
10122
return this.type.instances.length;
10123
else
10124
return this.instances.length;
10125
};
10126
Selection.prototype.getObjects = function ()
10127
{
10128
if (this.select_all)
10129
return this.type.instances;
10130
else
10131
return this.instances;
10132
};
10133
/*
10134
Selection.prototype.ensure_picked = function (inst, skip_siblings)
10135
{
10136
var i, len;
10137
var orblock = inst.runtime.getCurrentEventStack().current_event.orblock;
10138
if (this.select_all)
10139
{
10140
this.select_all = false;
10141
if (orblock)
10142
{
10143
cr.shallowAssignArray(this.else_instances, inst.type.instances);
10144
cr.arrayFindRemove(this.else_instances, inst);
10145
}
10146
this.instances.length = 1;
10147
this.instances[0] = inst;
10148
}
10149
else
10150
{
10151
if (orblock)
10152
{
10153
i = this.else_instances.indexOf(inst);
10154
if (i !== -1)
10155
{
10156
this.instances.push(this.else_instances[i]);
10157
this.else_instances.splice(i, 1);
10158
}
10159
}
10160
else
10161
{
10162
if (this.instances.indexOf(inst) === -1)
10163
this.instances.push(inst);
10164
}
10165
}
10166
if (!skip_siblings)
10167
{
10168
}
10169
};
10170
*/
10171
Selection.prototype.pick_one = function (inst)
10172
{
10173
if (!inst)
10174
return;
10175
if (inst.runtime.getCurrentEventStack().current_event.orblock)
10176
{
10177
if (this.select_all)
10178
{
10179
cr.clearArray(this.instances);
10180
cr.shallowAssignArray(this.else_instances, inst.type.instances);
10181
this.select_all = false;
10182
}
10183
var i = this.else_instances.indexOf(inst);
10184
if (i !== -1)
10185
{
10186
this.instances.push(this.else_instances[i]);
10187
this.else_instances.splice(i, 1);
10188
}
10189
}
10190
else
10191
{
10192
this.select_all = false;
10193
cr.clearArray(this.instances);
10194
this.instances[0] = inst;
10195
}
10196
};
10197
cr.selection = Selection;
10198
function EventBlock(sheet, parent, m)
10199
{
10200
this.sheet = sheet;
10201
this.parent = parent;
10202
this.runtime = sheet.runtime;
10203
this.solModifiers = [];
10204
this.solModifiersIncludingParents = [];
10205
this.solWriterAfterCnds = false; // block does not change SOL after running its conditions
10206
this.group = false; // is group of events
10207
this.initially_activated = false; // if a group, is active on startup
10208
this.toplevelevent = false; // is an event block parented only by a top-level group
10209
this.toplevelgroup = false; // is parented only by other groups or is top-level (i.e. not in a subevent)
10210
this.has_else_block = false; // is followed by else
10211
;
10212
this.conditions = [];
10213
this.actions = [];
10214
this.subevents = [];
10215
this.group_name = "";
10216
this.group = false;
10217
this.initially_activated = false;
10218
this.group_active = false;
10219
this.contained_includes = null;
10220
if (m[1])
10221
{
10222
this.group_name = m[1][1].toLowerCase();
10223
this.group = true;
10224
this.initially_activated = !!m[1][0];
10225
this.contained_includes = [];
10226
this.group_active = this.initially_activated;
10227
this.runtime.allGroups.push(this);
10228
this.runtime.groups_by_name[this.group_name] = this;
10229
}
10230
this.orblock = m[2];
10231
this.sid = m[4];
10232
if (!this.group)
10233
this.runtime.blocksBySid[this.sid.toString()] = this;
10234
var i, len;
10235
var cm = m[5];
10236
for (i = 0, len = cm.length; i < len; i++)
10237
{
10238
var cnd = new cr.condition(this, cm[i]);
10239
cnd.index = i;
10240
cr.seal(cnd);
10241
this.conditions.push(cnd);
10242
/*
10243
if (cnd.is_logical())
10244
this.is_logical = true;
10245
if (cnd.type && !cnd.type.plugin.singleglobal && this.cndReferences.indexOf(cnd.type) === -1)
10246
this.cndReferences.push(cnd.type);
10247
*/
10248
this.addSolModifier(cnd.type);
10249
}
10250
var am = m[6];
10251
for (i = 0, len = am.length; i < len; i++)
10252
{
10253
var act = new cr.action(this, am[i]);
10254
act.index = i;
10255
cr.seal(act);
10256
this.actions.push(act);
10257
}
10258
if (m.length === 8)
10259
{
10260
var em = m[7];
10261
for (i = 0, len = em.length; i < len; i++)
10262
this.sheet.init_event(em[i], this, this.subevents);
10263
}
10264
this.is_else_block = false;
10265
if (this.conditions.length)
10266
{
10267
this.is_else_block = (this.conditions[0].type == null && this.conditions[0].func == cr.system_object.prototype.cnds.Else);
10268
}
10269
};
10270
window["_c2hh_"] = "9B8E65E8653E4C80672958512A488E29C3DF5E90";
10271
EventBlock.prototype.postInit = function (hasElse/*, prevBlock_*/)
10272
{
10273
var i, len;
10274
var p = this.parent;
10275
if (this.group)
10276
{
10277
this.toplevelgroup = true;
10278
while (p)
10279
{
10280
if (!p.group)
10281
{
10282
this.toplevelgroup = false;
10283
break;
10284
}
10285
p = p.parent;
10286
}
10287
}
10288
this.toplevelevent = !this.is_trigger() && (!this.parent || (this.parent.group && this.parent.toplevelgroup));
10289
this.has_else_block = !!hasElse;
10290
this.solModifiersIncludingParents = this.solModifiers.slice(0);
10291
p = this.parent;
10292
while (p)
10293
{
10294
for (i = 0, len = p.solModifiers.length; i < len; i++)
10295
this.addParentSolModifier(p.solModifiers[i]);
10296
p = p.parent;
10297
}
10298
this.solModifiers = findMatchingSolModifier(this.solModifiers);
10299
this.solModifiersIncludingParents = findMatchingSolModifier(this.solModifiersIncludingParents);
10300
var i, len/*, s*/;
10301
for (i = 0, len = this.conditions.length; i < len; i++)
10302
this.conditions[i].postInit();
10303
for (i = 0, len = this.actions.length; i < len; i++)
10304
this.actions[i].postInit();
10305
for (i = 0, len = this.subevents.length; i < len; i++)
10306
{
10307
this.subevents[i].postInit(i < len - 1 && this.subevents[i + 1].is_else_block);
10308
}
10309
/*
10310
if (this.is_else_block && this.prev_block)
10311
{
10312
for (i = 0, len = this.prev_block.solModifiers.length; i < len; i++)
10313
{
10314
s = this.prev_block.solModifiers[i];
10315
if (this.solModifiers.indexOf(s) === -1)
10316
this.solModifiers.push(s);
10317
}
10318
}
10319
*/
10320
};
10321
EventBlock.prototype.setGroupActive = function (a)
10322
{
10323
if (this.group_active === !!a)
10324
return; // same state
10325
this.group_active = !!a;
10326
var i, len;
10327
for (i = 0, len = this.contained_includes.length; i < len; ++i)
10328
{
10329
this.contained_includes[i].updateActive();
10330
}
10331
if (len > 0 && this.runtime.running_layout.event_sheet)
10332
this.runtime.running_layout.event_sheet.updateDeepIncludes();
10333
};
10334
function addSolModifierToList(type, arr)
10335
{
10336
var i, len, t;
10337
if (!type)
10338
return;
10339
if (arr.indexOf(type) === -1)
10340
arr.push(type);
10341
if (type.is_contained)
10342
{
10343
for (i = 0, len = type.container.length; i < len; i++)
10344
{
10345
t = type.container[i];
10346
if (type === t)
10347
continue; // already handled
10348
if (arr.indexOf(t) === -1)
10349
arr.push(t);
10350
}
10351
}
10352
};
10353
EventBlock.prototype.addSolModifier = function (type)
10354
{
10355
addSolModifierToList(type, this.solModifiers);
10356
};
10357
EventBlock.prototype.addParentSolModifier = function (type)
10358
{
10359
addSolModifierToList(type, this.solModifiersIncludingParents);
10360
};
10361
EventBlock.prototype.setSolWriterAfterCnds = function ()
10362
{
10363
this.solWriterAfterCnds = true;
10364
if (this.parent)
10365
this.parent.setSolWriterAfterCnds();
10366
};
10367
EventBlock.prototype.is_trigger = function ()
10368
{
10369
if (!this.conditions.length) // no conditions
10370
return false;
10371
else
10372
return this.conditions[0].trigger;
10373
};
10374
EventBlock.prototype.run = function ()
10375
{
10376
var i, len, c, any_true = false, cnd_result;
10377
var runtime = this.runtime;
10378
var evinfo = this.runtime.getCurrentEventStack();
10379
evinfo.current_event = this;
10380
var conditions = this.conditions;
10381
if (!this.is_else_block)
10382
evinfo.else_branch_ran = false;
10383
if (this.orblock)
10384
{
10385
if (conditions.length === 0)
10386
any_true = true; // be sure to run if empty block
10387
evinfo.cndindex = 0
10388
for (len = conditions.length; evinfo.cndindex < len; evinfo.cndindex++)
10389
{
10390
c = conditions[evinfo.cndindex];
10391
if (c.trigger) // skip triggers when running OR block
10392
continue;
10393
cnd_result = c.run();
10394
if (cnd_result) // make sure all conditions run and run if any were true
10395
any_true = true;
10396
}
10397
evinfo.last_event_true = any_true;
10398
if (any_true)
10399
this.run_actions_and_subevents();
10400
}
10401
else
10402
{
10403
evinfo.cndindex = 0
10404
for (len = conditions.length; evinfo.cndindex < len; evinfo.cndindex++)
10405
{
10406
cnd_result = conditions[evinfo.cndindex].run();
10407
if (!cnd_result) // condition failed
10408
{
10409
evinfo.last_event_true = false;
10410
if (this.toplevelevent && runtime.hasPendingInstances)
10411
runtime.ClearDeathRow();
10412
return; // bail out now
10413
}
10414
}
10415
evinfo.last_event_true = true;
10416
this.run_actions_and_subevents();
10417
}
10418
this.end_run(evinfo);
10419
};
10420
EventBlock.prototype.end_run = function (evinfo)
10421
{
10422
if (evinfo.last_event_true && this.has_else_block)
10423
evinfo.else_branch_ran = true;
10424
if (this.toplevelevent && this.runtime.hasPendingInstances)
10425
this.runtime.ClearDeathRow();
10426
};
10427
EventBlock.prototype.run_orblocktrigger = function (index)
10428
{
10429
var evinfo = this.runtime.getCurrentEventStack();
10430
evinfo.current_event = this;
10431
if (this.conditions[index].run())
10432
{
10433
this.run_actions_and_subevents();
10434
this.runtime.getCurrentEventStack().last_event_true = true;
10435
}
10436
};
10437
EventBlock.prototype.run_actions_and_subevents = function ()
10438
{
10439
var evinfo = this.runtime.getCurrentEventStack();
10440
var len;
10441
for (evinfo.actindex = 0, len = this.actions.length; evinfo.actindex < len; evinfo.actindex++)
10442
{
10443
if (this.actions[evinfo.actindex].run())
10444
return;
10445
}
10446
this.run_subevents();
10447
};
10448
EventBlock.prototype.resume_actions_and_subevents = function ()
10449
{
10450
var evinfo = this.runtime.getCurrentEventStack();
10451
var len;
10452
for (len = this.actions.length; evinfo.actindex < len; evinfo.actindex++)
10453
{
10454
if (this.actions[evinfo.actindex].run())
10455
return;
10456
}
10457
this.run_subevents();
10458
};
10459
EventBlock.prototype.run_subevents = function ()
10460
{
10461
if (!this.subevents.length)
10462
return;
10463
var i, len, subev, pushpop/*, skipped_pop = false, pop_modifiers = null*/;
10464
var last = this.subevents.length - 1;
10465
this.runtime.pushEventStack(this);
10466
if (this.solWriterAfterCnds)
10467
{
10468
for (i = 0, len = this.subevents.length; i < len; i++)
10469
{
10470
subev = this.subevents[i];
10471
pushpop = (!this.toplevelgroup || (!this.group && i < last));
10472
if (pushpop)
10473
this.runtime.pushCopySol(subev.solModifiers);
10474
subev.run();
10475
if (pushpop)
10476
this.runtime.popSol(subev.solModifiers);
10477
else
10478
this.runtime.clearSol(subev.solModifiers);
10479
}
10480
}
10481
else
10482
{
10483
for (i = 0, len = this.subevents.length; i < len; i++)
10484
{
10485
this.subevents[i].run();
10486
}
10487
}
10488
this.runtime.popEventStack();
10489
};
10490
EventBlock.prototype.run_pretrigger = function ()
10491
{
10492
var evinfo = this.runtime.getCurrentEventStack();
10493
evinfo.current_event = this;
10494
var any_true = false;
10495
var i, len;
10496
for (evinfo.cndindex = 0, len = this.conditions.length; evinfo.cndindex < len; evinfo.cndindex++)
10497
{
10498
;
10499
if (this.conditions[evinfo.cndindex].run())
10500
any_true = true;
10501
else if (!this.orblock) // condition failed (let OR blocks run all conditions anyway)
10502
return false; // bail out
10503
}
10504
return this.orblock ? any_true : true;
10505
};
10506
EventBlock.prototype.retrigger = function ()
10507
{
10508
this.runtime.execcount++;
10509
var prevcndindex = this.runtime.getCurrentEventStack().cndindex;
10510
var len;
10511
var evinfo = this.runtime.pushEventStack(this);
10512
if (!this.orblock)
10513
{
10514
for (evinfo.cndindex = prevcndindex + 1, len = this.conditions.length; evinfo.cndindex < len; evinfo.cndindex++)
10515
{
10516
if (!this.conditions[evinfo.cndindex].run()) // condition failed
10517
{
10518
this.runtime.popEventStack(); // moving up level of recursion
10519
return false; // bail out
10520
}
10521
}
10522
}
10523
this.run_actions_and_subevents();
10524
this.runtime.popEventStack();
10525
return true; // ran an iteration
10526
};
10527
EventBlock.prototype.isFirstConditionOfType = function (cnd)
10528
{
10529
var cndindex = cnd.index;
10530
if (cndindex === 0)
10531
return true;
10532
--cndindex;
10533
for ( ; cndindex >= 0; --cndindex)
10534
{
10535
if (this.conditions[cndindex].type === cnd.type)
10536
return false;
10537
}
10538
return true;
10539
};
10540
cr.eventblock = EventBlock;
10541
function Condition(block, m)
10542
{
10543
this.block = block;
10544
this.sheet = block.sheet;
10545
this.runtime = block.runtime;
10546
this.parameters = [];
10547
this.results = [];
10548
this.extra = {}; // for plugins to stow away some custom info
10549
this.index = -1;
10550
this.anyParamVariesPerInstance = false;
10551
this.func = this.runtime.GetObjectReference(m[1]);
10552
;
10553
this.trigger = (m[3] > 0);
10554
this.fasttrigger = (m[3] === 2);
10555
this.looping = m[4];
10556
this.inverted = m[5];
10557
this.isstatic = m[6];
10558
this.sid = m[7];
10559
this.runtime.cndsBySid[this.sid.toString()] = this;
10560
if (m[0] === -1) // system object
10561
{
10562
this.type = null;
10563
this.run = this.run_system;
10564
this.behaviortype = null;
10565
this.beh_index = -1;
10566
}
10567
else
10568
{
10569
this.type = this.runtime.types_by_index[m[0]];
10570
;
10571
if (this.isstatic)
10572
this.run = this.run_static;
10573
else
10574
this.run = this.run_object;
10575
if (m[2])
10576
{
10577
this.behaviortype = this.type.getBehaviorByName(m[2]);
10578
;
10579
this.beh_index = this.type.getBehaviorIndexByName(m[2]);
10580
;
10581
}
10582
else
10583
{
10584
this.behaviortype = null;
10585
this.beh_index = -1;
10586
}
10587
if (this.block.parent)
10588
this.block.parent.setSolWriterAfterCnds();
10589
}
10590
if (this.fasttrigger)
10591
this.run = this.run_true;
10592
if (m.length === 10)
10593
{
10594
var i, len;
10595
var em = m[9];
10596
for (i = 0, len = em.length; i < len; i++)
10597
{
10598
var param = new cr.parameter(this, em[i]);
10599
cr.seal(param);
10600
this.parameters.push(param);
10601
}
10602
this.results.length = em.length;
10603
}
10604
};
10605
Condition.prototype.postInit = function ()
10606
{
10607
var i, len, p;
10608
for (i = 0, len = this.parameters.length; i < len; i++)
10609
{
10610
p = this.parameters[i];
10611
p.postInit();
10612
if (p.variesPerInstance)
10613
this.anyParamVariesPerInstance = true;
10614
}
10615
};
10616
/*
10617
Condition.prototype.is_logical = function ()
10618
{
10619
return !this.type || this.type.plugin.singleglobal;
10620
};
10621
*/
10622
Condition.prototype.run_true = function ()
10623
{
10624
return true;
10625
};
10626
Condition.prototype.run_system = function ()
10627
{
10628
var i, len;
10629
for (i = 0, len = this.parameters.length; i < len; i++)
10630
this.results[i] = this.parameters[i].get();
10631
return cr.xor(this.func.apply(this.runtime.system, this.results), this.inverted);
10632
};
10633
Condition.prototype.run_static = function ()
10634
{
10635
var i, len;
10636
for (i = 0, len = this.parameters.length; i < len; i++)
10637
this.results[i] = this.parameters[i].get();
10638
var ret = this.func.apply(this.behaviortype ? this.behaviortype : this.type, this.results);
10639
this.type.applySolToContainer();
10640
return ret;
10641
};
10642
Condition.prototype.run_object = function ()
10643
{
10644
var i, j, k, leni, lenj, p, ret, met, inst, s, sol2;
10645
var type = this.type;
10646
var sol = type.getCurrentSol();
10647
var is_orblock = this.block.orblock && !this.trigger; // triggers in OR blocks need to work normally
10648
var offset = 0;
10649
var is_contained = type.is_contained;
10650
var is_family = type.is_family;
10651
var family_index = type.family_index;
10652
var beh_index = this.beh_index;
10653
var is_beh = (beh_index > -1);
10654
var params_vary = this.anyParamVariesPerInstance;
10655
var parameters = this.parameters;
10656
var results = this.results;
10657
var inverted = this.inverted;
10658
var func = this.func;
10659
var arr, container;
10660
if (params_vary)
10661
{
10662
for (j = 0, lenj = parameters.length; j < lenj; ++j)
10663
{
10664
p = parameters[j];
10665
if (!p.variesPerInstance)
10666
results[j] = p.get(0);
10667
}
10668
}
10669
else
10670
{
10671
for (j = 0, lenj = parameters.length; j < lenj; ++j)
10672
results[j] = parameters[j].get(0);
10673
}
10674
if (sol.select_all) {
10675
cr.clearArray(sol.instances); // clear contents
10676
cr.clearArray(sol.else_instances);
10677
arr = type.instances;
10678
for (i = 0, leni = arr.length; i < leni; ++i)
10679
{
10680
inst = arr[i];
10681
;
10682
if (params_vary)
10683
{
10684
for (j = 0, lenj = parameters.length; j < lenj; ++j)
10685
{
10686
p = parameters[j];
10687
if (p.variesPerInstance)
10688
results[j] = p.get(i); // default SOL index is current object
10689
}
10690
}
10691
if (is_beh)
10692
{
10693
offset = 0;
10694
if (is_family)
10695
{
10696
offset = inst.type.family_beh_map[family_index];
10697
}
10698
ret = func.apply(inst.behavior_insts[beh_index + offset], results);
10699
}
10700
else
10701
ret = func.apply(inst, results);
10702
met = cr.xor(ret, inverted);
10703
if (met)
10704
sol.instances.push(inst);
10705
else if (is_orblock) // in OR blocks, keep the instances not meeting the condition for subsequent testing
10706
sol.else_instances.push(inst);
10707
}
10708
if (type.finish)
10709
type.finish(true);
10710
sol.select_all = false;
10711
type.applySolToContainer();
10712
return sol.hasObjects();
10713
}
10714
else {
10715
k = 0;
10716
var using_else_instances = (is_orblock && !this.block.isFirstConditionOfType(this));
10717
arr = (using_else_instances ? sol.else_instances : sol.instances);
10718
var any_true = false;
10719
for (i = 0, leni = arr.length; i < leni; ++i)
10720
{
10721
inst = arr[i];
10722
;
10723
if (params_vary)
10724
{
10725
for (j = 0, lenj = parameters.length; j < lenj; ++j)
10726
{
10727
p = parameters[j];
10728
if (p.variesPerInstance)
10729
results[j] = p.get(i); // default SOL index is current object
10730
}
10731
}
10732
if (is_beh)
10733
{
10734
offset = 0;
10735
if (is_family)
10736
{
10737
offset = inst.type.family_beh_map[family_index];
10738
}
10739
ret = func.apply(inst.behavior_insts[beh_index + offset], results);
10740
}
10741
else
10742
ret = func.apply(inst, results);
10743
if (cr.xor(ret, inverted))
10744
{
10745
any_true = true;
10746
if (using_else_instances)
10747
{
10748
sol.instances.push(inst);
10749
if (is_contained)
10750
{
10751
for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
10752
{
10753
s = inst.siblings[j];
10754
s.type.getCurrentSol().instances.push(s);
10755
}
10756
}
10757
}
10758
else
10759
{
10760
arr[k] = inst;
10761
if (is_contained)
10762
{
10763
for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
10764
{
10765
s = inst.siblings[j];
10766
s.type.getCurrentSol().instances[k] = s;
10767
}
10768
}
10769
k++;
10770
}
10771
}
10772
else
10773
{
10774
if (using_else_instances)
10775
{
10776
arr[k] = inst;
10777
if (is_contained)
10778
{
10779
for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
10780
{
10781
s = inst.siblings[j];
10782
s.type.getCurrentSol().else_instances[k] = s;
10783
}
10784
}
10785
k++;
10786
}
10787
else if (is_orblock)
10788
{
10789
sol.else_instances.push(inst);
10790
if (is_contained)
10791
{
10792
for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
10793
{
10794
s = inst.siblings[j];
10795
s.type.getCurrentSol().else_instances.push(s);
10796
}
10797
}
10798
}
10799
}
10800
}
10801
cr.truncateArray(arr, k);
10802
if (is_contained)
10803
{
10804
container = type.container;
10805
for (i = 0, leni = container.length; i < leni; i++)
10806
{
10807
sol2 = container[i].getCurrentSol();
10808
if (using_else_instances)
10809
cr.truncateArray(sol2.else_instances, k);
10810
else
10811
cr.truncateArray(sol2.instances, k);
10812
}
10813
}
10814
var pick_in_finish = any_true; // don't pick in finish() if we're only doing the logic test below
10815
if (using_else_instances && !any_true)
10816
{
10817
for (i = 0, leni = sol.instances.length; i < leni; i++)
10818
{
10819
inst = sol.instances[i];
10820
if (params_vary)
10821
{
10822
for (j = 0, lenj = parameters.length; j < lenj; j++)
10823
{
10824
p = parameters[j];
10825
if (p.variesPerInstance)
10826
results[j] = p.get(i);
10827
}
10828
}
10829
if (is_beh)
10830
ret = func.apply(inst.behavior_insts[beh_index], results);
10831
else
10832
ret = func.apply(inst, results);
10833
if (cr.xor(ret, inverted))
10834
{
10835
any_true = true;
10836
break; // got our flag, don't need to test any more
10837
}
10838
}
10839
}
10840
if (type.finish)
10841
type.finish(pick_in_finish || is_orblock);
10842
return is_orblock ? any_true : sol.hasObjects();
10843
}
10844
};
10845
cr.condition = Condition;
10846
function Action(block, m)
10847
{
10848
this.block = block;
10849
this.sheet = block.sheet;
10850
this.runtime = block.runtime;
10851
this.parameters = [];
10852
this.results = [];
10853
this.extra = {}; // for plugins to stow away some custom info
10854
this.index = -1;
10855
this.anyParamVariesPerInstance = false;
10856
this.func = this.runtime.GetObjectReference(m[1]);
10857
;
10858
if (m[0] === -1) // system
10859
{
10860
this.type = null;
10861
this.run = this.run_system;
10862
this.behaviortype = null;
10863
this.beh_index = -1;
10864
}
10865
else
10866
{
10867
this.type = this.runtime.types_by_index[m[0]];
10868
;
10869
this.run = this.run_object;
10870
if (m[2])
10871
{
10872
this.behaviortype = this.type.getBehaviorByName(m[2]);
10873
;
10874
this.beh_index = this.type.getBehaviorIndexByName(m[2]);
10875
;
10876
}
10877
else
10878
{
10879
this.behaviortype = null;
10880
this.beh_index = -1;
10881
}
10882
}
10883
this.sid = m[3];
10884
this.runtime.actsBySid[this.sid.toString()] = this;
10885
if (m.length === 6)
10886
{
10887
var i, len;
10888
var em = m[5];
10889
for (i = 0, len = em.length; i < len; i++)
10890
{
10891
var param = new cr.parameter(this, em[i]);
10892
cr.seal(param);
10893
this.parameters.push(param);
10894
}
10895
this.results.length = em.length;
10896
}
10897
};
10898
Action.prototype.postInit = function ()
10899
{
10900
var i, len, p;
10901
for (i = 0, len = this.parameters.length; i < len; i++)
10902
{
10903
p = this.parameters[i];
10904
p.postInit();
10905
if (p.variesPerInstance)
10906
this.anyParamVariesPerInstance = true;
10907
}
10908
};
10909
Action.prototype.run_system = function ()
10910
{
10911
var runtime = this.runtime;
10912
var i, len;
10913
var parameters = this.parameters;
10914
var results = this.results;
10915
for (i = 0, len = parameters.length; i < len; ++i)
10916
results[i] = parameters[i].get();
10917
return this.func.apply(runtime.system, results);
10918
};
10919
Action.prototype.run_object = function ()
10920
{
10921
var type = this.type;
10922
var beh_index = this.beh_index;
10923
var family_index = type.family_index;
10924
var params_vary = this.anyParamVariesPerInstance;
10925
var parameters = this.parameters;
10926
var results = this.results;
10927
var func = this.func;
10928
var instances = type.getCurrentSol().getObjects();
10929
var is_family = type.is_family;
10930
var is_beh = (beh_index > -1);
10931
var i, j, leni, lenj, p, inst, offset;
10932
if (params_vary)
10933
{
10934
for (j = 0, lenj = parameters.length; j < lenj; ++j)
10935
{
10936
p = parameters[j];
10937
if (!p.variesPerInstance)
10938
results[j] = p.get(0);
10939
}
10940
}
10941
else
10942
{
10943
for (j = 0, lenj = parameters.length; j < lenj; ++j)
10944
results[j] = parameters[j].get(0);
10945
}
10946
for (i = 0, leni = instances.length; i < leni; ++i)
10947
{
10948
inst = instances[i];
10949
if (params_vary)
10950
{
10951
for (j = 0, lenj = parameters.length; j < lenj; ++j)
10952
{
10953
p = parameters[j];
10954
if (p.variesPerInstance)
10955
results[j] = p.get(i); // pass i to use as default SOL index
10956
}
10957
}
10958
if (is_beh)
10959
{
10960
offset = 0;
10961
if (is_family)
10962
{
10963
offset = inst.type.family_beh_map[family_index];
10964
}
10965
func.apply(inst.behavior_insts[beh_index + offset], results);
10966
}
10967
else
10968
func.apply(inst, results);
10969
}
10970
return false;
10971
};
10972
cr.action = Action;
10973
var tempValues = [];
10974
var tempValuesPtr = -1;
10975
function pushTempValue()
10976
{
10977
tempValuesPtr++;
10978
if (tempValues.length === tempValuesPtr)
10979
tempValues.push(new cr.expvalue());
10980
return tempValues[tempValuesPtr];
10981
};
10982
function popTempValue()
10983
{
10984
tempValuesPtr--;
10985
};
10986
function Parameter(owner, m)
10987
{
10988
this.owner = owner;
10989
this.block = owner.block;
10990
this.sheet = owner.sheet;
10991
this.runtime = owner.runtime;
10992
this.type = m[0];
10993
this.expression = null;
10994
this.solindex = 0;
10995
this.get = null;
10996
this.combosel = 0;
10997
this.layout = null;
10998
this.key = 0;
10999
this.object = null;
11000
this.index = 0;
11001
this.varname = null;
11002
this.eventvar = null;
11003
this.fileinfo = null;
11004
this.subparams = null;
11005
this.variadicret = null;
11006
this.subparams = null;
11007
this.variadicret = null;
11008
this.variesPerInstance = false;
11009
var i, len, param;
11010
switch (m[0])
11011
{
11012
case 0: // number
11013
case 7: // any
11014
this.expression = new cr.expNode(this, m[1]);
11015
this.solindex = 0;
11016
this.get = this.get_exp;
11017
break;
11018
case 1: // string
11019
this.expression = new cr.expNode(this, m[1]);
11020
this.solindex = 0;
11021
this.get = this.get_exp_str;
11022
break;
11023
case 5: // layer
11024
this.expression = new cr.expNode(this, m[1]);
11025
this.solindex = 0;
11026
this.get = this.get_layer;
11027
break;
11028
case 3: // combo
11029
case 8: // cmp
11030
this.combosel = m[1];
11031
this.get = this.get_combosel;
11032
break;
11033
case 6: // layout
11034
this.layout = this.runtime.layouts[m[1]];
11035
;
11036
this.get = this.get_layout;
11037
break;
11038
case 9: // keyb
11039
this.key = m[1];
11040
this.get = this.get_key;
11041
break;
11042
case 4: // object
11043
this.object = this.runtime.types_by_index[m[1]];
11044
;
11045
this.get = this.get_object;
11046
this.block.addSolModifier(this.object);
11047
if (this.owner instanceof cr.action)
11048
this.block.setSolWriterAfterCnds();
11049
else if (this.block.parent)
11050
this.block.parent.setSolWriterAfterCnds();
11051
break;
11052
case 10: // instvar
11053
this.index = m[1];
11054
if (owner.type && owner.type.is_family)
11055
{
11056
this.get = this.get_familyvar;
11057
this.variesPerInstance = true;
11058
}
11059
else
11060
this.get = this.get_instvar;
11061
break;
11062
case 11: // eventvar
11063
this.varname = m[1];
11064
this.eventvar = null;
11065
this.get = this.get_eventvar;
11066
break;
11067
case 2: // audiofile ["name", ismusic]
11068
case 12: // fileinfo "name"
11069
this.fileinfo = m[1];
11070
this.get = this.get_audiofile;
11071
break;
11072
case 13: // variadic
11073
this.get = this.get_variadic;
11074
this.subparams = [];
11075
this.variadicret = [];
11076
for (i = 1, len = m.length; i < len; i++)
11077
{
11078
param = new cr.parameter(this.owner, m[i]);
11079
cr.seal(param);
11080
this.subparams.push(param);
11081
this.variadicret.push(0);
11082
}
11083
break;
11084
default:
11085
;
11086
}
11087
};
11088
Parameter.prototype.postInit = function ()
11089
{
11090
var i, len;
11091
if (this.type === 11) // eventvar
11092
{
11093
this.eventvar = this.runtime.getEventVariableByName(this.varname, this.block.parent);
11094
;
11095
}
11096
else if (this.type === 13) // variadic, postInit all sub-params
11097
{
11098
for (i = 0, len = this.subparams.length; i < len; i++)
11099
this.subparams[i].postInit();
11100
}
11101
if (this.expression)
11102
this.expression.postInit();
11103
};
11104
Parameter.prototype.maybeVaryForType = function (t)
11105
{
11106
if (this.variesPerInstance)
11107
return; // already varies per instance, no need to check again
11108
if (!t)
11109
return; // never vary for system type
11110
if (!t.plugin.singleglobal)
11111
{
11112
this.variesPerInstance = true;
11113
return;
11114
}
11115
};
11116
Parameter.prototype.setVaries = function ()
11117
{
11118
this.variesPerInstance = true;
11119
};
11120
Parameter.prototype.get_exp = function (solindex)
11121
{
11122
this.solindex = solindex || 0; // default SOL index to use
11123
var temp = pushTempValue();
11124
this.expression.get(temp);
11125
popTempValue();
11126
return temp.data; // return actual JS value, not expvalue
11127
};
11128
Parameter.prototype.get_exp_str = function (solindex)
11129
{
11130
this.solindex = solindex || 0; // default SOL index to use
11131
var temp = pushTempValue();
11132
this.expression.get(temp);
11133
popTempValue();
11134
if (cr.is_string(temp.data))
11135
return temp.data;
11136
else
11137
return "";
11138
};
11139
Parameter.prototype.get_object = function ()
11140
{
11141
return this.object;
11142
};
11143
Parameter.prototype.get_combosel = function ()
11144
{
11145
return this.combosel;
11146
};
11147
Parameter.prototype.get_layer = function (solindex)
11148
{
11149
this.solindex = solindex || 0; // default SOL index to use
11150
var temp = pushTempValue();
11151
this.expression.get(temp);
11152
popTempValue();
11153
if (temp.is_number())
11154
return this.runtime.getLayerByNumber(temp.data);
11155
else
11156
return this.runtime.getLayerByName(temp.data);
11157
}
11158
Parameter.prototype.get_layout = function ()
11159
{
11160
return this.layout;
11161
};
11162
Parameter.prototype.get_key = function ()
11163
{
11164
return this.key;
11165
};
11166
Parameter.prototype.get_instvar = function ()
11167
{
11168
return this.index;
11169
};
11170
Parameter.prototype.get_familyvar = function (solindex_)
11171
{
11172
var solindex = solindex_ || 0;
11173
var familytype = this.owner.type;
11174
var realtype = null;
11175
var sol = familytype.getCurrentSol();
11176
var objs = sol.getObjects();
11177
if (objs.length)
11178
realtype = objs[solindex % objs.length].type;
11179
else if (sol.else_instances.length)
11180
realtype = sol.else_instances[solindex % sol.else_instances.length].type;
11181
else if (familytype.instances.length)
11182
realtype = familytype.instances[solindex % familytype.instances.length].type;
11183
else
11184
return 0;
11185
return this.index + realtype.family_var_map[familytype.family_index];
11186
};
11187
Parameter.prototype.get_eventvar = function ()
11188
{
11189
return this.eventvar;
11190
};
11191
Parameter.prototype.get_audiofile = function ()
11192
{
11193
return this.fileinfo;
11194
};
11195
Parameter.prototype.get_variadic = function ()
11196
{
11197
var i, len;
11198
for (i = 0, len = this.subparams.length; i < len; i++)
11199
{
11200
this.variadicret[i] = this.subparams[i].get();
11201
}
11202
return this.variadicret;
11203
};
11204
cr.parameter = Parameter;
11205
function EventVariable(sheet, parent, m)
11206
{
11207
this.sheet = sheet;
11208
this.parent = parent;
11209
this.runtime = sheet.runtime;
11210
this.solModifiers = [];
11211
this.name = m[1];
11212
this.vartype = m[2];
11213
this.initial = m[3];
11214
this.is_static = !!m[4];
11215
this.is_constant = !!m[5];
11216
this.sid = m[6];
11217
this.runtime.varsBySid[this.sid.toString()] = this;
11218
this.data = this.initial; // note: also stored in event stack frame for local nonstatic nonconst vars
11219
if (this.parent) // local var
11220
{
11221
if (this.is_static || this.is_constant)
11222
this.localIndex = -1;
11223
else
11224
this.localIndex = this.runtime.stackLocalCount++;
11225
this.runtime.all_local_vars.push(this);
11226
}
11227
else // global var
11228
{
11229
this.localIndex = -1;
11230
this.runtime.all_global_vars.push(this);
11231
}
11232
};
11233
EventVariable.prototype.postInit = function ()
11234
{
11235
this.solModifiers = findMatchingSolModifier(this.solModifiers);
11236
};
11237
EventVariable.prototype.setValue = function (x)
11238
{
11239
;
11240
var lvs = this.runtime.getCurrentLocalVarStack();
11241
if (!this.parent || this.is_static || !lvs)
11242
this.data = x;
11243
else // local nonstatic variable: use event stack to keep value at this level of recursion
11244
{
11245
if (this.localIndex >= lvs.length)
11246
lvs.length = this.localIndex + 1;
11247
lvs[this.localIndex] = x;
11248
}
11249
};
11250
EventVariable.prototype.getValue = function ()
11251
{
11252
var lvs = this.runtime.getCurrentLocalVarStack();
11253
if (!this.parent || this.is_static || !lvs || this.is_constant)
11254
return this.data;
11255
else // local nonstatic variable
11256
{
11257
if (this.localIndex >= lvs.length)
11258
{
11259
return this.initial;
11260
}
11261
if (typeof lvs[this.localIndex] === "undefined")
11262
{
11263
return this.initial;
11264
}
11265
return lvs[this.localIndex];
11266
}
11267
};
11268
EventVariable.prototype.run = function ()
11269
{
11270
if (this.parent && !this.is_static && !this.is_constant)
11271
this.setValue(this.initial);
11272
};
11273
cr.eventvariable = EventVariable;
11274
function EventInclude(sheet, parent, m)
11275
{
11276
this.sheet = sheet;
11277
this.parent = parent;
11278
this.runtime = sheet.runtime;
11279
this.solModifiers = [];
11280
this.include_sheet = null; // determined in postInit
11281
this.include_sheet_name = m[1];
11282
this.active = true;
11283
};
11284
EventInclude.prototype.toString = function ()
11285
{
11286
return "include:" + this.include_sheet.toString();
11287
};
11288
EventInclude.prototype.postInit = function ()
11289
{
11290
this.include_sheet = this.runtime.eventsheets[this.include_sheet_name];
11291
;
11292
;
11293
this.sheet.includes.add(this);
11294
this.solModifiers = findMatchingSolModifier(this.solModifiers);
11295
var p = this.parent;
11296
while (p)
11297
{
11298
if (p.group)
11299
p.contained_includes.push(this);
11300
p = p.parent;
11301
}
11302
this.updateActive();
11303
};
11304
EventInclude.prototype.run = function ()
11305
{
11306
if (this.parent)
11307
this.runtime.pushCleanSol(this.runtime.types_by_index);
11308
if (!this.include_sheet.hasRun)
11309
this.include_sheet.run(true); // from include
11310
if (this.parent)
11311
this.runtime.popSol(this.runtime.types_by_index);
11312
};
11313
EventInclude.prototype.updateActive = function ()
11314
{
11315
var p = this.parent;
11316
while (p)
11317
{
11318
if (p.group && !p.group_active)
11319
{
11320
this.active = false;
11321
return;
11322
}
11323
p = p.parent;
11324
}
11325
this.active = true;
11326
};
11327
EventInclude.prototype.isActive = function ()
11328
{
11329
return this.active;
11330
};
11331
cr.eventinclude = EventInclude;
11332
function EventStackFrame()
11333
{
11334
this.temp_parents_arr = [];
11335
this.reset(null);
11336
cr.seal(this);
11337
};
11338
EventStackFrame.prototype.reset = function (cur_event)
11339
{
11340
this.current_event = cur_event;
11341
this.cndindex = 0;
11342
this.actindex = 0;
11343
cr.clearArray(this.temp_parents_arr);
11344
this.last_event_true = false;
11345
this.else_branch_ran = false;
11346
this.any_true_state = false;
11347
};
11348
EventStackFrame.prototype.isModifierAfterCnds = function ()
11349
{
11350
if (this.current_event.solWriterAfterCnds)
11351
return true;
11352
if (this.cndindex < this.current_event.conditions.length - 1)
11353
return !!this.current_event.solModifiers.length;
11354
return false;
11355
};
11356
cr.eventStackFrame = EventStackFrame;
11357
}());
11358
(function()
11359
{
11360
function ExpNode(owner_, m)
11361
{
11362
this.owner = owner_;
11363
this.runtime = owner_.runtime;
11364
this.type = m[0];
11365
;
11366
this.get = [this.eval_int,
11367
this.eval_float,
11368
this.eval_string,
11369
this.eval_unaryminus,
11370
this.eval_add,
11371
this.eval_subtract,
11372
this.eval_multiply,
11373
this.eval_divide,
11374
this.eval_mod,
11375
this.eval_power,
11376
this.eval_and,
11377
this.eval_or,
11378
this.eval_equal,
11379
this.eval_notequal,
11380
this.eval_less,
11381
this.eval_lessequal,
11382
this.eval_greater,
11383
this.eval_greaterequal,
11384
this.eval_conditional,
11385
this.eval_system_exp,
11386
this.eval_object_exp,
11387
this.eval_instvar_exp,
11388
this.eval_behavior_exp,
11389
this.eval_eventvar_exp][this.type];
11390
var paramsModel = null;
11391
this.value = null;
11392
this.first = null;
11393
this.second = null;
11394
this.third = null;
11395
this.func = null;
11396
this.results = null;
11397
this.parameters = null;
11398
this.object_type = null;
11399
this.beh_index = -1;
11400
this.instance_expr = null;
11401
this.varindex = -1;
11402
this.behavior_type = null;
11403
this.varname = null;
11404
this.eventvar = null;
11405
this.return_string = false;
11406
switch (this.type) {
11407
case 0: // int
11408
case 1: // float
11409
case 2: // string
11410
this.value = m[1];
11411
break;
11412
case 3: // unaryminus
11413
this.first = new cr.expNode(owner_, m[1]);
11414
break;
11415
case 18: // conditional
11416
this.first = new cr.expNode(owner_, m[1]);
11417
this.second = new cr.expNode(owner_, m[2]);
11418
this.third = new cr.expNode(owner_, m[3]);
11419
break;
11420
case 19: // system_exp
11421
this.func = this.runtime.GetObjectReference(m[1]);
11422
;
11423
if (this.func === cr.system_object.prototype.exps.random
11424
|| this.func === cr.system_object.prototype.exps.choose)
11425
{
11426
this.owner.setVaries();
11427
}
11428
this.results = [];
11429
this.parameters = [];
11430
if (m.length === 3)
11431
{
11432
paramsModel = m[2];
11433
this.results.length = paramsModel.length + 1; // must also fit 'ret'
11434
}
11435
else
11436
this.results.length = 1; // to fit 'ret'
11437
break;
11438
case 20: // object_exp
11439
this.object_type = this.runtime.types_by_index[m[1]];
11440
;
11441
this.beh_index = -1;
11442
this.func = this.runtime.GetObjectReference(m[2]);
11443
this.return_string = m[3];
11444
if (cr.plugins_.Function && this.func === cr.plugins_.Function.prototype.exps.Call)
11445
{
11446
this.owner.setVaries();
11447
}
11448
if (m[4])
11449
this.instance_expr = new cr.expNode(owner_, m[4]);
11450
else
11451
this.instance_expr = null;
11452
this.results = [];
11453
this.parameters = [];
11454
if (m.length === 6)
11455
{
11456
paramsModel = m[5];
11457
this.results.length = paramsModel.length + 1;
11458
}
11459
else
11460
this.results.length = 1; // to fit 'ret'
11461
break;
11462
case 21: // instvar_exp
11463
this.object_type = this.runtime.types_by_index[m[1]];
11464
;
11465
this.return_string = m[2];
11466
if (m[3])
11467
this.instance_expr = new cr.expNode(owner_, m[3]);
11468
else
11469
this.instance_expr = null;
11470
this.varindex = m[4];
11471
break;
11472
case 22: // behavior_exp
11473
this.object_type = this.runtime.types_by_index[m[1]];
11474
;
11475
this.behavior_type = this.object_type.getBehaviorByName(m[2]);
11476
;
11477
this.beh_index = this.object_type.getBehaviorIndexByName(m[2]);
11478
this.func = this.runtime.GetObjectReference(m[3]);
11479
this.return_string = m[4];
11480
if (m[5])
11481
this.instance_expr = new cr.expNode(owner_, m[5]);
11482
else
11483
this.instance_expr = null;
11484
this.results = [];
11485
this.parameters = [];
11486
if (m.length === 7)
11487
{
11488
paramsModel = m[6];
11489
this.results.length = paramsModel.length + 1;
11490
}
11491
else
11492
this.results.length = 1; // to fit 'ret'
11493
break;
11494
case 23: // eventvar_exp
11495
this.varname = m[1];
11496
this.eventvar = null; // assigned in postInit
11497
break;
11498
}
11499
this.owner.maybeVaryForType(this.object_type);
11500
if (this.type >= 4 && this.type <= 17)
11501
{
11502
this.first = new cr.expNode(owner_, m[1]);
11503
this.second = new cr.expNode(owner_, m[2]);
11504
}
11505
if (paramsModel)
11506
{
11507
var i, len;
11508
for (i = 0, len = paramsModel.length; i < len; i++)
11509
this.parameters.push(new cr.expNode(owner_, paramsModel[i]));
11510
}
11511
cr.seal(this);
11512
};
11513
ExpNode.prototype.postInit = function ()
11514
{
11515
if (this.type === 23) // eventvar_exp
11516
{
11517
this.eventvar = this.owner.runtime.getEventVariableByName(this.varname, this.owner.block.parent);
11518
;
11519
}
11520
if (this.first)
11521
this.first.postInit();
11522
if (this.second)
11523
this.second.postInit();
11524
if (this.third)
11525
this.third.postInit();
11526
if (this.instance_expr)
11527
this.instance_expr.postInit();
11528
if (this.parameters)
11529
{
11530
var i, len;
11531
for (i = 0, len = this.parameters.length; i < len; i++)
11532
this.parameters[i].postInit();
11533
}
11534
};
11535
var tempValues = [];
11536
var tempValuesPtr = -1;
11537
function pushTempValue()
11538
{
11539
++tempValuesPtr;
11540
if (tempValues.length === tempValuesPtr)
11541
tempValues.push(new cr.expvalue());
11542
return tempValues[tempValuesPtr];
11543
};
11544
function popTempValue()
11545
{
11546
--tempValuesPtr;
11547
};
11548
function eval_params(parameters, results, temp)
11549
{
11550
var i, len;
11551
for (i = 0, len = parameters.length; i < len; ++i)
11552
{
11553
parameters[i].get(temp);
11554
results[i + 1] = temp.data; // passing actual javascript value as argument instead of expvalue
11555
}
11556
}
11557
ExpNode.prototype.eval_system_exp = function (ret)
11558
{
11559
var parameters = this.parameters;
11560
var results = this.results;
11561
results[0] = ret;
11562
var temp = pushTempValue();
11563
eval_params(parameters, results, temp);
11564
popTempValue();
11565
this.func.apply(this.runtime.system, results);
11566
};
11567
ExpNode.prototype.eval_object_exp = function (ret)
11568
{
11569
var object_type = this.object_type;
11570
var results = this.results;
11571
var parameters = this.parameters;
11572
var instance_expr = this.instance_expr;
11573
var func = this.func;
11574
var index = this.owner.solindex; // default to parameter's intended SOL index
11575
var sol = object_type.getCurrentSol();
11576
var instances = sol.getObjects();
11577
if (!instances.length)
11578
{
11579
if (sol.else_instances.length)
11580
instances = sol.else_instances;
11581
else
11582
{
11583
if (this.return_string)
11584
ret.set_string("");
11585
else
11586
ret.set_int(0);
11587
return;
11588
}
11589
}
11590
results[0] = ret;
11591
ret.object_class = object_type; // so expression can access family type if need be
11592
var temp = pushTempValue();
11593
eval_params(parameters, results, temp);
11594
if (instance_expr) {
11595
instance_expr.get(temp);
11596
if (temp.is_number()) {
11597
index = temp.data;
11598
instances = object_type.instances; // pick from all instances, not SOL
11599
}
11600
}
11601
popTempValue();
11602
var len = instances.length;
11603
if (index >= len || index <= -len)
11604
index %= len; // wraparound
11605
if (index < 0)
11606
index += len;
11607
var returned_val = func.apply(instances[index], results);
11608
;
11609
};
11610
ExpNode.prototype.eval_behavior_exp = function (ret)
11611
{
11612
var object_type = this.object_type;
11613
var results = this.results;
11614
var parameters = this.parameters;
11615
var instance_expr = this.instance_expr;
11616
var beh_index = this.beh_index;
11617
var func = this.func;
11618
var index = this.owner.solindex; // default to parameter's intended SOL index
11619
var sol = object_type.getCurrentSol();
11620
var instances = sol.getObjects();
11621
if (!instances.length)
11622
{
11623
if (sol.else_instances.length)
11624
instances = sol.else_instances;
11625
else
11626
{
11627
if (this.return_string)
11628
ret.set_string("");
11629
else
11630
ret.set_int(0);
11631
return;
11632
}
11633
}
11634
results[0] = ret;
11635
ret.object_class = object_type; // so expression can access family type if need be
11636
var temp = pushTempValue();
11637
eval_params(parameters, results, temp);
11638
if (instance_expr) {
11639
instance_expr.get(temp);
11640
if (temp.is_number()) {
11641
index = temp.data;
11642
instances = object_type.instances; // pick from all instances, not SOL
11643
}
11644
}
11645
popTempValue();
11646
var len = instances.length;
11647
if (index >= len || index <= -len)
11648
index %= len; // wraparound
11649
if (index < 0)
11650
index += len;
11651
var inst = instances[index];
11652
var offset = 0;
11653
if (object_type.is_family)
11654
{
11655
offset = inst.type.family_beh_map[object_type.family_index];
11656
}
11657
var returned_val = func.apply(inst.behavior_insts[beh_index + offset], results);
11658
;
11659
};
11660
ExpNode.prototype.eval_instvar_exp = function (ret)
11661
{
11662
var instance_expr = this.instance_expr;
11663
var object_type = this.object_type;
11664
var varindex = this.varindex;
11665
var index = this.owner.solindex; // default to parameter's intended SOL index
11666
var sol = object_type.getCurrentSol();
11667
var instances = sol.getObjects();
11668
var inst;
11669
if (!instances.length)
11670
{
11671
if (sol.else_instances.length)
11672
instances = sol.else_instances;
11673
else
11674
{
11675
if (this.return_string)
11676
ret.set_string("");
11677
else
11678
ret.set_int(0);
11679
return;
11680
}
11681
}
11682
if (instance_expr)
11683
{
11684
var temp = pushTempValue();
11685
instance_expr.get(temp);
11686
if (temp.is_number())
11687
{
11688
index = temp.data;
11689
var type_instances = object_type.instances;
11690
if (type_instances.length !== 0) // avoid NaN result with %
11691
{
11692
index %= type_instances.length; // wraparound
11693
if (index < 0) // offset
11694
index += type_instances.length;
11695
}
11696
inst = object_type.getInstanceByIID(index);
11697
var to_ret = inst.instance_vars[varindex];
11698
if (cr.is_string(to_ret))
11699
ret.set_string(to_ret);
11700
else
11701
ret.set_float(to_ret);
11702
popTempValue();
11703
return; // done
11704
}
11705
popTempValue();
11706
}
11707
var len = instances.length;
11708
if (index >= len || index <= -len)
11709
index %= len; // wraparound
11710
if (index < 0)
11711
index += len;
11712
inst = instances[index];
11713
var offset = 0;
11714
if (object_type.is_family)
11715
{
11716
offset = inst.type.family_var_map[object_type.family_index];
11717
}
11718
var to_ret = inst.instance_vars[varindex + offset];
11719
if (cr.is_string(to_ret))
11720
ret.set_string(to_ret);
11721
else
11722
ret.set_float(to_ret);
11723
};
11724
ExpNode.prototype.eval_int = function (ret)
11725
{
11726
ret.type = cr.exptype.Integer;
11727
ret.data = this.value;
11728
};
11729
ExpNode.prototype.eval_float = function (ret)
11730
{
11731
ret.type = cr.exptype.Float;
11732
ret.data = this.value;
11733
};
11734
ExpNode.prototype.eval_string = function (ret)
11735
{
11736
ret.type = cr.exptype.String;
11737
ret.data = this.value;
11738
};
11739
ExpNode.prototype.eval_unaryminus = function (ret)
11740
{
11741
this.first.get(ret); // retrieve operand
11742
if (ret.is_number())
11743
ret.data = -ret.data;
11744
};
11745
ExpNode.prototype.eval_add = function (ret)
11746
{
11747
this.first.get(ret); // left operand
11748
var temp = pushTempValue();
11749
this.second.get(temp); // right operand
11750
if (ret.is_number() && temp.is_number())
11751
{
11752
ret.data += temp.data; // both operands numbers: add
11753
if (temp.is_float())
11754
ret.make_float();
11755
}
11756
popTempValue();
11757
};
11758
ExpNode.prototype.eval_subtract = function (ret)
11759
{
11760
this.first.get(ret); // left operand
11761
var temp = pushTempValue();
11762
this.second.get(temp); // right operand
11763
if (ret.is_number() && temp.is_number())
11764
{
11765
ret.data -= temp.data; // both operands numbers: subtract
11766
if (temp.is_float())
11767
ret.make_float();
11768
}
11769
popTempValue();
11770
};
11771
ExpNode.prototype.eval_multiply = function (ret)
11772
{
11773
this.first.get(ret); // left operand
11774
var temp = pushTempValue();
11775
this.second.get(temp); // right operand
11776
if (ret.is_number() && temp.is_number())
11777
{
11778
ret.data *= temp.data; // both operands numbers: multiply
11779
if (temp.is_float())
11780
ret.make_float();
11781
}
11782
popTempValue();
11783
};
11784
ExpNode.prototype.eval_divide = function (ret)
11785
{
11786
this.first.get(ret); // left operand
11787
var temp = pushTempValue();
11788
this.second.get(temp); // right operand
11789
if (ret.is_number() && temp.is_number())
11790
{
11791
ret.data /= temp.data; // both operands numbers: divide
11792
ret.make_float();
11793
}
11794
popTempValue();
11795
};
11796
ExpNode.prototype.eval_mod = function (ret)
11797
{
11798
this.first.get(ret); // left operand
11799
var temp = pushTempValue();
11800
this.second.get(temp); // right operand
11801
if (ret.is_number() && temp.is_number())
11802
{
11803
ret.data %= temp.data; // both operands numbers: modulo
11804
if (temp.is_float())
11805
ret.make_float();
11806
}
11807
popTempValue();
11808
};
11809
ExpNode.prototype.eval_power = function (ret)
11810
{
11811
this.first.get(ret); // left operand
11812
var temp = pushTempValue();
11813
this.second.get(temp); // right operand
11814
if (ret.is_number() && temp.is_number())
11815
{
11816
ret.data = Math.pow(ret.data, temp.data); // both operands numbers: raise to power
11817
if (temp.is_float())
11818
ret.make_float();
11819
}
11820
popTempValue();
11821
};
11822
ExpNode.prototype.eval_and = function (ret)
11823
{
11824
this.first.get(ret); // left operand
11825
var temp = pushTempValue();
11826
this.second.get(temp); // right operand
11827
if (temp.is_string() || ret.is_string())
11828
this.eval_and_stringconcat(ret, temp);
11829
else
11830
this.eval_and_logical(ret, temp);
11831
popTempValue();
11832
};
11833
ExpNode.prototype.eval_and_stringconcat = function (ret, temp)
11834
{
11835
if (ret.is_string() && temp.is_string())
11836
this.eval_and_stringconcat_str_str(ret, temp);
11837
else
11838
this.eval_and_stringconcat_num(ret, temp);
11839
};
11840
ExpNode.prototype.eval_and_stringconcat_str_str = function (ret, temp)
11841
{
11842
ret.data += temp.data;
11843
};
11844
ExpNode.prototype.eval_and_stringconcat_num = function (ret, temp)
11845
{
11846
if (ret.is_string())
11847
{
11848
ret.data += (Math.round(temp.data * 1e10) / 1e10).toString();
11849
}
11850
else
11851
{
11852
ret.set_string(ret.data.toString() + temp.data);
11853
}
11854
};
11855
ExpNode.prototype.eval_and_logical = function (ret, temp)
11856
{
11857
ret.set_int(ret.data && temp.data ? 1 : 0);
11858
};
11859
ExpNode.prototype.eval_or = function (ret)
11860
{
11861
this.first.get(ret); // left operand
11862
var temp = pushTempValue();
11863
this.second.get(temp); // right operand
11864
if (ret.is_number() && temp.is_number())
11865
{
11866
if (ret.data || temp.data)
11867
ret.set_int(1);
11868
else
11869
ret.set_int(0);
11870
}
11871
popTempValue();
11872
};
11873
ExpNode.prototype.eval_conditional = function (ret)
11874
{
11875
this.first.get(ret); // condition operand
11876
if (ret.data) // is true
11877
this.second.get(ret); // evaluate second operand to ret
11878
else
11879
this.third.get(ret); // evaluate third operand to ret
11880
};
11881
ExpNode.prototype.eval_equal = function (ret)
11882
{
11883
this.first.get(ret); // left operand
11884
var temp = pushTempValue();
11885
this.second.get(temp); // right operand
11886
ret.set_int(ret.data === temp.data ? 1 : 0);
11887
popTempValue();
11888
};
11889
ExpNode.prototype.eval_notequal = function (ret)
11890
{
11891
this.first.get(ret); // left operand
11892
var temp = pushTempValue();
11893
this.second.get(temp); // right operand
11894
ret.set_int(ret.data !== temp.data ? 1 : 0);
11895
popTempValue();
11896
};
11897
ExpNode.prototype.eval_less = function (ret)
11898
{
11899
this.first.get(ret); // left operand
11900
var temp = pushTempValue();
11901
this.second.get(temp); // right operand
11902
ret.set_int(ret.data < temp.data ? 1 : 0);
11903
popTempValue();
11904
};
11905
ExpNode.prototype.eval_lessequal = function (ret)
11906
{
11907
this.first.get(ret); // left operand
11908
var temp = pushTempValue();
11909
this.second.get(temp); // right operand
11910
ret.set_int(ret.data <= temp.data ? 1 : 0);
11911
popTempValue();
11912
};
11913
ExpNode.prototype.eval_greater = function (ret)
11914
{
11915
this.first.get(ret); // left operand
11916
var temp = pushTempValue();
11917
this.second.get(temp); // right operand
11918
ret.set_int(ret.data > temp.data ? 1 : 0);
11919
popTempValue();
11920
};
11921
ExpNode.prototype.eval_greaterequal = function (ret)
11922
{
11923
this.first.get(ret); // left operand
11924
var temp = pushTempValue();
11925
this.second.get(temp); // right operand
11926
ret.set_int(ret.data >= temp.data ? 1 : 0);
11927
popTempValue();
11928
};
11929
ExpNode.prototype.eval_eventvar_exp = function (ret)
11930
{
11931
var val = this.eventvar.getValue();
11932
if (cr.is_number(val))
11933
ret.set_float(val);
11934
else
11935
ret.set_string(val);
11936
};
11937
cr.expNode = ExpNode;
11938
function ExpValue(type, data)
11939
{
11940
this.type = type || cr.exptype.Integer;
11941
this.data = data || 0;
11942
this.object_class = null;
11943
;
11944
;
11945
;
11946
if (this.type == cr.exptype.Integer)
11947
this.data = Math.floor(this.data);
11948
cr.seal(this);
11949
};
11950
ExpValue.prototype.is_int = function ()
11951
{
11952
return this.type === cr.exptype.Integer;
11953
};
11954
ExpValue.prototype.is_float = function ()
11955
{
11956
return this.type === cr.exptype.Float;
11957
};
11958
ExpValue.prototype.is_number = function ()
11959
{
11960
return this.type === cr.exptype.Integer || this.type === cr.exptype.Float;
11961
};
11962
ExpValue.prototype.is_string = function ()
11963
{
11964
return this.type === cr.exptype.String;
11965
};
11966
ExpValue.prototype.make_int = function ()
11967
{
11968
if (!this.is_int())
11969
{
11970
if (this.is_float())
11971
this.data = Math.floor(this.data); // truncate float
11972
else if (this.is_string())
11973
this.data = parseInt(this.data, 10);
11974
this.type = cr.exptype.Integer;
11975
}
11976
};
11977
ExpValue.prototype.make_float = function ()
11978
{
11979
if (!this.is_float())
11980
{
11981
if (this.is_string())
11982
this.data = parseFloat(this.data);
11983
this.type = cr.exptype.Float;
11984
}
11985
};
11986
ExpValue.prototype.make_string = function ()
11987
{
11988
if (!this.is_string())
11989
{
11990
this.data = this.data.toString();
11991
this.type = cr.exptype.String;
11992
}
11993
};
11994
ExpValue.prototype.set_int = function (val)
11995
{
11996
;
11997
this.type = cr.exptype.Integer;
11998
this.data = Math.floor(val);
11999
};
12000
ExpValue.prototype.set_float = function (val)
12001
{
12002
;
12003
this.type = cr.exptype.Float;
12004
this.data = val;
12005
};
12006
ExpValue.prototype.set_string = function (val)
12007
{
12008
;
12009
this.type = cr.exptype.String;
12010
this.data = val;
12011
};
12012
ExpValue.prototype.set_any = function (val)
12013
{
12014
if (cr.is_number(val))
12015
{
12016
this.type = cr.exptype.Float;
12017
this.data = val;
12018
}
12019
else if (cr.is_string(val))
12020
{
12021
this.type = cr.exptype.String;
12022
this.data = val.toString();
12023
}
12024
else
12025
{
12026
this.type = cr.exptype.Integer;
12027
this.data = 0;
12028
}
12029
};
12030
cr.expvalue = ExpValue;
12031
cr.exptype = {
12032
Integer: 0, // emulated; no native integer support in javascript
12033
Float: 1,
12034
String: 2
12035
};
12036
}());
12037
;
12038
cr.system_object = function (runtime)
12039
{
12040
this.runtime = runtime;
12041
this.waits = [];
12042
};
12043
cr.system_object.prototype.saveToJSON = function ()
12044
{
12045
var o = {};
12046
var i, len, j, lenj, p, w, t, sobj;
12047
o["waits"] = [];
12048
var owaits = o["waits"];
12049
var waitobj;
12050
for (i = 0, len = this.waits.length; i < len; i++)
12051
{
12052
w = this.waits[i];
12053
waitobj = {
12054
"t": w.time,
12055
"st": w.signaltag,
12056
"s": w.signalled,
12057
"ev": w.ev.sid,
12058
"sm": [],
12059
"sols": {}
12060
};
12061
if (w.ev.actions[w.actindex])
12062
waitobj["act"] = w.ev.actions[w.actindex].sid;
12063
for (j = 0, lenj = w.solModifiers.length; j < lenj; j++)
12064
waitobj["sm"].push(w.solModifiers[j].sid);
12065
for (p in w.sols)
12066
{
12067
if (w.sols.hasOwnProperty(p))
12068
{
12069
t = this.runtime.types_by_index[parseInt(p, 10)];
12070
;
12071
sobj = {
12072
"sa": w.sols[p].sa,
12073
"insts": []
12074
};
12075
for (j = 0, lenj = w.sols[p].insts.length; j < lenj; j++)
12076
sobj["insts"].push(w.sols[p].insts[j].uid);
12077
waitobj["sols"][t.sid.toString()] = sobj;
12078
}
12079
}
12080
owaits.push(waitobj);
12081
}
12082
return o;
12083
};
12084
cr.system_object.prototype.loadFromJSON = function (o)
12085
{
12086
var owaits = o["waits"];
12087
var i, len, j, lenj, p, w, addWait, e, aindex, t, savedsol, nusol, inst;
12088
cr.clearArray(this.waits);
12089
for (i = 0, len = owaits.length; i < len; i++)
12090
{
12091
w = owaits[i];
12092
e = this.runtime.blocksBySid[w["ev"].toString()];
12093
if (!e)
12094
continue; // event must've gone missing
12095
aindex = -1;
12096
for (j = 0, lenj = e.actions.length; j < lenj; j++)
12097
{
12098
if (e.actions[j].sid === w["act"])
12099
{
12100
aindex = j;
12101
break;
12102
}
12103
}
12104
if (aindex === -1)
12105
continue; // action must've gone missing
12106
addWait = {};
12107
addWait.sols = {};
12108
addWait.solModifiers = [];
12109
addWait.deleteme = false;
12110
addWait.time = w["t"];
12111
addWait.signaltag = w["st"] || "";
12112
addWait.signalled = !!w["s"];
12113
addWait.ev = e;
12114
addWait.actindex = aindex;
12115
for (j = 0, lenj = w["sm"].length; j < lenj; j++)
12116
{
12117
t = this.runtime.getObjectTypeBySid(w["sm"][j]);
12118
if (t)
12119
addWait.solModifiers.push(t);
12120
}
12121
for (p in w["sols"])
12122
{
12123
if (w["sols"].hasOwnProperty(p))
12124
{
12125
t = this.runtime.getObjectTypeBySid(parseInt(p, 10));
12126
if (!t)
12127
continue; // type must've been deleted
12128
savedsol = w["sols"][p];
12129
nusol = {
12130
sa: savedsol["sa"],
12131
insts: []
12132
};
12133
for (j = 0, lenj = savedsol["insts"].length; j < lenj; j++)
12134
{
12135
inst = this.runtime.getObjectByUID(savedsol["insts"][j]);
12136
if (inst)
12137
nusol.insts.push(inst);
12138
}
12139
addWait.sols[t.index.toString()] = nusol;
12140
}
12141
}
12142
this.waits.push(addWait);
12143
}
12144
};
12145
(function ()
12146
{
12147
var sysProto = cr.system_object.prototype;
12148
function SysCnds() {};
12149
SysCnds.prototype.EveryTick = function()
12150
{
12151
return true;
12152
};
12153
SysCnds.prototype.OnLayoutStart = function()
12154
{
12155
return true;
12156
};
12157
SysCnds.prototype.OnLayoutEnd = function()
12158
{
12159
return true;
12160
};
12161
SysCnds.prototype.Compare = function(x, cmp, y)
12162
{
12163
return cr.do_cmp(x, cmp, y);
12164
};
12165
SysCnds.prototype.CompareTime = function (cmp, t)
12166
{
12167
var elapsed = this.runtime.kahanTime.sum;
12168
if (cmp === 0)
12169
{
12170
var cnd = this.runtime.getCurrentCondition();
12171
if (!cnd.extra["CompareTime_executed"])
12172
{
12173
if (elapsed >= t)
12174
{
12175
cnd.extra["CompareTime_executed"] = true;
12176
return true;
12177
}
12178
}
12179
return false;
12180
}
12181
return cr.do_cmp(elapsed, cmp, t);
12182
};
12183
SysCnds.prototype.LayerVisible = function (layer)
12184
{
12185
if (!layer)
12186
return false;
12187
else
12188
return layer.visible;
12189
};
12190
SysCnds.prototype.LayerEmpty = function (layer)
12191
{
12192
if (!layer)
12193
return false;
12194
else
12195
return !layer.instances.length;
12196
};
12197
SysCnds.prototype.LayerCmpOpacity = function (layer, cmp, opacity_)
12198
{
12199
if (!layer)
12200
return false;
12201
return cr.do_cmp(layer.opacity * 100, cmp, opacity_);
12202
};
12203
SysCnds.prototype.Repeat = function (count)
12204
{
12205
var current_frame = this.runtime.getCurrentEventStack();
12206
var current_event = current_frame.current_event;
12207
var solModifierAfterCnds = current_frame.isModifierAfterCnds();
12208
var current_loop = this.runtime.pushLoopStack();
12209
var i;
12210
if (solModifierAfterCnds)
12211
{
12212
for (i = 0; i < count && !current_loop.stopped; i++)
12213
{
12214
this.runtime.pushCopySol(current_event.solModifiers);
12215
current_loop.index = i;
12216
current_event.retrigger();
12217
this.runtime.popSol(current_event.solModifiers);
12218
}
12219
}
12220
else
12221
{
12222
for (i = 0; i < count && !current_loop.stopped; i++)
12223
{
12224
current_loop.index = i;
12225
current_event.retrigger();
12226
}
12227
}
12228
this.runtime.popLoopStack();
12229
return false;
12230
};
12231
SysCnds.prototype.While = function (count)
12232
{
12233
var current_frame = this.runtime.getCurrentEventStack();
12234
var current_event = current_frame.current_event;
12235
var solModifierAfterCnds = current_frame.isModifierAfterCnds();
12236
var current_loop = this.runtime.pushLoopStack();
12237
var i;
12238
if (solModifierAfterCnds)
12239
{
12240
for (i = 0; !current_loop.stopped; i++)
12241
{
12242
this.runtime.pushCopySol(current_event.solModifiers);
12243
current_loop.index = i;
12244
if (!current_event.retrigger()) // one of the other conditions returned false
12245
current_loop.stopped = true; // break
12246
this.runtime.popSol(current_event.solModifiers);
12247
}
12248
}
12249
else
12250
{
12251
for (i = 0; !current_loop.stopped; i++)
12252
{
12253
current_loop.index = i;
12254
if (!current_event.retrigger())
12255
current_loop.stopped = true;
12256
}
12257
}
12258
this.runtime.popLoopStack();
12259
return false;
12260
};
12261
SysCnds.prototype.For = function (name, start, end)
12262
{
12263
var current_frame = this.runtime.getCurrentEventStack();
12264
var current_event = current_frame.current_event;
12265
var solModifierAfterCnds = current_frame.isModifierAfterCnds();
12266
var current_loop = this.runtime.pushLoopStack(name);
12267
var i;
12268
if (end < start)
12269
{
12270
if (solModifierAfterCnds)
12271
{
12272
for (i = start; i >= end && !current_loop.stopped; --i) // inclusive to end
12273
{
12274
this.runtime.pushCopySol(current_event.solModifiers);
12275
current_loop.index = i;
12276
current_event.retrigger();
12277
this.runtime.popSol(current_event.solModifiers);
12278
}
12279
}
12280
else
12281
{
12282
for (i = start; i >= end && !current_loop.stopped; --i) // inclusive to end
12283
{
12284
current_loop.index = i;
12285
current_event.retrigger();
12286
}
12287
}
12288
}
12289
else
12290
{
12291
if (solModifierAfterCnds)
12292
{
12293
for (i = start; i <= end && !current_loop.stopped; ++i) // inclusive to end
12294
{
12295
this.runtime.pushCopySol(current_event.solModifiers);
12296
current_loop.index = i;
12297
current_event.retrigger();
12298
this.runtime.popSol(current_event.solModifiers);
12299
}
12300
}
12301
else
12302
{
12303
for (i = start; i <= end && !current_loop.stopped; ++i) // inclusive to end
12304
{
12305
current_loop.index = i;
12306
current_event.retrigger();
12307
}
12308
}
12309
}
12310
this.runtime.popLoopStack();
12311
return false;
12312
};
12313
var foreach_instancestack = [];
12314
var foreach_instanceptr = -1;
12315
SysCnds.prototype.ForEach = function (obj)
12316
{
12317
var sol = obj.getCurrentSol();
12318
foreach_instanceptr++;
12319
if (foreach_instancestack.length === foreach_instanceptr)
12320
foreach_instancestack.push([]);
12321
var instances = foreach_instancestack[foreach_instanceptr];
12322
cr.shallowAssignArray(instances, sol.getObjects());
12323
var current_frame = this.runtime.getCurrentEventStack();
12324
var current_event = current_frame.current_event;
12325
var solModifierAfterCnds = current_frame.isModifierAfterCnds();
12326
var current_loop = this.runtime.pushLoopStack();
12327
var i, len, j, lenj, inst, s, sol2;
12328
var is_contained = obj.is_contained;
12329
if (solModifierAfterCnds)
12330
{
12331
for (i = 0, len = instances.length; i < len && !current_loop.stopped; i++)
12332
{
12333
this.runtime.pushCopySol(current_event.solModifiers);
12334
inst = instances[i];
12335
sol = obj.getCurrentSol();
12336
sol.select_all = false;
12337
cr.clearArray(sol.instances);
12338
sol.instances[0] = inst;
12339
if (is_contained)
12340
{
12341
for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
12342
{
12343
s = inst.siblings[j];
12344
sol2 = s.type.getCurrentSol();
12345
sol2.select_all = false;
12346
cr.clearArray(sol2.instances);
12347
sol2.instances[0] = s;
12348
}
12349
}
12350
current_loop.index = i;
12351
current_event.retrigger();
12352
this.runtime.popSol(current_event.solModifiers);
12353
}
12354
}
12355
else
12356
{
12357
sol.select_all = false;
12358
cr.clearArray(sol.instances);
12359
for (i = 0, len = instances.length; i < len && !current_loop.stopped; i++)
12360
{
12361
inst = instances[i];
12362
sol.instances[0] = inst;
12363
if (is_contained)
12364
{
12365
for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
12366
{
12367
s = inst.siblings[j];
12368
sol2 = s.type.getCurrentSol();
12369
sol2.select_all = false;
12370
cr.clearArray(sol2.instances);
12371
sol2.instances[0] = s;
12372
}
12373
}
12374
current_loop.index = i;
12375
current_event.retrigger();
12376
}
12377
}
12378
cr.clearArray(instances);
12379
this.runtime.popLoopStack();
12380
foreach_instanceptr--;
12381
return false;
12382
};
12383
function foreach_sortinstances(a, b)
12384
{
12385
var va = a.extra["c2_feo_val"];
12386
var vb = b.extra["c2_feo_val"];
12387
if (cr.is_number(va) && cr.is_number(vb))
12388
return va - vb;
12389
else
12390
{
12391
va = "" + va;
12392
vb = "" + vb;
12393
if (va < vb)
12394
return -1;
12395
else if (va > vb)
12396
return 1;
12397
else
12398
return 0;
12399
}
12400
};
12401
SysCnds.prototype.ForEachOrdered = function (obj, exp, order)
12402
{
12403
var sol = obj.getCurrentSol();
12404
foreach_instanceptr++;
12405
if (foreach_instancestack.length === foreach_instanceptr)
12406
foreach_instancestack.push([]);
12407
var instances = foreach_instancestack[foreach_instanceptr];
12408
cr.shallowAssignArray(instances, sol.getObjects());
12409
var current_frame = this.runtime.getCurrentEventStack();
12410
var current_event = current_frame.current_event;
12411
var current_condition = this.runtime.getCurrentCondition();
12412
var solModifierAfterCnds = current_frame.isModifierAfterCnds();
12413
var current_loop = this.runtime.pushLoopStack();
12414
var i, len, j, lenj, inst, s, sol2;
12415
for (i = 0, len = instances.length; i < len; i++)
12416
{
12417
instances[i].extra["c2_feo_val"] = current_condition.parameters[1].get(i);
12418
}
12419
instances.sort(foreach_sortinstances);
12420
if (order === 1)
12421
instances.reverse();
12422
var is_contained = obj.is_contained;
12423
if (solModifierAfterCnds)
12424
{
12425
for (i = 0, len = instances.length; i < len && !current_loop.stopped; i++)
12426
{
12427
this.runtime.pushCopySol(current_event.solModifiers);
12428
inst = instances[i];
12429
sol = obj.getCurrentSol();
12430
sol.select_all = false;
12431
cr.clearArray(sol.instances);
12432
sol.instances[0] = inst;
12433
if (is_contained)
12434
{
12435
for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
12436
{
12437
s = inst.siblings[j];
12438
sol2 = s.type.getCurrentSol();
12439
sol2.select_all = false;
12440
cr.clearArray(sol2.instances);
12441
sol2.instances[0] = s;
12442
}
12443
}
12444
current_loop.index = i;
12445
current_event.retrigger();
12446
this.runtime.popSol(current_event.solModifiers);
12447
}
12448
}
12449
else
12450
{
12451
sol.select_all = false;
12452
cr.clearArray(sol.instances);
12453
for (i = 0, len = instances.length; i < len && !current_loop.stopped; i++)
12454
{
12455
inst = instances[i];
12456
sol.instances[0] = inst;
12457
if (is_contained)
12458
{
12459
for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
12460
{
12461
s = inst.siblings[j];
12462
sol2 = s.type.getCurrentSol();
12463
sol2.select_all = false;
12464
cr.clearArray(sol2.instances);
12465
sol2.instances[0] = s;
12466
}
12467
}
12468
current_loop.index = i;
12469
current_event.retrigger();
12470
}
12471
}
12472
cr.clearArray(instances);
12473
this.runtime.popLoopStack();
12474
foreach_instanceptr--;
12475
return false;
12476
};
12477
SysCnds.prototype.PickByComparison = function (obj_, exp_, cmp_, val_)
12478
{
12479
var i, len, k, inst;
12480
if (!obj_)
12481
return;
12482
foreach_instanceptr++;
12483
if (foreach_instancestack.length === foreach_instanceptr)
12484
foreach_instancestack.push([]);
12485
var tmp_instances = foreach_instancestack[foreach_instanceptr];
12486
var sol = obj_.getCurrentSol();
12487
cr.shallowAssignArray(tmp_instances, sol.getObjects());
12488
if (sol.select_all)
12489
cr.clearArray(sol.else_instances);
12490
var current_condition = this.runtime.getCurrentCondition();
12491
for (i = 0, k = 0, len = tmp_instances.length; i < len; i++)
12492
{
12493
inst = tmp_instances[i];
12494
tmp_instances[k] = inst;
12495
exp_ = current_condition.parameters[1].get(i);
12496
val_ = current_condition.parameters[3].get(i);
12497
if (cr.do_cmp(exp_, cmp_, val_))
12498
{
12499
k++;
12500
}
12501
else
12502
{
12503
sol.else_instances.push(inst);
12504
}
12505
}
12506
cr.truncateArray(tmp_instances, k);
12507
sol.select_all = false;
12508
cr.shallowAssignArray(sol.instances, tmp_instances);
12509
cr.clearArray(tmp_instances);
12510
foreach_instanceptr--;
12511
obj_.applySolToContainer();
12512
return !!sol.instances.length;
12513
};
12514
SysCnds.prototype.PickByEvaluate = function (obj_, exp_)
12515
{
12516
var i, len, k, inst;
12517
if (!obj_)
12518
return;
12519
foreach_instanceptr++;
12520
if (foreach_instancestack.length === foreach_instanceptr)
12521
foreach_instancestack.push([]);
12522
var tmp_instances = foreach_instancestack[foreach_instanceptr];
12523
var sol = obj_.getCurrentSol();
12524
cr.shallowAssignArray(tmp_instances, sol.getObjects());
12525
if (sol.select_all)
12526
cr.clearArray(sol.else_instances);
12527
var current_condition = this.runtime.getCurrentCondition();
12528
for (i = 0, k = 0, len = tmp_instances.length; i < len; i++)
12529
{
12530
inst = tmp_instances[i];
12531
tmp_instances[k] = inst;
12532
exp_ = current_condition.parameters[1].get(i);
12533
if (exp_)
12534
{
12535
k++;
12536
}
12537
else
12538
{
12539
sol.else_instances.push(inst);
12540
}
12541
}
12542
cr.truncateArray(tmp_instances, k);
12543
sol.select_all = false;
12544
cr.shallowAssignArray(sol.instances, tmp_instances);
12545
cr.clearArray(tmp_instances);
12546
foreach_instanceptr--;
12547
obj_.applySolToContainer();
12548
return !!sol.instances.length;
12549
};
12550
SysCnds.prototype.TriggerOnce = function ()
12551
{
12552
var cndextra = this.runtime.getCurrentCondition().extra;
12553
if (typeof cndextra["TriggerOnce_lastTick"] === "undefined")
12554
cndextra["TriggerOnce_lastTick"] = -1;
12555
var last_tick = cndextra["TriggerOnce_lastTick"];
12556
var cur_tick = this.runtime.tickcount;
12557
cndextra["TriggerOnce_lastTick"] = cur_tick;
12558
return this.runtime.layout_first_tick || last_tick !== cur_tick - 1;
12559
};
12560
SysCnds.prototype.Every = function (seconds)
12561
{
12562
var cnd = this.runtime.getCurrentCondition();
12563
var last_time = cnd.extra["Every_lastTime"] || 0;
12564
var cur_time = this.runtime.kahanTime.sum;
12565
if (typeof cnd.extra["Every_seconds"] === "undefined")
12566
cnd.extra["Every_seconds"] = seconds;
12567
var this_seconds = cnd.extra["Every_seconds"];
12568
if (cur_time >= last_time + this_seconds)
12569
{
12570
cnd.extra["Every_lastTime"] = last_time + this_seconds;
12571
if (cur_time >= cnd.extra["Every_lastTime"] + 0.04)
12572
{
12573
cnd.extra["Every_lastTime"] = cur_time;
12574
}
12575
cnd.extra["Every_seconds"] = seconds;
12576
return true;
12577
}
12578
else if (cur_time < last_time - 0.1)
12579
{
12580
cnd.extra["Every_lastTime"] = cur_time;
12581
}
12582
return false;
12583
};
12584
SysCnds.prototype.PickNth = function (obj, index)
12585
{
12586
if (!obj)
12587
return false;
12588
var sol = obj.getCurrentSol();
12589
var instances = sol.getObjects();
12590
index = cr.floor(index);
12591
if (index < 0 || index >= instances.length)
12592
return false;
12593
var inst = instances[index];
12594
sol.pick_one(inst);
12595
obj.applySolToContainer();
12596
return true;
12597
};
12598
SysCnds.prototype.PickRandom = function (obj)
12599
{
12600
if (!obj)
12601
return false;
12602
var sol = obj.getCurrentSol();
12603
var instances = sol.getObjects();
12604
var index = cr.floor(Math.random() * instances.length);
12605
if (index >= instances.length)
12606
return false;
12607
var inst = instances[index];
12608
sol.pick_one(inst);
12609
obj.applySolToContainer();
12610
return true;
12611
};
12612
SysCnds.prototype.CompareVar = function (v, cmp, val)
12613
{
12614
return cr.do_cmp(v.getValue(), cmp, val);
12615
};
12616
SysCnds.prototype.IsGroupActive = function (group)
12617
{
12618
var g = this.runtime.groups_by_name[group.toLowerCase()];
12619
return g && g.group_active;
12620
};
12621
SysCnds.prototype.IsPreview = function ()
12622
{
12623
return typeof cr_is_preview !== "undefined";
12624
};
12625
SysCnds.prototype.PickAll = function (obj)
12626
{
12627
if (!obj)
12628
return false;
12629
if (!obj.instances.length)
12630
return false;
12631
var sol = obj.getCurrentSol();
12632
sol.select_all = true;
12633
obj.applySolToContainer();
12634
return true;
12635
};
12636
SysCnds.prototype.IsMobile = function ()
12637
{
12638
return this.runtime.isMobile;
12639
};
12640
SysCnds.prototype.CompareBetween = function (x, a, b)
12641
{
12642
return x >= a && x <= b;
12643
};
12644
SysCnds.prototype.Else = function ()
12645
{
12646
var current_frame = this.runtime.getCurrentEventStack();
12647
if (current_frame.else_branch_ran)
12648
return false; // another event in this else-if chain has run
12649
else
12650
return !current_frame.last_event_true;
12651
/*
12652
var current_frame = this.runtime.getCurrentEventStack();
12653
var current_event = current_frame.current_event;
12654
var prev_event = current_event.prev_block;
12655
if (!prev_event)
12656
return false;
12657
if (prev_event.is_logical)
12658
return !this.runtime.last_event_true;
12659
var i, len, j, lenj, s, sol, temp, inst, any_picked = false;
12660
for (i = 0, len = prev_event.cndReferences.length; i < len; i++)
12661
{
12662
s = prev_event.cndReferences[i];
12663
sol = s.getCurrentSol();
12664
if (sol.select_all || sol.instances.length === s.instances.length)
12665
{
12666
sol.select_all = false;
12667
sol.instances.length = 0;
12668
}
12669
else
12670
{
12671
if (sol.instances.length === 1 && sol.else_instances.length === 0 && s.instances.length >= 2)
12672
{
12673
inst = sol.instances[0];
12674
sol.instances.length = 0;
12675
for (j = 0, lenj = s.instances.length; j < lenj; j++)
12676
{
12677
if (s.instances[j] != inst)
12678
sol.instances.push(s.instances[j]);
12679
}
12680
any_picked = true;
12681
}
12682
else
12683
{
12684
temp = sol.instances;
12685
sol.instances = sol.else_instances;
12686
sol.else_instances = temp;
12687
any_picked = true;
12688
}
12689
}
12690
}
12691
return any_picked;
12692
*/
12693
};
12694
SysCnds.prototype.OnLoadFinished = function ()
12695
{
12696
return true;
12697
};
12698
SysCnds.prototype.OnCanvasSnapshot = function ()
12699
{
12700
return true;
12701
};
12702
SysCnds.prototype.EffectsSupported = function ()
12703
{
12704
return !!this.runtime.glwrap;
12705
};
12706
SysCnds.prototype.OnSaveComplete = function ()
12707
{
12708
return true;
12709
};
12710
SysCnds.prototype.OnSaveFailed = function ()
12711
{
12712
return true;
12713
};
12714
SysCnds.prototype.OnLoadComplete = function ()
12715
{
12716
return true;
12717
};
12718
SysCnds.prototype.OnLoadFailed = function ()
12719
{
12720
return true;
12721
};
12722
SysCnds.prototype.ObjectUIDExists = function (u)
12723
{
12724
return !!this.runtime.getObjectByUID(u);
12725
};
12726
SysCnds.prototype.IsOnPlatform = function (p)
12727
{
12728
var rt = this.runtime;
12729
switch (p) {
12730
case 0: // HTML5 website
12731
return !rt.isDomFree && !rt.isNodeWebkit && !rt.isCordova && !rt.isWinJS && !rt.isWindowsPhone8 && !rt.isBlackberry10 && !rt.isAmazonWebApp;
12732
case 1: // iOS
12733
return rt.isiOS;
12734
case 2: // Android
12735
return rt.isAndroid;
12736
case 3: // Windows 8
12737
return rt.isWindows8App;
12738
case 4: // Windows Phone 8
12739
return rt.isWindowsPhone8;
12740
case 5: // Blackberry 10
12741
return rt.isBlackberry10;
12742
case 6: // Tizen
12743
return rt.isTizen;
12744
case 7: // CocoonJS
12745
return rt.isCocoonJs;
12746
case 8: // Cordova
12747
return rt.isCordova;
12748
case 9: // Scirra Arcade
12749
return rt.isArcade;
12750
case 10: // node-webkit
12751
return rt.isNodeWebkit;
12752
case 11: // crosswalk
12753
return rt.isCrosswalk;
12754
case 12: // amazon webapp
12755
return rt.isAmazonWebApp;
12756
case 13: // windows 10 app
12757
return rt.isWindows10;
12758
default: // should not be possible
12759
return false;
12760
}
12761
};
12762
var cacheRegex = null;
12763
var lastRegex = "";
12764
var lastFlags = "";
12765
function getRegex(regex_, flags_)
12766
{
12767
if (!cacheRegex || regex_ !== lastRegex || flags_ !== lastFlags)
12768
{
12769
cacheRegex = new RegExp(regex_, flags_);
12770
lastRegex = regex_;
12771
lastFlags = flags_;
12772
}
12773
cacheRegex.lastIndex = 0; // reset
12774
return cacheRegex;
12775
};
12776
SysCnds.prototype.RegexTest = function (str_, regex_, flags_)
12777
{
12778
var regex = getRegex(regex_, flags_);
12779
return regex.test(str_);
12780
};
12781
var tmp_arr = [];
12782
SysCnds.prototype.PickOverlappingPoint = function (obj_, x_, y_)
12783
{
12784
if (!obj_)
12785
return false;
12786
var sol = obj_.getCurrentSol();
12787
var instances = sol.getObjects();
12788
var current_event = this.runtime.getCurrentEventStack().current_event;
12789
var orblock = current_event.orblock;
12790
var cnd = this.runtime.getCurrentCondition();
12791
var i, len, inst, pick;
12792
if (sol.select_all)
12793
{
12794
cr.shallowAssignArray(tmp_arr, instances);
12795
cr.clearArray(sol.else_instances);
12796
sol.select_all = false;
12797
cr.clearArray(sol.instances);
12798
}
12799
else
12800
{
12801
if (orblock)
12802
{
12803
cr.shallowAssignArray(tmp_arr, sol.else_instances);
12804
cr.clearArray(sol.else_instances);
12805
}
12806
else
12807
{
12808
cr.shallowAssignArray(tmp_arr, instances);
12809
cr.clearArray(sol.instances);
12810
}
12811
}
12812
for (i = 0, len = tmp_arr.length; i < len; ++i)
12813
{
12814
inst = tmp_arr[i];
12815
inst.update_bbox();
12816
pick = cr.xor(inst.contains_pt(x_, y_), cnd.inverted);
12817
if (pick)
12818
sol.instances.push(inst);
12819
else
12820
sol.else_instances.push(inst);
12821
}
12822
obj_.applySolToContainer();
12823
return cr.xor(!!sol.instances.length, cnd.inverted);
12824
};
12825
SysCnds.prototype.IsNaN = function (n)
12826
{
12827
return !!isNaN(n);
12828
};
12829
SysCnds.prototype.AngleWithin = function (a1, within, a2)
12830
{
12831
return cr.angleDiff(cr.to_radians(a1), cr.to_radians(a2)) <= cr.to_radians(within);
12832
};
12833
SysCnds.prototype.IsClockwiseFrom = function (a1, a2)
12834
{
12835
return cr.angleClockwise(cr.to_radians(a1), cr.to_radians(a2));
12836
};
12837
SysCnds.prototype.IsBetweenAngles = function (a, la, ua)
12838
{
12839
var angle = cr.to_clamped_radians(a);
12840
var lower = cr.to_clamped_radians(la);
12841
var upper = cr.to_clamped_radians(ua);
12842
var obtuse = (!cr.angleClockwise(upper, lower));
12843
if (obtuse)
12844
return !(!cr.angleClockwise(angle, lower) && cr.angleClockwise(angle, upper));
12845
else
12846
return cr.angleClockwise(angle, lower) && !cr.angleClockwise(angle, upper);
12847
};
12848
SysCnds.prototype.IsValueType = function (x, t)
12849
{
12850
if (typeof x === "number")
12851
return t === 0;
12852
else // string
12853
return t === 1;
12854
};
12855
sysProto.cnds = new SysCnds();
12856
function SysActs() {};
12857
SysActs.prototype.GoToLayout = function (to)
12858
{
12859
if (this.runtime.isloading)
12860
return; // cannot change layout while loading on loader layout
12861
if (this.runtime.changelayout)
12862
return; // already changing to a different layout
12863
;
12864
this.runtime.changelayout = to;
12865
};
12866
SysActs.prototype.NextPrevLayout = function (prev)
12867
{
12868
if (this.runtime.isloading)
12869
return; // cannot change layout while loading on loader layout
12870
if (this.runtime.changelayout)
12871
return; // already changing to a different layout
12872
var index = this.runtime.layouts_by_index.indexOf(this.runtime.running_layout);
12873
if (prev && index === 0)
12874
return; // cannot go to previous layout from first layout
12875
if (!prev && index === this.runtime.layouts_by_index.length - 1)
12876
return; // cannot go to next layout from last layout
12877
var to = this.runtime.layouts_by_index[index + (prev ? -1 : 1)];
12878
;
12879
this.runtime.changelayout = to;
12880
};
12881
SysActs.prototype.CreateObject = function (obj, layer, x, y)
12882
{
12883
if (!layer || !obj)
12884
return;
12885
var inst = this.runtime.createInstance(obj, layer, x, y);
12886
if (!inst)
12887
return;
12888
this.runtime.isInOnDestroy++;
12889
var i, len, s;
12890
this.runtime.trigger(Object.getPrototypeOf(obj.plugin).cnds.OnCreated, inst);
12891
if (inst.is_contained)
12892
{
12893
for (i = 0, len = inst.siblings.length; i < len; i++)
12894
{
12895
s = inst.siblings[i];
12896
this.runtime.trigger(Object.getPrototypeOf(s.type.plugin).cnds.OnCreated, s);
12897
}
12898
}
12899
this.runtime.isInOnDestroy--;
12900
var sol = obj.getCurrentSol();
12901
sol.select_all = false;
12902
cr.clearArray(sol.instances);
12903
sol.instances[0] = inst;
12904
if (inst.is_contained)
12905
{
12906
for (i = 0, len = inst.siblings.length; i < len; i++)
12907
{
12908
s = inst.siblings[i];
12909
sol = s.type.getCurrentSol();
12910
sol.select_all = false;
12911
cr.clearArray(sol.instances);
12912
sol.instances[0] = s;
12913
}
12914
}
12915
};
12916
SysActs.prototype.SetLayerVisible = function (layer, visible_)
12917
{
12918
if (!layer)
12919
return;
12920
if (layer.visible !== visible_)
12921
{
12922
layer.visible = visible_;
12923
this.runtime.redraw = true;
12924
}
12925
};
12926
SysActs.prototype.SetLayerOpacity = function (layer, opacity_)
12927
{
12928
if (!layer)
12929
return;
12930
opacity_ = cr.clamp(opacity_ / 100, 0, 1);
12931
if (layer.opacity !== opacity_)
12932
{
12933
layer.opacity = opacity_;
12934
this.runtime.redraw = true;
12935
}
12936
};
12937
SysActs.prototype.SetLayerScaleRate = function (layer, sr)
12938
{
12939
if (!layer)
12940
return;
12941
if (layer.zoomRate !== sr)
12942
{
12943
layer.zoomRate = sr;
12944
this.runtime.redraw = true;
12945
}
12946
};
12947
SysActs.prototype.SetLayerForceOwnTexture = function (layer, f)
12948
{
12949
if (!layer)
12950
return;
12951
f = !!f;
12952
if (layer.forceOwnTexture !== f)
12953
{
12954
layer.forceOwnTexture = f;
12955
this.runtime.redraw = true;
12956
}
12957
};
12958
SysActs.prototype.SetLayoutScale = function (s)
12959
{
12960
if (!this.runtime.running_layout)
12961
return;
12962
if (this.runtime.running_layout.scale !== s)
12963
{
12964
this.runtime.running_layout.scale = s;
12965
this.runtime.running_layout.boundScrolling();
12966
this.runtime.redraw = true;
12967
}
12968
};
12969
SysActs.prototype.ScrollX = function(x)
12970
{
12971
this.runtime.running_layout.scrollToX(x);
12972
};
12973
SysActs.prototype.ScrollY = function(y)
12974
{
12975
this.runtime.running_layout.scrollToY(y);
12976
};
12977
SysActs.prototype.Scroll = function(x, y)
12978
{
12979
this.runtime.running_layout.scrollToX(x);
12980
this.runtime.running_layout.scrollToY(y);
12981
};
12982
SysActs.prototype.ScrollToObject = function(obj)
12983
{
12984
var inst = obj.getFirstPicked();
12985
if (inst)
12986
{
12987
this.runtime.running_layout.scrollToX(inst.x);
12988
this.runtime.running_layout.scrollToY(inst.y);
12989
}
12990
};
12991
SysActs.prototype.SetVar = function(v, x)
12992
{
12993
;
12994
if (v.vartype === 0)
12995
{
12996
if (cr.is_number(x))
12997
v.setValue(x);
12998
else
12999
v.setValue(parseFloat(x));
13000
}
13001
else if (v.vartype === 1)
13002
v.setValue(x.toString());
13003
};
13004
SysActs.prototype.AddVar = function(v, x)
13005
{
13006
;
13007
if (v.vartype === 0)
13008
{
13009
if (cr.is_number(x))
13010
v.setValue(v.getValue() + x);
13011
else
13012
v.setValue(v.getValue() + parseFloat(x));
13013
}
13014
else if (v.vartype === 1)
13015
v.setValue(v.getValue() + x.toString());
13016
};
13017
SysActs.prototype.SubVar = function(v, x)
13018
{
13019
;
13020
if (v.vartype === 0)
13021
{
13022
if (cr.is_number(x))
13023
v.setValue(v.getValue() - x);
13024
else
13025
v.setValue(v.getValue() - parseFloat(x));
13026
}
13027
};
13028
SysActs.prototype.SetGroupActive = function (group, active)
13029
{
13030
var g = this.runtime.groups_by_name[group.toLowerCase()];
13031
if (!g)
13032
return;
13033
switch (active) {
13034
case 0:
13035
g.setGroupActive(false);
13036
break;
13037
case 1:
13038
g.setGroupActive(true);
13039
break;
13040
case 2:
13041
g.setGroupActive(!g.group_active);
13042
break;
13043
}
13044
};
13045
SysActs.prototype.SetTimescale = function (ts_)
13046
{
13047
var ts = ts_;
13048
if (ts < 0)
13049
ts = 0;
13050
this.runtime.timescale = ts;
13051
};
13052
SysActs.prototype.SetObjectTimescale = function (obj, ts_)
13053
{
13054
var ts = ts_;
13055
if (ts < 0)
13056
ts = 0;
13057
if (!obj)
13058
return;
13059
var sol = obj.getCurrentSol();
13060
var instances = sol.getObjects();
13061
var i, len;
13062
for (i = 0, len = instances.length; i < len; i++)
13063
{
13064
instances[i].my_timescale = ts;
13065
}
13066
};
13067
SysActs.prototype.RestoreObjectTimescale = function (obj)
13068
{
13069
if (!obj)
13070
return false;
13071
var sol = obj.getCurrentSol();
13072
var instances = sol.getObjects();
13073
var i, len;
13074
for (i = 0, len = instances.length; i < len; i++)
13075
{
13076
instances[i].my_timescale = -1.0;
13077
}
13078
};
13079
var waitobjrecycle = [];
13080
function allocWaitObject()
13081
{
13082
var w;
13083
if (waitobjrecycle.length)
13084
w = waitobjrecycle.pop();
13085
else
13086
{
13087
w = {};
13088
w.sols = {};
13089
w.solModifiers = [];
13090
}
13091
w.deleteme = false;
13092
return w;
13093
};
13094
function freeWaitObject(w)
13095
{
13096
cr.wipe(w.sols);
13097
cr.clearArray(w.solModifiers);
13098
waitobjrecycle.push(w);
13099
};
13100
var solstateobjects = [];
13101
function allocSolStateObject()
13102
{
13103
var s;
13104
if (solstateobjects.length)
13105
s = solstateobjects.pop();
13106
else
13107
{
13108
s = {};
13109
s.insts = [];
13110
}
13111
s.sa = false;
13112
return s;
13113
};
13114
function freeSolStateObject(s)
13115
{
13116
cr.clearArray(s.insts);
13117
solstateobjects.push(s);
13118
};
13119
SysActs.prototype.Wait = function (seconds)
13120
{
13121
if (seconds < 0)
13122
return;
13123
var i, len, s, t, ss;
13124
var evinfo = this.runtime.getCurrentEventStack();
13125
var waitobj = allocWaitObject();
13126
waitobj.time = this.runtime.kahanTime.sum + seconds;
13127
waitobj.signaltag = "";
13128
waitobj.signalled = false;
13129
waitobj.ev = evinfo.current_event;
13130
waitobj.actindex = evinfo.actindex + 1; // pointing at next action
13131
for (i = 0, len = this.runtime.types_by_index.length; i < len; i++)
13132
{
13133
t = this.runtime.types_by_index[i];
13134
s = t.getCurrentSol();
13135
if (s.select_all && evinfo.current_event.solModifiers.indexOf(t) === -1)
13136
continue;
13137
waitobj.solModifiers.push(t);
13138
ss = allocSolStateObject();
13139
ss.sa = s.select_all;
13140
cr.shallowAssignArray(ss.insts, s.instances);
13141
waitobj.sols[i.toString()] = ss;
13142
}
13143
this.waits.push(waitobj);
13144
return true;
13145
};
13146
SysActs.prototype.WaitForSignal = function (tag)
13147
{
13148
var i, len, s, t, ss;
13149
var evinfo = this.runtime.getCurrentEventStack();
13150
var waitobj = allocWaitObject();
13151
waitobj.time = -1;
13152
waitobj.signaltag = tag.toLowerCase();
13153
waitobj.signalled = false;
13154
waitobj.ev = evinfo.current_event;
13155
waitobj.actindex = evinfo.actindex + 1; // pointing at next action
13156
for (i = 0, len = this.runtime.types_by_index.length; i < len; i++)
13157
{
13158
t = this.runtime.types_by_index[i];
13159
s = t.getCurrentSol();
13160
if (s.select_all && evinfo.current_event.solModifiers.indexOf(t) === -1)
13161
continue;
13162
waitobj.solModifiers.push(t);
13163
ss = allocSolStateObject();
13164
ss.sa = s.select_all;
13165
cr.shallowAssignArray(ss.insts, s.instances);
13166
waitobj.sols[i.toString()] = ss;
13167
}
13168
this.waits.push(waitobj);
13169
return true;
13170
};
13171
SysActs.prototype.Signal = function (tag)
13172
{
13173
var lowertag = tag.toLowerCase();
13174
var i, len, w;
13175
for (i = 0, len = this.waits.length; i < len; ++i)
13176
{
13177
w = this.waits[i];
13178
if (w.time !== -1)
13179
continue; // timer wait, ignore
13180
if (w.signaltag === lowertag) // waiting for this signal
13181
w.signalled = true; // will run on next check
13182
}
13183
};
13184
SysActs.prototype.SetLayerScale = function (layer, scale)
13185
{
13186
if (!layer)
13187
return;
13188
if (layer.scale === scale)
13189
return;
13190
layer.scale = scale;
13191
this.runtime.redraw = true;
13192
};
13193
SysActs.prototype.ResetGlobals = function ()
13194
{
13195
var i, len, g;
13196
for (i = 0, len = this.runtime.all_global_vars.length; i < len; i++)
13197
{
13198
g = this.runtime.all_global_vars[i];
13199
g.data = g.initial;
13200
}
13201
};
13202
SysActs.prototype.SetLayoutAngle = function (a)
13203
{
13204
a = cr.to_radians(a);
13205
a = cr.clamp_angle(a);
13206
if (this.runtime.running_layout)
13207
{
13208
if (this.runtime.running_layout.angle !== a)
13209
{
13210
this.runtime.running_layout.angle = a;
13211
this.runtime.redraw = true;
13212
}
13213
}
13214
};
13215
SysActs.prototype.SetLayerAngle = function (layer, a)
13216
{
13217
if (!layer)
13218
return;
13219
a = cr.to_radians(a);
13220
a = cr.clamp_angle(a);
13221
if (layer.angle === a)
13222
return;
13223
layer.angle = a;
13224
this.runtime.redraw = true;
13225
};
13226
SysActs.prototype.SetLayerParallax = function (layer, px, py)
13227
{
13228
if (!layer)
13229
return;
13230
if (layer.parallaxX === px / 100 && layer.parallaxY === py / 100)
13231
return;
13232
layer.parallaxX = px / 100;
13233
layer.parallaxY = py / 100;
13234
if (layer.parallaxX !== 1 || layer.parallaxY !== 1)
13235
{
13236
var i, len, instances = layer.instances;
13237
for (i = 0, len = instances.length; i < len; ++i)
13238
{
13239
instances[i].type.any_instance_parallaxed = true;
13240
}
13241
}
13242
this.runtime.redraw = true;
13243
};
13244
SysActs.prototype.SetLayerBackground = function (layer, c)
13245
{
13246
if (!layer)
13247
return;
13248
var r = cr.GetRValue(c);
13249
var g = cr.GetGValue(c);
13250
var b = cr.GetBValue(c);
13251
if (layer.background_color[0] === r && layer.background_color[1] === g && layer.background_color[2] === b)
13252
return;
13253
layer.background_color[0] = r;
13254
layer.background_color[1] = g;
13255
layer.background_color[2] = b;
13256
this.runtime.redraw = true;
13257
};
13258
SysActs.prototype.SetLayerTransparent = function (layer, t)
13259
{
13260
if (!layer)
13261
return;
13262
if (!!t === !!layer.transparent)
13263
return;
13264
layer.transparent = !!t;
13265
this.runtime.redraw = true;
13266
};
13267
SysActs.prototype.SetLayerBlendMode = function (layer, bm)
13268
{
13269
if (!layer)
13270
return;
13271
if (layer.blend_mode === bm)
13272
return;
13273
layer.blend_mode = bm;
13274
layer.compositeOp = cr.effectToCompositeOp(layer.blend_mode);
13275
if (this.runtime.gl)
13276
cr.setGLBlend(layer, layer.blend_mode, this.runtime.gl);
13277
this.runtime.redraw = true;
13278
};
13279
SysActs.prototype.StopLoop = function ()
13280
{
13281
if (this.runtime.loop_stack_index < 0)
13282
return; // no loop currently running
13283
this.runtime.getCurrentLoop().stopped = true;
13284
};
13285
SysActs.prototype.GoToLayoutByName = function (layoutname)
13286
{
13287
if (this.runtime.isloading)
13288
return; // cannot change layout while loading on loader layout
13289
if (this.runtime.changelayout)
13290
return; // already changing to different layout
13291
;
13292
var l;
13293
for (l in this.runtime.layouts)
13294
{
13295
if (this.runtime.layouts.hasOwnProperty(l) && cr.equals_nocase(l, layoutname))
13296
{
13297
this.runtime.changelayout = this.runtime.layouts[l];
13298
return;
13299
}
13300
}
13301
};
13302
SysActs.prototype.RestartLayout = function (layoutname)
13303
{
13304
if (this.runtime.isloading)
13305
return; // cannot restart loader layouts
13306
if (this.runtime.changelayout)
13307
return; // already changing to a different layout
13308
;
13309
if (!this.runtime.running_layout)
13310
return;
13311
this.runtime.changelayout = this.runtime.running_layout;
13312
var i, len, g;
13313
for (i = 0, len = this.runtime.allGroups.length; i < len; i++)
13314
{
13315
g = this.runtime.allGroups[i];
13316
g.setGroupActive(g.initially_activated);
13317
}
13318
};
13319
SysActs.prototype.SnapshotCanvas = function (format_, quality_)
13320
{
13321
this.runtime.doCanvasSnapshot(format_ === 0 ? "image/png" : "image/jpeg", quality_ / 100);
13322
};
13323
SysActs.prototype.SetCanvasSize = function (w, h)
13324
{
13325
if (w <= 0 || h <= 0)
13326
return;
13327
var mode = this.runtime.fullscreen_mode;
13328
var isfullscreen = (document["mozFullScreen"] || document["webkitIsFullScreen"] || !!document["msFullscreenElement"] || document["fullScreen"] || this.runtime.isNodeFullscreen);
13329
if (isfullscreen && this.runtime.fullscreen_scaling > 0)
13330
mode = this.runtime.fullscreen_scaling;
13331
if (mode === 0)
13332
{
13333
this.runtime["setSize"](w, h, true);
13334
}
13335
else
13336
{
13337
this.runtime.original_width = w;
13338
this.runtime.original_height = h;
13339
this.runtime["setSize"](this.runtime.lastWindowWidth, this.runtime.lastWindowHeight, true);
13340
}
13341
};
13342
SysActs.prototype.SetLayoutEffectEnabled = function (enable_, effectname_)
13343
{
13344
if (!this.runtime.running_layout || !this.runtime.glwrap)
13345
return;
13346
var et = this.runtime.running_layout.getEffectByName(effectname_);
13347
if (!et)
13348
return; // effect name not found
13349
var enable = (enable_ === 1);
13350
if (et.active == enable)
13351
return; // no change
13352
et.active = enable;
13353
this.runtime.running_layout.updateActiveEffects();
13354
this.runtime.redraw = true;
13355
};
13356
SysActs.prototype.SetLayerEffectEnabled = function (layer, enable_, effectname_)
13357
{
13358
if (!layer || !this.runtime.glwrap)
13359
return;
13360
var et = layer.getEffectByName(effectname_);
13361
if (!et)
13362
return; // effect name not found
13363
var enable = (enable_ === 1);
13364
if (et.active == enable)
13365
return; // no change
13366
et.active = enable;
13367
layer.updateActiveEffects();
13368
this.runtime.redraw = true;
13369
};
13370
SysActs.prototype.SetLayoutEffectParam = function (effectname_, index_, value_)
13371
{
13372
if (!this.runtime.running_layout || !this.runtime.glwrap)
13373
return;
13374
var et = this.runtime.running_layout.getEffectByName(effectname_);
13375
if (!et)
13376
return; // effect name not found
13377
var params = this.runtime.running_layout.effect_params[et.index];
13378
index_ = Math.floor(index_);
13379
if (index_ < 0 || index_ >= params.length)
13380
return; // effect index out of bounds
13381
if (this.runtime.glwrap.getProgramParameterType(et.shaderindex, index_) === 1)
13382
value_ /= 100.0;
13383
if (params[index_] === value_)
13384
return; // no change
13385
params[index_] = value_;
13386
if (et.active)
13387
this.runtime.redraw = true;
13388
};
13389
SysActs.prototype.SetLayerEffectParam = function (layer, effectname_, index_, value_)
13390
{
13391
if (!layer || !this.runtime.glwrap)
13392
return;
13393
var et = layer.getEffectByName(effectname_);
13394
if (!et)
13395
return; // effect name not found
13396
var params = layer.effect_params[et.index];
13397
index_ = Math.floor(index_);
13398
if (index_ < 0 || index_ >= params.length)
13399
return; // effect index out of bounds
13400
if (this.runtime.glwrap.getProgramParameterType(et.shaderindex, index_) === 1)
13401
value_ /= 100.0;
13402
if (params[index_] === value_)
13403
return; // no change
13404
params[index_] = value_;
13405
if (et.active)
13406
this.runtime.redraw = true;
13407
};
13408
SysActs.prototype.SaveState = function (slot_)
13409
{
13410
this.runtime.saveToSlot = slot_;
13411
};
13412
SysActs.prototype.LoadState = function (slot_)
13413
{
13414
this.runtime.loadFromSlot = slot_;
13415
};
13416
SysActs.prototype.LoadStateJSON = function (jsonstr_)
13417
{
13418
this.runtime.loadFromJson = jsonstr_;
13419
};
13420
SysActs.prototype.SetHalfFramerateMode = function (set_)
13421
{
13422
this.runtime.halfFramerateMode = (set_ !== 0);
13423
};
13424
SysActs.prototype.SetFullscreenQuality = function (q)
13425
{
13426
var isfullscreen = (document["mozFullScreen"] || document["webkitIsFullScreen"] || !!document["msFullscreenElement"] || document["fullScreen"] || this.isNodeFullscreen);
13427
if (!isfullscreen && this.runtime.fullscreen_mode === 0)
13428
return;
13429
this.runtime.wantFullscreenScalingQuality = (q !== 0);
13430
this.runtime["setSize"](this.runtime.lastWindowWidth, this.runtime.lastWindowHeight, true);
13431
};
13432
SysActs.prototype.ResetPersisted = function ()
13433
{
13434
var i, len;
13435
for (i = 0, len = this.runtime.layouts_by_index.length; i < len; ++i)
13436
{
13437
this.runtime.layouts_by_index[i].persist_data = {};
13438
this.runtime.layouts_by_index[i].first_visit = true;
13439
}
13440
};
13441
SysActs.prototype.RecreateInitialObjects = function (obj, x1, y1, x2, y2)
13442
{
13443
if (!obj)
13444
return;
13445
this.runtime.running_layout.recreateInitialObjects(obj, x1, y1, x2, y2);
13446
};
13447
SysActs.prototype.SetPixelRounding = function (m)
13448
{
13449
this.runtime.pixel_rounding = (m !== 0);
13450
this.runtime.redraw = true;
13451
};
13452
SysActs.prototype.SetMinimumFramerate = function (f)
13453
{
13454
if (f < 1)
13455
f = 1;
13456
if (f > 120)
13457
f = 120;
13458
this.runtime.minimumFramerate = f;
13459
};
13460
function SortZOrderList(a, b)
13461
{
13462
var layerA = a[0];
13463
var layerB = b[0];
13464
var diff = layerA - layerB;
13465
if (diff !== 0)
13466
return diff;
13467
var indexA = a[1];
13468
var indexB = b[1];
13469
return indexA - indexB;
13470
};
13471
function SortInstancesByValue(a, b)
13472
{
13473
return a[1] - b[1];
13474
};
13475
SysActs.prototype.SortZOrderByInstVar = function (obj, iv)
13476
{
13477
if (!obj)
13478
return;
13479
var i, len, inst, value, r, layer, toZ;
13480
var sol = obj.getCurrentSol();
13481
var pickedInstances = sol.getObjects();
13482
var zOrderList = [];
13483
var instValues = [];
13484
var layout = this.runtime.running_layout;
13485
var isFamily = obj.is_family;
13486
var familyIndex = obj.family_index;
13487
for (i = 0, len = pickedInstances.length; i < len; ++i)
13488
{
13489
inst = pickedInstances[i];
13490
if (!inst.layer)
13491
continue; // not a world instance
13492
if (isFamily)
13493
value = inst.instance_vars[iv + inst.type.family_var_map[familyIndex]];
13494
else
13495
value = inst.instance_vars[iv];
13496
zOrderList.push([
13497
inst.layer.index,
13498
inst.get_zindex()
13499
]);
13500
instValues.push([
13501
inst,
13502
value
13503
]);
13504
}
13505
if (!zOrderList.length)
13506
return; // no instances were world instances
13507
zOrderList.sort(SortZOrderList);
13508
instValues.sort(SortInstancesByValue);
13509
for (i = 0, len = zOrderList.length; i < len; ++i)
13510
{
13511
inst = instValues[i][0]; // instance in the order we want
13512
layer = layout.layers[zOrderList[i][0]]; // layer to put it on
13513
toZ = zOrderList[i][1]; // Z index on that layer to put it
13514
if (layer.instances[toZ] !== inst) // not already got this instance there
13515
{
13516
layer.instances[toZ] = inst; // update instance
13517
inst.layer = layer; // update instance's layer reference (could have changed)
13518
layer.setZIndicesStaleFrom(toZ); // mark Z indices stale from this point since they have changed
13519
}
13520
}
13521
};
13522
sysProto.acts = new SysActs();
13523
function SysExps() {};
13524
SysExps.prototype["int"] = function(ret, x)
13525
{
13526
if (cr.is_string(x))
13527
{
13528
ret.set_int(parseInt(x, 10));
13529
if (isNaN(ret.data))
13530
ret.data = 0;
13531
}
13532
else
13533
ret.set_int(x);
13534
};
13535
SysExps.prototype["float"] = function(ret, x)
13536
{
13537
if (cr.is_string(x))
13538
{
13539
ret.set_float(parseFloat(x));
13540
if (isNaN(ret.data))
13541
ret.data = 0;
13542
}
13543
else
13544
ret.set_float(x);
13545
};
13546
SysExps.prototype.str = function(ret, x)
13547
{
13548
if (cr.is_string(x))
13549
ret.set_string(x);
13550
else
13551
ret.set_string(x.toString());
13552
};
13553
SysExps.prototype.len = function(ret, x)
13554
{
13555
ret.set_int(x.length || 0);
13556
};
13557
SysExps.prototype.random = function (ret, a, b)
13558
{
13559
if (b === undefined)
13560
{
13561
ret.set_float(Math.random() * a);
13562
}
13563
else
13564
{
13565
ret.set_float(Math.random() * (b - a) + a);
13566
}
13567
};
13568
SysExps.prototype.sqrt = function(ret, x)
13569
{
13570
ret.set_float(Math.sqrt(x));
13571
};
13572
SysExps.prototype.abs = function(ret, x)
13573
{
13574
ret.set_float(Math.abs(x));
13575
};
13576
SysExps.prototype.round = function(ret, x)
13577
{
13578
ret.set_int(Math.round(x));
13579
};
13580
SysExps.prototype.floor = function(ret, x)
13581
{
13582
ret.set_int(Math.floor(x));
13583
};
13584
SysExps.prototype.ceil = function(ret, x)
13585
{
13586
ret.set_int(Math.ceil(x));
13587
};
13588
SysExps.prototype.sin = function(ret, x)
13589
{
13590
ret.set_float(Math.sin(cr.to_radians(x)));
13591
};
13592
SysExps.prototype.cos = function(ret, x)
13593
{
13594
ret.set_float(Math.cos(cr.to_radians(x)));
13595
};
13596
SysExps.prototype.tan = function(ret, x)
13597
{
13598
ret.set_float(Math.tan(cr.to_radians(x)));
13599
};
13600
SysExps.prototype.asin = function(ret, x)
13601
{
13602
ret.set_float(cr.to_degrees(Math.asin(x)));
13603
};
13604
SysExps.prototype.acos = function(ret, x)
13605
{
13606
ret.set_float(cr.to_degrees(Math.acos(x)));
13607
};
13608
SysExps.prototype.atan = function(ret, x)
13609
{
13610
ret.set_float(cr.to_degrees(Math.atan(x)));
13611
};
13612
SysExps.prototype.exp = function(ret, x)
13613
{
13614
ret.set_float(Math.exp(x));
13615
};
13616
SysExps.prototype.ln = function(ret, x)
13617
{
13618
ret.set_float(Math.log(x));
13619
};
13620
SysExps.prototype.log10 = function(ret, x)
13621
{
13622
ret.set_float(Math.log(x) / Math.LN10);
13623
};
13624
SysExps.prototype.max = function(ret)
13625
{
13626
var max_ = arguments[1];
13627
if (typeof max_ !== "number")
13628
max_ = 0;
13629
var i, len, a;
13630
for (i = 2, len = arguments.length; i < len; i++)
13631
{
13632
a = arguments[i];
13633
if (typeof a !== "number")
13634
continue; // ignore non-numeric types
13635
if (max_ < a)
13636
max_ = a;
13637
}
13638
ret.set_float(max_);
13639
};
13640
SysExps.prototype.min = function(ret)
13641
{
13642
var min_ = arguments[1];
13643
if (typeof min_ !== "number")
13644
min_ = 0;
13645
var i, len, a;
13646
for (i = 2, len = arguments.length; i < len; i++)
13647
{
13648
a = arguments[i];
13649
if (typeof a !== "number")
13650
continue; // ignore non-numeric types
13651
if (min_ > a)
13652
min_ = a;
13653
}
13654
ret.set_float(min_);
13655
};
13656
SysExps.prototype.dt = function(ret)
13657
{
13658
ret.set_float(this.runtime.dt);
13659
};
13660
SysExps.prototype.timescale = function(ret)
13661
{
13662
ret.set_float(this.runtime.timescale);
13663
};
13664
SysExps.prototype.wallclocktime = function(ret)
13665
{
13666
ret.set_float((Date.now() - this.runtime.start_time) / 1000.0);
13667
};
13668
SysExps.prototype.time = function(ret)
13669
{
13670
ret.set_float(this.runtime.kahanTime.sum);
13671
};
13672
SysExps.prototype.tickcount = function(ret)
13673
{
13674
ret.set_int(this.runtime.tickcount);
13675
};
13676
SysExps.prototype.objectcount = function(ret)
13677
{
13678
ret.set_int(this.runtime.objectcount);
13679
};
13680
SysExps.prototype.fps = function(ret)
13681
{
13682
ret.set_int(this.runtime.fps);
13683
};
13684
SysExps.prototype.loopindex = function(ret, name_)
13685
{
13686
var loop, i, len;
13687
if (!this.runtime.loop_stack.length)
13688
{
13689
ret.set_int(0);
13690
return;
13691
}
13692
if (name_)
13693
{
13694
for (i = this.runtime.loop_stack_index; i >= 0; --i)
13695
{
13696
loop = this.runtime.loop_stack[i];
13697
if (loop.name === name_)
13698
{
13699
ret.set_int(loop.index);
13700
return;
13701
}
13702
}
13703
ret.set_int(0);
13704
}
13705
else
13706
{
13707
loop = this.runtime.getCurrentLoop();
13708
ret.set_int(loop ? loop.index : -1);
13709
}
13710
};
13711
SysExps.prototype.distance = function(ret, x1, y1, x2, y2)
13712
{
13713
ret.set_float(cr.distanceTo(x1, y1, x2, y2));
13714
};
13715
SysExps.prototype.angle = function(ret, x1, y1, x2, y2)
13716
{
13717
ret.set_float(cr.to_degrees(cr.angleTo(x1, y1, x2, y2)));
13718
};
13719
SysExps.prototype.scrollx = function(ret)
13720
{
13721
ret.set_float(this.runtime.running_layout.scrollX);
13722
};
13723
SysExps.prototype.scrolly = function(ret)
13724
{
13725
ret.set_float(this.runtime.running_layout.scrollY);
13726
};
13727
SysExps.prototype.newline = function(ret)
13728
{
13729
ret.set_string("\n");
13730
};
13731
SysExps.prototype.lerp = function(ret, a, b, x)
13732
{
13733
ret.set_float(cr.lerp(a, b, x));
13734
};
13735
SysExps.prototype.qarp = function(ret, a, b, c, x)
13736
{
13737
ret.set_float(cr.qarp(a, b, c, x));
13738
};
13739
SysExps.prototype.cubic = function(ret, a, b, c, d, x)
13740
{
13741
ret.set_float(cr.cubic(a, b, c, d, x));
13742
};
13743
SysExps.prototype.cosp = function(ret, a, b, x)
13744
{
13745
ret.set_float(cr.cosp(a, b, x));
13746
};
13747
SysExps.prototype.windowwidth = function(ret)
13748
{
13749
ret.set_int(this.runtime.width);
13750
};
13751
SysExps.prototype.windowheight = function(ret)
13752
{
13753
ret.set_int(this.runtime.height);
13754
};
13755
SysExps.prototype.uppercase = function(ret, str)
13756
{
13757
ret.set_string(cr.is_string(str) ? str.toUpperCase() : "");
13758
};
13759
SysExps.prototype.lowercase = function(ret, str)
13760
{
13761
ret.set_string(cr.is_string(str) ? str.toLowerCase() : "");
13762
};
13763
SysExps.prototype.clamp = function(ret, x, l, u)
13764
{
13765
if (x < l)
13766
ret.set_float(l);
13767
else if (x > u)
13768
ret.set_float(u);
13769
else
13770
ret.set_float(x);
13771
};
13772
SysExps.prototype.layerscale = function (ret, layerparam)
13773
{
13774
var layer = this.runtime.getLayer(layerparam);
13775
if (!layer)
13776
ret.set_float(0);
13777
else
13778
ret.set_float(layer.scale);
13779
};
13780
SysExps.prototype.layeropacity = function (ret, layerparam)
13781
{
13782
var layer = this.runtime.getLayer(layerparam);
13783
if (!layer)
13784
ret.set_float(0);
13785
else
13786
ret.set_float(layer.opacity * 100);
13787
};
13788
SysExps.prototype.layerscalerate = function (ret, layerparam)
13789
{
13790
var layer = this.runtime.getLayer(layerparam);
13791
if (!layer)
13792
ret.set_float(0);
13793
else
13794
ret.set_float(layer.zoomRate);
13795
};
13796
SysExps.prototype.layerparallaxx = function (ret, layerparam)
13797
{
13798
var layer = this.runtime.getLayer(layerparam);
13799
if (!layer)
13800
ret.set_float(0);
13801
else
13802
ret.set_float(layer.parallaxX * 100);
13803
};
13804
SysExps.prototype.layerparallaxy = function (ret, layerparam)
13805
{
13806
var layer = this.runtime.getLayer(layerparam);
13807
if (!layer)
13808
ret.set_float(0);
13809
else
13810
ret.set_float(layer.parallaxY * 100);
13811
};
13812
SysExps.prototype.layerindex = function (ret, layerparam)
13813
{
13814
var layer = this.runtime.getLayer(layerparam);
13815
if (!layer)
13816
ret.set_int(-1);
13817
else
13818
ret.set_int(layer.index);
13819
};
13820
SysExps.prototype.layoutscale = function (ret)
13821
{
13822
if (this.runtime.running_layout)
13823
ret.set_float(this.runtime.running_layout.scale);
13824
else
13825
ret.set_float(0);
13826
};
13827
SysExps.prototype.layoutangle = function (ret)
13828
{
13829
ret.set_float(cr.to_degrees(this.runtime.running_layout.angle));
13830
};
13831
SysExps.prototype.layerangle = function (ret, layerparam)
13832
{
13833
var layer = this.runtime.getLayer(layerparam);
13834
if (!layer)
13835
ret.set_float(0);
13836
else
13837
ret.set_float(cr.to_degrees(layer.angle));
13838
};
13839
SysExps.prototype.layoutwidth = function (ret)
13840
{
13841
ret.set_int(this.runtime.running_layout.width);
13842
};
13843
SysExps.prototype.layoutheight = function (ret)
13844
{
13845
ret.set_int(this.runtime.running_layout.height);
13846
};
13847
SysExps.prototype.find = function (ret, text, searchstr)
13848
{
13849
if (cr.is_string(text) && cr.is_string(searchstr))
13850
ret.set_int(text.search(new RegExp(cr.regexp_escape(searchstr), "i")));
13851
else
13852
ret.set_int(-1);
13853
};
13854
SysExps.prototype.findcase = function (ret, text, searchstr)
13855
{
13856
if (cr.is_string(text) && cr.is_string(searchstr))
13857
ret.set_int(text.search(new RegExp(cr.regexp_escape(searchstr), "")));
13858
else
13859
ret.set_int(-1);
13860
};
13861
SysExps.prototype.left = function (ret, text, n)
13862
{
13863
ret.set_string(cr.is_string(text) ? text.substr(0, n) : "");
13864
};
13865
SysExps.prototype.right = function (ret, text, n)
13866
{
13867
ret.set_string(cr.is_string(text) ? text.substr(text.length - n) : "");
13868
};
13869
SysExps.prototype.mid = function (ret, text, index_, length_)
13870
{
13871
ret.set_string(cr.is_string(text) ? text.substr(index_, length_) : "");
13872
};
13873
SysExps.prototype.tokenat = function (ret, text, index_, sep)
13874
{
13875
if (cr.is_string(text) && cr.is_string(sep))
13876
{
13877
var arr = text.split(sep);
13878
var i = cr.floor(index_);
13879
if (i < 0 || i >= arr.length)
13880
ret.set_string("");
13881
else
13882
ret.set_string(arr[i]);
13883
}
13884
else
13885
ret.set_string("");
13886
};
13887
SysExps.prototype.tokencount = function (ret, text, sep)
13888
{
13889
if (cr.is_string(text) && text.length)
13890
ret.set_int(text.split(sep).length);
13891
else
13892
ret.set_int(0);
13893
};
13894
SysExps.prototype.replace = function (ret, text, find_, replace_)
13895
{
13896
if (cr.is_string(text) && cr.is_string(find_) && cr.is_string(replace_))
13897
ret.set_string(text.replace(new RegExp(cr.regexp_escape(find_), "gi"), replace_));
13898
else
13899
ret.set_string(cr.is_string(text) ? text : "");
13900
};
13901
SysExps.prototype.trim = function (ret, text)
13902
{
13903
ret.set_string(cr.is_string(text) ? text.trim() : "");
13904
};
13905
SysExps.prototype.pi = function (ret)
13906
{
13907
ret.set_float(cr.PI);
13908
};
13909
SysExps.prototype.layoutname = function (ret)
13910
{
13911
if (this.runtime.running_layout)
13912
ret.set_string(this.runtime.running_layout.name);
13913
else
13914
ret.set_string("");
13915
};
13916
SysExps.prototype.renderer = function (ret)
13917
{
13918
ret.set_string(this.runtime.gl ? "webgl" : "canvas2d");
13919
};
13920
SysExps.prototype.rendererdetail = function (ret)
13921
{
13922
ret.set_string(this.runtime.glUnmaskedRenderer);
13923
};
13924
SysExps.prototype.anglediff = function (ret, a, b)
13925
{
13926
ret.set_float(cr.to_degrees(cr.angleDiff(cr.to_radians(a), cr.to_radians(b))));
13927
};
13928
SysExps.prototype.choose = function (ret)
13929
{
13930
var index = cr.floor(Math.random() * (arguments.length - 1));
13931
ret.set_any(arguments[index + 1]);
13932
};
13933
SysExps.prototype.rgb = function (ret, r, g, b)
13934
{
13935
ret.set_int(cr.RGB(r, g, b));
13936
};
13937
SysExps.prototype.projectversion = function (ret)
13938
{
13939
ret.set_string(this.runtime.versionstr);
13940
};
13941
SysExps.prototype.projectname = function (ret)
13942
{
13943
ret.set_string(this.runtime.projectName);
13944
};
13945
SysExps.prototype.anglelerp = function (ret, a, b, x)
13946
{
13947
a = cr.to_radians(a);
13948
b = cr.to_radians(b);
13949
var diff = cr.angleDiff(a, b);
13950
if (cr.angleClockwise(b, a))
13951
{
13952
ret.set_float(cr.to_clamped_degrees(a + diff * x));
13953
}
13954
else
13955
{
13956
ret.set_float(cr.to_clamped_degrees(a - diff * x));
13957
}
13958
};
13959
SysExps.prototype.anglerotate = function (ret, a, b, c)
13960
{
13961
a = cr.to_radians(a);
13962
b = cr.to_radians(b);
13963
c = cr.to_radians(c);
13964
ret.set_float(cr.to_clamped_degrees(cr.angleRotate(a, b, c)));
13965
};
13966
SysExps.prototype.zeropad = function (ret, n, d)
13967
{
13968
var s = (n < 0 ? "-" : "");
13969
if (n < 0) n = -n;
13970
var zeroes = d - n.toString().length;
13971
for (var i = 0; i < zeroes; i++)
13972
s += "0";
13973
ret.set_string(s + n.toString());
13974
};
13975
SysExps.prototype.cpuutilisation = function (ret)
13976
{
13977
ret.set_float(this.runtime.cpuutilisation / 1000);
13978
};
13979
SysExps.prototype.viewportleft = function (ret, layerparam)
13980
{
13981
var layer = this.runtime.getLayer(layerparam);
13982
ret.set_float(layer ? layer.viewLeft : 0);
13983
};
13984
SysExps.prototype.viewporttop = function (ret, layerparam)
13985
{
13986
var layer = this.runtime.getLayer(layerparam);
13987
ret.set_float(layer ? layer.viewTop : 0);
13988
};
13989
SysExps.prototype.viewportright = function (ret, layerparam)
13990
{
13991
var layer = this.runtime.getLayer(layerparam);
13992
ret.set_float(layer ? layer.viewRight : 0);
13993
};
13994
SysExps.prototype.viewportbottom = function (ret, layerparam)
13995
{
13996
var layer = this.runtime.getLayer(layerparam);
13997
ret.set_float(layer ? layer.viewBottom : 0);
13998
};
13999
SysExps.prototype.loadingprogress = function (ret)
14000
{
14001
ret.set_float(this.runtime.loadingprogress);
14002
};
14003
SysExps.prototype.unlerp = function(ret, a, b, y)
14004
{
14005
ret.set_float(cr.unlerp(a, b, y));
14006
};
14007
SysExps.prototype.canvassnapshot = function (ret)
14008
{
14009
ret.set_string(this.runtime.snapshotData);
14010
};
14011
SysExps.prototype.urlencode = function (ret, s)
14012
{
14013
ret.set_string(encodeURIComponent(s));
14014
};
14015
SysExps.prototype.urldecode = function (ret, s)
14016
{
14017
ret.set_string(decodeURIComponent(s));
14018
};
14019
SysExps.prototype.canvastolayerx = function (ret, layerparam, x, y)
14020
{
14021
var layer = this.runtime.getLayer(layerparam);
14022
ret.set_float(layer ? layer.canvasToLayer(x, y, true) : 0);
14023
};
14024
SysExps.prototype.canvastolayery = function (ret, layerparam, x, y)
14025
{
14026
var layer = this.runtime.getLayer(layerparam);
14027
ret.set_float(layer ? layer.canvasToLayer(x, y, false) : 0);
14028
};
14029
SysExps.prototype.layertocanvasx = function (ret, layerparam, x, y)
14030
{
14031
var layer = this.runtime.getLayer(layerparam);
14032
ret.set_float(layer ? layer.layerToCanvas(x, y, true) : 0);
14033
};
14034
SysExps.prototype.layertocanvasy = function (ret, layerparam, x, y)
14035
{
14036
var layer = this.runtime.getLayer(layerparam);
14037
ret.set_float(layer ? layer.layerToCanvas(x, y, false) : 0);
14038
};
14039
SysExps.prototype.savestatejson = function (ret)
14040
{
14041
ret.set_string(this.runtime.lastSaveJson);
14042
};
14043
SysExps.prototype.imagememoryusage = function (ret)
14044
{
14045
if (this.runtime.glwrap)
14046
ret.set_float(Math.round(100 * this.runtime.glwrap.estimateVRAM() / (1024 * 1024)) / 100);
14047
else
14048
ret.set_float(0);
14049
};
14050
SysExps.prototype.regexsearch = function (ret, str_, regex_, flags_)
14051
{
14052
var regex = getRegex(regex_, flags_);
14053
ret.set_int(str_ ? str_.search(regex) : -1);
14054
};
14055
SysExps.prototype.regexreplace = function (ret, str_, regex_, flags_, replace_)
14056
{
14057
var regex = getRegex(regex_, flags_);
14058
ret.set_string(str_ ? str_.replace(regex, replace_) : "");
14059
};
14060
var regexMatches = [];
14061
var lastMatchesStr = "";
14062
var lastMatchesRegex = "";
14063
var lastMatchesFlags = "";
14064
function updateRegexMatches(str_, regex_, flags_)
14065
{
14066
if (str_ === lastMatchesStr && regex_ === lastMatchesRegex && flags_ === lastMatchesFlags)
14067
return;
14068
var regex = getRegex(regex_, flags_);
14069
regexMatches = str_.match(regex);
14070
lastMatchesStr = str_;
14071
lastMatchesRegex = regex_;
14072
lastMatchesFlags = flags_;
14073
};
14074
SysExps.prototype.regexmatchcount = function (ret, str_, regex_, flags_)
14075
{
14076
var regex = getRegex(regex_, flags_);
14077
updateRegexMatches(str_.toString(), regex_, flags_);
14078
ret.set_int(regexMatches ? regexMatches.length : 0);
14079
};
14080
SysExps.prototype.regexmatchat = function (ret, str_, regex_, flags_, index_)
14081
{
14082
index_ = Math.floor(index_);
14083
var regex = getRegex(regex_, flags_);
14084
updateRegexMatches(str_.toString(), regex_, flags_);
14085
if (!regexMatches || index_ < 0 || index_ >= regexMatches.length)
14086
ret.set_string("");
14087
else
14088
ret.set_string(regexMatches[index_]);
14089
};
14090
SysExps.prototype.infinity = function (ret)
14091
{
14092
ret.set_float(Infinity);
14093
};
14094
SysExps.prototype.setbit = function (ret, n, b, v)
14095
{
14096
n = n | 0;
14097
b = b | 0;
14098
v = (v !== 0 ? 1 : 0);
14099
ret.set_int((n & ~(1 << b)) | (v << b));
14100
};
14101
SysExps.prototype.togglebit = function (ret, n, b)
14102
{
14103
n = n | 0;
14104
b = b | 0;
14105
ret.set_int(n ^ (1 << b));
14106
};
14107
SysExps.prototype.getbit = function (ret, n, b)
14108
{
14109
n = n | 0;
14110
b = b | 0;
14111
ret.set_int((n & (1 << b)) ? 1 : 0);
14112
};
14113
SysExps.prototype.originalwindowwidth = function (ret)
14114
{
14115
ret.set_int(this.runtime.original_width);
14116
};
14117
SysExps.prototype.originalwindowheight = function (ret)
14118
{
14119
ret.set_int(this.runtime.original_height);
14120
};
14121
sysProto.exps = new SysExps();
14122
sysProto.runWaits = function ()
14123
{
14124
var i, j, len, w, k, s, ss;
14125
var evinfo = this.runtime.getCurrentEventStack();
14126
for (i = 0, len = this.waits.length; i < len; i++)
14127
{
14128
w = this.waits[i];
14129
if (w.time === -1) // signalled wait
14130
{
14131
if (!w.signalled)
14132
continue; // not yet signalled
14133
}
14134
else // timer wait
14135
{
14136
if (w.time > this.runtime.kahanTime.sum)
14137
continue; // timer not yet expired
14138
}
14139
evinfo.current_event = w.ev;
14140
evinfo.actindex = w.actindex;
14141
evinfo.cndindex = 0;
14142
for (k in w.sols)
14143
{
14144
if (w.sols.hasOwnProperty(k))
14145
{
14146
s = this.runtime.types_by_index[parseInt(k, 10)].getCurrentSol();
14147
ss = w.sols[k];
14148
s.select_all = ss.sa;
14149
cr.shallowAssignArray(s.instances, ss.insts);
14150
freeSolStateObject(ss);
14151
}
14152
}
14153
w.ev.resume_actions_and_subevents();
14154
this.runtime.clearSol(w.solModifiers);
14155
w.deleteme = true;
14156
}
14157
for (i = 0, j = 0, len = this.waits.length; i < len; i++)
14158
{
14159
w = this.waits[i];
14160
this.waits[j] = w;
14161
if (w.deleteme)
14162
freeWaitObject(w);
14163
else
14164
j++;
14165
}
14166
cr.truncateArray(this.waits, j);
14167
};
14168
}());
14169
;
14170
(function () {
14171
cr.add_common_aces = function (m, pluginProto)
14172
{
14173
var singleglobal_ = m[1];
14174
var position_aces = m[3];
14175
var size_aces = m[4];
14176
var angle_aces = m[5];
14177
var appearance_aces = m[6];
14178
var zorder_aces = m[7];
14179
var effects_aces = m[8];
14180
if (!pluginProto.cnds)
14181
pluginProto.cnds = {};
14182
if (!pluginProto.acts)
14183
pluginProto.acts = {};
14184
if (!pluginProto.exps)
14185
pluginProto.exps = {};
14186
var cnds = pluginProto.cnds;
14187
var acts = pluginProto.acts;
14188
var exps = pluginProto.exps;
14189
if (position_aces)
14190
{
14191
cnds.CompareX = function (cmp, x)
14192
{
14193
return cr.do_cmp(this.x, cmp, x);
14194
};
14195
cnds.CompareY = function (cmp, y)
14196
{
14197
return cr.do_cmp(this.y, cmp, y);
14198
};
14199
cnds.IsOnScreen = function ()
14200
{
14201
var layer = this.layer;
14202
this.update_bbox();
14203
var bbox = this.bbox;
14204
return !(bbox.right < layer.viewLeft || bbox.bottom < layer.viewTop || bbox.left > layer.viewRight || bbox.top > layer.viewBottom);
14205
};
14206
cnds.IsOutsideLayout = function ()
14207
{
14208
this.update_bbox();
14209
var bbox = this.bbox;
14210
var layout = this.runtime.running_layout;
14211
return (bbox.right < 0 || bbox.bottom < 0 || bbox.left > layout.width || bbox.top > layout.height);
14212
};
14213
cnds.PickDistance = function (which, x, y)
14214
{
14215
var sol = this.getCurrentSol();
14216
var instances = sol.getObjects();
14217
if (!instances.length)
14218
return false;
14219
var inst = instances[0];
14220
var pickme = inst;
14221
var dist = cr.distanceTo(inst.x, inst.y, x, y);
14222
var i, len, d;
14223
for (i = 1, len = instances.length; i < len; i++)
14224
{
14225
inst = instances[i];
14226
d = cr.distanceTo(inst.x, inst.y, x, y);
14227
if ((which === 0 && d < dist) || (which === 1 && d > dist))
14228
{
14229
dist = d;
14230
pickme = inst;
14231
}
14232
}
14233
sol.pick_one(pickme);
14234
return true;
14235
};
14236
acts.SetX = function (x)
14237
{
14238
if (this.x !== x)
14239
{
14240
this.x = x;
14241
this.set_bbox_changed();
14242
}
14243
};
14244
acts.SetY = function (y)
14245
{
14246
if (this.y !== y)
14247
{
14248
this.y = y;
14249
this.set_bbox_changed();
14250
}
14251
};
14252
acts.SetPos = function (x, y)
14253
{
14254
if (this.x !== x || this.y !== y)
14255
{
14256
this.x = x;
14257
this.y = y;
14258
this.set_bbox_changed();
14259
}
14260
};
14261
acts.SetPosToObject = function (obj, imgpt)
14262
{
14263
var inst = obj.getPairedInstance(this);
14264
if (!inst)
14265
return;
14266
var newx, newy;
14267
if (inst.getImagePoint)
14268
{
14269
newx = inst.getImagePoint(imgpt, true);
14270
newy = inst.getImagePoint(imgpt, false);
14271
}
14272
else
14273
{
14274
newx = inst.x;
14275
newy = inst.y;
14276
}
14277
if (this.x !== newx || this.y !== newy)
14278
{
14279
this.x = newx;
14280
this.y = newy;
14281
this.set_bbox_changed();
14282
}
14283
};
14284
acts.MoveForward = function (dist)
14285
{
14286
if (dist !== 0)
14287
{
14288
this.x += Math.cos(this.angle) * dist;
14289
this.y += Math.sin(this.angle) * dist;
14290
this.set_bbox_changed();
14291
}
14292
};
14293
acts.MoveAtAngle = function (a, dist)
14294
{
14295
if (dist !== 0)
14296
{
14297
this.x += Math.cos(cr.to_radians(a)) * dist;
14298
this.y += Math.sin(cr.to_radians(a)) * dist;
14299
this.set_bbox_changed();
14300
}
14301
};
14302
exps.X = function (ret)
14303
{
14304
ret.set_float(this.x);
14305
};
14306
exps.Y = function (ret)
14307
{
14308
ret.set_float(this.y);
14309
};
14310
exps.dt = function (ret)
14311
{
14312
ret.set_float(this.runtime.getDt(this));
14313
};
14314
}
14315
if (size_aces)
14316
{
14317
cnds.CompareWidth = function (cmp, w)
14318
{
14319
return cr.do_cmp(this.width, cmp, w);
14320
};
14321
cnds.CompareHeight = function (cmp, h)
14322
{
14323
return cr.do_cmp(this.height, cmp, h);
14324
};
14325
acts.SetWidth = function (w)
14326
{
14327
if (this.width !== w)
14328
{
14329
this.width = w;
14330
this.set_bbox_changed();
14331
}
14332
};
14333
acts.SetHeight = function (h)
14334
{
14335
if (this.height !== h)
14336
{
14337
this.height = h;
14338
this.set_bbox_changed();
14339
}
14340
};
14341
acts.SetSize = function (w, h)
14342
{
14343
if (this.width !== w || this.height !== h)
14344
{
14345
this.width = w;
14346
this.height = h;
14347
this.set_bbox_changed();
14348
}
14349
};
14350
exps.Width = function (ret)
14351
{
14352
ret.set_float(this.width);
14353
};
14354
exps.Height = function (ret)
14355
{
14356
ret.set_float(this.height);
14357
};
14358
exps.BBoxLeft = function (ret)
14359
{
14360
this.update_bbox();
14361
ret.set_float(this.bbox.left);
14362
};
14363
exps.BBoxTop = function (ret)
14364
{
14365
this.update_bbox();
14366
ret.set_float(this.bbox.top);
14367
};
14368
exps.BBoxRight = function (ret)
14369
{
14370
this.update_bbox();
14371
ret.set_float(this.bbox.right);
14372
};
14373
exps.BBoxBottom = function (ret)
14374
{
14375
this.update_bbox();
14376
ret.set_float(this.bbox.bottom);
14377
};
14378
}
14379
if (angle_aces)
14380
{
14381
cnds.AngleWithin = function (within, a)
14382
{
14383
return cr.angleDiff(this.angle, cr.to_radians(a)) <= cr.to_radians(within);
14384
};
14385
cnds.IsClockwiseFrom = function (a)
14386
{
14387
return cr.angleClockwise(this.angle, cr.to_radians(a));
14388
};
14389
cnds.IsBetweenAngles = function (a, b)
14390
{
14391
var lower = cr.to_clamped_radians(a);
14392
var upper = cr.to_clamped_radians(b);
14393
var angle = cr.clamp_angle(this.angle);
14394
var obtuse = (!cr.angleClockwise(upper, lower));
14395
if (obtuse)
14396
return !(!cr.angleClockwise(angle, lower) && cr.angleClockwise(angle, upper));
14397
else
14398
return cr.angleClockwise(angle, lower) && !cr.angleClockwise(angle, upper);
14399
};
14400
acts.SetAngle = function (a)
14401
{
14402
var newangle = cr.to_radians(cr.clamp_angle_degrees(a));
14403
if (isNaN(newangle))
14404
return;
14405
if (this.angle !== newangle)
14406
{
14407
this.angle = newangle;
14408
this.set_bbox_changed();
14409
}
14410
};
14411
acts.RotateClockwise = function (a)
14412
{
14413
if (a !== 0 && !isNaN(a))
14414
{
14415
this.angle += cr.to_radians(a);
14416
this.angle = cr.clamp_angle(this.angle);
14417
this.set_bbox_changed();
14418
}
14419
};
14420
acts.RotateCounterclockwise = function (a)
14421
{
14422
if (a !== 0 && !isNaN(a))
14423
{
14424
this.angle -= cr.to_radians(a);
14425
this.angle = cr.clamp_angle(this.angle);
14426
this.set_bbox_changed();
14427
}
14428
};
14429
acts.RotateTowardAngle = function (amt, target)
14430
{
14431
var newangle = cr.angleRotate(this.angle, cr.to_radians(target), cr.to_radians(amt));
14432
if (isNaN(newangle))
14433
return;
14434
if (this.angle !== newangle)
14435
{
14436
this.angle = newangle;
14437
this.set_bbox_changed();
14438
}
14439
};
14440
acts.RotateTowardPosition = function (amt, x, y)
14441
{
14442
var dx = x - this.x;
14443
var dy = y - this.y;
14444
var target = Math.atan2(dy, dx);
14445
var newangle = cr.angleRotate(this.angle, target, cr.to_radians(amt));
14446
if (isNaN(newangle))
14447
return;
14448
if (this.angle !== newangle)
14449
{
14450
this.angle = newangle;
14451
this.set_bbox_changed();
14452
}
14453
};
14454
acts.SetTowardPosition = function (x, y)
14455
{
14456
var dx = x - this.x;
14457
var dy = y - this.y;
14458
var newangle = Math.atan2(dy, dx);
14459
if (isNaN(newangle))
14460
return;
14461
if (this.angle !== newangle)
14462
{
14463
this.angle = newangle;
14464
this.set_bbox_changed();
14465
}
14466
};
14467
exps.Angle = function (ret)
14468
{
14469
ret.set_float(cr.to_clamped_degrees(this.angle));
14470
};
14471
}
14472
if (!singleglobal_)
14473
{
14474
cnds.CompareInstanceVar = function (iv, cmp, val)
14475
{
14476
return cr.do_cmp(this.instance_vars[iv], cmp, val);
14477
};
14478
cnds.IsBoolInstanceVarSet = function (iv)
14479
{
14480
return this.instance_vars[iv];
14481
};
14482
cnds.PickInstVarHiLow = function (which, iv)
14483
{
14484
var sol = this.getCurrentSol();
14485
var instances = sol.getObjects();
14486
if (!instances.length)
14487
return false;
14488
var inst = instances[0];
14489
var pickme = inst;
14490
var val = inst.instance_vars[iv];
14491
var i, len, v;
14492
for (i = 1, len = instances.length; i < len; i++)
14493
{
14494
inst = instances[i];
14495
v = inst.instance_vars[iv];
14496
if ((which === 0 && v < val) || (which === 1 && v > val))
14497
{
14498
val = v;
14499
pickme = inst;
14500
}
14501
}
14502
sol.pick_one(pickme);
14503
return true;
14504
};
14505
cnds.PickByUID = function (u)
14506
{
14507
var i, len, j, inst, families, instances, sol;
14508
var cnd = this.runtime.getCurrentCondition();
14509
if (cnd.inverted)
14510
{
14511
sol = this.getCurrentSol();
14512
if (sol.select_all)
14513
{
14514
sol.select_all = false;
14515
cr.clearArray(sol.instances);
14516
cr.clearArray(sol.else_instances);
14517
instances = this.instances;
14518
for (i = 0, len = instances.length; i < len; i++)
14519
{
14520
inst = instances[i];
14521
if (inst.uid === u)
14522
sol.else_instances.push(inst);
14523
else
14524
sol.instances.push(inst);
14525
}
14526
this.applySolToContainer();
14527
return !!sol.instances.length;
14528
}
14529
else
14530
{
14531
for (i = 0, j = 0, len = sol.instances.length; i < len; i++)
14532
{
14533
inst = sol.instances[i];
14534
sol.instances[j] = inst;
14535
if (inst.uid === u)
14536
{
14537
sol.else_instances.push(inst);
14538
}
14539
else
14540
j++;
14541
}
14542
cr.truncateArray(sol.instances, j);
14543
this.applySolToContainer();
14544
return !!sol.instances.length;
14545
}
14546
}
14547
else
14548
{
14549
inst = this.runtime.getObjectByUID(u);
14550
if (!inst)
14551
return false;
14552
sol = this.getCurrentSol();
14553
if (!sol.select_all && sol.instances.indexOf(inst) === -1)
14554
return false; // not picked
14555
if (this.is_family)
14556
{
14557
families = inst.type.families;
14558
for (i = 0, len = families.length; i < len; i++)
14559
{
14560
if (families[i] === this)
14561
{
14562
sol.pick_one(inst);
14563
this.applySolToContainer();
14564
return true;
14565
}
14566
}
14567
}
14568
else if (inst.type === this)
14569
{
14570
sol.pick_one(inst);
14571
this.applySolToContainer();
14572
return true;
14573
}
14574
return false;
14575
}
14576
};
14577
cnds.OnCreated = function ()
14578
{
14579
return true;
14580
};
14581
cnds.OnDestroyed = function ()
14582
{
14583
return true;
14584
};
14585
acts.SetInstanceVar = function (iv, val)
14586
{
14587
var myinstvars = this.instance_vars;
14588
if (cr.is_number(myinstvars[iv]))
14589
{
14590
if (cr.is_number(val))
14591
myinstvars[iv] = val;
14592
else
14593
myinstvars[iv] = parseFloat(val);
14594
}
14595
else if (cr.is_string(myinstvars[iv]))
14596
{
14597
if (cr.is_string(val))
14598
myinstvars[iv] = val;
14599
else
14600
myinstvars[iv] = val.toString();
14601
}
14602
else
14603
;
14604
};
14605
acts.AddInstanceVar = function (iv, val)
14606
{
14607
var myinstvars = this.instance_vars;
14608
if (cr.is_number(myinstvars[iv]))
14609
{
14610
if (cr.is_number(val))
14611
myinstvars[iv] += val;
14612
else
14613
myinstvars[iv] += parseFloat(val);
14614
}
14615
else if (cr.is_string(myinstvars[iv]))
14616
{
14617
if (cr.is_string(val))
14618
myinstvars[iv] += val;
14619
else
14620
myinstvars[iv] += val.toString();
14621
}
14622
else
14623
;
14624
};
14625
acts.SubInstanceVar = function (iv, val)
14626
{
14627
var myinstvars = this.instance_vars;
14628
if (cr.is_number(myinstvars[iv]))
14629
{
14630
if (cr.is_number(val))
14631
myinstvars[iv] -= val;
14632
else
14633
myinstvars[iv] -= parseFloat(val);
14634
}
14635
else
14636
;
14637
};
14638
acts.SetBoolInstanceVar = function (iv, val)
14639
{
14640
this.instance_vars[iv] = val ? 1 : 0;
14641
};
14642
acts.ToggleBoolInstanceVar = function (iv)
14643
{
14644
this.instance_vars[iv] = 1 - this.instance_vars[iv];
14645
};
14646
acts.Destroy = function ()
14647
{
14648
this.runtime.DestroyInstance(this);
14649
};
14650
if (!acts.LoadFromJsonString)
14651
{
14652
acts.LoadFromJsonString = function (str_)
14653
{
14654
var o, i, len, binst;
14655
try {
14656
o = JSON.parse(str_);
14657
}
14658
catch (e) {
14659
return;
14660
}
14661
this.runtime.loadInstanceFromJSON(this, o, true);
14662
if (this.afterLoad)
14663
this.afterLoad();
14664
if (this.behavior_insts)
14665
{
14666
for (i = 0, len = this.behavior_insts.length; i < len; ++i)
14667
{
14668
binst = this.behavior_insts[i];
14669
if (binst.afterLoad)
14670
binst.afterLoad();
14671
}
14672
}
14673
};
14674
}
14675
exps.Count = function (ret)
14676
{
14677
var count = ret.object_class.instances.length;
14678
var i, len, inst;
14679
for (i = 0, len = this.runtime.createRow.length; i < len; i++)
14680
{
14681
inst = this.runtime.createRow[i];
14682
if (ret.object_class.is_family)
14683
{
14684
if (inst.type.families.indexOf(ret.object_class) >= 0)
14685
count++;
14686
}
14687
else
14688
{
14689
if (inst.type === ret.object_class)
14690
count++;
14691
}
14692
}
14693
ret.set_int(count);
14694
};
14695
exps.PickedCount = function (ret)
14696
{
14697
ret.set_int(ret.object_class.getCurrentSol().getObjects().length);
14698
};
14699
exps.UID = function (ret)
14700
{
14701
ret.set_int(this.uid);
14702
};
14703
exps.IID = function (ret)
14704
{
14705
ret.set_int(this.get_iid());
14706
};
14707
if (!exps.AsJSON)
14708
{
14709
exps.AsJSON = function (ret)
14710
{
14711
ret.set_string(JSON.stringify(this.runtime.saveInstanceToJSON(this, true)));
14712
};
14713
}
14714
}
14715
if (appearance_aces)
14716
{
14717
cnds.IsVisible = function ()
14718
{
14719
return this.visible;
14720
};
14721
acts.SetVisible = function (v)
14722
{
14723
if (!v !== !this.visible)
14724
{
14725
this.visible = !!v;
14726
this.runtime.redraw = true;
14727
}
14728
};
14729
cnds.CompareOpacity = function (cmp, x)
14730
{
14731
return cr.do_cmp(cr.round6dp(this.opacity * 100), cmp, x);
14732
};
14733
acts.SetOpacity = function (x)
14734
{
14735
var new_opacity = x / 100.0;
14736
if (new_opacity < 0)
14737
new_opacity = 0;
14738
else if (new_opacity > 1)
14739
new_opacity = 1;
14740
if (new_opacity !== this.opacity)
14741
{
14742
this.opacity = new_opacity;
14743
this.runtime.redraw = true;
14744
}
14745
};
14746
exps.Opacity = function (ret)
14747
{
14748
ret.set_float(cr.round6dp(this.opacity * 100.0));
14749
};
14750
}
14751
if (zorder_aces)
14752
{
14753
cnds.IsOnLayer = function (layer_)
14754
{
14755
if (!layer_)
14756
return false;
14757
return this.layer === layer_;
14758
};
14759
cnds.PickTopBottom = function (which_)
14760
{
14761
var sol = this.getCurrentSol();
14762
var instances = sol.getObjects();
14763
if (!instances.length)
14764
return false;
14765
var inst = instances[0];
14766
var pickme = inst;
14767
var i, len;
14768
for (i = 1, len = instances.length; i < len; i++)
14769
{
14770
inst = instances[i];
14771
if (which_ === 0)
14772
{
14773
if (inst.layer.index > pickme.layer.index || (inst.layer.index === pickme.layer.index && inst.get_zindex() > pickme.get_zindex()))
14774
{
14775
pickme = inst;
14776
}
14777
}
14778
else
14779
{
14780
if (inst.layer.index < pickme.layer.index || (inst.layer.index === pickme.layer.index && inst.get_zindex() < pickme.get_zindex()))
14781
{
14782
pickme = inst;
14783
}
14784
}
14785
}
14786
sol.pick_one(pickme);
14787
return true;
14788
};
14789
acts.MoveToTop = function ()
14790
{
14791
var layer = this.layer;
14792
var layer_instances = layer.instances;
14793
if (layer_instances.length && layer_instances[layer_instances.length - 1] === this)
14794
return; // is already at top
14795
layer.removeFromInstanceList(this, false);
14796
layer.appendToInstanceList(this, false);
14797
this.runtime.redraw = true;
14798
};
14799
acts.MoveToBottom = function ()
14800
{
14801
var layer = this.layer;
14802
var layer_instances = layer.instances;
14803
if (layer_instances.length && layer_instances[0] === this)
14804
return; // is already at bottom
14805
layer.removeFromInstanceList(this, false);
14806
layer.prependToInstanceList(this, false);
14807
this.runtime.redraw = true;
14808
};
14809
acts.MoveToLayer = function (layerMove)
14810
{
14811
if (!layerMove || layerMove == this.layer)
14812
return;
14813
this.layer.removeFromInstanceList(this, true);
14814
this.layer = layerMove;
14815
layerMove.appendToInstanceList(this, true);
14816
this.runtime.redraw = true;
14817
};
14818
acts.ZMoveToObject = function (where_, obj_)
14819
{
14820
var isafter = (where_ === 0);
14821
if (!obj_)
14822
return;
14823
var other = obj_.getFirstPicked(this);
14824
if (!other || other.uid === this.uid)
14825
return;
14826
if (this.layer.index !== other.layer.index)
14827
{
14828
this.layer.removeFromInstanceList(this, true);
14829
this.layer = other.layer;
14830
other.layer.appendToInstanceList(this, true);
14831
}
14832
this.layer.moveInstanceAdjacent(this, other, isafter);
14833
this.runtime.redraw = true;
14834
};
14835
exps.LayerNumber = function (ret)
14836
{
14837
ret.set_int(this.layer.number);
14838
};
14839
exps.LayerName = function (ret)
14840
{
14841
ret.set_string(this.layer.name);
14842
};
14843
exps.ZIndex = function (ret)
14844
{
14845
ret.set_int(this.get_zindex());
14846
};
14847
}
14848
if (effects_aces)
14849
{
14850
acts.SetEffectEnabled = function (enable_, effectname_)
14851
{
14852
if (!this.runtime.glwrap)
14853
return;
14854
var i = this.type.getEffectIndexByName(effectname_);
14855
if (i < 0)
14856
return; // effect name not found
14857
var enable = (enable_ === 1);
14858
if (this.active_effect_flags[i] === enable)
14859
return; // no change
14860
this.active_effect_flags[i] = enable;
14861
this.updateActiveEffects();
14862
this.runtime.redraw = true;
14863
};
14864
acts.SetEffectParam = function (effectname_, index_, value_)
14865
{
14866
if (!this.runtime.glwrap)
14867
return;
14868
var i = this.type.getEffectIndexByName(effectname_);
14869
if (i < 0)
14870
return; // effect name not found
14871
var et = this.type.effect_types[i];
14872
var params = this.effect_params[i];
14873
index_ = Math.floor(index_);
14874
if (index_ < 0 || index_ >= params.length)
14875
return; // effect index out of bounds
14876
if (this.runtime.glwrap.getProgramParameterType(et.shaderindex, index_) === 1)
14877
value_ /= 100.0;
14878
if (params[index_] === value_)
14879
return; // no change
14880
params[index_] = value_;
14881
if (et.active)
14882
this.runtime.redraw = true;
14883
};
14884
}
14885
};
14886
cr.set_bbox_changed = function ()
14887
{
14888
this.bbox_changed = true; // will recreate next time box requested
14889
this.cell_changed = true;
14890
this.type.any_cell_changed = true; // avoid unnecessary updateAllBBox() calls
14891
this.runtime.redraw = true; // assume runtime needs to redraw
14892
var i, len, callbacks = this.bbox_changed_callbacks;
14893
for (i = 0, len = callbacks.length; i < len; ++i)
14894
{
14895
callbacks[i](this);
14896
}
14897
if (this.layer.useRenderCells)
14898
this.update_bbox();
14899
};
14900
cr.add_bbox_changed_callback = function (f)
14901
{
14902
if (f)
14903
{
14904
this.bbox_changed_callbacks.push(f);
14905
}
14906
};
14907
cr.update_bbox = function ()
14908
{
14909
if (!this.bbox_changed)
14910
return; // bounding box not changed
14911
var bbox = this.bbox;
14912
var bquad = this.bquad;
14913
bbox.set(this.x, this.y, this.x + this.width, this.y + this.height);
14914
bbox.offset(-this.hotspotX * this.width, -this.hotspotY * this.height);
14915
if (!this.angle)
14916
{
14917
bquad.set_from_rect(bbox); // make bounding quad from box
14918
}
14919
else
14920
{
14921
bbox.offset(-this.x, -this.y); // translate to origin
14922
bquad.set_from_rotated_rect(bbox, this.angle); // rotate around origin
14923
bquad.offset(this.x, this.y); // translate back to original position
14924
bquad.bounding_box(bbox);
14925
}
14926
bbox.normalize();
14927
this.bbox_changed = false; // bounding box up to date
14928
this.update_render_cell();
14929
};
14930
var tmprc = new cr.rect(0, 0, 0, 0);
14931
cr.update_render_cell = function ()
14932
{
14933
if (!this.layer.useRenderCells)
14934
return;
14935
var mygrid = this.layer.render_grid;
14936
var bbox = this.bbox;
14937
tmprc.set(mygrid.XToCell(bbox.left), mygrid.YToCell(bbox.top), mygrid.XToCell(bbox.right), mygrid.YToCell(bbox.bottom));
14938
if (this.rendercells.equals(tmprc))
14939
return;
14940
if (this.rendercells.right < this.rendercells.left)
14941
mygrid.update(this, null, tmprc); // first insertion with invalid rect: don't provide old range
14942
else
14943
mygrid.update(this, this.rendercells, tmprc);
14944
this.rendercells.copy(tmprc);
14945
this.layer.render_list_stale = true;
14946
};
14947
cr.update_collision_cell = function ()
14948
{
14949
if (!this.cell_changed || !this.collisionsEnabled)
14950
return;
14951
this.update_bbox();
14952
var mygrid = this.type.collision_grid;
14953
var bbox = this.bbox;
14954
tmprc.set(mygrid.XToCell(bbox.left), mygrid.YToCell(bbox.top), mygrid.XToCell(bbox.right), mygrid.YToCell(bbox.bottom));
14955
if (this.collcells.equals(tmprc))
14956
return;
14957
if (this.collcells.right < this.collcells.left)
14958
mygrid.update(this, null, tmprc); // first insertion with invalid rect: don't provide old range
14959
else
14960
mygrid.update(this, this.collcells, tmprc);
14961
this.collcells.copy(tmprc);
14962
this.cell_changed = false;
14963
};
14964
cr.inst_contains_pt = function (x, y)
14965
{
14966
if (!this.bbox.contains_pt(x, y))
14967
return false;
14968
if (!this.bquad.contains_pt(x, y))
14969
return false;
14970
if (this.tilemap_exists)
14971
return this.testPointOverlapTile(x, y);
14972
if (this.collision_poly && !this.collision_poly.is_empty())
14973
{
14974
this.collision_poly.cache_poly(this.width, this.height, this.angle);
14975
return this.collision_poly.contains_pt(x - this.x, y - this.y);
14976
}
14977
else
14978
return true;
14979
};
14980
cr.inst_get_iid = function ()
14981
{
14982
this.type.updateIIDs();
14983
return this.iid;
14984
};
14985
cr.inst_get_zindex = function ()
14986
{
14987
this.layer.updateZIndices();
14988
return this.zindex;
14989
};
14990
cr.inst_updateActiveEffects = function ()
14991
{
14992
cr.clearArray(this.active_effect_types);
14993
var i, len, et;
14994
var preserves_opaqueness = true;
14995
for (i = 0, len = this.active_effect_flags.length; i < len; i++)
14996
{
14997
if (this.active_effect_flags[i])
14998
{
14999
et = this.type.effect_types[i];
15000
this.active_effect_types.push(et);
15001
if (!et.preservesOpaqueness)
15002
preserves_opaqueness = false;
15003
}
15004
}
15005
this.uses_shaders = !!this.active_effect_types.length;
15006
this.shaders_preserve_opaqueness = preserves_opaqueness;
15007
};
15008
cr.inst_toString = function ()
15009
{
15010
return "Inst" + this.puid;
15011
};
15012
cr.type_getFirstPicked = function (frominst)
15013
{
15014
if (frominst && frominst.is_contained && frominst.type != this)
15015
{
15016
var i, len, s;
15017
for (i = 0, len = frominst.siblings.length; i < len; i++)
15018
{
15019
s = frominst.siblings[i];
15020
if (s.type == this)
15021
return s;
15022
}
15023
}
15024
var instances = this.getCurrentSol().getObjects();
15025
if (instances.length)
15026
return instances[0];
15027
else
15028
return null;
15029
};
15030
cr.type_getPairedInstance = function (inst)
15031
{
15032
var instances = this.getCurrentSol().getObjects();
15033
if (instances.length)
15034
return instances[inst.get_iid() % instances.length];
15035
else
15036
return null;
15037
};
15038
cr.type_updateIIDs = function ()
15039
{
15040
if (!this.stale_iids || this.is_family)
15041
return; // up to date or is family - don't want family to overwrite IIDs
15042
var i, len;
15043
for (i = 0, len = this.instances.length; i < len; i++)
15044
this.instances[i].iid = i;
15045
var next_iid = i;
15046
var createRow = this.runtime.createRow;
15047
for (i = 0, len = createRow.length; i < len; ++i)
15048
{
15049
if (createRow[i].type === this)
15050
createRow[i].iid = next_iid++;
15051
}
15052
this.stale_iids = false;
15053
};
15054
cr.type_getInstanceByIID = function (i)
15055
{
15056
if (i < this.instances.length)
15057
return this.instances[i];
15058
i -= this.instances.length;
15059
var createRow = this.runtime.createRow;
15060
var j, lenj;
15061
for (j = 0, lenj = createRow.length; j < lenj; ++j)
15062
{
15063
if (createRow[j].type === this)
15064
{
15065
if (i === 0)
15066
return createRow[j];
15067
--i;
15068
}
15069
}
15070
;
15071
return null;
15072
};
15073
cr.type_getCurrentSol = function ()
15074
{
15075
return this.solstack[this.cur_sol];
15076
};
15077
cr.type_pushCleanSol = function ()
15078
{
15079
this.cur_sol++;
15080
if (this.cur_sol === this.solstack.length)
15081
{
15082
this.solstack.push(new cr.selection(this));
15083
}
15084
else
15085
{
15086
this.solstack[this.cur_sol].select_all = true; // else clear next SOL
15087
cr.clearArray(this.solstack[this.cur_sol].else_instances);
15088
}
15089
};
15090
cr.type_pushCopySol = function ()
15091
{
15092
this.cur_sol++;
15093
if (this.cur_sol === this.solstack.length)
15094
this.solstack.push(new cr.selection(this));
15095
var clonesol = this.solstack[this.cur_sol];
15096
var prevsol = this.solstack[this.cur_sol - 1];
15097
if (prevsol.select_all)
15098
{
15099
clonesol.select_all = true;
15100
}
15101
else
15102
{
15103
clonesol.select_all = false;
15104
cr.shallowAssignArray(clonesol.instances, prevsol.instances);
15105
}
15106
cr.clearArray(clonesol.else_instances);
15107
};
15108
cr.type_popSol = function ()
15109
{
15110
;
15111
this.cur_sol--;
15112
};
15113
cr.type_getBehaviorByName = function (behname)
15114
{
15115
var i, len, j, lenj, f, index = 0;
15116
if (!this.is_family)
15117
{
15118
for (i = 0, len = this.families.length; i < len; i++)
15119
{
15120
f = this.families[i];
15121
for (j = 0, lenj = f.behaviors.length; j < lenj; j++)
15122
{
15123
if (behname === f.behaviors[j].name)
15124
{
15125
this.extra["lastBehIndex"] = index;
15126
return f.behaviors[j];
15127
}
15128
index++;
15129
}
15130
}
15131
}
15132
for (i = 0, len = this.behaviors.length; i < len; i++) {
15133
if (behname === this.behaviors[i].name)
15134
{
15135
this.extra["lastBehIndex"] = index;
15136
return this.behaviors[i];
15137
}
15138
index++;
15139
}
15140
return null;
15141
};
15142
cr.type_getBehaviorIndexByName = function (behname)
15143
{
15144
var b = this.getBehaviorByName(behname);
15145
if (b)
15146
return this.extra["lastBehIndex"];
15147
else
15148
return -1;
15149
};
15150
cr.type_getEffectIndexByName = function (name_)
15151
{
15152
var i, len;
15153
for (i = 0, len = this.effect_types.length; i < len; i++)
15154
{
15155
if (this.effect_types[i].name === name_)
15156
return i;
15157
}
15158
return -1;
15159
};
15160
cr.type_applySolToContainer = function ()
15161
{
15162
if (!this.is_contained || this.is_family)
15163
return;
15164
var i, len, j, lenj, t, sol, sol2;
15165
this.updateIIDs();
15166
sol = this.getCurrentSol();
15167
var select_all = sol.select_all;
15168
var es = this.runtime.getCurrentEventStack();
15169
var orblock = es && es.current_event && es.current_event.orblock;
15170
for (i = 0, len = this.container.length; i < len; i++)
15171
{
15172
t = this.container[i];
15173
if (t === this)
15174
continue;
15175
t.updateIIDs();
15176
sol2 = t.getCurrentSol();
15177
sol2.select_all = select_all;
15178
if (!select_all)
15179
{
15180
cr.clearArray(sol2.instances);
15181
for (j = 0, lenj = sol.instances.length; j < lenj; ++j)
15182
sol2.instances[j] = t.getInstanceByIID(sol.instances[j].iid);
15183
if (orblock)
15184
{
15185
cr.clearArray(sol2.else_instances);
15186
for (j = 0, lenj = sol.else_instances.length; j < lenj; ++j)
15187
sol2.else_instances[j] = t.getInstanceByIID(sol.else_instances[j].iid);
15188
}
15189
}
15190
}
15191
};
15192
cr.type_toString = function ()
15193
{
15194
return "Type" + this.sid;
15195
};
15196
cr.do_cmp = function (x, cmp, y)
15197
{
15198
if (typeof x === "undefined" || typeof y === "undefined")
15199
return false;
15200
switch (cmp)
15201
{
15202
case 0: // equal
15203
return x === y;
15204
case 1: // not equal
15205
return x !== y;
15206
case 2: // less
15207
return x < y;
15208
case 3: // less/equal
15209
return x <= y;
15210
case 4: // greater
15211
return x > y;
15212
case 5: // greater/equal
15213
return x >= y;
15214
default:
15215
;
15216
return false;
15217
}
15218
};
15219
})();
15220
cr.shaders = {};
15221
cr.shaders["water"] = {src: ["varying mediump vec2 vTex;",
15222
"uniform lowp sampler2D samplerFront;",
15223
"precision mediump float;",
15224
"uniform float seconds;",
15225
"uniform float pixelWidth;",
15226
"uniform float pixelHeight;",
15227
"const float PI = 3.1415926535897932;",
15228
"uniform float speed;",
15229
"uniform float speed_x;",
15230
"uniform float speed_y;",
15231
"uniform float intensity;",
15232
"const int steps = 8;",
15233
"uniform float frequency;",
15234
"uniform float angle; // better when a prime",
15235
"uniform float delta;",
15236
"uniform float intence;",
15237
"uniform float emboss;",
15238
"float col(vec2 coord)",
15239
"{",
15240
"float delta_theta = 2.0 * PI / angle;",
15241
"float col = 0.0;",
15242
"float theta = 0.0;",
15243
"for (int i = 0; i < steps; i++)",
15244
"{",
15245
"vec2 adjc = coord;",
15246
"theta = delta_theta*float(i);",
15247
"adjc.x += cos(theta)*seconds*speed + seconds * speed_x;",
15248
"adjc.y -= sin(theta)*seconds*speed - seconds * speed_y;",
15249
"col = col + cos( (adjc.x*cos(theta) - adjc.y*sin(theta))*frequency)*intensity;",
15250
"}",
15251
"return cos(col);",
15252
"}",
15253
"void main(void)",
15254
"{",
15255
"vec2 p = vTex, c1 = p, c2 = p;",
15256
"float cc1 = col(c1);",
15257
"c2.x += (1.0 / pixelWidth) / delta;",
15258
"float dx = emboss*(cc1-col(c2))/delta;",
15259
"c2.x = p.x;",
15260
"c2.y += (1.0 / pixelHeight) / delta;",
15261
"float dy = emboss*(cc1-col(c2))/delta;",
15262
"c1.x += dx;",
15263
"c1.y = -(c1.y+dy);",
15264
"float alpha = 1.+dot(dx,dy)*intence;",
15265
"c1.y = -c1.y;",
15266
"gl_FragColor = texture2D(samplerFront,c1)*(alpha);",
15267
"}"
15268
].join("\n"),
15269
extendBoxHorizontal: 25,
15270
extendBoxVertical: 25,
15271
crossSampling: false,
15272
preservesOpaqueness: false,
15273
animated: true,
15274
parameters: [["speed", 0, 1], ["speed_x", 0, 1], ["speed_y", 0, 1], ["intensity", 0, 0], ["frequency", 0, 0], ["angle", 0, 0], ["delta", 0, 0], ["intence", 0, 0], ["emboss", 0, 1]] }
15275
;
15276
;
15277
cr.plugins_.Arr = function(runtime)
15278
{
15279
this.runtime = runtime;
15280
};
15281
(function ()
15282
{
15283
var pluginProto = cr.plugins_.Arr.prototype;
15284
pluginProto.Type = function(plugin)
15285
{
15286
this.plugin = plugin;
15287
this.runtime = plugin.runtime;
15288
};
15289
var typeProto = pluginProto.Type.prototype;
15290
typeProto.onCreate = function()
15291
{
15292
};
15293
pluginProto.Instance = function(type)
15294
{
15295
this.type = type;
15296
this.runtime = type.runtime;
15297
};
15298
var instanceProto = pluginProto.Instance.prototype;
15299
var arrCache = [];
15300
function allocArray()
15301
{
15302
if (arrCache.length)
15303
return arrCache.pop();
15304
else
15305
return [];
15306
};
15307
if (!Array.isArray)
15308
{
15309
Array.isArray = function (vArg) {
15310
return Object.prototype.toString.call(vArg) === "[object Array]";
15311
};
15312
}
15313
function freeArray(a)
15314
{
15315
var i, len;
15316
for (i = 0, len = a.length; i < len; i++)
15317
{
15318
if (Array.isArray(a[i]))
15319
freeArray(a[i]);
15320
}
15321
cr.clearArray(a);
15322
arrCache.push(a);
15323
};
15324
instanceProto.onCreate = function()
15325
{
15326
this.cx = this.properties[0];
15327
this.cy = this.properties[1];
15328
this.cz = this.properties[2];
15329
if (!this.recycled)
15330
this.arr = allocArray();
15331
var a = this.arr;
15332
a.length = this.cx;
15333
var x, y, z;
15334
for (x = 0; x < this.cx; x++)
15335
{
15336
if (!a[x])
15337
a[x] = allocArray();
15338
a[x].length = this.cy;
15339
for (y = 0; y < this.cy; y++)
15340
{
15341
if (!a[x][y])
15342
a[x][y] = allocArray();
15343
a[x][y].length = this.cz;
15344
for (z = 0; z < this.cz; z++)
15345
a[x][y][z] = 0;
15346
}
15347
}
15348
this.forX = [];
15349
this.forY = [];
15350
this.forZ = [];
15351
this.forDepth = -1;
15352
};
15353
instanceProto.onDestroy = function ()
15354
{
15355
var x;
15356
for (x = 0; x < this.cx; x++)
15357
freeArray(this.arr[x]); // will recurse down and recycle other arrays
15358
cr.clearArray(this.arr);
15359
};
15360
instanceProto.at = function (x, y, z)
15361
{
15362
x = Math.floor(x);
15363
y = Math.floor(y);
15364
z = Math.floor(z);
15365
if (isNaN(x) || x < 0 || x > this.cx - 1)
15366
return 0;
15367
if (isNaN(y) || y < 0 || y > this.cy - 1)
15368
return 0;
15369
if (isNaN(z) || z < 0 || z > this.cz - 1)
15370
return 0;
15371
return this.arr[x][y][z];
15372
};
15373
instanceProto.set = function (x, y, z, val)
15374
{
15375
x = Math.floor(x);
15376
y = Math.floor(y);
15377
z = Math.floor(z);
15378
if (isNaN(x) || x < 0 || x > this.cx - 1)
15379
return;
15380
if (isNaN(y) || y < 0 || y > this.cy - 1)
15381
return;
15382
if (isNaN(z) || z < 0 || z > this.cz - 1)
15383
return;
15384
this.arr[x][y][z] = val;
15385
};
15386
instanceProto.getAsJSON = function ()
15387
{
15388
return JSON.stringify({
15389
"c2array": true,
15390
"size": [this.cx, this.cy, this.cz],
15391
"data": this.arr
15392
});
15393
};
15394
instanceProto.saveToJSON = function ()
15395
{
15396
return {
15397
"size": [this.cx, this.cy, this.cz],
15398
"data": this.arr
15399
};
15400
};
15401
instanceProto.loadFromJSON = function (o)
15402
{
15403
var sz = o["size"];
15404
this.cx = sz[0];
15405
this.cy = sz[1];
15406
this.cz = sz[2];
15407
this.arr = o["data"];
15408
};
15409
instanceProto.setSize = function (w, h, d)
15410
{
15411
if (w < 0) w = 0;
15412
if (h < 0) h = 0;
15413
if (d < 0) d = 0;
15414
if (this.cx === w && this.cy === h && this.cz === d)
15415
return; // no change
15416
this.cx = w;
15417
this.cy = h;
15418
this.cz = d;
15419
var x, y, z;
15420
var a = this.arr;
15421
a.length = w;
15422
for (x = 0; x < this.cx; x++)
15423
{
15424
if (cr.is_undefined(a[x]))
15425
a[x] = allocArray();
15426
a[x].length = h;
15427
for (y = 0; y < this.cy; y++)
15428
{
15429
if (cr.is_undefined(a[x][y]))
15430
a[x][y] = allocArray();
15431
a[x][y].length = d;
15432
for (z = 0; z < this.cz; z++)
15433
{
15434
if (cr.is_undefined(a[x][y][z]))
15435
a[x][y][z] = 0;
15436
}
15437
}
15438
}
15439
};
15440
instanceProto.getForX = function ()
15441
{
15442
if (this.forDepth >= 0 && this.forDepth < this.forX.length)
15443
return this.forX[this.forDepth];
15444
else
15445
return 0;
15446
};
15447
instanceProto.getForY = function ()
15448
{
15449
if (this.forDepth >= 0 && this.forDepth < this.forY.length)
15450
return this.forY[this.forDepth];
15451
else
15452
return 0;
15453
};
15454
instanceProto.getForZ = function ()
15455
{
15456
if (this.forDepth >= 0 && this.forDepth < this.forZ.length)
15457
return this.forZ[this.forDepth];
15458
else
15459
return 0;
15460
};
15461
function Cnds() {};
15462
Cnds.prototype.CompareX = function (x, cmp, val)
15463
{
15464
return cr.do_cmp(this.at(x, 0, 0), cmp, val);
15465
};
15466
Cnds.prototype.CompareXY = function (x, y, cmp, val)
15467
{
15468
return cr.do_cmp(this.at(x, y, 0), cmp, val);
15469
};
15470
Cnds.prototype.CompareXYZ = function (x, y, z, cmp, val)
15471
{
15472
return cr.do_cmp(this.at(x, y, z), cmp, val);
15473
};
15474
instanceProto.doForEachTrigger = function (current_event)
15475
{
15476
this.runtime.pushCopySol(current_event.solModifiers);
15477
current_event.retrigger();
15478
this.runtime.popSol(current_event.solModifiers);
15479
};
15480
Cnds.prototype.ArrForEach = function (dims)
15481
{
15482
var current_event = this.runtime.getCurrentEventStack().current_event;
15483
this.forDepth++;
15484
var forDepth = this.forDepth;
15485
if (forDepth === this.forX.length)
15486
{
15487
this.forX.push(0);
15488
this.forY.push(0);
15489
this.forZ.push(0);
15490
}
15491
else
15492
{
15493
this.forX[forDepth] = 0;
15494
this.forY[forDepth] = 0;
15495
this.forZ[forDepth] = 0;
15496
}
15497
switch (dims) {
15498
case 0:
15499
for (this.forX[forDepth] = 0; this.forX[forDepth] < this.cx; this.forX[forDepth]++)
15500
{
15501
for (this.forY[forDepth] = 0; this.forY[forDepth] < this.cy; this.forY[forDepth]++)
15502
{
15503
for (this.forZ[forDepth] = 0; this.forZ[forDepth] < this.cz; this.forZ[forDepth]++)
15504
{
15505
this.doForEachTrigger(current_event);
15506
}
15507
}
15508
}
15509
break;
15510
case 1:
15511
for (this.forX[forDepth] = 0; this.forX[forDepth] < this.cx; this.forX[forDepth]++)
15512
{
15513
for (this.forY[forDepth] = 0; this.forY[forDepth] < this.cy; this.forY[forDepth]++)
15514
{
15515
this.doForEachTrigger(current_event);
15516
}
15517
}
15518
break;
15519
case 2:
15520
for (this.forX[forDepth] = 0; this.forX[forDepth] < this.cx; this.forX[forDepth]++)
15521
{
15522
this.doForEachTrigger(current_event);
15523
}
15524
break;
15525
}
15526
this.forDepth--;
15527
return false;
15528
};
15529
Cnds.prototype.CompareCurrent = function (cmp, val)
15530
{
15531
return cr.do_cmp(this.at(this.getForX(), this.getForY(), this.getForZ()), cmp, val);
15532
};
15533
Cnds.prototype.Contains = function(val)
15534
{
15535
var x, y, z;
15536
for (x = 0; x < this.cx; x++)
15537
{
15538
for (y = 0; y < this.cy; y++)
15539
{
15540
for (z = 0; z < this.cz; z++)
15541
{
15542
if (this.arr[x][y][z] === val)
15543
return true;
15544
}
15545
}
15546
}
15547
return false;
15548
};
15549
Cnds.prototype.IsEmpty = function ()
15550
{
15551
return this.cx === 0 || this.cy === 0 || this.cz === 0;
15552
};
15553
Cnds.prototype.CompareSize = function (axis, cmp, value)
15554
{
15555
var s = 0;
15556
switch (axis) {
15557
case 0:
15558
s = this.cx;
15559
break;
15560
case 1:
15561
s = this.cy;
15562
break;
15563
case 2:
15564
s = this.cz;
15565
break;
15566
}
15567
return cr.do_cmp(s, cmp, value);
15568
};
15569
pluginProto.cnds = new Cnds();
15570
function Acts() {};
15571
Acts.prototype.Clear = function ()
15572
{
15573
var x, y, z;
15574
for (x = 0; x < this.cx; x++)
15575
for (y = 0; y < this.cy; y++)
15576
for (z = 0; z < this.cz; z++)
15577
this.arr[x][y][z] = 0;
15578
};
15579
Acts.prototype.SetSize = function (w, h, d)
15580
{
15581
this.setSize(w, h, d);
15582
};
15583
Acts.prototype.SetX = function (x, val)
15584
{
15585
this.set(x, 0, 0, val);
15586
};
15587
Acts.prototype.SetXY = function (x, y, val)
15588
{
15589
this.set(x, y, 0, val);
15590
};
15591
Acts.prototype.SetXYZ = function (x, y, z, val)
15592
{
15593
this.set(x, y, z, val);
15594
};
15595
Acts.prototype.Push = function (where, value, axis)
15596
{
15597
var x = 0, y = 0, z = 0;
15598
var a = this.arr;
15599
switch (axis) {
15600
case 0: // X axis
15601
if (where === 0) // back
15602
{
15603
x = a.length;
15604
a.push(allocArray());
15605
}
15606
else // front
15607
{
15608
x = 0;
15609
a.unshift(allocArray());
15610
}
15611
a[x].length = this.cy;
15612
for ( ; y < this.cy; y++)
15613
{
15614
a[x][y] = allocArray();
15615
a[x][y].length = this.cz;
15616
for (z = 0; z < this.cz; z++)
15617
a[x][y][z] = value;
15618
}
15619
this.cx++;
15620
break;
15621
case 1: // Y axis
15622
for ( ; x < this.cx; x++)
15623
{
15624
if (where === 0) // back
15625
{
15626
y = a[x].length;
15627
a[x].push(allocArray());
15628
}
15629
else // front
15630
{
15631
y = 0;
15632
a[x].unshift(allocArray());
15633
}
15634
a[x][y].length = this.cz;
15635
for (z = 0; z < this.cz; z++)
15636
a[x][y][z] = value;
15637
}
15638
this.cy++;
15639
break;
15640
case 2: // Z axis
15641
for ( ; x < this.cx; x++)
15642
{
15643
for (y = 0; y < this.cy; y++)
15644
{
15645
if (where === 0) // back
15646
{
15647
a[x][y].push(value);
15648
}
15649
else // front
15650
{
15651
a[x][y].unshift(value);
15652
}
15653
}
15654
}
15655
this.cz++;
15656
break;
15657
}
15658
};
15659
Acts.prototype.Pop = function (where, axis)
15660
{
15661
var x = 0, y = 0, z = 0;
15662
var a = this.arr;
15663
switch (axis) {
15664
case 0: // X axis
15665
if (this.cx === 0)
15666
break;
15667
if (where === 0) // back
15668
{
15669
freeArray(a.pop());
15670
}
15671
else // front
15672
{
15673
freeArray(a.shift());
15674
}
15675
this.cx--;
15676
break;
15677
case 1: // Y axis
15678
if (this.cy === 0)
15679
break;
15680
for ( ; x < this.cx; x++)
15681
{
15682
if (where === 0) // back
15683
{
15684
freeArray(a[x].pop());
15685
}
15686
else // front
15687
{
15688
freeArray(a[x].shift());
15689
}
15690
}
15691
this.cy--;
15692
break;
15693
case 2: // Z axis
15694
if (this.cz === 0)
15695
break;
15696
for ( ; x < this.cx; x++)
15697
{
15698
for (y = 0; y < this.cy; y++)
15699
{
15700
if (where === 0) // back
15701
{
15702
a[x][y].pop();
15703
}
15704
else // front
15705
{
15706
a[x][y].shift();
15707
}
15708
}
15709
}
15710
this.cz--;
15711
break;
15712
}
15713
};
15714
Acts.prototype.Reverse = function (axis)
15715
{
15716
var x = 0, y = 0, z = 0;
15717
var a = this.arr;
15718
if (this.cx === 0 || this.cy === 0 || this.cz === 0)
15719
return; // no point reversing empty array
15720
switch (axis) {
15721
case 0: // X axis
15722
a.reverse();
15723
break;
15724
case 1: // Y axis
15725
for ( ; x < this.cx; x++)
15726
a[x].reverse();
15727
break;
15728
case 2: // Z axis
15729
for ( ; x < this.cx; x++)
15730
for (y = 0; y < this.cy; y++)
15731
a[x][y].reverse();
15732
break;
15733
}
15734
};
15735
function compareValues(va, vb)
15736
{
15737
if (cr.is_number(va) && cr.is_number(vb))
15738
return va - vb;
15739
else
15740
{
15741
var sa = "" + va;
15742
var sb = "" + vb;
15743
if (sa < sb)
15744
return -1;
15745
else if (sa > sb)
15746
return 1;
15747
else
15748
return 0;
15749
}
15750
}
15751
Acts.prototype.Sort = function (axis)
15752
{
15753
var x = 0, y = 0, z = 0;
15754
var a = this.arr;
15755
if (this.cx === 0 || this.cy === 0 || this.cz === 0)
15756
return; // no point sorting empty array
15757
switch (axis) {
15758
case 0: // X axis
15759
a.sort(function (a, b) {
15760
return compareValues(a[0][0], b[0][0]);
15761
});
15762
break;
15763
case 1: // Y axis
15764
for ( ; x < this.cx; x++)
15765
{
15766
a[x].sort(function (a, b) {
15767
return compareValues(a[0], b[0]);
15768
});
15769
}
15770
break;
15771
case 2: // Z axis
15772
for ( ; x < this.cx; x++)
15773
{
15774
for (y = 0; y < this.cy; y++)
15775
{
15776
a[x][y].sort(compareValues);
15777
}
15778
}
15779
break;
15780
}
15781
};
15782
Acts.prototype.Delete = function (index, axis)
15783
{
15784
var x = 0, y = 0, z = 0;
15785
index = Math.floor(index);
15786
var a = this.arr;
15787
if (index < 0)
15788
return;
15789
switch (axis) {
15790
case 0: // X axis
15791
if (index >= this.cx)
15792
break;
15793
freeArray(a[index]);
15794
a.splice(index, 1);
15795
this.cx--;
15796
break;
15797
case 1: // Y axis
15798
if (index >= this.cy)
15799
break;
15800
for ( ; x < this.cx; x++)
15801
{
15802
freeArray(a[x][index]);
15803
a[x].splice(index, 1);
15804
}
15805
this.cy--;
15806
break;
15807
case 2: // Z axis
15808
if (index >= this.cz)
15809
break;
15810
for ( ; x < this.cx; x++)
15811
{
15812
for (y = 0; y < this.cy; y++)
15813
{
15814
a[x][y].splice(index, 1);
15815
}
15816
}
15817
this.cz--;
15818
break;
15819
}
15820
};
15821
Acts.prototype.Insert = function (value, index, axis)
15822
{
15823
var x = 0, y = 0, z = 0;
15824
index = Math.floor(index);
15825
var a = this.arr;
15826
if (index < 0)
15827
return;
15828
switch (axis) {
15829
case 0: // X axis
15830
if (index > this.cx)
15831
return;
15832
x = index;
15833
a.splice(x, 0, allocArray());
15834
a[x].length = this.cy;
15835
for ( ; y < this.cy; y++)
15836
{
15837
a[x][y] = allocArray();
15838
a[x][y].length = this.cz;
15839
for (z = 0; z < this.cz; z++)
15840
a[x][y][z] = value;
15841
}
15842
this.cx++;
15843
break;
15844
case 1: // Y axis
15845
if (index > this.cy)
15846
return;
15847
for ( ; x < this.cx; x++)
15848
{
15849
y = index;
15850
a[x].splice(y, 0, allocArray());
15851
a[x][y].length = this.cz;
15852
for (z = 0; z < this.cz; z++)
15853
a[x][y][z] = value;
15854
}
15855
this.cy++;
15856
break;
15857
case 2: // Z axis
15858
if (index > this.cz)
15859
return;
15860
for ( ; x < this.cx; x++)
15861
{
15862
for (y = 0; y < this.cy; y++)
15863
{
15864
a[x][y].splice(index, 0, value);
15865
}
15866
}
15867
this.cz++;
15868
break;
15869
}
15870
};
15871
Acts.prototype.JSONLoad = function (json_)
15872
{
15873
var o;
15874
try {
15875
o = JSON.parse(json_);
15876
}
15877
catch(e) { return; }
15878
if (!o["c2array"]) // presumably not a c2array object
15879
return;
15880
var sz = o["size"];
15881
this.cx = sz[0];
15882
this.cy = sz[1];
15883
this.cz = sz[2];
15884
this.arr = o["data"];
15885
};
15886
Acts.prototype.JSONDownload = function (filename)
15887
{
15888
var a = document.createElement("a");
15889
if (typeof a.download === "undefined")
15890
{
15891
var str = 'data:text/html,' + encodeURIComponent("<p><a download='" + filename + "' href=\"data:application/json,"
15892
+ encodeURIComponent(this.getAsJSON())
15893
+ "\">Download link</a></p>");
15894
window.open(str);
15895
}
15896
else
15897
{
15898
var body = document.getElementsByTagName("body")[0];
15899
a.textContent = filename;
15900
a.href = "data:application/json," + encodeURIComponent(this.getAsJSON());
15901
a.download = filename;
15902
body.appendChild(a);
15903
var clickEvent = document.createEvent("MouseEvent");
15904
clickEvent.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
15905
a.dispatchEvent(clickEvent);
15906
body.removeChild(a);
15907
}
15908
};
15909
pluginProto.acts = new Acts();
15910
function Exps() {};
15911
Exps.prototype.At = function (ret, x, y_, z_)
15912
{
15913
var y = y_ || 0;
15914
var z = z_ || 0;
15915
ret.set_any(this.at(x, y, z));
15916
};
15917
Exps.prototype.Width = function (ret)
15918
{
15919
ret.set_int(this.cx);
15920
};
15921
Exps.prototype.Height = function (ret)
15922
{
15923
ret.set_int(this.cy);
15924
};
15925
Exps.prototype.Depth = function (ret)
15926
{
15927
ret.set_int(this.cz);
15928
};
15929
Exps.prototype.CurX = function (ret)
15930
{
15931
ret.set_int(this.getForX());
15932
};
15933
Exps.prototype.CurY = function (ret)
15934
{
15935
ret.set_int(this.getForY());
15936
};
15937
Exps.prototype.CurZ = function (ret)
15938
{
15939
ret.set_int(this.getForZ());
15940
};
15941
Exps.prototype.CurValue = function (ret)
15942
{
15943
ret.set_any(this.at(this.getForX(), this.getForY(), this.getForZ()));
15944
};
15945
Exps.prototype.Front = function (ret)
15946
{
15947
ret.set_any(this.at(0, 0, 0));
15948
};
15949
Exps.prototype.Back = function (ret)
15950
{
15951
ret.set_any(this.at(this.cx - 1, 0, 0));
15952
};
15953
Exps.prototype.IndexOf = function (ret, v)
15954
{
15955
for (var i = 0; i < this.cx; i++)
15956
{
15957
if (this.arr[i][0][0] === v)
15958
{
15959
ret.set_int(i);
15960
return;
15961
}
15962
}
15963
ret.set_int(-1);
15964
};
15965
Exps.prototype.LastIndexOf = function (ret, v)
15966
{
15967
for (var i = this.cx - 1; i >= 0; i--)
15968
{
15969
if (this.arr[i][0][0] === v)
15970
{
15971
ret.set_int(i);
15972
return;
15973
}
15974
}
15975
ret.set_int(-1);
15976
};
15977
Exps.prototype.AsJSON = function (ret)
15978
{
15979
ret.set_string(this.getAsJSON());
15980
};
15981
pluginProto.exps = new Exps();
15982
}());
15983
;
15984
;
15985
cr.plugins_.Audio = function(runtime)
15986
{
15987
this.runtime = runtime;
15988
};
15989
(function ()
15990
{
15991
var pluginProto = cr.plugins_.Audio.prototype;
15992
pluginProto.Type = function(plugin)
15993
{
15994
this.plugin = plugin;
15995
this.runtime = plugin.runtime;
15996
};
15997
var typeProto = pluginProto.Type.prototype;
15998
typeProto.onCreate = function()
15999
{
16000
};
16001
var audRuntime = null;
16002
var audInst = null;
16003
var audTag = "";
16004
var appPath = ""; // for Cordova only
16005
var API_HTML5 = 0;
16006
var API_WEBAUDIO = 1;
16007
var API_CORDOVA = 2;
16008
var API_APPMOBI = 3;
16009
var api = API_HTML5;
16010
var context = null;
16011
var audioBuffers = []; // cache of buffers
16012
var audioInstances = []; // cache of instances
16013
var lastAudio = null;
16014
var useOgg = false; // determined at create time
16015
var timescale_mode = 0;
16016
var silent = false;
16017
var masterVolume = 1;
16018
var listenerX = 0;
16019
var listenerY = 0;
16020
var isContextSuspended = false;
16021
var panningModel = 1; // HRTF
16022
var distanceModel = 1; // Inverse
16023
var refDistance = 10;
16024
var maxDistance = 10000;
16025
var rolloffFactor = 1;
16026
var micSource = null;
16027
var micTag = "";
16028
var useNextTouchWorkaround = false; // heuristic in case play() does not return a promise and we have to guess if the play was blocked
16029
var playOnNextInput = []; // C2AudioInstances with HTMLAudioElements to play on next input event
16030
var playMusicAsSoundWorkaround = false; // play music tracks with Web Audio API
16031
var hasPlayedDummyBuffer = false; // dummy buffer played to unblock AudioContext on some platforms
16032
function addAudioToPlayOnNextInput(a)
16033
{
16034
var i = playOnNextInput.indexOf(a);
16035
if (i === -1)
16036
playOnNextInput.push(a);
16037
};
16038
function tryPlayAudioElement(a)
16039
{
16040
var audioElem = a.instanceObject;
16041
var playRet;
16042
try {
16043
playRet = audioElem.play();
16044
}
16045
catch (err) {
16046
addAudioToPlayOnNextInput(a);
16047
return;
16048
}
16049
if (playRet) // promise was returned
16050
{
16051
playRet.catch(function (err)
16052
{
16053
addAudioToPlayOnNextInput(a);
16054
});
16055
}
16056
else if (useNextTouchWorkaround && !audRuntime.isInUserInputEvent)
16057
{
16058
addAudioToPlayOnNextInput(a);
16059
}
16060
};
16061
function playQueuedAudio()
16062
{
16063
var i, len, m, playRet;
16064
if (!hasPlayedDummyBuffer && !isContextSuspended && context)
16065
{
16066
playDummyBuffer();
16067
if (context["state"] === "running")
16068
hasPlayedDummyBuffer = true;
16069
}
16070
var tryPlay = playOnNextInput.slice(0);
16071
cr.clearArray(playOnNextInput);
16072
if (!silent)
16073
{
16074
for (i = 0, len = tryPlay.length; i < len; ++i)
16075
{
16076
m = tryPlay[i];
16077
if (!m.stopped && !m.is_paused)
16078
{
16079
playRet = m.instanceObject.play();
16080
if (playRet)
16081
{
16082
playRet.catch(function (err)
16083
{
16084
addAudioToPlayOnNextInput(m);
16085
});
16086
}
16087
}
16088
}
16089
}
16090
};
16091
function playDummyBuffer()
16092
{
16093
if (context["state"] === "suspended" && context["resume"])
16094
context["resume"]();
16095
if (!context["createBuffer"])
16096
return;
16097
var buffer = context["createBuffer"](1, 220, 22050);
16098
var source = context["createBufferSource"]();
16099
source["buffer"] = buffer;
16100
source["connect"](context["destination"]);
16101
startSource(source);
16102
};
16103
document.addEventListener("pointerup", playQueuedAudio, true);
16104
document.addEventListener("touchend", playQueuedAudio, true);
16105
document.addEventListener("click", playQueuedAudio, true);
16106
document.addEventListener("keydown", playQueuedAudio, true);
16107
document.addEventListener("gamepadconnected", playQueuedAudio, true);
16108
function dbToLinear(x)
16109
{
16110
var v = dbToLinear_nocap(x);
16111
if (!isFinite(v)) // accidentally passing a string can result in NaN; set volume to 0 if so
16112
v = 0;
16113
if (v < 0)
16114
v = 0;
16115
if (v > 1)
16116
v = 1;
16117
return v;
16118
};
16119
function linearToDb(x)
16120
{
16121
if (x < 0)
16122
x = 0;
16123
if (x > 1)
16124
x = 1;
16125
return linearToDb_nocap(x);
16126
};
16127
function dbToLinear_nocap(x)
16128
{
16129
return Math.pow(10, x / 20);
16130
};
16131
function linearToDb_nocap(x)
16132
{
16133
return (Math.log(x) / Math.log(10)) * 20;
16134
};
16135
var effects = {};
16136
function getDestinationForTag(tag)
16137
{
16138
tag = tag.toLowerCase();
16139
if (effects.hasOwnProperty(tag))
16140
{
16141
if (effects[tag].length)
16142
return effects[tag][0].getInputNode();
16143
}
16144
return context["destination"];
16145
};
16146
function createGain()
16147
{
16148
if (context["createGain"])
16149
return context["createGain"]();
16150
else
16151
return context["createGainNode"]();
16152
};
16153
function createDelay(d)
16154
{
16155
if (context["createDelay"])
16156
return context["createDelay"](d);
16157
else
16158
return context["createDelayNode"](d);
16159
};
16160
function startSource(s, scheduledTime)
16161
{
16162
if (s["start"])
16163
s["start"](scheduledTime || 0);
16164
else
16165
s["noteOn"](scheduledTime || 0);
16166
};
16167
function startSourceAt(s, x, d, scheduledTime)
16168
{
16169
if (s["start"])
16170
s["start"](scheduledTime || 0, x);
16171
else
16172
s["noteGrainOn"](scheduledTime || 0, x, d - x);
16173
};
16174
function stopSource(s)
16175
{
16176
try {
16177
if (s["stop"])
16178
s["stop"](0);
16179
else
16180
s["noteOff"](0);
16181
}
16182
catch (e) {}
16183
};
16184
function setAudioParam(ap, value, ramp, time)
16185
{
16186
if (!ap)
16187
return; // iOS is missing some parameters
16188
ap["cancelScheduledValues"](0);
16189
if (time === 0)
16190
{
16191
ap["value"] = value;
16192
return;
16193
}
16194
var curTime = context["currentTime"];
16195
time += curTime;
16196
switch (ramp) {
16197
case 0: // step
16198
ap["setValueAtTime"](value, time);
16199
break;
16200
case 1: // linear
16201
ap["setValueAtTime"](ap["value"], curTime); // to set what to ramp from
16202
ap["linearRampToValueAtTime"](value, time);
16203
break;
16204
case 2: // exponential
16205
ap["setValueAtTime"](ap["value"], curTime); // to set what to ramp from
16206
ap["exponentialRampToValueAtTime"](value, time);
16207
break;
16208
}
16209
};
16210
var filterTypes = ["lowpass", "highpass", "bandpass", "lowshelf", "highshelf", "peaking", "notch", "allpass"];
16211
function FilterEffect(type, freq, detune, q, gain, mix)
16212
{
16213
this.type = "filter";
16214
this.params = [type, freq, detune, q, gain, mix];
16215
this.inputNode = createGain();
16216
this.wetNode = createGain();
16217
this.wetNode["gain"]["value"] = mix;
16218
this.dryNode = createGain();
16219
this.dryNode["gain"]["value"] = 1 - mix;
16220
this.filterNode = context["createBiquadFilter"]();
16221
if (typeof this.filterNode["type"] === "number")
16222
this.filterNode["type"] = type;
16223
else
16224
this.filterNode["type"] = filterTypes[type];
16225
this.filterNode["frequency"]["value"] = freq;
16226
if (this.filterNode["detune"]) // iOS 6 doesn't have detune yet
16227
this.filterNode["detune"]["value"] = detune;
16228
this.filterNode["Q"]["value"] = q;
16229
this.filterNode["gain"]["value"] = gain;
16230
this.inputNode["connect"](this.filterNode);
16231
this.inputNode["connect"](this.dryNode);
16232
this.filterNode["connect"](this.wetNode);
16233
};
16234
FilterEffect.prototype.connectTo = function (node)
16235
{
16236
this.wetNode["disconnect"]();
16237
this.wetNode["connect"](node);
16238
this.dryNode["disconnect"]();
16239
this.dryNode["connect"](node);
16240
};
16241
FilterEffect.prototype.remove = function ()
16242
{
16243
this.inputNode["disconnect"]();
16244
this.filterNode["disconnect"]();
16245
this.wetNode["disconnect"]();
16246
this.dryNode["disconnect"]();
16247
};
16248
FilterEffect.prototype.getInputNode = function ()
16249
{
16250
return this.inputNode;
16251
};
16252
FilterEffect.prototype.setParam = function(param, value, ramp, time)
16253
{
16254
switch (param) {
16255
case 0: // mix
16256
value = value / 100;
16257
if (value < 0) value = 0;
16258
if (value > 1) value = 1;
16259
this.params[5] = value;
16260
setAudioParam(this.wetNode["gain"], value, ramp, time);
16261
setAudioParam(this.dryNode["gain"], 1 - value, ramp, time);
16262
break;
16263
case 1: // filter frequency
16264
this.params[1] = value;
16265
setAudioParam(this.filterNode["frequency"], value, ramp, time);
16266
break;
16267
case 2: // filter detune
16268
this.params[2] = value;
16269
setAudioParam(this.filterNode["detune"], value, ramp, time);
16270
break;
16271
case 3: // filter Q
16272
this.params[3] = value;
16273
setAudioParam(this.filterNode["Q"], value, ramp, time);
16274
break;
16275
case 4: // filter/delay gain (note value is in dB here)
16276
this.params[4] = value;
16277
setAudioParam(this.filterNode["gain"], value, ramp, time);
16278
break;
16279
}
16280
};
16281
function DelayEffect(delayTime, delayGain, mix)
16282
{
16283
this.type = "delay";
16284
this.params = [delayTime, delayGain, mix];
16285
this.inputNode = createGain();
16286
this.wetNode = createGain();
16287
this.wetNode["gain"]["value"] = mix;
16288
this.dryNode = createGain();
16289
this.dryNode["gain"]["value"] = 1 - mix;
16290
this.mainNode = createGain();
16291
this.delayNode = createDelay(delayTime);
16292
this.delayNode["delayTime"]["value"] = delayTime;
16293
this.delayGainNode = createGain();
16294
this.delayGainNode["gain"]["value"] = delayGain;
16295
this.inputNode["connect"](this.mainNode);
16296
this.inputNode["connect"](this.dryNode);
16297
this.mainNode["connect"](this.wetNode);
16298
this.mainNode["connect"](this.delayNode);
16299
this.delayNode["connect"](this.delayGainNode);
16300
this.delayGainNode["connect"](this.mainNode);
16301
};
16302
DelayEffect.prototype.connectTo = function (node)
16303
{
16304
this.wetNode["disconnect"]();
16305
this.wetNode["connect"](node);
16306
this.dryNode["disconnect"]();
16307
this.dryNode["connect"](node);
16308
};
16309
DelayEffect.prototype.remove = function ()
16310
{
16311
this.inputNode["disconnect"]();
16312
this.mainNode["disconnect"]();
16313
this.delayNode["disconnect"]();
16314
this.delayGainNode["disconnect"]();
16315
this.wetNode["disconnect"]();
16316
this.dryNode["disconnect"]();
16317
};
16318
DelayEffect.prototype.getInputNode = function ()
16319
{
16320
return this.inputNode;
16321
};
16322
DelayEffect.prototype.setParam = function(param, value, ramp, time)
16323
{
16324
switch (param) {
16325
case 0: // mix
16326
value = value / 100;
16327
if (value < 0) value = 0;
16328
if (value > 1) value = 1;
16329
this.params[2] = value;
16330
setAudioParam(this.wetNode["gain"], value, ramp, time);
16331
setAudioParam(this.dryNode["gain"], 1 - value, ramp, time);
16332
break;
16333
case 4: // filter/delay gain (note value is passed in dB but needs to be linear here)
16334
this.params[1] = dbToLinear(value);
16335
setAudioParam(this.delayGainNode["gain"], dbToLinear(value), ramp, time);
16336
break;
16337
case 5: // delay time
16338
this.params[0] = value;
16339
setAudioParam(this.delayNode["delayTime"], value, ramp, time);
16340
break;
16341
}
16342
};
16343
function ConvolveEffect(buffer, normalize, mix, src)
16344
{
16345
this.type = "convolve";
16346
this.params = [normalize, mix, src];
16347
this.inputNode = createGain();
16348
this.wetNode = createGain();
16349
this.wetNode["gain"]["value"] = mix;
16350
this.dryNode = createGain();
16351
this.dryNode["gain"]["value"] = 1 - mix;
16352
this.convolveNode = context["createConvolver"]();
16353
if (buffer)
16354
{
16355
this.convolveNode["normalize"] = normalize;
16356
this.convolveNode["buffer"] = buffer;
16357
}
16358
this.inputNode["connect"](this.convolveNode);
16359
this.inputNode["connect"](this.dryNode);
16360
this.convolveNode["connect"](this.wetNode);
16361
};
16362
ConvolveEffect.prototype.connectTo = function (node)
16363
{
16364
this.wetNode["disconnect"]();
16365
this.wetNode["connect"](node);
16366
this.dryNode["disconnect"]();
16367
this.dryNode["connect"](node);
16368
};
16369
ConvolveEffect.prototype.remove = function ()
16370
{
16371
this.inputNode["disconnect"]();
16372
this.convolveNode["disconnect"]();
16373
this.wetNode["disconnect"]();
16374
this.dryNode["disconnect"]();
16375
};
16376
ConvolveEffect.prototype.getInputNode = function ()
16377
{
16378
return this.inputNode;
16379
};
16380
ConvolveEffect.prototype.setParam = function(param, value, ramp, time)
16381
{
16382
switch (param) {
16383
case 0: // mix
16384
value = value / 100;
16385
if (value < 0) value = 0;
16386
if (value > 1) value = 1;
16387
this.params[1] = value;
16388
setAudioParam(this.wetNode["gain"], value, ramp, time);
16389
setAudioParam(this.dryNode["gain"], 1 - value, ramp, time);
16390
break;
16391
}
16392
};
16393
function FlangerEffect(delay, modulation, freq, feedback, mix)
16394
{
16395
this.type = "flanger";
16396
this.params = [delay, modulation, freq, feedback, mix];
16397
this.inputNode = createGain();
16398
this.dryNode = createGain();
16399
this.dryNode["gain"]["value"] = 1 - (mix / 2);
16400
this.wetNode = createGain();
16401
this.wetNode["gain"]["value"] = mix / 2;
16402
this.feedbackNode = createGain();
16403
this.feedbackNode["gain"]["value"] = feedback;
16404
this.delayNode = createDelay(delay + modulation);
16405
this.delayNode["delayTime"]["value"] = delay;
16406
this.oscNode = context["createOscillator"]();
16407
this.oscNode["frequency"]["value"] = freq;
16408
this.oscGainNode = createGain();
16409
this.oscGainNode["gain"]["value"] = modulation;
16410
this.inputNode["connect"](this.delayNode);
16411
this.inputNode["connect"](this.dryNode);
16412
this.delayNode["connect"](this.wetNode);
16413
this.delayNode["connect"](this.feedbackNode);
16414
this.feedbackNode["connect"](this.delayNode);
16415
this.oscNode["connect"](this.oscGainNode);
16416
this.oscGainNode["connect"](this.delayNode["delayTime"]);
16417
startSource(this.oscNode);
16418
};
16419
FlangerEffect.prototype.connectTo = function (node)
16420
{
16421
this.dryNode["disconnect"]();
16422
this.dryNode["connect"](node);
16423
this.wetNode["disconnect"]();
16424
this.wetNode["connect"](node);
16425
};
16426
FlangerEffect.prototype.remove = function ()
16427
{
16428
this.inputNode["disconnect"]();
16429
this.delayNode["disconnect"]();
16430
this.oscNode["disconnect"]();
16431
this.oscGainNode["disconnect"]();
16432
this.dryNode["disconnect"]();
16433
this.wetNode["disconnect"]();
16434
this.feedbackNode["disconnect"]();
16435
};
16436
FlangerEffect.prototype.getInputNode = function ()
16437
{
16438
return this.inputNode;
16439
};
16440
FlangerEffect.prototype.setParam = function(param, value, ramp, time)
16441
{
16442
switch (param) {
16443
case 0: // mix
16444
value = value / 100;
16445
if (value < 0) value = 0;
16446
if (value > 1) value = 1;
16447
this.params[4] = value;
16448
setAudioParam(this.wetNode["gain"], value / 2, ramp, time);
16449
setAudioParam(this.dryNode["gain"], 1 - (value / 2), ramp, time);
16450
break;
16451
case 6: // modulation
16452
this.params[1] = value / 1000;
16453
setAudioParam(this.oscGainNode["gain"], value / 1000, ramp, time);
16454
break;
16455
case 7: // modulation frequency
16456
this.params[2] = value;
16457
setAudioParam(this.oscNode["frequency"], value, ramp, time);
16458
break;
16459
case 8: // feedback
16460
this.params[3] = value / 100;
16461
setAudioParam(this.feedbackNode["gain"], value / 100, ramp, time);
16462
break;
16463
}
16464
};
16465
function PhaserEffect(freq, detune, q, modulation, modfreq, mix)
16466
{
16467
this.type = "phaser";
16468
this.params = [freq, detune, q, modulation, modfreq, mix];
16469
this.inputNode = createGain();
16470
this.dryNode = createGain();
16471
this.dryNode["gain"]["value"] = 1 - (mix / 2);
16472
this.wetNode = createGain();
16473
this.wetNode["gain"]["value"] = mix / 2;
16474
this.filterNode = context["createBiquadFilter"]();
16475
if (typeof this.filterNode["type"] === "number")
16476
this.filterNode["type"] = 7; // all-pass
16477
else
16478
this.filterNode["type"] = "allpass";
16479
this.filterNode["frequency"]["value"] = freq;
16480
if (this.filterNode["detune"]) // iOS 6 doesn't have detune yet
16481
this.filterNode["detune"]["value"] = detune;
16482
this.filterNode["Q"]["value"] = q;
16483
this.oscNode = context["createOscillator"]();
16484
this.oscNode["frequency"]["value"] = modfreq;
16485
this.oscGainNode = createGain();
16486
this.oscGainNode["gain"]["value"] = modulation;
16487
this.inputNode["connect"](this.filterNode);
16488
this.inputNode["connect"](this.dryNode);
16489
this.filterNode["connect"](this.wetNode);
16490
this.oscNode["connect"](this.oscGainNode);
16491
this.oscGainNode["connect"](this.filterNode["frequency"]);
16492
startSource(this.oscNode);
16493
};
16494
PhaserEffect.prototype.connectTo = function (node)
16495
{
16496
this.dryNode["disconnect"]();
16497
this.dryNode["connect"](node);
16498
this.wetNode["disconnect"]();
16499
this.wetNode["connect"](node);
16500
};
16501
PhaserEffect.prototype.remove = function ()
16502
{
16503
this.inputNode["disconnect"]();
16504
this.filterNode["disconnect"]();
16505
this.oscNode["disconnect"]();
16506
this.oscGainNode["disconnect"]();
16507
this.dryNode["disconnect"]();
16508
this.wetNode["disconnect"]();
16509
};
16510
PhaserEffect.prototype.getInputNode = function ()
16511
{
16512
return this.inputNode;
16513
};
16514
PhaserEffect.prototype.setParam = function(param, value, ramp, time)
16515
{
16516
switch (param) {
16517
case 0: // mix
16518
value = value / 100;
16519
if (value < 0) value = 0;
16520
if (value > 1) value = 1;
16521
this.params[5] = value;
16522
setAudioParam(this.wetNode["gain"], value / 2, ramp, time);
16523
setAudioParam(this.dryNode["gain"], 1 - (value / 2), ramp, time);
16524
break;
16525
case 1: // filter frequency
16526
this.params[0] = value;
16527
setAudioParam(this.filterNode["frequency"], value, ramp, time);
16528
break;
16529
case 2: // filter detune
16530
this.params[1] = value;
16531
setAudioParam(this.filterNode["detune"], value, ramp, time);
16532
break;
16533
case 3: // filter Q
16534
this.params[2] = value;
16535
setAudioParam(this.filterNode["Q"], value, ramp, time);
16536
break;
16537
case 6: // modulation
16538
this.params[3] = value;
16539
setAudioParam(this.oscGainNode["gain"], value, ramp, time);
16540
break;
16541
case 7: // modulation frequency
16542
this.params[4] = value;
16543
setAudioParam(this.oscNode["frequency"], value, ramp, time);
16544
break;
16545
}
16546
};
16547
function GainEffect(g)
16548
{
16549
this.type = "gain";
16550
this.params = [g];
16551
this.node = createGain();
16552
this.node["gain"]["value"] = g;
16553
};
16554
GainEffect.prototype.connectTo = function (node_)
16555
{
16556
this.node["disconnect"]();
16557
this.node["connect"](node_);
16558
};
16559
GainEffect.prototype.remove = function ()
16560
{
16561
this.node["disconnect"]();
16562
};
16563
GainEffect.prototype.getInputNode = function ()
16564
{
16565
return this.node;
16566
};
16567
GainEffect.prototype.setParam = function(param, value, ramp, time)
16568
{
16569
switch (param) {
16570
case 4: // gain
16571
this.params[0] = dbToLinear(value);
16572
setAudioParam(this.node["gain"], dbToLinear(value), ramp, time);
16573
break;
16574
}
16575
};
16576
function TremoloEffect(freq, mix)
16577
{
16578
this.type = "tremolo";
16579
this.params = [freq, mix];
16580
this.node = createGain();
16581
this.node["gain"]["value"] = 1 - (mix / 2);
16582
this.oscNode = context["createOscillator"]();
16583
this.oscNode["frequency"]["value"] = freq;
16584
this.oscGainNode = createGain();
16585
this.oscGainNode["gain"]["value"] = mix / 2;
16586
this.oscNode["connect"](this.oscGainNode);
16587
this.oscGainNode["connect"](this.node["gain"]);
16588
startSource(this.oscNode);
16589
};
16590
TremoloEffect.prototype.connectTo = function (node_)
16591
{
16592
this.node["disconnect"]();
16593
this.node["connect"](node_);
16594
};
16595
TremoloEffect.prototype.remove = function ()
16596
{
16597
this.oscNode["disconnect"]();
16598
this.oscGainNode["disconnect"]();
16599
this.node["disconnect"]();
16600
};
16601
TremoloEffect.prototype.getInputNode = function ()
16602
{
16603
return this.node;
16604
};
16605
TremoloEffect.prototype.setParam = function(param, value, ramp, time)
16606
{
16607
switch (param) {
16608
case 0: // mix
16609
value = value / 100;
16610
if (value < 0) value = 0;
16611
if (value > 1) value = 1;
16612
this.params[1] = value;
16613
setAudioParam(this.node["gain"]["value"], 1 - (value / 2), ramp, time);
16614
setAudioParam(this.oscGainNode["gain"]["value"], value / 2, ramp, time);
16615
break;
16616
case 7: // modulation frequency
16617
this.params[0] = value;
16618
setAudioParam(this.oscNode["frequency"], value, ramp, time);
16619
break;
16620
}
16621
};
16622
function RingModulatorEffect(freq, mix)
16623
{
16624
this.type = "ringmod";
16625
this.params = [freq, mix];
16626
this.inputNode = createGain();
16627
this.wetNode = createGain();
16628
this.wetNode["gain"]["value"] = mix;
16629
this.dryNode = createGain();
16630
this.dryNode["gain"]["value"] = 1 - mix;
16631
this.ringNode = createGain();
16632
this.ringNode["gain"]["value"] = 0;
16633
this.oscNode = context["createOscillator"]();
16634
this.oscNode["frequency"]["value"] = freq;
16635
this.oscNode["connect"](this.ringNode["gain"]);
16636
startSource(this.oscNode);
16637
this.inputNode["connect"](this.ringNode);
16638
this.inputNode["connect"](this.dryNode);
16639
this.ringNode["connect"](this.wetNode);
16640
};
16641
RingModulatorEffect.prototype.connectTo = function (node_)
16642
{
16643
this.wetNode["disconnect"]();
16644
this.wetNode["connect"](node_);
16645
this.dryNode["disconnect"]();
16646
this.dryNode["connect"](node_);
16647
};
16648
RingModulatorEffect.prototype.remove = function ()
16649
{
16650
this.oscNode["disconnect"]();
16651
this.ringNode["disconnect"]();
16652
this.inputNode["disconnect"]();
16653
this.wetNode["disconnect"]();
16654
this.dryNode["disconnect"]();
16655
};
16656
RingModulatorEffect.prototype.getInputNode = function ()
16657
{
16658
return this.inputNode;
16659
};
16660
RingModulatorEffect.prototype.setParam = function(param, value, ramp, time)
16661
{
16662
switch (param) {
16663
case 0: // mix
16664
value = value / 100;
16665
if (value < 0) value = 0;
16666
if (value > 1) value = 1;
16667
this.params[1] = value;
16668
setAudioParam(this.wetNode["gain"], value, ramp, time);
16669
setAudioParam(this.dryNode["gain"], 1 - value, ramp, time);
16670
break;
16671
case 7: // modulation frequency
16672
this.params[0] = value;
16673
setAudioParam(this.oscNode["frequency"], value, ramp, time);
16674
break;
16675
}
16676
};
16677
function DistortionEffect(threshold, headroom, drive, makeupgain, mix)
16678
{
16679
this.type = "distortion";
16680
this.params = [threshold, headroom, drive, makeupgain, mix];
16681
this.inputNode = createGain();
16682
this.preGain = createGain();
16683
this.postGain = createGain();
16684
this.setDrive(drive, dbToLinear_nocap(makeupgain));
16685
this.wetNode = createGain();
16686
this.wetNode["gain"]["value"] = mix;
16687
this.dryNode = createGain();
16688
this.dryNode["gain"]["value"] = 1 - mix;
16689
this.waveShaper = context["createWaveShaper"]();
16690
this.curve = new Float32Array(65536);
16691
this.generateColortouchCurve(threshold, headroom);
16692
this.waveShaper.curve = this.curve;
16693
this.inputNode["connect"](this.preGain);
16694
this.inputNode["connect"](this.dryNode);
16695
this.preGain["connect"](this.waveShaper);
16696
this.waveShaper["connect"](this.postGain);
16697
this.postGain["connect"](this.wetNode);
16698
};
16699
DistortionEffect.prototype.setDrive = function (drive, makeupgain)
16700
{
16701
if (drive < 0.01)
16702
drive = 0.01;
16703
this.preGain["gain"]["value"] = drive;
16704
this.postGain["gain"]["value"] = Math.pow(1 / drive, 0.6) * makeupgain;
16705
};
16706
function e4(x, k)
16707
{
16708
return 1.0 - Math.exp(-k * x);
16709
}
16710
DistortionEffect.prototype.shape = function (x, linearThreshold, linearHeadroom)
16711
{
16712
var maximum = 1.05 * linearHeadroom * linearThreshold;
16713
var kk = (maximum - linearThreshold);
16714
var sign = x < 0 ? -1 : +1;
16715
var absx = x < 0 ? -x : x;
16716
var shapedInput = absx < linearThreshold ? absx : linearThreshold + kk * e4(absx - linearThreshold, 1.0 / kk);
16717
shapedInput *= sign;
16718
return shapedInput;
16719
};
16720
DistortionEffect.prototype.generateColortouchCurve = function (threshold, headroom)
16721
{
16722
var linearThreshold = dbToLinear_nocap(threshold);
16723
var linearHeadroom = dbToLinear_nocap(headroom);
16724
var n = 65536;
16725
var n2 = n / 2;
16726
var x = 0;
16727
for (var i = 0; i < n2; ++i) {
16728
x = i / n2;
16729
x = this.shape(x, linearThreshold, linearHeadroom);
16730
this.curve[n2 + i] = x;
16731
this.curve[n2 - i - 1] = -x;
16732
}
16733
};
16734
DistortionEffect.prototype.connectTo = function (node)
16735
{
16736
this.wetNode["disconnect"]();
16737
this.wetNode["connect"](node);
16738
this.dryNode["disconnect"]();
16739
this.dryNode["connect"](node);
16740
};
16741
DistortionEffect.prototype.remove = function ()
16742
{
16743
this.inputNode["disconnect"]();
16744
this.preGain["disconnect"]();
16745
this.waveShaper["disconnect"]();
16746
this.postGain["disconnect"]();
16747
this.wetNode["disconnect"]();
16748
this.dryNode["disconnect"]();
16749
};
16750
DistortionEffect.prototype.getInputNode = function ()
16751
{
16752
return this.inputNode;
16753
};
16754
DistortionEffect.prototype.setParam = function(param, value, ramp, time)
16755
{
16756
switch (param) {
16757
case 0: // mix
16758
value = value / 100;
16759
if (value < 0) value = 0;
16760
if (value > 1) value = 1;
16761
this.params[4] = value;
16762
setAudioParam(this.wetNode["gain"], value, ramp, time);
16763
setAudioParam(this.dryNode["gain"], 1 - value, ramp, time);
16764
break;
16765
}
16766
};
16767
function CompressorEffect(threshold, knee, ratio, attack, release)
16768
{
16769
this.type = "compressor";
16770
this.params = [threshold, knee, ratio, attack, release];
16771
this.node = context["createDynamicsCompressor"]();
16772
try {
16773
this.node["threshold"]["value"] = threshold;
16774
this.node["knee"]["value"] = knee;
16775
this.node["ratio"]["value"] = ratio;
16776
this.node["attack"]["value"] = attack;
16777
this.node["release"]["value"] = release;
16778
}
16779
catch (e) {}
16780
};
16781
CompressorEffect.prototype.connectTo = function (node_)
16782
{
16783
this.node["disconnect"]();
16784
this.node["connect"](node_);
16785
};
16786
CompressorEffect.prototype.remove = function ()
16787
{
16788
this.node["disconnect"]();
16789
};
16790
CompressorEffect.prototype.getInputNode = function ()
16791
{
16792
return this.node;
16793
};
16794
CompressorEffect.prototype.setParam = function(param, value, ramp, time)
16795
{
16796
};
16797
function AnalyserEffect(fftSize, smoothing)
16798
{
16799
this.type = "analyser";
16800
this.params = [fftSize, smoothing];
16801
this.node = context["createAnalyser"]();
16802
this.node["fftSize"] = fftSize;
16803
this.node["smoothingTimeConstant"] = smoothing;
16804
this.freqBins = new Float32Array(this.node["frequencyBinCount"]);
16805
this.signal = new Uint8Array(fftSize);
16806
this.peak = 0;
16807
this.rms = 0;
16808
};
16809
AnalyserEffect.prototype.tick = function ()
16810
{
16811
this.node["getFloatFrequencyData"](this.freqBins);
16812
this.node["getByteTimeDomainData"](this.signal);
16813
var fftSize = this.node["fftSize"];
16814
var i = 0;
16815
this.peak = 0;
16816
var rmsSquaredSum = 0;
16817
var s = 0;
16818
for ( ; i < fftSize; i++)
16819
{
16820
s = (this.signal[i] - 128) / 128;
16821
if (s < 0)
16822
s = -s;
16823
if (this.peak < s)
16824
this.peak = s;
16825
rmsSquaredSum += s * s;
16826
}
16827
this.peak = linearToDb(this.peak);
16828
this.rms = linearToDb(Math.sqrt(rmsSquaredSum / fftSize));
16829
};
16830
AnalyserEffect.prototype.connectTo = function (node_)
16831
{
16832
this.node["disconnect"]();
16833
this.node["connect"](node_);
16834
};
16835
AnalyserEffect.prototype.remove = function ()
16836
{
16837
this.node["disconnect"]();
16838
};
16839
AnalyserEffect.prototype.getInputNode = function ()
16840
{
16841
return this.node;
16842
};
16843
AnalyserEffect.prototype.setParam = function(param, value, ramp, time)
16844
{
16845
};
16846
function ObjectTracker()
16847
{
16848
this.obj = null;
16849
this.loadUid = 0;
16850
};
16851
ObjectTracker.prototype.setObject = function (obj_)
16852
{
16853
this.obj = obj_;
16854
};
16855
ObjectTracker.prototype.hasObject = function ()
16856
{
16857
return !!this.obj;
16858
};
16859
ObjectTracker.prototype.tick = function (dt)
16860
{
16861
};
16862
function C2AudioBuffer(src_, is_music)
16863
{
16864
this.src = src_;
16865
this.myapi = api;
16866
this.is_music = is_music;
16867
this.added_end_listener = false;
16868
var self = this;
16869
this.outNode = null;
16870
this.mediaSourceNode = null;
16871
this.panWhenReady = []; // for web audio API positioned sounds
16872
this.seekWhenReady = 0;
16873
this.pauseWhenReady = false;
16874
this.supportWebAudioAPI = false;
16875
this.failedToLoad = false;
16876
this.wasEverReady = false; // if a buffer is ever marked as ready, it's permanently considered ready after then.
16877
if (api === API_WEBAUDIO && is_music && !playMusicAsSoundWorkaround)
16878
{
16879
this.myapi = API_HTML5;
16880
this.outNode = createGain();
16881
}
16882
this.bufferObject = null; // actual audio object
16883
this.audioData = null; // web audio api: ajax request result (compressed audio that needs decoding)
16884
var request;
16885
switch (this.myapi) {
16886
case API_HTML5:
16887
this.bufferObject = new Audio();
16888
this.bufferObject.crossOrigin = "anonymous";
16889
this.bufferObject.addEventListener("canplaythrough", function () {
16890
self.wasEverReady = true; // update loaded state so preload is considered complete
16891
});
16892
if (api === API_WEBAUDIO && context["createMediaElementSource"] && !/wiiu/i.test(navigator.userAgent))
16893
{
16894
this.supportWebAudioAPI = true; // can be routed through web audio api
16895
this.bufferObject.addEventListener("canplay", function ()
16896
{
16897
if (!self.mediaSourceNode && self.bufferObject)
16898
{
16899
self.mediaSourceNode = context["createMediaElementSource"](self.bufferObject);
16900
self.mediaSourceNode["connect"](self.outNode);
16901
}
16902
});
16903
}
16904
this.bufferObject.autoplay = false; // this is only a source buffer, not an instance
16905
this.bufferObject.preload = "auto";
16906
this.bufferObject.src = src_;
16907
break;
16908
case API_WEBAUDIO:
16909
if (audRuntime.isWKWebView)
16910
{
16911
audRuntime.fetchLocalFileViaCordovaAsArrayBuffer(src_, function (arrayBuffer)
16912
{
16913
self.audioData = arrayBuffer;
16914
self.decodeAudioBuffer();
16915
}, function (err)
16916
{
16917
self.failedToLoad = true;
16918
});
16919
}
16920
else
16921
{
16922
request = new XMLHttpRequest();
16923
request.open("GET", src_, true);
16924
request.responseType = "arraybuffer";
16925
request.onload = function () {
16926
self.audioData = request.response;
16927
self.decodeAudioBuffer();
16928
};
16929
request.onerror = function () {
16930
self.failedToLoad = true;
16931
};
16932
request.send();
16933
}
16934
break;
16935
case API_CORDOVA:
16936
this.bufferObject = true;
16937
break;
16938
case API_APPMOBI:
16939
this.bufferObject = true;
16940
break;
16941
}
16942
};
16943
C2AudioBuffer.prototype.release = function ()
16944
{
16945
var i, len, j, a;
16946
for (i = 0, j = 0, len = audioInstances.length; i < len; ++i)
16947
{
16948
a = audioInstances[i];
16949
audioInstances[j] = a;
16950
if (a.buffer === this)
16951
a.stop();
16952
else
16953
++j; // keep
16954
}
16955
audioInstances.length = j;
16956
if (this.mediaSourceNode)
16957
{
16958
this.mediaSourceNode["disconnect"]();
16959
this.mediaSourceNode = null;
16960
}
16961
if (this.outNode)
16962
{
16963
this.outNode["disconnect"]();
16964
this.outNode = null;
16965
}
16966
this.bufferObject = null;
16967
this.audioData = null;
16968
};
16969
C2AudioBuffer.prototype.decodeAudioBuffer = function ()
16970
{
16971
if (this.bufferObject || !this.audioData)
16972
return; // audio already decoded or AJAX request not yet complete
16973
var self = this;
16974
if (context["decodeAudioData"])
16975
{
16976
context["decodeAudioData"](this.audioData, function (buffer) {
16977
self.bufferObject = buffer;
16978
self.audioData = null; // clear AJAX response to allow GC and save memory, only need the bufferObject now
16979
var p, i, len, a;
16980
if (!cr.is_undefined(self.playTagWhenReady) && !silent)
16981
{
16982
if (self.panWhenReady.length)
16983
{
16984
for (i = 0, len = self.panWhenReady.length; i < len; i++)
16985
{
16986
p = self.panWhenReady[i];
16987
a = new C2AudioInstance(self, p.thistag);
16988
a.setPannerEnabled(true);
16989
if (typeof p.objUid !== "undefined")
16990
{
16991
p.obj = audRuntime.getObjectByUID(p.objUid);
16992
if (!p.obj)
16993
continue;
16994
}
16995
if (p.obj)
16996
{
16997
var px = cr.rotatePtAround(p.obj.x, p.obj.y, -p.obj.layer.getAngle(), listenerX, listenerY, true);
16998
var py = cr.rotatePtAround(p.obj.x, p.obj.y, -p.obj.layer.getAngle(), listenerX, listenerY, false);
16999
a.setPan(px, py, cr.to_degrees(p.obj.angle - p.obj.layer.getAngle()), p.ia, p.oa, p.og);
17000
a.setObject(p.obj);
17001
}
17002
else
17003
{
17004
a.setPan(p.x, p.y, p.a, p.ia, p.oa, p.og);
17005
}
17006
a.play(self.loopWhenReady, self.volumeWhenReady, self.seekWhenReady);
17007
if (self.pauseWhenReady)
17008
a.pause();
17009
audioInstances.push(a);
17010
}
17011
cr.clearArray(self.panWhenReady);
17012
}
17013
else
17014
{
17015
a = new C2AudioInstance(self, self.playTagWhenReady || ""); // sometimes playTagWhenReady is not set - TODO: why?
17016
a.play(self.loopWhenReady, self.volumeWhenReady, self.seekWhenReady);
17017
if (self.pauseWhenReady)
17018
a.pause();
17019
audioInstances.push(a);
17020
}
17021
}
17022
else if (!cr.is_undefined(self.convolveWhenReady))
17023
{
17024
var convolveNode = self.convolveWhenReady.convolveNode;
17025
convolveNode["normalize"] = self.normalizeWhenReady;
17026
convolveNode["buffer"] = buffer;
17027
}
17028
}, function (e) {
17029
self.failedToLoad = true;
17030
});
17031
}
17032
else
17033
{
17034
this.bufferObject = context["createBuffer"](this.audioData, false);
17035
this.audioData = null; // clear AJAX response to allow GC and save memory, only need the bufferObject now
17036
if (!cr.is_undefined(this.playTagWhenReady) && !silent)
17037
{
17038
var a = new C2AudioInstance(this, this.playTagWhenReady);
17039
a.play(this.loopWhenReady, this.volumeWhenReady, this.seekWhenReady);
17040
if (this.pauseWhenReady)
17041
a.pause();
17042
audioInstances.push(a);
17043
}
17044
else if (!cr.is_undefined(this.convolveWhenReady))
17045
{
17046
var convolveNode = this.convolveWhenReady.convolveNode;
17047
convolveNode["normalize"] = this.normalizeWhenReady;
17048
convolveNode["buffer"] = this.bufferObject;
17049
}
17050
}
17051
};
17052
C2AudioBuffer.prototype.isLoaded = function ()
17053
{
17054
switch (this.myapi) {
17055
case API_HTML5:
17056
var ret = this.bufferObject["readyState"] >= 4; // HAVE_ENOUGH_DATA
17057
if (ret)
17058
this.wasEverReady = true;
17059
return ret || this.wasEverReady;
17060
case API_WEBAUDIO:
17061
return !!this.audioData || !!this.bufferObject;
17062
case API_CORDOVA:
17063
return true;
17064
case API_APPMOBI:
17065
return true;
17066
}
17067
return false;
17068
};
17069
C2AudioBuffer.prototype.isLoadedAndDecoded = function ()
17070
{
17071
switch (this.myapi) {
17072
case API_HTML5:
17073
return this.isLoaded(); // no distinction between loaded and decoded in HTML5 audio, just rely on ready state
17074
case API_WEBAUDIO:
17075
return !!this.bufferObject;
17076
case API_CORDOVA:
17077
return true;
17078
case API_APPMOBI:
17079
return true;
17080
}
17081
return false;
17082
};
17083
C2AudioBuffer.prototype.hasFailedToLoad = function ()
17084
{
17085
switch (this.myapi) {
17086
case API_HTML5:
17087
return !!this.bufferObject["error"];
17088
case API_WEBAUDIO:
17089
return this.failedToLoad;
17090
}
17091
return false;
17092
};
17093
function C2AudioInstance(buffer_, tag_)
17094
{
17095
var self = this;
17096
this.tag = tag_;
17097
this.fresh = true;
17098
this.stopped = true;
17099
this.src = buffer_.src;
17100
this.buffer = buffer_;
17101
this.myapi = api;
17102
this.is_music = buffer_.is_music;
17103
this.playbackRate = 1;
17104
this.hasPlaybackEnded = true; // ended flag
17105
this.resume_me = false; // make sure resumes when leaving suspend
17106
this.is_paused = false;
17107
this.resume_position = 0; // for web audio api to resume from correct playback position
17108
this.looping = false;
17109
this.is_muted = false;
17110
this.is_silent = false;
17111
this.volume = 1;
17112
this.onended_handler = function (e)
17113
{
17114
if (self.is_paused || self.resume_me)
17115
return;
17116
var bufferThatEnded = this;
17117
if (!bufferThatEnded)
17118
bufferThatEnded = e.target;
17119
if (bufferThatEnded !== self.active_buffer)
17120
return;
17121
self.hasPlaybackEnded = true;
17122
self.stopped = true;
17123
audTag = self.tag;
17124
audRuntime.trigger(cr.plugins_.Audio.prototype.cnds.OnEnded, audInst);
17125
};
17126
this.active_buffer = null;
17127
this.isTimescaled = ((timescale_mode === 1 && !this.is_music) || timescale_mode === 2);
17128
this.mutevol = 1;
17129
this.startTime = (this.isTimescaled ? audRuntime.kahanTime.sum : audRuntime.wallTime.sum);
17130
this.gainNode = null;
17131
this.pannerNode = null;
17132
this.pannerEnabled = false;
17133
this.objectTracker = null;
17134
this.panX = 0;
17135
this.panY = 0;
17136
this.panAngle = 0;
17137
this.panConeInner = 0;
17138
this.panConeOuter = 0;
17139
this.panConeOuterGain = 0;
17140
this.instanceObject = null;
17141
var add_end_listener = false;
17142
if (this.myapi === API_WEBAUDIO && this.buffer.myapi === API_HTML5 && !this.buffer.supportWebAudioAPI)
17143
this.myapi = API_HTML5;
17144
switch (this.myapi) {
17145
case API_HTML5:
17146
if (this.is_music)
17147
{
17148
this.instanceObject = buffer_.bufferObject;
17149
add_end_listener = !buffer_.added_end_listener;
17150
buffer_.added_end_listener = true;
17151
}
17152
else
17153
{
17154
this.instanceObject = new Audio();
17155
this.instanceObject.crossOrigin = "anonymous";
17156
this.instanceObject.autoplay = false;
17157
this.instanceObject.src = buffer_.bufferObject.src;
17158
add_end_listener = true;
17159
}
17160
if (add_end_listener)
17161
{
17162
this.instanceObject.addEventListener('ended', function () {
17163
audTag = self.tag;
17164
self.stopped = true;
17165
audRuntime.trigger(cr.plugins_.Audio.prototype.cnds.OnEnded, audInst);
17166
});
17167
}
17168
break;
17169
case API_WEBAUDIO:
17170
this.gainNode = createGain();
17171
this.gainNode["connect"](getDestinationForTag(tag_));
17172
if (this.buffer.myapi === API_WEBAUDIO)
17173
{
17174
if (buffer_.bufferObject)
17175
{
17176
this.instanceObject = context["createBufferSource"]();
17177
this.instanceObject["buffer"] = buffer_.bufferObject;
17178
this.instanceObject["connect"](this.gainNode);
17179
}
17180
}
17181
else
17182
{
17183
this.instanceObject = this.buffer.bufferObject; // reference the audio element
17184
this.buffer.outNode["connect"](this.gainNode);
17185
if (!this.buffer.added_end_listener)
17186
{
17187
this.buffer.added_end_listener = true;
17188
this.buffer.bufferObject.addEventListener('ended', function () {
17189
audTag = self.tag;
17190
self.stopped = true;
17191
audRuntime.trigger(cr.plugins_.Audio.prototype.cnds.OnEnded, audInst);
17192
});
17193
}
17194
}
17195
break;
17196
case API_CORDOVA:
17197
this.instanceObject = new window["Media"](appPath + this.src, null, null, function (status) {
17198
if (status === window["Media"]["MEDIA_STOPPED"])
17199
{
17200
self.hasPlaybackEnded = true;
17201
self.stopped = true;
17202
audTag = self.tag;
17203
audRuntime.trigger(cr.plugins_.Audio.prototype.cnds.OnEnded, audInst);
17204
}
17205
});
17206
break;
17207
case API_APPMOBI:
17208
this.instanceObject = true;
17209
break;
17210
}
17211
};
17212
C2AudioInstance.prototype.hasEnded = function ()
17213
{
17214
var time;
17215
switch (this.myapi) {
17216
case API_HTML5:
17217
return this.instanceObject.ended;
17218
case API_WEBAUDIO:
17219
if (this.buffer.myapi === API_WEBAUDIO)
17220
{
17221
if (!this.fresh && !this.stopped && this.instanceObject["loop"])
17222
return false;
17223
if (this.is_paused)
17224
return false;
17225
return this.hasPlaybackEnded;
17226
}
17227
else
17228
return this.instanceObject.ended;
17229
case API_CORDOVA:
17230
return this.hasPlaybackEnded;
17231
case API_APPMOBI:
17232
true; // recycling an AppMobi sound does not matter because it will just do another throwaway playSound
17233
}
17234
return true;
17235
};
17236
C2AudioInstance.prototype.canBeRecycled = function ()
17237
{
17238
if (this.fresh || this.stopped)
17239
return true; // not yet used or is not playing
17240
return this.hasEnded();
17241
};
17242
C2AudioInstance.prototype.setPannerEnabled = function (enable_)
17243
{
17244
if (api !== API_WEBAUDIO)
17245
return;
17246
if (!this.pannerEnabled && enable_)
17247
{
17248
if (!this.gainNode)
17249
return;
17250
if (!this.pannerNode)
17251
{
17252
this.pannerNode = context["createPanner"]();
17253
if (typeof this.pannerNode["panningModel"] === "number")
17254
this.pannerNode["panningModel"] = panningModel;
17255
else
17256
this.pannerNode["panningModel"] = ["equalpower", "HRTF", "soundfield"][panningModel];
17257
if (typeof this.pannerNode["distanceModel"] === "number")
17258
this.pannerNode["distanceModel"] = distanceModel;
17259
else
17260
this.pannerNode["distanceModel"] = ["linear", "inverse", "exponential"][distanceModel];
17261
this.pannerNode["refDistance"] = refDistance;
17262
this.pannerNode["maxDistance"] = maxDistance;
17263
this.pannerNode["rolloffFactor"] = rolloffFactor;
17264
}
17265
this.gainNode["disconnect"]();
17266
this.gainNode["connect"](this.pannerNode);
17267
this.pannerNode["connect"](getDestinationForTag(this.tag));
17268
this.pannerEnabled = true;
17269
}
17270
else if (this.pannerEnabled && !enable_)
17271
{
17272
if (!this.gainNode)
17273
return;
17274
this.pannerNode["disconnect"]();
17275
this.gainNode["disconnect"]();
17276
this.gainNode["connect"](getDestinationForTag(this.tag));
17277
this.pannerEnabled = false;
17278
}
17279
};
17280
C2AudioInstance.prototype.setPan = function (x, y, angle, innerangle, outerangle, outergain)
17281
{
17282
if (!this.pannerEnabled || api !== API_WEBAUDIO)
17283
return;
17284
this.pannerNode["setPosition"](x, y, 0);
17285
this.pannerNode["setOrientation"](Math.cos(cr.to_radians(angle)), Math.sin(cr.to_radians(angle)), 0);
17286
this.pannerNode["coneInnerAngle"] = innerangle;
17287
this.pannerNode["coneOuterAngle"] = outerangle;
17288
this.pannerNode["coneOuterGain"] = outergain;
17289
this.panX = x;
17290
this.panY = y;
17291
this.panAngle = angle;
17292
this.panConeInner = innerangle;
17293
this.panConeOuter = outerangle;
17294
this.panConeOuterGain = outergain;
17295
};
17296
C2AudioInstance.prototype.setObject = function (o)
17297
{
17298
if (!this.pannerEnabled || api !== API_WEBAUDIO)
17299
return;
17300
if (!this.objectTracker)
17301
this.objectTracker = new ObjectTracker();
17302
this.objectTracker.setObject(o);
17303
};
17304
C2AudioInstance.prototype.tick = function (dt)
17305
{
17306
if (!this.pannerEnabled || api !== API_WEBAUDIO || !this.objectTracker || !this.objectTracker.hasObject() || !this.isPlaying())
17307
{
17308
return;
17309
}
17310
this.objectTracker.tick(dt);
17311
var inst = this.objectTracker.obj;
17312
var px = cr.rotatePtAround(inst.x, inst.y, -inst.layer.getAngle(), listenerX, listenerY, true);
17313
var py = cr.rotatePtAround(inst.x, inst.y, -inst.layer.getAngle(), listenerX, listenerY, false);
17314
this.pannerNode["setPosition"](px, py, 0);
17315
var a = 0;
17316
if (typeof this.objectTracker.obj.angle !== "undefined")
17317
{
17318
a = inst.angle - inst.layer.getAngle();
17319
this.pannerNode["setOrientation"](Math.cos(a), Math.sin(a), 0);
17320
}
17321
};
17322
C2AudioInstance.prototype.play = function (looping, vol, fromPosition, scheduledTime)
17323
{
17324
var instobj = this.instanceObject;
17325
this.looping = looping;
17326
this.volume = vol;
17327
var seekPos = fromPosition || 0;
17328
scheduledTime = scheduledTime || 0;
17329
switch (this.myapi) {
17330
case API_HTML5:
17331
if (instobj.playbackRate !== 1.0)
17332
instobj.playbackRate = 1.0;
17333
if (instobj.volume !== vol * masterVolume)
17334
instobj.volume = vol * masterVolume;
17335
if (instobj.loop !== looping)
17336
instobj.loop = looping;
17337
if (instobj.muted)
17338
instobj.muted = false;
17339
if (instobj.currentTime !== seekPos)
17340
{
17341
try {
17342
instobj.currentTime = seekPos;
17343
}
17344
catch (err)
17345
{
17346
;
17347
}
17348
}
17349
tryPlayAudioElement(this);
17350
break;
17351
case API_WEBAUDIO:
17352
this.muted = false;
17353
this.mutevol = 1;
17354
if (this.buffer.myapi === API_WEBAUDIO)
17355
{
17356
this.gainNode["gain"]["value"] = vol * masterVolume;
17357
if (!this.fresh)
17358
{
17359
this.instanceObject = context["createBufferSource"]();
17360
this.instanceObject["buffer"] = this.buffer.bufferObject;
17361
this.instanceObject["connect"](this.gainNode);
17362
}
17363
this.instanceObject["onended"] = this.onended_handler;
17364
this.active_buffer = this.instanceObject;
17365
this.instanceObject.loop = looping;
17366
this.hasPlaybackEnded = false;
17367
if (seekPos === 0)
17368
startSource(this.instanceObject, scheduledTime);
17369
else
17370
startSourceAt(this.instanceObject, seekPos, this.getDuration(), scheduledTime);
17371
}
17372
else
17373
{
17374
if (instobj.playbackRate !== 1.0)
17375
instobj.playbackRate = 1.0;
17376
if (instobj.loop !== looping)
17377
instobj.loop = looping;
17378
instobj.volume = vol * masterVolume;
17379
if (instobj.currentTime !== seekPos)
17380
{
17381
try {
17382
instobj.currentTime = seekPos;
17383
}
17384
catch (err)
17385
{
17386
;
17387
}
17388
}
17389
tryPlayAudioElement(this);
17390
}
17391
break;
17392
case API_CORDOVA:
17393
if ((!this.fresh && this.stopped) || seekPos !== 0)
17394
instobj["seekTo"](seekPos);
17395
instobj["play"]();
17396
this.hasPlaybackEnded = false;
17397
break;
17398
case API_APPMOBI:
17399
if (audRuntime.isDirectCanvas)
17400
AppMobi["context"]["playSound"](this.src, looping);
17401
else
17402
AppMobi["player"]["playSound"](this.src, looping);
17403
break;
17404
}
17405
this.playbackRate = 1;
17406
this.startTime = (this.isTimescaled ? audRuntime.kahanTime.sum : audRuntime.wallTime.sum) - seekPos;
17407
this.fresh = false;
17408
this.stopped = false;
17409
this.is_paused = false;
17410
};
17411
C2AudioInstance.prototype.stop = function ()
17412
{
17413
switch (this.myapi) {
17414
case API_HTML5:
17415
if (!this.instanceObject.paused)
17416
this.instanceObject.pause();
17417
break;
17418
case API_WEBAUDIO:
17419
if (this.buffer.myapi === API_WEBAUDIO)
17420
stopSource(this.instanceObject);
17421
else
17422
{
17423
if (!this.instanceObject.paused)
17424
this.instanceObject.pause();
17425
}
17426
break;
17427
case API_CORDOVA:
17428
this.instanceObject["stop"]();
17429
break;
17430
case API_APPMOBI:
17431
if (audRuntime.isDirectCanvas)
17432
AppMobi["context"]["stopSound"](this.src);
17433
break;
17434
}
17435
this.stopped = true;
17436
this.is_paused = false;
17437
};
17438
C2AudioInstance.prototype.pause = function ()
17439
{
17440
if (this.fresh || this.stopped || this.hasEnded() || this.is_paused)
17441
return;
17442
switch (this.myapi) {
17443
case API_HTML5:
17444
if (!this.instanceObject.paused)
17445
this.instanceObject.pause();
17446
break;
17447
case API_WEBAUDIO:
17448
if (this.buffer.myapi === API_WEBAUDIO)
17449
{
17450
this.resume_position = this.getPlaybackTime(true);
17451
if (this.looping)
17452
this.resume_position = this.resume_position % this.getDuration();
17453
this.is_paused = true;
17454
stopSource(this.instanceObject);
17455
}
17456
else
17457
{
17458
if (!this.instanceObject.paused)
17459
this.instanceObject.pause();
17460
}
17461
break;
17462
case API_CORDOVA:
17463
this.instanceObject["pause"]();
17464
break;
17465
case API_APPMOBI:
17466
if (audRuntime.isDirectCanvas)
17467
AppMobi["context"]["stopSound"](this.src);
17468
break;
17469
}
17470
this.is_paused = true;
17471
};
17472
C2AudioInstance.prototype.resume = function ()
17473
{
17474
if (this.fresh || this.stopped || this.hasEnded() || !this.is_paused)
17475
return;
17476
switch (this.myapi) {
17477
case API_HTML5:
17478
tryPlayAudioElement(this);
17479
break;
17480
case API_WEBAUDIO:
17481
if (this.buffer.myapi === API_WEBAUDIO)
17482
{
17483
this.instanceObject = context["createBufferSource"]();
17484
this.instanceObject["buffer"] = this.buffer.bufferObject;
17485
this.instanceObject["connect"](this.gainNode);
17486
this.instanceObject["onended"] = this.onended_handler;
17487
this.active_buffer = this.instanceObject;
17488
this.instanceObject.loop = this.looping;
17489
this.gainNode["gain"]["value"] = masterVolume * this.volume * this.mutevol;
17490
this.updatePlaybackRate();
17491
this.startTime = (this.isTimescaled ? audRuntime.kahanTime.sum : audRuntime.wallTime.sum) - (this.resume_position / (this.playbackRate || 0.001));
17492
startSourceAt(this.instanceObject, this.resume_position, this.getDuration());
17493
}
17494
else
17495
{
17496
tryPlayAudioElement(this);
17497
}
17498
break;
17499
case API_CORDOVA:
17500
this.instanceObject["play"]();
17501
break;
17502
case API_APPMOBI:
17503
if (audRuntime.isDirectCanvas)
17504
AppMobi["context"]["resumeSound"](this.src);
17505
break;
17506
}
17507
this.is_paused = false;
17508
};
17509
C2AudioInstance.prototype.seek = function (pos)
17510
{
17511
if (this.fresh || this.stopped || this.hasEnded())
17512
return;
17513
switch (this.myapi) {
17514
case API_HTML5:
17515
try {
17516
this.instanceObject.currentTime = pos;
17517
}
17518
catch (e) {}
17519
break;
17520
case API_WEBAUDIO:
17521
if (this.buffer.myapi === API_WEBAUDIO)
17522
{
17523
if (this.is_paused)
17524
this.resume_position = pos;
17525
else
17526
{
17527
this.pause();
17528
this.resume_position = pos;
17529
this.resume();
17530
}
17531
}
17532
else
17533
{
17534
try {
17535
this.instanceObject.currentTime = pos;
17536
}
17537
catch (e) {}
17538
}
17539
break;
17540
case API_CORDOVA:
17541
break;
17542
case API_APPMOBI:
17543
if (audRuntime.isDirectCanvas)
17544
AppMobi["context"]["seekSound"](this.src, pos);
17545
break;
17546
}
17547
};
17548
C2AudioInstance.prototype.reconnect = function (toNode)
17549
{
17550
if (this.myapi !== API_WEBAUDIO)
17551
return;
17552
if (this.pannerEnabled)
17553
{
17554
this.pannerNode["disconnect"]();
17555
this.pannerNode["connect"](toNode);
17556
}
17557
else
17558
{
17559
this.gainNode["disconnect"]();
17560
this.gainNode["connect"](toNode);
17561
}
17562
};
17563
C2AudioInstance.prototype.getDuration = function (applyPlaybackRate)
17564
{
17565
var ret = 0;
17566
switch (this.myapi) {
17567
case API_HTML5:
17568
if (typeof this.instanceObject.duration !== "undefined")
17569
ret = this.instanceObject.duration;
17570
break;
17571
case API_WEBAUDIO:
17572
ret = this.buffer.bufferObject["duration"];
17573
break;
17574
case API_CORDOVA:
17575
ret = this.instanceObject["getDuration"]();
17576
break;
17577
case API_APPMOBI:
17578
if (audRuntime.isDirectCanvas)
17579
ret = AppMobi["context"]["getDurationSound"](this.src);
17580
break;
17581
}
17582
if (applyPlaybackRate)
17583
ret /= (this.playbackRate || 0.001); // avoid divide-by-zero
17584
return ret;
17585
};
17586
C2AudioInstance.prototype.getPlaybackTime = function (applyPlaybackRate)
17587
{
17588
var duration = this.getDuration();
17589
var ret = 0;
17590
switch (this.myapi) {
17591
case API_HTML5:
17592
if (typeof this.instanceObject.currentTime !== "undefined")
17593
ret = this.instanceObject.currentTime;
17594
break;
17595
case API_WEBAUDIO:
17596
if (this.buffer.myapi === API_WEBAUDIO)
17597
{
17598
if (this.is_paused)
17599
return this.resume_position;
17600
else
17601
ret = (this.isTimescaled ? audRuntime.kahanTime.sum : audRuntime.wallTime.sum) - this.startTime;
17602
}
17603
else if (typeof this.instanceObject.currentTime !== "undefined")
17604
ret = this.instanceObject.currentTime;
17605
break;
17606
case API_CORDOVA:
17607
break;
17608
case API_APPMOBI:
17609
if (audRuntime.isDirectCanvas)
17610
ret = AppMobi["context"]["getPlaybackTimeSound"](this.src);
17611
break;
17612
}
17613
if (applyPlaybackRate)
17614
ret *= this.playbackRate;
17615
if (!this.looping && ret > duration)
17616
ret = duration;
17617
return ret;
17618
};
17619
C2AudioInstance.prototype.isPlaying = function ()
17620
{
17621
return !this.is_paused && !this.fresh && !this.stopped && !this.hasEnded();
17622
};
17623
C2AudioInstance.prototype.shouldSave = function ()
17624
{
17625
return !this.fresh && !this.stopped && !this.hasEnded();
17626
};
17627
C2AudioInstance.prototype.setVolume = function (v)
17628
{
17629
this.volume = v;
17630
this.updateVolume();
17631
};
17632
C2AudioInstance.prototype.updateVolume = function ()
17633
{
17634
var volToSet = this.volume * masterVolume;
17635
if (!isFinite(volToSet))
17636
volToSet = 0; // HTMLMediaElement throws if setting non-finite volume
17637
switch (this.myapi) {
17638
case API_HTML5:
17639
if (typeof this.instanceObject.volume !== "undefined" && this.instanceObject.volume !== volToSet)
17640
this.instanceObject.volume = volToSet;
17641
break;
17642
case API_WEBAUDIO:
17643
if (this.buffer.myapi === API_WEBAUDIO)
17644
{
17645
this.gainNode["gain"]["value"] = volToSet * this.mutevol;
17646
}
17647
else
17648
{
17649
if (typeof this.instanceObject.volume !== "undefined" && this.instanceObject.volume !== volToSet)
17650
this.instanceObject.volume = volToSet;
17651
}
17652
break;
17653
case API_CORDOVA:
17654
break;
17655
case API_APPMOBI:
17656
break;
17657
}
17658
};
17659
C2AudioInstance.prototype.getVolume = function ()
17660
{
17661
return this.volume;
17662
};
17663
C2AudioInstance.prototype.doSetMuted = function (m)
17664
{
17665
switch (this.myapi) {
17666
case API_HTML5:
17667
if (this.instanceObject.muted !== !!m)
17668
this.instanceObject.muted = !!m;
17669
break;
17670
case API_WEBAUDIO:
17671
if (this.buffer.myapi === API_WEBAUDIO)
17672
{
17673
this.mutevol = (m ? 0 : 1);
17674
this.gainNode["gain"]["value"] = masterVolume * this.volume * this.mutevol;
17675
}
17676
else
17677
{
17678
if (this.instanceObject.muted !== !!m)
17679
this.instanceObject.muted = !!m;
17680
}
17681
break;
17682
case API_CORDOVA:
17683
break;
17684
case API_APPMOBI:
17685
break;
17686
}
17687
};
17688
C2AudioInstance.prototype.setMuted = function (m)
17689
{
17690
this.is_muted = !!m;
17691
this.doSetMuted(this.is_muted || this.is_silent);
17692
};
17693
C2AudioInstance.prototype.setSilent = function (m)
17694
{
17695
this.is_silent = !!m;
17696
this.doSetMuted(this.is_muted || this.is_silent);
17697
};
17698
C2AudioInstance.prototype.setLooping = function (l)
17699
{
17700
this.looping = l;
17701
switch (this.myapi) {
17702
case API_HTML5:
17703
if (this.instanceObject.loop !== !!l)
17704
this.instanceObject.loop = !!l;
17705
break;
17706
case API_WEBAUDIO:
17707
if (this.instanceObject.loop !== !!l)
17708
this.instanceObject.loop = !!l;
17709
break;
17710
case API_CORDOVA:
17711
break;
17712
case API_APPMOBI:
17713
if (audRuntime.isDirectCanvas)
17714
AppMobi["context"]["setLoopingSound"](this.src, l);
17715
break;
17716
}
17717
};
17718
C2AudioInstance.prototype.setPlaybackRate = function (r)
17719
{
17720
this.playbackRate = r;
17721
this.updatePlaybackRate();
17722
};
17723
C2AudioInstance.prototype.updatePlaybackRate = function ()
17724
{
17725
var r = this.playbackRate;
17726
if (this.isTimescaled)
17727
r *= audRuntime.timescale;
17728
switch (this.myapi) {
17729
case API_HTML5:
17730
if (this.instanceObject.playbackRate !== r)
17731
this.instanceObject.playbackRate = r;
17732
break;
17733
case API_WEBAUDIO:
17734
if (this.buffer.myapi === API_WEBAUDIO)
17735
{
17736
if (this.instanceObject["playbackRate"]["value"] !== r)
17737
this.instanceObject["playbackRate"]["value"] = r;
17738
}
17739
else
17740
{
17741
if (this.instanceObject.playbackRate !== r)
17742
this.instanceObject.playbackRate = r;
17743
}
17744
break;
17745
case API_CORDOVA:
17746
break;
17747
case API_APPMOBI:
17748
break;
17749
}
17750
};
17751
C2AudioInstance.prototype.setSuspended = function (s)
17752
{
17753
switch (this.myapi) {
17754
case API_HTML5:
17755
if (s)
17756
{
17757
if (this.isPlaying())
17758
{
17759
this.resume_me = true;
17760
this.instanceObject["pause"]();
17761
}
17762
else
17763
this.resume_me = false;
17764
}
17765
else
17766
{
17767
if (this.resume_me)
17768
{
17769
this.instanceObject["play"]();
17770
this.resume_me = false;
17771
}
17772
}
17773
break;
17774
case API_WEBAUDIO:
17775
if (s)
17776
{
17777
if (this.isPlaying())
17778
{
17779
this.resume_me = true;
17780
if (this.buffer.myapi === API_WEBAUDIO)
17781
{
17782
this.resume_position = this.getPlaybackTime(true);
17783
if (this.looping)
17784
this.resume_position = this.resume_position % this.getDuration();
17785
stopSource(this.instanceObject);
17786
}
17787
else
17788
this.instanceObject["pause"]();
17789
}
17790
else
17791
this.resume_me = false;
17792
}
17793
else
17794
{
17795
if (this.resume_me)
17796
{
17797
if (this.buffer.myapi === API_WEBAUDIO)
17798
{
17799
this.instanceObject = context["createBufferSource"]();
17800
this.instanceObject["buffer"] = this.buffer.bufferObject;
17801
this.instanceObject["connect"](this.gainNode);
17802
this.instanceObject["onended"] = this.onended_handler;
17803
this.active_buffer = this.instanceObject;
17804
this.instanceObject.loop = this.looping;
17805
this.gainNode["gain"]["value"] = masterVolume * this.volume * this.mutevol;
17806
this.updatePlaybackRate();
17807
this.startTime = (this.isTimescaled ? audRuntime.kahanTime.sum : audRuntime.wallTime.sum) - (this.resume_position / (this.playbackRate || 0.001));
17808
startSourceAt(this.instanceObject, this.resume_position, this.getDuration());
17809
}
17810
else
17811
{
17812
this.instanceObject["play"]();
17813
}
17814
this.resume_me = false;
17815
}
17816
}
17817
break;
17818
case API_CORDOVA:
17819
if (s)
17820
{
17821
if (this.isPlaying())
17822
{
17823
this.instanceObject["pause"]();
17824
this.resume_me = true;
17825
}
17826
else
17827
this.resume_me = false;
17828
}
17829
else
17830
{
17831
if (this.resume_me)
17832
{
17833
this.resume_me = false;
17834
this.instanceObject["play"]();
17835
}
17836
}
17837
break;
17838
case API_APPMOBI:
17839
break;
17840
}
17841
};
17842
pluginProto.Instance = function(type)
17843
{
17844
this.type = type;
17845
this.runtime = type.runtime;
17846
audRuntime = this.runtime;
17847
audInst = this;
17848
this.listenerTracker = null;
17849
this.listenerZ = -600;
17850
if (this.runtime.isWKWebView)
17851
playMusicAsSoundWorkaround = true;
17852
if ((this.runtime.isiOS || (this.runtime.isAndroid && (this.runtime.isChrome || this.runtime.isAndroidStockBrowser))) && !this.runtime.isCrosswalk && !this.runtime.isDomFree && !this.runtime.isAmazonWebApp && !playMusicAsSoundWorkaround)
17853
{
17854
useNextTouchWorkaround = true;
17855
}
17856
context = null;
17857
if (typeof AudioContext !== "undefined")
17858
{
17859
api = API_WEBAUDIO;
17860
context = new AudioContext();
17861
}
17862
else if (typeof webkitAudioContext !== "undefined")
17863
{
17864
api = API_WEBAUDIO;
17865
context = new webkitAudioContext();
17866
}
17867
if (this.runtime.isiOS && context)
17868
{
17869
if (context.close)
17870
context.close();
17871
if (typeof AudioContext !== "undefined")
17872
context = new AudioContext();
17873
else if (typeof webkitAudioContext !== "undefined")
17874
context = new webkitAudioContext();
17875
}
17876
if (api !== API_WEBAUDIO)
17877
{
17878
if (this.runtime.isCordova && typeof window["Media"] !== "undefined")
17879
api = API_CORDOVA;
17880
else if (this.runtime.isAppMobi)
17881
api = API_APPMOBI;
17882
}
17883
if (api === API_CORDOVA)
17884
{
17885
appPath = location.href;
17886
var i = appPath.lastIndexOf("/");
17887
if (i > -1)
17888
appPath = appPath.substr(0, i + 1);
17889
appPath = appPath.replace("file://", "");
17890
}
17891
if (this.runtime.isSafari && this.runtime.isWindows && typeof Audio === "undefined")
17892
{
17893
alert("It looks like you're using Safari for Windows without Quicktime. Audio cannot be played until Quicktime is installed.");
17894
this.runtime.DestroyInstance(this);
17895
}
17896
else
17897
{
17898
if (this.runtime.isDirectCanvas)
17899
useOgg = this.runtime.isAndroid; // AAC on iOS, OGG on Android
17900
else
17901
{
17902
try {
17903
useOgg = !!(new Audio().canPlayType('audio/ogg; codecs="vorbis"')) &&
17904
!this.runtime.isWindows10;
17905
}
17906
catch (e)
17907
{
17908
useOgg = false;
17909
}
17910
}
17911
switch (api) {
17912
case API_HTML5:
17913
;
17914
break;
17915
case API_WEBAUDIO:
17916
;
17917
break;
17918
case API_CORDOVA:
17919
;
17920
break;
17921
case API_APPMOBI:
17922
;
17923
break;
17924
default:
17925
;
17926
}
17927
this.runtime.tickMe(this);
17928
}
17929
};
17930
var instanceProto = pluginProto.Instance.prototype;
17931
instanceProto.onCreate = function ()
17932
{
17933
this.runtime.audioInstance = this;
17934
timescale_mode = this.properties[0]; // 0 = off, 1 = sounds only, 2 = all
17935
this.saveload = this.properties[1]; // 0 = all, 1 = sounds only, 2 = music only, 3 = none
17936
this.playinbackground = (this.properties[2] !== 0);
17937
this.nextPlayTime = 0;
17938
panningModel = this.properties[3]; // 0 = equalpower, 1 = hrtf, 3 = soundfield
17939
distanceModel = this.properties[4]; // 0 = linear, 1 = inverse, 2 = exponential
17940
this.listenerZ = -this.properties[5];
17941
refDistance = this.properties[6];
17942
maxDistance = this.properties[7];
17943
rolloffFactor = this.properties[8];
17944
this.listenerTracker = new ObjectTracker();
17945
var draw_width = (this.runtime.draw_width || this.runtime.width);
17946
var draw_height = (this.runtime.draw_height || this.runtime.height);
17947
if (api === API_WEBAUDIO)
17948
{
17949
context["listener"]["setPosition"](draw_width / 2, draw_height / 2, this.listenerZ);
17950
context["listener"]["setOrientation"](0, 0, 1, 0, -1, 0);
17951
window["c2OnAudioMicStream"] = function (localMediaStream, tag)
17952
{
17953
if (micSource)
17954
micSource["disconnect"]();
17955
micTag = tag.toLowerCase();
17956
micSource = context["createMediaStreamSource"](localMediaStream);
17957
micSource["connect"](getDestinationForTag(micTag));
17958
};
17959
}
17960
this.runtime.addSuspendCallback(function(s)
17961
{
17962
audInst.onSuspend(s);
17963
});
17964
var self = this;
17965
this.runtime.addDestroyCallback(function (inst)
17966
{
17967
self.onInstanceDestroyed(inst);
17968
});
17969
};
17970
instanceProto.onInstanceDestroyed = function (inst)
17971
{
17972
var i, len, a;
17973
for (i = 0, len = audioInstances.length; i < len; i++)
17974
{
17975
a = audioInstances[i];
17976
if (a.objectTracker)
17977
{
17978
if (a.objectTracker.obj === inst)
17979
{
17980
a.objectTracker.obj = null;
17981
if (a.pannerEnabled && a.isPlaying() && a.looping)
17982
a.stop();
17983
}
17984
}
17985
}
17986
if (this.listenerTracker.obj === inst)
17987
this.listenerTracker.obj = null;
17988
};
17989
instanceProto.saveToJSON = function ()
17990
{
17991
var o = {
17992
"silent": silent,
17993
"masterVolume": masterVolume,
17994
"listenerZ": this.listenerZ,
17995
"listenerUid": this.listenerTracker.hasObject() ? this.listenerTracker.obj.uid : -1,
17996
"playing": [],
17997
"effects": {}
17998
};
17999
var playingarr = o["playing"];
18000
var i, len, a, d, p, panobj, playbackTime;
18001
for (i = 0, len = audioInstances.length; i < len; i++)
18002
{
18003
a = audioInstances[i];
18004
if (!a.shouldSave())
18005
continue; // no need to save stopped sounds
18006
if (this.saveload === 3) // not saving/loading any sounds/music
18007
continue;
18008
if (a.is_music && this.saveload === 1) // not saving/loading music
18009
continue;
18010
if (!a.is_music && this.saveload === 2) // not saving/loading sound
18011
continue;
18012
playbackTime = a.getPlaybackTime();
18013
if (a.looping)
18014
playbackTime = playbackTime % a.getDuration();
18015
d = {
18016
"tag": a.tag,
18017
"buffersrc": a.buffer.src,
18018
"is_music": a.is_music,
18019
"playbackTime": playbackTime,
18020
"volume": a.volume,
18021
"looping": a.looping,
18022
"muted": a.is_muted,
18023
"playbackRate": a.playbackRate,
18024
"paused": a.is_paused,
18025
"resume_position": a.resume_position
18026
};
18027
if (a.pannerEnabled)
18028
{
18029
d["pan"] = {};
18030
panobj = d["pan"];
18031
if (a.objectTracker && a.objectTracker.hasObject())
18032
{
18033
panobj["objUid"] = a.objectTracker.obj.uid;
18034
}
18035
else
18036
{
18037
panobj["x"] = a.panX;
18038
panobj["y"] = a.panY;
18039
panobj["a"] = a.panAngle;
18040
}
18041
panobj["ia"] = a.panConeInner;
18042
panobj["oa"] = a.panConeOuter;
18043
panobj["og"] = a.panConeOuterGain;
18044
}
18045
playingarr.push(d);
18046
}
18047
var fxobj = o["effects"];
18048
var fxarr;
18049
for (p in effects)
18050
{
18051
if (effects.hasOwnProperty(p))
18052
{
18053
fxarr = [];
18054
for (i = 0, len = effects[p].length; i < len; i++)
18055
{
18056
fxarr.push({ "type": effects[p][i].type, "params": effects[p][i].params });
18057
}
18058
fxobj[p] = fxarr;
18059
}
18060
}
18061
return o;
18062
};
18063
var objectTrackerUidsToLoad = [];
18064
instanceProto.loadFromJSON = function (o)
18065
{
18066
var setSilent = o["silent"];
18067
masterVolume = o["masterVolume"];
18068
this.listenerZ = o["listenerZ"];
18069
this.listenerTracker.setObject(null);
18070
var listenerUid = o["listenerUid"];
18071
if (listenerUid !== -1)
18072
{
18073
this.listenerTracker.loadUid = listenerUid;
18074
objectTrackerUidsToLoad.push(this.listenerTracker);
18075
}
18076
var playingarr = o["playing"];
18077
var i, len, d, src, is_music, tag, playbackTime, looping, vol, b, a, p, pan, panObjUid;
18078
if (this.saveload !== 3)
18079
{
18080
for (i = 0, len = audioInstances.length; i < len; i++)
18081
{
18082
a = audioInstances[i];
18083
if (a.is_music && this.saveload === 1)
18084
continue; // only saving/loading sound: leave music playing
18085
if (!a.is_music && this.saveload === 2)
18086
continue; // only saving/loading music: leave sound playing
18087
a.stop();
18088
}
18089
}
18090
var fxarr, fxtype, fxparams, fx;
18091
for (p in effects)
18092
{
18093
if (effects.hasOwnProperty(p))
18094
{
18095
for (i = 0, len = effects[p].length; i < len; i++)
18096
effects[p][i].remove();
18097
}
18098
}
18099
cr.wipe(effects);
18100
for (p in o["effects"])
18101
{
18102
if (o["effects"].hasOwnProperty(p))
18103
{
18104
fxarr = o["effects"][p];
18105
for (i = 0, len = fxarr.length; i < len; i++)
18106
{
18107
fxtype = fxarr[i]["type"];
18108
fxparams = fxarr[i]["params"];
18109
switch (fxtype) {
18110
case "filter":
18111
addEffectForTag(p, new FilterEffect(fxparams[0], fxparams[1], fxparams[2], fxparams[3], fxparams[4], fxparams[5]));
18112
break;
18113
case "delay":
18114
addEffectForTag(p, new DelayEffect(fxparams[0], fxparams[1], fxparams[2]));
18115
break;
18116
case "convolve":
18117
src = fxparams[2];
18118
b = this.getAudioBuffer(src, false);
18119
if (b.bufferObject)
18120
{
18121
fx = new ConvolveEffect(b.bufferObject, fxparams[0], fxparams[1], src);
18122
}
18123
else
18124
{
18125
fx = new ConvolveEffect(null, fxparams[0], fxparams[1], src);
18126
b.normalizeWhenReady = fxparams[0];
18127
b.convolveWhenReady = fx;
18128
}
18129
addEffectForTag(p, fx);
18130
break;
18131
case "flanger":
18132
addEffectForTag(p, new FlangerEffect(fxparams[0], fxparams[1], fxparams[2], fxparams[3], fxparams[4]));
18133
break;
18134
case "phaser":
18135
addEffectForTag(p, new PhaserEffect(fxparams[0], fxparams[1], fxparams[2], fxparams[3], fxparams[4], fxparams[5]));
18136
break;
18137
case "gain":
18138
addEffectForTag(p, new GainEffect(fxparams[0]));
18139
break;
18140
case "tremolo":
18141
addEffectForTag(p, new TremoloEffect(fxparams[0], fxparams[1]));
18142
break;
18143
case "ringmod":
18144
addEffectForTag(p, new RingModulatorEffect(fxparams[0], fxparams[1]));
18145
break;
18146
case "distortion":
18147
addEffectForTag(p, new DistortionEffect(fxparams[0], fxparams[1], fxparams[2], fxparams[3], fxparams[4]));
18148
break;
18149
case "compressor":
18150
addEffectForTag(p, new CompressorEffect(fxparams[0], fxparams[1], fxparams[2], fxparams[3], fxparams[4]));
18151
break;
18152
case "analyser":
18153
addEffectForTag(p, new AnalyserEffect(fxparams[0], fxparams[1]));
18154
break;
18155
}
18156
}
18157
}
18158
}
18159
for (i = 0, len = playingarr.length; i < len; i++)
18160
{
18161
if (this.saveload === 3) // not saving/loading any sounds/music
18162
continue;
18163
d = playingarr[i];
18164
src = d["buffersrc"];
18165
is_music = d["is_music"];
18166
tag = d["tag"];
18167
playbackTime = d["playbackTime"];
18168
looping = d["looping"];
18169
vol = d["volume"];
18170
pan = d["pan"];
18171
panObjUid = (pan && pan.hasOwnProperty("objUid")) ? pan["objUid"] : -1;
18172
if (is_music && this.saveload === 1) // not saving/loading music
18173
continue;
18174
if (!is_music && this.saveload === 2) // not saving/loading sound
18175
continue;
18176
a = this.getAudioInstance(src, tag, is_music, looping, vol);
18177
if (!a)
18178
{
18179
b = this.getAudioBuffer(src, is_music);
18180
b.seekWhenReady = playbackTime;
18181
b.pauseWhenReady = d["paused"];
18182
if (pan)
18183
{
18184
if (panObjUid !== -1)
18185
{
18186
b.panWhenReady.push({ objUid: panObjUid, ia: pan["ia"], oa: pan["oa"], og: pan["og"], thistag: tag });
18187
}
18188
else
18189
{
18190
b.panWhenReady.push({ x: pan["x"], y: pan["y"], a: pan["a"], ia: pan["ia"], oa: pan["oa"], og: pan["og"], thistag: tag });
18191
}
18192
}
18193
continue;
18194
}
18195
a.resume_position = d["resume_position"];
18196
a.setPannerEnabled(!!pan);
18197
a.play(looping, vol, playbackTime);
18198
a.updatePlaybackRate();
18199
a.updateVolume();
18200
a.doSetMuted(a.is_muted || a.is_silent);
18201
if (d["paused"])
18202
a.pause();
18203
if (d["muted"])
18204
a.setMuted(true);
18205
a.doSetMuted(a.is_muted || a.is_silent);
18206
if (pan)
18207
{
18208
if (panObjUid !== -1)
18209
{
18210
a.objectTracker = a.objectTracker || new ObjectTracker();
18211
a.objectTracker.loadUid = panObjUid;
18212
objectTrackerUidsToLoad.push(a.objectTracker);
18213
}
18214
else
18215
{
18216
a.setPan(pan["x"], pan["y"], pan["a"], pan["ia"], pan["oa"], pan["og"]);
18217
}
18218
}
18219
}
18220
if (setSilent && !silent) // setting silent
18221
{
18222
for (i = 0, len = audioInstances.length; i < len; i++)
18223
audioInstances[i].setSilent(true);
18224
silent = true;
18225
}
18226
else if (!setSilent && silent) // setting not silent
18227
{
18228
for (i = 0, len = audioInstances.length; i < len; i++)
18229
audioInstances[i].setSilent(false);
18230
silent = false;
18231
}
18232
};
18233
instanceProto.afterLoad = function ()
18234
{
18235
var i, len, ot, inst;
18236
for (i = 0, len = objectTrackerUidsToLoad.length; i < len; i++)
18237
{
18238
ot = objectTrackerUidsToLoad[i];
18239
inst = this.runtime.getObjectByUID(ot.loadUid);
18240
ot.setObject(inst);
18241
ot.loadUid = -1;
18242
if (inst)
18243
{
18244
listenerX = inst.x;
18245
listenerY = inst.y;
18246
}
18247
}
18248
cr.clearArray(objectTrackerUidsToLoad);
18249
};
18250
instanceProto.onSuspend = function (s)
18251
{
18252
if (this.playinbackground)
18253
return;
18254
if (!s && context && context["resume"])
18255
{
18256
context["resume"]();
18257
isContextSuspended = false;
18258
}
18259
var i, len;
18260
for (i = 0, len = audioInstances.length; i < len; i++)
18261
audioInstances[i].setSuspended(s);
18262
if (s && context && context["suspend"])
18263
{
18264
context["suspend"]();
18265
isContextSuspended = true;
18266
}
18267
};
18268
instanceProto.tick = function ()
18269
{
18270
var dt = this.runtime.dt;
18271
var i, len, a;
18272
for (i = 0, len = audioInstances.length; i < len; i++)
18273
{
18274
a = audioInstances[i];
18275
a.tick(dt);
18276
if (timescale_mode !== 0)
18277
a.updatePlaybackRate();
18278
}
18279
var p, arr, f;
18280
for (p in effects)
18281
{
18282
if (effects.hasOwnProperty(p))
18283
{
18284
arr = effects[p];
18285
for (i = 0, len = arr.length; i < len; i++)
18286
{
18287
f = arr[i];
18288
if (f.tick)
18289
f.tick();
18290
}
18291
}
18292
}
18293
if (api === API_WEBAUDIO && this.listenerTracker.hasObject())
18294
{
18295
this.listenerTracker.tick(dt);
18296
listenerX = this.listenerTracker.obj.x;
18297
listenerY = this.listenerTracker.obj.y;
18298
context["listener"]["setPosition"](this.listenerTracker.obj.x, this.listenerTracker.obj.y, this.listenerZ);
18299
}
18300
};
18301
var preload_list = [];
18302
instanceProto.setPreloadList = function (arr)
18303
{
18304
var i, len, p, filename, size, isOgg;
18305
var total_size = 0;
18306
for (i = 0, len = arr.length; i < len; ++i)
18307
{
18308
p = arr[i];
18309
filename = p[0];
18310
size = p[1] * 2;
18311
isOgg = (filename.length > 4 && filename.substr(filename.length - 4) === ".ogg");
18312
if ((isOgg && useOgg) || (!isOgg && !useOgg))
18313
{
18314
preload_list.push({
18315
filename: filename,
18316
size: size,
18317
obj: null
18318
});
18319
total_size += size;
18320
}
18321
}
18322
return total_size;
18323
};
18324
instanceProto.startPreloads = function ()
18325
{
18326
var i, len, p, src;
18327
for (i = 0, len = preload_list.length; i < len; ++i)
18328
{
18329
p = preload_list[i];
18330
src = this.runtime.files_subfolder + p.filename;
18331
p.obj = this.getAudioBuffer(src, false);
18332
}
18333
};
18334
instanceProto.getPreloadedSize = function ()
18335
{
18336
var completed = 0;
18337
var i, len, p;
18338
for (i = 0, len = preload_list.length; i < len; ++i)
18339
{
18340
p = preload_list[i];
18341
if (p.obj.isLoadedAndDecoded() || p.obj.hasFailedToLoad() || this.runtime.isDomFree || this.runtime.isAndroidStockBrowser)
18342
{
18343
completed += p.size;
18344
}
18345
else if (p.obj.isLoaded()) // downloaded but not decoded: only happens in Web Audio API, count as half-way progress
18346
{
18347
completed += Math.floor(p.size / 2);
18348
}
18349
};
18350
return completed;
18351
};
18352
instanceProto.releaseAllMusicBuffers = function ()
18353
{
18354
var i, len, j, b;
18355
for (i = 0, j = 0, len = audioBuffers.length; i < len; ++i)
18356
{
18357
b = audioBuffers[i];
18358
audioBuffers[j] = b;
18359
if (b.is_music)
18360
b.release();
18361
else
18362
++j; // keep
18363
}
18364
audioBuffers.length = j;
18365
};
18366
instanceProto.getAudioBuffer = function (src_, is_music, dont_create)
18367
{
18368
var i, len, a, ret = null, j, k, lenj, ai;
18369
for (i = 0, len = audioBuffers.length; i < len; i++)
18370
{
18371
a = audioBuffers[i];
18372
if (a.src === src_)
18373
{
18374
ret = a;
18375
break;
18376
}
18377
}
18378
if (!ret && !dont_create)
18379
{
18380
if (playMusicAsSoundWorkaround && is_music)
18381
this.releaseAllMusicBuffers();
18382
ret = new C2AudioBuffer(src_, is_music);
18383
audioBuffers.push(ret);
18384
}
18385
return ret;
18386
};
18387
instanceProto.getAudioInstance = function (src_, tag, is_music, looping, vol)
18388
{
18389
var i, len, a;
18390
for (i = 0, len = audioInstances.length; i < len; i++)
18391
{
18392
a = audioInstances[i];
18393
if (a.src === src_ && (a.canBeRecycled() || is_music))
18394
{
18395
a.tag = tag;
18396
return a;
18397
}
18398
}
18399
var b = this.getAudioBuffer(src_, is_music);
18400
if (!b.bufferObject)
18401
{
18402
if (tag !== "<preload>")
18403
{
18404
b.playTagWhenReady = tag;
18405
b.loopWhenReady = looping;
18406
b.volumeWhenReady = vol;
18407
}
18408
return null;
18409
}
18410
a = new C2AudioInstance(b, tag);
18411
audioInstances.push(a);
18412
return a;
18413
};
18414
var taggedAudio = [];
18415
function SortByIsPlaying(a, b)
18416
{
18417
var an = a.isPlaying() ? 1 : 0;
18418
var bn = b.isPlaying() ? 1 : 0;
18419
if (an === bn)
18420
return 0;
18421
else if (an < bn)
18422
return 1;
18423
else
18424
return -1;
18425
};
18426
function getAudioByTag(tag, sort_by_playing)
18427
{
18428
cr.clearArray(taggedAudio);
18429
if (!tag.length)
18430
{
18431
if (!lastAudio || lastAudio.hasEnded())
18432
return;
18433
else
18434
{
18435
cr.clearArray(taggedAudio);
18436
taggedAudio[0] = lastAudio;
18437
return;
18438
}
18439
}
18440
var i, len, a;
18441
for (i = 0, len = audioInstances.length; i < len; i++)
18442
{
18443
a = audioInstances[i];
18444
if (cr.equals_nocase(tag, a.tag))
18445
taggedAudio.push(a);
18446
}
18447
if (sort_by_playing)
18448
taggedAudio.sort(SortByIsPlaying);
18449
};
18450
function reconnectEffects(tag)
18451
{
18452
var i, len, arr, n, toNode = context["destination"];
18453
if (effects.hasOwnProperty(tag))
18454
{
18455
arr = effects[tag];
18456
if (arr.length)
18457
{
18458
toNode = arr[0].getInputNode();
18459
for (i = 0, len = arr.length; i < len; i++)
18460
{
18461
n = arr[i];
18462
if (i + 1 === len)
18463
n.connectTo(context["destination"]);
18464
else
18465
n.connectTo(arr[i + 1].getInputNode());
18466
}
18467
}
18468
}
18469
getAudioByTag(tag);
18470
for (i = 0, len = taggedAudio.length; i < len; i++)
18471
taggedAudio[i].reconnect(toNode);
18472
if (micSource && micTag === tag)
18473
{
18474
micSource["disconnect"]();
18475
micSource["connect"](toNode);
18476
}
18477
};
18478
function addEffectForTag(tag, fx)
18479
{
18480
if (!effects.hasOwnProperty(tag))
18481
effects[tag] = [fx];
18482
else
18483
effects[tag].push(fx);
18484
reconnectEffects(tag);
18485
};
18486
function Cnds() {};
18487
Cnds.prototype.OnEnded = function (t)
18488
{
18489
return cr.equals_nocase(audTag, t);
18490
};
18491
Cnds.prototype.PreloadsComplete = function ()
18492
{
18493
var i, len;
18494
for (i = 0, len = audioBuffers.length; i < len; i++)
18495
{
18496
if (!audioBuffers[i].isLoadedAndDecoded() && !audioBuffers[i].hasFailedToLoad())
18497
return false;
18498
}
18499
return true;
18500
};
18501
Cnds.prototype.AdvancedAudioSupported = function ()
18502
{
18503
return api === API_WEBAUDIO;
18504
};
18505
Cnds.prototype.IsSilent = function ()
18506
{
18507
return silent;
18508
};
18509
Cnds.prototype.IsAnyPlaying = function ()
18510
{
18511
var i, len;
18512
for (i = 0, len = audioInstances.length; i < len; i++)
18513
{
18514
if (audioInstances[i].isPlaying())
18515
return true;
18516
}
18517
return false;
18518
};
18519
Cnds.prototype.IsTagPlaying = function (tag)
18520
{
18521
getAudioByTag(tag);
18522
var i, len;
18523
for (i = 0, len = taggedAudio.length; i < len; i++)
18524
{
18525
if (taggedAudio[i].isPlaying())
18526
return true;
18527
}
18528
return false;
18529
};
18530
pluginProto.cnds = new Cnds();
18531
function Acts() {};
18532
Acts.prototype.Play = function (file, looping, vol, tag)
18533
{
18534
if (silent)
18535
return;
18536
var v = dbToLinear(vol);
18537
var is_music = file[1];
18538
var src = this.runtime.files_subfolder + file[0] + (useOgg ? ".ogg" : ".m4a");
18539
lastAudio = this.getAudioInstance(src, tag, is_music, looping!==0, v);
18540
if (!lastAudio)
18541
return;
18542
lastAudio.setPannerEnabled(false);
18543
lastAudio.play(looping!==0, v, 0, this.nextPlayTime);
18544
this.nextPlayTime = 0;
18545
};
18546
Acts.prototype.PlayAtPosition = function (file, looping, vol, x_, y_, angle_, innerangle_, outerangle_, outergain_, tag)
18547
{
18548
if (silent)
18549
return;
18550
var v = dbToLinear(vol);
18551
var is_music = file[1];
18552
var src = this.runtime.files_subfolder + file[0] + (useOgg ? ".ogg" : ".m4a");
18553
lastAudio = this.getAudioInstance(src, tag, is_music, looping!==0, v);
18554
if (!lastAudio)
18555
{
18556
var b = this.getAudioBuffer(src, is_music);
18557
b.panWhenReady.push({ x: x_, y: y_, a: angle_, ia: innerangle_, oa: outerangle_, og: dbToLinear(outergain_), thistag: tag });
18558
return;
18559
}
18560
lastAudio.setPannerEnabled(true);
18561
lastAudio.setPan(x_, y_, angle_, innerangle_, outerangle_, dbToLinear(outergain_));
18562
lastAudio.play(looping!==0, v, 0, this.nextPlayTime);
18563
this.nextPlayTime = 0;
18564
};
18565
Acts.prototype.PlayAtObject = function (file, looping, vol, obj, innerangle, outerangle, outergain, tag)
18566
{
18567
if (silent || !obj)
18568
return;
18569
var inst = obj.getFirstPicked();
18570
if (!inst)
18571
return;
18572
var v = dbToLinear(vol);
18573
var is_music = file[1];
18574
var src = this.runtime.files_subfolder + file[0] + (useOgg ? ".ogg" : ".m4a");
18575
lastAudio = this.getAudioInstance(src, tag, is_music, looping!==0, v);
18576
if (!lastAudio)
18577
{
18578
var b = this.getAudioBuffer(src, is_music);
18579
b.panWhenReady.push({ obj: inst, ia: innerangle, oa: outerangle, og: dbToLinear(outergain), thistag: tag });
18580
return;
18581
}
18582
lastAudio.setPannerEnabled(true);
18583
var px = cr.rotatePtAround(inst.x, inst.y, -inst.layer.getAngle(), listenerX, listenerY, true);
18584
var py = cr.rotatePtAround(inst.x, inst.y, -inst.layer.getAngle(), listenerX, listenerY, false);
18585
lastAudio.setPan(px, py, cr.to_degrees(inst.angle - inst.layer.getAngle()), innerangle, outerangle, dbToLinear(outergain));
18586
lastAudio.setObject(inst);
18587
lastAudio.play(looping!==0, v, 0, this.nextPlayTime);
18588
this.nextPlayTime = 0;
18589
};
18590
Acts.prototype.PlayByName = function (folder, filename, looping, vol, tag)
18591
{
18592
if (silent)
18593
return;
18594
var v = dbToLinear(vol);
18595
var is_music = (folder === 1);
18596
var src = this.runtime.files_subfolder + filename.toLowerCase() + (useOgg ? ".ogg" : ".m4a");
18597
lastAudio = this.getAudioInstance(src, tag, is_music, looping!==0, v);
18598
if (!lastAudio)
18599
return;
18600
lastAudio.setPannerEnabled(false);
18601
lastAudio.play(looping!==0, v, 0, this.nextPlayTime);
18602
this.nextPlayTime = 0;
18603
};
18604
Acts.prototype.PlayAtPositionByName = function (folder, filename, looping, vol, x_, y_, angle_, innerangle_, outerangle_, outergain_, tag)
18605
{
18606
if (silent)
18607
return;
18608
var v = dbToLinear(vol);
18609
var is_music = (folder === 1);
18610
var src = this.runtime.files_subfolder + filename.toLowerCase() + (useOgg ? ".ogg" : ".m4a");
18611
lastAudio = this.getAudioInstance(src, tag, is_music, looping!==0, v);
18612
if (!lastAudio)
18613
{
18614
var b = this.getAudioBuffer(src, is_music);
18615
b.panWhenReady.push({ x: x_, y: y_, a: angle_, ia: innerangle_, oa: outerangle_, og: dbToLinear(outergain_), thistag: tag });
18616
return;
18617
}
18618
lastAudio.setPannerEnabled(true);
18619
lastAudio.setPan(x_, y_, angle_, innerangle_, outerangle_, dbToLinear(outergain_));
18620
lastAudio.play(looping!==0, v, 0, this.nextPlayTime);
18621
this.nextPlayTime = 0;
18622
};
18623
Acts.prototype.PlayAtObjectByName = function (folder, filename, looping, vol, obj, innerangle, outerangle, outergain, tag)
18624
{
18625
if (silent || !obj)
18626
return;
18627
var inst = obj.getFirstPicked();
18628
if (!inst)
18629
return;
18630
var v = dbToLinear(vol);
18631
var is_music = (folder === 1);
18632
var src = this.runtime.files_subfolder + filename.toLowerCase() + (useOgg ? ".ogg" : ".m4a");
18633
lastAudio = this.getAudioInstance(src, tag, is_music, looping!==0, v);
18634
if (!lastAudio)
18635
{
18636
var b = this.getAudioBuffer(src, is_music);
18637
b.panWhenReady.push({ obj: inst, ia: innerangle, oa: outerangle, og: dbToLinear(outergain), thistag: tag });
18638
return;
18639
}
18640
lastAudio.setPannerEnabled(true);
18641
var px = cr.rotatePtAround(inst.x, inst.y, -inst.layer.getAngle(), listenerX, listenerY, true);
18642
var py = cr.rotatePtAround(inst.x, inst.y, -inst.layer.getAngle(), listenerX, listenerY, false);
18643
lastAudio.setPan(px, py, cr.to_degrees(inst.angle - inst.layer.getAngle()), innerangle, outerangle, dbToLinear(outergain));
18644
lastAudio.setObject(inst);
18645
lastAudio.play(looping!==0, v, 0, this.nextPlayTime);
18646
this.nextPlayTime = 0;
18647
};
18648
Acts.prototype.SetLooping = function (tag, looping)
18649
{
18650
getAudioByTag(tag);
18651
var i, len;
18652
for (i = 0, len = taggedAudio.length; i < len; i++)
18653
taggedAudio[i].setLooping(looping === 0);
18654
};
18655
Acts.prototype.SetMuted = function (tag, muted)
18656
{
18657
getAudioByTag(tag);
18658
var i, len;
18659
for (i = 0, len = taggedAudio.length; i < len; i++)
18660
taggedAudio[i].setMuted(muted === 0);
18661
};
18662
Acts.prototype.SetVolume = function (tag, vol)
18663
{
18664
getAudioByTag(tag);
18665
var v = dbToLinear(vol);
18666
var i, len;
18667
for (i = 0, len = taggedAudio.length; i < len; i++)
18668
taggedAudio[i].setVolume(v);
18669
};
18670
Acts.prototype.Preload = function (file)
18671
{
18672
if (silent)
18673
return;
18674
var is_music = file[1];
18675
var src = this.runtime.files_subfolder + file[0] + (useOgg ? ".ogg" : ".m4a");
18676
if (api === API_APPMOBI)
18677
{
18678
if (this.runtime.isDirectCanvas)
18679
AppMobi["context"]["loadSound"](src);
18680
else
18681
AppMobi["player"]["loadSound"](src);
18682
return;
18683
}
18684
else if (api === API_CORDOVA)
18685
{
18686
return;
18687
}
18688
this.getAudioInstance(src, "<preload>", is_music, false);
18689
};
18690
Acts.prototype.PreloadByName = function (folder, filename)
18691
{
18692
if (silent)
18693
return;
18694
var is_music = (folder === 1);
18695
var src = this.runtime.files_subfolder + filename.toLowerCase() + (useOgg ? ".ogg" : ".m4a");
18696
if (api === API_APPMOBI)
18697
{
18698
if (this.runtime.isDirectCanvas)
18699
AppMobi["context"]["loadSound"](src);
18700
else
18701
AppMobi["player"]["loadSound"](src);
18702
return;
18703
}
18704
else if (api === API_CORDOVA)
18705
{
18706
return;
18707
}
18708
this.getAudioInstance(src, "<preload>", is_music, false);
18709
};
18710
Acts.prototype.SetPlaybackRate = function (tag, rate)
18711
{
18712
getAudioByTag(tag);
18713
if (rate < 0.0)
18714
rate = 0;
18715
var i, len;
18716
for (i = 0, len = taggedAudio.length; i < len; i++)
18717
taggedAudio[i].setPlaybackRate(rate);
18718
};
18719
Acts.prototype.Stop = function (tag)
18720
{
18721
getAudioByTag(tag);
18722
var i, len;
18723
for (i = 0, len = taggedAudio.length; i < len; i++)
18724
taggedAudio[i].stop();
18725
};
18726
Acts.prototype.StopAll = function ()
18727
{
18728
var i, len;
18729
for (i = 0, len = audioInstances.length; i < len; i++)
18730
audioInstances[i].stop();
18731
};
18732
Acts.prototype.SetPaused = function (tag, state)
18733
{
18734
getAudioByTag(tag);
18735
var i, len;
18736
for (i = 0, len = taggedAudio.length; i < len; i++)
18737
{
18738
if (state === 0)
18739
taggedAudio[i].pause();
18740
else
18741
taggedAudio[i].resume();
18742
}
18743
};
18744
Acts.prototype.Seek = function (tag, pos)
18745
{
18746
getAudioByTag(tag);
18747
var i, len;
18748
for (i = 0, len = taggedAudio.length; i < len; i++)
18749
{
18750
taggedAudio[i].seek(pos);
18751
}
18752
};
18753
Acts.prototype.SetSilent = function (s)
18754
{
18755
var i, len;
18756
if (s === 2) // toggling
18757
s = (silent ? 1 : 0); // choose opposite state
18758
if (s === 0 && !silent) // setting silent
18759
{
18760
for (i = 0, len = audioInstances.length; i < len; i++)
18761
audioInstances[i].setSilent(true);
18762
silent = true;
18763
}
18764
else if (s === 1 && silent) // setting not silent
18765
{
18766
for (i = 0, len = audioInstances.length; i < len; i++)
18767
audioInstances[i].setSilent(false);
18768
silent = false;
18769
}
18770
};
18771
Acts.prototype.SetMasterVolume = function (vol)
18772
{
18773
masterVolume = dbToLinear(vol);
18774
var i, len;
18775
for (i = 0, len = audioInstances.length; i < len; i++)
18776
audioInstances[i].updateVolume();
18777
};
18778
Acts.prototype.AddFilterEffect = function (tag, type, freq, detune, q, gain, mix)
18779
{
18780
if (api !== API_WEBAUDIO || type < 0 || type >= filterTypes.length || !context["createBiquadFilter"])
18781
return;
18782
tag = tag.toLowerCase();
18783
mix = mix / 100;
18784
if (mix < 0) mix = 0;
18785
if (mix > 1) mix = 1;
18786
addEffectForTag(tag, new FilterEffect(type, freq, detune, q, gain, mix));
18787
};
18788
Acts.prototype.AddDelayEffect = function (tag, delay, gain, mix)
18789
{
18790
if (api !== API_WEBAUDIO)
18791
return;
18792
tag = tag.toLowerCase();
18793
mix = mix / 100;
18794
if (mix < 0) mix = 0;
18795
if (mix > 1) mix = 1;
18796
addEffectForTag(tag, new DelayEffect(delay, dbToLinear(gain), mix));
18797
};
18798
Acts.prototype.AddFlangerEffect = function (tag, delay, modulation, freq, feedback, mix)
18799
{
18800
if (api !== API_WEBAUDIO || !context["createOscillator"])
18801
return;
18802
tag = tag.toLowerCase();
18803
mix = mix / 100;
18804
if (mix < 0) mix = 0;
18805
if (mix > 1) mix = 1;
18806
addEffectForTag(tag, new FlangerEffect(delay / 1000, modulation / 1000, freq, feedback / 100, mix));
18807
};
18808
Acts.prototype.AddPhaserEffect = function (tag, freq, detune, q, mod, modfreq, mix)
18809
{
18810
if (api !== API_WEBAUDIO || !context["createOscillator"])
18811
return;
18812
tag = tag.toLowerCase();
18813
mix = mix / 100;
18814
if (mix < 0) mix = 0;
18815
if (mix > 1) mix = 1;
18816
addEffectForTag(tag, new PhaserEffect(freq, detune, q, mod, modfreq, mix));
18817
};
18818
Acts.prototype.AddConvolutionEffect = function (tag, file, norm, mix)
18819
{
18820
if (api !== API_WEBAUDIO || !context["createConvolver"])
18821
return;
18822
var doNormalize = (norm === 0);
18823
var src = this.runtime.files_subfolder + file[0] + (useOgg ? ".ogg" : ".m4a");
18824
var b = this.getAudioBuffer(src, false);
18825
tag = tag.toLowerCase();
18826
mix = mix / 100;
18827
if (mix < 0) mix = 0;
18828
if (mix > 1) mix = 1;
18829
var fx;
18830
if (b.bufferObject)
18831
{
18832
fx = new ConvolveEffect(b.bufferObject, doNormalize, mix, src);
18833
}
18834
else
18835
{
18836
fx = new ConvolveEffect(null, doNormalize, mix, src);
18837
b.normalizeWhenReady = doNormalize;
18838
b.convolveWhenReady = fx;
18839
}
18840
addEffectForTag(tag, fx);
18841
};
18842
Acts.prototype.AddGainEffect = function (tag, g)
18843
{
18844
if (api !== API_WEBAUDIO)
18845
return;
18846
tag = tag.toLowerCase();
18847
addEffectForTag(tag, new GainEffect(dbToLinear(g)));
18848
};
18849
Acts.prototype.AddMuteEffect = function (tag)
18850
{
18851
if (api !== API_WEBAUDIO)
18852
return;
18853
tag = tag.toLowerCase();
18854
addEffectForTag(tag, new GainEffect(0)); // re-use gain effect with 0 gain
18855
};
18856
Acts.prototype.AddTremoloEffect = function (tag, freq, mix)
18857
{
18858
if (api !== API_WEBAUDIO || !context["createOscillator"])
18859
return;
18860
tag = tag.toLowerCase();
18861
mix = mix / 100;
18862
if (mix < 0) mix = 0;
18863
if (mix > 1) mix = 1;
18864
addEffectForTag(tag, new TremoloEffect(freq, mix));
18865
};
18866
Acts.prototype.AddRingModEffect = function (tag, freq, mix)
18867
{
18868
if (api !== API_WEBAUDIO || !context["createOscillator"])
18869
return;
18870
tag = tag.toLowerCase();
18871
mix = mix / 100;
18872
if (mix < 0) mix = 0;
18873
if (mix > 1) mix = 1;
18874
addEffectForTag(tag, new RingModulatorEffect(freq, mix));
18875
};
18876
Acts.prototype.AddDistortionEffect = function (tag, threshold, headroom, drive, makeupgain, mix)
18877
{
18878
if (api !== API_WEBAUDIO || !context["createWaveShaper"])
18879
return;
18880
tag = tag.toLowerCase();
18881
mix = mix / 100;
18882
if (mix < 0) mix = 0;
18883
if (mix > 1) mix = 1;
18884
addEffectForTag(tag, new DistortionEffect(threshold, headroom, drive, makeupgain, mix));
18885
};
18886
Acts.prototype.AddCompressorEffect = function (tag, threshold, knee, ratio, attack, release)
18887
{
18888
if (api !== API_WEBAUDIO || !context["createDynamicsCompressor"])
18889
return;
18890
tag = tag.toLowerCase();
18891
addEffectForTag(tag, new CompressorEffect(threshold, knee, ratio, attack / 1000, release / 1000));
18892
};
18893
Acts.prototype.AddAnalyserEffect = function (tag, fftSize, smoothing)
18894
{
18895
if (api !== API_WEBAUDIO)
18896
return;
18897
tag = tag.toLowerCase();
18898
addEffectForTag(tag, new AnalyserEffect(fftSize, smoothing));
18899
};
18900
Acts.prototype.RemoveEffects = function (tag)
18901
{
18902
if (api !== API_WEBAUDIO)
18903
return;
18904
tag = tag.toLowerCase();
18905
var i, len, arr;
18906
if (effects.hasOwnProperty(tag))
18907
{
18908
arr = effects[tag];
18909
if (arr.length)
18910
{
18911
for (i = 0, len = arr.length; i < len; i++)
18912
arr[i].remove();
18913
cr.clearArray(arr);
18914
reconnectEffects(tag);
18915
}
18916
}
18917
};
18918
Acts.prototype.SetEffectParameter = function (tag, index, param, value, ramp, time)
18919
{
18920
if (api !== API_WEBAUDIO)
18921
return;
18922
tag = tag.toLowerCase();
18923
index = Math.floor(index);
18924
var arr;
18925
if (!effects.hasOwnProperty(tag))
18926
return;
18927
arr = effects[tag];
18928
if (index < 0 || index >= arr.length)
18929
return;
18930
arr[index].setParam(param, value, ramp, time);
18931
};
18932
Acts.prototype.SetListenerObject = function (obj_)
18933
{
18934
if (!obj_ || api !== API_WEBAUDIO)
18935
return;
18936
var inst = obj_.getFirstPicked();
18937
if (!inst)
18938
return;
18939
this.listenerTracker.setObject(inst);
18940
listenerX = inst.x;
18941
listenerY = inst.y;
18942
};
18943
Acts.prototype.SetListenerZ = function (z)
18944
{
18945
this.listenerZ = z;
18946
};
18947
Acts.prototype.ScheduleNextPlay = function (t)
18948
{
18949
if (!context)
18950
return; // needs Web Audio API
18951
this.nextPlayTime = t;
18952
};
18953
Acts.prototype.UnloadAudio = function (file)
18954
{
18955
var is_music = file[1];
18956
var src = this.runtime.files_subfolder + file[0] + (useOgg ? ".ogg" : ".m4a");
18957
var b = this.getAudioBuffer(src, is_music, true /* don't create if missing */);
18958
if (!b)
18959
return; // not loaded
18960
b.release();
18961
cr.arrayFindRemove(audioBuffers, b);
18962
};
18963
Acts.prototype.UnloadAudioByName = function (folder, filename)
18964
{
18965
var is_music = (folder === 1);
18966
var src = this.runtime.files_subfolder + filename.toLowerCase() + (useOgg ? ".ogg" : ".m4a");
18967
var b = this.getAudioBuffer(src, is_music, true /* don't create if missing */);
18968
if (!b)
18969
return; // not loaded
18970
b.release();
18971
cr.arrayFindRemove(audioBuffers, b);
18972
};
18973
Acts.prototype.UnloadAll = function ()
18974
{
18975
var i, len;
18976
for (i = 0, len = audioBuffers.length; i < len; ++i)
18977
{
18978
audioBuffers[i].release();
18979
};
18980
cr.clearArray(audioBuffers);
18981
};
18982
pluginProto.acts = new Acts();
18983
function Exps() {};
18984
Exps.prototype.Duration = function (ret, tag)
18985
{
18986
getAudioByTag(tag, true);
18987
if (taggedAudio.length)
18988
ret.set_float(taggedAudio[0].getDuration());
18989
else
18990
ret.set_float(0);
18991
};
18992
Exps.prototype.PlaybackTime = function (ret, tag)
18993
{
18994
getAudioByTag(tag, true);
18995
if (taggedAudio.length)
18996
ret.set_float(taggedAudio[0].getPlaybackTime(true));
18997
else
18998
ret.set_float(0);
18999
};
19000
Exps.prototype.Volume = function (ret, tag)
19001
{
19002
getAudioByTag(tag, true);
19003
if (taggedAudio.length)
19004
{
19005
var v = taggedAudio[0].getVolume();
19006
ret.set_float(linearToDb(v));
19007
}
19008
else
19009
ret.set_float(0);
19010
};
19011
Exps.prototype.MasterVolume = function (ret)
19012
{
19013
ret.set_float(linearToDb(masterVolume));
19014
};
19015
Exps.prototype.EffectCount = function (ret, tag)
19016
{
19017
tag = tag.toLowerCase();
19018
var arr = null;
19019
if (effects.hasOwnProperty(tag))
19020
arr = effects[tag];
19021
ret.set_int(arr ? arr.length : 0);
19022
};
19023
function getAnalyser(tag, index)
19024
{
19025
var arr = null;
19026
if (effects.hasOwnProperty(tag))
19027
arr = effects[tag];
19028
if (arr && index >= 0 && index < arr.length && arr[index].freqBins)
19029
return arr[index];
19030
else
19031
return null;
19032
};
19033
Exps.prototype.AnalyserFreqBinCount = function (ret, tag, index)
19034
{
19035
tag = tag.toLowerCase();
19036
index = Math.floor(index);
19037
var analyser = getAnalyser(tag, index);
19038
ret.set_int(analyser ? analyser.node["frequencyBinCount"] : 0);
19039
};
19040
Exps.prototype.AnalyserFreqBinAt = function (ret, tag, index, bin)
19041
{
19042
tag = tag.toLowerCase();
19043
index = Math.floor(index);
19044
bin = Math.floor(bin);
19045
var analyser = getAnalyser(tag, index);
19046
if (!analyser)
19047
ret.set_float(0);
19048
else if (bin < 0 || bin >= analyser.node["frequencyBinCount"])
19049
ret.set_float(0);
19050
else
19051
ret.set_float(analyser.freqBins[bin]);
19052
};
19053
Exps.prototype.AnalyserPeakLevel = function (ret, tag, index)
19054
{
19055
tag = tag.toLowerCase();
19056
index = Math.floor(index);
19057
var analyser = getAnalyser(tag, index);
19058
if (analyser)
19059
ret.set_float(analyser.peak);
19060
else
19061
ret.set_float(0);
19062
};
19063
Exps.prototype.AnalyserRMSLevel = function (ret, tag, index)
19064
{
19065
tag = tag.toLowerCase();
19066
index = Math.floor(index);
19067
var analyser = getAnalyser(tag, index);
19068
if (analyser)
19069
ret.set_float(analyser.rms);
19070
else
19071
ret.set_float(0);
19072
};
19073
Exps.prototype.SampleRate = function (ret)
19074
{
19075
ret.set_int(context ? context.sampleRate : 0);
19076
};
19077
Exps.prototype.CurrentTime = function (ret)
19078
{
19079
ret.set_float(context ? context.currentTime : cr.performance_now());
19080
};
19081
pluginProto.exps = new Exps();
19082
}());
19083
;
19084
;
19085
cr.plugins_.Browser = function(runtime)
19086
{
19087
this.runtime = runtime;
19088
};
19089
(function ()
19090
{
19091
var pluginProto = cr.plugins_.Browser.prototype;
19092
pluginProto.Type = function(plugin)
19093
{
19094
this.plugin = plugin;
19095
this.runtime = plugin.runtime;
19096
};
19097
var typeProto = pluginProto.Type.prototype;
19098
typeProto.onCreate = function()
19099
{
19100
};
19101
var offlineScriptReady = false;
19102
var browserPluginReady = false;
19103
document.addEventListener("DOMContentLoaded", function ()
19104
{
19105
if (window["C2_RegisterSW"] && navigator["serviceWorker"])
19106
{
19107
var offlineClientScript = document.createElement("script");
19108
offlineClientScript.onload = function ()
19109
{
19110
offlineScriptReady = true;
19111
checkReady()
19112
};
19113
offlineClientScript.src = "offlineClient.js";
19114
document.head.appendChild(offlineClientScript);
19115
}
19116
});
19117
var browserInstance = null;
19118
typeProto.onAppBegin = function ()
19119
{
19120
browserPluginReady = true;
19121
checkReady();
19122
};
19123
function checkReady()
19124
{
19125
if (offlineScriptReady && browserPluginReady && window["OfflineClientInfo"])
19126
{
19127
window["OfflineClientInfo"]["SetMessageCallback"](function (e)
19128
{
19129
browserInstance.onSWMessage(e);
19130
});
19131
}
19132
};
19133
pluginProto.Instance = function(type)
19134
{
19135
this.type = type;
19136
this.runtime = type.runtime;
19137
};
19138
var instanceProto = pluginProto.Instance.prototype;
19139
instanceProto.onCreate = function()
19140
{
19141
var self = this;
19142
window.addEventListener("resize", function () {
19143
self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnResize, self);
19144
});
19145
browserInstance = this;
19146
if (typeof navigator.onLine !== "undefined")
19147
{
19148
window.addEventListener("online", function() {
19149
self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnOnline, self);
19150
});
19151
window.addEventListener("offline", function() {
19152
self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnOffline, self);
19153
});
19154
}
19155
if (!this.runtime.isDirectCanvas)
19156
{
19157
document.addEventListener("appMobi.device.update.available", function() {
19158
self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnUpdateReady, self);
19159
});
19160
document.addEventListener("backbutton", function() {
19161
self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnBackButton, self);
19162
});
19163
document.addEventListener("menubutton", function() {
19164
self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnMenuButton, self);
19165
});
19166
document.addEventListener("searchbutton", function() {
19167
self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnSearchButton, self);
19168
});
19169
document.addEventListener("tizenhwkey", function (e) {
19170
var ret;
19171
switch (e["keyName"]) {
19172
case "back":
19173
ret = self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnBackButton, self);
19174
if (!ret)
19175
{
19176
if (window["tizen"])
19177
window["tizen"]["application"]["getCurrentApplication"]()["exit"]();
19178
}
19179
break;
19180
case "menu":
19181
ret = self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnMenuButton, self);
19182
if (!ret)
19183
e.preventDefault();
19184
break;
19185
}
19186
});
19187
}
19188
if (this.runtime.isWindows10 && typeof Windows !== "undefined")
19189
{
19190
Windows["UI"]["Core"]["SystemNavigationManager"]["getForCurrentView"]().addEventListener("backrequested", function (e)
19191
{
19192
var ret = self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnBackButton, self);
19193
if (ret)
19194
e["handled"] = true;
19195
});
19196
}
19197
else if (this.runtime.isWinJS && WinJS["Application"])
19198
{
19199
WinJS["Application"]["onbackclick"] = function (e)
19200
{
19201
return !!self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnBackButton, self);
19202
};
19203
}
19204
this.runtime.addSuspendCallback(function(s) {
19205
if (s)
19206
{
19207
self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnPageHidden, self);
19208
}
19209
else
19210
{
19211
self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnPageVisible, self);
19212
}
19213
});
19214
this.is_arcade = (typeof window["is_scirra_arcade"] !== "undefined");
19215
};
19216
instanceProto.onSWMessage = function (e)
19217
{
19218
var messageType = e["data"]["type"];
19219
if (messageType === "downloading-update")
19220
this.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnUpdateFound, this);
19221
else if (messageType === "update-ready" || messageType === "update-pending")
19222
this.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnUpdateReady, this);
19223
else if (messageType === "offline-ready")
19224
this.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnOfflineReady, this);
19225
};
19226
var batteryManager = null;
19227
var loadedBatteryManager = false;
19228
function maybeLoadBatteryManager()
19229
{
19230
if (loadedBatteryManager)
19231
return;
19232
if (!navigator["getBattery"])
19233
return;
19234
var promise = navigator["getBattery"]();
19235
loadedBatteryManager = true;
19236
if (promise)
19237
{
19238
promise.then(function (manager) {
19239
batteryManager = manager;
19240
});
19241
}
19242
};
19243
function Cnds() {};
19244
Cnds.prototype.CookiesEnabled = function()
19245
{
19246
return navigator ? navigator.cookieEnabled : false;
19247
};
19248
Cnds.prototype.IsOnline = function()
19249
{
19250
return navigator ? navigator.onLine : false;
19251
};
19252
Cnds.prototype.HasJava = function()
19253
{
19254
return navigator ? navigator.javaEnabled() : false;
19255
};
19256
Cnds.prototype.OnOnline = function()
19257
{
19258
return true;
19259
};
19260
Cnds.prototype.OnOffline = function()
19261
{
19262
return true;
19263
};
19264
Cnds.prototype.IsDownloadingUpdate = function ()
19265
{
19266
return false; // deprecated
19267
};
19268
Cnds.prototype.OnUpdateReady = function ()
19269
{
19270
return true;
19271
};
19272
Cnds.prototype.PageVisible = function ()
19273
{
19274
return !this.runtime.isSuspended;
19275
};
19276
Cnds.prototype.OnPageVisible = function ()
19277
{
19278
return true;
19279
};
19280
Cnds.prototype.OnPageHidden = function ()
19281
{
19282
return true;
19283
};
19284
Cnds.prototype.OnResize = function ()
19285
{
19286
return true;
19287
};
19288
Cnds.prototype.IsFullscreen = function ()
19289
{
19290
return !!(document["mozFullScreen"] || document["webkitIsFullScreen"] || document["fullScreen"] || this.runtime.isNodeFullscreen);
19291
};
19292
Cnds.prototype.OnBackButton = function ()
19293
{
19294
return true;
19295
};
19296
Cnds.prototype.OnMenuButton = function ()
19297
{
19298
return true;
19299
};
19300
Cnds.prototype.OnSearchButton = function ()
19301
{
19302
return true;
19303
};
19304
Cnds.prototype.IsMetered = function ()
19305
{
19306
var connection = navigator["connection"] || navigator["mozConnection"] || navigator["webkitConnection"];
19307
if (!connection)
19308
return false;
19309
return !!connection["metered"];
19310
};
19311
Cnds.prototype.IsCharging = function ()
19312
{
19313
var battery = navigator["battery"] || navigator["mozBattery"] || navigator["webkitBattery"];
19314
if (battery)
19315
{
19316
return !!battery["charging"]
19317
}
19318
else
19319
{
19320
maybeLoadBatteryManager();
19321
if (batteryManager)
19322
{
19323
return !!batteryManager["charging"];
19324
}
19325
else
19326
{
19327
return true; // if unknown, default to charging (powered)
19328
}
19329
}
19330
};
19331
Cnds.prototype.IsPortraitLandscape = function (p)
19332
{
19333
var current = (window.innerWidth <= window.innerHeight ? 0 : 1);
19334
return current === p;
19335
};
19336
Cnds.prototype.SupportsFullscreen = function ()
19337
{
19338
if (this.runtime.isNodeWebkit)
19339
return true;
19340
var elem = this.runtime.canvasdiv || this.runtime.canvas;
19341
return !!(elem["requestFullscreen"] || elem["mozRequestFullScreen"] || elem["msRequestFullscreen"] || elem["webkitRequestFullScreen"]);
19342
};
19343
Cnds.prototype.OnUpdateFound = function ()
19344
{
19345
return true;
19346
};
19347
Cnds.prototype.OnUpdateReady = function ()
19348
{
19349
return true;
19350
};
19351
Cnds.prototype.OnOfflineReady = function ()
19352
{
19353
return true;
19354
};
19355
pluginProto.cnds = new Cnds();
19356
function Acts() {};
19357
Acts.prototype.Alert = function (msg)
19358
{
19359
if (!this.runtime.isDomFree)
19360
alert(msg.toString());
19361
};
19362
Acts.prototype.Close = function ()
19363
{
19364
if (this.runtime.isCocoonJs)
19365
CocoonJS["App"]["forceToFinish"]();
19366
else if (window["tizen"])
19367
window["tizen"]["application"]["getCurrentApplication"]()["exit"]();
19368
else if (navigator["app"] && navigator["app"]["exitApp"])
19369
navigator["app"]["exitApp"]();
19370
else if (navigator["device"] && navigator["device"]["exitApp"])
19371
navigator["device"]["exitApp"]();
19372
else if (!this.is_arcade && !this.runtime.isDomFree)
19373
window.close();
19374
};
19375
Acts.prototype.Focus = function ()
19376
{
19377
if (this.runtime.isNodeWebkit)
19378
{
19379
var win = window["nwgui"]["Window"]["get"]();
19380
win["focus"]();
19381
}
19382
else if (!this.is_arcade && !this.runtime.isDomFree)
19383
window.focus();
19384
};
19385
Acts.prototype.Blur = function ()
19386
{
19387
if (this.runtime.isNodeWebkit)
19388
{
19389
var win = window["nwgui"]["Window"]["get"]();
19390
win["blur"]();
19391
}
19392
else if (!this.is_arcade && !this.runtime.isDomFree)
19393
window.blur();
19394
};
19395
Acts.prototype.GoBack = function ()
19396
{
19397
if (navigator["app"] && navigator["app"]["backHistory"])
19398
navigator["app"]["backHistory"]();
19399
else if (!this.is_arcade && !this.runtime.isDomFree && window.back)
19400
window.back();
19401
};
19402
Acts.prototype.GoForward = function ()
19403
{
19404
if (!this.is_arcade && !this.runtime.isDomFree && window.forward)
19405
window.forward();
19406
};
19407
Acts.prototype.GoHome = function ()
19408
{
19409
if (!this.is_arcade && !this.runtime.isDomFree && window.home)
19410
window.home();
19411
};
19412
Acts.prototype.GoToURL = function (url, target)
19413
{
19414
if (this.runtime.isCocoonJs)
19415
CocoonJS["App"]["openURL"](url);
19416
else if (this.runtime.isEjecta)
19417
ejecta["openURL"](url);
19418
else if (this.runtime.isWinJS)
19419
Windows["System"]["Launcher"]["launchUriAsync"](new Windows["Foundation"]["Uri"](url));
19420
else if (navigator["app"] && navigator["app"]["loadUrl"])
19421
navigator["app"]["loadUrl"](url, { "openExternal": true });
19422
else if (this.runtime.isCordova)
19423
window.open(url, "_system");
19424
else if (!this.is_arcade && !this.runtime.isDomFree)
19425
{
19426
if (target === 2 && !this.is_arcade) // top
19427
window.top.location = url;
19428
else if (target === 1 && !this.is_arcade) // parent
19429
window.parent.location = url;
19430
else // self
19431
window.location = url;
19432
}
19433
};
19434
Acts.prototype.GoToURLWindow = function (url, tag)
19435
{
19436
if (this.runtime.isCocoonJs)
19437
CocoonJS["App"]["openURL"](url);
19438
else if (this.runtime.isEjecta)
19439
ejecta["openURL"](url);
19440
else if (this.runtime.isWinJS)
19441
Windows["System"]["Launcher"]["launchUriAsync"](new Windows["Foundation"]["Uri"](url));
19442
else if (navigator["app"] && navigator["app"]["loadUrl"])
19443
navigator["app"]["loadUrl"](url, { "openExternal": true });
19444
else if (this.runtime.isCordova)
19445
window.open(url, "_system");
19446
else if (!this.is_arcade && !this.runtime.isDomFree)
19447
window.open(url, tag);
19448
};
19449
Acts.prototype.Reload = function ()
19450
{
19451
if (!this.is_arcade && !this.runtime.isDomFree)
19452
window.location.reload();
19453
};
19454
var firstRequestFullscreen = true;
19455
var crruntime = null;
19456
function onFullscreenError(e)
19457
{
19458
if (console && console.warn)
19459
console.warn("Fullscreen request failed: ", e);
19460
crruntime["setSize"](window.innerWidth, window.innerHeight);
19461
};
19462
Acts.prototype.RequestFullScreen = function (stretchmode)
19463
{
19464
if (this.runtime.isDomFree)
19465
{
19466
cr.logexport("[Construct 2] Requesting fullscreen is not supported on this platform - the request has been ignored");
19467
return;
19468
}
19469
if (stretchmode >= 2)
19470
stretchmode += 1;
19471
if (stretchmode === 6)
19472
stretchmode = 2;
19473
if (this.runtime.isNodeWebkit)
19474
{
19475
if (this.runtime.isDebug)
19476
{
19477
debuggerFullscreen(true);
19478
}
19479
else if (!this.runtime.isNodeFullscreen && window["nwgui"])
19480
{
19481
window["nwgui"]["Window"]["get"]()["enterFullscreen"]();
19482
this.runtime.isNodeFullscreen = true;
19483
this.runtime.fullscreen_scaling = (stretchmode >= 2 ? stretchmode : 0);
19484
}
19485
}
19486
else
19487
{
19488
if (document["mozFullScreen"] || document["webkitIsFullScreen"] || !!document["msFullscreenElement"] || document["fullScreen"] || document["fullScreenElement"])
19489
{
19490
return;
19491
}
19492
this.runtime.fullscreen_scaling = (stretchmode >= 2 ? stretchmode : 0);
19493
var elem = document.documentElement;
19494
if (firstRequestFullscreen)
19495
{
19496
firstRequestFullscreen = false;
19497
crruntime = this.runtime;
19498
elem.addEventListener("mozfullscreenerror", onFullscreenError);
19499
elem.addEventListener("webkitfullscreenerror", onFullscreenError);
19500
elem.addEventListener("MSFullscreenError", onFullscreenError);
19501
elem.addEventListener("fullscreenerror", onFullscreenError);
19502
}
19503
if (elem["requestFullscreen"])
19504
elem["requestFullscreen"]();
19505
else if (elem["mozRequestFullScreen"])
19506
elem["mozRequestFullScreen"]();
19507
else if (elem["msRequestFullscreen"])
19508
elem["msRequestFullscreen"]();
19509
else if (elem["webkitRequestFullScreen"])
19510
{
19511
if (typeof Element !== "undefined" && typeof Element["ALLOW_KEYBOARD_INPUT"] !== "undefined")
19512
elem["webkitRequestFullScreen"](Element["ALLOW_KEYBOARD_INPUT"]);
19513
else
19514
elem["webkitRequestFullScreen"]();
19515
}
19516
}
19517
};
19518
Acts.prototype.CancelFullScreen = function ()
19519
{
19520
if (this.runtime.isDomFree)
19521
{
19522
cr.logexport("[Construct 2] Exiting fullscreen is not supported on this platform - the request has been ignored");
19523
return;
19524
}
19525
if (this.runtime.isNodeWebkit)
19526
{
19527
if (this.runtime.isDebug)
19528
{
19529
debuggerFullscreen(false);
19530
}
19531
else if (this.runtime.isNodeFullscreen && window["nwgui"])
19532
{
19533
window["nwgui"]["Window"]["get"]()["leaveFullscreen"]();
19534
this.runtime.isNodeFullscreen = false;
19535
}
19536
}
19537
else
19538
{
19539
if (document["exitFullscreen"])
19540
document["exitFullscreen"]();
19541
else if (document["mozCancelFullScreen"])
19542
document["mozCancelFullScreen"]();
19543
else if (document["msExitFullscreen"])
19544
document["msExitFullscreen"]();
19545
else if (document["webkitCancelFullScreen"])
19546
document["webkitCancelFullScreen"]();
19547
}
19548
};
19549
Acts.prototype.Vibrate = function (pattern_)
19550
{
19551
try {
19552
var arr = pattern_.split(",");
19553
var i, len;
19554
for (i = 0, len = arr.length; i < len; i++)
19555
{
19556
arr[i] = parseInt(arr[i], 10);
19557
}
19558
if (navigator["vibrate"])
19559
navigator["vibrate"](arr);
19560
else if (navigator["mozVibrate"])
19561
navigator["mozVibrate"](arr);
19562
else if (navigator["webkitVibrate"])
19563
navigator["webkitVibrate"](arr);
19564
else if (navigator["msVibrate"])
19565
navigator["msVibrate"](arr);
19566
}
19567
catch (e) {}
19568
};
19569
Acts.prototype.InvokeDownload = function (url_, filename_)
19570
{
19571
var a = document.createElement("a");
19572
if (typeof a["download"] === "undefined")
19573
{
19574
window.open(url_);
19575
}
19576
else
19577
{
19578
var body = document.getElementsByTagName("body")[0];
19579
a.textContent = filename_;
19580
a.href = url_;
19581
a["download"] = filename_;
19582
body.appendChild(a);
19583
var clickEvent = new MouseEvent("click");
19584
a.dispatchEvent(clickEvent);
19585
body.removeChild(a);
19586
}
19587
};
19588
Acts.prototype.InvokeDownloadString = function (str_, mimetype_, filename_)
19589
{
19590
var datauri = "data:" + mimetype_ + "," + encodeURIComponent(str_);
19591
var a = document.createElement("a");
19592
if (typeof a["download"] === "undefined")
19593
{
19594
window.open(datauri);
19595
}
19596
else
19597
{
19598
var body = document.getElementsByTagName("body")[0];
19599
a.textContent = filename_;
19600
a.href = datauri;
19601
a["download"] = filename_;
19602
body.appendChild(a);
19603
var clickEvent = new MouseEvent("click");
19604
a.dispatchEvent(clickEvent);
19605
body.removeChild(a);
19606
}
19607
};
19608
Acts.prototype.ConsoleLog = function (type_, msg_)
19609
{
19610
if (typeof console === "undefined")
19611
return;
19612
if (type_ === 0 && console.log)
19613
console.log(msg_.toString());
19614
if (type_ === 1 && console.warn)
19615
console.warn(msg_.toString());
19616
if (type_ === 2 && console.error)
19617
console.error(msg_.toString());
19618
};
19619
Acts.prototype.ConsoleGroup = function (name_)
19620
{
19621
if (console && console.group)
19622
console.group(name_);
19623
};
19624
Acts.prototype.ConsoleGroupEnd = function ()
19625
{
19626
if (console && console.groupEnd)
19627
console.groupEnd();
19628
};
19629
Acts.prototype.ExecJs = function (js_)
19630
{
19631
try {
19632
if (eval)
19633
eval(js_);
19634
}
19635
catch (e)
19636
{
19637
if (console && console.error)
19638
console.error("Error executing Javascript: ", e);
19639
}
19640
};
19641
var orientations = [
19642
"portrait",
19643
"landscape",
19644
"portrait-primary",
19645
"portrait-secondary",
19646
"landscape-primary",
19647
"landscape-secondary"
19648
];
19649
Acts.prototype.LockOrientation = function (o)
19650
{
19651
o = Math.floor(o);
19652
if (o < 0 || o >= orientations.length)
19653
return;
19654
this.runtime.autoLockOrientation = false;
19655
var orientation = orientations[o];
19656
if (screen["orientation"] && screen["orientation"]["lock"])
19657
screen["orientation"]["lock"](orientation);
19658
else if (screen["lockOrientation"])
19659
screen["lockOrientation"](orientation);
19660
else if (screen["webkitLockOrientation"])
19661
screen["webkitLockOrientation"](orientation);
19662
else if (screen["mozLockOrientation"])
19663
screen["mozLockOrientation"](orientation);
19664
else if (screen["msLockOrientation"])
19665
screen["msLockOrientation"](orientation);
19666
};
19667
Acts.prototype.UnlockOrientation = function ()
19668
{
19669
this.runtime.autoLockOrientation = false;
19670
if (screen["orientation"] && screen["orientation"]["unlock"])
19671
screen["orientation"]["unlock"]();
19672
else if (screen["unlockOrientation"])
19673
screen["unlockOrientation"]();
19674
else if (screen["webkitUnlockOrientation"])
19675
screen["webkitUnlockOrientation"]();
19676
else if (screen["mozUnlockOrientation"])
19677
screen["mozUnlockOrientation"]();
19678
else if (screen["msUnlockOrientation"])
19679
screen["msUnlockOrientation"]();
19680
};
19681
pluginProto.acts = new Acts();
19682
function Exps() {};
19683
Exps.prototype.URL = function (ret)
19684
{
19685
ret.set_string(this.runtime.isDomFree ? "" : window.location.toString());
19686
};
19687
Exps.prototype.Protocol = function (ret)
19688
{
19689
ret.set_string(this.runtime.isDomFree ? "" : window.location.protocol);
19690
};
19691
Exps.prototype.Domain = function (ret)
19692
{
19693
ret.set_string(this.runtime.isDomFree ? "" : window.location.hostname);
19694
};
19695
Exps.prototype.PathName = function (ret)
19696
{
19697
ret.set_string(this.runtime.isDomFree ? "" : window.location.pathname);
19698
};
19699
Exps.prototype.Hash = function (ret)
19700
{
19701
ret.set_string(this.runtime.isDomFree ? "" : window.location.hash);
19702
};
19703
Exps.prototype.Referrer = function (ret)
19704
{
19705
ret.set_string(this.runtime.isDomFree ? "" : document.referrer);
19706
};
19707
Exps.prototype.Title = function (ret)
19708
{
19709
ret.set_string(this.runtime.isDomFree ? "" : document.title);
19710
};
19711
Exps.prototype.Name = function (ret)
19712
{
19713
ret.set_string(this.runtime.isDomFree ? "" : navigator.appName);
19714
};
19715
Exps.prototype.Version = function (ret)
19716
{
19717
ret.set_string(this.runtime.isDomFree ? "" : navigator.appVersion);
19718
};
19719
Exps.prototype.Language = function (ret)
19720
{
19721
if (navigator && navigator.language)
19722
ret.set_string(navigator.language);
19723
else
19724
ret.set_string("");
19725
};
19726
Exps.prototype.Platform = function (ret)
19727
{
19728
ret.set_string(this.runtime.isDomFree ? "" : navigator.platform);
19729
};
19730
Exps.prototype.Product = function (ret)
19731
{
19732
if (navigator && navigator.product)
19733
ret.set_string(navigator.product);
19734
else
19735
ret.set_string("");
19736
};
19737
Exps.prototype.Vendor = function (ret)
19738
{
19739
if (navigator && navigator.vendor)
19740
ret.set_string(navigator.vendor);
19741
else
19742
ret.set_string("");
19743
};
19744
Exps.prototype.UserAgent = function (ret)
19745
{
19746
ret.set_string(this.runtime.isDomFree ? "" : navigator.userAgent);
19747
};
19748
Exps.prototype.QueryString = function (ret)
19749
{
19750
ret.set_string(this.runtime.isDomFree ? "" : window.location.search);
19751
};
19752
Exps.prototype.QueryParam = function (ret, paramname)
19753
{
19754
if (this.runtime.isDomFree)
19755
{
19756
ret.set_string("");
19757
return;
19758
}
19759
var match = RegExp('[?&]' + paramname + '=([^&]*)').exec(window.location.search);
19760
if (match)
19761
ret.set_string(decodeURIComponent(match[1].replace(/\+/g, ' ')));
19762
else
19763
ret.set_string("");
19764
};
19765
Exps.prototype.Bandwidth = function (ret)
19766
{
19767
var connection = navigator["connection"] || navigator["mozConnection"] || navigator["webkitConnection"];
19768
if (!connection)
19769
ret.set_float(Number.POSITIVE_INFINITY);
19770
else
19771
{
19772
if (typeof connection["bandwidth"] !== "undefined")
19773
ret.set_float(connection["bandwidth"]);
19774
else if (typeof connection["downlinkMax"] !== "undefined")
19775
ret.set_float(connection["downlinkMax"]);
19776
else
19777
ret.set_float(Number.POSITIVE_INFINITY);
19778
}
19779
};
19780
Exps.prototype.ConnectionType = function (ret)
19781
{
19782
var connection = navigator["connection"] || navigator["mozConnection"] || navigator["webkitConnection"];
19783
if (!connection)
19784
ret.set_string("unknown");
19785
else
19786
{
19787
ret.set_string(connection["type"] || "unknown");
19788
}
19789
};
19790
Exps.prototype.BatteryLevel = function (ret)
19791
{
19792
var battery = navigator["battery"] || navigator["mozBattery"] || navigator["webkitBattery"];
19793
if (battery)
19794
{
19795
ret.set_float(battery["level"]);
19796
}
19797
else
19798
{
19799
maybeLoadBatteryManager();
19800
if (batteryManager)
19801
{
19802
ret.set_float(batteryManager["level"]);
19803
}
19804
else
19805
{
19806
ret.set_float(1); // not supported/unknown: assume charged
19807
}
19808
}
19809
};
19810
Exps.prototype.BatteryTimeLeft = function (ret)
19811
{
19812
var battery = navigator["battery"] || navigator["mozBattery"] || navigator["webkitBattery"];
19813
if (battery)
19814
{
19815
ret.set_float(battery["dischargingTime"]);
19816
}
19817
else
19818
{
19819
maybeLoadBatteryManager();
19820
if (batteryManager)
19821
{
19822
ret.set_float(batteryManager["dischargingTime"]);
19823
}
19824
else
19825
{
19826
ret.set_float(Number.POSITIVE_INFINITY); // not supported/unknown: assume infinite time left
19827
}
19828
}
19829
};
19830
Exps.prototype.ExecJS = function (ret, js_)
19831
{
19832
if (!eval)
19833
{
19834
ret.set_any(0);
19835
return;
19836
}
19837
var result = 0;
19838
try {
19839
result = eval(js_);
19840
}
19841
catch (e)
19842
{
19843
if (console && console.error)
19844
console.error("Error executing Javascript: ", e);
19845
}
19846
if (typeof result === "number")
19847
ret.set_any(result);
19848
else if (typeof result === "string")
19849
ret.set_any(result);
19850
else if (typeof result === "boolean")
19851
ret.set_any(result ? 1 : 0);
19852
else
19853
ret.set_any(0);
19854
};
19855
Exps.prototype.ScreenWidth = function (ret)
19856
{
19857
ret.set_int(screen.width);
19858
};
19859
Exps.prototype.ScreenHeight = function (ret)
19860
{
19861
ret.set_int(screen.height);
19862
};
19863
Exps.prototype.DevicePixelRatio = function (ret)
19864
{
19865
ret.set_float(this.runtime.devicePixelRatio);
19866
};
19867
Exps.prototype.WindowInnerWidth = function (ret)
19868
{
19869
ret.set_int(window.innerWidth);
19870
};
19871
Exps.prototype.WindowInnerHeight = function (ret)
19872
{
19873
ret.set_int(window.innerHeight);
19874
};
19875
Exps.prototype.WindowOuterWidth = function (ret)
19876
{
19877
ret.set_int(window.outerWidth);
19878
};
19879
Exps.prototype.WindowOuterHeight = function (ret)
19880
{
19881
ret.set_int(window.outerHeight);
19882
};
19883
pluginProto.exps = new Exps();
19884
}());
19885
;
19886
;
19887
cr.plugins_.Dictionary = function(runtime)
19888
{
19889
this.runtime = runtime;
19890
};
19891
(function ()
19892
{
19893
var pluginProto = cr.plugins_.Dictionary.prototype;
19894
pluginProto.Type = function(plugin)
19895
{
19896
this.plugin = plugin;
19897
this.runtime = plugin.runtime;
19898
};
19899
var typeProto = pluginProto.Type.prototype;
19900
typeProto.onCreate = function()
19901
{
19902
};
19903
pluginProto.Instance = function(type)
19904
{
19905
this.type = type;
19906
this.runtime = type.runtime;
19907
};
19908
var instanceProto = pluginProto.Instance.prototype;
19909
instanceProto.onCreate = function()
19910
{
19911
this.dictionary = {};
19912
this.cur_key = ""; // current key in for-each loop
19913
this.key_count = 0;
19914
};
19915
instanceProto.saveToJSON = function ()
19916
{
19917
return this.dictionary;
19918
};
19919
instanceProto.loadFromJSON = function (o)
19920
{
19921
this.dictionary = o;
19922
this.key_count = 0;
19923
for (var p in this.dictionary)
19924
{
19925
if (this.dictionary.hasOwnProperty(p))
19926
this.key_count++;
19927
}
19928
};
19929
function Cnds() {};
19930
Cnds.prototype.CompareValue = function (key_, cmp_, value_)
19931
{
19932
return cr.do_cmp(this.dictionary[key_], cmp_, value_);
19933
};
19934
Cnds.prototype.ForEachKey = function ()
19935
{
19936
var current_event = this.runtime.getCurrentEventStack().current_event;
19937
for (var p in this.dictionary)
19938
{
19939
if (this.dictionary.hasOwnProperty(p))
19940
{
19941
this.cur_key = p;
19942
this.runtime.pushCopySol(current_event.solModifiers);
19943
current_event.retrigger();
19944
this.runtime.popSol(current_event.solModifiers);
19945
}
19946
}
19947
this.cur_key = "";
19948
return false;
19949
};
19950
Cnds.prototype.CompareCurrentValue = function (cmp_, value_)
19951
{
19952
return cr.do_cmp(this.dictionary[this.cur_key], cmp_, value_);
19953
};
19954
Cnds.prototype.HasKey = function (key_)
19955
{
19956
return this.dictionary.hasOwnProperty(key_);
19957
};
19958
Cnds.prototype.IsEmpty = function ()
19959
{
19960
return this.key_count === 0;
19961
};
19962
pluginProto.cnds = new Cnds();
19963
function Acts() {};
19964
Acts.prototype.AddKey = function (key_, value_)
19965
{
19966
if (!this.dictionary.hasOwnProperty(key_))
19967
this.key_count++;
19968
this.dictionary[key_] = value_;
19969
};
19970
Acts.prototype.SetKey = function (key_, value_)
19971
{
19972
if (this.dictionary.hasOwnProperty(key_))
19973
this.dictionary[key_] = value_;
19974
};
19975
Acts.prototype.DeleteKey = function (key_)
19976
{
19977
if (this.dictionary.hasOwnProperty(key_))
19978
{
19979
delete this.dictionary[key_];
19980
this.key_count--;
19981
}
19982
};
19983
Acts.prototype.Clear = function ()
19984
{
19985
cr.wipe(this.dictionary); // avoid garbaging
19986
this.key_count = 0;
19987
};
19988
Acts.prototype.JSONLoad = function (json_)
19989
{
19990
var o;
19991
try {
19992
o = JSON.parse(json_);
19993
}
19994
catch(e) { return; }
19995
if (!o["c2dictionary"]) // presumably not a c2dictionary object
19996
return;
19997
this.dictionary = o["data"];
19998
this.key_count = 0;
19999
for (var p in this.dictionary)
20000
{
20001
if (this.dictionary.hasOwnProperty(p))
20002
this.key_count++;
20003
}
20004
};
20005
Acts.prototype.JSONDownload = function (filename)
20006
{
20007
var a = document.createElement("a");
20008
if (typeof a.download === "undefined")
20009
{
20010
var str = 'data:text/html,' + encodeURIComponent("<p><a download='data.json' href=\"data:application/json,"
20011
+ encodeURIComponent(JSON.stringify({
20012
"c2dictionary": true,
20013
"data": this.dictionary
20014
}))
20015
+ "\">Download link</a></p>");
20016
window.open(str);
20017
}
20018
else
20019
{
20020
var body = document.getElementsByTagName("body")[0];
20021
a.textContent = filename;
20022
a.href = "data:application/json," + encodeURIComponent(JSON.stringify({
20023
"c2dictionary": true,
20024
"data": this.dictionary
20025
}));
20026
a.download = filename;
20027
body.appendChild(a);
20028
var clickEvent = document.createEvent("MouseEvent");
20029
clickEvent.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
20030
a.dispatchEvent(clickEvent);
20031
body.removeChild(a);
20032
}
20033
};
20034
pluginProto.acts = new Acts();
20035
function Exps() {};
20036
Exps.prototype.Get = function (ret, key_)
20037
{
20038
if (this.dictionary.hasOwnProperty(key_))
20039
ret.set_any(this.dictionary[key_]);
20040
else
20041
ret.set_int(0);
20042
};
20043
Exps.prototype.KeyCount = function (ret)
20044
{
20045
ret.set_int(this.key_count);
20046
};
20047
Exps.prototype.CurrentKey = function (ret)
20048
{
20049
ret.set_string(this.cur_key);
20050
};
20051
Exps.prototype.CurrentValue = function (ret)
20052
{
20053
if (this.dictionary.hasOwnProperty(this.cur_key))
20054
ret.set_any(this.dictionary[this.cur_key]);
20055
else
20056
ret.set_int(0);
20057
};
20058
Exps.prototype.AsJSON = function (ret)
20059
{
20060
ret.set_string(JSON.stringify({
20061
"c2dictionary": true,
20062
"data": this.dictionary
20063
}));
20064
};
20065
pluginProto.exps = new Exps();
20066
}());
20067
;
20068
;
20069
cr.plugins_.Function = function(runtime)
20070
{
20071
this.runtime = runtime;
20072
};
20073
(function ()
20074
{
20075
var pluginProto = cr.plugins_.Function.prototype;
20076
pluginProto.Type = function(plugin)
20077
{
20078
this.plugin = plugin;
20079
this.runtime = plugin.runtime;
20080
};
20081
var typeProto = pluginProto.Type.prototype;
20082
typeProto.onCreate = function()
20083
{
20084
};
20085
pluginProto.Instance = function(type)
20086
{
20087
this.type = type;
20088
this.runtime = type.runtime;
20089
};
20090
var instanceProto = pluginProto.Instance.prototype;
20091
var funcStack = [];
20092
var funcStackPtr = -1;
20093
var isInPreview = false; // set in onCreate
20094
function FuncStackEntry()
20095
{
20096
this.name = "";
20097
this.retVal = 0;
20098
this.params = [];
20099
};
20100
function pushFuncStack()
20101
{
20102
funcStackPtr++;
20103
if (funcStackPtr === funcStack.length)
20104
funcStack.push(new FuncStackEntry());
20105
return funcStack[funcStackPtr];
20106
};
20107
function getCurrentFuncStack()
20108
{
20109
if (funcStackPtr < 0)
20110
return null;
20111
return funcStack[funcStackPtr];
20112
};
20113
function getOneAboveFuncStack()
20114
{
20115
if (!funcStack.length)
20116
return null;
20117
var i = funcStackPtr + 1;
20118
if (i >= funcStack.length)
20119
i = funcStack.length - 1;
20120
return funcStack[i];
20121
};
20122
function popFuncStack()
20123
{
20124
;
20125
funcStackPtr--;
20126
};
20127
instanceProto.onCreate = function()
20128
{
20129
isInPreview = (typeof cr_is_preview !== "undefined");
20130
var self = this;
20131
window["c2_callFunction"] = function (name_, params_)
20132
{
20133
var i, len, v;
20134
var fs = pushFuncStack();
20135
fs.name = name_.toLowerCase();
20136
fs.retVal = 0;
20137
if (params_)
20138
{
20139
fs.params.length = params_.length;
20140
for (i = 0, len = params_.length; i < len; ++i)
20141
{
20142
v = params_[i];
20143
if (typeof v === "number" || typeof v === "string")
20144
fs.params[i] = v;
20145
else if (typeof v === "boolean")
20146
fs.params[i] = (v ? 1 : 0);
20147
else
20148
fs.params[i] = 0;
20149
}
20150
}
20151
else
20152
{
20153
cr.clearArray(fs.params);
20154
}
20155
self.runtime.trigger(cr.plugins_.Function.prototype.cnds.OnFunction, self, fs.name);
20156
popFuncStack();
20157
return fs.retVal;
20158
};
20159
};
20160
function Cnds() {};
20161
Cnds.prototype.OnFunction = function (name_)
20162
{
20163
var fs = getCurrentFuncStack();
20164
if (!fs)
20165
return false;
20166
return cr.equals_nocase(name_, fs.name);
20167
};
20168
Cnds.prototype.CompareParam = function (index_, cmp_, value_)
20169
{
20170
var fs = getCurrentFuncStack();
20171
if (!fs)
20172
return false;
20173
index_ = cr.floor(index_);
20174
if (index_ < 0 || index_ >= fs.params.length)
20175
return false;
20176
return cr.do_cmp(fs.params[index_], cmp_, value_);
20177
};
20178
pluginProto.cnds = new Cnds();
20179
function Acts() {};
20180
Acts.prototype.CallFunction = function (name_, params_)
20181
{
20182
var fs = pushFuncStack();
20183
fs.name = name_.toLowerCase();
20184
fs.retVal = 0;
20185
cr.shallowAssignArray(fs.params, params_);
20186
var ran = this.runtime.trigger(cr.plugins_.Function.prototype.cnds.OnFunction, this, fs.name);
20187
if (isInPreview && !ran)
20188
{
20189
;
20190
}
20191
popFuncStack();
20192
};
20193
Acts.prototype.SetReturnValue = function (value_)
20194
{
20195
var fs = getCurrentFuncStack();
20196
if (fs)
20197
fs.retVal = value_;
20198
else
20199
;
20200
};
20201
Acts.prototype.CallExpression = function (unused)
20202
{
20203
};
20204
pluginProto.acts = new Acts();
20205
function Exps() {};
20206
Exps.prototype.ReturnValue = function (ret)
20207
{
20208
var fs = getOneAboveFuncStack();
20209
if (fs)
20210
ret.set_any(fs.retVal);
20211
else
20212
ret.set_int(0);
20213
};
20214
Exps.prototype.ParamCount = function (ret)
20215
{
20216
var fs = getCurrentFuncStack();
20217
if (fs)
20218
ret.set_int(fs.params.length);
20219
else
20220
{
20221
;
20222
ret.set_int(0);
20223
}
20224
};
20225
Exps.prototype.Param = function (ret, index_)
20226
{
20227
index_ = cr.floor(index_);
20228
var fs = getCurrentFuncStack();
20229
if (fs)
20230
{
20231
if (index_ >= 0 && index_ < fs.params.length)
20232
{
20233
ret.set_any(fs.params[index_]);
20234
}
20235
else
20236
{
20237
;
20238
ret.set_int(0);
20239
}
20240
}
20241
else
20242
{
20243
;
20244
ret.set_int(0);
20245
}
20246
};
20247
Exps.prototype.Call = function (ret, name_)
20248
{
20249
var fs = pushFuncStack();
20250
fs.name = name_.toLowerCase();
20251
fs.retVal = 0;
20252
cr.clearArray(fs.params);
20253
var i, len;
20254
for (i = 2, len = arguments.length; i < len; i++)
20255
fs.params.push(arguments[i]);
20256
var ran = this.runtime.trigger(cr.plugins_.Function.prototype.cnds.OnFunction, this, fs.name);
20257
if (isInPreview && !ran)
20258
{
20259
;
20260
}
20261
popFuncStack();
20262
ret.set_any(fs.retVal);
20263
};
20264
pluginProto.exps = new Exps();
20265
}());
20266
;
20267
;
20268
cr.plugins_.GD_SDK = function(runtime) {
20269
this.runtime = runtime;
20270
};
20271
(function() {
20272
var pluginProto = cr.plugins_.GD_SDK.prototype;
20273
pluginProto.Type = function(plugin) {
20274
this.plugin = plugin;
20275
this.runtime = plugin.runtime;
20276
};
20277
var typeProto = pluginProto.Type.prototype;
20278
typeProto.onCreate = function() {};
20279
pluginProto.Instance = function(type) {
20280
this.type = type;
20281
this.runtime = type.runtime;
20282
window["gdsdk"] = {};
20283
window["GD_OPTIONS"] = {};
20284
};
20285
var instanceProto = pluginProto.Instance.prototype;
20286
var isSupported = false;
20287
instanceProto.onCreate = function() {
20288
if (!window["gdsdk"] && !window["GD_OPTIONS"]) {
20289
cr.logexport(
20290
"[Construct 2] Gamedistribution.com SDK is required to show advertisements within Cordova; other platforms are not supported."
20291
);
20292
return;
20293
}
20294
isSupported = true;
20295
this.gdsdk = window["gdsdk"];
20296
var self = this;
20297
this.gdsdk["onInit"] = function() {
20298
cr.logexport("Gamedistribution.com SDK: onInit");
20299
self.isShowingBannerAd = false;
20300
self.runtime.trigger(cr.plugins_.GD_SDK.prototype.cnds.onInit, self);
20301
};
20302
this.gdsdk["onError"] = function() {
20303
cr.logexport("Gamedistribution.com SDK: onError");
20304
self.isShowingBannerAd = true;
20305
self.runtime.trigger(cr.plugins_.GD_SDK.prototype.cnds.onError, self);
20306
};
20307
this.gdsdk["onResumeGame"] = function() {
20308
cr.logexport("Gamedistribution.com SDK: onResume");
20309
self.isShowingBannerAd = false;
20310
self.runtime.trigger(
20311
cr.plugins_.GD_SDK.prototype.cnds.onResumeGame,
20312
self
20313
);
20314
};
20315
this.gdsdk["onPauseGame"] = function() {
20316
cr.logexport("Gamedistribution.com SDK: onPauseGame");
20317
self.isShowingBannerAd = true;
20318
self.runtime.trigger(cr.plugins_.GD_SDK.prototype.cnds.onPauseGame, self);
20319
};
20320
this.gdsdk["onPreloadedAd"] = function() {
20321
cr.logexport("Gamedistribution.com SDK: onPreloadedAd");
20322
self.isShowingBannerAd = true;
20323
self.runtime.trigger(
20324
cr.plugins_.GD_SDK.prototype.cnds.onPreloadedAd,
20325
self
20326
);
20327
};
20328
this.gdsdk["InitAds"] = function() {
20329
window["GD_OPTIONS"] = {
20330
gameId: self.properties[0],
20331
advertisementSettings: {
20332
autoplay: false
20333
},
20334
onEvent: function(event) {
20335
switch (event.name) {
20336
case "SDK_GAME_START":
20337
self.gdsdk["onResumeGame"]();
20338
break;
20339
case "SDK_GAME_PAUSE":
20340
self.gdsdk["onPauseGame"]();
20341
break;
20342
case "SDK_READY":
20343
self.gdsdk["onInit"]();
20344
break;
20345
case "SDK_ERROR":
20346
self.gdsdk["onError"]();
20347
break;
20348
}
20349
}
20350
};
20351
(function(d, s, id) {
20352
var js,
20353
fjs = d.getElementsByTagName(s)[0];
20354
if (d.getElementById(id)) return;
20355
js = d.createElement(s);
20356
js.id = id;
20357
js.src = "";
20358
fjs.parentNode.insertBefore(js, fjs);
20359
})(document, "script", "gamedistribution-jssdk");
20360
};
20361
};
20362
function Cnds() {}
20363
Cnds.prototype.IsShowingBanner = function() {
20364
return this.isShowingBannerAd;
20365
};
20366
Cnds.prototype.onInit = function() {
20367
return true;
20368
};
20369
Cnds.prototype.onError = function(data) {
20370
return true;
20371
};
20372
Cnds.prototype.onResumeGame = function(data) {
20373
return true;
20374
};
20375
Cnds.prototype.onPauseGame = function(data) {
20376
return true;
20377
};
20378
Cnds.prototype.onPreloadedAd = function(data) {
20379
return true;
20380
};
20381
pluginProto.cnds = new Cnds();
20382
function Acts() {}
20383
Acts.prototype.ShowAd = function() {
20384
if (!isSupported) return;
20385
if (typeof window["gdsdk"]["showAd"] === "undefined") {
20386
cr.logexport(
20387
"Gamedistribution.com SDK is not loaded or an ad blocker is present."
20388
);
20389
this.gdsdk["onResumeGame"]();
20390
return;
20391
}
20392
window["gdsdk"]["showAd"]();
20393
cr.logexport("ShowAd");
20394
this.isShowingBannerAd = true;
20395
};
20396
Acts.prototype.ShowRewardedAd = function() {
20397
if (!isSupported) return;
20398
if (typeof window["gdsdk"]["showAd"] === "undefined") {
20399
cr.logexport(
20400
"Gamedistribution.com SDK is not loaded or an ad blocker is present."
20401
);
20402
this.gdsdk["onResumeGame"]();
20403
return;
20404
}
20405
window["gdsdk"]["showAd"]("rewarded");
20406
cr.logexport("ShowRewardedAd");
20407
this.isShowingBannerAd = true;
20408
};
20409
Acts.prototype.PreloadRewardedAd = function() {
20410
if (!isSupported) return;
20411
if (typeof window["gdsdk"]["preloadAd"] === "undefined") {
20412
cr.logexport(
20413
"Gamedistribution.com SDK is not loaded or an ad blocker is present."
20414
);
20415
this.gdsdk["onResumeGame"]();
20416
return;
20417
}
20418
window["gdsdk"]
20419
["preloadAd"]("rewarded")
20420
.then(() => {
20421
this.gdsdk["onPreloadedAd"]();
20422
})
20423
.catch(error => {
20424
this.gdsdk["onResumeGame"]();
20425
});
20426
cr.logexport("PreloadRewardedAd");
20427
this.isShowingBannerAd = false;
20428
};
20429
Acts.prototype.PlayLog = function() {
20430
if (!isSupported) return;
20431
};
20432
Acts.prototype.CustomLog = function() {
20433
if (!isSupported) return;
20434
};
20435
Acts.prototype.InitAds = function() {
20436
if (!isSupported) return;
20437
this.gdsdk["InitAds"]();
20438
};
20439
pluginProto.acts = new Acts();
20440
function Exps() {}
20441
pluginProto.exps = new Exps();
20442
})();
20443
;
20444
;
20445
cr.plugins_.GoogleAnalytics_ST = function(runtime)
20446
{
20447
this.runtime = runtime;
20448
};
20449
(function ()
20450
{
20451
var pluginProto = cr.plugins_.GoogleAnalytics_ST.prototype;
20452
pluginProto.Type = function(plugin)
20453
{
20454
this.plugin = plugin;
20455
this.runtime = plugin.runtime;
20456
};
20457
var typeProto = pluginProto.Type.prototype;
20458
typeProto.onCreate = function()
20459
{
20460
if( !this.runtime.isCocoonJs )
20461
return;
20462
};
20463
pluginProto.Instance = function(type)
20464
{
20465
this.type = type;
20466
this.runtime = type.runtime;
20467
};
20468
var instanceProto = pluginProto.Instance.prototype;
20469
instanceProto.onCreate = function()
20470
{
20471
this.timingEvents = {};
20472
if( this.properties[0] == "" || this.properties[0] == "0" )
20473
alert( "Please enter your Google Analytics Tracking ID in Google Analytic Object's properties for Google Analytics to work!" );
20474
ga( 'create', this.properties[0], 'auto' );
20475
ga( 'send', 'pageview' );
20476
};
20477
instanceProto.onDestroy = function ()
20478
{
20479
};
20480
instanceProto.saveToJSON = function ()
20481
{
20482
return {
20483
};
20484
};
20485
instanceProto.loadFromJSON = function (o)
20486
{
20487
};
20488
instanceProto.draw = function(ctx)
20489
{
20490
};
20491
instanceProto.drawGL = function (glw)
20492
{
20493
};
20494
function Cnds() {};
20495
pluginProto.cnds = new Cnds();
20496
function Acts() {};
20497
Acts.prototype.TrackEvent = function(category,action)
20498
{
20499
ga('send', 'event', category, action);
20500
}
20501
Acts.prototype.TrackEventEx = function(category,action,label,value)
20502
{
20503
ga('send', 'event', category, action, label, value);
20504
}
20505
Acts.prototype.TrackTimeStart = function(category,name)
20506
{
20507
var curTime = (new Date()).getTime();
20508
var prop = "cat___" + category + "___name___" + name;
20509
if( this.timingEvents.hasOwnProperty( prop ) )
20510
{
20511
ga('send', 'timing', category, name, curTime - this.timingEvents[ prop ] );
20512
}
20513
this.timingEvents[ prop ] = curTime;
20514
}
20515
Acts.prototype.TrackTimeStop = function(category,name)
20516
{
20517
var curTime = (new Date()).getTime();
20518
var prop = "cat___" + category + "___name___" + name;
20519
if( this.timingEvents.hasOwnProperty( prop ) )
20520
{
20521
ga('send', 'timing', category, name, curTime - this.timingEvents[ prop ] );
20522
delete this.timingEvents[ prop ];
20523
}
20524
else
20525
{
20526
console.log( "Google Analytics Plugin: time tracking for " + prop + " was not started yet is now attempted to be stopped!" );
20527
}
20528
}
20529
pluginProto.acts = new Acts();
20530
function Exps() {};
20531
pluginProto.exps = new Exps();
20532
}());
20533
;
20534
;
20535
cr.plugins_.Keyboard = function(runtime)
20536
{
20537
this.runtime = runtime;
20538
};
20539
(function ()
20540
{
20541
var pluginProto = cr.plugins_.Keyboard.prototype;
20542
pluginProto.Type = function(plugin)
20543
{
20544
this.plugin = plugin;
20545
this.runtime = plugin.runtime;
20546
};
20547
var typeProto = pluginProto.Type.prototype;
20548
typeProto.onCreate = function()
20549
{
20550
};
20551
pluginProto.Instance = function(type)
20552
{
20553
this.type = type;
20554
this.runtime = type.runtime;
20555
this.keyMap = new Array(256); // stores key up/down state
20556
this.usedKeys = new Array(256);
20557
this.triggerKey = 0;
20558
};
20559
var instanceProto = pluginProto.Instance.prototype;
20560
instanceProto.onCreate = function()
20561
{
20562
var self = this;
20563
if (!this.runtime.isDomFree)
20564
{
20565
jQuery(document).keydown(
20566
function(info) {
20567
self.onKeyDown(info);
20568
}
20569
);
20570
jQuery(document).keyup(
20571
function(info) {
20572
self.onKeyUp(info);
20573
}
20574
);
20575
}
20576
};
20577
var keysToBlockWhenFramed = [32, 33, 34, 35, 36, 37, 38, 39, 40, 44];
20578
instanceProto.onKeyDown = function (info)
20579
{
20580
var alreadyPreventedDefault = false;
20581
if (window != window.top && keysToBlockWhenFramed.indexOf(info.which) > -1)
20582
{
20583
info.preventDefault();
20584
alreadyPreventedDefault = true;
20585
info.stopPropagation();
20586
}
20587
if (this.keyMap[info.which])
20588
{
20589
if (this.usedKeys[info.which] && !alreadyPreventedDefault)
20590
info.preventDefault();
20591
return;
20592
}
20593
this.keyMap[info.which] = true;
20594
this.triggerKey = info.which;
20595
this.runtime.isInUserInputEvent = true;
20596
this.runtime.trigger(cr.plugins_.Keyboard.prototype.cnds.OnAnyKey, this);
20597
var eventRan = this.runtime.trigger(cr.plugins_.Keyboard.prototype.cnds.OnKey, this);
20598
var eventRan2 = this.runtime.trigger(cr.plugins_.Keyboard.prototype.cnds.OnKeyCode, this);
20599
this.runtime.isInUserInputEvent = false;
20600
if (eventRan || eventRan2)
20601
{
20602
this.usedKeys[info.which] = true;
20603
if (!alreadyPreventedDefault)
20604
info.preventDefault();
20605
}
20606
};
20607
instanceProto.onKeyUp = function (info)
20608
{
20609
this.keyMap[info.which] = false;
20610
this.triggerKey = info.which;
20611
this.runtime.isInUserInputEvent = true;
20612
this.runtime.trigger(cr.plugins_.Keyboard.prototype.cnds.OnAnyKeyReleased, this);
20613
var eventRan = this.runtime.trigger(cr.plugins_.Keyboard.prototype.cnds.OnKeyReleased, this);
20614
var eventRan2 = this.runtime.trigger(cr.plugins_.Keyboard.prototype.cnds.OnKeyCodeReleased, this);
20615
this.runtime.isInUserInputEvent = false;
20616
if (eventRan || eventRan2 || this.usedKeys[info.which])
20617
{
20618
this.usedKeys[info.which] = true;
20619
info.preventDefault();
20620
}
20621
};
20622
instanceProto.onWindowBlur = function ()
20623
{
20624
var i;
20625
for (i = 0; i < 256; ++i)
20626
{
20627
if (!this.keyMap[i])
20628
continue; // key already up
20629
this.keyMap[i] = false;
20630
this.triggerKey = i;
20631
this.runtime.trigger(cr.plugins_.Keyboard.prototype.cnds.OnAnyKeyReleased, this);
20632
var eventRan = this.runtime.trigger(cr.plugins_.Keyboard.prototype.cnds.OnKeyReleased, this);
20633
var eventRan2 = this.runtime.trigger(cr.plugins_.Keyboard.prototype.cnds.OnKeyCodeReleased, this);
20634
if (eventRan || eventRan2)
20635
this.usedKeys[i] = true;
20636
}
20637
};
20638
instanceProto.saveToJSON = function ()
20639
{
20640
return { "triggerKey": this.triggerKey };
20641
};
20642
instanceProto.loadFromJSON = function (o)
20643
{
20644
this.triggerKey = o["triggerKey"];
20645
};
20646
function Cnds() {};
20647
Cnds.prototype.IsKeyDown = function(key)
20648
{
20649
return this.keyMap[key];
20650
};
20651
Cnds.prototype.OnKey = function(key)
20652
{
20653
return (key === this.triggerKey);
20654
};
20655
Cnds.prototype.OnAnyKey = function(key)
20656
{
20657
return true;
20658
};
20659
Cnds.prototype.OnAnyKeyReleased = function(key)
20660
{
20661
return true;
20662
};
20663
Cnds.prototype.OnKeyReleased = function(key)
20664
{
20665
return (key === this.triggerKey);
20666
};
20667
Cnds.prototype.IsKeyCodeDown = function(key)
20668
{
20669
key = Math.floor(key);
20670
if (key < 0 || key >= this.keyMap.length)
20671
return false;
20672
return this.keyMap[key];
20673
};
20674
Cnds.prototype.OnKeyCode = function(key)
20675
{
20676
return (key === this.triggerKey);
20677
};
20678
Cnds.prototype.OnKeyCodeReleased = function(key)
20679
{
20680
return (key === this.triggerKey);
20681
};
20682
pluginProto.cnds = new Cnds();
20683
function Acts() {};
20684
pluginProto.acts = new Acts();
20685
function Exps() {};
20686
Exps.prototype.LastKeyCode = function (ret)
20687
{
20688
ret.set_int(this.triggerKey);
20689
};
20690
function fixedStringFromCharCode(kc)
20691
{
20692
kc = Math.floor(kc);
20693
switch (kc) {
20694
case 8: return "backspace";
20695
case 9: return "tab";
20696
case 13: return "enter";
20697
case 16: return "shift";
20698
case 17: return "control";
20699
case 18: return "alt";
20700
case 19: return "pause";
20701
case 20: return "capslock";
20702
case 27: return "esc";
20703
case 33: return "pageup";
20704
case 34: return "pagedown";
20705
case 35: return "end";
20706
case 36: return "home";
20707
case 37: return "←";
20708
case 38: return "↑";
20709
case 39: return "→";
20710
case 40: return "↓";
20711
case 45: return "insert";
20712
case 46: return "del";
20713
case 91: return "left window key";
20714
case 92: return "right window key";
20715
case 93: return "select";
20716
case 96: return "numpad 0";
20717
case 97: return "numpad 1";
20718
case 98: return "numpad 2";
20719
case 99: return "numpad 3";
20720
case 100: return "numpad 4";
20721
case 101: return "numpad 5";
20722
case 102: return "numpad 6";
20723
case 103: return "numpad 7";
20724
case 104: return "numpad 8";
20725
case 105: return "numpad 9";
20726
case 106: return "numpad *";
20727
case 107: return "numpad +";
20728
case 109: return "numpad -";
20729
case 110: return "numpad .";
20730
case 111: return "numpad /";
20731
case 112: return "F1";
20732
case 113: return "F2";
20733
case 114: return "F3";
20734
case 115: return "F4";
20735
case 116: return "F5";
20736
case 117: return "F6";
20737
case 118: return "F7";
20738
case 119: return "F8";
20739
case 120: return "F9";
20740
case 121: return "F10";
20741
case 122: return "F11";
20742
case 123: return "F12";
20743
case 144: return "numlock";
20744
case 145: return "scroll lock";
20745
case 186: return ";";
20746
case 187: return "=";
20747
case 188: return ",";
20748
case 189: return "-";
20749
case 190: return ".";
20750
case 191: return "/";
20751
case 192: return "'";
20752
case 219: return "[";
20753
case 220: return "\\";
20754
case 221: return "]";
20755
case 222: return "#";
20756
case 223: return "`";
20757
default: return String.fromCharCode(kc);
20758
}
20759
};
20760
Exps.prototype.StringFromKeyCode = function (ret, kc)
20761
{
20762
ret.set_string(fixedStringFromCharCode(kc));
20763
};
20764
pluginProto.exps = new Exps();
20765
}());
20766
;
20767
;
20768
cr.plugins_.Mouse = function(runtime)
20769
{
20770
this.runtime = runtime;
20771
};
20772
(function ()
20773
{
20774
var pluginProto = cr.plugins_.Mouse.prototype;
20775
pluginProto.Type = function(plugin)
20776
{
20777
this.plugin = plugin;
20778
this.runtime = plugin.runtime;
20779
};
20780
var typeProto = pluginProto.Type.prototype;
20781
typeProto.onCreate = function()
20782
{
20783
};
20784
pluginProto.Instance = function(type)
20785
{
20786
this.type = type;
20787
this.runtime = type.runtime;
20788
this.buttonMap = new Array(4); // mouse down states
20789
this.mouseXcanvas = 0; // mouse position relative to canvas
20790
this.mouseYcanvas = 0;
20791
this.triggerButton = 0;
20792
this.triggerType = 0;
20793
this.triggerDir = 0;
20794
this.handled = false;
20795
};
20796
var instanceProto = pluginProto.Instance.prototype;
20797
instanceProto.onCreate = function()
20798
{
20799
var self = this;
20800
if (!this.runtime.isDomFree)
20801
{
20802
jQuery(document).mousemove(
20803
function(info) {
20804
self.onMouseMove(info);
20805
}
20806
);
20807
jQuery(document).mousedown(
20808
function(info) {
20809
self.onMouseDown(info);
20810
}
20811
);
20812
jQuery(document).mouseup(
20813
function(info) {
20814
self.onMouseUp(info);
20815
}
20816
);
20817
jQuery(document).dblclick(
20818
function(info) {
20819
self.onDoubleClick(info);
20820
}
20821
);
20822
var wheelevent = function(info) {
20823
self.onWheel(info);
20824
};
20825
document.addEventListener("mousewheel", wheelevent, false);
20826
document.addEventListener("DOMMouseScroll", wheelevent, false);
20827
}
20828
};
20829
var dummyoffset = {left: 0, top: 0};
20830
instanceProto.onMouseMove = function(info)
20831
{
20832
var offset = this.runtime.isDomFree ? dummyoffset : jQuery(this.runtime.canvas).offset();
20833
this.mouseXcanvas = info.pageX - offset.left;
20834
this.mouseYcanvas = info.pageY - offset.top;
20835
};
20836
instanceProto.mouseInGame = function ()
20837
{
20838
if (this.runtime.fullscreen_mode > 0)
20839
return true;
20840
return this.mouseXcanvas >= 0 && this.mouseYcanvas >= 0
20841
&& this.mouseXcanvas < this.runtime.width && this.mouseYcanvas < this.runtime.height;
20842
};
20843
instanceProto.onMouseDown = function(info)
20844
{
20845
if (!this.mouseInGame())
20846
return;
20847
this.buttonMap[info.which] = true;
20848
this.runtime.isInUserInputEvent = true;
20849
this.runtime.trigger(cr.plugins_.Mouse.prototype.cnds.OnAnyClick, this);
20850
this.triggerButton = info.which - 1; // 1-based
20851
this.triggerType = 0; // single click
20852
this.runtime.trigger(cr.plugins_.Mouse.prototype.cnds.OnClick, this);
20853
this.runtime.trigger(cr.plugins_.Mouse.prototype.cnds.OnObjectClicked, this);
20854
this.runtime.isInUserInputEvent = false;
20855
};
20856
instanceProto.onMouseUp = function(info)
20857
{
20858
if (!this.buttonMap[info.which])
20859
return;
20860
if (this.runtime.had_a_click && !this.runtime.isMobile)
20861
info.preventDefault();
20862
this.runtime.had_a_click = true;
20863
this.buttonMap[info.which] = false;
20864
this.runtime.isInUserInputEvent = true;
20865
this.triggerButton = info.which - 1; // 1-based
20866
this.runtime.trigger(cr.plugins_.Mouse.prototype.cnds.OnRelease, this);
20867
this.runtime.isInUserInputEvent = false;
20868
};
20869
instanceProto.onDoubleClick = function(info)
20870
{
20871
if (!this.mouseInGame())
20872
return;
20873
info.preventDefault();
20874
this.runtime.isInUserInputEvent = true;
20875
this.triggerButton = info.which - 1; // 1-based
20876
this.triggerType = 1; // double click
20877
this.runtime.trigger(cr.plugins_.Mouse.prototype.cnds.OnClick, this);
20878
this.runtime.trigger(cr.plugins_.Mouse.prototype.cnds.OnObjectClicked, this);
20879
this.runtime.isInUserInputEvent = false;
20880
};
20881
instanceProto.onWheel = function (info)
20882
{
20883
var delta = info.wheelDelta ? info.wheelDelta : info.detail ? -info.detail : 0;
20884
this.triggerDir = (delta < 0 ? 0 : 1);
20885
this.handled = false;
20886
this.runtime.isInUserInputEvent = true;
20887
this.runtime.trigger(cr.plugins_.Mouse.prototype.cnds.OnWheel, this);
20888
this.runtime.isInUserInputEvent = false;
20889
if (this.handled && cr.isCanvasInputEvent(info))
20890
info.preventDefault();
20891
};
20892
instanceProto.onWindowBlur = function ()
20893
{
20894
var i, len;
20895
for (i = 0, len = this.buttonMap.length; i < len; ++i)
20896
{
20897
if (!this.buttonMap[i])
20898
continue;
20899
this.buttonMap[i] = false;
20900
this.triggerButton = i - 1;
20901
this.runtime.trigger(cr.plugins_.Mouse.prototype.cnds.OnRelease, this);
20902
}
20903
};
20904
function Cnds() {};
20905
Cnds.prototype.OnClick = function (button, type)
20906
{
20907
return button === this.triggerButton && type === this.triggerType;
20908
};
20909
Cnds.prototype.OnAnyClick = function ()
20910
{
20911
return true;
20912
};
20913
Cnds.prototype.IsButtonDown = function (button)
20914
{
20915
return this.buttonMap[button + 1]; // jQuery uses 1-based buttons for some reason
20916
};
20917
Cnds.prototype.OnRelease = function (button)
20918
{
20919
return button === this.triggerButton;
20920
};
20921
Cnds.prototype.IsOverObject = function (obj)
20922
{
20923
var cnd = this.runtime.getCurrentCondition();
20924
var mx = this.mouseXcanvas;
20925
var my = this.mouseYcanvas;
20926
return cr.xor(this.runtime.testAndSelectCanvasPointOverlap(obj, mx, my, cnd.inverted), cnd.inverted);
20927
};
20928
Cnds.prototype.OnObjectClicked = function (button, type, obj)
20929
{
20930
if (button !== this.triggerButton || type !== this.triggerType)
20931
return false; // wrong click type
20932
return this.runtime.testAndSelectCanvasPointOverlap(obj, this.mouseXcanvas, this.mouseYcanvas, false);
20933
};
20934
Cnds.prototype.OnWheel = function (dir)
20935
{
20936
this.handled = true;
20937
return dir === this.triggerDir;
20938
};
20939
pluginProto.cnds = new Cnds();
20940
function Acts() {};
20941
var lastSetCursor = null;
20942
Acts.prototype.SetCursor = function (c)
20943
{
20944
if (this.runtime.isDomFree)
20945
return;
20946
var cursor_style = ["auto", "pointer", "text", "crosshair", "move", "help", "wait", "none"][c];
20947
if (lastSetCursor === cursor_style)
20948
return; // redundant
20949
lastSetCursor = cursor_style;
20950
document.body.style.cursor = cursor_style;
20951
};
20952
Acts.prototype.SetCursorSprite = function (obj)
20953
{
20954
if (this.runtime.isDomFree || this.runtime.isMobile || !obj)
20955
return;
20956
var inst = obj.getFirstPicked();
20957
if (!inst || !inst.curFrame)
20958
return;
20959
var frame = inst.curFrame;
20960
if (lastSetCursor === frame)
20961
return; // already set this frame
20962
lastSetCursor = frame;
20963
var datauri = frame.getDataUri();
20964
var cursor_style = "url(" + datauri + ") " + Math.round(frame.hotspotX * frame.width) + " " + Math.round(frame.hotspotY * frame.height) + ", auto";
20965
document.body.style.cursor = "";
20966
document.body.style.cursor = cursor_style;
20967
};
20968
pluginProto.acts = new Acts();
20969
function Exps() {};
20970
Exps.prototype.X = function (ret, layerparam)
20971
{
20972
var layer, oldScale, oldZoomRate, oldParallaxX, oldAngle;
20973
if (cr.is_undefined(layerparam))
20974
{
20975
layer = this.runtime.getLayerByNumber(0);
20976
oldScale = layer.scale;
20977
oldZoomRate = layer.zoomRate;
20978
oldParallaxX = layer.parallaxX;
20979
oldAngle = layer.angle;
20980
layer.scale = 1;
20981
layer.zoomRate = 1.0;
20982
layer.parallaxX = 1.0;
20983
layer.angle = 0;
20984
ret.set_float(layer.canvasToLayer(this.mouseXcanvas, this.mouseYcanvas, true));
20985
layer.scale = oldScale;
20986
layer.zoomRate = oldZoomRate;
20987
layer.parallaxX = oldParallaxX;
20988
layer.angle = oldAngle;
20989
}
20990
else
20991
{
20992
if (cr.is_number(layerparam))
20993
layer = this.runtime.getLayerByNumber(layerparam);
20994
else
20995
layer = this.runtime.getLayerByName(layerparam);
20996
if (layer)
20997
ret.set_float(layer.canvasToLayer(this.mouseXcanvas, this.mouseYcanvas, true));
20998
else
20999
ret.set_float(0);
21000
}
21001
};
21002
Exps.prototype.Y = function (ret, layerparam)
21003
{
21004
var layer, oldScale, oldZoomRate, oldParallaxY, oldAngle;
21005
if (cr.is_undefined(layerparam))
21006
{
21007
layer = this.runtime.getLayerByNumber(0);
21008
oldScale = layer.scale;
21009
oldZoomRate = layer.zoomRate;
21010
oldParallaxY = layer.parallaxY;
21011
oldAngle = layer.angle;
21012
layer.scale = 1;
21013
layer.zoomRate = 1.0;
21014
layer.parallaxY = 1.0;
21015
layer.angle = 0;
21016
ret.set_float(layer.canvasToLayer(this.mouseXcanvas, this.mouseYcanvas, false));
21017
layer.scale = oldScale;
21018
layer.zoomRate = oldZoomRate;
21019
layer.parallaxY = oldParallaxY;
21020
layer.angle = oldAngle;
21021
}
21022
else
21023
{
21024
if (cr.is_number(layerparam))
21025
layer = this.runtime.getLayerByNumber(layerparam);
21026
else
21027
layer = this.runtime.getLayerByName(layerparam);
21028
if (layer)
21029
ret.set_float(layer.canvasToLayer(this.mouseXcanvas, this.mouseYcanvas, false));
21030
else
21031
ret.set_float(0);
21032
}
21033
};
21034
Exps.prototype.AbsoluteX = function (ret)
21035
{
21036
ret.set_float(this.mouseXcanvas);
21037
};
21038
Exps.prototype.AbsoluteY = function (ret)
21039
{
21040
ret.set_float(this.mouseYcanvas);
21041
};
21042
pluginProto.exps = new Exps();
21043
}());
21044
;
21045
;
21046
cr.plugins_.Photon = function(runtime)
21047
{
21048
this.runtime = runtime;
21049
};
21050
(function ()
21051
{
21052
var pluginProto = cr.plugins_.Photon.prototype;
21053
pluginProto.Type = function(plugin)
21054
{
21055
this.plugin = plugin;
21056
this.runtime = plugin.runtime;
21057
};
21058
var typeProto = pluginProto.Type.prototype;
21059
typeProto.onCreate = function()
21060
{
21061
};
21062
pluginProto.Instance = function(type)
21063
{
21064
this.type = type;
21065
this.runtime = type.runtime;
21066
};
21067
var instanceProto = pluginProto.Instance.prototype;
21068
instanceProto.onCreate = function()
21069
{
21070
this.AppId = this.properties[0];
21071
this.AppVersion = this.properties[1];
21072
this.Protocol = ["ws", "wss"][this.properties[2]] == "wss" ? this.Protocol = Photon["ConnectionProtocol"]["Wss"] : Photon["ConnectionProtocol"]["Ws"];
21073
this.Region = ["eu", "us", "asia", "jp", "au", "usw", "sa", "cae", "kr", "in"][this.properties[3]];
21074
this.SelfHosted = this.properties[4] == 1;
21075
this.SelfHostedAddress = this.properties[5];
21076
this.LogLevel = this.properties[6] + Exitgames["Common"]["Logger"]["Level"]["DEBUG"];
21077
Photon["LoadBalancing"]["LoadBalancingClient"].prototype["roomFactory"] = function(name) {
21078
var r = new Photon["LoadBalancing"]["Room"](name);
21079
r["onPropertiesChange"] = function (changedCustomProps, byClient) {
21080
self.changedPropertiesNames = [];
21081
for(var i in changedCustomProps) {
21082
self.changedPropertiesNames.push(i);
21083
}
21084
}
21085
return r;
21086
}
21087
Photon["LoadBalancing"]["LoadBalancingClient"].prototype["actorFactory"] = function(name, actorNr, isLocal) {
21088
var a = new Photon["LoadBalancing"]["Actor"](name, actorNr, isLocal)
21089
a["onPropertiesChange"] = function (changedCustomProps, byClient) {
21090
self.changedPropertiesNames = [];
21091
for(var i in changedCustomProps) {
21092
self.changedPropertiesNames.push(i);
21093
}
21094
}
21095
return a;
21096
}
21097
this.lbc = new Photon["LoadBalancing"]["LoadBalancingClient"](this.Protocol, this.AppId, this.AppVersion);
21098
var self = this;
21099
this.lbc["setLogLevel"](this.LogLevel);
21100
this.lbc["onError"] = function(errorCode, errorMsg) {
21101
self.errorCode = errorCode;
21102
self.errorMsg = errorMsg;
21103
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onError, self);
21104
}
21105
this.lbc["onStateChange"] = function(state) {
21106
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onStateChange, self);
21107
var LBC = Photon["LoadBalancing"]["LoadBalancingClient"];
21108
switch (state) {
21109
case LBC["State"]["JoinedLobby"]:
21110
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onJoinedLobby, self);
21111
break;
21112
default:
21113
break;
21114
}
21115
};
21116
this.lbc["onOperationResponse"] = function (errorCode, errorMsg, code, content) {
21117
if (errorCode) {
21118
switch (code) {
21119
case Photon["LoadBalancing"]["Constants"]["OperationCode"]["JoinRandomGame"]:
21120
switch (errorCode) {
21121
case Photon["LoadBalancing"]["Constants"]["ErrorCode"]["NoRandomMatchFound"]:
21122
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onJoinRandomRoomNoMatchFound, self);
21123
break;
21124
default:
21125
break;
21126
}
21127
break;
21128
default:
21129
self.errorCode = errorCode;
21130
self.errorMsg = errorMsg;
21131
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onError, self);
21132
break;
21133
}
21134
}
21135
};
21136
this.lbc["onEvent"] = function (code, data, actorNr) {
21137
self.eventCode = code;
21138
self.eventData = data;
21139
self.actorNr = actorNr;
21140
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onEvent, self);
21141
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onAnyEvent, self);
21142
}
21143
this.lbc["onRoomList"] = function (rooms){
21144
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onRoomList, self);
21145
}
21146
this.lbc["onRoomListUpdate"] = function (rooms, roomsUpdated, roomsAdded, roomsRemoved) {
21147
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onRoomListUpdate, self);
21148
}
21149
this.lbc["onMyRoomPropertiesChange"] = function () {
21150
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onMyRoomPropertiesChange, self);
21151
}
21152
this.lbc["onActorPropertiesChange"] = function (actor) {
21153
self.actorNr = actor["actorNr"];
21154
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onActorPropertiesChange, self);
21155
}
21156
this.lbc["onJoinRoom"] = function (createdByMe) {
21157
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onJoinRoom, self);
21158
};
21159
this.lbc["onActorJoin"] = function (actor) {
21160
self.actorNr = actor["actorNr"];
21161
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onActorJoin, self);
21162
}
21163
this.lbc["onActorLeave"] = function (actor) {
21164
self.actorNr = actor["actorNr"];
21165
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onActorLeave, self);
21166
}
21167
this.lbc["onActorSuspend"] = function (actor) {
21168
self.actorNr = actor["actorNr"];
21169
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onActorSuspend, self);
21170
}
21171
this.lbc["onWebRpcResult"] = function (errorCode, errorMsg, uriPath, resultCode, data) {
21172
self.errorCode = errorCode;
21173
self.errorMsg = errorMsg;
21174
self.webRpcUriPath = uriPath;
21175
self.webRpcResultCode = resultCode;
21176
self.webRpcData = data;
21177
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onWebRpcResult, self);
21178
}
21179
this.lbc["onFindFriendsResult"] = function (errorCode, errorMsg, friends) {
21180
self.errorCode = errorCode;
21181
self.errorMsg = errorMsg;
21182
self.friends = friends
21183
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onFindFriendsResult, self);
21184
}
21185
this.lbc["onLobbyStats"] = function (errorCode, errorMsg, lobbies) {
21186
self.errorCode = errorCode;
21187
self.errorMsg = errorMsg;
21188
self.lobbyStats = lobbies;
21189
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onLobbyStats, self);
21190
}
21191
this.lbc["onAppStats"] = function (errorCode, errorMsg, stats) {
21192
self.errorCode = errorCode;
21193
self.errorMsg = errorMsg;
21194
self.appStats = stats;
21195
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onAppStats, self);
21196
}
21197
};
21198
instanceProto.onDestroy = function ()
21199
{
21200
};
21201
instanceProto.saveToJSON = function ()
21202
{
21203
return {
21204
};
21205
};
21206
instanceProto.loadFromJSON = function (o)
21207
{
21208
};
21209
instanceProto.draw = function(ctx)
21210
{
21211
};
21212
instanceProto.drawGL = function (glw)
21213
{
21214
};
21215
function Cnds() {};
21216
Cnds.prototype.onError = function() { return true; }
21217
Cnds.prototype.onStateChange = function() { return true; }
21218
Cnds.prototype.onEvent = function(code) { return this.eventCode == code; }
21219
Cnds.prototype.onAnyEvent = function() { return true; }
21220
Cnds.prototype.onRoomList = function() { return true; }
21221
Cnds.prototype.onRoomListUpdate = function() { return true; }
21222
Cnds.prototype.onActorPropertiesChange = function() { return true; }
21223
Cnds.prototype.onMyRoomPropertiesChange = function() { return true; }
21224
Cnds.prototype.onJoinRoom = function() { return true; }
21225
Cnds.prototype.onActorJoin = function() { return true; }
21226
Cnds.prototype.onActorLeave = function() { return true; }
21227
Cnds.prototype.onActorSuspend = function() { return true; }
21228
Cnds.prototype.onWebRpcResult = function() { return true; }
21229
Cnds.prototype.onFindFriendsResult = function() { return true; }
21230
Cnds.prototype.onLobbyStats = function() { return true; }
21231
Cnds.prototype.onAppStats = function() { return true; }
21232
Cnds.prototype.onJoinedLobby = function() { return true; }
21233
Cnds.prototype.onJoinRandomRoomNoMatchFound = function() { return true; }
21234
Cnds.prototype.isConnectedToNameServer = function ()
21235
{
21236
return this.lbc["isConnectedToNameServer"]();
21237
};
21238
Cnds.prototype.isConnectedToMaster = function ()
21239
{
21240
return this.lbc["isConnectedToMaster"]();
21241
};
21242
Cnds.prototype.isInLobby = function ()
21243
{
21244
return this.lbc["isInLobby"]();
21245
};
21246
Cnds.prototype.isJoinedToRoom = function ()
21247
{
21248
return this.lbc["isJoinedToRoom"]();
21249
};
21250
pluginProto.cnds = new Cnds();
21251
function Acts() {};
21252
Acts.prototype.setUserId = function (userId)
21253
{
21254
this.lbc["setUserId"](userId);
21255
}
21256
Acts.prototype.setCustomAuthentication = function (authParameters, authType)
21257
{
21258
this.lbc["setCustomAuthentication"](authParameters, authType);
21259
}
21260
Acts.prototype.setRegion = function (region)
21261
{
21262
this.Region = region;
21263
}
21264
Acts.prototype.setAppId = function (AppId)
21265
{
21266
this.AppId = AppId;
21267
this.lbc = new Photon["LoadBalancing"]["LoadBalancingClient"](this.Protocol, this.AppId, this.AppVersion);
21268
var self = this;
21269
this.lbc["setLogLevel"](this.LogLevel);
21270
this.lbc["onError"] = function(errorCode, errorMsg) {
21271
self.errorCode = errorCode;
21272
self.errorMsg = errorMsg;
21273
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onError, self);
21274
}
21275
this.lbc["onStateChange"] = function(state) {
21276
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onStateChange, self);
21277
var LBC = Photon["LoadBalancing"]["LoadBalancingClient"];
21278
switch (state) {
21279
case LBC["State"]["JoinedLobby"]:
21280
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onJoinedLobby, self);
21281
break;
21282
default:
21283
break;
21284
}
21285
};
21286
this.lbc["onOperationResponse"] = function (errorCode, errorMsg, code, content) {
21287
if (errorCode) {
21288
switch (code) {
21289
case Photon["LoadBalancing"]["Constants"]["OperationCode"]["JoinRandomGame"]:
21290
switch (errorCode) {
21291
case Photon["LoadBalancing"]["Constants"]["ErrorCode"]["NoRandomMatchFound"]:
21292
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onJoinRandomRoomNoMatchFound, self);
21293
break;
21294
default:
21295
break;
21296
}
21297
break;
21298
default:
21299
self.errorCode = errorCode;
21300
self.errorMsg = errorMsg;
21301
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onError, self);
21302
break;
21303
}
21304
}
21305
};
21306
this.lbc["onEvent"] = function (code, data, actorNr) {
21307
self.eventCode = code;
21308
self.eventData = data;
21309
self.actorNr = actorNr;
21310
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onEvent, self);
21311
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onAnyEvent, self);
21312
}
21313
this.lbc["onRoomList"] = function (rooms){
21314
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onRoomList, self);
21315
}
21316
this.lbc["onRoomListUpdate"] = function (rooms, roomsUpdated, roomsAdded, roomsRemoved) {
21317
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onRoomListUpdate, self);
21318
}
21319
this.lbc["onMyRoomPropertiesChange"] = function () {
21320
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onMyRoomPropertiesChange, self);
21321
}
21322
this.lbc["onActorPropertiesChange"] = function (actor) {
21323
self.actorNr = actor["actorNr"];
21324
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onActorPropertiesChange, self);
21325
}
21326
this.lbc["onJoinRoom"] = function (createdByMe) {
21327
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onJoinRoom, self);
21328
};
21329
this.lbc["onActorJoin"] = function (actor) {
21330
self.actorNr = actor["actorNr"];
21331
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onActorJoin, self);
21332
}
21333
this.lbc["onActorLeave"] = function (actor) {
21334
self.actorNr = actor["actorNr"];
21335
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onActorLeave, self);
21336
}
21337
this.lbc["onActorSuspend"] = function (actor) {
21338
self.actorNr = actor["actorNr"];
21339
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onActorSuspend, self);
21340
}
21341
this.lbc["onWebRpcResult"] = function (errorCode, errorMsg, uriPath, resultCode, data) {
21342
self.errorCode = errorCode;
21343
self.errorMsg = errorMsg;
21344
self.webRpcUriPath = uriPath;
21345
self.webRpcResultCode = resultCode;
21346
self.webRpcData = data;
21347
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onWebRpcResult, self);
21348
}
21349
this.lbc["onFindFriendsResult"] = function (errorCode, errorMsg, friends) {
21350
self.errorCode = errorCode;
21351
self.errorMsg = errorMsg;
21352
self.friends = friends
21353
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onFindFriendsResult, self);
21354
}
21355
this.lbc["onLobbyStats"] = function (errorCode, errorMsg, lobbies) {
21356
self.errorCode = errorCode;
21357
self.errorMsg = errorMsg;
21358
self.lobbyStats = lobbies;
21359
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onLobbyStats, self);
21360
}
21361
this.lbc["onAppStats"] = function (errorCode, errorMsg, stats) {
21362
self.errorCode = errorCode;
21363
self.errorMsg = errorMsg;
21364
self.appStats = stats;
21365
self.runtime.trigger(cr.plugins_.Photon.prototype.cnds.onAppStats, self);
21366
}
21367
}
21368
Acts.prototype.connect = function ()
21369
{
21370
if (this.SelfHosted) {
21371
this.lbc["setMasterServerAddress"](this.SelfHostedAddress);
21372
this.lbc["connect"]();
21373
}
21374
else {
21375
if (this.Region)
21376
this.lbc["connectToRegionMaster"](this.Region);
21377
else
21378
this.lbc["connectToNameServer"]();
21379
}
21380
};
21381
Acts.prototype.createRoom = function (name, lobbyName, lobbyType)
21382
{
21383
if (lobbyType == 1) {
21384
lobbyType = Photon["LoadBalancing"]["Constants"]["LobbyType"]["SqlLobby"] // 2
21385
}
21386
var options = {
21387
"lobbyName": lobbyName,
21388
"lobbyType": lobbyType
21389
}
21390
this.lbc["createRoomFromMy"](name, options);
21391
};
21392
Acts.prototype.joinRoom = function (name, rejoinActorNr, createIfNotExists, lobbyName, lobbyType)
21393
{
21394
if (lobbyType == 1) {
21395
lobbyType = Photon["LoadBalancing"]["Constants"]["LobbyType"]["SqlLobby"] // 2
21396
}
21397
var joinOptions = {
21398
"joinToken": rejoinActorNr ? "" + rejoinActorNr : "",
21399
"createIfNotExists": createIfNotExists && true,
21400
"lobbyName": lobbyName,
21401
"lobbyType": lobbyType
21402
}
21403
var createOptions = {
21404
"lobbyName": lobbyName,
21405
"lobbyType": lobbyType
21406
}
21407
createOptions = this.lbc["copyCreateOptionsFromMyRoom"](createOptions);
21408
this.lbc["joinRoom"](name, joinOptions, createOptions);
21409
};
21410
Acts.prototype.joinRandomRoom = function (matchMyRoom, matchmakingMode, lobbyName, lobbyType, sqlLobbyFilter)
21411
{
21412
if (lobbyType == 1) {
21413
lobbyType = Photon["LoadBalancing"]["Constants"]["LobbyType"]["SqlLobby"] // 2
21414
}
21415
var options = {
21416
"matchmakingMode": matchmakingMode,
21417
"lobbyName": lobbyName,
21418
"lobbyType": lobbyType,
21419
"sqlLobbyFilter": sqlLobbyFilter
21420
}
21421
if (matchMyRoom) {
21422
options.expectedCustomRoomProperties = this.lbc["myRoom"]()["_customProperties"];
21423
options.expectedMaxPlayers = this.lbc["myRoom"]()["maxPlayers"];
21424
}
21425
this.lbc["joinRandomRoom"](options);
21426
};
21427
Acts.prototype.disconnect = function ()
21428
{
21429
this.lbc["disconnect"]();
21430
};
21431
Acts.prototype.suspendRoom = function ()
21432
{
21433
this.lbc["suspendRoom"]();
21434
};
21435
Acts.prototype.leaveRoom = function ()
21436
{
21437
this.lbc["leaveRoom"]();
21438
};
21439
Acts.prototype.raiseEvent = function (eventCode, data, interestGroup, cache, receivers, targetActors, webForward)
21440
{
21441
var opt = {
21442
"interestGroup": interestGroup,
21443
"cache": cache,
21444
"receivers": receivers,
21445
"webForward": webForward,
21446
};
21447
if(typeof(targetActors) === "string" && targetActors) {
21448
opt["targetActors"] = targetActors.split(",").map(function(x) { return parseInt(x); } )
21449
}
21450
this.lbc["raiseEvent"](eventCode, data, opt);
21451
};
21452
Acts.prototype.changeGroups = function (action, group)
21453
{
21454
switch (action) {
21455
case 0: // Add
21456
this.lbc["changeGroups"](null, [group]);
21457
break;
21458
case 1: // Add all current
21459
this.lbc["changeGroups"](null ,[]);
21460
break;
21461
case 2: // Remove
21462
this.lbc["changeGroups"]([group], null);
21463
break;
21464
case 3: // Remove all
21465
this.lbc["changeGroups"]([], null);
21466
break;
21467
}
21468
};
21469
Acts.prototype.webRpc = function (uriPath, parameters, parametersType)
21470
{
21471
this.lbc["webRpc"](uriPath, parametersType ? JSON.parse(parameters) : parameters);
21472
}
21473
Acts.prototype.findFriends = function (friends)
21474
{
21475
this.lbc["findFriends"](friends.split(","));
21476
}
21477
Acts.prototype.requestLobbyStats = function ()
21478
{
21479
this.lbc["requestLobbyStats"]();
21480
}
21481
Acts.prototype.setMyActorName = function (name)
21482
{
21483
this.lbc["myActor"]()["setName"](name);
21484
};
21485
Acts.prototype.setPropertyOfActorByNr = function (nr, propName, propValue, webForward, checkAndSwap, expectedValue)
21486
{
21487
this.lbc["myRoomActors"]()[nr]["setCustomProperty"](propName, propValue, webForward, checkAndSwap ? expectedValue : undefined);
21488
};
21489
Acts.prototype.setPropertyOfMyRoom = function (propName, propValue, webForward, checkAndSwap, expectedValue)
21490
{
21491
this.lbc["myRoom"]()["setCustomProperty"](propName, propValue, webForward, checkAndSwap ? expectedValue : undefined);
21492
};
21493
Acts.prototype.setPropsListedInLobby = function (propNames)
21494
{
21495
this.lbc["myRoom"]()["setPropsListedInLobby"](propNames.split(","));
21496
};
21497
Acts.prototype.setMyRoomIsVisible = function (isVisisble)
21498
{
21499
this.lbc["myRoom"]()["setIsVisible"](isVisisble ? true : false);
21500
};
21501
Acts.prototype.setMyRoomIsOpen = function (isOpen)
21502
{
21503
this.lbc["myRoom"]()["setIsOpen"](isOpen ? true : false);
21504
};
21505
Acts.prototype.setMyRoomMaxPlayers = function (maxPlayers)
21506
{
21507
this.lbc["myRoom"]()["setMaxPlayers"](maxPlayers);
21508
};
21509
Acts.prototype.setEmptyRoomLiveTime = function (emptyRoomLiveTime)
21510
{
21511
this.lbc["myRoom"]()["setEmptyRoomLiveTime"](emptyRoomLiveTime);
21512
};
21513
Acts.prototype.setSuspendedPlayerLiveTime = function (suspendedPlayerLiveTime)
21514
{
21515
this.lbc["myRoom"]()["setSuspendedPlayerLiveTime"](suspendedPlayerLiveTime);
21516
};
21517
Acts.prototype.setUniqueUserId = function (unique)
21518
{
21519
this.lbc["myRoom"]()["setUniqueUserId"](unique ? true : false);
21520
};
21521
pluginProto.acts = new Acts();
21522
function Exps() {};
21523
Exps.prototype.ErrorCode = function (ret)
21524
{
21525
ret.set_int(this.errorCode || 0);
21526
}
21527
Exps.prototype.ErrorMessage = function (ret)
21528
{
21529
ret.set_string(this.errorMsg || "");
21530
}
21531
Exps.prototype.State = function (ret)
21532
{
21533
ret.set_int(this.lbc["state"]);
21534
};
21535
Exps.prototype.StateString = function (ret)
21536
{
21537
ret.set_string(Photon["LoadBalancing"]["LoadBalancingClient"]["StateToName"](this.lbc["state"]));
21538
};
21539
Exps.prototype.UserId = function (ret)
21540
{
21541
ret.set_string(this.lbc["getUserId"]() || "");
21542
};
21543
Exps.prototype.MyActorNr = function (ret)
21544
{
21545
ret.set_int(this.lbc["myActor"]()["actorNr"]);
21546
};
21547
Exps.prototype.ActorNr = function (ret)
21548
{
21549
ret.set_int(this.actorNr || 0);
21550
}
21551
Exps.prototype.MyRoomName = function (ret)
21552
{
21553
ret.set_string(this.lbc["myRoom"]().name || "");
21554
}
21555
Exps.prototype.EventCode = function (ret)
21556
{
21557
ret.set_int(this.eventCode || 0);
21558
};
21559
Exps.prototype.EventData = function (ret)
21560
{
21561
ret.set_any(this.eventData);
21562
};
21563
Exps.prototype.ActorNr = function (ret)
21564
{
21565
ret.set_int(this.actorNr || 0);
21566
};
21567
Exps.prototype.RoomCount = function (ret)
21568
{
21569
ret.set_int(this.lbc["availableRooms"]().length);
21570
};
21571
Exps.prototype.RoomNameAt = function (ret, i)
21572
{
21573
ret.set_string(this.lbc["availableRooms"]()[i].name || "");
21574
};
21575
Exps.prototype.RoomMaxPlayers = function (ret, name)
21576
{
21577
var r = this.lbc["roomInfosDict"][name];
21578
ret.set_int(r && r["maxPlayers"] || 0);
21579
};
21580
Exps.prototype.RoomIsOpen = function (ret, name)
21581
{
21582
var r = this.lbc["roomInfosDict"][name];
21583
ret.set_int(r && r["isOpen"] ? 1 : 0);
21584
};
21585
Exps.prototype.RoomPlayerCount = function (ret, name)
21586
{
21587
var r = this.lbc["roomInfosDict"][name];
21588
ret.set_int(r && r["playerCount"]);
21589
};
21590
Exps.prototype.RoomProperty = function (ret, name, propName)
21591
{
21592
var r = this.lbc["roomInfosDict"][name];
21593
ret.set_any(r && r["getCustomProperty"](propName));
21594
};
21595
Exps.prototype.PropertyOfMyRoom = function (ret, propName)
21596
{
21597
var r = this.lbc["myRoom"]();
21598
ret.set_any(r && r["getCustomProperty"](propName));
21599
};
21600
Exps.prototype.ActorCount = function (ret)
21601
{
21602
ret.set_int(this.lbc["myRoomActorsArray"]().length);
21603
};
21604
Exps.prototype.ActorNrAt = function (ret, i)
21605
{
21606
var a = this.lbc["myRoomActorsArray"]()[i];
21607
ret.set_int(a && a["actorNr"] || -i);
21608
};
21609
Exps.prototype.ActorNameByNr = function (ret, nr)
21610
{
21611
var a = this.lbc["myRoomActors"]()[nr];
21612
ret.set_string(a && a["name"] || "-- not found acorNr " + nr);
21613
};
21614
Exps.prototype.PropertyOfActorByNr = function (ret, nr, propName)
21615
{
21616
var a = this.lbc["myRoomActors"]()[nr];
21617
ret.set_any(a && a["getCustomProperty"](propName));
21618
};
21619
Exps.prototype.ChangedPropertiesCount = function (ret)
21620
{
21621
ret.set_int(this.changedPropertiesNames && this.changedPropertiesNames.length || 0);
21622
};
21623
Exps.prototype.ChangedPropertyNameAt = function (ret, i)
21624
{
21625
ret.set_any(this.changedPropertiesNames && this.changedPropertiesNames[i]);
21626
};
21627
Exps.prototype.MasterActorNr = function (ret, i)
21628
{
21629
ret.set_int(this.lbc["myRoomMasterActorNr"]());
21630
};
21631
Exps.prototype.WebRpcUriPath = function (ret)
21632
{
21633
ret.set_string(this.webRpcUriPath || "");
21634
};
21635
Exps.prototype.WebRpcResultCode = function (ret)
21636
{
21637
ret.set_int(this.webRpcResultCode || 0);
21638
};
21639
Exps.prototype.WebRpcData = function (ret)
21640
{
21641
ret.set_any(this.webRpcData);
21642
};
21643
Exps.prototype.FriendOnline = function (ret, name)
21644
{
21645
ret.set_int(this.friends && this.friends[name] && this.friends[name].online ? 1 : 0);
21646
};
21647
Exps.prototype.FriendRoom = function (ret, name)
21648
{
21649
ret.set_string(this.friends && this.friends[name] ? this.friends[name].roomId : "");
21650
};
21651
Exps.prototype.LobbyStatsCount = function (ret)
21652
{
21653
ret.set_int(this.lobbyStats ? this.lobbyStats.length : 0);
21654
};
21655
Exps.prototype.LobbyStatsNameAt = function (ret, i)
21656
{
21657
ret.set_string(this.lobbyStats && this.lobbyStats[i] ? this.lobbyStats[i].lobbyName : "");
21658
};
21659
Exps.prototype.LobbyStatsTypeAt = function (ret, i)
21660
{
21661
ret.set_int(this.lobbyStats && this.lobbyStats[i] ? this.lobbyStats[i].lobbyType : 0);
21662
};
21663
Exps.prototype.LobbyStatsPeerCountAt = function (ret, i)
21664
{
21665
ret.set_int(this.lobbyStats && this.lobbyStats[i] ? this.lobbyStats[i].peerCount : 0);
21666
};
21667
Exps.prototype.LobbyStatsGameCountAt = function (ret, i)
21668
{
21669
ret.set_int(this.lobbyStats && this.lobbyStats[i] ? this.lobbyStats[i].gameCount : 0);
21670
};
21671
Exps.prototype.AppStatsPeerCount = function (ret, i)
21672
{
21673
ret.set_int(this.appStats ? this.appStats.peerCount : 0);
21674
};
21675
Exps.prototype.AppStatsMasterPeerCount = function (ret, i)
21676
{
21677
ret.set_int(this.appStats ? this.appStats.masterPeerCount : 0);
21678
};
21679
Exps.prototype.AppStatsGameCount = function (ret, i)
21680
{
21681
ret.set_int(this.appStats ? this.appStats.gameCount : 0);
21682
};
21683
pluginProto.exps = new Exps();
21684
}());
21685
;
21686
;
21687
cr.plugins_.Sprite = function(runtime)
21688
{
21689
this.runtime = runtime;
21690
};
21691
(function ()
21692
{
21693
var pluginProto = cr.plugins_.Sprite.prototype;
21694
pluginProto.Type = function(plugin)
21695
{
21696
this.plugin = plugin;
21697
this.runtime = plugin.runtime;
21698
};
21699
var typeProto = pluginProto.Type.prototype;
21700
function frame_getDataUri()
21701
{
21702
if (this.datauri.length === 0)
21703
{
21704
var tmpcanvas = document.createElement("canvas");
21705
tmpcanvas.width = this.width;
21706
tmpcanvas.height = this.height;
21707
var tmpctx = tmpcanvas.getContext("2d");
21708
if (this.spritesheeted)
21709
{
21710
tmpctx.drawImage(this.texture_img, this.offx, this.offy, this.width, this.height,
21711
0, 0, this.width, this.height);
21712
}
21713
else
21714
{
21715
tmpctx.drawImage(this.texture_img, 0, 0, this.width, this.height);
21716
}
21717
this.datauri = tmpcanvas.toDataURL("image/png");
21718
}
21719
return this.datauri;
21720
};
21721
typeProto.onCreate = function()
21722
{
21723
if (this.is_family)
21724
return;
21725
var i, leni, j, lenj;
21726
var anim, frame, animobj, frameobj, wt, uv;
21727
this.all_frames = [];
21728
this.has_loaded_textures = false;
21729
for (i = 0, leni = this.animations.length; i < leni; i++)
21730
{
21731
anim = this.animations[i];
21732
animobj = {};
21733
animobj.name = anim[0];
21734
animobj.speed = anim[1];
21735
animobj.loop = anim[2];
21736
animobj.repeatcount = anim[3];
21737
animobj.repeatto = anim[4];
21738
animobj.pingpong = anim[5];
21739
animobj.sid = anim[6];
21740
animobj.frames = [];
21741
for (j = 0, lenj = anim[7].length; j < lenj; j++)
21742
{
21743
frame = anim[7][j];
21744
frameobj = {};
21745
frameobj.texture_file = frame[0];
21746
frameobj.texture_filesize = frame[1];
21747
frameobj.offx = frame[2];
21748
frameobj.offy = frame[3];
21749
frameobj.width = frame[4];
21750
frameobj.height = frame[5];
21751
frameobj.duration = frame[6];
21752
frameobj.hotspotX = frame[7];
21753
frameobj.hotspotY = frame[8];
21754
frameobj.image_points = frame[9];
21755
frameobj.poly_pts = frame[10];
21756
frameobj.pixelformat = frame[11];
21757
frameobj.spritesheeted = (frameobj.width !== 0);
21758
frameobj.datauri = ""; // generated on demand and cached
21759
frameobj.getDataUri = frame_getDataUri;
21760
uv = {};
21761
uv.left = 0;
21762
uv.top = 0;
21763
uv.right = 1;
21764
uv.bottom = 1;
21765
frameobj.sheetTex = uv;
21766
frameobj.webGL_texture = null;
21767
wt = this.runtime.findWaitingTexture(frame[0]);
21768
if (wt)
21769
{
21770
frameobj.texture_img = wt;
21771
}
21772
else
21773
{
21774
frameobj.texture_img = new Image();
21775
frameobj.texture_img.cr_src = frame[0];
21776
frameobj.texture_img.cr_filesize = frame[1];
21777
frameobj.texture_img.c2webGL_texture = null;
21778
this.runtime.waitForImageLoad(frameobj.texture_img, frame[0]);
21779
}
21780
cr.seal(frameobj);
21781
animobj.frames.push(frameobj);
21782
this.all_frames.push(frameobj);
21783
}
21784
cr.seal(animobj);
21785
this.animations[i] = animobj; // swap array data for object
21786
}
21787
};
21788
typeProto.updateAllCurrentTexture = function ()
21789
{
21790
var i, len, inst;
21791
for (i = 0, len = this.instances.length; i < len; i++)
21792
{
21793
inst = this.instances[i];
21794
inst.curWebGLTexture = inst.curFrame.webGL_texture;
21795
}
21796
};
21797
typeProto.onLostWebGLContext = function ()
21798
{
21799
if (this.is_family)
21800
return;
21801
var i, len, frame;
21802
for (i = 0, len = this.all_frames.length; i < len; ++i)
21803
{
21804
frame = this.all_frames[i];
21805
frame.texture_img.c2webGL_texture = null;
21806
frame.webGL_texture = null;
21807
}
21808
this.has_loaded_textures = false;
21809
this.updateAllCurrentTexture();
21810
};
21811
typeProto.onRestoreWebGLContext = function ()
21812
{
21813
if (this.is_family || !this.instances.length)
21814
return;
21815
var i, len, frame;
21816
for (i = 0, len = this.all_frames.length; i < len; ++i)
21817
{
21818
frame = this.all_frames[i];
21819
frame.webGL_texture = this.runtime.glwrap.loadTexture(frame.texture_img, false, this.runtime.linearSampling, frame.pixelformat);
21820
}
21821
this.updateAllCurrentTexture();
21822
};
21823
typeProto.loadTextures = function ()
21824
{
21825
if (this.is_family || this.has_loaded_textures || !this.runtime.glwrap)
21826
return;
21827
var i, len, frame;
21828
for (i = 0, len = this.all_frames.length; i < len; ++i)
21829
{
21830
frame = this.all_frames[i];
21831
frame.webGL_texture = this.runtime.glwrap.loadTexture(frame.texture_img, false, this.runtime.linearSampling, frame.pixelformat);
21832
}
21833
this.has_loaded_textures = true;
21834
};
21835
typeProto.unloadTextures = function ()
21836
{
21837
if (this.is_family || this.instances.length || !this.has_loaded_textures)
21838
return;
21839
var i, len, frame;
21840
for (i = 0, len = this.all_frames.length; i < len; ++i)
21841
{
21842
frame = this.all_frames[i];
21843
this.runtime.glwrap.deleteTexture(frame.webGL_texture);
21844
frame.webGL_texture = null;
21845
}
21846
this.has_loaded_textures = false;
21847
};
21848
var already_drawn_images = [];
21849
typeProto.preloadCanvas2D = function (ctx)
21850
{
21851
var i, len, frameimg;
21852
cr.clearArray(already_drawn_images);
21853
for (i = 0, len = this.all_frames.length; i < len; ++i)
21854
{
21855
frameimg = this.all_frames[i].texture_img;
21856
if (already_drawn_images.indexOf(frameimg) !== -1)
21857
continue;
21858
ctx.drawImage(frameimg, 0, 0);
21859
already_drawn_images.push(frameimg);
21860
}
21861
};
21862
pluginProto.Instance = function(type)
21863
{
21864
this.type = type;
21865
this.runtime = type.runtime;
21866
var poly_pts = this.type.animations[0].frames[0].poly_pts;
21867
if (this.recycled)
21868
this.collision_poly.set_pts(poly_pts);
21869
else
21870
this.collision_poly = new cr.CollisionPoly(poly_pts);
21871
};
21872
var instanceProto = pluginProto.Instance.prototype;
21873
instanceProto.onCreate = function()
21874
{
21875
this.visible = (this.properties[0] === 0); // 0=visible, 1=invisible
21876
this.isTicking = false;
21877
this.inAnimTrigger = false;
21878
this.collisionsEnabled = (this.properties[3] !== 0);
21879
this.cur_animation = this.getAnimationByName(this.properties[1]) || this.type.animations[0];
21880
this.cur_frame = this.properties[2];
21881
if (this.cur_frame < 0)
21882
this.cur_frame = 0;
21883
if (this.cur_frame >= this.cur_animation.frames.length)
21884
this.cur_frame = this.cur_animation.frames.length - 1;
21885
var curanimframe = this.cur_animation.frames[this.cur_frame];
21886
this.collision_poly.set_pts(curanimframe.poly_pts);
21887
this.hotspotX = curanimframe.hotspotX;
21888
this.hotspotY = curanimframe.hotspotY;
21889
this.cur_anim_speed = this.cur_animation.speed;
21890
this.cur_anim_repeatto = this.cur_animation.repeatto;
21891
if (!(this.type.animations.length === 1 && this.type.animations[0].frames.length === 1) && this.cur_anim_speed !== 0)
21892
{
21893
this.runtime.tickMe(this);
21894
this.isTicking = true;
21895
}
21896
if (this.recycled)
21897
this.animTimer.reset();
21898
else
21899
this.animTimer = new cr.KahanAdder();
21900
this.frameStart = this.getNowTime();
21901
this.animPlaying = true;
21902
this.animRepeats = 0;
21903
this.animForwards = true;
21904
this.animTriggerName = "";
21905
this.changeAnimName = "";
21906
this.changeAnimFrom = 0;
21907
this.changeAnimFrame = -1;
21908
this.type.loadTextures();
21909
var i, leni, j, lenj;
21910
var anim, frame, uv, maintex;
21911
for (i = 0, leni = this.type.animations.length; i < leni; i++)
21912
{
21913
anim = this.type.animations[i];
21914
for (j = 0, lenj = anim.frames.length; j < lenj; j++)
21915
{
21916
frame = anim.frames[j];
21917
if (frame.width === 0)
21918
{
21919
frame.width = frame.texture_img.width;
21920
frame.height = frame.texture_img.height;
21921
}
21922
if (frame.spritesheeted)
21923
{
21924
maintex = frame.texture_img;
21925
uv = frame.sheetTex;
21926
uv.left = frame.offx / maintex.width;
21927
uv.top = frame.offy / maintex.height;
21928
uv.right = (frame.offx + frame.width) / maintex.width;
21929
uv.bottom = (frame.offy + frame.height) / maintex.height;
21930
if (frame.offx === 0 && frame.offy === 0 && frame.width === maintex.width && frame.height === maintex.height)
21931
{
21932
frame.spritesheeted = false;
21933
}
21934
}
21935
}
21936
}
21937
this.curFrame = this.cur_animation.frames[this.cur_frame];
21938
this.curWebGLTexture = this.curFrame.webGL_texture;
21939
};
21940
instanceProto.saveToJSON = function ()
21941
{
21942
var o = {
21943
"a": this.cur_animation.sid,
21944
"f": this.cur_frame,
21945
"cas": this.cur_anim_speed,
21946
"fs": this.frameStart,
21947
"ar": this.animRepeats,
21948
"at": this.animTimer.sum,
21949
"rt": this.cur_anim_repeatto
21950
};
21951
if (!this.animPlaying)
21952
o["ap"] = this.animPlaying;
21953
if (!this.animForwards)
21954
o["af"] = this.animForwards;
21955
return o;
21956
};
21957
instanceProto.loadFromJSON = function (o)
21958
{
21959
var anim = this.getAnimationBySid(o["a"]);
21960
if (anim)
21961
this.cur_animation = anim;
21962
this.cur_frame = o["f"];
21963
if (this.cur_frame < 0)
21964
this.cur_frame = 0;
21965
if (this.cur_frame >= this.cur_animation.frames.length)
21966
this.cur_frame = this.cur_animation.frames.length - 1;
21967
this.cur_anim_speed = o["cas"];
21968
this.frameStart = o["fs"];
21969
this.animRepeats = o["ar"];
21970
this.animTimer.reset();
21971
this.animTimer.sum = o["at"];
21972
this.animPlaying = o.hasOwnProperty("ap") ? o["ap"] : true;
21973
this.animForwards = o.hasOwnProperty("af") ? o["af"] : true;
21974
if (o.hasOwnProperty("rt"))
21975
this.cur_anim_repeatto = o["rt"];
21976
else
21977
this.cur_anim_repeatto = this.cur_animation.repeatto;
21978
this.curFrame = this.cur_animation.frames[this.cur_frame];
21979
this.curWebGLTexture = this.curFrame.webGL_texture;
21980
this.collision_poly.set_pts(this.curFrame.poly_pts);
21981
this.hotspotX = this.curFrame.hotspotX;
21982
this.hotspotY = this.curFrame.hotspotY;
21983
};
21984
instanceProto.animationFinish = function (reverse)
21985
{
21986
this.cur_frame = reverse ? 0 : this.cur_animation.frames.length - 1;
21987
this.animPlaying = false;
21988
this.animTriggerName = this.cur_animation.name;
21989
this.inAnimTrigger = true;
21990
this.runtime.trigger(cr.plugins_.Sprite.prototype.cnds.OnAnyAnimFinished, this);
21991
this.runtime.trigger(cr.plugins_.Sprite.prototype.cnds.OnAnimFinished, this);
21992
this.inAnimTrigger = false;
21993
this.animRepeats = 0;
21994
};
21995
instanceProto.getNowTime = function()
21996
{
21997
return this.animTimer.sum;
21998
};
21999
instanceProto.tick = function()
22000
{
22001
this.animTimer.add(this.runtime.getDt(this));
22002
if (this.changeAnimName.length)
22003
this.doChangeAnim();
22004
if (this.changeAnimFrame >= 0)
22005
this.doChangeAnimFrame();
22006
var now = this.getNowTime();
22007
var cur_animation = this.cur_animation;
22008
var prev_frame = cur_animation.frames[this.cur_frame];
22009
var next_frame;
22010
var cur_frame_time = prev_frame.duration / this.cur_anim_speed;
22011
if (this.animPlaying && now >= this.frameStart + cur_frame_time)
22012
{
22013
if (this.animForwards)
22014
{
22015
this.cur_frame++;
22016
}
22017
else
22018
{
22019
this.cur_frame--;
22020
}
22021
this.frameStart += cur_frame_time;
22022
if (this.cur_frame >= cur_animation.frames.length)
22023
{
22024
if (cur_animation.pingpong)
22025
{
22026
this.animForwards = false;
22027
this.cur_frame = cur_animation.frames.length - 2;
22028
}
22029
else if (cur_animation.loop)
22030
{
22031
this.cur_frame = this.cur_anim_repeatto;
22032
}
22033
else
22034
{
22035
this.animRepeats++;
22036
if (this.animRepeats >= cur_animation.repeatcount)
22037
{
22038
this.animationFinish(false);
22039
}
22040
else
22041
{
22042
this.cur_frame = this.cur_anim_repeatto;
22043
}
22044
}
22045
}
22046
if (this.cur_frame < 0)
22047
{
22048
if (cur_animation.pingpong)
22049
{
22050
this.cur_frame = 1;
22051
this.animForwards = true;
22052
if (!cur_animation.loop)
22053
{
22054
this.animRepeats++;
22055
if (this.animRepeats >= cur_animation.repeatcount)
22056
{
22057
this.animationFinish(true);
22058
}
22059
}
22060
}
22061
else
22062
{
22063
if (cur_animation.loop)
22064
{
22065
this.cur_frame = this.cur_anim_repeatto;
22066
}
22067
else
22068
{
22069
this.animRepeats++;
22070
if (this.animRepeats >= cur_animation.repeatcount)
22071
{
22072
this.animationFinish(true);
22073
}
22074
else
22075
{
22076
this.cur_frame = this.cur_anim_repeatto;
22077
}
22078
}
22079
}
22080
}
22081
if (this.cur_frame < 0)
22082
this.cur_frame = 0;
22083
else if (this.cur_frame >= cur_animation.frames.length)
22084
this.cur_frame = cur_animation.frames.length - 1;
22085
if (now > this.frameStart + (cur_animation.frames[this.cur_frame].duration / this.cur_anim_speed))
22086
{
22087
this.frameStart = now;
22088
}
22089
next_frame = cur_animation.frames[this.cur_frame];
22090
this.OnFrameChanged(prev_frame, next_frame);
22091
this.runtime.redraw = true;
22092
}
22093
};
22094
instanceProto.getAnimationByName = function (name_)
22095
{
22096
var i, len, a;
22097
for (i = 0, len = this.type.animations.length; i < len; i++)
22098
{
22099
a = this.type.animations[i];
22100
if (cr.equals_nocase(a.name, name_))
22101
return a;
22102
}
22103
return null;
22104
};
22105
instanceProto.getAnimationBySid = function (sid_)
22106
{
22107
var i, len, a;
22108
for (i = 0, len = this.type.animations.length; i < len; i++)
22109
{
22110
a = this.type.animations[i];
22111
if (a.sid === sid_)
22112
return a;
22113
}
22114
return null;
22115
};
22116
instanceProto.doChangeAnim = function ()
22117
{
22118
var prev_frame = this.cur_animation.frames[this.cur_frame];
22119
var anim = this.getAnimationByName(this.changeAnimName);
22120
this.changeAnimName = "";
22121
if (!anim)
22122
return;
22123
if (cr.equals_nocase(anim.name, this.cur_animation.name) && this.animPlaying)
22124
return;
22125
this.cur_animation = anim;
22126
this.cur_anim_speed = anim.speed;
22127
this.cur_anim_repeatto = anim.repeatto;
22128
if (this.cur_frame < 0)
22129
this.cur_frame = 0;
22130
if (this.cur_frame >= this.cur_animation.frames.length)
22131
this.cur_frame = this.cur_animation.frames.length - 1;
22132
if (this.changeAnimFrom === 1)
22133
this.cur_frame = 0;
22134
this.animPlaying = true;
22135
this.frameStart = this.getNowTime();
22136
this.animForwards = true;
22137
this.OnFrameChanged(prev_frame, this.cur_animation.frames[this.cur_frame]);
22138
this.runtime.redraw = true;
22139
};
22140
instanceProto.doChangeAnimFrame = function ()
22141
{
22142
var prev_frame = this.cur_animation.frames[this.cur_frame];
22143
var prev_frame_number = this.cur_frame;
22144
this.cur_frame = cr.floor(this.changeAnimFrame);
22145
if (this.cur_frame < 0)
22146
this.cur_frame = 0;
22147
if (this.cur_frame >= this.cur_animation.frames.length)
22148
this.cur_frame = this.cur_animation.frames.length - 1;
22149
if (prev_frame_number !== this.cur_frame)
22150
{
22151
this.OnFrameChanged(prev_frame, this.cur_animation.frames[this.cur_frame]);
22152
this.frameStart = this.getNowTime();
22153
this.runtime.redraw = true;
22154
}
22155
this.changeAnimFrame = -1;
22156
};
22157
instanceProto.OnFrameChanged = function (prev_frame, next_frame)
22158
{
22159
var oldw = prev_frame.width;
22160
var oldh = prev_frame.height;
22161
var neww = next_frame.width;
22162
var newh = next_frame.height;
22163
if (oldw != neww)
22164
this.width *= (neww / oldw);
22165
if (oldh != newh)
22166
this.height *= (newh / oldh);
22167
this.hotspotX = next_frame.hotspotX;
22168
this.hotspotY = next_frame.hotspotY;
22169
this.collision_poly.set_pts(next_frame.poly_pts);
22170
this.set_bbox_changed();
22171
this.curFrame = next_frame;
22172
this.curWebGLTexture = next_frame.webGL_texture;
22173
var i, len, b;
22174
for (i = 0, len = this.behavior_insts.length; i < len; i++)
22175
{
22176
b = this.behavior_insts[i];
22177
if (b.onSpriteFrameChanged)
22178
b.onSpriteFrameChanged(prev_frame, next_frame);
22179
}
22180
this.runtime.trigger(cr.plugins_.Sprite.prototype.cnds.OnFrameChanged, this);
22181
};
22182
instanceProto.draw = function(ctx)
22183
{
22184
ctx.globalAlpha = this.opacity;
22185
var cur_frame = this.curFrame;
22186
var spritesheeted = cur_frame.spritesheeted;
22187
var cur_image = cur_frame.texture_img;
22188
var myx = this.x;
22189
var myy = this.y;
22190
var w = this.width;
22191
var h = this.height;
22192
if (this.angle === 0 && w >= 0 && h >= 0)
22193
{
22194
myx -= this.hotspotX * w;
22195
myy -= this.hotspotY * h;
22196
if (this.runtime.pixel_rounding)
22197
{
22198
myx = Math.round(myx);
22199
myy = Math.round(myy);
22200
}
22201
if (spritesheeted)
22202
{
22203
ctx.drawImage(cur_image, cur_frame.offx, cur_frame.offy, cur_frame.width, cur_frame.height,
22204
myx, myy, w, h);
22205
}
22206
else
22207
{
22208
ctx.drawImage(cur_image, myx, myy, w, h);
22209
}
22210
}
22211
else
22212
{
22213
if (this.runtime.pixel_rounding)
22214
{
22215
myx = Math.round(myx);
22216
myy = Math.round(myy);
22217
}
22218
ctx.save();
22219
var widthfactor = w > 0 ? 1 : -1;
22220
var heightfactor = h > 0 ? 1 : -1;
22221
ctx.translate(myx, myy);
22222
if (widthfactor !== 1 || heightfactor !== 1)
22223
ctx.scale(widthfactor, heightfactor);
22224
ctx.rotate(this.angle * widthfactor * heightfactor);
22225
var drawx = 0 - (this.hotspotX * cr.abs(w))
22226
var drawy = 0 - (this.hotspotY * cr.abs(h));
22227
if (spritesheeted)
22228
{
22229
ctx.drawImage(cur_image, cur_frame.offx, cur_frame.offy, cur_frame.width, cur_frame.height,
22230
drawx, drawy, cr.abs(w), cr.abs(h));
22231
}
22232
else
22233
{
22234
ctx.drawImage(cur_image, drawx, drawy, cr.abs(w), cr.abs(h));
22235
}
22236
ctx.restore();
22237
}
22238
/*
22239
ctx.strokeStyle = "#f00";
22240
ctx.lineWidth = 3;
22241
ctx.beginPath();
22242
this.collision_poly.cache_poly(this.width, this.height, this.angle);
22243
var i, len, ax, ay, bx, by;
22244
for (i = 0, len = this.collision_poly.pts_count; i < len; i++)
22245
{
22246
ax = this.collision_poly.pts_cache[i*2] + this.x;
22247
ay = this.collision_poly.pts_cache[i*2+1] + this.y;
22248
bx = this.collision_poly.pts_cache[((i+1)%len)*2] + this.x;
22249
by = this.collision_poly.pts_cache[((i+1)%len)*2+1] + this.y;
22250
ctx.moveTo(ax, ay);
22251
ctx.lineTo(bx, by);
22252
}
22253
ctx.stroke();
22254
ctx.closePath();
22255
*/
22256
/*
22257
if (this.behavior_insts.length >= 1 && this.behavior_insts[0].draw)
22258
{
22259
this.behavior_insts[0].draw(ctx);
22260
}
22261
*/
22262
};
22263
instanceProto.drawGL_earlyZPass = function(glw)
22264
{
22265
this.drawGL(glw);
22266
};
22267
instanceProto.drawGL = function(glw)
22268
{
22269
glw.setTexture(this.curWebGLTexture);
22270
glw.setOpacity(this.opacity);
22271
var cur_frame = this.curFrame;
22272
var q = this.bquad;
22273
if (this.runtime.pixel_rounding)
22274
{
22275
var ox = Math.round(this.x) - this.x;
22276
var oy = Math.round(this.y) - this.y;
22277
if (cur_frame.spritesheeted)
22278
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);
22279
else
22280
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);
22281
}
22282
else
22283
{
22284
if (cur_frame.spritesheeted)
22285
glw.quadTex(q.tlx, q.tly, q.trx, q.try_, q.brx, q.bry, q.blx, q.bly, cur_frame.sheetTex);
22286
else
22287
glw.quad(q.tlx, q.tly, q.trx, q.try_, q.brx, q.bry, q.blx, q.bly);
22288
}
22289
};
22290
instanceProto.getImagePointIndexByName = function(name_)
22291
{
22292
var cur_frame = this.curFrame;
22293
var i, len;
22294
for (i = 0, len = cur_frame.image_points.length; i < len; i++)
22295
{
22296
if (cr.equals_nocase(name_, cur_frame.image_points[i][0]))
22297
return i;
22298
}
22299
return -1;
22300
};
22301
instanceProto.getImagePoint = function(imgpt, getX)
22302
{
22303
var cur_frame = this.curFrame;
22304
var image_points = cur_frame.image_points;
22305
var index;
22306
if (cr.is_string(imgpt))
22307
index = this.getImagePointIndexByName(imgpt);
22308
else
22309
index = imgpt - 1; // 0 is origin
22310
index = cr.floor(index);
22311
if (index < 0 || index >= image_points.length)
22312
return getX ? this.x : this.y; // return origin
22313
var x = (image_points[index][1] - cur_frame.hotspotX) * this.width;
22314
var y = image_points[index][2];
22315
y = (y - cur_frame.hotspotY) * this.height;
22316
var cosa = Math.cos(this.angle);
22317
var sina = Math.sin(this.angle);
22318
var x_temp = (x * cosa) - (y * sina);
22319
y = (y * cosa) + (x * sina);
22320
x = x_temp;
22321
x += this.x;
22322
y += this.y;
22323
return getX ? x : y;
22324
};
22325
function Cnds() {};
22326
var arrCache = [];
22327
function allocArr()
22328
{
22329
if (arrCache.length)
22330
return arrCache.pop();
22331
else
22332
return [0, 0, 0];
22333
};
22334
function freeArr(a)
22335
{
22336
a[0] = 0;
22337
a[1] = 0;
22338
a[2] = 0;
22339
arrCache.push(a);
22340
};
22341
function makeCollKey(a, b)
22342
{
22343
if (a < b)
22344
return "" + a + "," + b;
22345
else
22346
return "" + b + "," + a;
22347
};
22348
function collmemory_add(collmemory, a, b, tickcount)
22349
{
22350
var a_uid = a.uid;
22351
var b_uid = b.uid;
22352
var key = makeCollKey(a_uid, b_uid);
22353
if (collmemory.hasOwnProperty(key))
22354
{
22355
collmemory[key][2] = tickcount;
22356
return;
22357
}
22358
var arr = allocArr();
22359
arr[0] = a_uid;
22360
arr[1] = b_uid;
22361
arr[2] = tickcount;
22362
collmemory[key] = arr;
22363
};
22364
function collmemory_remove(collmemory, a, b)
22365
{
22366
var key = makeCollKey(a.uid, b.uid);
22367
if (collmemory.hasOwnProperty(key))
22368
{
22369
freeArr(collmemory[key]);
22370
delete collmemory[key];
22371
}
22372
};
22373
function collmemory_removeInstance(collmemory, inst)
22374
{
22375
var uid = inst.uid;
22376
var p, entry;
22377
for (p in collmemory)
22378
{
22379
if (collmemory.hasOwnProperty(p))
22380
{
22381
entry = collmemory[p];
22382
if (entry[0] === uid || entry[1] === uid)
22383
{
22384
freeArr(collmemory[p]);
22385
delete collmemory[p];
22386
}
22387
}
22388
}
22389
};
22390
var last_coll_tickcount = -2;
22391
function collmemory_has(collmemory, a, b)
22392
{
22393
var key = makeCollKey(a.uid, b.uid);
22394
if (collmemory.hasOwnProperty(key))
22395
{
22396
last_coll_tickcount = collmemory[key][2];
22397
return true;
22398
}
22399
else
22400
{
22401
last_coll_tickcount = -2;
22402
return false;
22403
}
22404
};
22405
var candidates1 = [];
22406
Cnds.prototype.OnCollision = function (rtype)
22407
{
22408
if (!rtype)
22409
return false;
22410
var runtime = this.runtime;
22411
var cnd = runtime.getCurrentCondition();
22412
var ltype = cnd.type;
22413
var collmemory = null;
22414
if (cnd.extra["collmemory"])
22415
{
22416
collmemory = cnd.extra["collmemory"];
22417
}
22418
else
22419
{
22420
collmemory = {};
22421
cnd.extra["collmemory"] = collmemory;
22422
}
22423
if (!cnd.extra["spriteCreatedDestroyCallback"])
22424
{
22425
cnd.extra["spriteCreatedDestroyCallback"] = true;
22426
runtime.addDestroyCallback(function(inst) {
22427
collmemory_removeInstance(cnd.extra["collmemory"], inst);
22428
});
22429
}
22430
var lsol = ltype.getCurrentSol();
22431
var rsol = rtype.getCurrentSol();
22432
var linstances = lsol.getObjects();
22433
var rinstances;
22434
var registeredInstances;
22435
var l, linst, r, rinst;
22436
var curlsol, currsol;
22437
var tickcount = this.runtime.tickcount;
22438
var lasttickcount = tickcount - 1;
22439
var exists, run;
22440
var current_event = runtime.getCurrentEventStack().current_event;
22441
var orblock = current_event.orblock;
22442
for (l = 0; l < linstances.length; l++)
22443
{
22444
linst = linstances[l];
22445
if (rsol.select_all)
22446
{
22447
linst.update_bbox();
22448
this.runtime.getCollisionCandidates(linst.layer, rtype, linst.bbox, candidates1);
22449
rinstances = candidates1;
22450
this.runtime.addRegisteredCollisionCandidates(linst, rtype, rinstances);
22451
}
22452
else
22453
{
22454
rinstances = rsol.getObjects();
22455
}
22456
for (r = 0; r < rinstances.length; r++)
22457
{
22458
rinst = rinstances[r];
22459
if (runtime.testOverlap(linst, rinst) || runtime.checkRegisteredCollision(linst, rinst))
22460
{
22461
exists = collmemory_has(collmemory, linst, rinst);
22462
run = (!exists || (last_coll_tickcount < lasttickcount));
22463
collmemory_add(collmemory, linst, rinst, tickcount);
22464
if (run)
22465
{
22466
runtime.pushCopySol(current_event.solModifiers);
22467
curlsol = ltype.getCurrentSol();
22468
currsol = rtype.getCurrentSol();
22469
curlsol.select_all = false;
22470
currsol.select_all = false;
22471
if (ltype === rtype)
22472
{
22473
curlsol.instances.length = 2; // just use lsol, is same reference as rsol
22474
curlsol.instances[0] = linst;
22475
curlsol.instances[1] = rinst;
22476
ltype.applySolToContainer();
22477
}
22478
else
22479
{
22480
curlsol.instances.length = 1;
22481
currsol.instances.length = 1;
22482
curlsol.instances[0] = linst;
22483
currsol.instances[0] = rinst;
22484
ltype.applySolToContainer();
22485
rtype.applySolToContainer();
22486
}
22487
current_event.retrigger();
22488
runtime.popSol(current_event.solModifiers);
22489
}
22490
}
22491
else
22492
{
22493
collmemory_remove(collmemory, linst, rinst);
22494
}
22495
}
22496
cr.clearArray(candidates1);
22497
}
22498
return false;
22499
};
22500
var rpicktype = null;
22501
var rtopick = new cr.ObjectSet();
22502
var needscollisionfinish = false;
22503
var candidates2 = [];
22504
var temp_bbox = new cr.rect(0, 0, 0, 0);
22505
function DoOverlapCondition(rtype, offx, offy)
22506
{
22507
if (!rtype)
22508
return false;
22509
var do_offset = (offx !== 0 || offy !== 0);
22510
var oldx, oldy, ret = false, r, lenr, rinst;
22511
var cnd = this.runtime.getCurrentCondition();
22512
var ltype = cnd.type;
22513
var inverted = cnd.inverted;
22514
var rsol = rtype.getCurrentSol();
22515
var orblock = this.runtime.getCurrentEventStack().current_event.orblock;
22516
var rinstances;
22517
if (rsol.select_all)
22518
{
22519
this.update_bbox();
22520
temp_bbox.copy(this.bbox);
22521
temp_bbox.offset(offx, offy);
22522
this.runtime.getCollisionCandidates(this.layer, rtype, temp_bbox, candidates2);
22523
rinstances = candidates2;
22524
}
22525
else if (orblock)
22526
{
22527
if (this.runtime.isCurrentConditionFirst() && !rsol.else_instances.length && rsol.instances.length)
22528
rinstances = rsol.instances;
22529
else
22530
rinstances = rsol.else_instances;
22531
}
22532
else
22533
{
22534
rinstances = rsol.instances;
22535
}
22536
rpicktype = rtype;
22537
needscollisionfinish = (ltype !== rtype && !inverted);
22538
if (do_offset)
22539
{
22540
oldx = this.x;
22541
oldy = this.y;
22542
this.x += offx;
22543
this.y += offy;
22544
this.set_bbox_changed();
22545
}
22546
for (r = 0, lenr = rinstances.length; r < lenr; r++)
22547
{
22548
rinst = rinstances[r];
22549
if (this.runtime.testOverlap(this, rinst))
22550
{
22551
ret = true;
22552
if (inverted)
22553
break;
22554
if (ltype !== rtype)
22555
rtopick.add(rinst);
22556
}
22557
}
22558
if (do_offset)
22559
{
22560
this.x = oldx;
22561
this.y = oldy;
22562
this.set_bbox_changed();
22563
}
22564
cr.clearArray(candidates2);
22565
return ret;
22566
};
22567
typeProto.finish = function (do_pick)
22568
{
22569
if (!needscollisionfinish)
22570
return;
22571
if (do_pick)
22572
{
22573
var orblock = this.runtime.getCurrentEventStack().current_event.orblock;
22574
var sol = rpicktype.getCurrentSol();
22575
var topick = rtopick.valuesRef();
22576
var i, len, inst;
22577
if (sol.select_all)
22578
{
22579
sol.select_all = false;
22580
cr.clearArray(sol.instances);
22581
for (i = 0, len = topick.length; i < len; ++i)
22582
{
22583
sol.instances[i] = topick[i];
22584
}
22585
if (orblock)
22586
{
22587
cr.clearArray(sol.else_instances);
22588
for (i = 0, len = rpicktype.instances.length; i < len; ++i)
22589
{
22590
inst = rpicktype.instances[i];
22591
if (!rtopick.contains(inst))
22592
sol.else_instances.push(inst);
22593
}
22594
}
22595
}
22596
else
22597
{
22598
if (orblock)
22599
{
22600
var initsize = sol.instances.length;
22601
for (i = 0, len = topick.length; i < len; ++i)
22602
{
22603
sol.instances[initsize + i] = topick[i];
22604
cr.arrayFindRemove(sol.else_instances, topick[i]);
22605
}
22606
}
22607
else
22608
{
22609
cr.shallowAssignArray(sol.instances, topick);
22610
}
22611
}
22612
rpicktype.applySolToContainer();
22613
}
22614
rtopick.clear();
22615
needscollisionfinish = false;
22616
};
22617
Cnds.prototype.IsOverlapping = function (rtype)
22618
{
22619
return DoOverlapCondition.call(this, rtype, 0, 0);
22620
};
22621
Cnds.prototype.IsOverlappingOffset = function (rtype, offx, offy)
22622
{
22623
return DoOverlapCondition.call(this, rtype, offx, offy);
22624
};
22625
Cnds.prototype.IsAnimPlaying = function (animname)
22626
{
22627
if (this.changeAnimName.length)
22628
return cr.equals_nocase(this.changeAnimName, animname);
22629
else
22630
return cr.equals_nocase(this.cur_animation.name, animname);
22631
};
22632
Cnds.prototype.CompareFrame = function (cmp, framenum)
22633
{
22634
return cr.do_cmp(this.cur_frame, cmp, framenum);
22635
};
22636
Cnds.prototype.CompareAnimSpeed = function (cmp, x)
22637
{
22638
var s = (this.animForwards ? this.cur_anim_speed : -this.cur_anim_speed);
22639
return cr.do_cmp(s, cmp, x);
22640
};
22641
Cnds.prototype.OnAnimFinished = function (animname)
22642
{
22643
return cr.equals_nocase(this.animTriggerName, animname);
22644
};
22645
Cnds.prototype.OnAnyAnimFinished = function ()
22646
{
22647
return true;
22648
};
22649
Cnds.prototype.OnFrameChanged = function ()
22650
{
22651
return true;
22652
};
22653
Cnds.prototype.IsMirrored = function ()
22654
{
22655
return this.width < 0;
22656
};
22657
Cnds.prototype.IsFlipped = function ()
22658
{
22659
return this.height < 0;
22660
};
22661
Cnds.prototype.OnURLLoaded = function ()
22662
{
22663
return true;
22664
};
22665
Cnds.prototype.IsCollisionEnabled = function ()
22666
{
22667
return this.collisionsEnabled;
22668
};
22669
pluginProto.cnds = new Cnds();
22670
function Acts() {};
22671
Acts.prototype.Spawn = function (obj, layer, imgpt)
22672
{
22673
if (!obj || !layer)
22674
return;
22675
var inst = this.runtime.createInstance(obj, layer, this.getImagePoint(imgpt, true), this.getImagePoint(imgpt, false));
22676
if (!inst)
22677
return;
22678
if (typeof inst.angle !== "undefined")
22679
{
22680
inst.angle = this.angle;
22681
inst.set_bbox_changed();
22682
}
22683
this.runtime.isInOnDestroy++;
22684
var i, len, s;
22685
this.runtime.trigger(Object.getPrototypeOf(obj.plugin).cnds.OnCreated, inst);
22686
if (inst.is_contained)
22687
{
22688
for (i = 0, len = inst.siblings.length; i < len; i++)
22689
{
22690
s = inst.siblings[i];
22691
this.runtime.trigger(Object.getPrototypeOf(s.type.plugin).cnds.OnCreated, s);
22692
}
22693
}
22694
this.runtime.isInOnDestroy--;
22695
var cur_act = this.runtime.getCurrentAction();
22696
var reset_sol = false;
22697
if (cr.is_undefined(cur_act.extra["Spawn_LastExec"]) || cur_act.extra["Spawn_LastExec"] < this.runtime.execcount)
22698
{
22699
reset_sol = true;
22700
cur_act.extra["Spawn_LastExec"] = this.runtime.execcount;
22701
}
22702
var sol;
22703
if (obj != this.type)
22704
{
22705
sol = obj.getCurrentSol();
22706
sol.select_all = false;
22707
if (reset_sol)
22708
{
22709
cr.clearArray(sol.instances);
22710
sol.instances[0] = inst;
22711
}
22712
else
22713
sol.instances.push(inst);
22714
if (inst.is_contained)
22715
{
22716
for (i = 0, len = inst.siblings.length; i < len; i++)
22717
{
22718
s = inst.siblings[i];
22719
sol = s.type.getCurrentSol();
22720
sol.select_all = false;
22721
if (reset_sol)
22722
{
22723
cr.clearArray(sol.instances);
22724
sol.instances[0] = s;
22725
}
22726
else
22727
sol.instances.push(s);
22728
}
22729
}
22730
}
22731
};
22732
Acts.prototype.SetEffect = function (effect)
22733
{
22734
this.blend_mode = effect;
22735
this.compositeOp = cr.effectToCompositeOp(effect);
22736
cr.setGLBlend(this, effect, this.runtime.gl);
22737
this.runtime.redraw = true;
22738
};
22739
Acts.prototype.StopAnim = function ()
22740
{
22741
this.animPlaying = false;
22742
};
22743
Acts.prototype.StartAnim = function (from)
22744
{
22745
this.animPlaying = true;
22746
this.frameStart = this.getNowTime();
22747
if (from === 1 && this.cur_frame !== 0)
22748
{
22749
this.changeAnimFrame = 0;
22750
if (!this.inAnimTrigger)
22751
this.doChangeAnimFrame();
22752
}
22753
if (!this.isTicking)
22754
{
22755
this.runtime.tickMe(this);
22756
this.isTicking = true;
22757
}
22758
};
22759
Acts.prototype.SetAnim = function (animname, from)
22760
{
22761
this.changeAnimName = animname;
22762
this.changeAnimFrom = from;
22763
if (!this.isTicking)
22764
{
22765
this.runtime.tickMe(this);
22766
this.isTicking = true;
22767
}
22768
if (!this.inAnimTrigger)
22769
this.doChangeAnim();
22770
};
22771
Acts.prototype.SetAnimFrame = function (framenumber)
22772
{
22773
this.changeAnimFrame = framenumber;
22774
if (!this.isTicking)
22775
{
22776
this.runtime.tickMe(this);
22777
this.isTicking = true;
22778
}
22779
if (!this.inAnimTrigger)
22780
this.doChangeAnimFrame();
22781
};
22782
Acts.prototype.SetAnimSpeed = function (s)
22783
{
22784
this.cur_anim_speed = cr.abs(s);
22785
this.animForwards = (s >= 0);
22786
if (!this.isTicking)
22787
{
22788
this.runtime.tickMe(this);
22789
this.isTicking = true;
22790
}
22791
};
22792
Acts.prototype.SetAnimRepeatToFrame = function (s)
22793
{
22794
s = Math.floor(s);
22795
if (s < 0)
22796
s = 0;
22797
if (s >= this.cur_animation.frames.length)
22798
s = this.cur_animation.frames.length - 1;
22799
this.cur_anim_repeatto = s;
22800
};
22801
Acts.prototype.SetMirrored = function (m)
22802
{
22803
var neww = cr.abs(this.width) * (m === 0 ? -1 : 1);
22804
if (this.width === neww)
22805
return;
22806
this.width = neww;
22807
this.set_bbox_changed();
22808
};
22809
Acts.prototype.SetFlipped = function (f)
22810
{
22811
var newh = cr.abs(this.height) * (f === 0 ? -1 : 1);
22812
if (this.height === newh)
22813
return;
22814
this.height = newh;
22815
this.set_bbox_changed();
22816
};
22817
Acts.prototype.SetScale = function (s)
22818
{
22819
var cur_frame = this.curFrame;
22820
var mirror_factor = (this.width < 0 ? -1 : 1);
22821
var flip_factor = (this.height < 0 ? -1 : 1);
22822
var new_width = cur_frame.width * s * mirror_factor;
22823
var new_height = cur_frame.height * s * flip_factor;
22824
if (this.width !== new_width || this.height !== new_height)
22825
{
22826
this.width = new_width;
22827
this.height = new_height;
22828
this.set_bbox_changed();
22829
}
22830
};
22831
Acts.prototype.LoadURL = function (url_, resize_, crossOrigin_)
22832
{
22833
var img = new Image();
22834
var self = this;
22835
var curFrame_ = this.curFrame;
22836
img.onload = function ()
22837
{
22838
if (curFrame_.texture_img.src === img.src)
22839
{
22840
if (self.runtime.glwrap && self.curFrame === curFrame_)
22841
self.curWebGLTexture = curFrame_.webGL_texture;
22842
if (resize_ === 0) // resize to image size
22843
{
22844
self.width = img.width;
22845
self.height = img.height;
22846
self.set_bbox_changed();
22847
}
22848
self.runtime.redraw = true;
22849
self.runtime.trigger(cr.plugins_.Sprite.prototype.cnds.OnURLLoaded, self);
22850
return;
22851
}
22852
curFrame_.texture_img = img;
22853
curFrame_.offx = 0;
22854
curFrame_.offy = 0;
22855
curFrame_.width = img.width;
22856
curFrame_.height = img.height;
22857
curFrame_.spritesheeted = false;
22858
curFrame_.datauri = "";
22859
curFrame_.pixelformat = 0; // reset to RGBA, since we don't know what type of image will have come in
22860
if (self.runtime.glwrap)
22861
{
22862
if (curFrame_.webGL_texture)
22863
self.runtime.glwrap.deleteTexture(curFrame_.webGL_texture);
22864
curFrame_.webGL_texture = self.runtime.glwrap.loadTexture(img, false, self.runtime.linearSampling);
22865
if (self.curFrame === curFrame_)
22866
self.curWebGLTexture = curFrame_.webGL_texture;
22867
self.type.updateAllCurrentTexture();
22868
}
22869
if (resize_ === 0) // resize to image size
22870
{
22871
self.width = img.width;
22872
self.height = img.height;
22873
self.set_bbox_changed();
22874
}
22875
self.runtime.redraw = true;
22876
self.runtime.trigger(cr.plugins_.Sprite.prototype.cnds.OnURLLoaded, self);
22877
};
22878
if (url_.substr(0, 5) !== "data:" && crossOrigin_ === 0)
22879
img["crossOrigin"] = "anonymous";
22880
this.runtime.setImageSrc(img, url_);
22881
};
22882
Acts.prototype.SetCollisions = function (set_)
22883
{
22884
if (this.collisionsEnabled === (set_ !== 0))
22885
return; // no change
22886
this.collisionsEnabled = (set_ !== 0);
22887
if (this.collisionsEnabled)
22888
this.set_bbox_changed(); // needs to be added back to cells
22889
else
22890
{
22891
if (this.collcells.right >= this.collcells.left)
22892
this.type.collision_grid.update(this, this.collcells, null);
22893
this.collcells.set(0, 0, -1, -1);
22894
}
22895
};
22896
pluginProto.acts = new Acts();
22897
function Exps() {};
22898
Exps.prototype.AnimationFrame = function (ret)
22899
{
22900
ret.set_int(this.cur_frame);
22901
};
22902
Exps.prototype.AnimationFrameCount = function (ret)
22903
{
22904
ret.set_int(this.cur_animation.frames.length);
22905
};
22906
Exps.prototype.AnimationName = function (ret)
22907
{
22908
ret.set_string(this.cur_animation.name);
22909
};
22910
Exps.prototype.AnimationSpeed = function (ret)
22911
{
22912
ret.set_float(this.animForwards ? this.cur_anim_speed : -this.cur_anim_speed);
22913
};
22914
Exps.prototype.ImagePointX = function (ret, imgpt)
22915
{
22916
ret.set_float(this.getImagePoint(imgpt, true));
22917
};
22918
Exps.prototype.ImagePointY = function (ret, imgpt)
22919
{
22920
ret.set_float(this.getImagePoint(imgpt, false));
22921
};
22922
Exps.prototype.ImagePointCount = function (ret)
22923
{
22924
ret.set_int(this.curFrame.image_points.length);
22925
};
22926
Exps.prototype.ImageWidth = function (ret)
22927
{
22928
ret.set_float(this.curFrame.width);
22929
};
22930
Exps.prototype.ImageHeight = function (ret)
22931
{
22932
ret.set_float(this.curFrame.height);
22933
};
22934
pluginProto.exps = new Exps();
22935
}());
22936
/* global cr,log,assert2 */
22937
/* jshint globalstrict: true */
22938
/* jshint strict: true */
22939
;
22940
;
22941
var jText = '';
22942
cr.plugins_.SpriteFontPlus = function(runtime)
22943
{
22944
this.runtime = runtime;
22945
};
22946
(function ()
22947
{
22948
var pluginProto = cr.plugins_.SpriteFontPlus.prototype;
22949
pluginProto.onCreate = function ()
22950
{
22951
};
22952
pluginProto.Type = function(plugin)
22953
{
22954
this.plugin = plugin;
22955
this.runtime = plugin.runtime;
22956
};
22957
var typeProto = pluginProto.Type.prototype;
22958
typeProto.onCreate = function()
22959
{
22960
if (this.is_family)
22961
return;
22962
this.texture_img = new Image();
22963
this.texture_img["idtkLoadDisposed"] = true;
22964
this.texture_img.src = this.texture_file;
22965
this.runtime.wait_for_textures.push(this.texture_img);
22966
this.webGL_texture = null;
22967
};
22968
typeProto.onLostWebGLContext = function ()
22969
{
22970
if (this.is_family)
22971
return;
22972
this.webGL_texture = null;
22973
};
22974
typeProto.onRestoreWebGLContext = function ()
22975
{
22976
if (this.is_family || !this.instances.length)
22977
return;
22978
if (!this.webGL_texture)
22979
{
22980
this.webGL_texture = this.runtime.glwrap.loadTexture(this.texture_img, false, this.runtime.linearSampling, this.texture_pixelformat);
22981
}
22982
var i, len;
22983
for (i = 0, len = this.instances.length; i < len; i++)
22984
this.instances[i].webGL_texture = this.webGL_texture;
22985
};
22986
typeProto.unloadTextures = function ()
22987
{
22988
if (this.is_family || this.instances.length || !this.webGL_texture)
22989
return;
22990
this.runtime.glwrap.deleteTexture(this.webGL_texture);
22991
this.webGL_texture = null;
22992
};
22993
typeProto.preloadCanvas2D = function (ctx)
22994
{
22995
ctx.drawImage(this.texture_img, 0, 0);
22996
};
22997
pluginProto.Instance = function(type)
22998
{
22999
this.type = type;
23000
this.runtime = type.runtime;
23001
};
23002
var instanceProto = pluginProto.Instance.prototype;
23003
instanceProto.onDestroy = function()
23004
{
23005
freeAllLines (this.lines);
23006
freeAllClip (this.clipList);
23007
freeAllClipUV(this.clipUV);
23008
cr.wipe(this.characterWidthList);
23009
};
23010
instanceProto.onCreate = function()
23011
{
23012
this.texture_img = this.type.texture_img;
23013
this.characterWidth = this.properties[0];
23014
this.characterHeight = this.properties[1];
23015
this.characterSet = this.properties[2];
23016
this.text = this.properties[3];
23017
this.characterScale = this.properties[4];
23018
this.visible = (this.properties[5] === 0); // 0=visible, 1=invisible
23019
this.halign = this.properties[6]/2.0; // 0=left, 1=center, 2=right
23020
this.valign = this.properties[7]/2.0; // 0=top, 1=center, 2=bottom
23021
this.wrapbyword = (this.properties[9] === 0); // 0=word, 1=character
23022
this.characterSpacing = this.properties[10];
23023
this.lineHeight = this.properties[11];
23024
this.textWidth = 0;
23025
this.textHeight = 0;
23026
this.charWidthJSON = this.properties[12];
23027
this.spaceWidth = this.properties[13];
23028
console.log(this.charWidthJSON);
23029
jText = this.charWidthJSON;
23030
if (this.recycled)
23031
{
23032
this.lines.length = 0;
23033
cr.wipe(this.clipList);
23034
cr.wipe(this.clipUV);
23035
cr.wipe(this.characterWidthList);
23036
}
23037
else
23038
{
23039
this.lines = [];
23040
this.clipList = {};
23041
this.clipUV = {};
23042
this.characterWidthList = {};
23043
}
23044
try{
23045
if(this.charWidthJSON){
23046
if(this.charWidthJSON.indexOf('""c2array""') !== -1) {
23047
var jStr = jQuery.parseJSON(this.charWidthJSON.replace(/""/g,'"'));
23048
var l = jStr.size[1];
23049
for(var s = 0; s < l; s++) {
23050
var cs = jStr.data[1][s][0];
23051
var w = jStr.data[0][s][0];
23052
for(var c = 0; c < cs.length; c++) {
23053
this.characterWidthList[cs.charAt(c)] = w
23054
}
23055
}
23056
} else {
23057
var jStr = jQuery.parseJSON(this.charWidthJSON);
23058
var l = jStr.length;
23059
for(var s = 0; s < l; s++) {
23060
var cs = jStr[s][1];
23061
var w = jStr[s][0];
23062
for(var c = 0; c < cs.length; c++) {
23063
this.characterWidthList[cs.charAt(c)] = w
23064
}
23065
}
23066
}
23067
}
23068
if(this.spaceWidth !== -1) {
23069
this.characterWidthList[' '] = this.spaceWidth;
23070
}
23071
}
23072
catch(e){
23073
if(window.console && window.console.log) {
23074
window.console.log('SpriteFont+ Failure: ' + e);
23075
}
23076
}
23077
this.text_changed = true;
23078
this.lastwrapwidth = this.width;
23079
if (this.runtime.glwrap)
23080
{
23081
if (!this.type.webGL_texture)
23082
{
23083
this.type.webGL_texture = this.runtime.glwrap.loadTexture(this.type.texture_img, false, this.runtime.linearSampling, this.type.texture_pixelformat);
23084
}
23085
this.webGL_texture = this.type.webGL_texture;
23086
}
23087
this.SplitSheet();
23088
};
23089
instanceProto.saveToJSON = function ()
23090
{
23091
var save = {
23092
"t": this.text,
23093
"csc": this.characterScale,
23094
"csp": this.characterSpacing,
23095
"lh": this.lineHeight,
23096
"tw": this.textWidth,
23097
"th": this.textHeight,
23098
"lrt": this.last_render_tick,
23099
"cw": {}
23100
};
23101
for (var ch in this.characterWidthList)
23102
save["cw"][ch] = this.characterWidthList[ch];
23103
return save;
23104
};
23105
instanceProto.loadFromJSON = function (o)
23106
{
23107
this.text = o["t"];
23108
this.characterScale = o["csc"];
23109
this.characterSpacing = o["csp"];
23110
this.lineHeight = o["lh"];
23111
this.textWidth = o["tw"];
23112
this.textHeight = o["th"];
23113
this.last_render_tick = o["lrt"];
23114
for(var ch in o["cw"])
23115
this.characterWidthList[ch] = o["cw"][ch];
23116
this.text_changed = true;
23117
this.lastwrapwidth = this.width;
23118
};
23119
function trimRight(text)
23120
{
23121
return text.replace(/\s\s*$/, '');
23122
}
23123
var MAX_CACHE_SIZE = 1000;
23124
function alloc(cache,Constructor)
23125
{
23126
if (cache.length)
23127
return cache.pop();
23128
else
23129
return new Constructor();
23130
}
23131
function free(cache,data)
23132
{
23133
if (cache.length < MAX_CACHE_SIZE)
23134
{
23135
cache.push(data);
23136
}
23137
}
23138
function freeAll(cache,dataList,isArray)
23139
{
23140
if (isArray) {
23141
var i, len;
23142
for (i = 0, len = dataList.length; i < len; i++)
23143
{
23144
free(cache,dataList[i]);
23145
}
23146
dataList.length = 0;
23147
} else {
23148
var prop;
23149
for(prop in dataList) {
23150
if(Object.prototype.hasOwnProperty.call(dataList,prop)) {
23151
free(cache,dataList[prop]);
23152
delete dataList[prop];
23153
}
23154
}
23155
}
23156
}
23157
function addLine(inst,lineIndex,cur_line) {
23158
var lines = inst.lines;
23159
var line;
23160
cur_line = trimRight(cur_line);
23161
if (lineIndex >= lines.length)
23162
lines.push(allocLine());
23163
line = lines[lineIndex];
23164
line.text = cur_line;
23165
line.width = inst.measureWidth(cur_line);
23166
inst.textWidth = cr.max(inst.textWidth,line.width);
23167
}
23168
var linesCache = [];
23169
function allocLine() { return alloc(linesCache,Object); }
23170
function freeLine(l) { free(linesCache,l); }
23171
function freeAllLines(arr) { freeAll(linesCache,arr,true); }
23172
function addClip(obj,property,x,y,w,h) {
23173
if (obj[property] === undefined) {
23174
obj[property] = alloc(clipCache,Object);
23175
}
23176
obj[property].x = x;
23177
obj[property].y = y;
23178
obj[property].w = w;
23179
obj[property].h = h;
23180
}
23181
var clipCache = [];
23182
function allocClip() { return alloc(clipCache,Object); }
23183
function freeAllClip(obj) { freeAll(clipCache,obj,false);}
23184
function addClipUV(obj,property,left,top,right,bottom) {
23185
if (obj[property] === undefined) {
23186
obj[property] = alloc(clipUVCache,cr.rect);
23187
}
23188
obj[property].left = left;
23189
obj[property].top = top;
23190
obj[property].right = right;
23191
obj[property].bottom = bottom;
23192
}
23193
var clipUVCache = [];
23194
function allocClipUV() { return alloc(clipUVCache,cr.rect);}
23195
function freeAllClipUV(obj) { freeAll(clipUVCache,obj,false);}
23196
instanceProto.SplitSheet = function() {
23197
var texture = this.texture_img;
23198
var texWidth = texture.width;
23199
var texHeight = texture.height;
23200
var charWidth = this.characterWidth;
23201
var charHeight = this.characterHeight;
23202
var charU = charWidth /texWidth;
23203
var charV = charHeight/texHeight;
23204
var charSet = this.characterSet ;
23205
var cols = Math.floor(texWidth/charWidth);
23206
var rows = Math.floor(texHeight/charHeight);
23207
for ( var c = 0; c < charSet.length; c++) {
23208
if (c >= cols * rows) break;
23209
var x = c%cols;
23210
var y = Math.floor(c/cols);
23211
var letter = charSet.charAt(c);
23212
if (this.runtime.glwrap) {
23213
addClipUV(
23214
this.clipUV, letter,
23215
x * charU ,
23216
y * charV ,
23217
(x+1) * charU ,
23218
(y+1) * charV
23219
);
23220
} else {
23221
addClip(
23222
this.clipList, letter,
23223
x * charWidth,
23224
y * charHeight,
23225
charWidth,
23226
charHeight
23227
);
23228
}
23229
}
23230
};
23231
/*
23232
* Word-Wrapping
23233
*/
23234
var wordsCache = [];
23235
pluginProto.TokeniseWords = function (text)
23236
{
23237
wordsCache.length = 0;
23238
var cur_word = "";
23239
var ch;
23240
var i = 0;
23241
while (i < text.length)
23242
{
23243
ch = text.charAt(i);
23244
if (ch === "\n")
23245
{
23246
if (cur_word.length)
23247
{
23248
wordsCache.push(cur_word);
23249
cur_word = "";
23250
}
23251
wordsCache.push("\n");
23252
++i;
23253
}
23254
else if (ch === " " || ch === "\t" || ch === "-")
23255
{
23256
do {
23257
cur_word += text.charAt(i);
23258
i++;
23259
}
23260
while (i < text.length && (text.charAt(i) === " " || text.charAt(i) === "\t"));
23261
wordsCache.push(cur_word);
23262
cur_word = "";
23263
}
23264
else if (i < text.length)
23265
{
23266
cur_word += ch;
23267
i++;
23268
}
23269
}
23270
if (cur_word.length)
23271
wordsCache.push(cur_word);
23272
};
23273
pluginProto.WordWrap = function (inst)
23274
{
23275
var text = inst.text;
23276
var lines = inst.lines;
23277
if (!text || !text.length)
23278
{
23279
freeAllLines(lines);
23280
return;
23281
}
23282
var width = inst.width;
23283
if (width <= 2.0)
23284
{
23285
freeAllLines(lines);
23286
return;
23287
}
23288
var charWidth = inst.characterWidth;
23289
var charScale = inst.characterScale;
23290
var charSpacing = inst.characterSpacing;
23291
if ( (text.length * (charWidth * charScale + charSpacing) - charSpacing) <= width && text.indexOf("\n") === -1)
23292
{
23293
var all_width = inst.measureWidth(text);
23294
if (all_width <= width)
23295
{
23296
freeAllLines(lines);
23297
lines.push(allocLine());
23298
lines[0].text = text;
23299
lines[0].width = all_width;
23300
inst.textWidth = all_width;
23301
inst.textHeight = inst.characterHeight * charScale + inst.lineHeight;
23302
return;
23303
}
23304
}
23305
var wrapbyword = inst.wrapbyword;
23306
this.WrapText(inst);
23307
inst.textHeight = lines.length * (inst.characterHeight * charScale + inst.lineHeight);
23308
};
23309
pluginProto.WrapText = function (inst)
23310
{
23311
var wrapbyword = inst.wrapbyword;
23312
var text = inst.text;
23313
var lines = inst.lines;
23314
var width = inst.width;
23315
var wordArray;
23316
if (wrapbyword) {
23317
this.TokeniseWords(text); // writes to wordsCache
23318
wordArray = wordsCache;
23319
} else {
23320
wordArray = text;
23321
}
23322
var cur_line = "";
23323
var prev_line;
23324
var line_width;
23325
var i;
23326
var lineIndex = 0;
23327
var line;
23328
var ignore_newline = false;
23329
for (i = 0; i < wordArray.length; i++)
23330
{
23331
if (wordArray[i] === "\n")
23332
{
23333
if (ignore_newline === true) {
23334
ignore_newline = false;
23335
} else {
23336
addLine(inst,lineIndex,cur_line);
23337
lineIndex++;
23338
}
23339
cur_line = "";
23340
continue;
23341
}
23342
ignore_newline = false;
23343
prev_line = cur_line;
23344
cur_line += wordArray[i];
23345
line_width = inst.measureWidth(trimRight(cur_line));
23346
if (line_width > width)
23347
{
23348
if (prev_line === "") {
23349
addLine(inst,lineIndex,cur_line);
23350
cur_line = "";
23351
ignore_newline = true;
23352
} else {
23353
addLine(inst,lineIndex,prev_line);
23354
cur_line = wordArray[i];
23355
}
23356
lineIndex++;
23357
if (!wrapbyword && cur_line === " ")
23358
cur_line = "";
23359
}
23360
}
23361
if (trimRight(cur_line).length)
23362
{
23363
addLine(inst,lineIndex,cur_line);
23364
lineIndex++;
23365
}
23366
for (i = lineIndex; i < lines.length; i++)
23367
freeLine(lines[i]);
23368
lines.length = lineIndex;
23369
};
23370
instanceProto.measureWidth = function(text) {
23371
var spacing = this.characterSpacing;
23372
var len = text.length;
23373
var width = 0;
23374
for (var i = 0; i < len; i++) {
23375
width += this.getCharacterWidth(text.charAt(i)) * this.characterScale + spacing;
23376
}
23377
width -= (width > 0) ? spacing : 0;
23378
return width;
23379
};
23380
/***/
23381
instanceProto.getCharacterWidth = function(character) {
23382
var widthList = this.characterWidthList;
23383
if (widthList[character] !== undefined) {
23384
return widthList[character];
23385
} else {
23386
return this.characterWidth;
23387
}
23388
};
23389
instanceProto.rebuildText = function() {
23390
if (this.text_changed || this.width !== this.lastwrapwidth) {
23391
this.textWidth = 0;
23392
this.textHeight = 0;
23393
this.type.plugin.WordWrap(this);
23394
this.text_changed = false;
23395
this.lastwrapwidth = this.width;
23396
}
23397
};
23398
var EPSILON = 0.00001;
23399
instanceProto.draw = function(ctx, glmode)
23400
{
23401
var texture = this.texture_img;
23402
if (this.text !== "" && texture != null) {
23403
this.rebuildText();
23404
if (this.height < this.characterHeight*this.characterScale + this.lineHeight) {
23405
return;
23406
}
23407
ctx.globalAlpha = this.opacity;
23408
var myx = this.x;
23409
var myy = this.y;
23410
if (this.runtime.pixel_rounding)
23411
{
23412
myx = (myx + 0.5) | 0;
23413
myy = (myy + 0.5) | 0;
23414
}
23415
ctx.save();
23416
ctx.translate(myx, myy);
23417
ctx.rotate(this.angle);
23418
var ha = this.halign;
23419
var va = this.valign;
23420
var scale = this.characterScale;
23421
var charHeight = this.characterHeight * scale;
23422
var lineHeight = this.lineHeight;
23423
var charSpace = this.characterSpacing;
23424
var lines = this.lines;
23425
var textHeight = this.textHeight;
23426
var halign;
23427
var valign = va * cr.max(0,(this.height - textHeight));
23428
var offx = -(this.hotspotX * this.width);
23429
var offy = -(this.hotspotY * this.height);
23430
offy += valign;
23431
var drawX ;
23432
var drawY = offy;
23433
for(var i = 0; i < lines.length; i++) {
23434
var line = lines[i].text;
23435
var len = lines[i].width;
23436
halign = ha * cr.max(0,this.width - len);
23437
drawX = offx + halign;
23438
drawY += lineHeight;
23439
for(var j = 0; j < line.length; j++) {
23440
var letter = line.charAt(j);
23441
var clip = this.clipList[letter];
23442
if ( drawX + this.getCharacterWidth(letter) * scale > this.width + EPSILON ) {
23443
break;
23444
}
23445
if (clip !== undefined) {
23446
ctx.drawImage( this.texture_img,
23447
clip.x, clip.y, clip.w, clip.h,
23448
Math.round(drawX),Math.round(drawY),clip.w*scale,clip.h*scale);
23449
}
23450
drawX += this.getCharacterWidth(letter) * scale + charSpace;
23451
}
23452
drawY += charHeight;
23453
if ( drawY + charHeight + lineHeight > this.height) {
23454
break;
23455
}
23456
}
23457
ctx.restore();
23458
}
23459
};
23460
var dQuad = new cr.quad();
23461
function rotateQuad(quad,cosa,sina) {
23462
var x_temp;
23463
x_temp = (quad.tlx * cosa) - (quad.tly * sina);
23464
quad.tly = (quad.tly * cosa) + (quad.tlx * sina);
23465
quad.tlx = x_temp;
23466
x_temp = (quad.trx * cosa) - (quad.try_ * sina);
23467
quad.try_ = (quad.try_ * cosa) + (quad.trx * sina);
23468
quad.trx = x_temp;
23469
x_temp = (quad.blx * cosa) - (quad.bly * sina);
23470
quad.bly = (quad.bly * cosa) + (quad.blx * sina);
23471
quad.blx = x_temp;
23472
x_temp = (quad.brx * cosa) - (quad.bry * sina);
23473
quad.bry = (quad.bry * cosa) + (quad.brx * sina);
23474
quad.brx = x_temp;
23475
}
23476
instanceProto.drawGL = function(glw)
23477
{
23478
glw.setTexture(this.webGL_texture);
23479
glw.setOpacity(this.opacity);
23480
if (this.text !== "") {
23481
this.rebuildText();
23482
if (this.height < this.characterHeight*this.characterScale + this.lineHeight) {
23483
return;
23484
}
23485
this.update_bbox();
23486
var q = this.bquad;
23487
var ox = 0;
23488
var oy = 0;
23489
if (this.runtime.pixel_rounding)
23490
{
23491
ox = ((this.x + 0.5) | 0) - this.x;
23492
oy = ((this.y + 0.5) | 0) - this.y;
23493
}
23494
var angle = this.angle;
23495
var ha = this.halign;
23496
var va = this.valign;
23497
var scale = this.characterScale;
23498
var charHeight = this.characterHeight * scale; // to precalculate in onCreate or on change
23499
var lineHeight = this.lineHeight;
23500
var charSpace = this.characterSpacing;
23501
var lines = this.lines;
23502
var textHeight = this.textHeight;
23503
var cosa,sina;
23504
if (angle !== 0)
23505
{
23506
cosa = Math.cos(angle);
23507
sina = Math.sin(angle);
23508
}
23509
var halign;
23510
var valign = va * cr.max(0,(this.height - textHeight));
23511
var offx = q.tlx + ox;
23512
var offy = q.tly + oy;
23513
var drawX ;
23514
var drawY = valign;
23515
for(var i = 0; i < lines.length; i++) {
23516
var line = lines[i].text;
23517
var lineWidth = lines[i].width;
23518
halign = ha * cr.max(0,this.width - lineWidth);
23519
drawX = halign;
23520
drawY += lineHeight;
23521
for(var j = 0; j < line.length; j++) {
23522
var letter = line.charAt(j);
23523
var clipUV = this.clipUV[letter];
23524
if ( drawX + this.getCharacterWidth(letter) * scale > this.width + EPSILON) {
23525
break;
23526
}
23527
if (clipUV !== undefined) {
23528
var clipWidth = this.characterWidth*scale;
23529
var clipHeight = this.characterHeight*scale;
23530
dQuad.tlx = drawX;
23531
dQuad.tly = drawY;
23532
dQuad.trx = drawX + clipWidth;
23533
dQuad.try_ = drawY ;
23534
dQuad.blx = drawX;
23535
dQuad.bly = drawY + clipHeight;
23536
dQuad.brx = drawX + clipWidth;
23537
dQuad.bry = drawY + clipHeight;
23538
if(angle !== 0)
23539
{
23540
rotateQuad(dQuad,cosa,sina);
23541
}
23542
dQuad.offset(offx,offy);
23543
glw.quadTex(
23544
dQuad.tlx, dQuad.tly,
23545
dQuad.trx, dQuad.try_,
23546
dQuad.brx, dQuad.bry,
23547
dQuad.blx, dQuad.bly,
23548
clipUV
23549
);
23550
}
23551
drawX += this.getCharacterWidth(letter) * scale + charSpace;
23552
}
23553
drawY += charHeight;
23554
if ( drawY + charHeight + lineHeight > this.height) {
23555
break;
23556
}
23557
}
23558
}
23559
};
23560
function Cnds() {}
23561
Cnds.prototype.CompareText = function(text_to_compare, case_sensitive)
23562
{
23563
if (case_sensitive)
23564
return this.text == text_to_compare;
23565
else
23566
return cr.equals_nocase(this.text, text_to_compare);
23567
};
23568
pluginProto.cnds = new Cnds();
23569
function Acts() {}
23570
Acts.prototype.SetText = function(param)
23571
{
23572
if (cr.is_number(param) && param < 1e9)
23573
param = Math.round(param * 1e10) / 1e10; // round to nearest ten billionth - hides floating point errors
23574
var text_to_set = param.toString();
23575
if (this.text !== text_to_set)
23576
{
23577
this.text = text_to_set;
23578
this.text_changed = true;
23579
this.runtime.redraw = true;
23580
}
23581
};
23582
Acts.prototype.AppendText = function(param)
23583
{
23584
if (cr.is_number(param))
23585
param = Math.round(param * 1e10) / 1e10; // round to nearest ten billionth - hides floating point errors
23586
var text_to_append = param.toString();
23587
if (text_to_append) // not empty
23588
{
23589
this.text += text_to_append;
23590
this.text_changed = true;
23591
this.runtime.redraw = true;
23592
}
23593
};
23594
Acts.prototype.SetScale = function(param)
23595
{
23596
if (param !== this.characterScale) {
23597
this.characterScale = param;
23598
this.text_changed = true;
23599
this.runtime.redraw = true;
23600
}
23601
};
23602
Acts.prototype.SetCharacterSpacing = function(param)
23603
{
23604
if (param !== this.CharacterSpacing) {
23605
this.characterSpacing = param;
23606
this.text_changed = true;
23607
this.runtime.redraw = true;
23608
}
23609
};
23610
Acts.prototype.SetLineHeight = function(param)
23611
{
23612
if (param !== this.lineHeight) {
23613
this.lineHeight = param;
23614
this.text_changed = true;
23615
this.runtime.redraw = true;
23616
}
23617
};
23618
instanceProto.SetCharWidth = function(character,width) {
23619
var w = parseInt(width,10);
23620
if (this.characterWidthList[character] !== w) {
23621
this.characterWidthList[character] = w;
23622
this.text_changed = true;
23623
this.runtime.redraw = true;
23624
}
23625
};
23626
Acts.prototype.SetCharacterWidth = function(characterSet,width)
23627
{
23628
if (characterSet !== "") {
23629
for(var c = 0; c < characterSet.length; c++) {
23630
this.SetCharWidth(characterSet.charAt(c),width);
23631
}
23632
}
23633
};
23634
Acts.prototype.SetEffect = function (effect)
23635
{
23636
this.compositeOp = cr.effectToCompositeOp(effect);
23637
cr.setGLBlend(this, effect, this.runtime.gl);
23638
this.runtime.redraw = true;
23639
};
23640
pluginProto.acts = new Acts();
23641
function Exps() {}
23642
Exps.prototype.CharacterWidth = function(ret,character)
23643
{
23644
ret.set_int(this.getCharacterWidth(character));
23645
};
23646
Exps.prototype.CharacterHeight = function(ret)
23647
{
23648
ret.set_int(this.characterHeight);
23649
};
23650
Exps.prototype.CharacterScale = function(ret)
23651
{
23652
ret.set_float(this.characterScale);
23653
};
23654
Exps.prototype.CharacterSpacing = function(ret)
23655
{
23656
ret.set_int(this.characterSpacing);
23657
};
23658
Exps.prototype.LineHeight = function(ret)
23659
{
23660
ret.set_int(this.lineHeight);
23661
};
23662
Exps.prototype.Text = function(ret)
23663
{
23664
ret.set_string(this.text);
23665
};
23666
Exps.prototype.TextWidth = function (ret)
23667
{
23668
this.rebuildText();
23669
ret.set_float(this.textWidth);
23670
};
23671
Exps.prototype.TextHeight = function (ret)
23672
{
23673
this.rebuildText();
23674
ret.set_float(this.textHeight);
23675
};
23676
pluginProto.exps = new Exps();
23677
}());
23678
;
23679
;
23680
cr.plugins_.Text = function(runtime)
23681
{
23682
this.runtime = runtime;
23683
};
23684
(function ()
23685
{
23686
var pluginProto = cr.plugins_.Text.prototype;
23687
pluginProto.onCreate = function ()
23688
{
23689
pluginProto.acts.SetWidth = function (w)
23690
{
23691
if (this.width !== w)
23692
{
23693
this.width = w;
23694
this.text_changed = true; // also recalculate text wrapping
23695
this.set_bbox_changed();
23696
}
23697
};
23698
};
23699
pluginProto.Type = function(plugin)
23700
{
23701
this.plugin = plugin;
23702
this.runtime = plugin.runtime;
23703
};
23704
var typeProto = pluginProto.Type.prototype;
23705
typeProto.onCreate = function()
23706
{
23707
};
23708
typeProto.onLostWebGLContext = function ()
23709
{
23710
if (this.is_family)
23711
return;
23712
var i, len, inst;
23713
for (i = 0, len = this.instances.length; i < len; i++)
23714
{
23715
inst = this.instances[i];
23716
inst.mycanvas = null;
23717
inst.myctx = null;
23718
inst.mytex = null;
23719
}
23720
};
23721
pluginProto.Instance = function(type)
23722
{
23723
this.type = type;
23724
this.runtime = type.runtime;
23725
if (this.recycled)
23726
cr.clearArray(this.lines);
23727
else
23728
this.lines = []; // for word wrapping
23729
this.text_changed = true;
23730
};
23731
var instanceProto = pluginProto.Instance.prototype;
23732
var requestedWebFonts = {}; // already requested web fonts have an entry here
23733
instanceProto.onCreate = function()
23734
{
23735
this.text = this.properties[0];
23736
this.visible = (this.properties[1] === 0); // 0=visible, 1=invisible
23737
this.font = this.properties[2];
23738
this.color = this.properties[3];
23739
this.halign = this.properties[4]; // 0=left, 1=center, 2=right
23740
this.valign = this.properties[5]; // 0=top, 1=center, 2=bottom
23741
this.wrapbyword = (this.properties[7] === 0); // 0=word, 1=character
23742
this.lastwidth = this.width;
23743
this.lastwrapwidth = this.width;
23744
this.lastheight = this.height;
23745
this.line_height_offset = this.properties[8];
23746
this.facename = "";
23747
this.fontstyle = "";
23748
this.ptSize = 0;
23749
this.textWidth = 0;
23750
this.textHeight = 0;
23751
this.parseFont();
23752
this.mycanvas = null;
23753
this.myctx = null;
23754
this.mytex = null;
23755
this.need_text_redraw = false;
23756
this.last_render_tick = this.runtime.tickcount;
23757
if (this.recycled)
23758
this.rcTex.set(0, 0, 1, 1);
23759
else
23760
this.rcTex = new cr.rect(0, 0, 1, 1);
23761
if (this.runtime.glwrap)
23762
this.runtime.tickMe(this);
23763
;
23764
};
23765
instanceProto.parseFont = function ()
23766
{
23767
var arr = this.font.split(" ");
23768
var i;
23769
for (i = 0; i < arr.length; i++)
23770
{
23771
if (arr[i].substr(arr[i].length - 2, 2) === "pt")
23772
{
23773
this.ptSize = parseInt(arr[i].substr(0, arr[i].length - 2));
23774
this.pxHeight = Math.ceil((this.ptSize / 72.0) * 96.0) + 4; // assume 96dpi...
23775
if (i > 0)
23776
this.fontstyle = arr[i - 1];
23777
this.facename = arr[i + 1];
23778
for (i = i + 2; i < arr.length; i++)
23779
this.facename += " " + arr[i];
23780
break;
23781
}
23782
}
23783
};
23784
instanceProto.saveToJSON = function ()
23785
{
23786
return {
23787
"t": this.text,
23788
"f": this.font,
23789
"c": this.color,
23790
"ha": this.halign,
23791
"va": this.valign,
23792
"wr": this.wrapbyword,
23793
"lho": this.line_height_offset,
23794
"fn": this.facename,
23795
"fs": this.fontstyle,
23796
"ps": this.ptSize,
23797
"pxh": this.pxHeight,
23798
"tw": this.textWidth,
23799
"th": this.textHeight,
23800
"lrt": this.last_render_tick
23801
};
23802
};
23803
instanceProto.loadFromJSON = function (o)
23804
{
23805
this.text = o["t"];
23806
this.font = o["f"];
23807
this.color = o["c"];
23808
this.halign = o["ha"];
23809
this.valign = o["va"];
23810
this.wrapbyword = o["wr"];
23811
this.line_height_offset = o["lho"];
23812
this.facename = o["fn"];
23813
this.fontstyle = o["fs"];
23814
this.ptSize = o["ps"];
23815
this.pxHeight = o["pxh"];
23816
this.textWidth = o["tw"];
23817
this.textHeight = o["th"];
23818
this.last_render_tick = o["lrt"];
23819
this.text_changed = true;
23820
this.lastwidth = this.width;
23821
this.lastwrapwidth = this.width;
23822
this.lastheight = this.height;
23823
};
23824
instanceProto.tick = function ()
23825
{
23826
if (this.runtime.glwrap && this.mytex && (this.runtime.tickcount - this.last_render_tick >= 300))
23827
{
23828
var layer = this.layer;
23829
this.update_bbox();
23830
var bbox = this.bbox;
23831
if (bbox.right < layer.viewLeft || bbox.bottom < layer.viewTop || bbox.left > layer.viewRight || bbox.top > layer.viewBottom)
23832
{
23833
this.runtime.glwrap.deleteTexture(this.mytex);
23834
this.mytex = null;
23835
this.myctx = null;
23836
this.mycanvas = null;
23837
}
23838
}
23839
};
23840
instanceProto.onDestroy = function ()
23841
{
23842
this.myctx = null;
23843
this.mycanvas = null;
23844
if (this.runtime.glwrap && this.mytex)
23845
this.runtime.glwrap.deleteTexture(this.mytex);
23846
this.mytex = null;
23847
};
23848
instanceProto.updateFont = function ()
23849
{
23850
this.font = this.fontstyle + " " + this.ptSize.toString() + "pt " + this.facename;
23851
this.text_changed = true;
23852
this.runtime.redraw = true;
23853
};
23854
instanceProto.draw = function(ctx, glmode)
23855
{
23856
ctx.font = this.font;
23857
ctx.textBaseline = "top";
23858
ctx.fillStyle = this.color;
23859
ctx.globalAlpha = glmode ? 1 : this.opacity;
23860
var myscale = 1;
23861
if (glmode)
23862
{
23863
myscale = Math.abs(this.layer.getScale());
23864
ctx.save();
23865
ctx.scale(myscale, myscale);
23866
}
23867
if (this.text_changed || this.width !== this.lastwrapwidth)
23868
{
23869
this.type.plugin.WordWrap(this.text, this.lines, ctx, this.width, this.wrapbyword);
23870
this.text_changed = false;
23871
this.lastwrapwidth = this.width;
23872
}
23873
this.update_bbox();
23874
var penX = glmode ? 0 : this.bquad.tlx;
23875
var penY = glmode ? 0 : this.bquad.tly;
23876
if (this.runtime.pixel_rounding)
23877
{
23878
penX = (penX + 0.5) | 0;
23879
penY = (penY + 0.5) | 0;
23880
}
23881
if (this.angle !== 0 && !glmode)
23882
{
23883
ctx.save();
23884
ctx.translate(penX, penY);
23885
ctx.rotate(this.angle);
23886
penX = 0;
23887
penY = 0;
23888
}
23889
var endY = penY + this.height;
23890
var line_height = this.pxHeight;
23891
line_height += this.line_height_offset;
23892
var drawX;
23893
var i;
23894
if (this.valign === 1) // center
23895
penY += Math.max(this.height / 2 - (this.lines.length * line_height) / 2, 0);
23896
else if (this.valign === 2) // bottom
23897
penY += Math.max(this.height - (this.lines.length * line_height) - 2, 0);
23898
for (i = 0; i < this.lines.length; i++)
23899
{
23900
drawX = penX;
23901
if (this.halign === 1) // center
23902
drawX = penX + (this.width - this.lines[i].width) / 2;
23903
else if (this.halign === 2) // right
23904
drawX = penX + (this.width - this.lines[i].width);
23905
ctx.fillText(this.lines[i].text, drawX, penY);
23906
penY += line_height;
23907
if (penY >= endY - line_height)
23908
break;
23909
}
23910
if (this.angle !== 0 || glmode)
23911
ctx.restore();
23912
this.last_render_tick = this.runtime.tickcount;
23913
};
23914
instanceProto.drawGL = function(glw)
23915
{
23916
if (this.width < 1 || this.height < 1)
23917
return;
23918
var need_redraw = this.text_changed || this.need_text_redraw;
23919
this.need_text_redraw = false;
23920
var layer_scale = this.layer.getScale();
23921
var layer_angle = this.layer.getAngle();
23922
var rcTex = this.rcTex;
23923
var floatscaledwidth = layer_scale * this.width;
23924
var floatscaledheight = layer_scale * this.height;
23925
var scaledwidth = Math.ceil(floatscaledwidth);
23926
var scaledheight = Math.ceil(floatscaledheight);
23927
var absscaledwidth = Math.abs(scaledwidth);
23928
var absscaledheight = Math.abs(scaledheight);
23929
var halfw = this.runtime.draw_width / 2;
23930
var halfh = this.runtime.draw_height / 2;
23931
if (!this.myctx)
23932
{
23933
this.mycanvas = document.createElement("canvas");
23934
this.mycanvas.width = absscaledwidth;
23935
this.mycanvas.height = absscaledheight;
23936
this.lastwidth = absscaledwidth;
23937
this.lastheight = absscaledheight;
23938
need_redraw = true;
23939
this.myctx = this.mycanvas.getContext("2d");
23940
}
23941
if (absscaledwidth !== this.lastwidth || absscaledheight !== this.lastheight)
23942
{
23943
this.mycanvas.width = absscaledwidth;
23944
this.mycanvas.height = absscaledheight;
23945
if (this.mytex)
23946
{
23947
glw.deleteTexture(this.mytex);
23948
this.mytex = null;
23949
}
23950
need_redraw = true;
23951
}
23952
if (need_redraw)
23953
{
23954
this.myctx.clearRect(0, 0, absscaledwidth, absscaledheight);
23955
this.draw(this.myctx, true);
23956
if (!this.mytex)
23957
this.mytex = glw.createEmptyTexture(absscaledwidth, absscaledheight, this.runtime.linearSampling, this.runtime.isMobile);
23958
glw.videoToTexture(this.mycanvas, this.mytex, this.runtime.isMobile);
23959
}
23960
this.lastwidth = absscaledwidth;
23961
this.lastheight = absscaledheight;
23962
glw.setTexture(this.mytex);
23963
glw.setOpacity(this.opacity);
23964
glw.resetModelView();
23965
glw.translate(-halfw, -halfh);
23966
glw.updateModelView();
23967
var q = this.bquad;
23968
var tlx = this.layer.layerToCanvas(q.tlx, q.tly, true, true);
23969
var tly = this.layer.layerToCanvas(q.tlx, q.tly, false, true);
23970
var trx = this.layer.layerToCanvas(q.trx, q.try_, true, true);
23971
var try_ = this.layer.layerToCanvas(q.trx, q.try_, false, true);
23972
var brx = this.layer.layerToCanvas(q.brx, q.bry, true, true);
23973
var bry = this.layer.layerToCanvas(q.brx, q.bry, false, true);
23974
var blx = this.layer.layerToCanvas(q.blx, q.bly, true, true);
23975
var bly = this.layer.layerToCanvas(q.blx, q.bly, false, true);
23976
if (this.runtime.pixel_rounding || (this.angle === 0 && layer_angle === 0))
23977
{
23978
var ox = ((tlx + 0.5) | 0) - tlx;
23979
var oy = ((tly + 0.5) | 0) - tly
23980
tlx += ox;
23981
tly += oy;
23982
trx += ox;
23983
try_ += oy;
23984
brx += ox;
23985
bry += oy;
23986
blx += ox;
23987
bly += oy;
23988
}
23989
if (this.angle === 0 && layer_angle === 0)
23990
{
23991
trx = tlx + scaledwidth;
23992
try_ = tly;
23993
brx = trx;
23994
bry = tly + scaledheight;
23995
blx = tlx;
23996
bly = bry;
23997
rcTex.right = 1;
23998
rcTex.bottom = 1;
23999
}
24000
else
24001
{
24002
rcTex.right = floatscaledwidth / scaledwidth;
24003
rcTex.bottom = floatscaledheight / scaledheight;
24004
}
24005
glw.quadTex(tlx, tly, trx, try_, brx, bry, blx, bly, rcTex);
24006
glw.resetModelView();
24007
glw.scale(layer_scale, layer_scale);
24008
glw.rotateZ(-this.layer.getAngle());
24009
glw.translate((this.layer.viewLeft + this.layer.viewRight) / -2, (this.layer.viewTop + this.layer.viewBottom) / -2);
24010
glw.updateModelView();
24011
this.last_render_tick = this.runtime.tickcount;
24012
};
24013
var wordsCache = [];
24014
pluginProto.TokeniseWords = function (text)
24015
{
24016
cr.clearArray(wordsCache);
24017
var cur_word = "";
24018
var ch;
24019
var i = 0;
24020
while (i < text.length)
24021
{
24022
ch = text.charAt(i);
24023
if (ch === "\n")
24024
{
24025
if (cur_word.length)
24026
{
24027
wordsCache.push(cur_word);
24028
cur_word = "";
24029
}
24030
wordsCache.push("\n");
24031
++i;
24032
}
24033
else if (ch === " " || ch === "\t" || ch === "-")
24034
{
24035
do {
24036
cur_word += text.charAt(i);
24037
i++;
24038
}
24039
while (i < text.length && (text.charAt(i) === " " || text.charAt(i) === "\t"));
24040
wordsCache.push(cur_word);
24041
cur_word = "";
24042
}
24043
else if (i < text.length)
24044
{
24045
cur_word += ch;
24046
i++;
24047
}
24048
}
24049
if (cur_word.length)
24050
wordsCache.push(cur_word);
24051
};
24052
var linesCache = [];
24053
function allocLine()
24054
{
24055
if (linesCache.length)
24056
return linesCache.pop();
24057
else
24058
return {};
24059
};
24060
function freeLine(l)
24061
{
24062
linesCache.push(l);
24063
};
24064
function freeAllLines(arr)
24065
{
24066
var i, len;
24067
for (i = 0, len = arr.length; i < len; i++)
24068
{
24069
freeLine(arr[i]);
24070
}
24071
cr.clearArray(arr);
24072
};
24073
pluginProto.WordWrap = function (text, lines, ctx, width, wrapbyword)
24074
{
24075
if (!text || !text.length)
24076
{
24077
freeAllLines(lines);
24078
return;
24079
}
24080
if (width <= 2.0)
24081
{
24082
freeAllLines(lines);
24083
return;
24084
}
24085
if (text.length <= 100 && text.indexOf("\n") === -1)
24086
{
24087
var all_width = ctx.measureText(text).width;
24088
if (all_width <= width)
24089
{
24090
freeAllLines(lines);
24091
lines.push(allocLine());
24092
lines[0].text = text;
24093
lines[0].width = all_width;
24094
return;
24095
}
24096
}
24097
this.WrapText(text, lines, ctx, width, wrapbyword);
24098
};
24099
function trimSingleSpaceRight(str)
24100
{
24101
if (!str.length || str.charAt(str.length - 1) !== " ")
24102
return str;
24103
return str.substring(0, str.length - 1);
24104
};
24105
pluginProto.WrapText = function (text, lines, ctx, width, wrapbyword)
24106
{
24107
var wordArray;
24108
if (wrapbyword)
24109
{
24110
this.TokeniseWords(text); // writes to wordsCache
24111
wordArray = wordsCache;
24112
}
24113
else
24114
wordArray = text;
24115
var cur_line = "";
24116
var prev_line;
24117
var line_width;
24118
var i;
24119
var lineIndex = 0;
24120
var line;
24121
for (i = 0; i < wordArray.length; i++)
24122
{
24123
if (wordArray[i] === "\n")
24124
{
24125
if (lineIndex >= lines.length)
24126
lines.push(allocLine());
24127
cur_line = trimSingleSpaceRight(cur_line); // for correct center/right alignment
24128
line = lines[lineIndex];
24129
line.text = cur_line;
24130
line.width = ctx.measureText(cur_line).width;
24131
lineIndex++;
24132
cur_line = "";
24133
continue;
24134
}
24135
prev_line = cur_line;
24136
cur_line += wordArray[i];
24137
line_width = ctx.measureText(cur_line).width;
24138
if (line_width >= width)
24139
{
24140
if (lineIndex >= lines.length)
24141
lines.push(allocLine());
24142
prev_line = trimSingleSpaceRight(prev_line);
24143
line = lines[lineIndex];
24144
line.text = prev_line;
24145
line.width = ctx.measureText(prev_line).width;
24146
lineIndex++;
24147
cur_line = wordArray[i];
24148
if (!wrapbyword && cur_line === " ")
24149
cur_line = "";
24150
}
24151
}
24152
if (cur_line.length)
24153
{
24154
if (lineIndex >= lines.length)
24155
lines.push(allocLine());
24156
cur_line = trimSingleSpaceRight(cur_line);
24157
line = lines[lineIndex];
24158
line.text = cur_line;
24159
line.width = ctx.measureText(cur_line).width;
24160
lineIndex++;
24161
}
24162
for (i = lineIndex; i < lines.length; i++)
24163
freeLine(lines[i]);
24164
lines.length = lineIndex;
24165
};
24166
function Cnds() {};
24167
Cnds.prototype.CompareText = function(text_to_compare, case_sensitive)
24168
{
24169
if (case_sensitive)
24170
return this.text == text_to_compare;
24171
else
24172
return cr.equals_nocase(this.text, text_to_compare);
24173
};
24174
pluginProto.cnds = new Cnds();
24175
function Acts() {};
24176
Acts.prototype.SetText = function(param)
24177
{
24178
if (cr.is_number(param) && param < 1e9)
24179
param = Math.round(param * 1e10) / 1e10; // round to nearest ten billionth - hides floating point errors
24180
var text_to_set = param.toString();
24181
if (this.text !== text_to_set)
24182
{
24183
this.text = text_to_set;
24184
this.text_changed = true;
24185
this.runtime.redraw = true;
24186
}
24187
};
24188
Acts.prototype.AppendText = function(param)
24189
{
24190
if (cr.is_number(param))
24191
param = Math.round(param * 1e10) / 1e10; // round to nearest ten billionth - hides floating point errors
24192
var text_to_append = param.toString();
24193
if (text_to_append) // not empty
24194
{
24195
this.text += text_to_append;
24196
this.text_changed = true;
24197
this.runtime.redraw = true;
24198
}
24199
};
24200
Acts.prototype.SetFontFace = function (face_, style_)
24201
{
24202
var newstyle = "";
24203
switch (style_) {
24204
case 1: newstyle = "bold"; break;
24205
case 2: newstyle = "italic"; break;
24206
case 3: newstyle = "bold italic"; break;
24207
}
24208
if (face_ === this.facename && newstyle === this.fontstyle)
24209
return; // no change
24210
this.facename = face_;
24211
this.fontstyle = newstyle;
24212
this.updateFont();
24213
};
24214
Acts.prototype.SetFontSize = function (size_)
24215
{
24216
if (this.ptSize === size_)
24217
return;
24218
this.ptSize = size_;
24219
this.pxHeight = Math.ceil((this.ptSize / 72.0) * 96.0) + 4; // assume 96dpi...
24220
this.updateFont();
24221
};
24222
Acts.prototype.SetFontColor = function (rgb)
24223
{
24224
var newcolor = "rgb(" + cr.GetRValue(rgb).toString() + "," + cr.GetGValue(rgb).toString() + "," + cr.GetBValue(rgb).toString() + ")";
24225
if (newcolor === this.color)
24226
return;
24227
this.color = newcolor;
24228
this.need_text_redraw = true;
24229
this.runtime.redraw = true;
24230
};
24231
Acts.prototype.SetWebFont = function (familyname_, cssurl_)
24232
{
24233
if (this.runtime.isDomFree)
24234
{
24235
cr.logexport("[Construct 2] Text plugin: 'Set web font' not supported on this platform - the action has been ignored");
24236
return; // DC todo
24237
}
24238
var self = this;
24239
var refreshFunc = (function () {
24240
self.runtime.redraw = true;
24241
self.text_changed = true;
24242
});
24243
if (requestedWebFonts.hasOwnProperty(cssurl_))
24244
{
24245
var newfacename = "'" + familyname_ + "'";
24246
if (this.facename === newfacename)
24247
return; // no change
24248
this.facename = newfacename;
24249
this.updateFont();
24250
for (var i = 1; i < 10; i++)
24251
{
24252
setTimeout(refreshFunc, i * 100);
24253
setTimeout(refreshFunc, i * 1000);
24254
}
24255
return;
24256
}
24257
var wf = document.createElement("link");
24258
wf.href = cssurl_;
24259
wf.rel = "stylesheet";
24260
wf.type = "text/css";
24261
wf.onload = refreshFunc;
24262
document.getElementsByTagName('head')[0].appendChild(wf);
24263
requestedWebFonts[cssurl_] = true;
24264
this.facename = "'" + familyname_ + "'";
24265
this.updateFont();
24266
for (var i = 1; i < 10; i++)
24267
{
24268
setTimeout(refreshFunc, i * 100);
24269
setTimeout(refreshFunc, i * 1000);
24270
}
24271
;
24272
};
24273
Acts.prototype.SetEffect = function (effect)
24274
{
24275
this.blend_mode = effect;
24276
this.compositeOp = cr.effectToCompositeOp(effect);
24277
cr.setGLBlend(this, effect, this.runtime.gl);
24278
this.runtime.redraw = true;
24279
};
24280
pluginProto.acts = new Acts();
24281
function Exps() {};
24282
Exps.prototype.Text = function(ret)
24283
{
24284
ret.set_string(this.text);
24285
};
24286
Exps.prototype.FaceName = function (ret)
24287
{
24288
ret.set_string(this.facename);
24289
};
24290
Exps.prototype.FaceSize = function (ret)
24291
{
24292
ret.set_int(this.ptSize);
24293
};
24294
Exps.prototype.TextWidth = function (ret)
24295
{
24296
var w = 0;
24297
var i, len, x;
24298
for (i = 0, len = this.lines.length; i < len; i++)
24299
{
24300
x = this.lines[i].width;
24301
if (w < x)
24302
w = x;
24303
}
24304
ret.set_int(w);
24305
};
24306
Exps.prototype.TextHeight = function (ret)
24307
{
24308
ret.set_int(this.lines.length * (this.pxHeight + this.line_height_offset) - this.line_height_offset);
24309
};
24310
pluginProto.exps = new Exps();
24311
}());
24312
;
24313
;
24314
cr.plugins_.TiledBg = function(runtime)
24315
{
24316
this.runtime = runtime;
24317
};
24318
(function ()
24319
{
24320
var pluginProto = cr.plugins_.TiledBg.prototype;
24321
pluginProto.Type = function(plugin)
24322
{
24323
this.plugin = plugin;
24324
this.runtime = plugin.runtime;
24325
};
24326
var typeProto = pluginProto.Type.prototype;
24327
typeProto.onCreate = function()
24328
{
24329
if (this.is_family)
24330
return;
24331
this.texture_img = new Image();
24332
this.texture_img.cr_filesize = this.texture_filesize;
24333
this.runtime.waitForImageLoad(this.texture_img, this.texture_file);
24334
this.pattern = null;
24335
this.webGL_texture = null;
24336
};
24337
typeProto.onLostWebGLContext = function ()
24338
{
24339
if (this.is_family)
24340
return;
24341
this.webGL_texture = null;
24342
};
24343
typeProto.onRestoreWebGLContext = function ()
24344
{
24345
if (this.is_family || !this.instances.length)
24346
return;
24347
if (!this.webGL_texture)
24348
{
24349
this.webGL_texture = this.runtime.glwrap.loadTexture(this.texture_img, true, this.runtime.linearSampling, this.texture_pixelformat);
24350
}
24351
var i, len;
24352
for (i = 0, len = this.instances.length; i < len; i++)
24353
this.instances[i].webGL_texture = this.webGL_texture;
24354
};
24355
typeProto.loadTextures = function ()
24356
{
24357
if (this.is_family || this.webGL_texture || !this.runtime.glwrap)
24358
return;
24359
this.webGL_texture = this.runtime.glwrap.loadTexture(this.texture_img, true, this.runtime.linearSampling, this.texture_pixelformat);
24360
};
24361
typeProto.unloadTextures = function ()
24362
{
24363
if (this.is_family || this.instances.length || !this.webGL_texture)
24364
return;
24365
this.runtime.glwrap.deleteTexture(this.webGL_texture);
24366
this.webGL_texture = null;
24367
};
24368
typeProto.preloadCanvas2D = function (ctx)
24369
{
24370
ctx.drawImage(this.texture_img, 0, 0);
24371
};
24372
pluginProto.Instance = function(type)
24373
{
24374
this.type = type;
24375
this.runtime = type.runtime;
24376
};
24377
var instanceProto = pluginProto.Instance.prototype;
24378
instanceProto.onCreate = function()
24379
{
24380
this.visible = (this.properties[0] === 0); // 0=visible, 1=invisible
24381
this.rcTex = new cr.rect(0, 0, 0, 0);
24382
this.has_own_texture = false; // true if a texture loaded in from URL
24383
this.texture_img = this.type.texture_img;
24384
if (this.runtime.glwrap)
24385
{
24386
this.type.loadTextures();
24387
this.webGL_texture = this.type.webGL_texture;
24388
}
24389
else
24390
{
24391
if (!this.type.pattern)
24392
this.type.pattern = this.runtime.ctx.createPattern(this.type.texture_img, "repeat");
24393
this.pattern = this.type.pattern;
24394
}
24395
};
24396
instanceProto.afterLoad = function ()
24397
{
24398
this.has_own_texture = false;
24399
this.texture_img = this.type.texture_img;
24400
};
24401
instanceProto.onDestroy = function ()
24402
{
24403
if (this.runtime.glwrap && this.has_own_texture && this.webGL_texture)
24404
{
24405
this.runtime.glwrap.deleteTexture(this.webGL_texture);
24406
this.webGL_texture = null;
24407
}
24408
};
24409
instanceProto.draw = function(ctx)
24410
{
24411
ctx.globalAlpha = this.opacity;
24412
ctx.save();
24413
ctx.fillStyle = this.pattern;
24414
var myx = this.x;
24415
var myy = this.y;
24416
if (this.runtime.pixel_rounding)
24417
{
24418
myx = Math.round(myx);
24419
myy = Math.round(myy);
24420
}
24421
var drawX = -(this.hotspotX * this.width);
24422
var drawY = -(this.hotspotY * this.height);
24423
var offX = drawX % this.texture_img.width;
24424
var offY = drawY % this.texture_img.height;
24425
if (offX < 0)
24426
offX += this.texture_img.width;
24427
if (offY < 0)
24428
offY += this.texture_img.height;
24429
ctx.translate(myx, myy);
24430
ctx.rotate(this.angle);
24431
ctx.translate(offX, offY);
24432
ctx.fillRect(drawX - offX,
24433
drawY - offY,
24434
this.width,
24435
this.height);
24436
ctx.restore();
24437
};
24438
instanceProto.drawGL_earlyZPass = function(glw)
24439
{
24440
this.drawGL(glw);
24441
};
24442
instanceProto.drawGL = function(glw)
24443
{
24444
glw.setTexture(this.webGL_texture);
24445
glw.setOpacity(this.opacity);
24446
var rcTex = this.rcTex;
24447
rcTex.right = this.width / this.texture_img.width;
24448
rcTex.bottom = this.height / this.texture_img.height;
24449
var q = this.bquad;
24450
if (this.runtime.pixel_rounding)
24451
{
24452
var ox = Math.round(this.x) - this.x;
24453
var oy = Math.round(this.y) - this.y;
24454
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, rcTex);
24455
}
24456
else
24457
glw.quadTex(q.tlx, q.tly, q.trx, q.try_, q.brx, q.bry, q.blx, q.bly, rcTex);
24458
};
24459
function Cnds() {};
24460
Cnds.prototype.OnURLLoaded = function ()
24461
{
24462
return true;
24463
};
24464
pluginProto.cnds = new Cnds();
24465
function Acts() {};
24466
Acts.prototype.SetEffect = function (effect)
24467
{
24468
this.blend_mode = effect;
24469
this.compositeOp = cr.effectToCompositeOp(effect);
24470
cr.setGLBlend(this, effect, this.runtime.gl);
24471
this.runtime.redraw = true;
24472
};
24473
Acts.prototype.LoadURL = function (url_, crossOrigin_)
24474
{
24475
var img = new Image();
24476
var self = this;
24477
img.onload = function ()
24478
{
24479
self.texture_img = img;
24480
if (self.runtime.glwrap)
24481
{
24482
if (self.has_own_texture && self.webGL_texture)
24483
self.runtime.glwrap.deleteTexture(self.webGL_texture);
24484
self.webGL_texture = self.runtime.glwrap.loadTexture(img, true, self.runtime.linearSampling);
24485
}
24486
else
24487
{
24488
self.pattern = self.runtime.ctx.createPattern(img, "repeat");
24489
}
24490
self.has_own_texture = true;
24491
self.runtime.redraw = true;
24492
self.runtime.trigger(cr.plugins_.TiledBg.prototype.cnds.OnURLLoaded, self);
24493
};
24494
if (url_.substr(0, 5) !== "data:" && crossOrigin_ === 0)
24495
img.crossOrigin = "anonymous";
24496
this.runtime.setImageSrc(img, url_);
24497
};
24498
pluginProto.acts = new Acts();
24499
function Exps() {};
24500
Exps.prototype.ImageWidth = function (ret)
24501
{
24502
ret.set_float(this.texture_img.width);
24503
};
24504
Exps.prototype.ImageHeight = function (ret)
24505
{
24506
ret.set_float(this.texture_img.height);
24507
};
24508
pluginProto.exps = new Exps();
24509
}());
24510
;
24511
;
24512
cr.plugins_.Tilemap = function(runtime)
24513
{
24514
this.runtime = runtime;
24515
};
24516
(function ()
24517
{
24518
var pluginProto = cr.plugins_.Tilemap.prototype;
24519
pluginProto.Type = function(plugin)
24520
{
24521
this.plugin = plugin;
24522
this.runtime = plugin.runtime;
24523
};
24524
var typeProto = pluginProto.Type.prototype;
24525
typeProto.onCreate = function()
24526
{
24527
var i, len, p;
24528
if (this.is_family)
24529
return;
24530
this.texture_img = new Image();
24531
this.texture_img.cr_filesize = this.texture_filesize;
24532
this.runtime.waitForImageLoad(this.texture_img, this.texture_file);
24533
this.cut_tiles = [];
24534
this.cut_tiles_valid = false;
24535
this.tile_polys = [];
24536
this.tile_polys_cached = false; // first instance will cache polys with the tile width/height
24537
if (this.tile_poly_data && this.tile_poly_data.length)
24538
{
24539
for (i = 0, len = this.tile_poly_data.length; i < len; ++i)
24540
{
24541
p = this.tile_poly_data[i];
24542
if (p)
24543
{
24544
this.tile_polys.push({
24545
poly: p,
24546
flipmap: [[[null, null], [null, null]], [[null, null], [null, null]]]
24547
});
24548
}
24549
else
24550
this.tile_polys.push(null);
24551
}
24552
}
24553
};
24554
typeProto.cacheTilePoly = function (tileid, tilewidth, tileheight, fliph, flipv, flipd)
24555
{
24556
if (tileid < 0 || tileid >= this.tile_polys.length)
24557
return;
24558
if (!this.tile_polys[tileid])
24559
return; // no poly for this tile
24560
var poly = this.tile_polys[tileid].poly;
24561
var flipmap = this.tile_polys[tileid].flipmap;
24562
var cached_poly = new cr.CollisionPoly(poly);
24563
cached_poly.cache_poly(tilewidth, tileheight, 0);
24564
if (flipd)
24565
cached_poly.diag();
24566
if (fliph)
24567
cached_poly.mirror(tilewidth / 2);
24568
if (flipv)
24569
cached_poly.flip(tileheight / 2);
24570
flipmap[fliph?1:0][flipv?1:0][flipd?1:0] = cached_poly;
24571
};
24572
typeProto.getTilePoly = function (id)
24573
{
24574
if (id === -1)
24575
return null;
24576
var tileid = (id & TILE_ID_MASK);
24577
if (tileid < 0 || tileid >= this.tile_polys.length)
24578
return null; // out of range
24579
if (!this.tile_polys[tileid])
24580
return null; // no poly for this tile
24581
var fliph = (id & TILE_FLIPPED_HORIZONTAL) ? 1 : 0;
24582
var flipv = (id & TILE_FLIPPED_VERTICAL) ? 1 : 0;
24583
var flipd = (id & TILE_FLIPPED_DIAGONAL) ? 1 : 0;
24584
return this.tile_polys[tileid].flipmap[fliph][flipv][flipd];
24585
};
24586
typeProto.freeCutTiles = function ()
24587
{
24588
var i, len;
24589
var glwrap = this.runtime.glwrap;
24590
if (glwrap)
24591
{
24592
for (i = 0, len = this.cut_tiles.length; i < len; ++i)
24593
glwrap.deleteTexture(this.cut_tiles[i]);
24594
}
24595
cr.clearArray(this.cut_tiles);
24596
this.cut_tiles_valid = false;
24597
}
24598
typeProto.maybeCutTiles = function (tw, th, offx, offy, sepx, sepy, seamless)
24599
{
24600
if (this.cut_tiles_valid)
24601
return; // no changed
24602
if (tw <= 0 || th <= 0)
24603
return;
24604
this.freeCutTiles();
24605
var img_width = this.texture_img.width;
24606
var img_height = this.texture_img.height;
24607
var x, y;
24608
for (y = offy; y + th <= img_height; y += (th + sepy))
24609
{
24610
for (x = offx; x + tw <= img_width; x += (tw + sepx))
24611
{
24612
this.cut_tiles.push(this.CutTileImage(x, y, tw, th, seamless));
24613
}
24614
}
24615
this.cut_tiles_valid = true;
24616
};
24617
typeProto.CutTileImage = function(x, y, w, h, seamless)
24618
{
24619
if (this.runtime.glwrap)
24620
{
24621
return this.DoCutTileImage(x, y, w, h, false, false, false, seamless);
24622
}
24623
else
24624
{
24625
var flipmap = [[[null, null], [null, null]], [[null, null], [null, null]]];
24626
flipmap[0][0][0] = this.DoCutTileImage(x, y, w, h, false, false, false, seamless);
24627
return {
24628
flipmap: flipmap,
24629
x: x,
24630
y: y,
24631
w: w,
24632
h: h
24633
};
24634
}
24635
};
24636
typeProto.GetFlippedTileImage = function (tileid, fliph, flipv, flipd, seamless)
24637
{
24638
if (tileid < 0 || tileid >= this.cut_tiles.length)
24639
return null;
24640
var tile = this.cut_tiles[tileid];
24641
var flipmap = tile.flipmap;
24642
var hi = (fliph ? 1 : 0);
24643
var vi = (flipv ? 1 : 0);
24644
var di = (flipd ? 1 : 0);
24645
var ret = flipmap[hi][vi][di];
24646
if (ret)
24647
{
24648
return ret;
24649
}
24650
else
24651
{
24652
ret = this.DoCutTileImage(tile.x, tile.y, tile.w, tile.h, hi!==0, vi!==0, di!==0, seamless);
24653
flipmap[hi][vi][di] = ret;
24654
return ret;
24655
}
24656
};
24657
typeProto.DoCutTileImage = function(x, y, w, h, fliph, flipv, flipd, seamless)
24658
{
24659
var dw = w;
24660
var dh = h;
24661
if (this.runtime.glwrap && !seamless)
24662
{
24663
if (!cr.isPOT(dw))
24664
dw = cr.nextHighestPowerOfTwo(dw);
24665
if (!cr.isPOT(dh))
24666
dh = cr.nextHighestPowerOfTwo(dh);
24667
}
24668
var tmpcanvas = document.createElement("canvas");
24669
tmpcanvas.width = dw;
24670
tmpcanvas.height = dh;
24671
var tmpctx = tmpcanvas.getContext("2d");
24672
if (this.runtime.ctx)
24673
{
24674
if (fliph)
24675
{
24676
if (flipv)
24677
{
24678
if (flipd)
24679
{
24680
tmpctx.rotate(Math.PI / 2);
24681
tmpctx.scale(-1, 1);
24682
tmpctx.translate(-dw, -dh);
24683
}
24684
else
24685
{
24686
tmpctx.scale(-1, -1);
24687
tmpctx.translate(-dw, -dh);
24688
}
24689
}
24690
else
24691
{
24692
if (flipd)
24693
{
24694
tmpctx.rotate(Math.PI / 2);
24695
tmpctx.translate(0, -dh);
24696
}
24697
else
24698
{
24699
tmpctx.scale(-1, 1);
24700
tmpctx.translate(-dw, 0);
24701
}
24702
}
24703
}
24704
else
24705
{
24706
if (flipv)
24707
{
24708
if (flipd)
24709
{
24710
tmpctx.rotate(-Math.PI / 2);
24711
tmpctx.translate(-dw, 0);
24712
}
24713
else
24714
{
24715
tmpctx.scale(1, -1);
24716
tmpctx.translate(0, -dh);
24717
}
24718
}
24719
else
24720
{
24721
if (flipd)
24722
{
24723
tmpctx.scale(-1, 1);
24724
tmpctx.rotate(Math.PI / 2);
24725
}
24726
}
24727
}
24728
tmpctx.drawImage(this.texture_img, x, y, w, h, 0, 0, dw, dh);
24729
if (seamless)
24730
return tmpcanvas;
24731
else
24732
return this.runtime.ctx.createPattern(tmpcanvas, "repeat");
24733
}
24734
else
24735
{
24736
;
24737
tmpctx.drawImage(this.texture_img, x, y, w, h, 0, 0, dw, dh);
24738
var tex = this.runtime.glwrap.createEmptyTexture(dw, dh, this.runtime.linearSampling, false, !seamless);
24739
this.runtime.glwrap.videoToTexture(tmpcanvas, tex);
24740
return tex;
24741
}
24742
};
24743
typeProto.onLostWebGLContext = function ()
24744
{
24745
if (this.is_family)
24746
return;
24747
this.freeCutTiles();
24748
};
24749
typeProto.onRestoreWebGLContext = function ()
24750
{
24751
};
24752
typeProto.loadTextures = function ()
24753
{
24754
};
24755
typeProto.unloadTextures = function ()
24756
{
24757
if (this.is_family || this.instances.length)
24758
return;
24759
this.freeCutTiles();
24760
};
24761
typeProto.preloadCanvas2D = function (ctx)
24762
{
24763
};
24764
pluginProto.Instance = function(type)
24765
{
24766
this.type = type;
24767
this.runtime = type.runtime;
24768
};
24769
var instanceProto = pluginProto.Instance.prototype;
24770
var TILE_FLIPPED_HORIZONTAL = -0x80000000 // note: pretend is a signed int, so negate
24771
var TILE_FLIPPED_VERTICAL = 0x40000000
24772
var TILE_FLIPPED_DIAGONAL = 0x20000000
24773
var TILE_FLAGS_MASK = 0xE0000000
24774
var TILE_ID_MASK = 0x1FFFFFFF
24775
function TileQuad()
24776
{
24777
this.id = -1;
24778
this.tileid = -1;
24779
this.horiz_flip = false;
24780
this.vert_flip = false;
24781
this.diag_flip = false;
24782
this.any_flip = false;
24783
this.rc = new cr.rect(0, 0, 0, 0);
24784
};
24785
var tilequad_cache = [];
24786
function allocTileQuad()
24787
{
24788
if (tilequad_cache.length)
24789
return tilequad_cache.pop();
24790
else
24791
return new TileQuad();
24792
};
24793
function freeTileQuad(tq)
24794
{
24795
if (tilequad_cache.length < 10000)
24796
tilequad_cache.push(tq);
24797
};
24798
function TileCollisionRect()
24799
{
24800
this.id = -1;
24801
this.rc = new cr.rect(0, 0, 0, 0);
24802
this.poly = null;
24803
}
24804
var collrect_cache = [];
24805
function allocCollRect()
24806
{
24807
if (collrect_cache.length)
24808
return collrect_cache.pop();
24809
else
24810
return new TileCollisionRect();
24811
};
24812
function freeCollRect(r)
24813
{
24814
if (collrect_cache.length < 10000)
24815
collrect_cache.push(r);
24816
};
24817
var tile_cell_cache = [];
24818
function allocTileCell(inst_, x_, y_)
24819
{
24820
var ret;
24821
if (tile_cell_cache.length)
24822
{
24823
ret = tile_cell_cache.pop();
24824
ret.inst = inst_;
24825
ret.x = x_;
24826
ret.y = y_;
24827
ret.left = ret.x * ret.inst.cellwidth * ret.inst.tilewidth;
24828
ret.top = ret.y * ret.inst.cellheight * ret.inst.tileheight;
24829
ret.clear();
24830
ret.quadmap_valid = false;
24831
return ret;
24832
}
24833
else
24834
return new TileCell(inst_, x_, y_);
24835
};
24836
function freeTileCell(tc)
24837
{
24838
var i, len;
24839
for (i = 0, len = tc.quads.length; i < len; ++i)
24840
freeTileQuad(tc.quads[i]);
24841
cr.clearArray(tc.quads);
24842
for (i = 0, len = tc.collision_rects.length; i < len; ++i)
24843
freeCollRect(tc.collision_rects[i]);
24844
cr.clearArray(tc.collision_rects);
24845
if (tile_cell_cache.length < 1000)
24846
tile_cell_cache.push(tc);
24847
};
24848
function TileCell(inst_, x_, y_)
24849
{
24850
this.inst = inst_;
24851
this.x = x_;
24852
this.y = y_;
24853
this.left = this.x * this.inst.cellwidth * this.inst.tilewidth;
24854
this.top = this.y * this.inst.cellheight * this.inst.tileheight;
24855
this.tiles = [];
24856
this.quads = [];
24857
this.collision_rects = [];
24858
this.quadmap_valid = false;
24859
var i, len, j, lenj, arr;
24860
for (i = 0, len = this.inst.cellheight; i < len; ++i)
24861
{
24862
arr = [];
24863
for (j = 0, lenj = this.inst.cellwidth; j < lenj; ++j)
24864
arr.push(-1);
24865
this.tiles.push(arr);
24866
}
24867
};
24868
TileCell.prototype.clear = function ()
24869
{
24870
var i, len, j, lenj, arr;
24871
this.tiles.length = this.inst.cellheight;
24872
for (i = 0, len = this.tiles.length; i < len; ++i)
24873
{
24874
arr = this.tiles[i];
24875
if (!arr)
24876
{
24877
arr = [];
24878
this.tiles[i] = arr;
24879
}
24880
arr.length = this.inst.cellwidth;
24881
for (j = 0, lenj = arr.length; j < lenj; ++j)
24882
arr[j] = -1;
24883
}
24884
};
24885
TileCell.prototype.maybeBuildQuadMap = function ()
24886
{
24887
if (this.quadmap_valid)
24888
return; // not changed
24889
var tilewidth = this.inst.tilewidth;
24890
var tileheight = this.inst.tileheight;
24891
if (tilewidth <= 0 || tileheight <= 0)
24892
return;
24893
var i, j, len, y, leny, x, lenx, arr, t, p, q;
24894
for (i = 0, len = this.quads.length; i < len; ++i)
24895
freeTileQuad(this.quads[i]);
24896
for (i = 0, len = this.collision_rects.length; i < len; ++i)
24897
freeCollRect(this.collision_rects[i]);
24898
cr.clearArray(this.quads);
24899
cr.clearArray(this.collision_rects);
24900
var extentwidth = Math.min(this.inst.mapwidth, Math.floor(this.inst.width / tilewidth));
24901
var extentheight = Math.min(this.inst.mapheight, Math.floor(this.inst.height / tileheight));
24902
extentwidth -= this.left / tilewidth;
24903
extentheight -= this.top / tileheight;
24904
if (extentwidth > this.inst.cellwidth)
24905
extentwidth = this.inst.cellwidth;
24906
if (extentheight > this.inst.cellheight)
24907
extentheight = this.inst.cellheight;
24908
var seamless = this.inst.seamless;
24909
var cur_quad = null;
24910
for (y = 0, leny = extentheight; y < leny; ++y)
24911
{
24912
arr = this.tiles[y];
24913
for (x = 0, lenx = extentwidth; x < lenx; ++x)
24914
{
24915
t = arr[x];
24916
if (t === -1)
24917
{
24918
if (cur_quad)
24919
{
24920
this.quads.push(cur_quad);
24921
cur_quad = null;
24922
}
24923
continue;
24924
}
24925
if (seamless || !cur_quad || t !== cur_quad.id)
24926
{
24927
if (cur_quad)
24928
this.quads.push(cur_quad);
24929
cur_quad = allocTileQuad();
24930
cur_quad.id = t;
24931
cur_quad.tileid = (t & TILE_ID_MASK);
24932
cur_quad.horiz_flip = (t & TILE_FLIPPED_HORIZONTAL) !== 0;
24933
cur_quad.vert_flip = (t & TILE_FLIPPED_VERTICAL) !== 0;
24934
cur_quad.diag_flip = (t & TILE_FLIPPED_DIAGONAL) !== 0;
24935
cur_quad.any_flip = (cur_quad.horiz_flip || cur_quad.vert_flip || cur_quad.diag_flip);
24936
cur_quad.rc.left = x * tilewidth + this.left;
24937
cur_quad.rc.top = y * tileheight + this.top;
24938
cur_quad.rc.right = cur_quad.rc.left + tilewidth;
24939
cur_quad.rc.bottom = cur_quad.rc.top + tileheight;
24940
}
24941
else
24942
{
24943
cur_quad.rc.right += tilewidth;
24944
}
24945
}
24946
if (cur_quad)
24947
{
24948
this.quads.push(cur_quad);
24949
cur_quad = null;
24950
}
24951
}
24952
var cur_rect = null;
24953
var tileid, tilepoly;
24954
var cur_has_poly = false;
24955
var rc;
24956
for (y = 0, leny = extentheight; y < leny; ++y)
24957
{
24958
arr = this.tiles[y];
24959
for (x = 0, lenx = extentwidth; x < lenx; ++x)
24960
{
24961
t = arr[x];
24962
if (t === -1)
24963
{
24964
if (cur_rect)
24965
{
24966
this.collision_rects.push(cur_rect);
24967
cur_rect = null;
24968
cur_has_poly = false;
24969
}
24970
continue;
24971
}
24972
tileid = (t & TILE_ID_MASK);
24973
tilepoly = this.inst.type.getTilePoly(t);
24974
if (!cur_rect || tilepoly || cur_has_poly)
24975
{
24976
if (cur_rect)
24977
{
24978
this.collision_rects.push(cur_rect);
24979
cur_rect = null;
24980
}
24981
;
24982
cur_rect = allocCollRect();
24983
cur_rect.id = t;
24984
cur_rect.poly = tilepoly ? tilepoly : null;
24985
rc = cur_rect.rc;
24986
rc.left = x * tilewidth + this.left;
24987
rc.top = y * tileheight + this.top;
24988
rc.right = rc.left + tilewidth;
24989
rc.bottom = rc.top + tileheight;
24990
cur_has_poly = !!tilepoly;
24991
}
24992
else
24993
{
24994
cur_rect.rc.right += tilewidth;
24995
}
24996
}
24997
if (cur_rect)
24998
{
24999
this.collision_rects.push(cur_rect);
25000
cur_rect = null;
25001
cur_has_poly = false;
25002
}
25003
}
25004
if (!seamless)
25005
{
25006
len = this.quads.length;
25007
for (i = 0; i < len; ++i)
25008
{
25009
q = this.quads[i];
25010
for (j = i + 1; j < len; ++j)
25011
{
25012
p = this.quads[j];
25013
if (p.rc.top < q.rc.bottom)
25014
continue;
25015
if (p.rc.top > q.rc.bottom)
25016
break;
25017
if (p.rc.right > q.rc.right || p.rc.left > q.rc.left)
25018
break;
25019
if (p.id === q.id && p.rc.left === q.rc.left && p.rc.right === q.rc.right)
25020
{
25021
freeTileQuad(this.quads[j]);
25022
this.quads.splice(j, 1);
25023
--len;
25024
q.rc.bottom += tileheight;
25025
--j; // look at same j index again
25026
}
25027
}
25028
}
25029
}
25030
len = this.collision_rects.length;
25031
var prc, qrc;
25032
for (i = 0; i < len; ++i)
25033
{
25034
q = this.collision_rects[i];
25035
if (q.poly)
25036
continue;
25037
qrc = q.rc;
25038
for (j = i + 1; j < len; ++j)
25039
{
25040
p = this.collision_rects[j];
25041
prc = p.rc;
25042
if (prc.top < qrc.bottom)
25043
continue;
25044
if (prc.top > qrc.bottom)
25045
break;
25046
if (prc.right > qrc.right || prc.left > qrc.left)
25047
break;
25048
if (p.poly)
25049
continue;
25050
if (prc.left === qrc.left && prc.right === qrc.right)
25051
{
25052
freeCollRect(this.collision_rects[j]);
25053
this.collision_rects.splice(j, 1);
25054
--len;
25055
qrc.bottom += tileheight;
25056
--j; // look at same j index again
25057
}
25058
}
25059
}
25060
this.quadmap_valid = true;
25061
};
25062
TileCell.prototype.setTileAt = function (x_, y_, t_)
25063
{
25064
if (this.tiles[y_][x_] !== t_)
25065
{
25066
this.tiles[y_][x_] = t_;
25067
this.quadmap_valid = false;
25068
this.inst.any_quadmap_changed = true;
25069
this.inst.physics_changed = true;
25070
this.inst.runtime.redraw = true;
25071
}
25072
};
25073
instanceProto.onCreate = function()
25074
{
25075
;
25076
var i, len, p;
25077
this.visible = (this.properties[0] === 0);
25078
this.tilewidth = this.properties[1];
25079
this.tileheight = this.properties[2];
25080
this.tilexoffset = this.properties[3];
25081
this.tileyoffset = this.properties[4];
25082
this.tilexspacing = this.properties[5];
25083
this.tileyspacing = this.properties[6];
25084
this.seamless = (this.properties[7] !== 0);
25085
this.mapwidth = this.tilemap_width;
25086
this.mapheight = this.tilemap_height;
25087
this.lastwidth = this.width;
25088
this.lastheight = this.height;
25089
var tw = this.tilewidth;
25090
var th = this.tileheight;
25091
if (tw === 0)
25092
tw = 1;
25093
if (th === 0)
25094
th = 1;
25095
this.cellwidth = Math.ceil(this.runtime.original_width / tw);
25096
this.cellheight = Math.ceil(this.runtime.original_height / th);
25097
if (!this.type.tile_polys_cached)
25098
{
25099
this.type.tile_polys_cached = true;
25100
for (i = 0, len = this.type.tile_polys.length; i < len; ++i)
25101
{
25102
p = this.type.tile_polys[i];
25103
if (!p)
25104
continue;
25105
this.type.cacheTilePoly(i, tw, th, false, false, false);
25106
this.type.cacheTilePoly(i, tw, th, false, false, true);
25107
this.type.cacheTilePoly(i, tw, th, false, true, false);
25108
this.type.cacheTilePoly(i, tw, th, false, true, true);
25109
this.type.cacheTilePoly(i, tw, th, true, false, false);
25110
this.type.cacheTilePoly(i, tw, th, true, false, true);
25111
this.type.cacheTilePoly(i, tw, th, true, true, false);
25112
this.type.cacheTilePoly(i, tw, th, true, true, true);
25113
}
25114
}
25115
if (!this.recycled)
25116
this.tilecells = [];
25117
this.maybeResizeTilemap(true);
25118
this.setTilesFromRLECSV(this.tilemap_data);
25119
this.type.maybeCutTiles(this.tilewidth, this.tileheight, this.tilexoffset, this.tileyoffset, this.tilexspacing, this.tileyspacing, this.seamless);
25120
this.physics_changed = false; // to indicate to physics behavior to recreate body
25121
this.any_quadmap_changed = true;
25122
this.maybeBuildAllQuadMap();
25123
};
25124
instanceProto.maybeBuildAllQuadMap = function ()
25125
{
25126
if (!this.any_quadmap_changed)
25127
return; // no change
25128
var i, len, j, lenj, arr;
25129
for (i = 0, len = this.tilecells.length; i < len; ++i)
25130
{
25131
arr = this.tilecells[i];
25132
for (j = 0, lenj = arr.length; j < lenj; ++j)
25133
{
25134
arr[j].maybeBuildQuadMap();
25135
}
25136
}
25137
this.any_quadmap_changed = false;
25138
};
25139
instanceProto.setAllQuadMapChanged = function ()
25140
{
25141
var i, len, j, lenj, arr;
25142
for (i = 0, len = this.tilecells.length; i < len; ++i)
25143
{
25144
arr = this.tilecells[i];
25145
for (j = 0, lenj = arr.length; j < lenj; ++j)
25146
{
25147
arr[j].quadmap_valid = false;
25148
}
25149
}
25150
this.any_quadmap_changed = true;
25151
};
25152
function RunLengthDecode(str)
25153
{
25154
var ret = [];
25155
var parts = str.split(",");
25156
var i, len, p, x, n, t, part;
25157
for (i = 0, len = parts.length; i < len; ++i)
25158
{
25159
p = parts[i];
25160
x = p.indexOf("x");
25161
if (x > -1)
25162
{
25163
n = parseInt(p.substring(0, x), 10);
25164
part = p.substring(x + 1);
25165
t = parseInt(part, 10);
25166
if (part.indexOf("h") > -1)
25167
t = t | TILE_FLIPPED_HORIZONTAL;
25168
if (part.indexOf("v") > -1)
25169
t = t | TILE_FLIPPED_VERTICAL;
25170
if (part.indexOf("d") > -1)
25171
t = t | TILE_FLIPPED_DIAGONAL;
25172
for ( ; n > 0; --n)
25173
ret.push(t);
25174
}
25175
else
25176
{
25177
t = parseInt(p, 10);
25178
if (p.indexOf("h") > -1)
25179
t = t | TILE_FLIPPED_HORIZONTAL;
25180
if (p.indexOf("v") > -1)
25181
t = t | TILE_FLIPPED_VERTICAL;
25182
if (p.indexOf("d") > -1)
25183
t = t | TILE_FLIPPED_DIAGONAL;
25184
ret.push(t);
25185
}
25186
}
25187
return ret;
25188
};
25189
instanceProto.maybeResizeTilemap = function (force)
25190
{
25191
var curwidth = cr.floor(this.width / this.tilewidth);
25192
var curheight = cr.floor(this.height / this.tileheight);
25193
if (curwidth <= this.mapwidth && curheight <= this.mapheight && !force)
25194
return;
25195
var vcells, hcells;
25196
if (force)
25197
{
25198
vcells = Math.ceil(this.mapheight / this.cellheight);
25199
hcells = Math.ceil(this.mapwidth / this.cellwidth);
25200
}
25201
else
25202
{
25203
vcells = this.tilecells.length;
25204
hcells = Math.ceil(this.mapwidth / this.cellwidth);
25205
if (curheight > this.mapheight)
25206
{
25207
this.mapheight = curheight;
25208
vcells = Math.ceil(this.mapheight / this.cellheight);
25209
}
25210
if (curwidth > this.mapwidth)
25211
{
25212
this.mapwidth = curwidth;
25213
hcells = Math.ceil(this.mapwidth / this.cellwidth);
25214
}
25215
this.setAllQuadMapChanged();
25216
this.physics_changed = true;
25217
this.runtime.redraw = true;
25218
}
25219
var y, x, arr;
25220
for (y = 0; y < vcells; ++y)
25221
{
25222
arr = this.tilecells[y];
25223
if (!arr)
25224
{
25225
arr = [];
25226
for (x = 0; x < hcells; ++x)
25227
arr.push(allocTileCell(this, x, y));
25228
this.tilecells[y] = arr;
25229
}
25230
else
25231
{
25232
for (x = arr.length; x < hcells; ++x)
25233
arr.push(allocTileCell(this, x, y));
25234
}
25235
}
25236
};
25237
instanceProto.cellAt = function (tx, ty)
25238
{
25239
if (tx < 0 || ty < 0)
25240
return null;
25241
var cy = cr.floor(ty / this.cellheight);
25242
if (cy >= this.tilecells.length)
25243
return null;
25244
var row = this.tilecells[cy];
25245
var cx = cr.floor(tx / this.cellwidth);
25246
if (cx >= row.length)
25247
return null;
25248
return row[cx];
25249
};
25250
instanceProto.cellAtIndex = function (cx, cy)
25251
{
25252
if (cx < 0 || cy < 0 || cy >= this.tilecells.length)
25253
return null;
25254
var row = this.tilecells[cy];
25255
if (cx >= row.length)
25256
return null;
25257
return row[cx];
25258
};
25259
instanceProto.setTilesFromRLECSV = function (str)
25260
{
25261
var tilestream = RunLengthDecode(str);
25262
var next = 0;
25263
var y, x, arr, tile, cell;
25264
for (y = 0; y < this.mapheight; ++y)
25265
{
25266
for (x = 0; x < this.mapwidth; ++x)
25267
{
25268
tile = tilestream[next++];
25269
cell = this.cellAt(x, y);
25270
if (cell)
25271
cell.setTileAt(x % this.cellwidth, y % this.cellheight, tile);
25272
}
25273
}
25274
};
25275
instanceProto.getTilesAsRLECSV = function ()
25276
{
25277
var ret = "";
25278
if (this.mapwidth <= 0 || this.mapheight <= 0)
25279
return ret;
25280
var run_count = 1;
25281
var run_number = this.getTileAt(0, 0);
25282
var y, leny, x, lenx, t;
25283
var tileid, horiz_flip, vert_flip, diag_flip;
25284
lenx = cr.floor(this.width / this.tilewidth);
25285
leny = cr.floor(this.height / this.tileheight);
25286
for (y = 0; y < leny; ++y)
25287
{
25288
for (x = (y === 0 ? 1 : 0) ; x < lenx; ++x)
25289
{
25290
t = this.getTileAt(x, y);
25291
if (t === run_number)
25292
++run_count;
25293
else
25294
{
25295
if (run_number === -1)
25296
{
25297
tileid = -1;
25298
horiz_flip = false;
25299
vert_flip = false;
25300
diag_flip = false;
25301
}
25302
else
25303
{
25304
tileid = (run_number & TILE_ID_MASK);
25305
horiz_flip = (run_number & TILE_FLIPPED_HORIZONTAL) !== 0;
25306
vert_flip = (run_number & TILE_FLIPPED_VERTICAL) !== 0;
25307
diag_flip = (run_number & TILE_FLIPPED_DIAGONAL) !== 0;
25308
}
25309
if (run_count === 1)
25310
ret += "" + tileid;
25311
else
25312
ret += "" + run_count + "x" + tileid;
25313
if (horiz_flip)
25314
ret += "h";
25315
if (vert_flip)
25316
ret += "v";
25317
if (diag_flip)
25318
ret += "d";
25319
ret += ",";
25320
run_count = 1;
25321
run_number = t;
25322
}
25323
}
25324
}
25325
if (run_number === -1)
25326
{
25327
tileid = -1;
25328
horiz_flip = false;
25329
vert_flip = false;
25330
diag_flip = false;
25331
}
25332
else
25333
{
25334
tileid = (run_number & TILE_ID_MASK);
25335
horiz_flip = (run_number & TILE_FLIPPED_HORIZONTAL) !== 0;
25336
vert_flip = (run_number & TILE_FLIPPED_VERTICAL) !== 0;
25337
diag_flip = (run_number & TILE_FLIPPED_DIAGONAL) !== 0;
25338
}
25339
if (run_count === 1)
25340
ret += "" + tileid;
25341
else
25342
ret += "" + run_count + "x" + tileid;
25343
if (horiz_flip)
25344
ret += "h";
25345
if (vert_flip)
25346
ret += "v";
25347
if (diag_flip)
25348
ret += "d";
25349
return ret;
25350
};
25351
instanceProto.getTileAt = function (x_, y_)
25352
{
25353
x_ = Math.floor(x_);
25354
y_ = Math.floor(y_);
25355
if (x_ < 0 || y_ < 0 || x_ >= this.mapwidth || y_ >= this.mapheight)
25356
return -1;
25357
var cell = this.cellAt(x_, y_);
25358
if (!cell)
25359
return -1;
25360
return cell.tiles[y_ % this.cellheight][x_ % this.cellwidth];
25361
};
25362
instanceProto.setTileAt = function (x_, y_, t_)
25363
{
25364
x_ = Math.floor(x_);
25365
y_ = Math.floor(y_);
25366
if (x_ < 0 || y_ < 0 || x_ >= this.mapwidth || y_ >= this.mapheight)
25367
return -1;
25368
var cell = this.cellAt(x_, y_);
25369
if (!cell)
25370
return -1;
25371
cell.setTileAt(x_ % this.cellwidth, y_ % this.cellheight, t_);
25372
};
25373
instanceProto.worldToCellX = function (x)
25374
{
25375
return Math.floor((x - this.x) / (this.cellwidth * this.tilewidth));
25376
};
25377
instanceProto.worldToCellY = function (y)
25378
{
25379
return Math.floor((y - this.y) / (this.cellheight * this.tileheight));
25380
};
25381
instanceProto.worldToTileX = function (x)
25382
{
25383
return Math.floor((x - this.x) / this.tilewidth)
25384
};
25385
instanceProto.worldToTileY = function (y)
25386
{
25387
return Math.floor((y - this.y) / this.tileheight);
25388
};
25389
instanceProto.getCollisionRectCandidates = function (bbox, candidates)
25390
{
25391
var firstCellX = this.worldToCellX(bbox.left);
25392
var firstCellY = this.worldToCellY(bbox.top);
25393
var lastCellX = this.worldToCellX(bbox.right);
25394
var lastCellY = this.worldToCellY(bbox.bottom);
25395
var cx, cy, cell;
25396
for (cx = firstCellX; cx <= lastCellX; ++cx)
25397
{
25398
for (cy = firstCellY; cy <= lastCellY; ++cy)
25399
{
25400
cell = this.cellAtIndex(cx, cy);
25401
if (!cell)
25402
continue;
25403
cell.maybeBuildQuadMap();
25404
cr.appendArray(candidates, cell.collision_rects);
25405
}
25406
}
25407
};
25408
instanceProto.testPointOverlapTile = function (x, y)
25409
{
25410
var tx = this.worldToTileX(x);
25411
var ty = this.worldToTileY(y);
25412
var tile = this.getTileAt(tx, ty);
25413
if (tile === -1)
25414
return false; // empty tile here
25415
var poly = this.type.getTilePoly(tile);
25416
if (!poly)
25417
return true; // no poly; whole tile registers overlap
25418
var tileStartX = (Math.floor((x - this.x) / this.tilewidth) * this.tilewidth) + this.x;
25419
var tileStartY = (Math.floor((y - this.y) / this.tileheight) * this.tileheight) + this.y;
25420
x -= tileStartX;
25421
y -= tileStartY;
25422
return poly.contains_pt(x, y);
25423
};
25424
instanceProto.getAllCollisionRects = function (candidates)
25425
{
25426
var i, len, j, lenj, row, cell;
25427
for (i = 0, len = this.tilecells.length; i < len; ++i)
25428
{
25429
row = this.tilecells[i];
25430
for (j = 0, lenj = row.length; j < lenj; ++j)
25431
{
25432
cell = row[j];
25433
cell.maybeBuildQuadMap();
25434
cr.appendArray(candidates, cell.collision_rects);
25435
}
25436
}
25437
};
25438
instanceProto.onDestroy = function ()
25439
{
25440
var i, len, j, lenj, arr;
25441
for (i = 0, len = this.tilecells.length; i < len; ++i)
25442
{
25443
arr = this.tilecells[i];
25444
for (j = 0, lenj = arr.length; j < lenj; ++j)
25445
{
25446
freeTileCell(arr[j]);
25447
}
25448
cr.clearArray(arr);
25449
}
25450
cr.clearArray(this.tilecells);
25451
};
25452
instanceProto.saveToJSON = function ()
25453
{
25454
this.maybeResizeTilemap();
25455
var curwidth = cr.floor(this.width / this.tilewidth);
25456
var curheight = cr.floor(this.height / this.tileheight);
25457
return {
25458
"w": curwidth,
25459
"h": curheight,
25460
"d": this.getTilesAsRLECSV()
25461
};
25462
};
25463
instanceProto.loadFromJSON = function (o)
25464
{
25465
this.mapwidth = o["w"];
25466
this.mapheight = o["h"];
25467
this.maybeResizeTilemap(true);
25468
this.setTilesFromRLECSV(o["d"]);
25469
this.physics_changed = true;
25470
this.setAllQuadMapChanged();
25471
};
25472
instanceProto.draw = function(ctx)
25473
{
25474
if (this.tilewidth <= 0 || this.tileheight <= 0)
25475
return;
25476
this.type.maybeCutTiles(this.tilewidth, this.tileheight, this.tilexoffset, this.tileyoffset, this.tilexspacing, this.tileyspacing, this.seamless);
25477
if (this.width !== this.lastwidth || this.height !== this.lastheight)
25478
{
25479
this.physics_changed = true;
25480
this.setAllQuadMapChanged();
25481
this.maybeBuildAllQuadMap();
25482
this.lastwidth = this.width;
25483
this.lastheight = this.height;
25484
}
25485
ctx.globalAlpha = this.opacity;
25486
var layer = this.layer;
25487
var viewLeft = layer.viewLeft;
25488
var viewTop = layer.viewTop;
25489
var viewRight = layer.viewRight;
25490
var viewBottom = layer.viewBottom;
25491
var myx = this.x;
25492
var myy = this.y;
25493
var seamless = this.seamless;
25494
var qrc;
25495
if (this.runtime.pixel_rounding)
25496
{
25497
myx = Math.round(myx);
25498
myy = Math.round(myy);
25499
}
25500
var cellWidthPx = this.cellwidth * this.tilewidth;
25501
var cellHeightPx = this.cellheight * this.tileheight;
25502
var firstCellX = Math.floor((viewLeft - myx) / cellWidthPx);
25503
var lastCellX = Math.floor((viewRight - myx) / cellWidthPx);
25504
var firstCellY = Math.floor((viewTop - myy) / cellHeightPx);
25505
var lastCellY = Math.floor((viewBottom - myy) / cellHeightPx);
25506
var offx = myx % this.tilewidth;
25507
var offy = myy % this.tileheight;
25508
if (this.seamless)
25509
{
25510
offx = 0;
25511
offy = 0;
25512
}
25513
if (offx !== 0 || offy !== 0)
25514
{
25515
ctx.save();
25516
ctx.translate(offx, offy);
25517
myx -= offx;
25518
myy -= offy;
25519
viewLeft -= offx;
25520
viewTop -= offy;
25521
viewRight -= offx;
25522
viewBottom -= offy;
25523
}
25524
var cx, cy, cell, i, len, q, qleft, qtop, qright, qbottom, img;
25525
for (cx = firstCellX; cx <= lastCellX; ++cx)
25526
{
25527
for (cy = firstCellY; cy <= lastCellY; ++cy)
25528
{
25529
cell = this.cellAtIndex(cx, cy);
25530
if (!cell)
25531
continue;
25532
cell.maybeBuildQuadMap();
25533
for (i = 0, len = cell.quads.length; i < len; ++i)
25534
{
25535
q = cell.quads[i];
25536
if (q.id === -1)
25537
continue;
25538
qrc = q.rc;
25539
qleft = qrc.left + myx;
25540
qtop = qrc.top + myy;
25541
qright = qrc.right + myx;
25542
qbottom = qrc.bottom + myy;
25543
if (qleft > viewRight || qright < viewLeft || qtop > viewBottom || qbottom < viewTop)
25544
continue;
25545
img = this.type.GetFlippedTileImage(q.tileid, q.horiz_flip, q.vert_flip, q.diag_flip, this.seamless);
25546
if (seamless)
25547
{
25548
ctx.drawImage(img, qleft, qtop);
25549
}
25550
else
25551
{
25552
ctx.fillStyle = this.type.GetFlippedTileImage(q.tileid, q.horiz_flip, q.vert_flip, q.diag_flip, this.seamless);
25553
ctx.fillRect(qleft, qtop, qright - qleft, qbottom - qtop);
25554
}
25555
}
25556
/*
25557
for (i = 0, len = cell.collision_rects.length; i < len; ++i)
25558
{
25559
qrc = cell.collision_rects[i].rc;
25560
qleft = qrc.left + myx;
25561
qtop = qrc.top + myy;
25562
qright = qrc.right + myx;
25563
qbottom = qrc.bottom + myy;
25564
ctx.strokeRect(qleft, qtop, qright - qleft, qbottom - qtop);
25565
}
25566
*/
25567
}
25568
}
25569
if (offx !== 0 || offy !== 0)
25570
ctx.restore();
25571
};
25572
var tmp_rect = new cr.rect(0, 0, 1, 1);
25573
instanceProto.drawGL_earlyZPass = function(glw)
25574
{
25575
this.drawGL(glw);
25576
};
25577
instanceProto.drawGL = function (glw)
25578
{
25579
if (this.tilewidth <= 0 || this.tileheight <= 0)
25580
return;
25581
this.type.maybeCutTiles(this.tilewidth, this.tileheight, this.tilexoffset, this.tileyoffset, this.tilexspacing, this.tileyspacing, this.seamless);
25582
if (this.width !== this.lastwidth || this.height !== this.lastheight)
25583
{
25584
this.physics_changed = true;
25585
this.setAllQuadMapChanged();
25586
this.maybeBuildAllQuadMap();
25587
this.lastwidth = this.width;
25588
this.lastheight = this.height;
25589
}
25590
glw.setOpacity(this.opacity);
25591
var cut_tiles = this.type.cut_tiles;
25592
var layer = this.layer;
25593
var viewLeft = layer.viewLeft;
25594
var viewTop = layer.viewTop;
25595
var viewRight = layer.viewRight;
25596
var viewBottom = layer.viewBottom;
25597
var myx = this.x;
25598
var myy = this.y;
25599
var qrc;
25600
if (this.runtime.pixel_rounding)
25601
{
25602
myx = Math.round(myx);
25603
myy = Math.round(myy);
25604
}
25605
var cellWidthPx = this.cellwidth * this.tilewidth;
25606
var cellHeightPx = this.cellheight * this.tileheight;
25607
var firstCellX = Math.floor((viewLeft - myx) / cellWidthPx);
25608
var lastCellX = Math.floor((viewRight - myx) / cellWidthPx);
25609
var firstCellY = Math.floor((viewTop - myy) / cellHeightPx);
25610
var lastCellY = Math.floor((viewBottom - myy) / cellHeightPx);
25611
var i, len, q, qleft, qtop, qright, qbottom;
25612
var qtlx, qtly, qtrx, qtry, qbrx, qbry, qblx, qbly, temp;
25613
var cx, cy, cell;
25614
for (cx = firstCellX; cx <= lastCellX; ++cx)
25615
{
25616
for (cy = firstCellY; cy <= lastCellY; ++cy)
25617
{
25618
cell = this.cellAtIndex(cx, cy);
25619
if (!cell)
25620
continue;
25621
cell.maybeBuildQuadMap();
25622
for (i = 0, len = cell.quads.length; i < len; ++i)
25623
{
25624
q = cell.quads[i];
25625
if (q.id === -1)
25626
continue;
25627
qrc = q.rc;
25628
qleft = qrc.left + myx;
25629
qtop = qrc.top + myy;
25630
qright = qrc.right + myx;
25631
qbottom = qrc.bottom + myy;
25632
if (qleft > viewRight || qright < viewLeft || qtop > viewBottom || qbottom < viewTop)
25633
continue;
25634
glw.setTexture(cut_tiles[q.tileid]);
25635
tmp_rect.right = (qright - qleft) / this.tilewidth;
25636
tmp_rect.bottom = (qbottom - qtop) / this.tileheight;
25637
if (q.any_flip)
25638
{
25639
if (q.diag_flip)
25640
{
25641
temp = tmp_rect.right;
25642
tmp_rect.right = tmp_rect.bottom;
25643
tmp_rect.bottom = temp;
25644
}
25645
qtlx = 0;
25646
qtly = 0;
25647
qtrx = tmp_rect.right;
25648
qtry = 0;
25649
qbrx = tmp_rect.right;
25650
qbry = tmp_rect.bottom;
25651
qblx = 0;
25652
qbly = tmp_rect.bottom;
25653
if (q.diag_flip)
25654
{
25655
temp = qblx; qblx = qtrx; qtrx = temp;
25656
temp = qbly; qbly = qtry; qtry = temp;
25657
}
25658
if (q.horiz_flip)
25659
{
25660
temp = qtlx; qtlx = qtrx; qtrx = temp;
25661
temp = qtly; qtly = qtry; qtry = temp;
25662
temp = qblx; qblx = qbrx; qbrx = temp;
25663
temp = qbly; qbly = qbry; qbry = temp;
25664
}
25665
if (q.vert_flip)
25666
{
25667
temp = qtlx; qtlx = qblx; qblx = temp;
25668
temp = qtly; qtly = qbly; qbly = temp;
25669
temp = qtrx; qtrx = qbrx; qbrx = temp;
25670
temp = qtry; qtry = qbry; qbry = temp;
25671
}
25672
glw.quadTexUV(qleft, qtop, qright, qtop, qright, qbottom, qleft, qbottom, qtlx, qtly, qtrx, qtry, qbrx, qbry, qblx, qbly);
25673
}
25674
else
25675
{
25676
glw.quadTex(qleft, qtop, qright, qtop, qright, qbottom, qleft, qbottom, tmp_rect);
25677
}
25678
}
25679
}
25680
}
25681
};
25682
function Cnds() {};
25683
Cnds.prototype.CompareTileAt = function (tx, ty, cmp, t)
25684
{
25685
var tile = this.getTileAt(tx, ty);
25686
if (tile !== -1)
25687
tile = (tile & TILE_ID_MASK);
25688
return cr.do_cmp(tile, cmp, t);
25689
};
25690
function StateComboToFlags(state)
25691
{
25692
switch (state) {
25693
case 0: // normal
25694
return 0;
25695
case 1: // flipped horizontal
25696
return TILE_FLIPPED_HORIZONTAL;
25697
case 2: // flipped vertical
25698
return TILE_FLIPPED_VERTICAL;
25699
case 3: // rotated 90
25700
return TILE_FLIPPED_HORIZONTAL | TILE_FLIPPED_DIAGONAL;
25701
case 4: // rotated 180
25702
return TILE_FLIPPED_HORIZONTAL | TILE_FLIPPED_VERTICAL;
25703
case 5: // rotated 270
25704
return TILE_FLIPPED_VERTICAL | TILE_FLIPPED_DIAGONAL;
25705
case 6: // rotated 90, flipped vertical
25706
return TILE_FLIPPED_HORIZONTAL | TILE_FLIPPED_VERTICAL | TILE_FLIPPED_DIAGONAL;
25707
case 7: // rotated 270, flipped vertical
25708
return TILE_FLIPPED_DIAGONAL;
25709
default:
25710
return 0;
25711
}
25712
};
25713
Cnds.prototype.CompareTileStateAt = function (tx, ty, state)
25714
{
25715
var tile = this.getTileAt(tx, ty);
25716
var flags = 0;
25717
if (tile !== -1)
25718
flags = (tile & TILE_FLAGS_MASK);
25719
return flags === StateComboToFlags(state);
25720
};
25721
Cnds.prototype.OnURLLoaded = function ()
25722
{
25723
return true;
25724
};
25725
pluginProto.cnds = new Cnds();
25726
function Acts() {};
25727
Acts.prototype.EraseTile = function (tx, ty)
25728
{
25729
this.maybeResizeTilemap();
25730
this.setTileAt(tx, ty, -1);
25731
};
25732
Acts.prototype.SetTile = function (tx, ty, t, state)
25733
{
25734
this.maybeResizeTilemap();
25735
this.setTileAt(tx, ty, (t & TILE_ID_MASK) | StateComboToFlags(state));
25736
};
25737
Acts.prototype.SetTileState = function (tx, ty, state)
25738
{
25739
var t = this.getTileAt(tx, ty);
25740
if (t !== -1)
25741
{
25742
this.maybeResizeTilemap();
25743
this.setTileAt(tx, ty, (t & TILE_ID_MASK) | StateComboToFlags(state));
25744
}
25745
};
25746
Acts.prototype.EraseTileRange = function (tx, ty, tw, th)
25747
{
25748
var fromx = Math.floor(cr.max(tx, 0));
25749
var fromy = Math.floor(cr.max(ty, 0));
25750
var tox = Math.floor(cr.min(tx + tw, this.mapwidth));
25751
var toy = Math.floor(cr.min(ty + th, this.mapheight));
25752
var x, y;
25753
for (y = fromy; y < toy; ++y)
25754
{
25755
for (x = fromx; x < tox; ++x)
25756
{
25757
this.setTileAt(x, y, -1);
25758
}
25759
}
25760
};
25761
Acts.prototype.SetTileRange = function (tx, ty, tw, th, t, state)
25762
{
25763
this.maybeResizeTilemap();
25764
var fromx = Math.floor(cr.max(tx, 0));
25765
var fromy = Math.floor(cr.max(ty, 0));
25766
var tox = Math.floor(cr.min(tx + tw, this.mapwidth));
25767
var toy = Math.floor(cr.min(ty + th, this.mapheight));
25768
var settile = (t & TILE_ID_MASK) | StateComboToFlags(state);
25769
var x, y;
25770
for (y = fromy; y < toy; ++y)
25771
{
25772
for (x = fromx; x < tox; ++x)
25773
{
25774
this.setTileAt(x, y, settile);
25775
}
25776
}
25777
};
25778
Acts.prototype.SetTileStateRange = function (tx, ty, tw, th, state)
25779
{
25780
this.maybeResizeTilemap();
25781
var fromx = Math.floor(cr.max(tx, 0));
25782
var fromy = Math.floor(cr.max(ty, 0));
25783
var tox = Math.floor(cr.min(tx + tw, this.mapwidth));
25784
var toy = Math.floor(cr.min(ty + th, this.mapheight));
25785
var setstate = StateComboToFlags(state);
25786
var x, y, t;
25787
for (y = fromy; y < toy; ++y)
25788
{
25789
for (x = fromx; x < tox; ++x)
25790
{
25791
t = this.getTileAt(x, y);
25792
if (t !== -1)
25793
this.setTileAt(x, y, (t & TILE_ID_MASK) | setstate);
25794
}
25795
}
25796
};
25797
Acts.prototype.LoadFromJSON = function (str)
25798
{
25799
var o;
25800
try {
25801
o = JSON.parse(str);
25802
}
25803
catch (e) {
25804
return;
25805
}
25806
if (!o["c2tilemap"])
25807
return; // not a known tilemap data format
25808
this.mapwidth = o["width"];
25809
this.mapheight = o["height"];
25810
this.maybeResizeTilemap(true);
25811
this.setTilesFromRLECSV(o["data"]);
25812
this.setAllQuadMapChanged();
25813
this.physics_changed = true;
25814
};
25815
Acts.prototype.JSONDownload = function (filename)
25816
{
25817
var a = document.createElement("a");
25818
var o = {
25819
"c2tilemap": true,
25820
"width": this.mapwidth,
25821
"height": this.mapheight,
25822
"data": this.getTilesAsRLECSV()
25823
};
25824
if (typeof a.download === "undefined")
25825
{
25826
var str = 'data:text/html,' + encodeURIComponent("<p><a download='data.json' href=\"data:application/json,"
25827
+ encodeURIComponent(JSON.stringify(o))
25828
+ "\">Download link</a></p>");
25829
window.open(str);
25830
}
25831
else
25832
{
25833
var body = document.getElementsByTagName("body")[0];
25834
a.textContent = filename;
25835
a.href = "data:application/json," + encodeURIComponent(JSON.stringify(o));
25836
a.download = filename;
25837
body.appendChild(a);
25838
var clickEvent = document.createEvent("MouseEvent");
25839
clickEvent.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
25840
a.dispatchEvent(clickEvent);
25841
body.removeChild(a);
25842
}
25843
};
25844
Acts.prototype.LoadURL = function (url_, crossOrigin_)
25845
{
25846
var img = new Image();
25847
var self = this;
25848
img.onload = function ()
25849
{
25850
var type = self.type;
25851
type.freeCutTiles();
25852
type.texture_img = img;
25853
self.runtime.redraw = true;
25854
self.runtime.trigger(cr.plugins_.Tilemap.prototype.cnds.OnURLLoaded, self);
25855
};
25856
if (url_.substr(0, 5) !== "data:" && crossOrigin_ === 0)
25857
img.crossOrigin = "anonymous";
25858
this.runtime.setImageSrc(img, url_);
25859
};
25860
pluginProto.acts = new Acts();
25861
function Exps() {};
25862
Exps.prototype.TileAt = function (ret, tx, ty)
25863
{
25864
var tile = this.getTileAt(tx, ty);
25865
ret.set_int(tile === -1 ? -1 : (tile & TILE_ID_MASK));
25866
};
25867
Exps.prototype.PositionToTileX = function (ret, x_)
25868
{
25869
ret.set_float(this.worldToTileX(x_));
25870
};
25871
Exps.prototype.PositionToTileY = function (ret, y_)
25872
{
25873
ret.set_float(this.worldToTileY(y_));
25874
};
25875
Exps.prototype.TileToPositionX = function (ret, x_)
25876
{
25877
ret.set_float((x_ * this.tilewidth) + this.x + (this.tilewidth / 2));
25878
};
25879
Exps.prototype.TileToPositionY = function (ret, y_)
25880
{
25881
ret.set_float((y_ * this.tileheight) + this.y + (this.tileheight / 2));
25882
};
25883
Exps.prototype.SnapX = function (ret, x_)
25884
{
25885
ret.set_float((Math.floor((x_ - this.x) / this.tilewidth) * this.tilewidth) + this.x + (this.tilewidth / 2));
25886
};
25887
Exps.prototype.SnapY = function (ret, y_)
25888
{
25889
ret.set_float((Math.floor((y_ - this.y) / this.tileheight) * this.tileheight) + this.y + (this.tileheight / 2));
25890
};
25891
Exps.prototype.TilesJSON = function (ret)
25892
{
25893
this.maybeResizeTilemap();
25894
var curwidth = cr.floor(this.width / this.tilewidth);
25895
var curheight = cr.floor(this.height / this.tileheight);
25896
ret.set_string(JSON.stringify({
25897
"c2tilemap": true,
25898
"width": curwidth,
25899
"height": curheight,
25900
"data": this.getTilesAsRLECSV()
25901
}));
25902
};
25903
pluginProto.exps = new Exps();
25904
}());
25905
;
25906
;
25907
cr.plugins_.Touch = function(runtime)
25908
{
25909
this.runtime = runtime;
25910
};
25911
(function ()
25912
{
25913
var pluginProto = cr.plugins_.Touch.prototype;
25914
pluginProto.Type = function(plugin)
25915
{
25916
this.plugin = plugin;
25917
this.runtime = plugin.runtime;
25918
};
25919
var typeProto = pluginProto.Type.prototype;
25920
typeProto.onCreate = function()
25921
{
25922
};
25923
pluginProto.Instance = function(type)
25924
{
25925
this.type = type;
25926
this.runtime = type.runtime;
25927
this.touches = [];
25928
this.mouseDown = false;
25929
};
25930
var instanceProto = pluginProto.Instance.prototype;
25931
var dummyoffset = {left: 0, top: 0};
25932
instanceProto.findTouch = function (id)
25933
{
25934
var i, len;
25935
for (i = 0, len = this.touches.length; i < len; i++)
25936
{
25937
if (this.touches[i]["id"] === id)
25938
return i;
25939
}
25940
return -1;
25941
};
25942
var appmobi_accx = 0;
25943
var appmobi_accy = 0;
25944
var appmobi_accz = 0;
25945
function AppMobiGetAcceleration(evt)
25946
{
25947
appmobi_accx = evt.x;
25948
appmobi_accy = evt.y;
25949
appmobi_accz = evt.z;
25950
};
25951
var pg_accx = 0;
25952
var pg_accy = 0;
25953
var pg_accz = 0;
25954
function PhoneGapGetAcceleration(evt)
25955
{
25956
pg_accx = evt.x;
25957
pg_accy = evt.y;
25958
pg_accz = evt.z;
25959
};
25960
var theInstance = null;
25961
var touchinfo_cache = [];
25962
function AllocTouchInfo(x, y, id, index)
25963
{
25964
var ret;
25965
if (touchinfo_cache.length)
25966
ret = touchinfo_cache.pop();
25967
else
25968
ret = new TouchInfo();
25969
ret.init(x, y, id, index);
25970
return ret;
25971
};
25972
function ReleaseTouchInfo(ti)
25973
{
25974
if (touchinfo_cache.length < 100)
25975
touchinfo_cache.push(ti);
25976
};
25977
var GESTURE_HOLD_THRESHOLD = 15; // max px motion for hold gesture to register
25978
var GESTURE_HOLD_TIMEOUT = 500; // time for hold gesture to register
25979
var GESTURE_TAP_TIMEOUT = 333; // time for tap gesture to register
25980
var GESTURE_DOUBLETAP_THRESHOLD = 25; // max distance apart for taps to be
25981
function TouchInfo()
25982
{
25983
this.starttime = 0;
25984
this.time = 0;
25985
this.lasttime = 0;
25986
this.startx = 0;
25987
this.starty = 0;
25988
this.x = 0;
25989
this.y = 0;
25990
this.lastx = 0;
25991
this.lasty = 0;
25992
this["id"] = 0;
25993
this.startindex = 0;
25994
this.triggeredHold = false;
25995
this.tooFarForHold = false;
25996
};
25997
TouchInfo.prototype.init = function (x, y, id, index)
25998
{
25999
var nowtime = cr.performance_now();
26000
this.time = nowtime;
26001
this.lasttime = nowtime;
26002
this.starttime = nowtime;
26003
this.startx = x;
26004
this.starty = y;
26005
this.x = x;
26006
this.y = y;
26007
this.lastx = x;
26008
this.lasty = y;
26009
this.width = 0;
26010
this.height = 0;
26011
this.pressure = 0;
26012
this["id"] = id;
26013
this.startindex = index;
26014
this.triggeredHold = false;
26015
this.tooFarForHold = false;
26016
};
26017
TouchInfo.prototype.update = function (nowtime, x, y, width, height, pressure)
26018
{
26019
this.lasttime = this.time;
26020
this.time = nowtime;
26021
this.lastx = this.x;
26022
this.lasty = this.y;
26023
this.x = x;
26024
this.y = y;
26025
this.width = width;
26026
this.height = height;
26027
this.pressure = pressure;
26028
if (!this.tooFarForHold && cr.distanceTo(this.startx, this.starty, this.x, this.y) >= GESTURE_HOLD_THRESHOLD)
26029
{
26030
this.tooFarForHold = true;
26031
}
26032
};
26033
TouchInfo.prototype.maybeTriggerHold = function (inst, index)
26034
{
26035
if (this.triggeredHold)
26036
return; // already triggered this gesture
26037
var nowtime = cr.performance_now();
26038
if (nowtime - this.starttime >= GESTURE_HOLD_TIMEOUT && !this.tooFarForHold && cr.distanceTo(this.startx, this.starty, this.x, this.y) < GESTURE_HOLD_THRESHOLD)
26039
{
26040
this.triggeredHold = true;
26041
inst.trigger_index = this.startindex;
26042
inst.trigger_id = this["id"];
26043
inst.getTouchIndex = index;
26044
inst.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnHoldGesture, inst);
26045
inst.curTouchX = this.x;
26046
inst.curTouchY = this.y;
26047
inst.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnHoldGestureObject, inst);
26048
inst.getTouchIndex = 0;
26049
}
26050
};
26051
var lastTapX = -1000;
26052
var lastTapY = -1000;
26053
var lastTapTime = -10000;
26054
TouchInfo.prototype.maybeTriggerTap = function (inst, index)
26055
{
26056
if (this.triggeredHold)
26057
return;
26058
var nowtime = cr.performance_now();
26059
if (nowtime - this.starttime <= GESTURE_TAP_TIMEOUT && !this.tooFarForHold && cr.distanceTo(this.startx, this.starty, this.x, this.y) < GESTURE_HOLD_THRESHOLD)
26060
{
26061
inst.trigger_index = this.startindex;
26062
inst.trigger_id = this["id"];
26063
inst.getTouchIndex = index;
26064
if ((nowtime - lastTapTime <= GESTURE_TAP_TIMEOUT * 2) && cr.distanceTo(lastTapX, lastTapY, this.x, this.y) < GESTURE_DOUBLETAP_THRESHOLD)
26065
{
26066
inst.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnDoubleTapGesture, inst);
26067
inst.curTouchX = this.x;
26068
inst.curTouchY = this.y;
26069
inst.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnDoubleTapGestureObject, inst);
26070
lastTapX = -1000;
26071
lastTapY = -1000;
26072
lastTapTime = -10000;
26073
}
26074
else
26075
{
26076
inst.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnTapGesture, inst);
26077
inst.curTouchX = this.x;
26078
inst.curTouchY = this.y;
26079
inst.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnTapGestureObject, inst);
26080
lastTapX = this.x;
26081
lastTapY = this.y;
26082
lastTapTime = nowtime;
26083
}
26084
inst.getTouchIndex = 0;
26085
}
26086
};
26087
instanceProto.onCreate = function()
26088
{
26089
theInstance = this;
26090
this.isWindows8 = !!(typeof window["c2isWindows8"] !== "undefined" && window["c2isWindows8"]);
26091
this.orient_alpha = 0;
26092
this.orient_beta = 0;
26093
this.orient_gamma = 0;
26094
this.acc_g_x = 0;
26095
this.acc_g_y = 0;
26096
this.acc_g_z = 0;
26097
this.acc_x = 0;
26098
this.acc_y = 0;
26099
this.acc_z = 0;
26100
this.curTouchX = 0;
26101
this.curTouchY = 0;
26102
this.trigger_index = 0;
26103
this.trigger_id = 0;
26104
this.trigger_permission = 0;
26105
this.getTouchIndex = 0;
26106
this.useMouseInput = (this.properties[0] !== 0);
26107
var elem = (this.runtime.fullscreen_mode > 0) ? document : this.runtime.canvas;
26108
var elem2 = document;
26109
if (this.runtime.isDirectCanvas)
26110
elem2 = elem = window["Canvas"];
26111
else if (this.runtime.isCocoonJs)
26112
elem2 = elem = window;
26113
var self = this;
26114
if (typeof PointerEvent !== "undefined")
26115
{
26116
elem.addEventListener("pointerdown",
26117
function(info) {
26118
self.onPointerStart(info);
26119
},
26120
false
26121
);
26122
elem.addEventListener("pointermove",
26123
function(info) {
26124
self.onPointerMove(info);
26125
},
26126
false
26127
);
26128
elem2.addEventListener("pointerup",
26129
function(info) {
26130
self.onPointerEnd(info, false);
26131
},
26132
false
26133
);
26134
elem2.addEventListener("pointercancel",
26135
function(info) {
26136
self.onPointerEnd(info, true);
26137
},
26138
false
26139
);
26140
if (this.runtime.canvas)
26141
{
26142
this.runtime.canvas.addEventListener("MSGestureHold", function(e) {
26143
e.preventDefault();
26144
}, false);
26145
document.addEventListener("MSGestureHold", function(e) {
26146
e.preventDefault();
26147
}, false);
26148
this.runtime.canvas.addEventListener("gesturehold", function(e) {
26149
e.preventDefault();
26150
}, false);
26151
document.addEventListener("gesturehold", function(e) {
26152
e.preventDefault();
26153
}, false);
26154
}
26155
}
26156
else if (window.navigator["msPointerEnabled"])
26157
{
26158
elem.addEventListener("MSPointerDown",
26159
function(info) {
26160
self.onPointerStart(info);
26161
},
26162
false
26163
);
26164
elem.addEventListener("MSPointerMove",
26165
function(info) {
26166
self.onPointerMove(info);
26167
},
26168
false
26169
);
26170
elem2.addEventListener("MSPointerUp",
26171
function(info) {
26172
self.onPointerEnd(info, false);
26173
},
26174
false
26175
);
26176
elem2.addEventListener("MSPointerCancel",
26177
function(info) {
26178
self.onPointerEnd(info, true);
26179
},
26180
false
26181
);
26182
if (this.runtime.canvas)
26183
{
26184
this.runtime.canvas.addEventListener("MSGestureHold", function(e) {
26185
e.preventDefault();
26186
}, false);
26187
document.addEventListener("MSGestureHold", function(e) {
26188
e.preventDefault();
26189
}, false);
26190
}
26191
}
26192
else
26193
{
26194
elem.addEventListener("touchstart",
26195
function(info) {
26196
self.onTouchStart(info);
26197
},
26198
false
26199
);
26200
elem.addEventListener("touchmove",
26201
function(info) {
26202
self.onTouchMove(info);
26203
},
26204
false
26205
);
26206
elem2.addEventListener("touchend",
26207
function(info) {
26208
self.onTouchEnd(info, false);
26209
},
26210
false
26211
);
26212
elem2.addEventListener("touchcancel",
26213
function(info) {
26214
self.onTouchEnd(info, true);
26215
},
26216
false
26217
);
26218
}
26219
if (this.isWindows8)
26220
{
26221
var win8accelerometerFn = function(e) {
26222
var reading = e["reading"];
26223
self.acc_x = reading["accelerationX"];
26224
self.acc_y = reading["accelerationY"];
26225
self.acc_z = reading["accelerationZ"];
26226
};
26227
var win8inclinometerFn = function(e) {
26228
var reading = e["reading"];
26229
self.orient_alpha = reading["yawDegrees"];
26230
self.orient_beta = reading["pitchDegrees"];
26231
self.orient_gamma = reading["rollDegrees"];
26232
};
26233
var accelerometer = Windows["Devices"]["Sensors"]["Accelerometer"]["getDefault"]();
26234
if (accelerometer)
26235
{
26236
accelerometer["reportInterval"] = Math.max(accelerometer["minimumReportInterval"], 16);
26237
accelerometer.addEventListener("readingchanged", win8accelerometerFn);
26238
}
26239
var inclinometer = Windows["Devices"]["Sensors"]["Inclinometer"]["getDefault"]();
26240
if (inclinometer)
26241
{
26242
inclinometer["reportInterval"] = Math.max(inclinometer["minimumReportInterval"], 16);
26243
inclinometer.addEventListener("readingchanged", win8inclinometerFn);
26244
}
26245
document.addEventListener("visibilitychange", function(e) {
26246
if (document["hidden"] || document["msHidden"])
26247
{
26248
if (accelerometer)
26249
accelerometer.removeEventListener("readingchanged", win8accelerometerFn);
26250
if (inclinometer)
26251
inclinometer.removeEventListener("readingchanged", win8inclinometerFn);
26252
}
26253
else
26254
{
26255
if (accelerometer)
26256
accelerometer.addEventListener("readingchanged", win8accelerometerFn);
26257
if (inclinometer)
26258
inclinometer.addEventListener("readingchanged", win8inclinometerFn);
26259
}
26260
}, false);
26261
}
26262
else
26263
{
26264
window.addEventListener("deviceorientation", function (eventData) {
26265
self.orient_alpha = eventData["alpha"] || 0;
26266
self.orient_beta = eventData["beta"] || 0;
26267
self.orient_gamma = eventData["gamma"] || 0;
26268
}, false);
26269
window.addEventListener("devicemotion", function (eventData) {
26270
if (eventData["accelerationIncludingGravity"])
26271
{
26272
self.acc_g_x = eventData["accelerationIncludingGravity"]["x"] || 0;
26273
self.acc_g_y = eventData["accelerationIncludingGravity"]["y"] || 0;
26274
self.acc_g_z = eventData["accelerationIncludingGravity"]["z"] || 0;
26275
}
26276
if (eventData["acceleration"])
26277
{
26278
self.acc_x = eventData["acceleration"]["x"] || 0;
26279
self.acc_y = eventData["acceleration"]["y"] || 0;
26280
self.acc_z = eventData["acceleration"]["z"] || 0;
26281
}
26282
}, false);
26283
}
26284
if (this.useMouseInput && !this.runtime.isDomFree)
26285
{
26286
jQuery(document).mousemove(
26287
function(info) {
26288
self.onMouseMove(info);
26289
}
26290
);
26291
jQuery(document).mousedown(
26292
function(info) {
26293
self.onMouseDown(info);
26294
}
26295
);
26296
jQuery(document).mouseup(
26297
function(info) {
26298
self.onMouseUp(info);
26299
}
26300
);
26301
}
26302
if (!this.runtime.isiOS && this.runtime.isCordova && navigator["accelerometer"] && navigator["accelerometer"]["watchAcceleration"])
26303
{
26304
navigator["accelerometer"]["watchAcceleration"](PhoneGapGetAcceleration, null, { "frequency": 40 });
26305
}
26306
this.runtime.tick2Me(this);
26307
};
26308
instanceProto.onPointerMove = function (info)
26309
{
26310
if (info["pointerType"] === info["MSPOINTER_TYPE_MOUSE"] || info["pointerType"] === "mouse")
26311
return;
26312
if (info.preventDefault)
26313
info.preventDefault();
26314
var i = this.findTouch(info["pointerId"]);
26315
var nowtime = cr.performance_now();
26316
if (i >= 0)
26317
{
26318
var offset = this.runtime.isDomFree ? dummyoffset : jQuery(this.runtime.canvas).offset();
26319
var t = this.touches[i];
26320
if (nowtime - t.time < 2)
26321
return;
26322
t.update(nowtime, info.pageX - offset.left, info.pageY - offset.top, info.width || 0, info.height || 0, info.pressure || 0);
26323
}
26324
};
26325
instanceProto.onPointerStart = function (info)
26326
{
26327
if (info["pointerType"] === info["MSPOINTER_TYPE_MOUSE"] || info["pointerType"] === "mouse")
26328
return;
26329
if (info.preventDefault && cr.isCanvasInputEvent(info))
26330
info.preventDefault();
26331
var offset = this.runtime.isDomFree ? dummyoffset : jQuery(this.runtime.canvas).offset();
26332
var touchx = info.pageX - offset.left;
26333
var touchy = info.pageY - offset.top;
26334
var nowtime = cr.performance_now();
26335
this.trigger_index = this.touches.length;
26336
this.trigger_id = info["pointerId"];
26337
this.touches.push(AllocTouchInfo(touchx, touchy, info["pointerId"], this.trigger_index));
26338
this.runtime.isInUserInputEvent = true;
26339
this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnNthTouchStart, this);
26340
this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnTouchStart, this);
26341
this.curTouchX = touchx;
26342
this.curTouchY = touchy;
26343
this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnTouchObject, this);
26344
this.runtime.isInUserInputEvent = false;
26345
};
26346
instanceProto.onPointerEnd = function (info, isCancel)
26347
{
26348
if (info["pointerType"] === info["MSPOINTER_TYPE_MOUSE"] || info["pointerType"] === "mouse")
26349
return;
26350
if (info.preventDefault && cr.isCanvasInputEvent(info))
26351
info.preventDefault();
26352
var i = this.findTouch(info["pointerId"]);
26353
this.trigger_index = (i >= 0 ? this.touches[i].startindex : -1);
26354
this.trigger_id = (i >= 0 ? this.touches[i]["id"] : -1);
26355
this.runtime.isInUserInputEvent = true;
26356
this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnNthTouchEnd, this);
26357
this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnTouchEnd, this);
26358
if (i >= 0)
26359
{
26360
if (!isCancel)
26361
this.touches[i].maybeTriggerTap(this, i);
26362
ReleaseTouchInfo(this.touches[i]);
26363
this.touches.splice(i, 1);
26364
}
26365
this.runtime.isInUserInputEvent = false;
26366
};
26367
instanceProto.onTouchMove = function (info)
26368
{
26369
if (info.preventDefault)
26370
info.preventDefault();
26371
var nowtime = cr.performance_now();
26372
var i, len, t, u;
26373
for (i = 0, len = info.changedTouches.length; i < len; i++)
26374
{
26375
t = info.changedTouches[i];
26376
var j = this.findTouch(t["identifier"]);
26377
if (j >= 0)
26378
{
26379
var offset = this.runtime.isDomFree ? dummyoffset : jQuery(this.runtime.canvas).offset();
26380
u = this.touches[j];
26381
if (nowtime - u.time < 2)
26382
continue;
26383
var touchWidth = (t.radiusX || t.webkitRadiusX || t.mozRadiusX || t.msRadiusX || 0) * 2;
26384
var touchHeight = (t.radiusY || t.webkitRadiusY || t.mozRadiusY || t.msRadiusY || 0) * 2;
26385
var touchForce = t.force || t.webkitForce || t.mozForce || t.msForce || 0;
26386
u.update(nowtime, t.pageX - offset.left, t.pageY - offset.top, touchWidth, touchHeight, touchForce);
26387
}
26388
}
26389
};
26390
instanceProto.onTouchStart = function (info)
26391
{
26392
if (info.preventDefault && cr.isCanvasInputEvent(info))
26393
info.preventDefault();
26394
var offset = this.runtime.isDomFree ? dummyoffset : jQuery(this.runtime.canvas).offset();
26395
var nowtime = cr.performance_now();
26396
this.runtime.isInUserInputEvent = true;
26397
var i, len, t, j;
26398
for (i = 0, len = info.changedTouches.length; i < len; i++)
26399
{
26400
t = info.changedTouches[i];
26401
j = this.findTouch(t["identifier"]);
26402
if (j !== -1)
26403
continue;
26404
var touchx = t.pageX - offset.left;
26405
var touchy = t.pageY - offset.top;
26406
this.trigger_index = this.touches.length;
26407
this.trigger_id = t["identifier"];
26408
this.touches.push(AllocTouchInfo(touchx, touchy, t["identifier"], this.trigger_index));
26409
this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnNthTouchStart, this);
26410
this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnTouchStart, this);
26411
this.curTouchX = touchx;
26412
this.curTouchY = touchy;
26413
this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnTouchObject, this);
26414
}
26415
this.runtime.isInUserInputEvent = false;
26416
};
26417
instanceProto.onTouchEnd = function (info, isCancel)
26418
{
26419
if (info.preventDefault && cr.isCanvasInputEvent(info))
26420
info.preventDefault();
26421
this.runtime.isInUserInputEvent = true;
26422
var i, len, t, j;
26423
for (i = 0, len = info.changedTouches.length; i < len; i++)
26424
{
26425
t = info.changedTouches[i];
26426
j = this.findTouch(t["identifier"]);
26427
if (j >= 0)
26428
{
26429
this.trigger_index = this.touches[j].startindex;
26430
this.trigger_id = this.touches[j]["id"];
26431
this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnNthTouchEnd, this);
26432
this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnTouchEnd, this);
26433
if (!isCancel)
26434
this.touches[j].maybeTriggerTap(this, j);
26435
ReleaseTouchInfo(this.touches[j]);
26436
this.touches.splice(j, 1);
26437
}
26438
}
26439
this.runtime.isInUserInputEvent = false;
26440
};
26441
instanceProto.getAlpha = function ()
26442
{
26443
if (this.runtime.isCordova && this.orient_alpha === 0 && pg_accz !== 0)
26444
return pg_accz * 90;
26445
else
26446
return this.orient_alpha;
26447
};
26448
instanceProto.getBeta = function ()
26449
{
26450
if (this.runtime.isCordova && this.orient_beta === 0 && pg_accy !== 0)
26451
return pg_accy * 90;
26452
else
26453
return this.orient_beta;
26454
};
26455
instanceProto.getGamma = function ()
26456
{
26457
if (this.runtime.isCordova && this.orient_gamma === 0 && pg_accx !== 0)
26458
return pg_accx * 90;
26459
else
26460
return this.orient_gamma;
26461
};
26462
var noop_func = function(){};
26463
function isCompatibilityMouseEvent(e)
26464
{
26465
return (e["sourceCapabilities"] && e["sourceCapabilities"]["firesTouchEvents"]) ||
26466
(e.originalEvent && e.originalEvent["sourceCapabilities"] && e.originalEvent["sourceCapabilities"]["firesTouchEvents"]);
26467
};
26468
instanceProto.onMouseDown = function(info)
26469
{
26470
if (isCompatibilityMouseEvent(info))
26471
return;
26472
var t = { pageX: info.pageX, pageY: info.pageY, "identifier": 0 };
26473
var fakeinfo = { changedTouches: [t] };
26474
this.onTouchStart(fakeinfo);
26475
this.mouseDown = true;
26476
};
26477
instanceProto.onMouseMove = function(info)
26478
{
26479
if (!this.mouseDown)
26480
return;
26481
if (isCompatibilityMouseEvent(info))
26482
return;
26483
var t = { pageX: info.pageX, pageY: info.pageY, "identifier": 0 };
26484
var fakeinfo = { changedTouches: [t] };
26485
this.onTouchMove(fakeinfo);
26486
};
26487
instanceProto.onMouseUp = function(info)
26488
{
26489
if (info.preventDefault && this.runtime.had_a_click && !this.runtime.isMobile)
26490
info.preventDefault();
26491
this.runtime.had_a_click = true;
26492
if (isCompatibilityMouseEvent(info))
26493
return;
26494
var t = { pageX: info.pageX, pageY: info.pageY, "identifier": 0 };
26495
var fakeinfo = { changedTouches: [t] };
26496
this.onTouchEnd(fakeinfo);
26497
this.mouseDown = false;
26498
};
26499
instanceProto.tick2 = function()
26500
{
26501
var i, len, t;
26502
var nowtime = cr.performance_now();
26503
for (i = 0, len = this.touches.length; i < len; ++i)
26504
{
26505
t = this.touches[i];
26506
if (t.time <= nowtime - 50)
26507
t.lasttime = nowtime;
26508
t.maybeTriggerHold(this, i);
26509
}
26510
};
26511
function Cnds() {};
26512
Cnds.prototype.OnTouchStart = function ()
26513
{
26514
return true;
26515
};
26516
Cnds.prototype.OnTouchEnd = function ()
26517
{
26518
return true;
26519
};
26520
Cnds.prototype.IsInTouch = function ()
26521
{
26522
return this.touches.length;
26523
};
26524
Cnds.prototype.OnTouchObject = function (type)
26525
{
26526
if (!type)
26527
return false;
26528
return this.runtime.testAndSelectCanvasPointOverlap(type, this.curTouchX, this.curTouchY, false);
26529
};
26530
var touching = [];
26531
Cnds.prototype.IsTouchingObject = function (type)
26532
{
26533
if (!type)
26534
return false;
26535
var sol = type.getCurrentSol();
26536
var instances = sol.getObjects();
26537
var px, py;
26538
var i, leni, j, lenj;
26539
for (i = 0, leni = instances.length; i < leni; i++)
26540
{
26541
var inst = instances[i];
26542
inst.update_bbox();
26543
for (j = 0, lenj = this.touches.length; j < lenj; j++)
26544
{
26545
var touch = this.touches[j];
26546
px = inst.layer.canvasToLayer(touch.x, touch.y, true);
26547
py = inst.layer.canvasToLayer(touch.x, touch.y, false);
26548
if (inst.contains_pt(px, py))
26549
{
26550
touching.push(inst);
26551
break;
26552
}
26553
}
26554
}
26555
if (touching.length)
26556
{
26557
sol.select_all = false;
26558
cr.shallowAssignArray(sol.instances, touching);
26559
type.applySolToContainer();
26560
cr.clearArray(touching);
26561
return true;
26562
}
26563
else
26564
return false;
26565
};
26566
Cnds.prototype.CompareTouchSpeed = function (index, cmp, s)
26567
{
26568
index = Math.floor(index);
26569
if (index < 0 || index >= this.touches.length)
26570
return false;
26571
var t = this.touches[index];
26572
var dist = cr.distanceTo(t.x, t.y, t.lastx, t.lasty);
26573
var timediff = (t.time - t.lasttime) / 1000;
26574
var speed = 0;
26575
if (timediff > 0)
26576
speed = dist / timediff;
26577
return cr.do_cmp(speed, cmp, s);
26578
};
26579
Cnds.prototype.OrientationSupported = function ()
26580
{
26581
return typeof window["DeviceOrientationEvent"] !== "undefined";
26582
};
26583
Cnds.prototype.MotionSupported = function ()
26584
{
26585
return typeof window["DeviceMotionEvent"] !== "undefined";
26586
};
26587
Cnds.prototype.CompareOrientation = function (orientation_, cmp_, angle_)
26588
{
26589
var v = 0;
26590
if (orientation_ === 0)
26591
v = this.getAlpha();
26592
else if (orientation_ === 1)
26593
v = this.getBeta();
26594
else
26595
v = this.getGamma();
26596
return cr.do_cmp(v, cmp_, angle_);
26597
};
26598
Cnds.prototype.CompareAcceleration = function (acceleration_, cmp_, angle_)
26599
{
26600
var v = 0;
26601
if (acceleration_ === 0)
26602
v = this.acc_g_x;
26603
else if (acceleration_ === 1)
26604
v = this.acc_g_y;
26605
else if (acceleration_ === 2)
26606
v = this.acc_g_z;
26607
else if (acceleration_ === 3)
26608
v = this.acc_x;
26609
else if (acceleration_ === 4)
26610
v = this.acc_y;
26611
else if (acceleration_ === 5)
26612
v = this.acc_z;
26613
return cr.do_cmp(v, cmp_, angle_);
26614
};
26615
Cnds.prototype.OnNthTouchStart = function (touch_)
26616
{
26617
touch_ = Math.floor(touch_);
26618
return touch_ === this.trigger_index;
26619
};
26620
Cnds.prototype.OnNthTouchEnd = function (touch_)
26621
{
26622
touch_ = Math.floor(touch_);
26623
return touch_ === this.trigger_index;
26624
};
26625
Cnds.prototype.HasNthTouch = function (touch_)
26626
{
26627
touch_ = Math.floor(touch_);
26628
return this.touches.length >= touch_ + 1;
26629
};
26630
Cnds.prototype.OnHoldGesture = function ()
26631
{
26632
return true;
26633
};
26634
Cnds.prototype.OnTapGesture = function ()
26635
{
26636
return true;
26637
};
26638
Cnds.prototype.OnDoubleTapGesture = function ()
26639
{
26640
return true;
26641
};
26642
Cnds.prototype.OnHoldGestureObject = function (type)
26643
{
26644
if (!type)
26645
return false;
26646
return this.runtime.testAndSelectCanvasPointOverlap(type, this.curTouchX, this.curTouchY, false);
26647
};
26648
Cnds.prototype.OnTapGestureObject = function (type)
26649
{
26650
if (!type)
26651
return false;
26652
return this.runtime.testAndSelectCanvasPointOverlap(type, this.curTouchX, this.curTouchY, false);
26653
};
26654
Cnds.prototype.OnDoubleTapGestureObject = function (type)
26655
{
26656
if (!type)
26657
return false;
26658
return this.runtime.testAndSelectCanvasPointOverlap(type, this.curTouchX, this.curTouchY, false);
26659
};
26660
Cnds.prototype.OnPermissionGranted = function (type)
26661
{
26662
return this.trigger_permission === type;
26663
};
26664
Cnds.prototype.OnPermissionDenied = function (type)
26665
{
26666
return this.trigger_permission === type;
26667
};
26668
pluginProto.cnds = new Cnds();
26669
function Acts() {};
26670
Acts.prototype.RequestPermission = function (type)
26671
{
26672
var self = this;
26673
var promise = Promise.resolve(true);
26674
if (type === 0) // orientation
26675
{
26676
if (window["DeviceOrientationEvent"] && window["DeviceOrientationEvent"]["requestPermission"])
26677
{
26678
promise = window["DeviceOrientationEvent"]["requestPermission"]()
26679
.then(function (state)
26680
{
26681
return state === "granted";
26682
});
26683
}
26684
}
26685
else // motion
26686
{
26687
if (window["DeviceMotionEvent"] && window["DeviceMotionEvent"]["requestPermission"])
26688
{
26689
promise = window["DeviceMotionEvent"]["requestPermission"]()
26690
.then(function (state)
26691
{
26692
return state === "granted";
26693
});
26694
}
26695
}
26696
promise.then(function (result)
26697
{
26698
self.trigger_permission = type;
26699
if (result)
26700
self.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnPermissionGranted, self);
26701
else
26702
self.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnPermissionDenied, self);
26703
});
26704
};
26705
pluginProto.acts = new Acts();
26706
function Exps() {};
26707
Exps.prototype.TouchCount = function (ret)
26708
{
26709
ret.set_int(this.touches.length);
26710
};
26711
Exps.prototype.X = function (ret, layerparam)
26712
{
26713
var index = this.getTouchIndex;
26714
if (index < 0 || index >= this.touches.length)
26715
{
26716
ret.set_float(0);
26717
return;
26718
}
26719
var layer, oldScale, oldZoomRate, oldParallaxX, oldAngle;
26720
if (cr.is_undefined(layerparam))
26721
{
26722
layer = this.runtime.getLayerByNumber(0);
26723
oldScale = layer.scale;
26724
oldZoomRate = layer.zoomRate;
26725
oldParallaxX = layer.parallaxX;
26726
oldAngle = layer.angle;
26727
layer.scale = 1;
26728
layer.zoomRate = 1.0;
26729
layer.parallaxX = 1.0;
26730
layer.angle = 0;
26731
ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, true));
26732
layer.scale = oldScale;
26733
layer.zoomRate = oldZoomRate;
26734
layer.parallaxX = oldParallaxX;
26735
layer.angle = oldAngle;
26736
}
26737
else
26738
{
26739
if (cr.is_number(layerparam))
26740
layer = this.runtime.getLayerByNumber(layerparam);
26741
else
26742
layer = this.runtime.getLayerByName(layerparam);
26743
if (layer)
26744
ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, true));
26745
else
26746
ret.set_float(0);
26747
}
26748
};
26749
Exps.prototype.XAt = function (ret, index, layerparam)
26750
{
26751
index = Math.floor(index);
26752
if (index < 0 || index >= this.touches.length)
26753
{
26754
ret.set_float(0);
26755
return;
26756
}
26757
var layer, oldScale, oldZoomRate, oldParallaxX, oldAngle;
26758
if (cr.is_undefined(layerparam))
26759
{
26760
layer = this.runtime.getLayerByNumber(0);
26761
oldScale = layer.scale;
26762
oldZoomRate = layer.zoomRate;
26763
oldParallaxX = layer.parallaxX;
26764
oldAngle = layer.angle;
26765
layer.scale = 1;
26766
layer.zoomRate = 1.0;
26767
layer.parallaxX = 1.0;
26768
layer.angle = 0;
26769
ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, true));
26770
layer.scale = oldScale;
26771
layer.zoomRate = oldZoomRate;
26772
layer.parallaxX = oldParallaxX;
26773
layer.angle = oldAngle;
26774
}
26775
else
26776
{
26777
if (cr.is_number(layerparam))
26778
layer = this.runtime.getLayerByNumber(layerparam);
26779
else
26780
layer = this.runtime.getLayerByName(layerparam);
26781
if (layer)
26782
ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, true));
26783
else
26784
ret.set_float(0);
26785
}
26786
};
26787
Exps.prototype.XForID = function (ret, id, layerparam)
26788
{
26789
var index = this.findTouch(id);
26790
if (index < 0)
26791
{
26792
ret.set_float(0);
26793
return;
26794
}
26795
var touch = this.touches[index];
26796
var layer, oldScale, oldZoomRate, oldParallaxX, oldAngle;
26797
if (cr.is_undefined(layerparam))
26798
{
26799
layer = this.runtime.getLayerByNumber(0);
26800
oldScale = layer.scale;
26801
oldZoomRate = layer.zoomRate;
26802
oldParallaxX = layer.parallaxX;
26803
oldAngle = layer.angle;
26804
layer.scale = 1;
26805
layer.zoomRate = 1.0;
26806
layer.parallaxX = 1.0;
26807
layer.angle = 0;
26808
ret.set_float(layer.canvasToLayer(touch.x, touch.y, true));
26809
layer.scale = oldScale;
26810
layer.zoomRate = oldZoomRate;
26811
layer.parallaxX = oldParallaxX;
26812
layer.angle = oldAngle;
26813
}
26814
else
26815
{
26816
if (cr.is_number(layerparam))
26817
layer = this.runtime.getLayerByNumber(layerparam);
26818
else
26819
layer = this.runtime.getLayerByName(layerparam);
26820
if (layer)
26821
ret.set_float(layer.canvasToLayer(touch.x, touch.y, true));
26822
else
26823
ret.set_float(0);
26824
}
26825
};
26826
Exps.prototype.Y = function (ret, layerparam)
26827
{
26828
var index = this.getTouchIndex;
26829
if (index < 0 || index >= this.touches.length)
26830
{
26831
ret.set_float(0);
26832
return;
26833
}
26834
var layer, oldScale, oldZoomRate, oldParallaxY, oldAngle;
26835
if (cr.is_undefined(layerparam))
26836
{
26837
layer = this.runtime.getLayerByNumber(0);
26838
oldScale = layer.scale;
26839
oldZoomRate = layer.zoomRate;
26840
oldParallaxY = layer.parallaxY;
26841
oldAngle = layer.angle;
26842
layer.scale = 1;
26843
layer.zoomRate = 1.0;
26844
layer.parallaxY = 1.0;
26845
layer.angle = 0;
26846
ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, false));
26847
layer.scale = oldScale;
26848
layer.zoomRate = oldZoomRate;
26849
layer.parallaxY = oldParallaxY;
26850
layer.angle = oldAngle;
26851
}
26852
else
26853
{
26854
if (cr.is_number(layerparam))
26855
layer = this.runtime.getLayerByNumber(layerparam);
26856
else
26857
layer = this.runtime.getLayerByName(layerparam);
26858
if (layer)
26859
ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, false));
26860
else
26861
ret.set_float(0);
26862
}
26863
};
26864
Exps.prototype.YAt = function (ret, index, layerparam)
26865
{
26866
index = Math.floor(index);
26867
if (index < 0 || index >= this.touches.length)
26868
{
26869
ret.set_float(0);
26870
return;
26871
}
26872
var layer, oldScale, oldZoomRate, oldParallaxY, oldAngle;
26873
if (cr.is_undefined(layerparam))
26874
{
26875
layer = this.runtime.getLayerByNumber(0);
26876
oldScale = layer.scale;
26877
oldZoomRate = layer.zoomRate;
26878
oldParallaxY = layer.parallaxY;
26879
oldAngle = layer.angle;
26880
layer.scale = 1;
26881
layer.zoomRate = 1.0;
26882
layer.parallaxY = 1.0;
26883
layer.angle = 0;
26884
ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, false));
26885
layer.scale = oldScale;
26886
layer.zoomRate = oldZoomRate;
26887
layer.parallaxY = oldParallaxY;
26888
layer.angle = oldAngle;
26889
}
26890
else
26891
{
26892
if (cr.is_number(layerparam))
26893
layer = this.runtime.getLayerByNumber(layerparam);
26894
else
26895
layer = this.runtime.getLayerByName(layerparam);
26896
if (layer)
26897
ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, false));
26898
else
26899
ret.set_float(0);
26900
}
26901
};
26902
Exps.prototype.YForID = function (ret, id, layerparam)
26903
{
26904
var index = this.findTouch(id);
26905
if (index < 0)
26906
{
26907
ret.set_float(0);
26908
return;
26909
}
26910
var touch = this.touches[index];
26911
var layer, oldScale, oldZoomRate, oldParallaxY, oldAngle;
26912
if (cr.is_undefined(layerparam))
26913
{
26914
layer = this.runtime.getLayerByNumber(0);
26915
oldScale = layer.scale;
26916
oldZoomRate = layer.zoomRate;
26917
oldParallaxY = layer.parallaxY;
26918
oldAngle = layer.angle;
26919
layer.scale = 1;
26920
layer.zoomRate = 1.0;
26921
layer.parallaxY = 1.0;
26922
layer.angle = 0;
26923
ret.set_float(layer.canvasToLayer(touch.x, touch.y, false));
26924
layer.scale = oldScale;
26925
layer.zoomRate = oldZoomRate;
26926
layer.parallaxY = oldParallaxY;
26927
layer.angle = oldAngle;
26928
}
26929
else
26930
{
26931
if (cr.is_number(layerparam))
26932
layer = this.runtime.getLayerByNumber(layerparam);
26933
else
26934
layer = this.runtime.getLayerByName(layerparam);
26935
if (layer)
26936
ret.set_float(layer.canvasToLayer(touch.x, touch.y, false));
26937
else
26938
ret.set_float(0);
26939
}
26940
};
26941
Exps.prototype.AbsoluteX = function (ret)
26942
{
26943
if (this.touches.length)
26944
ret.set_float(this.touches[0].x);
26945
else
26946
ret.set_float(0);
26947
};
26948
Exps.prototype.AbsoluteXAt = function (ret, index)
26949
{
26950
index = Math.floor(index);
26951
if (index < 0 || index >= this.touches.length)
26952
{
26953
ret.set_float(0);
26954
return;
26955
}
26956
ret.set_float(this.touches[index].x);
26957
};
26958
Exps.prototype.AbsoluteXForID = function (ret, id)
26959
{
26960
var index = this.findTouch(id);
26961
if (index < 0)
26962
{
26963
ret.set_float(0);
26964
return;
26965
}
26966
var touch = this.touches[index];
26967
ret.set_float(touch.x);
26968
};
26969
Exps.prototype.AbsoluteY = function (ret)
26970
{
26971
if (this.touches.length)
26972
ret.set_float(this.touches[0].y);
26973
else
26974
ret.set_float(0);
26975
};
26976
Exps.prototype.AbsoluteYAt = function (ret, index)
26977
{
26978
index = Math.floor(index);
26979
if (index < 0 || index >= this.touches.length)
26980
{
26981
ret.set_float(0);
26982
return;
26983
}
26984
ret.set_float(this.touches[index].y);
26985
};
26986
Exps.prototype.AbsoluteYForID = function (ret, id)
26987
{
26988
var index = this.findTouch(id);
26989
if (index < 0)
26990
{
26991
ret.set_float(0);
26992
return;
26993
}
26994
var touch = this.touches[index];
26995
ret.set_float(touch.y);
26996
};
26997
Exps.prototype.SpeedAt = function (ret, index)
26998
{
26999
index = Math.floor(index);
27000
if (index < 0 || index >= this.touches.length)
27001
{
27002
ret.set_float(0);
27003
return;
27004
}
27005
var t = this.touches[index];
27006
var dist = cr.distanceTo(t.x, t.y, t.lastx, t.lasty);
27007
var timediff = (t.time - t.lasttime) / 1000;
27008
if (timediff <= 0)
27009
ret.set_float(0);
27010
else
27011
ret.set_float(dist / timediff);
27012
};
27013
Exps.prototype.SpeedForID = function (ret, id)
27014
{
27015
var index = this.findTouch(id);
27016
if (index < 0)
27017
{
27018
ret.set_float(0);
27019
return;
27020
}
27021
var touch = this.touches[index];
27022
var dist = cr.distanceTo(touch.x, touch.y, touch.lastx, touch.lasty);
27023
var timediff = (touch.time - touch.lasttime) / 1000;
27024
if (timediff <= 0)
27025
ret.set_float(0);
27026
else
27027
ret.set_float(dist / timediff);
27028
};
27029
Exps.prototype.AngleAt = function (ret, index)
27030
{
27031
index = Math.floor(index);
27032
if (index < 0 || index >= this.touches.length)
27033
{
27034
ret.set_float(0);
27035
return;
27036
}
27037
var t = this.touches[index];
27038
ret.set_float(cr.to_degrees(cr.angleTo(t.lastx, t.lasty, t.x, t.y)));
27039
};
27040
Exps.prototype.AngleForID = function (ret, id)
27041
{
27042
var index = this.findTouch(id);
27043
if (index < 0)
27044
{
27045
ret.set_float(0);
27046
return;
27047
}
27048
var touch = this.touches[index];
27049
ret.set_float(cr.to_degrees(cr.angleTo(touch.lastx, touch.lasty, touch.x, touch.y)));
27050
};
27051
Exps.prototype.Alpha = function (ret)
27052
{
27053
ret.set_float(this.getAlpha());
27054
};
27055
Exps.prototype.Beta = function (ret)
27056
{
27057
ret.set_float(this.getBeta());
27058
};
27059
Exps.prototype.Gamma = function (ret)
27060
{
27061
ret.set_float(this.getGamma());
27062
};
27063
Exps.prototype.AccelerationXWithG = function (ret)
27064
{
27065
ret.set_float(this.acc_g_x);
27066
};
27067
Exps.prototype.AccelerationYWithG = function (ret)
27068
{
27069
ret.set_float(this.acc_g_y);
27070
};
27071
Exps.prototype.AccelerationZWithG = function (ret)
27072
{
27073
ret.set_float(this.acc_g_z);
27074
};
27075
Exps.prototype.AccelerationX = function (ret)
27076
{
27077
ret.set_float(this.acc_x);
27078
};
27079
Exps.prototype.AccelerationY = function (ret)
27080
{
27081
ret.set_float(this.acc_y);
27082
};
27083
Exps.prototype.AccelerationZ = function (ret)
27084
{
27085
ret.set_float(this.acc_z);
27086
};
27087
Exps.prototype.TouchIndex = function (ret)
27088
{
27089
ret.set_int(this.trigger_index);
27090
};
27091
Exps.prototype.TouchID = function (ret)
27092
{
27093
ret.set_float(this.trigger_id);
27094
};
27095
Exps.prototype.WidthForID = function (ret, id)
27096
{
27097
var index = this.findTouch(id);
27098
if (index < 0)
27099
{
27100
ret.set_float(0);
27101
return;
27102
}
27103
var touch = this.touches[index];
27104
ret.set_float(touch.width);
27105
};
27106
Exps.prototype.HeightForID = function (ret, id)
27107
{
27108
var index = this.findTouch(id);
27109
if (index < 0)
27110
{
27111
ret.set_float(0);
27112
return;
27113
}
27114
var touch = this.touches[index];
27115
ret.set_float(touch.height);
27116
};
27117
Exps.prototype.PressureForID = function (ret, id)
27118
{
27119
var index = this.findTouch(id);
27120
if (index < 0)
27121
{
27122
ret.set_float(0);
27123
return;
27124
}
27125
var touch = this.touches[index];
27126
ret.set_float(touch.pressure);
27127
};
27128
pluginProto.exps = new Exps();
27129
}());
27130
;
27131
;
27132
cr.behaviors.Anchor = function(runtime)
27133
{
27134
this.runtime = runtime;
27135
};
27136
(function ()
27137
{
27138
var behaviorProto = cr.behaviors.Anchor.prototype;
27139
behaviorProto.Type = function(behavior, objtype)
27140
{
27141
this.behavior = behavior;
27142
this.objtype = objtype;
27143
this.runtime = behavior.runtime;
27144
};
27145
var behtypeProto = behaviorProto.Type.prototype;
27146
behtypeProto.onCreate = function()
27147
{
27148
};
27149
behaviorProto.Instance = function(type, inst)
27150
{
27151
this.type = type;
27152
this.behavior = type.behavior;
27153
this.inst = inst; // associated object instance to modify
27154
this.runtime = type.runtime;
27155
};
27156
var behinstProto = behaviorProto.Instance.prototype;
27157
behinstProto.onCreate = function()
27158
{
27159
this.anch_left = this.properties[0]; // 0 = left, 1 = right, 2 = none
27160
this.anch_top = this.properties[1]; // 0 = top, 1 = bottom, 2 = none
27161
this.anch_right = this.properties[2]; // 0 = none, 1 = right
27162
this.anch_bottom = this.properties[3]; // 0 = none, 1 = bottom
27163
this.inst.update_bbox();
27164
this.xleft = this.inst.bbox.left;
27165
this.ytop = this.inst.bbox.top;
27166
this.xright = this.runtime.original_width - this.inst.bbox.left;
27167
this.ybottom = this.runtime.original_height - this.inst.bbox.top;
27168
this.rdiff = this.runtime.original_width - this.inst.bbox.right;
27169
this.bdiff = this.runtime.original_height - this.inst.bbox.bottom;
27170
this.enabled = (this.properties[4] !== 0);
27171
};
27172
behinstProto.saveToJSON = function ()
27173
{
27174
return {
27175
"xleft": this.xleft,
27176
"ytop": this.ytop,
27177
"xright": this.xright,
27178
"ybottom": this.ybottom,
27179
"rdiff": this.rdiff,
27180
"bdiff": this.bdiff,
27181
"enabled": this.enabled
27182
};
27183
};
27184
behinstProto.loadFromJSON = function (o)
27185
{
27186
this.xleft = o["xleft"];
27187
this.ytop = o["ytop"];
27188
this.xright = o["xright"];
27189
this.ybottom = o["ybottom"];
27190
this.rdiff = o["rdiff"];
27191
this.bdiff = o["bdiff"];
27192
this.enabled = o["enabled"];
27193
};
27194
behinstProto.tick = function ()
27195
{
27196
if (!this.enabled)
27197
return;
27198
var n;
27199
var layer = this.inst.layer;
27200
var inst = this.inst;
27201
var bbox = this.inst.bbox;
27202
if (this.anch_left === 0)
27203
{
27204
inst.update_bbox();
27205
n = (layer.viewLeft + this.xleft) - bbox.left;
27206
if (n !== 0)
27207
{
27208
inst.x += n;
27209
inst.set_bbox_changed();
27210
}
27211
}
27212
else if (this.anch_left === 1)
27213
{
27214
inst.update_bbox();
27215
n = (layer.viewRight - this.xright) - bbox.left;
27216
if (n !== 0)
27217
{
27218
inst.x += n;
27219
inst.set_bbox_changed();
27220
}
27221
}
27222
if (this.anch_top === 0)
27223
{
27224
inst.update_bbox();
27225
n = (layer.viewTop + this.ytop) - bbox.top;
27226
if (n !== 0)
27227
{
27228
inst.y += n;
27229
inst.set_bbox_changed();
27230
}
27231
}
27232
else if (this.anch_top === 1)
27233
{
27234
inst.update_bbox();
27235
n = (layer.viewBottom - this.ybottom) - bbox.top;
27236
if (n !== 0)
27237
{
27238
inst.y += n;
27239
inst.set_bbox_changed();
27240
}
27241
}
27242
if (this.anch_right === 1)
27243
{
27244
inst.update_bbox();
27245
n = (layer.viewRight - this.rdiff) - bbox.right;
27246
if (n !== 0)
27247
{
27248
inst.width += n;
27249
if (inst.width < 0)
27250
inst.width = 0;
27251
inst.set_bbox_changed();
27252
}
27253
}
27254
if (this.anch_bottom === 1)
27255
{
27256
inst.update_bbox();
27257
n = (layer.viewBottom - this.bdiff) - bbox.bottom;
27258
if (n !== 0)
27259
{
27260
inst.height += n;
27261
if (inst.height < 0)
27262
inst.height = 0;
27263
inst.set_bbox_changed();
27264
}
27265
}
27266
};
27267
function Cnds() {};
27268
behaviorProto.cnds = new Cnds();
27269
function Acts() {};
27270
Acts.prototype.SetEnabled = function (e)
27271
{
27272
if (this.enabled && e === 0)
27273
this.enabled = false;
27274
else if (!this.enabled && e !== 0)
27275
{
27276
this.inst.update_bbox();
27277
this.xleft = this.inst.bbox.left;
27278
this.ytop = this.inst.bbox.top;
27279
this.xright = this.runtime.original_width - this.inst.bbox.left;
27280
this.ybottom = this.runtime.original_height - this.inst.bbox.top;
27281
this.rdiff = this.runtime.original_width - this.inst.bbox.right;
27282
this.bdiff = this.runtime.original_height - this.inst.bbox.bottom;
27283
this.enabled = true;
27284
}
27285
};
27286
behaviorProto.acts = new Acts();
27287
function Exps() {};
27288
behaviorProto.exps = new Exps();
27289
}());
27290
;
27291
;
27292
cr.behaviors.Fade = function(runtime)
27293
{
27294
this.runtime = runtime;
27295
};
27296
(function ()
27297
{
27298
var behaviorProto = cr.behaviors.Fade.prototype;
27299
behaviorProto.Type = function(behavior, objtype)
27300
{
27301
this.behavior = behavior;
27302
this.objtype = objtype;
27303
this.runtime = behavior.runtime;
27304
};
27305
var behtypeProto = behaviorProto.Type.prototype;
27306
behtypeProto.onCreate = function()
27307
{
27308
};
27309
behaviorProto.Instance = function(type, inst)
27310
{
27311
this.type = type;
27312
this.behavior = type.behavior;
27313
this.inst = inst; // associated object instance to modify
27314
this.runtime = type.runtime;
27315
};
27316
var behinstProto = behaviorProto.Instance.prototype;
27317
behinstProto.onCreate = function()
27318
{
27319
this.activeAtStart = this.properties[0] === 1;
27320
this.setMaxOpacity = false; // used to retrieve maxOpacity once in first 'Start fade' action if initially inactive
27321
this.fadeInTime = this.properties[1];
27322
this.waitTime = this.properties[2];
27323
this.fadeOutTime = this.properties[3];
27324
this.destroy = this.properties[4]; // 0 = no, 1 = after fade out
27325
this.stage = this.activeAtStart ? 0 : 3; // 0 = fade in, 1 = wait, 2 = fade out, 3 = done
27326
if (this.recycled)
27327
this.stageTime.reset();
27328
else
27329
this.stageTime = new cr.KahanAdder();
27330
this.maxOpacity = (this.inst.opacity ? this.inst.opacity : 1.0);
27331
if (this.activeAtStart)
27332
{
27333
if (this.fadeInTime === 0)
27334
{
27335
this.stage = 1;
27336
if (this.waitTime === 0)
27337
this.stage = 2;
27338
}
27339
else
27340
{
27341
this.inst.opacity = 0;
27342
this.runtime.redraw = true;
27343
}
27344
}
27345
};
27346
behinstProto.saveToJSON = function ()
27347
{
27348
return {
27349
"fit": this.fadeInTime,
27350
"wt": this.waitTime,
27351
"fot": this.fadeOutTime,
27352
"s": this.stage,
27353
"st": this.stageTime.sum,
27354
"mo": this.maxOpacity,
27355
};
27356
};
27357
behinstProto.loadFromJSON = function (o)
27358
{
27359
this.fadeInTime = o["fit"];
27360
this.waitTime = o["wt"];
27361
this.fadeOutTime = o["fot"];
27362
this.stage = o["s"];
27363
this.stageTime.reset();
27364
this.stageTime.sum = o["st"];
27365
this.maxOpacity = o["mo"];
27366
};
27367
behinstProto.tick = function ()
27368
{
27369
this.stageTime.add(this.runtime.getDt(this.inst));
27370
if (this.stage === 0)
27371
{
27372
this.inst.opacity = (this.stageTime.sum / this.fadeInTime) * this.maxOpacity;
27373
this.runtime.redraw = true;
27374
if (this.inst.opacity >= this.maxOpacity)
27375
{
27376
this.inst.opacity = this.maxOpacity;
27377
this.stage = 1; // wait stage
27378
this.stageTime.reset();
27379
this.runtime.trigger(cr.behaviors.Fade.prototype.cnds.OnFadeInEnd, this.inst);
27380
}
27381
}
27382
if (this.stage === 1)
27383
{
27384
if (this.stageTime.sum >= this.waitTime)
27385
{
27386
this.stage = 2; // fade out stage
27387
this.stageTime.reset();
27388
this.runtime.trigger(cr.behaviors.Fade.prototype.cnds.OnWaitEnd, this.inst);
27389
}
27390
}
27391
if (this.stage === 2)
27392
{
27393
if (this.fadeOutTime !== 0)
27394
{
27395
this.inst.opacity = this.maxOpacity - ((this.stageTime.sum / this.fadeOutTime) * this.maxOpacity);
27396
this.runtime.redraw = true;
27397
if (this.inst.opacity < 0)
27398
{
27399
this.inst.opacity = 0;
27400
this.stage = 3; // done
27401
this.stageTime.reset();
27402
this.runtime.trigger(cr.behaviors.Fade.prototype.cnds.OnFadeOutEnd, this.inst);
27403
if (this.destroy === 1)
27404
this.runtime.DestroyInstance(this.inst);
27405
}
27406
}
27407
}
27408
};
27409
behinstProto.doStart = function ()
27410
{
27411
this.stage = 0;
27412
this.stageTime.reset();
27413
if (this.fadeInTime === 0)
27414
{
27415
this.stage = 1;
27416
if (this.waitTime === 0)
27417
this.stage = 2;
27418
}
27419
else
27420
{
27421
this.inst.opacity = 0;
27422
this.runtime.redraw = true;
27423
}
27424
};
27425
function Cnds() {};
27426
Cnds.prototype.OnFadeOutEnd = function ()
27427
{
27428
return true;
27429
};
27430
Cnds.prototype.OnFadeInEnd = function ()
27431
{
27432
return true;
27433
};
27434
Cnds.prototype.OnWaitEnd = function ()
27435
{
27436
return true;
27437
};
27438
behaviorProto.cnds = new Cnds();
27439
function Acts() {};
27440
Acts.prototype.StartFade = function ()
27441
{
27442
if (!this.activeAtStart && !this.setMaxOpacity)
27443
{
27444
this.maxOpacity = (this.inst.opacity ? this.inst.opacity : 1.0);
27445
this.setMaxOpacity = true;
27446
}
27447
if (this.stage === 3)
27448
this.doStart();
27449
};
27450
Acts.prototype.RestartFade = function ()
27451
{
27452
this.doStart();
27453
};
27454
Acts.prototype.SetFadeInTime = function (t)
27455
{
27456
if (t < 0)
27457
t = 0;
27458
this.fadeInTime = t;
27459
};
27460
Acts.prototype.SetWaitTime = function (t)
27461
{
27462
if (t < 0)
27463
t = 0;
27464
this.waitTime = t;
27465
};
27466
Acts.prototype.SetFadeOutTime = function (t)
27467
{
27468
if (t < 0)
27469
t = 0;
27470
this.fadeOutTime = t;
27471
};
27472
behaviorProto.acts = new Acts();
27473
function Exps() {};
27474
Exps.prototype.FadeInTime = function (ret)
27475
{
27476
ret.set_float(this.fadeInTime);
27477
};
27478
Exps.prototype.WaitTime = function (ret)
27479
{
27480
ret.set_float(this.waitTime);
27481
};
27482
Exps.prototype.FadeOutTime = function (ret)
27483
{
27484
ret.set_float(this.fadeOutTime);
27485
};
27486
behaviorProto.exps = new Exps();
27487
}());
27488
;
27489
;
27490
cr.behaviors.Flash = function(runtime)
27491
{
27492
this.runtime = runtime;
27493
};
27494
(function ()
27495
{
27496
var behaviorProto = cr.behaviors.Flash.prototype;
27497
behaviorProto.Type = function(behavior, objtype)
27498
{
27499
this.behavior = behavior;
27500
this.objtype = objtype;
27501
this.runtime = behavior.runtime;
27502
};
27503
var behtypeProto = behaviorProto.Type.prototype;
27504
behtypeProto.onCreate = function()
27505
{
27506
};
27507
behaviorProto.Instance = function(type, inst)
27508
{
27509
this.type = type;
27510
this.behavior = type.behavior;
27511
this.inst = inst; // associated object instance to modify
27512
this.runtime = type.runtime;
27513
};
27514
var behinstProto = behaviorProto.Instance.prototype;
27515
behinstProto.onCreate = function()
27516
{
27517
this.ontime = 0;
27518
this.offtime = 0;
27519
this.stage = 0; // 0 = on, 1 = off
27520
this.stagetimeleft = 0;
27521
this.timeleft = 0;
27522
};
27523
behinstProto.saveToJSON = function ()
27524
{
27525
return {
27526
"ontime": this.ontime,
27527
"offtime": this.offtime,
27528
"stage": this.stage,
27529
"stagetimeleft": this.stagetimeleft,
27530
"timeleft": this.timeleft
27531
};
27532
};
27533
behinstProto.loadFromJSON = function (o)
27534
{
27535
this.ontime = o["ontime"];
27536
this.offtime = o["offtime"];
27537
this.stage = o["stage"];
27538
this.stagetimeleft = o["stagetimeleft"];
27539
this.timeleft = o["timeleft"];
27540
if (this.timeleft === null)
27541
this.timeleft = Infinity;
27542
};
27543
behinstProto.tick = function ()
27544
{
27545
if (this.timeleft <= 0)
27546
return; // not flashing
27547
var dt = this.runtime.getDt(this.inst);
27548
this.timeleft -= dt;
27549
if (this.timeleft <= 0)
27550
{
27551
this.timeleft = 0;
27552
this.inst.visible = true;
27553
this.runtime.redraw = true;
27554
this.runtime.trigger(cr.behaviors.Flash.prototype.cnds.OnFlashEnded, this.inst);
27555
return;
27556
}
27557
this.stagetimeleft -= dt;
27558
if (this.stagetimeleft <= 0)
27559
{
27560
if (this.stage === 0)
27561
{
27562
this.inst.visible = false;
27563
this.stage = 1;
27564
this.stagetimeleft += this.offtime;
27565
}
27566
else
27567
{
27568
this.inst.visible = true;
27569
this.stage = 0;
27570
this.stagetimeleft += this.ontime;
27571
}
27572
this.runtime.redraw = true;
27573
}
27574
};
27575
function Cnds() {};
27576
Cnds.prototype.IsFlashing = function ()
27577
{
27578
return this.timeleft > 0;
27579
};
27580
Cnds.prototype.OnFlashEnded = function ()
27581
{
27582
return true;
27583
};
27584
behaviorProto.cnds = new Cnds();
27585
function Acts() {};
27586
Acts.prototype.Flash = function (on_, off_, dur_)
27587
{
27588
this.ontime = on_;
27589
this.offtime = off_;
27590
this.stage = 1; // always start off
27591
this.stagetimeleft = off_;
27592
this.timeleft = dur_;
27593
this.inst.visible = false;
27594
this.runtime.redraw = true;
27595
};
27596
Acts.prototype.StopFlashing = function ()
27597
{
27598
this.timeleft = 0;
27599
this.inst.visible = true;
27600
this.runtime.redraw = true;
27601
return;
27602
};
27603
behaviorProto.acts = new Acts();
27604
function Exps() {};
27605
behaviorProto.exps = new Exps();
27606
}());
27607
;
27608
;
27609
cr.behaviors.Pin = function(runtime)
27610
{
27611
this.runtime = runtime;
27612
};
27613
(function ()
27614
{
27615
var behaviorProto = cr.behaviors.Pin.prototype;
27616
behaviorProto.Type = function(behavior, objtype)
27617
{
27618
this.behavior = behavior;
27619
this.objtype = objtype;
27620
this.runtime = behavior.runtime;
27621
};
27622
var behtypeProto = behaviorProto.Type.prototype;
27623
behtypeProto.onCreate = function()
27624
{
27625
};
27626
behaviorProto.Instance = function(type, inst)
27627
{
27628
this.type = type;
27629
this.behavior = type.behavior;
27630
this.inst = inst; // associated object instance to modify
27631
this.runtime = type.runtime;
27632
};
27633
var behinstProto = behaviorProto.Instance.prototype;
27634
behinstProto.onCreate = function()
27635
{
27636
this.pinObject = null;
27637
this.pinObjectUid = -1; // for loading
27638
this.pinAngle = 0;
27639
this.pinDist = 0;
27640
this.myStartAngle = 0;
27641
this.theirStartAngle = 0;
27642
this.lastKnownAngle = 0;
27643
this.mode = 0; // 0 = position & angle; 1 = position; 2 = angle; 3 = rope; 4 = bar
27644
var self = this;
27645
if (!this.recycled)
27646
{
27647
this.myDestroyCallback = (function(inst) {
27648
self.onInstanceDestroyed(inst);
27649
});
27650
}
27651
this.runtime.addDestroyCallback(this.myDestroyCallback);
27652
};
27653
behinstProto.saveToJSON = function ()
27654
{
27655
return {
27656
"uid": this.pinObject ? this.pinObject.uid : -1,
27657
"pa": this.pinAngle,
27658
"pd": this.pinDist,
27659
"msa": this.myStartAngle,
27660
"tsa": this.theirStartAngle,
27661
"lka": this.lastKnownAngle,
27662
"m": this.mode
27663
};
27664
};
27665
behinstProto.loadFromJSON = function (o)
27666
{
27667
this.pinObjectUid = o["uid"]; // wait until afterLoad to look up
27668
this.pinAngle = o["pa"];
27669
this.pinDist = o["pd"];
27670
this.myStartAngle = o["msa"];
27671
this.theirStartAngle = o["tsa"];
27672
this.lastKnownAngle = o["lka"];
27673
this.mode = o["m"];
27674
};
27675
behinstProto.afterLoad = function ()
27676
{
27677
if (this.pinObjectUid === -1)
27678
this.pinObject = null;
27679
else
27680
{
27681
this.pinObject = this.runtime.getObjectByUID(this.pinObjectUid);
27682
;
27683
}
27684
this.pinObjectUid = -1;
27685
};
27686
behinstProto.onInstanceDestroyed = function (inst)
27687
{
27688
if (this.pinObject == inst)
27689
this.pinObject = null;
27690
};
27691
behinstProto.onDestroy = function()
27692
{
27693
this.pinObject = null;
27694
this.runtime.removeDestroyCallback(this.myDestroyCallback);
27695
};
27696
behinstProto.tick = function ()
27697
{
27698
};
27699
behinstProto.tick2 = function ()
27700
{
27701
if (!this.pinObject)
27702
return;
27703
if (this.lastKnownAngle !== this.inst.angle)
27704
this.myStartAngle = cr.clamp_angle(this.myStartAngle + (this.inst.angle - this.lastKnownAngle));
27705
var newx = this.inst.x;
27706
var newy = this.inst.y;
27707
if (this.mode === 3 || this.mode === 4) // rope mode or bar mode
27708
{
27709
var dist = cr.distanceTo(this.inst.x, this.inst.y, this.pinObject.x, this.pinObject.y);
27710
if ((dist > this.pinDist) || (this.mode === 4 && dist < this.pinDist))
27711
{
27712
var a = cr.angleTo(this.pinObject.x, this.pinObject.y, this.inst.x, this.inst.y);
27713
newx = this.pinObject.x + Math.cos(a) * this.pinDist;
27714
newy = this.pinObject.y + Math.sin(a) * this.pinDist;
27715
}
27716
}
27717
else
27718
{
27719
newx = this.pinObject.x + Math.cos(this.pinObject.angle + this.pinAngle) * this.pinDist;
27720
newy = this.pinObject.y + Math.sin(this.pinObject.angle + this.pinAngle) * this.pinDist;
27721
}
27722
var newangle = cr.clamp_angle(this.myStartAngle + (this.pinObject.angle - this.theirStartAngle));
27723
this.lastKnownAngle = newangle;
27724
if ((this.mode === 0 || this.mode === 1 || this.mode === 3 || this.mode === 4)
27725
&& (this.inst.x !== newx || this.inst.y !== newy))
27726
{
27727
this.inst.x = newx;
27728
this.inst.y = newy;
27729
this.inst.set_bbox_changed();
27730
}
27731
if ((this.mode === 0 || this.mode === 2) && (this.inst.angle !== newangle))
27732
{
27733
this.inst.angle = newangle;
27734
this.inst.set_bbox_changed();
27735
}
27736
};
27737
function Cnds() {};
27738
Cnds.prototype.IsPinned = function ()
27739
{
27740
return !!this.pinObject;
27741
};
27742
behaviorProto.cnds = new Cnds();
27743
function Acts() {};
27744
Acts.prototype.Pin = function (obj, mode_)
27745
{
27746
if (!obj)
27747
return;
27748
var otherinst = obj.getFirstPicked(this.inst);
27749
if (!otherinst)
27750
return;
27751
this.pinObject = otherinst;
27752
this.pinAngle = cr.angleTo(otherinst.x, otherinst.y, this.inst.x, this.inst.y) - otherinst.angle;
27753
this.pinDist = cr.distanceTo(otherinst.x, otherinst.y, this.inst.x, this.inst.y);
27754
this.myStartAngle = this.inst.angle;
27755
this.lastKnownAngle = this.inst.angle;
27756
this.theirStartAngle = otherinst.angle;
27757
this.mode = mode_;
27758
};
27759
Acts.prototype.Unpin = function ()
27760
{
27761
this.pinObject = null;
27762
};
27763
behaviorProto.acts = new Acts();
27764
function Exps() {};
27765
Exps.prototype.PinnedUID = function (ret)
27766
{
27767
ret.set_int(this.pinObject ? this.pinObject.uid : -1);
27768
};
27769
behaviorProto.exps = new Exps();
27770
}());
27771
;
27772
;
27773
cr.behaviors.Platform = function(runtime)
27774
{
27775
this.runtime = runtime;
27776
};
27777
(function ()
27778
{
27779
var behaviorProto = cr.behaviors.Platform.prototype;
27780
behaviorProto.Type = function(behavior, objtype)
27781
{
27782
this.behavior = behavior;
27783
this.objtype = objtype;
27784
this.runtime = behavior.runtime;
27785
};
27786
var behtypeProto = behaviorProto.Type.prototype;
27787
behtypeProto.onCreate = function()
27788
{
27789
};
27790
var ANIMMODE_STOPPED = 0;
27791
var ANIMMODE_MOVING = 1;
27792
var ANIMMODE_JUMPING = 2;
27793
var ANIMMODE_FALLING = 3;
27794
behaviorProto.Instance = function(type, inst)
27795
{
27796
this.type = type;
27797
this.behavior = type.behavior;
27798
this.inst = inst; // associated object instance to modify
27799
this.runtime = type.runtime;
27800
this.leftkey = false;
27801
this.rightkey = false;
27802
this.jumpkey = false;
27803
this.jumped = false; // prevent bunnyhopping
27804
this.doubleJumped = false;
27805
this.canDoubleJump = false;
27806
this.ignoreInput = false;
27807
this.simleft = false;
27808
this.simright = false;
27809
this.simjump = false;
27810
this.lastFloorObject = null;
27811
this.loadFloorObject = -1;
27812
this.lastFloorX = 0;
27813
this.lastFloorY = 0;
27814
this.floorIsJumpthru = false;
27815
this.animMode = ANIMMODE_STOPPED;
27816
this.fallthrough = 0; // fall through jump-thru. >0 to disable, lasts a few ticks
27817
this.firstTick = true;
27818
this.dx = 0;
27819
this.dy = 0;
27820
};
27821
var behinstProto = behaviorProto.Instance.prototype;
27822
behinstProto.updateGravity = function()
27823
{
27824
this.downx = Math.cos(this.ga);
27825
this.downy = Math.sin(this.ga);
27826
this.rightx = Math.cos(this.ga - Math.PI / 2);
27827
this.righty = Math.sin(this.ga - Math.PI / 2);
27828
this.downx = cr.round6dp(this.downx);
27829
this.downy = cr.round6dp(this.downy);
27830
this.rightx = cr.round6dp(this.rightx);
27831
this.righty = cr.round6dp(this.righty);
27832
this.g1 = this.g;
27833
if (this.g < 0)
27834
{
27835
this.downx *= -1;
27836
this.downy *= -1;
27837
this.g = Math.abs(this.g);
27838
}
27839
};
27840
behinstProto.onCreate = function()
27841
{
27842
this.maxspeed = this.properties[0];
27843
this.acc = this.properties[1];
27844
this.dec = this.properties[2];
27845
this.jumpStrength = this.properties[3];
27846
this.g = this.properties[4];
27847
this.g1 = this.g;
27848
this.maxFall = this.properties[5];
27849
this.enableDoubleJump = (this.properties[6] !== 0); // 0=disabled, 1=enabled
27850
this.jumpSustain = (this.properties[7] / 1000); // convert ms to s
27851
this.defaultControls = (this.properties[8] === 1); // 0=no, 1=yes
27852
this.enabled = (this.properties[9] !== 0);
27853
this.wasOnFloor = false;
27854
this.wasOverJumpthru = this.runtime.testOverlapJumpThru(this.inst);
27855
this.loadOverJumpthru = -1;
27856
this.sustainTime = 0; // time of jump sustain remaining
27857
this.ga = cr.to_radians(90);
27858
this.updateGravity();
27859
var self = this;
27860
if (this.defaultControls && !this.runtime.isDomFree)
27861
{
27862
jQuery(document).keydown(function(info) {
27863
self.onKeyDown(info);
27864
});
27865
jQuery(document).keyup(function(info) {
27866
self.onKeyUp(info);
27867
});
27868
}
27869
if (!this.recycled)
27870
{
27871
this.myDestroyCallback = function(inst) {
27872
self.onInstanceDestroyed(inst);
27873
};
27874
}
27875
this.runtime.addDestroyCallback(this.myDestroyCallback);
27876
this.inst.extra["isPlatformBehavior"] = true;
27877
};
27878
behinstProto.saveToJSON = function ()
27879
{
27880
return {
27881
"ii": this.ignoreInput,
27882
"lfx": this.lastFloorX,
27883
"lfy": this.lastFloorY,
27884
"lfo": (this.lastFloorObject ? this.lastFloorObject.uid : -1),
27885
"am": this.animMode,
27886
"en": this.enabled,
27887
"fall": this.fallthrough,
27888
"ft": this.firstTick,
27889
"dx": this.dx,
27890
"dy": this.dy,
27891
"ms": this.maxspeed,
27892
"acc": this.acc,
27893
"dec": this.dec,
27894
"js": this.jumpStrength,
27895
"g": this.g,
27896
"g1": this.g1,
27897
"mf": this.maxFall,
27898
"wof": this.wasOnFloor,
27899
"woj": (this.wasOverJumpthru ? this.wasOverJumpthru.uid : -1),
27900
"ga": this.ga,
27901
"edj": this.enableDoubleJump,
27902
"cdj": this.canDoubleJump,
27903
"dj": this.doubleJumped,
27904
"sus": this.jumpSustain
27905
};
27906
};
27907
behinstProto.loadFromJSON = function (o)
27908
{
27909
this.ignoreInput = o["ii"];
27910
this.lastFloorX = o["lfx"];
27911
this.lastFloorY = o["lfy"];
27912
this.loadFloorObject = o["lfo"];
27913
this.animMode = o["am"];
27914
this.enabled = o["en"];
27915
this.fallthrough = o["fall"];
27916
this.firstTick = o["ft"];
27917
this.dx = o["dx"];
27918
this.dy = o["dy"];
27919
this.maxspeed = o["ms"];
27920
this.acc = o["acc"];
27921
this.dec = o["dec"];
27922
this.jumpStrength = o["js"];
27923
this.g = o["g"];
27924
this.g1 = o["g1"];
27925
this.maxFall = o["mf"];
27926
this.wasOnFloor = o["wof"];
27927
this.loadOverJumpthru = o["woj"];
27928
this.ga = o["ga"];
27929
this.enableDoubleJump = o["edj"];
27930
this.canDoubleJump = o["cdj"];
27931
this.doubleJumped = o["dj"];
27932
this.jumpSustain = o["sus"];
27933
this.leftkey = false;
27934
this.rightkey = false;
27935
this.jumpkey = false;
27936
this.jumped = false;
27937
this.simleft = false;
27938
this.simright = false;
27939
this.simjump = false;
27940
this.sustainTime = 0;
27941
this.updateGravity();
27942
};
27943
behinstProto.afterLoad = function ()
27944
{
27945
if (this.loadFloorObject === -1)
27946
this.lastFloorObject = null;
27947
else
27948
this.lastFloorObject = this.runtime.getObjectByUID(this.loadFloorObject);
27949
if (this.loadOverJumpthru === -1)
27950
this.wasOverJumpthru = null;
27951
else
27952
this.wasOverJumpthru = this.runtime.getObjectByUID(this.loadOverJumpthru);
27953
};
27954
behinstProto.onInstanceDestroyed = function (inst)
27955
{
27956
if (this.lastFloorObject == inst)
27957
this.lastFloorObject = null;
27958
};
27959
behinstProto.onDestroy = function ()
27960
{
27961
this.lastFloorObject = null;
27962
this.runtime.removeDestroyCallback(this.myDestroyCallback);
27963
};
27964
behinstProto.onKeyDown = function (info)
27965
{
27966
switch (info.which) {
27967
case 38: // up
27968
info.preventDefault();
27969
this.jumpkey = true;
27970
break;
27971
case 37: // left
27972
info.preventDefault();
27973
this.leftkey = true;
27974
break;
27975
case 39: // right
27976
info.preventDefault();
27977
this.rightkey = true;
27978
break;
27979
}
27980
};
27981
behinstProto.onKeyUp = function (info)
27982
{
27983
switch (info.which) {
27984
case 38: // up
27985
info.preventDefault();
27986
this.jumpkey = false;
27987
this.jumped = false;
27988
break;
27989
case 37: // left
27990
info.preventDefault();
27991
this.leftkey = false;
27992
break;
27993
case 39: // right
27994
info.preventDefault();
27995
this.rightkey = false;
27996
break;
27997
}
27998
};
27999
behinstProto.onWindowBlur = function ()
28000
{
28001
this.leftkey = false;
28002
this.rightkey = false;
28003
this.jumpkey = false;
28004
};
28005
behinstProto.getGDir = function ()
28006
{
28007
if (this.g < 0)
28008
return -1;
28009
else
28010
return 1;
28011
};
28012
behinstProto.isOnFloor = function ()
28013
{
28014
var ret = null;
28015
var ret2 = null;
28016
var i, len, j;
28017
var oldx = this.inst.x;
28018
var oldy = this.inst.y;
28019
this.inst.x += this.downx;
28020
this.inst.y += this.downy;
28021
this.inst.set_bbox_changed();
28022
if (this.lastFloorObject && this.runtime.testOverlap(this.inst, this.lastFloorObject) &&
28023
(!this.runtime.typeHasBehavior(this.lastFloorObject.type, cr.behaviors.solid) || this.lastFloorObject.extra["solidEnabled"]))
28024
{
28025
this.inst.x = oldx;
28026
this.inst.y = oldy;
28027
this.inst.set_bbox_changed();
28028
return this.lastFloorObject;
28029
}
28030
else
28031
{
28032
ret = this.runtime.testOverlapSolid(this.inst);
28033
if (!ret && this.fallthrough === 0)
28034
ret2 = this.runtime.testOverlapJumpThru(this.inst, true);
28035
this.inst.x = oldx;
28036
this.inst.y = oldy;
28037
this.inst.set_bbox_changed();
28038
if (ret) // was overlapping solid
28039
{
28040
if (this.runtime.testOverlap(this.inst, ret))
28041
return null;
28042
else
28043
{
28044
this.floorIsJumpthru = false;
28045
return ret;
28046
}
28047
}
28048
if (ret2 && ret2.length)
28049
{
28050
for (i = 0, j = 0, len = ret2.length; i < len; i++)
28051
{
28052
ret2[j] = ret2[i];
28053
if (!this.runtime.testOverlap(this.inst, ret2[i]))
28054
j++;
28055
}
28056
if (j >= 1)
28057
{
28058
this.floorIsJumpthru = true;
28059
return ret2[0];
28060
}
28061
}
28062
return null;
28063
}
28064
};
28065
behinstProto.tick = function ()
28066
{
28067
};
28068
behinstProto.posttick = function ()
28069
{
28070
var dt = this.runtime.getDt(this.inst);
28071
var mx, my, obstacle, mag, allover, i, len, j, oldx, oldy;
28072
if (!this.jumpkey && !this.simjump)
28073
this.jumped = false;
28074
var left = this.leftkey || this.simleft;
28075
var right = this.rightkey || this.simright;
28076
var jumpkey = (this.jumpkey || this.simjump);
28077
var jump = jumpkey && !this.jumped;
28078
this.simleft = false;
28079
this.simright = false;
28080
this.simjump = false;
28081
if (!this.enabled)
28082
return;
28083
if (this.ignoreInput)
28084
{
28085
left = false;
28086
right = false;
28087
jumpkey = false;
28088
jump = false;
28089
}
28090
if (!jumpkey)
28091
this.sustainTime = 0;
28092
var lastFloor = this.lastFloorObject;
28093
var floor_moved = false;
28094
if (this.firstTick)
28095
{
28096
if (this.runtime.testOverlapSolid(this.inst) || this.runtime.testOverlapJumpThru(this.inst))
28097
{
28098
this.runtime.pushOutSolid(this.inst, -this.downx, -this.downy, 4, true);
28099
}
28100
this.firstTick = false;
28101
}
28102
if (lastFloor && this.dy === 0 && (lastFloor.y !== this.lastFloorY || lastFloor.x !== this.lastFloorX))
28103
{
28104
mx = (lastFloor.x - this.lastFloorX);
28105
my = (lastFloor.y - this.lastFloorY);
28106
this.inst.x += mx;
28107
this.inst.y += my;
28108
this.inst.set_bbox_changed();
28109
this.lastFloorX = lastFloor.x;
28110
this.lastFloorY = lastFloor.y;
28111
floor_moved = true;
28112
if (this.runtime.testOverlapSolid(this.inst))
28113
{
28114
this.runtime.pushOutSolid(this.inst, -mx, -my, Math.sqrt(mx * mx + my * my) * 2.5);
28115
}
28116
}
28117
var floor_ = this.isOnFloor();
28118
var collobj = this.runtime.testOverlapSolid(this.inst);
28119
if (collobj)
28120
{
28121
var instWidth = Math.abs(this.inst.width);
28122
var instHeight = Math.abs(this.inst.height);
28123
if (this.inst.extra["inputPredicted"])
28124
{
28125
this.runtime.pushOutSolid(this.inst, -this.downx, -this.downy, 10, false);
28126
}
28127
else if (this.runtime.pushOutSolidAxis(this.inst, -this.downx, -this.downy, instHeight / 8))
28128
{
28129
this.runtime.registerCollision(this.inst, collobj);
28130
}
28131
else if (this.runtime.pushOutSolidAxis(this.inst, this.rightx, this.righty, instWidth / 2))
28132
{
28133
this.runtime.registerCollision(this.inst, collobj);
28134
}
28135
else if (this.runtime.pushOutSolidAxis(this.inst, this.downx, this.downy, instHeight / 2))
28136
{
28137
this.runtime.registerCollision(this.inst, collobj);
28138
}
28139
else if (this.runtime.pushOutSolidNearest(this.inst, Math.max(instWidth, instHeight) / 2))
28140
{
28141
this.runtime.registerCollision(this.inst, collobj);
28142
}
28143
else
28144
return;
28145
}
28146
if (floor_)
28147
{
28148
this.doubleJumped = false; // reset double jump flags for next jump
28149
this.canDoubleJump = false;
28150
if (this.dy > 0)
28151
{
28152
if (!this.wasOnFloor)
28153
{
28154
this.runtime.pushInFractional(this.inst, -this.downx, -this.downy, floor_, 16);
28155
this.wasOnFloor = true;
28156
}
28157
this.dy = 0;
28158
}
28159
if (lastFloor != floor_)
28160
{
28161
this.lastFloorObject = floor_;
28162
this.lastFloorX = floor_.x;
28163
this.lastFloorY = floor_.y;
28164
this.runtime.registerCollision(this.inst, floor_);
28165
}
28166
else if (floor_moved)
28167
{
28168
collobj = this.runtime.testOverlapSolid(this.inst);
28169
if (collobj)
28170
{
28171
this.runtime.registerCollision(this.inst, collobj);
28172
if (mx !== 0)
28173
{
28174
if (mx > 0)
28175
this.runtime.pushOutSolid(this.inst, -this.rightx, -this.righty);
28176
else
28177
this.runtime.pushOutSolid(this.inst, this.rightx, this.righty);
28178
}
28179
this.runtime.pushOutSolid(this.inst, -this.downx, -this.downy);
28180
}
28181
}
28182
}
28183
else
28184
{
28185
if (!jumpkey)
28186
this.canDoubleJump = true;
28187
}
28188
if ((floor_ && jump) || (!floor_ && this.enableDoubleJump && jumpkey && this.canDoubleJump && !this.doubleJumped))
28189
{
28190
oldx = this.inst.x;
28191
oldy = this.inst.y;
28192
this.inst.x -= this.downx;
28193
this.inst.y -= this.downy;
28194
this.inst.set_bbox_changed();
28195
if (!this.runtime.testOverlapSolid(this.inst))
28196
{
28197
this.sustainTime = this.jumpSustain;
28198
this.runtime.trigger(cr.behaviors.Platform.prototype.cnds.OnJump, this.inst);
28199
this.animMode = ANIMMODE_JUMPING;
28200
this.dy = -this.jumpStrength;
28201
jump = true; // set in case is double jump
28202
if (floor_)
28203
this.jumped = true;
28204
else
28205
this.doubleJumped = true;
28206
}
28207
else
28208
jump = false;
28209
this.inst.x = oldx;
28210
this.inst.y = oldy;
28211
this.inst.set_bbox_changed();
28212
}
28213
if (!floor_)
28214
{
28215
if (jumpkey && this.sustainTime > 0)
28216
{
28217
this.dy = -this.jumpStrength;
28218
this.sustainTime -= dt;
28219
}
28220
else
28221
{
28222
this.lastFloorObject = null;
28223
this.dy += this.g * dt;
28224
if (this.dy > this.maxFall)
28225
this.dy = this.maxFall;
28226
}
28227
if (jump)
28228
this.jumped = true;
28229
}
28230
this.wasOnFloor = !!floor_;
28231
if (left == right) // both up or both down
28232
{
28233
if (this.dx < 0)
28234
{
28235
this.dx += this.dec * dt;
28236
if (this.dx > 0)
28237
this.dx = 0;
28238
}
28239
else if (this.dx > 0)
28240
{
28241
this.dx -= this.dec * dt;
28242
if (this.dx < 0)
28243
this.dx = 0;
28244
}
28245
}
28246
if (left && !right)
28247
{
28248
if (this.dx > 0)
28249
this.dx -= (this.acc + this.dec) * dt;
28250
else
28251
this.dx -= this.acc * dt;
28252
}
28253
if (right && !left)
28254
{
28255
if (this.dx < 0)
28256
this.dx += (this.acc + this.dec) * dt;
28257
else
28258
this.dx += this.acc * dt;
28259
}
28260
if (this.dx > this.maxspeed)
28261
this.dx = this.maxspeed;
28262
else if (this.dx < -this.maxspeed)
28263
this.dx = -this.maxspeed;
28264
var landed = false;
28265
if (this.dx !== 0)
28266
{
28267
oldx = this.inst.x;
28268
oldy = this.inst.y;
28269
mx = this.dx * dt * this.rightx;
28270
my = this.dx * dt * this.righty;
28271
this.inst.x += this.rightx * (this.dx > 1 ? 1 : -1) - this.downx;
28272
this.inst.y += this.righty * (this.dx > 1 ? 1 : -1) - this.downy;
28273
this.inst.set_bbox_changed();
28274
var is_jumpthru = false;
28275
var slope_too_steep = this.runtime.testOverlapSolid(this.inst);
28276
/*
28277
if (!slope_too_steep && floor_)
28278
{
28279
slope_too_steep = this.runtime.testOverlapJumpThru(this.inst);
28280
is_jumpthru = true;
28281
if (slope_too_steep)
28282
{
28283
this.inst.x = oldx;
28284
this.inst.y = oldy;
28285
this.inst.set_bbox_changed();
28286
if (this.runtime.testOverlap(this.inst, slope_too_steep))
28287
{
28288
slope_too_steep = null;
28289
is_jumpthru = false;
28290
}
28291
}
28292
}
28293
*/
28294
this.inst.x = oldx + mx;
28295
this.inst.y = oldy + my;
28296
this.inst.set_bbox_changed();
28297
obstacle = this.runtime.testOverlapSolid(this.inst);
28298
if (!obstacle && floor_)
28299
{
28300
obstacle = this.runtime.testOverlapJumpThru(this.inst);
28301
if (obstacle)
28302
{
28303
this.inst.x = oldx;
28304
this.inst.y = oldy;
28305
this.inst.set_bbox_changed();
28306
if (this.runtime.testOverlap(this.inst, obstacle))
28307
{
28308
obstacle = null;
28309
is_jumpthru = false;
28310
}
28311
else
28312
is_jumpthru = true;
28313
this.inst.x = oldx + mx;
28314
this.inst.y = oldy + my;
28315
this.inst.set_bbox_changed();
28316
}
28317
}
28318
if (obstacle)
28319
{
28320
var push_dist = Math.abs(this.dx * dt) + 2;
28321
if (slope_too_steep || !this.runtime.pushOutSolid(this.inst, -this.downx, -this.downy, push_dist, is_jumpthru, obstacle))
28322
{
28323
this.runtime.registerCollision(this.inst, obstacle);
28324
push_dist = Math.max(Math.abs(this.dx * dt * 2.5), 30);
28325
if (!this.runtime.pushOutSolid(this.inst, this.rightx * (this.dx < 0 ? 1 : -1), this.righty * (this.dx < 0 ? 1 : -1), push_dist, false))
28326
{
28327
this.inst.x = oldx;
28328
this.inst.y = oldy;
28329
this.inst.set_bbox_changed();
28330
}
28331
else if (floor_ && !is_jumpthru && !this.floorIsJumpthru)
28332
{
28333
oldx = this.inst.x;
28334
oldy = this.inst.y;
28335
this.inst.x += this.downx;
28336
this.inst.y += this.downy;
28337
if (this.runtime.testOverlapSolid(this.inst))
28338
{
28339
if (!this.runtime.pushOutSolid(this.inst, -this.downx, -this.downy, 3, false))
28340
{
28341
this.inst.x = oldx;
28342
this.inst.y = oldy;
28343
this.inst.set_bbox_changed();
28344
}
28345
}
28346
else
28347
{
28348
this.inst.x = oldx;
28349
this.inst.y = oldy;
28350
this.inst.set_bbox_changed();
28351
}
28352
}
28353
if (!is_jumpthru)
28354
this.dx = 0; // stop
28355
}
28356
else if (!slope_too_steep && !jump && (Math.abs(this.dy) < Math.abs(this.jumpStrength / 4)))
28357
{
28358
this.dy = 0;
28359
if (!floor_)
28360
landed = true;
28361
}
28362
}
28363
else
28364
{
28365
var newfloor = this.isOnFloor();
28366
if (floor_ && !newfloor)
28367
{
28368
mag = Math.ceil(Math.abs(this.dx * dt)) + 2;
28369
oldx = this.inst.x;
28370
oldy = this.inst.y;
28371
this.inst.x += this.downx * mag;
28372
this.inst.y += this.downy * mag;
28373
this.inst.set_bbox_changed();
28374
if (this.runtime.testOverlapSolid(this.inst) || this.runtime.testOverlapJumpThru(this.inst))
28375
this.runtime.pushOutSolid(this.inst, -this.downx, -this.downy, mag + 2, true);
28376
else
28377
{
28378
this.inst.x = oldx;
28379
this.inst.y = oldy;
28380
this.inst.set_bbox_changed();
28381
}
28382
}
28383
else if (newfloor)
28384
{
28385
if (!floor_ && this.floorIsJumpthru)
28386
{
28387
this.lastFloorObject = newfloor;
28388
this.lastFloorX = newfloor.x;
28389
this.lastFloorY = newfloor.y;
28390
this.dy = 0;
28391
landed = true;
28392
}
28393
if (this.dy === 0)
28394
{
28395
this.runtime.pushInFractional(this.inst, -this.downx, -this.downy, newfloor, 16);
28396
}
28397
}
28398
}
28399
}
28400
if (this.dy !== 0)
28401
{
28402
oldx = this.inst.x;
28403
oldy = this.inst.y;
28404
this.inst.x += this.dy * dt * this.downx;
28405
this.inst.y += this.dy * dt * this.downy;
28406
var newx = this.inst.x;
28407
var newy = this.inst.y;
28408
this.inst.set_bbox_changed();
28409
collobj = this.runtime.testOverlapSolid(this.inst);
28410
var fell_on_jumpthru = false;
28411
if (!collobj && (this.dy > 0) && !floor_)
28412
{
28413
allover = this.fallthrough > 0 ? null : this.runtime.testOverlapJumpThru(this.inst, true);
28414
if (allover && allover.length)
28415
{
28416
if (this.wasOverJumpthru)
28417
{
28418
this.inst.x = oldx;
28419
this.inst.y = oldy;
28420
this.inst.set_bbox_changed();
28421
for (i = 0, j = 0, len = allover.length; i < len; i++)
28422
{
28423
allover[j] = allover[i];
28424
if (!this.runtime.testOverlap(this.inst, allover[i]))
28425
j++;
28426
}
28427
allover.length = j;
28428
this.inst.x = newx;
28429
this.inst.y = newy;
28430
this.inst.set_bbox_changed();
28431
}
28432
if (allover.length >= 1)
28433
collobj = allover[0];
28434
}
28435
fell_on_jumpthru = !!collobj;
28436
}
28437
if (collobj)
28438
{
28439
this.runtime.registerCollision(this.inst, collobj);
28440
this.sustainTime = 0;
28441
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));
28442
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))
28443
{
28444
this.inst.x = oldx;
28445
this.inst.y = oldy;
28446
this.inst.set_bbox_changed();
28447
this.wasOnFloor = true; // prevent adjustment for unexpected floor landings
28448
if (!fell_on_jumpthru)
28449
this.dy = 0; // stop
28450
}
28451
else
28452
{
28453
this.lastFloorObject = collobj;
28454
this.lastFloorX = collobj.x;
28455
this.lastFloorY = collobj.y;
28456
this.floorIsJumpthru = fell_on_jumpthru;
28457
if (fell_on_jumpthru)
28458
landed = true;
28459
this.dy = 0; // stop
28460
}
28461
}
28462
}
28463
if (this.animMode !== ANIMMODE_FALLING && this.dy > 0 && !floor_)
28464
{
28465
this.runtime.trigger(cr.behaviors.Platform.prototype.cnds.OnFall, this.inst);
28466
this.animMode = ANIMMODE_FALLING;
28467
}
28468
if ((floor_ || landed) && this.dy >= 0)
28469
{
28470
if (this.animMode === ANIMMODE_FALLING || landed || (jump && this.dy === 0))
28471
{
28472
this.runtime.trigger(cr.behaviors.Platform.prototype.cnds.OnLand, this.inst);
28473
if (this.dx === 0 && this.dy === 0)
28474
this.animMode = ANIMMODE_STOPPED;
28475
else
28476
this.animMode = ANIMMODE_MOVING;
28477
}
28478
else
28479
{
28480
if (this.animMode !== ANIMMODE_STOPPED && this.dx === 0 && this.dy === 0)
28481
{
28482
this.runtime.trigger(cr.behaviors.Platform.prototype.cnds.OnStop, this.inst);
28483
this.animMode = ANIMMODE_STOPPED;
28484
}
28485
if (this.animMode !== ANIMMODE_MOVING && (this.dx !== 0 || this.dy !== 0) && !jump)
28486
{
28487
this.runtime.trigger(cr.behaviors.Platform.prototype.cnds.OnMove, this.inst);
28488
this.animMode = ANIMMODE_MOVING;
28489
}
28490
}
28491
}
28492
if (this.fallthrough > 0)
28493
this.fallthrough--;
28494
this.wasOverJumpthru = this.runtime.testOverlapJumpThru(this.inst);
28495
};
28496
function Cnds() {};
28497
Cnds.prototype.IsMoving = function ()
28498
{
28499
return this.dx !== 0 || this.dy !== 0;
28500
};
28501
Cnds.prototype.CompareSpeed = function (cmp, s)
28502
{
28503
var speed = Math.sqrt(this.dx * this.dx + this.dy * this.dy);
28504
return cr.do_cmp(speed, cmp, s);
28505
};
28506
Cnds.prototype.IsOnFloor = function ()
28507
{
28508
if (this.dy !== 0)
28509
return false;
28510
var ret = null;
28511
var ret2 = null;
28512
var i, len, j;
28513
var oldx = this.inst.x;
28514
var oldy = this.inst.y;
28515
this.inst.x += this.downx;
28516
this.inst.y += this.downy;
28517
this.inst.set_bbox_changed();
28518
ret = this.runtime.testOverlapSolid(this.inst);
28519
if (!ret && this.fallthrough === 0)
28520
ret2 = this.runtime.testOverlapJumpThru(this.inst, true);
28521
this.inst.x = oldx;
28522
this.inst.y = oldy;
28523
this.inst.set_bbox_changed();
28524
if (ret) // was overlapping solid
28525
{
28526
return !this.runtime.testOverlap(this.inst, ret);
28527
}
28528
if (ret2 && ret2.length)
28529
{
28530
for (i = 0, j = 0, len = ret2.length; i < len; i++)
28531
{
28532
ret2[j] = ret2[i];
28533
if (!this.runtime.testOverlap(this.inst, ret2[i]))
28534
j++;
28535
}
28536
if (j >= 1)
28537
return true;
28538
}
28539
return false;
28540
};
28541
Cnds.prototype.IsByWall = function (side)
28542
{
28543
var ret = false;
28544
var oldx = this.inst.x;
28545
var oldy = this.inst.y;
28546
if (side === 0) // left
28547
{
28548
this.inst.x -= this.rightx * 2;
28549
this.inst.y -= this.righty * 2;
28550
}
28551
else
28552
{
28553
this.inst.x += this.rightx * 2;
28554
this.inst.y += this.righty * 2;
28555
}
28556
this.inst.set_bbox_changed();
28557
if (!this.runtime.testOverlapSolid(this.inst))
28558
{
28559
this.inst.x = oldx;
28560
this.inst.y = oldy;
28561
this.inst.set_bbox_changed();
28562
return false;
28563
}
28564
this.inst.x -= this.downx * 3;
28565
this.inst.y -= this.downy * 3;
28566
this.inst.set_bbox_changed();
28567
ret = this.runtime.testOverlapSolid(this.inst);
28568
this.inst.x = oldx;
28569
this.inst.y = oldy;
28570
this.inst.set_bbox_changed();
28571
return ret;
28572
};
28573
Cnds.prototype.IsJumping = function ()
28574
{
28575
return this.dy < 0;
28576
};
28577
Cnds.prototype.IsFalling = function ()
28578
{
28579
return this.dy > 0;
28580
};
28581
Cnds.prototype.OnJump = function ()
28582
{
28583
return true;
28584
};
28585
Cnds.prototype.OnFall = function ()
28586
{
28587
return true;
28588
};
28589
Cnds.prototype.OnStop = function ()
28590
{
28591
return true;
28592
};
28593
Cnds.prototype.OnMove = function ()
28594
{
28595
return true;
28596
};
28597
Cnds.prototype.OnLand = function ()
28598
{
28599
return true;
28600
};
28601
Cnds.prototype.IsDoubleJumpEnabled = function ()
28602
{
28603
return this.enableDoubleJump;
28604
};
28605
behaviorProto.cnds = new Cnds();
28606
function Acts() {};
28607
Acts.prototype.SetIgnoreInput = function (ignoring)
28608
{
28609
this.ignoreInput = ignoring;
28610
};
28611
Acts.prototype.SetMaxSpeed = function (maxspeed)
28612
{
28613
this.maxspeed = maxspeed;
28614
if (this.maxspeed < 0)
28615
this.maxspeed = 0;
28616
};
28617
Acts.prototype.SetAcceleration = function (acc)
28618
{
28619
this.acc = acc;
28620
if (this.acc < 0)
28621
this.acc = 0;
28622
};
28623
Acts.prototype.SetDeceleration = function (dec)
28624
{
28625
this.dec = dec;
28626
if (this.dec < 0)
28627
this.dec = 0;
28628
};
28629
Acts.prototype.SetJumpStrength = function (js)
28630
{
28631
this.jumpStrength = js;
28632
if (this.jumpStrength < 0)
28633
this.jumpStrength = 0;
28634
};
28635
Acts.prototype.SetGravity = function (grav)
28636
{
28637
if (this.g1 === grav)
28638
return; // no change
28639
this.g = grav;
28640
this.updateGravity();
28641
if (this.runtime.testOverlapSolid(this.inst))
28642
{
28643
this.runtime.pushOutSolid(this.inst, this.downx, this.downy, 10);
28644
this.inst.x += this.downx * 2;
28645
this.inst.y += this.downy * 2;
28646
this.inst.set_bbox_changed();
28647
}
28648
this.lastFloorObject = null;
28649
};
28650
Acts.prototype.SetMaxFallSpeed = function (mfs)
28651
{
28652
this.maxFall = mfs;
28653
if (this.maxFall < 0)
28654
this.maxFall = 0;
28655
};
28656
Acts.prototype.SimulateControl = function (ctrl)
28657
{
28658
switch (ctrl) {
28659
case 0: this.simleft = true; break;
28660
case 1: this.simright = true; break;
28661
case 2: this.simjump = true; break;
28662
}
28663
};
28664
Acts.prototype.SetVectorX = function (vx)
28665
{
28666
this.dx = vx;
28667
};
28668
Acts.prototype.SetVectorY = function (vy)
28669
{
28670
this.dy = vy;
28671
};
28672
Acts.prototype.SetGravityAngle = function (a)
28673
{
28674
a = cr.to_radians(a);
28675
a = cr.clamp_angle(a);
28676
if (this.ga === a)
28677
return; // no change
28678
this.ga = a;
28679
this.updateGravity();
28680
this.lastFloorObject = null;
28681
};
28682
Acts.prototype.SetEnabled = function (en)
28683
{
28684
if (this.enabled !== (en === 1))
28685
{
28686
this.enabled = (en === 1);
28687
if (!this.enabled)
28688
this.lastFloorObject = null;
28689
}
28690
};
28691
Acts.prototype.FallThrough = function ()
28692
{
28693
var oldx = this.inst.x;
28694
var oldy = this.inst.y;
28695
this.inst.x += this.downx;
28696
this.inst.y += this.downy;
28697
this.inst.set_bbox_changed();
28698
var overlaps = this.runtime.testOverlapJumpThru(this.inst, false);
28699
this.inst.x = oldx;
28700
this.inst.y = oldy;
28701
this.inst.set_bbox_changed();
28702
if (!overlaps)
28703
return;
28704
this.fallthrough = 3; // disable jumpthrus for 3 ticks (1 doesn't do it, 2 does, 3 to be on safe side)
28705
this.lastFloorObject = null;
28706
};
28707
Acts.prototype.SetDoubleJumpEnabled = function (e)
28708
{
28709
this.enableDoubleJump = (e !== 0);
28710
};
28711
Acts.prototype.SetJumpSustain = function (s)
28712
{
28713
this.jumpSustain = s / 1000; // convert to ms
28714
};
28715
behaviorProto.acts = new Acts();
28716
function Exps() {};
28717
Exps.prototype.Speed = function (ret)
28718
{
28719
ret.set_float(Math.sqrt(this.dx * this.dx + this.dy * this.dy));
28720
};
28721
Exps.prototype.MaxSpeed = function (ret)
28722
{
28723
ret.set_float(this.maxspeed);
28724
};
28725
Exps.prototype.Acceleration = function (ret)
28726
{
28727
ret.set_float(this.acc);
28728
};
28729
Exps.prototype.Deceleration = function (ret)
28730
{
28731
ret.set_float(this.dec);
28732
};
28733
Exps.prototype.JumpStrength = function (ret)
28734
{
28735
ret.set_float(this.jumpStrength);
28736
};
28737
Exps.prototype.Gravity = function (ret)
28738
{
28739
ret.set_float(this.g);
28740
};
28741
Exps.prototype.GravityAngle = function (ret)
28742
{
28743
ret.set_float(cr.to_degrees(this.ga));
28744
};
28745
Exps.prototype.MaxFallSpeed = function (ret)
28746
{
28747
ret.set_float(this.maxFall);
28748
};
28749
Exps.prototype.MovingAngle = function (ret)
28750
{
28751
ret.set_float(cr.to_degrees(Math.atan2(this.dy, this.dx)));
28752
};
28753
Exps.prototype.VectorX = function (ret)
28754
{
28755
ret.set_float(this.dx);
28756
};
28757
Exps.prototype.VectorY = function (ret)
28758
{
28759
ret.set_float(this.dy);
28760
};
28761
Exps.prototype.JumpSustain = function (ret)
28762
{
28763
ret.set_float(this.jumpSustain * 1000); // convert back to ms
28764
};
28765
behaviorProto.exps = new Exps();
28766
}());
28767
;
28768
;
28769
cr.behaviors.Rotate = function(runtime)
28770
{
28771
this.runtime = runtime;
28772
};
28773
(function ()
28774
{
28775
var behaviorProto = cr.behaviors.Rotate.prototype;
28776
behaviorProto.Type = function(behavior, objtype)
28777
{
28778
this.behavior = behavior;
28779
this.objtype = objtype;
28780
this.runtime = behavior.runtime;
28781
};
28782
var behtypeProto = behaviorProto.Type.prototype;
28783
behtypeProto.onCreate = function()
28784
{
28785
};
28786
behaviorProto.Instance = function(type, inst)
28787
{
28788
this.type = type;
28789
this.behavior = type.behavior;
28790
this.inst = inst; // associated object instance to modify
28791
this.runtime = type.runtime;
28792
};
28793
var behinstProto = behaviorProto.Instance.prototype;
28794
behinstProto.onCreate = function()
28795
{
28796
this.speed = cr.to_radians(this.properties[0]);
28797
this.acc = cr.to_radians(this.properties[1]);
28798
};
28799
behinstProto.saveToJSON = function ()
28800
{
28801
return {
28802
"speed": this.speed,
28803
"acc": this.acc
28804
};
28805
};
28806
behinstProto.loadFromJSON = function (o)
28807
{
28808
this.speed = o["speed"];
28809
this.acc = o["acc"];
28810
};
28811
behinstProto.tick = function ()
28812
{
28813
var dt = this.runtime.getDt(this.inst);
28814
if (dt === 0)
28815
return;
28816
if (this.acc !== 0)
28817
this.speed += this.acc * dt;
28818
if (this.speed !== 0)
28819
{
28820
this.inst.angle = cr.clamp_angle(this.inst.angle + this.speed * dt);
28821
this.inst.set_bbox_changed();
28822
}
28823
};
28824
function Cnds() {};
28825
behaviorProto.cnds = new Cnds();
28826
function Acts() {};
28827
Acts.prototype.SetSpeed = function (s)
28828
{
28829
this.speed = cr.to_radians(s);
28830
};
28831
Acts.prototype.SetAcceleration = function (a)
28832
{
28833
this.acc = cr.to_radians(a);
28834
};
28835
behaviorProto.acts = new Acts();
28836
function Exps() {};
28837
Exps.prototype.Speed = function (ret)
28838
{
28839
ret.set_float(cr.to_degrees(this.speed));
28840
};
28841
Exps.prototype.Acceleration = function (ret)
28842
{
28843
ret.set_float(cr.to_degrees(this.acc));
28844
};
28845
behaviorProto.exps = new Exps();
28846
}());
28847
;
28848
;
28849
cr.behaviors.Sin = function(runtime)
28850
{
28851
this.runtime = runtime;
28852
};
28853
(function ()
28854
{
28855
var behaviorProto = cr.behaviors.Sin.prototype;
28856
behaviorProto.Type = function(behavior, objtype)
28857
{
28858
this.behavior = behavior;
28859
this.objtype = objtype;
28860
this.runtime = behavior.runtime;
28861
};
28862
var behtypeProto = behaviorProto.Type.prototype;
28863
behtypeProto.onCreate = function()
28864
{
28865
};
28866
behaviorProto.Instance = function(type, inst)
28867
{
28868
this.type = type;
28869
this.behavior = type.behavior;
28870
this.inst = inst; // associated object instance to modify
28871
this.runtime = type.runtime;
28872
this.i = 0; // period offset (radians)
28873
};
28874
var behinstProto = behaviorProto.Instance.prototype;
28875
var _2pi = 2 * Math.PI;
28876
var _pi_2 = Math.PI / 2;
28877
var _3pi_2 = (3 * Math.PI) / 2;
28878
behinstProto.onCreate = function()
28879
{
28880
this.active = (this.properties[0] === 1);
28881
this.movement = this.properties[1]; // 0=Horizontal|1=Vertical|2=Size|3=Width|4=Height|5=Angle|6=Opacity|7=Value only
28882
this.wave = this.properties[2]; // 0=Sine|1=Triangle|2=Sawtooth|3=Reverse sawtooth|4=Square
28883
this.period = this.properties[3];
28884
this.period += Math.random() * this.properties[4]; // period random
28885
if (this.period === 0)
28886
this.i = 0;
28887
else
28888
{
28889
this.i = (this.properties[5] / this.period) * _2pi; // period offset
28890
this.i += ((Math.random() * this.properties[6]) / this.period) * _2pi; // period offset random
28891
}
28892
this.mag = this.properties[7]; // magnitude
28893
this.mag += Math.random() * this.properties[8]; // magnitude random
28894
this.initialValue = 0;
28895
this.initialValue2 = 0;
28896
this.ratio = 0;
28897
if (this.movement === 5) // angle
28898
this.mag = cr.to_radians(this.mag);
28899
this.init();
28900
};
28901
behinstProto.saveToJSON = function ()
28902
{
28903
return {
28904
"i": this.i,
28905
"a": this.active,
28906
"mv": this.movement,
28907
"w": this.wave,
28908
"p": this.period,
28909
"mag": this.mag,
28910
"iv": this.initialValue,
28911
"iv2": this.initialValue2,
28912
"r": this.ratio,
28913
"lkv": this.lastKnownValue,
28914
"lkv2": this.lastKnownValue2
28915
};
28916
};
28917
behinstProto.loadFromJSON = function (o)
28918
{
28919
this.i = o["i"];
28920
this.active = o["a"];
28921
this.movement = o["mv"];
28922
this.wave = o["w"];
28923
this.period = o["p"];
28924
this.mag = o["mag"];
28925
this.initialValue = o["iv"];
28926
this.initialValue2 = o["iv2"] || 0;
28927
this.ratio = o["r"];
28928
this.lastKnownValue = o["lkv"];
28929
this.lastKnownValue2 = o["lkv2"] || 0;
28930
};
28931
behinstProto.init = function ()
28932
{
28933
switch (this.movement) {
28934
case 0: // horizontal
28935
this.initialValue = this.inst.x;
28936
break;
28937
case 1: // vertical
28938
this.initialValue = this.inst.y;
28939
break;
28940
case 2: // size
28941
this.initialValue = this.inst.width;
28942
this.ratio = this.inst.height / this.inst.width;
28943
break;
28944
case 3: // width
28945
this.initialValue = this.inst.width;
28946
break;
28947
case 4: // height
28948
this.initialValue = this.inst.height;
28949
break;
28950
case 5: // angle
28951
this.initialValue = this.inst.angle;
28952
break;
28953
case 6: // opacity
28954
this.initialValue = this.inst.opacity;
28955
break;
28956
case 7:
28957
this.initialValue = 0;
28958
break;
28959
case 8: // forwards/backwards
28960
this.initialValue = this.inst.x;
28961
this.initialValue2 = this.inst.y;
28962
break;
28963
default:
28964
;
28965
}
28966
this.lastKnownValue = this.initialValue;
28967
this.lastKnownValue2 = this.initialValue2;
28968
};
28969
behinstProto.waveFunc = function (x)
28970
{
28971
x = x % _2pi;
28972
switch (this.wave) {
28973
case 0: // sine
28974
return Math.sin(x);
28975
case 1: // triangle
28976
if (x <= _pi_2)
28977
return x / _pi_2;
28978
else if (x <= _3pi_2)
28979
return 1 - (2 * (x - _pi_2) / Math.PI);
28980
else
28981
return (x - _3pi_2) / _pi_2 - 1;
28982
case 2: // sawtooth
28983
return 2 * x / _2pi - 1;
28984
case 3: // reverse sawtooth
28985
return -2 * x / _2pi + 1;
28986
case 4: // square
28987
return x < Math.PI ? -1 : 1;
28988
};
28989
return 0;
28990
};
28991
behinstProto.tick = function ()
28992
{
28993
var dt = this.runtime.getDt(this.inst);
28994
if (!this.active || dt === 0)
28995
return;
28996
if (this.period === 0)
28997
this.i = 0;
28998
else
28999
{
29000
this.i += (dt / this.period) * _2pi;
29001
this.i = this.i % _2pi;
29002
}
29003
this.updateFromPhase();
29004
};
29005
behinstProto.updateFromPhase = function ()
29006
{
29007
switch (this.movement) {
29008
case 0: // horizontal
29009
if (this.inst.x !== this.lastKnownValue)
29010
this.initialValue += this.inst.x - this.lastKnownValue;
29011
this.inst.x = this.initialValue + this.waveFunc(this.i) * this.mag;
29012
this.lastKnownValue = this.inst.x;
29013
break;
29014
case 1: // vertical
29015
if (this.inst.y !== this.lastKnownValue)
29016
this.initialValue += this.inst.y - this.lastKnownValue;
29017
this.inst.y = this.initialValue + this.waveFunc(this.i) * this.mag;
29018
this.lastKnownValue = this.inst.y;
29019
break;
29020
case 2: // size
29021
this.inst.width = this.initialValue + this.waveFunc(this.i) * this.mag;
29022
this.inst.height = this.inst.width * this.ratio;
29023
break;
29024
case 3: // width
29025
this.inst.width = this.initialValue + this.waveFunc(this.i) * this.mag;
29026
break;
29027
case 4: // height
29028
this.inst.height = this.initialValue + this.waveFunc(this.i) * this.mag;
29029
break;
29030
case 5: // angle
29031
if (this.inst.angle !== this.lastKnownValue)
29032
this.initialValue = cr.clamp_angle(this.initialValue + (this.inst.angle - this.lastKnownValue));
29033
this.inst.angle = cr.clamp_angle(this.initialValue + this.waveFunc(this.i) * this.mag);
29034
this.lastKnownValue = this.inst.angle;
29035
break;
29036
case 6: // opacity
29037
this.inst.opacity = this.initialValue + (this.waveFunc(this.i) * this.mag) / 100;
29038
if (this.inst.opacity < 0)
29039
this.inst.opacity = 0;
29040
else if (this.inst.opacity > 1)
29041
this.inst.opacity = 1;
29042
break;
29043
case 8: // forwards/backwards
29044
if (this.inst.x !== this.lastKnownValue)
29045
this.initialValue += this.inst.x - this.lastKnownValue;
29046
if (this.inst.y !== this.lastKnownValue2)
29047
this.initialValue2 += this.inst.y - this.lastKnownValue2;
29048
this.inst.x = this.initialValue + Math.cos(this.inst.angle) * this.waveFunc(this.i) * this.mag;
29049
this.inst.y = this.initialValue2 + Math.sin(this.inst.angle) * this.waveFunc(this.i) * this.mag;
29050
this.lastKnownValue = this.inst.x;
29051
this.lastKnownValue2 = this.inst.y;
29052
break;
29053
}
29054
this.inst.set_bbox_changed();
29055
};
29056
behinstProto.onSpriteFrameChanged = function (prev_frame, next_frame)
29057
{
29058
switch (this.movement) {
29059
case 2: // size
29060
this.initialValue *= (next_frame.width / prev_frame.width);
29061
this.ratio = next_frame.height / next_frame.width;
29062
break;
29063
case 3: // width
29064
this.initialValue *= (next_frame.width / prev_frame.width);
29065
break;
29066
case 4: // height
29067
this.initialValue *= (next_frame.height / prev_frame.height);
29068
break;
29069
}
29070
};
29071
function Cnds() {};
29072
Cnds.prototype.IsActive = function ()
29073
{
29074
return this.active;
29075
};
29076
Cnds.prototype.CompareMovement = function (m)
29077
{
29078
return this.movement === m;
29079
};
29080
Cnds.prototype.ComparePeriod = function (cmp, v)
29081
{
29082
return cr.do_cmp(this.period, cmp, v);
29083
};
29084
Cnds.prototype.CompareMagnitude = function (cmp, v)
29085
{
29086
if (this.movement === 5)
29087
return cr.do_cmp(this.mag, cmp, cr.to_radians(v));
29088
else
29089
return cr.do_cmp(this.mag, cmp, v);
29090
};
29091
Cnds.prototype.CompareWave = function (w)
29092
{
29093
return this.wave === w;
29094
};
29095
behaviorProto.cnds = new Cnds();
29096
function Acts() {};
29097
Acts.prototype.SetActive = function (a)
29098
{
29099
this.active = (a === 1);
29100
};
29101
Acts.prototype.SetPeriod = function (x)
29102
{
29103
this.period = x;
29104
};
29105
Acts.prototype.SetMagnitude = function (x)
29106
{
29107
this.mag = x;
29108
if (this.movement === 5) // angle
29109
this.mag = cr.to_radians(this.mag);
29110
};
29111
Acts.prototype.SetMovement = function (m)
29112
{
29113
if (this.movement === 5 && m !== 5)
29114
this.mag = cr.to_degrees(this.mag);
29115
this.movement = m;
29116
this.init();
29117
};
29118
Acts.prototype.SetWave = function (w)
29119
{
29120
this.wave = w;
29121
};
29122
Acts.prototype.SetPhase = function (x)
29123
{
29124
this.i = (x * _2pi) % _2pi;
29125
this.updateFromPhase();
29126
};
29127
Acts.prototype.UpdateInitialState = function ()
29128
{
29129
this.init();
29130
};
29131
behaviorProto.acts = new Acts();
29132
function Exps() {};
29133
Exps.prototype.CyclePosition = function (ret)
29134
{
29135
ret.set_float(this.i / _2pi);
29136
};
29137
Exps.prototype.Period = function (ret)
29138
{
29139
ret.set_float(this.period);
29140
};
29141
Exps.prototype.Magnitude = function (ret)
29142
{
29143
if (this.movement === 5) // angle
29144
ret.set_float(cr.to_degrees(this.mag));
29145
else
29146
ret.set_float(this.mag);
29147
};
29148
Exps.prototype.Value = function (ret)
29149
{
29150
ret.set_float(this.waveFunc(this.i) * this.mag);
29151
};
29152
behaviorProto.exps = new Exps();
29153
}());
29154
var easeOutBounceArray = [];
29155
var easeInElasticArray = [];
29156
var easeOutElasticArray = [];
29157
var easeInOutElasticArray = [];
29158
var easeInCircle = [];
29159
var easeOutCircle = [];
29160
var easeInOutCircle = [];
29161
var easeInBack = [];
29162
var easeOutBack = [];
29163
var easeInOutBack = [];
29164
var litetween_precision = 10000;
29165
var updateLimit = 0; //0.0165;
29166
function easeOutBouncefunc(t) {
29167
var b=0.0;
29168
var c=1.0;
29169
var d=1.0;
29170
if ((t/=d) < (1/2.75)) {
29171
result = c*(7.5625*t*t) + b;
29172
} else if (t < (2/2.75)) {
29173
result = c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
29174
} else if (t < (2.5/2.75)) {
29175
result = c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
29176
} else {
29177
result = c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
29178
}
29179
return result;
29180
}
29181
function integerize(t, d)
29182
{
29183
return Math.round(t/d*litetween_precision);
29184
}
29185
function easeFunc(easing, t, b, c, d, flip, param)
29186
{
29187
var ret_ease = 0;
29188
switch (easing) {
29189
case 0: // linear
29190
ret_ease = c*t/d + b;
29191
break;
29192
case 1: // easeInQuad
29193
ret_ease = c*(t/=d)*t + b;
29194
break;
29195
case 2: // easeOutQuad
29196
ret_ease = -c *(t/=d)*(t-2) + b;
29197
break;
29198
case 3: // easeInOutQuad
29199
if ((t/=d/2) < 1)
29200
ret_ease = c/2*t*t + b
29201
else
29202
ret_ease = -c/2 * ((--t)*(t-2) - 1) + b;
29203
break;
29204
case 4: // easeInCubic
29205
ret_ease = c*(t/=d)*t*t + b;
29206
break;
29207
case 5: // easeOutCubic
29208
ret_ease = c*((t=t/d-1)*t*t + 1) + b;
29209
break;
29210
case 6: // easeInOutCubic
29211
if ((t/=d/2) < 1)
29212
ret_ease = c/2*t*t*t + b
29213
else
29214
ret_ease = c/2*((t-=2)*t*t + 2) + b;
29215
break;
29216
case 7: // easeInQuart
29217
ret_ease = c*(t/=d)*t*t*t + b;
29218
break;
29219
case 8: // easeOutQuart
29220
ret_ease = -c * ((t=t/d-1)*t*t*t - 1) + b;
29221
break;
29222
case 9: // easeInOutQuart
29223
if ((t/=d/2) < 1)
29224
ret_ease = c/2*t*t*t*t + b
29225
else
29226
ret_ease = -c/2 * ((t-=2)*t*t*t - 2) + b;
29227
break;
29228
case 10: // easeInQuint
29229
ret_ease = c*(t/=d)*t*t*t*t + b;
29230
break;
29231
case 11: // easeOutQuint
29232
ret_ease = c*((t=t/d-1)*t*t*t*t + 1) + b;
29233
break;
29234
case 12: // easeInOutQuint
29235
if ((t/=d/2) < 1)
29236
ret_ease = c/2*t*t*t*t*t + b
29237
else
29238
ret_ease = c/2*((t-=2)*t*t*t*t + 2) + b;
29239
break;
29240
case 13: // easeInCircle
29241
if (param.optimized) {
29242
ret_ease = easeInCircle[integerize(t,d)];
29243
} else {
29244
ret_ease = -(Math.sqrt(1-t*t) - 1);
29245
}
29246
break;
29247
case 14: // easeOutCircle
29248
if (param.optimized) {
29249
ret_ease = easeOutCircle[integerize(t,d)];
29250
} else {
29251
ret_ease = Math.sqrt(1 - ((t-1)*(t-1)));
29252
}
29253
break;
29254
case 15: // easeInOutCircle
29255
if (param.optimized) {
29256
ret_ease = easeInOutCircle[integerize(t,d)];
29257
} else {
29258
if ((t/=d/2) < 1) ret_ease = -c/2 * (Math.sqrt(1 - t*t) - 1) + b
29259
else ret_ease = c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
29260
}
29261
break;
29262
case 16: // easeInBack
29263
if (param.optimized) {
29264
ret_ease = easeInBack[integerize(t,d)];
29265
} else {
29266
var s = param.s;
29267
ret_ease = c*(t/=d)*t*((s+1)*t - s) + b;
29268
}
29269
break;
29270
case 17: // easeOutBack
29271
if (param.optimized) {
29272
ret_ease = easeOutBack[integerize(t,d)];
29273
} else {
29274
var s = param.s;
29275
ret_ease = c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
29276
}
29277
break;
29278
case 18: // easeInOutBack
29279
if (param.optimized) {
29280
ret_ease = easeInOutBack[integerize(t,d)];
29281
} else {
29282
var s = param.s
29283
if ((t/=d/2) < 1)
29284
ret_ease = c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b
29285
else
29286
ret_ease = c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
29287
}
29288
break;
29289
case 19: //easeInElastic
29290
if (param.optimized) {
29291
ret_ease = easeInElasticArray[integerize(t, d)];
29292
} else {
29293
var a = param.a;
29294
var p = param.p;
29295
var s = 0;
29296
if (t==0) ret_ease = b; if ((t/=d)==1) ret_ease = b+c;
29297
if (p==0) p=d*.3; if (a==0 || a < Math.abs(c)) { a=c; s=p/4; }
29298
else var s = p/(2*Math.PI) * Math.asin (c/a);
29299
ret_ease = -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
29300
}
29301
break;
29302
case 20: //easeOutElastic
29303
if (param.optimized) {
29304
ret_ease = easeOutElasticArray[integerize(t,d)];
29305
} else {
29306
var a = param.a;
29307
var p = param.p;
29308
var s = 0;
29309
if (t==0) ret_ease= b; if ((t/=d)==1) ret_ease= b+c; if (p == 0) p=d*.3;
29310
if (a==0 || a < Math.abs(c)) { a=c; var s=p/4; }
29311
else var s = p/(2*Math.PI) * Math.asin (c/a);
29312
ret_ease= (a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b);
29313
}
29314
break;
29315
case 21: //easeInOutElastic
29316
if (param.optimized) {
29317
ret_ease = easeInOutElasticArray[integerize(t,d)];
29318
} else {
29319
var a = param.a;
29320
var p = param.p;
29321
var s = 0;
29322
if (t==0) ret_ease = b;
29323
if ((t/=d/2)==2) ret_ease = b+c;
29324
if (p==0) p=d*(.3*1.5);
29325
if (a==0 || a < Math.abs(c)) { a=c; var s=p/4; }
29326
else var s = p/(2*Math.PI) * Math.asin (c/a);
29327
if (t < 1)
29328
ret_ease = -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b
29329
else
29330
ret_ease = a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
29331
}
29332
break;
29333
case 22: //easeInBounce
29334
if (param.optimized) {
29335
ret_ease = c - easeOutBounceArray[integerize(d-t, d)] + b;
29336
} else {
29337
ret_ease = c - easeOutBouncefunc(d-t/d) + b;
29338
}
29339
break;
29340
case 23: //easeOutBounce
29341
if (param.optimized) {
29342
ret_ease = easeOutBounceArray[integerize(t, d)];
29343
} else {
29344
ret_ease = easeOutBouncefunc(t/d);
29345
}
29346
break;
29347
case 24: //easeInOutBounce
29348
if (param.optimized) {
29349
if (t < d/2)
29350
ret_ease = (c - easeOutBounceArray[integerize(d-(t*2), d)] + b) * 0.5 +b;
29351
else
29352
ret_ease = easeOutBounceArray[integerize(t*2-d, d)] * .5 + c*.5 + b;
29353
} else {
29354
if (t < d/2)
29355
ret_ease = (c - easeOutBouncefunc(d-(t*2)) + b) * 0.5 +b;
29356
else
29357
ret_ease = easeOutBouncefunc((t*2-d)/d) * .5 + c *.5 + b;
29358
}
29359
break;
29360
case 25: //easeInSmoothstep
29361
var mt = (t/d) / 2;
29362
ret_ease = (2*(mt * mt * (3 - 2*mt)));
29363
break;
29364
case 26: //easeOutSmoothstep
29365
var mt = ((t/d) + 1) / 2;
29366
ret_ease = ((2*(mt * mt * (3 - 2*mt))) - 1);
29367
break;
29368
case 27: //easeInOutSmoothstep
29369
var mt = (t / d);
29370
ret_ease = (mt * mt * (3 - 2*mt));
29371
break;
29372
};
29373
if (flip)
29374
return (c - b) - ret_ease
29375
else
29376
return ret_ease;
29377
};
29378
(function preCalculateArray() {
29379
var d = 1.0;
29380
var b = 0.0;
29381
var c = 1.0;
29382
var result = 0.0;
29383
var a = 0.0;
29384
var p = 0.0;
29385
var t = 0.0;
29386
var s = 0.0;
29387
for (var ti = 0; ti <= litetween_precision; ti++) {
29388
t = ti/litetween_precision;
29389
if ((t/=d) < (1/2.75)) {
29390
result = c*(7.5625*t*t) + b;
29391
} else if (t < (2/2.75)) {
29392
result = c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
29393
} else if (t < (2.5/2.75)) {
29394
result = c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
29395
} else {
29396
result = c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
29397
}
29398
easeOutBounceArray[ti] = result;
29399
t = ti/litetween_precision; a = 0; p = 0;
29400
if (t==0) result = b; if ((t/=d)==1) result = b+c;
29401
if (p==0) p=d*.3; if (a==0 || a < Math.abs(c)) { a=c; var s=p/4; }
29402
else var s = p/(2*Math.PI) * Math.asin (c/a);
29403
result = -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
29404
easeInElasticArray[ti] = result;
29405
t = ti/litetween_precision; a = 0; p = 0;
29406
if (t==0) result= b; if ((t/=d)==1) result= b+c; if (p == 0) p=d*.3;
29407
if (a==0 || a < Math.abs(c)) { a=c; var s=p/4; }
29408
else var s = p/(2*Math.PI) * Math.asin (c/a);
29409
result= (a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b);
29410
easeOutElasticArray[ti] = result;
29411
t = ti/litetween_precision; a = 0; p = 0;
29412
if (t==0) result = b;
29413
if ((t/=d/2)==2) result = b+c;
29414
if (p==0) p=d*(.3*1.5);
29415
if (a==0 || a < Math.abs(c)) { a=c; var s=p/4; }
29416
else var s = p/(2*Math.PI) * Math.asin (c/a);
29417
if (t < 1)
29418
result = -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b
29419
else
29420
result = a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
29421
easeInOutElasticArray[ti] = result;
29422
t = ti/litetween_precision; easeInCircle[ti] = -(Math.sqrt(1-t*t) - 1);
29423
t = ti/litetween_precision; easeOutCircle[ti] = Math.sqrt(1 - ((t-1)*(t-1)));
29424
t = ti/litetween_precision;
29425
if ((t/=d/2) < 1) result = -c/2 * (Math.sqrt(1 - t*t) - 1) + b
29426
else result = c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
29427
easeInOutCircle[ti] = result;
29428
t = ti/litetween_precision; s = 0;
29429
if (s==0) s = 1.70158;
29430
result = c*(t/=d)*t*((s+1)*t - s) + b;
29431
easeInBack[ti] = result;
29432
t = ti/litetween_precision; s = 0;
29433
if (s==0) s = 1.70158;
29434
result = c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
29435
easeOutBack[ti] = result;
29436
t = ti/litetween_precision; s = 0; if (s==0) s = 1.70158;
29437
if ((t/=d/2) < 1)
29438
result = c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b
29439
else
29440
result = c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
29441
easeInOutBack[ti] = result;
29442
}
29443
}());
29444
var TweenObject = function()
29445
{
29446
var constructor = function (tname, tweened, easefunc, initial, target, duration, enforce)
29447
{
29448
this.name = tname;
29449
this.value = 0;
29450
this.setInitial(initial);
29451
this.setTarget(target);
29452
this.easefunc = easefunc;
29453
this.tweened = tweened;
29454
this.duration = duration;
29455
this.progress = 0;
29456
this.state = 0;
29457
this.onStart = false;
29458
this.onEnd = false;
29459
this.onReverseStart = false;
29460
this.onReverseEnd = false;
29461
this.lastKnownValue = 0;
29462
this.lastKnownValue2 = 0;
29463
this.enforce = enforce;
29464
this.pingpong = 1.0;
29465
this.flipEase = false;
29466
this.easingparam = [];
29467
this.lastState = 1;
29468
for (var i=0; i<28; i++) {
29469
this.easingparam[i] = {};
29470
this.easingparam[i].a = 0.0;
29471
this.easingparam[i].p = 0.0;
29472
this.easingparam[i].t = 0.0;
29473
this.easingparam[i].s = 0.0;
29474
this.easingparam[i].optimized = true;
29475
}
29476
}
29477
return constructor;
29478
}();
29479
(function () {
29480
TweenObject.prototype = {
29481
};
29482
TweenObject.prototype.flipTarget = function ()
29483
{
29484
var x1 = this.initialparam1;
29485
var x2 = this.initialparam2;
29486
this.initialparam1 = this.targetparam1;
29487
this.initialparam2 = this.targetparam2;
29488
this.targetparam1 = x1;
29489
this.targetparam2 = x2;
29490
this.lastKnownValue = 0;
29491
this.lastKnownValue2 = 0;
29492
}
29493
TweenObject.prototype.setInitial = function (initial)
29494
{
29495
this.initialparam1 = parseFloat(initial.split(",")[0]);
29496
this.initialparam2 = parseFloat(initial.split(",")[1]);
29497
this.lastKnownValue = 0;
29498
this.lastKnownValue2 = 0;
29499
}
29500
TweenObject.prototype.setTarget = function (target)
29501
{
29502
this.targetparam1 = parseFloat(target.split(",")[0]);
29503
this.targetparam2 = parseFloat(target.split(",")[1]);
29504
if (isNaN(this.targetparam2)) this.targetparam2 = this.targetparam1;
29505
}
29506
TweenObject.prototype.OnTick = function(dt)
29507
{
29508
if (this.state === 0) return -1.0;
29509
if (this.state === 1)
29510
this.progress += dt;
29511
if (this.state === 2)
29512
this.progress -= dt;
29513
if (this.state === 3) {
29514
this.state = 0;
29515
}
29516
if ((this.state === 4) || (this.state === 6)) {
29517
this.progress += dt * this.pingpong;
29518
}
29519
if (this.state === 5) {
29520
this.progress += dt * this.pingpong;
29521
}
29522
if (this.progress < 0) {
29523
this.progress = 0;
29524
if (this.state === 4) {
29525
this.pingpong = 1;
29526
} else if (this.state === 6) {
29527
this.pingpong = 1;
29528
this.flipEase = false;
29529
} else {
29530
this.state = 0;
29531
}
29532
this.onReverseEnd = true;
29533
return 0.0;
29534
} else if (this.progress > this.duration) {
29535
this.progress = this.duration;
29536
if (this.state === 4) {
29537
this.pingpong = -1;
29538
} else if (this.state === 6) {
29539
this.pingpong = -1;
29540
this.flipEase = true;
29541
} else if (this.state === 5) {
29542
this.progress = 0.0;
29543
} else {
29544
this.state = 0;
29545
}
29546
this.onEnd = true;
29547
return 1.0;
29548
} else {
29549
if (this.flipEase) {
29550
var factor = easeFunc(this.easefunc, this.duration - this.progress, 0, 1, this.duration, this.flipEase, this.easingparam[this.easefunc]);
29551
} else {
29552
var factor = easeFunc(this.easefunc, this.progress, 0, 1, this.duration, this.flipEase, this.easingparam[this.easefunc]);
29553
}
29554
return factor;
29555
}
29556
};
29557
}());
29558
;
29559
;
29560
function trim (str) {
29561
return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
29562
}
29563
cr.behaviors.lunarray_LiteTween = function(runtime)
29564
{
29565
this.runtime = runtime;
29566
};
29567
(function ()
29568
{
29569
var behaviorProto = cr.behaviors.lunarray_LiteTween.prototype;
29570
behaviorProto.Type = function(behavior, objtype)
29571
{
29572
this.behavior = behavior;
29573
this.objtype = objtype;
29574
this.runtime = behavior.runtime;
29575
};
29576
var behtypeProto = behaviorProto.Type.prototype;
29577
behtypeProto.onCreate = function()
29578
{
29579
};
29580
behaviorProto.Instance = function(type, inst)
29581
{
29582
this.type = type;
29583
this.behavior = type.behavior;
29584
this.inst = inst; // associated object instance to modify
29585
this.runtime = type.runtime;
29586
this.i = 0; // progress
29587
};
29588
var behinstProto = behaviorProto.Instance.prototype;
29589
behinstProto.onCreate = function()
29590
{
29591
this.playmode = this.properties[0];
29592
this.active = (this.playmode == 1) || (this.playmode == 2) || (this.playmode == 3) || (this.playmode == 4);
29593
this.tweened = this.properties[1]; // 0=Position|1=Size|2=Width|3=Height|4=Angle|5=Opacity|6=Value only|7=Horizontal|8=Vertical|9=Scale
29594
this.easing = this.properties[2];
29595
this.target = this.properties[3];
29596
this.targetmode = this.properties[4];
29597
this.useCurrent = false;
29598
if (this.targetmode === 1) this.target = "relative("+this.target+")";
29599
this.duration = this.properties[5];
29600
this.enforce = (this.properties[6] === 1);
29601
this.value = 0;
29602
this.tween_list = {};
29603
this.addToTweenList("default", this.tweened, this.easing, "current", this.target, this.duration, this.enforce);
29604
if (this.properties[0] === 1) this.startTween(0)
29605
if (this.properties[0] === 2) this.startTween(2)
29606
if (this.properties[0] === 3) this.startTween(3)
29607
if (this.properties[0] === 4) this.startTween(4)
29608
};
29609
behinstProto.parseCurrent = function(tweened, parseText)
29610
{
29611
if (parseText === undefined) parseText = "current";
29612
var parsed = trim(parseText);
29613
parseText = trim(parseText);
29614
var value = this.value;
29615
if (parseText === "current") {
29616
switch (tweened) {
29617
case 0: parsed = this.inst.x + "," + this.inst.y; break;
29618
case 1: parsed = this.inst.width + "," + this.inst.height; break;
29619
case 2: parsed = this.inst.width + "," + this.inst.height; break;
29620
case 3: parsed = this.inst.width + "," + this.inst.height; break;
29621
case 4: parsed = cr.to_degrees(this.inst.angle) + "," + cr.to_degrees(this.inst.angle); break;
29622
case 5: parsed = (this.inst.opacity*100) + "," + (this.inst.opacity*100); break;
29623
case 6: parsed = value + "," + value; break;
29624
case 7: parsed = this.inst.x + "," + this.inst.y; break;
29625
case 8: parsed = this.inst.x + "," + this.inst.y; break;
29626
case 9:
29627
if (this.inst.curFrame !== undefined)
29628
parsed = (this.inst.width/this.inst.curFrame.width) + "," +(this.inst.height/this.inst.curFrame.height)
29629
else
29630
parsed = "1,1";
29631
break;
29632
default: break;
29633
}
29634
}
29635
if (parseText.substring(0,8) === "relative") {
29636
var param1 = parseText.match(/\((.*?)\)/);
29637
if (param1) {
29638
var relativex = parseFloat(param1[1].split(",")[0]);
29639
var relativey = parseFloat(param1[1].split(",")[1]);
29640
}
29641
if (isNaN(relativex)) relativex = 0;
29642
if (isNaN(relativey)) relativey = 0;
29643
switch (tweened) {
29644
case 0: parsed = (this.inst.x+relativex) + "," + (this.inst.y+relativey); break;
29645
case 1: parsed = (this.inst.width+relativex) + "," + (this.inst.height+relativey); break;
29646
case 2: parsed = (this.inst.width+relativex) + "," + (this.inst.height+relativey); break;
29647
case 3: parsed = (this.inst.width+relativex) + "," + (this.inst.height+relativey); break;
29648
case 4: parsed = (cr.to_degrees(this.inst.angle)+relativex) + "," + (cr.to_degrees(this.inst.angle)+relativey); break;
29649
case 5: parsed = (this.inst.opacity*100+relativex) + "," + (this.inst.opacity*100+relativey); break;
29650
case 6: parsed = value+relativex + "," + value+relativex; break;
29651
case 7: parsed = (this.inst.x+relativex) + "," + (this.inst.y); break;
29652
case 8: parsed = (this.inst.x) + "," + (this.inst.y+relativex); break;
29653
case 9: parsed = (relativex) + "," + (relativey); break;
29654
default: break;
29655
}
29656
}
29657
return parsed;
29658
};
29659
behinstProto.addToTweenList = function(tname, tweened, easing, init, targ, duration, enforce)
29660
{
29661
init = this.parseCurrent(tweened, init);
29662
targ = this.parseCurrent(tweened, targ);
29663
if (this.tween_list[tname] !== undefined) {
29664
delete this.tween_list[tname]
29665
}
29666
this.tween_list[tname] = new TweenObject(tname, tweened, easing, init, targ, duration, enforce);
29667
this.tween_list[tname].dt = 0;
29668
};
29669
behinstProto.saveToJSON = function ()
29670
{
29671
var v = JSON.stringify(this.tween_list["default"]);
29672
return {
29673
"playmode": this.playmode,
29674
"active": this.active,
29675
"tweened": this.tweened,
29676
"easing": this.easing,
29677
"target": this.target,
29678
"targetmode": this.targetmode,
29679
"useCurrent": this.useCurrent,
29680
"duration": this.duration,
29681
"enforce": this.enforce,
29682
"value": this.value,
29683
"tweenlist": JSON.stringify(this.tween_list["default"])
29684
};
29685
};
29686
TweenObject.Load = function(rawObj, tname, tweened, easing, init, targ, duration, enforce)
29687
{
29688
var obj = new TweenObject(tname, tweened, easing, init, targ, duration, enforce);
29689
for(var i in rawObj)
29690
obj[i] = rawObj[i];
29691
return obj;
29692
};
29693
behinstProto.loadFromJSON = function (o)
29694
{
29695
var x = JSON.parse(o["tweenlist"]);
29696
var tempObj = TweenObject.Load(x, x.name, x.tweened, x.easefunc, x.initialparam1+","+x.initialparam2, x.targetparam1+","+x.targetparam2, x.duration, x.enforce);
29697
this.tween_list["default"] = tempObj;
29698
this.playmode = o["playmode"];
29699
this.active = o["active"];
29700
this.movement = o["tweened"];
29701
this.easing = o["easing"];
29702
this.target = o["target"];
29703
this.targetmode = o["targetmode"];
29704
this.useCurrent = o["useCurrent"];
29705
this.duration = o["duration"];
29706
this.enforce = o["enforce"];
29707
this.value = o["value"];
29708
};
29709
behinstProto.setProgressTo = function (mark)
29710
{
29711
if (mark > 1.0) mark = 1.0;
29712
if (mark < 0.0) mark = 0.0;
29713
for (var i in this.tween_list) {
29714
var inst = this.tween_list[i];
29715
inst.lastKnownValue = 0;
29716
inst.lastKnownValue2 = 0;
29717
inst.state = 3;
29718
inst.progress = mark * inst.duration;
29719
var factor = inst.OnTick(0);
29720
this.updateTween(inst, factor);
29721
}
29722
}
29723
behinstProto.startTween = function (startMode)
29724
{
29725
for (var i in this.tween_list) {
29726
var inst = this.tween_list[i];
29727
if (this.useCurrent) {
29728
var init = this.parseCurrent(inst.tweened, "current");
29729
var target = this.parseCurrent(inst.tweened, this.target);
29730
inst.setInitial(init);
29731
inst.setTarget(target);
29732
}
29733
if (startMode === 0) {
29734
inst.progress = 0.000001;
29735
inst.lastKnownValue = 0;
29736
inst.lastKnownValue2 = 0;
29737
inst.onStart = true;
29738
inst.state = 1;
29739
}
29740
if (startMode === 1) {
29741
inst.state = inst.lastState;
29742
}
29743
if ((startMode === 2) || (startMode === 4)) {
29744
inst.progress = 0.000001;
29745
inst.lastKnownValue = 0;
29746
inst.lastKnownValue2 = 0;
29747
inst.onStart = true;
29748
if (startMode == 2) inst.state = 4; //state ping pong
29749
if (startMode == 4) inst.state = 6; //state flip flop
29750
}
29751
if (startMode === 3) {
29752
inst.progress = 0.000001;
29753
inst.lastKnownValue = 0;
29754
inst.lastKnownValue2 = 0;
29755
inst.onStart = true;
29756
inst.state = 5;
29757
}
29758
}
29759
}
29760
behinstProto.stopTween = function (stopMode)
29761
{
29762
for (var i in this.tween_list) {
29763
var inst = this.tween_list[i];
29764
if ((inst.state != 3) && (inst.state != 0)) //don't save paused/seek state
29765
inst.lastState = inst.state;
29766
if (stopMode === 1) inst.progress = 0.0;
29767
if (stopMode === 2) inst.progress = inst.duration;
29768
inst.state = 3;
29769
var factor = inst.OnTick(0);
29770
this.updateTween(inst, factor);
29771
}
29772
}
29773
behinstProto.reverseTween = function(reverseMode)
29774
{
29775
for (var i in this.tween_list) {
29776
var inst = this.tween_list[i];
29777
if (reverseMode === 1) {
29778
inst.progress = inst.duration;
29779
inst.lastKnownValue = 0;
29780
inst.lastKnownValue2 = 0;
29781
inst.onReverseStart = true;
29782
}
29783
inst.state = 2;
29784
}
29785
}
29786
behinstProto.updateTween = function (inst, factor)
29787
{
29788
if (inst.tweened === 0) {
29789
if (inst.enforce) {
29790
this.inst.x = inst.initialparam1 + (inst.targetparam1 - inst.initialparam1) * factor;
29791
this.inst.y = inst.initialparam2 + (inst.targetparam2 - inst.initialparam2) * factor;
29792
} else {
29793
this.inst.x += ((inst.targetparam1 - inst.initialparam1) * factor) - inst.lastKnownValue;
29794
this.inst.y += ((inst.targetparam2 - inst.initialparam2) * factor) - inst.lastKnownValue2;
29795
inst.lastKnownValue = ((inst.targetparam1 - inst.initialparam1) * factor);
29796
inst.lastKnownValue2 = ((inst.targetparam2 - inst.initialparam2) * factor);
29797
}
29798
} else if (inst.tweened === 1) {
29799
if (inst.enforce) {
29800
this.inst.width = (inst.initialparam1 + ((inst.targetparam1 - inst.initialparam1) * (factor)));
29801
this.inst.height = (inst.initialparam2 + ((inst.targetparam2 - inst.initialparam2) * (factor)));
29802
} else {
29803
this.inst.width += ((inst.targetparam1 - inst.initialparam1) * factor) - inst.lastKnownValue;
29804
this.inst.height += ((inst.targetparam2 - inst.initialparam2) * factor) - inst.lastKnownValue2;
29805
inst.lastKnownValue = ((inst.targetparam1 - inst.initialparam1) * factor);
29806
inst.lastKnownValue2 = ((inst.targetparam2 - inst.initialparam2) * factor);
29807
}
29808
} else if (inst.tweened === 2) {
29809
if (inst.enforce) {
29810
this.inst.width = (inst.initialparam1 + ((inst.targetparam1 - inst.initialparam1) * (factor)));
29811
} else {
29812
this.inst.width += ((inst.targetparam1 - inst.initialparam1) * factor) - inst.lastKnownValue;
29813
inst.lastKnownValue = ((inst.targetparam1 - inst.initialparam1) * factor);
29814
}
29815
} else if (inst.tweened === 3) {
29816
if (inst.enforce) {
29817
this.inst.height = (inst.initialparam2 + ((inst.targetparam2 - inst.initialparam2) * (factor)));
29818
} else {
29819
this.inst.height += ((inst.targetparam2 - inst.initialparam2) * factor) - inst.lastKnownValue2;
29820
inst.lastKnownValue2 = ((inst.targetparam2 - inst.initialparam2) * factor);
29821
}
29822
} else if (inst.tweened === 4) {
29823
if (inst.enforce) {
29824
var tangle = inst.initialparam1 + (inst.targetparam1 - inst.initialparam1) * factor;
29825
this.inst.angle = cr.clamp_angle(cr.to_radians(tangle));
29826
} else {
29827
var tangle = ((inst.targetparam1 - inst.initialparam1) * factor) - inst.lastKnownValue;
29828
this.inst.angle = cr.clamp_angle(this.inst.angle + cr.to_radians(tangle));
29829
inst.lastKnownValue = (inst.targetparam1 - inst.initialparam1) * factor;
29830
}
29831
} else if (inst.tweened === 5) {
29832
if (inst.enforce) {
29833
this.inst.opacity = (inst.initialparam1 + (inst.targetparam1 - inst.initialparam1) * factor) / 100;
29834
} else {
29835
this.inst.opacity += (((inst.targetparam1 - inst.initialparam1) * factor) - inst.lastKnownValue) / 100;
29836
inst.lastKnownValue = ((inst.targetparam1 - inst.initialparam1) * factor);
29837
}
29838
} else if (inst.tweened === 6) {
29839
if (inst.enforce) {
29840
this.value = (inst.initialparam1 + (inst.targetparam1 - inst.initialparam1) * factor);
29841
} else {
29842
this.value += (((inst.targetparam1 - inst.initialparam1) * factor) - inst.lastKnownValue);
29843
inst.lastKnownValue = ((inst.targetparam1 - inst.initialparam1) * factor);
29844
}
29845
} else if (inst.tweened === 7) {
29846
if (inst.enforce) {
29847
this.inst.x = inst.initialparam1 + (inst.targetparam1 - inst.initialparam1) * factor;
29848
} else {
29849
this.inst.x += ((inst.targetparam1 - inst.initialparam1) * factor) - inst.lastKnownValue;
29850
inst.lastKnownValue = ((inst.targetparam1 - inst.initialparam1) * factor);
29851
}
29852
} else if (inst.tweened === 8) {
29853
if (inst.enforce) {
29854
this.inst.y = inst.initialparam2 + (inst.targetparam2 - inst.initialparam2) * factor;
29855
} else {
29856
this.inst.y += ((inst.targetparam2 - inst.initialparam2) * factor) - inst.lastKnownValue2;
29857
inst.lastKnownValue2 = ((inst.targetparam2 - inst.initialparam2) * factor);
29858
}
29859
} else if (inst.tweened === 9) {
29860
var scalex = inst.initialparam1 + (inst.targetparam1 - inst.initialparam1) * factor;
29861
var scaley = inst.initialparam2 + (inst.targetparam2 - inst.initialparam2) * factor;
29862
if (this.inst.width < 0) scalex = inst.initialparam1 + (inst.targetparam1 + inst.initialparam1) * -factor;
29863
if (this.inst.height < 0) scaley = inst.initialparam2 + (inst.targetparam2 + inst.initialparam2) * -factor;
29864
if (inst.enforce) {
29865
this.inst.width = this.inst.curFrame.width * scalex;
29866
this.inst.height = this.inst.curFrame.height * scaley;
29867
} else {
29868
if (this.inst.width < 0) {
29869
this.inst.width = scalex * (this.inst.width / (-1+inst.lastKnownValue));
29870
inst.lastKnownValue = scalex + 1
29871
} else {
29872
this.inst.width = scalex * (this.inst.width / (1+inst.lastKnownValue));
29873
inst.lastKnownValue = scalex - 1;
29874
}
29875
if (this.inst.height < 0) {
29876
this.inst.height = scaley * (this.inst.height / (-1+inst.lastKnownValue2));
29877
inst.lastKnownValue2 = scaley + 1
29878
} else {
29879
this.inst.height = scaley * (this.inst.height / (1+inst.lastKnownValue2));
29880
inst.lastKnownValue2 = scaley - 1;
29881
}
29882
}
29883
}
29884
this.inst.set_bbox_changed();
29885
}
29886
behinstProto.tick = function ()
29887
{
29888
var dt = this.runtime.getDt(this.inst);
29889
var inst = this.tween_list["default"];
29890
if (inst.state !== 0) {
29891
if (inst.onStart) {
29892
this.runtime.trigger(cr.behaviors.lunarray_LiteTween.prototype.cnds.OnStart, this.inst);
29893
inst.onStart = false;
29894
}
29895
if (inst.onReverseStart) {
29896
this.runtime.trigger(cr.behaviors.lunarray_LiteTween.prototype.cnds.OnReverseStart, this.inst);
29897
inst.onReverseStart = false;
29898
}
29899
this.active = (inst.state == 1) || (inst.state == 2) || (inst.state == 4) || (inst.state == 5) || (inst.state == 6);
29900
var factor = inst.OnTick(dt);
29901
this.updateTween(inst, factor);
29902
if (inst.onEnd) {
29903
this.runtime.trigger(cr.behaviors.lunarray_LiteTween.prototype.cnds.OnEnd, this.inst);
29904
inst.onEnd = false;
29905
}
29906
if (inst.onReverseEnd) {
29907
this.runtime.trigger(cr.behaviors.lunarray_LiteTween.prototype.cnds.OnReverseEnd, this.inst);
29908
inst.onReverseEnd = false;
29909
}
29910
}
29911
};
29912
behaviorProto.cnds = {};
29913
var cnds = behaviorProto.cnds;
29914
cnds.IsActive = function ()
29915
{
29916
return (this.tween_list["default"].state !== 0);
29917
};
29918
cnds.IsReversing = function ()
29919
{
29920
return (this.tween_list["default"].state == 2);
29921
};
29922
cnds.CompareProgress = function (cmp, v)
29923
{
29924
var inst = this.tween_list["default"];
29925
return cr.do_cmp((inst.progress / inst.duration), cmp, v);
29926
};
29927
cnds.OnThreshold = function (cmp, v)
29928
{
29929
var inst = this.tween_list["default"];
29930
this.threshold = (cr.do_cmp((inst.progress / inst.duration), cmp, v));
29931
var ret = (this.oldthreshold != this.threshold) && (this.threshold);
29932
if (ret) {
29933
this.oldthreshold = this.threshold;
29934
}
29935
return ret;
29936
};
29937
cnds.OnStart = function ()
29938
{
29939
if (this.tween_list["default"] === undefined)
29940
return false;
29941
return this.tween_list["default"].onStart;
29942
};
29943
cnds.OnReverseStart = function ()
29944
{
29945
if (this.tween_list["default"] === undefined)
29946
return false;
29947
return this.tween_list["default"].onReverseStart;
29948
};
29949
cnds.OnEnd = function ()
29950
{
29951
if (this.tween_list["default"] === undefined)
29952
return false;
29953
return this.tween_list["default"].onEnd;
29954
};
29955
cnds.OnReverseEnd = function ()
29956
{
29957
if (this.tween_list["default"] === undefined)
29958
return false;
29959
return this.tween_list["default"].onReverseEnd;
29960
};
29961
behaviorProto.acts = {};
29962
var acts = behaviorProto.acts;
29963
acts.Start = function (startmode, current)
29964
{
29965
this.threshold = false;
29966
this.oldthreshold = false;
29967
this.useCurrent = (current == 1);
29968
this.startTween(startmode);
29969
};
29970
acts.Stop = function (stopmode)
29971
{
29972
this.stopTween(stopmode);
29973
};
29974
acts.Reverse = function (revMode)
29975
{
29976
this.threshold = false;
29977
this.oldthreshold = false;
29978
this.reverseTween(revMode);
29979
};
29980
acts.ProgressTo = function (progress)
29981
{
29982
this.setProgressTo(progress);
29983
};
29984
acts.SetDuration = function (x)
29985
{
29986
if (isNaN(x)) return;
29987
if (x < 0) return;
29988
if (this.tween_list["default"] === undefined) return;
29989
this.tween_list["default"].duration = x;
29990
};
29991
acts.SetEnforce = function (x)
29992
{
29993
if (this.tween_list["default"] === undefined) return;
29994
this.tween_list["default"].enforce = (x===1);
29995
};
29996
acts.SetInitial = function (x)
29997
{
29998
if (this.tween_list["default"] === undefined) return;
29999
var init = this.parseCurrent(this.tween_list["default"].tweened, x);
30000
this.tween_list["default"].setInitial(init);
30001
};
30002
acts.SetTarget = function (targettype, absrel, x)
30003
{
30004
if (this.tween_list["default"] === undefined) return;
30005
if (isNaN(x)) return;
30006
var inst = this.tween_list["default"];
30007
var parsed = x + "";
30008
this.targetmode = absrel;
30009
var x1 = "";
30010
var x2 = "";
30011
if (absrel === 1) {
30012
this.target = "relative(" + parsed + ")";
30013
switch (targettype) {
30014
case 0: x1 = (this.inst.x + x); x2 = inst.targetparam2; break;
30015
case 1: x1 = inst.targetparam1; x2 = (this.inst.y + x); break;
30016
case 2: x1 = "" + cr.to_degrees(this.inst.angle + cr.to_radians(x)); x2 = x1; break; //angle
30017
case 3: x1 = "" + (this.inst.opacity*100) + x; x2 = x1; break; //opacity
30018
case 4: x1 = (this.inst.width + x); x2 = inst.targetparam2; break; //width
30019
case 5: x1 = inst.targetparam1; x2 = (this.inst.height + x); break; //height
30020
case 6: x1 = x; x2 = x; break; //value
30021
default: break;
30022
}
30023
parsed = x1 + "," + x2;
30024
} else {
30025
switch (targettype) {
30026
case 0: x1 = x; x2 = inst.targetparam2; break;
30027
case 1: x1 = inst.targetparam1; x2 = x; break;
30028
case 2: x1 = x; x2 = x; break; //angle
30029
case 3: x1 = x; x2 = x; break; //opacity
30030
case 4: x1 = x; x2 = inst.targetparam2; break; //width
30031
case 5: x1 = inst.targetparam1; x2 = x; break; //height
30032
case 6: x1 = x; x2 = x; break; //value
30033
default: break;
30034
}
30035
parsed = x1 + "," + x2;
30036
this.target = parsed;
30037
}
30038
var init = this.parseCurrent(this.tween_list["default"].tweened, "current");
30039
var targ = this.parseCurrent(this.tween_list["default"].tweened, parsed);
30040
inst.setInitial(init);
30041
inst.setTarget(targ);
30042
};
30043
acts.SetTweenedProperty = function (x)
30044
{
30045
if (this.tween_list["default"] === undefined) return;
30046
this.tween_list["default"].tweened = x;
30047
};
30048
acts.SetEasing = function (x)
30049
{
30050
if (this.tween_list["default"] === undefined) return;
30051
this.tween_list["default"].easefunc = x;
30052
};
30053
acts.SetEasingParam = function (x, a, p, t, s)
30054
{
30055
if (this.tween_list["default"] === undefined) return;
30056
this.tween_list["default"].easingparam[x].optimized = false;
30057
this.tween_list["default"].easingparam[x].a = a;
30058
this.tween_list["default"].easingparam[x].p = p;
30059
this.tween_list["default"].easingparam[x].t = t;
30060
this.tween_list["default"].easingparam[x].s = s;
30061
};
30062
acts.ResetEasingParam = function ()
30063
{
30064
if (this.tween_list["default"] === undefined) return;
30065
this.tween_list["default"].optimized = true;
30066
};
30067
acts.SetValue = function (x)
30068
{
30069
var inst = this.tween_list["default"];
30070
this.value = x;
30071
if (inst.tweened === 6)
30072
inst.setInitial( this.parseCurrent(inst.tweened, "current") );
30073
};
30074
acts.SetParameter = function (tweened, easefunction, target, duration, enforce)
30075
{
30076
if (this.tween_list["default"] === undefined) {
30077
this.addToTweenList("default", tweened, easefunction, initial, target, duration, enforce, 0);
30078
} else {
30079
var inst = this.tween_list["default"];
30080
inst.tweened = tweened;
30081
inst.easefunc = easefunction;
30082
inst.setInitial( this.parseCurrent(tweened, "current") );
30083
inst.setTarget( this.parseCurrent(tweened, target) );
30084
inst.duration = duration;
30085
inst.enforce = (enforce === 1);
30086
}
30087
};
30088
behaviorProto.exps = {};
30089
var exps = behaviorProto.exps;
30090
exps.State = function (ret)
30091
{
30092
var parsed = "N/A";
30093
switch (this.tween_list["default"].state) {
30094
case 0: parsed = "paused"; break;
30095
case 1: parsed = "playing"; break;
30096
case 2: parsed = "reversing"; break;
30097
case 3: parsed = "seeking"; break;
30098
default: break;
30099
}
30100
ret.set_string(parsed);
30101
};
30102
exps.Progress = function (ret)
30103
{
30104
var progress = this.tween_list["default"].progress/this.tween_list["default"].duration;
30105
ret.set_float(progress);
30106
};
30107
exps.Duration = function (ret)
30108
{
30109
ret.set_float(this.tween_list["default"].duration);
30110
};
30111
exps.Target = function (ret)
30112
{
30113
var inst = this.tween_list["default"];
30114
var parsed = "N/A";
30115
switch (inst.tweened) {
30116
case 0: parsed = inst.targetparam1; break;
30117
case 1: parsed = inst.targetparam2; break;
30118
case 2: parsed = inst.targetparam1; break;
30119
case 3: parsed = inst.targetparam1; break;
30120
case 4: parsed = inst.targetparam1; break;
30121
case 5: parsed = inst.targetparam2; break;
30122
case 6: parsed = inst.targetparam1; break;
30123
default: break;
30124
}
30125
ret.set_float(parsed);
30126
};
30127
exps.Value = function (ret)
30128
{
30129
var tval = this.value;
30130
ret.set_float(tval);
30131
};
30132
exps.Tween = function (ret, a_, b_, x_, easefunc_)
30133
{
30134
var currX = (x_>1.0?1.0:x_);
30135
var factor = easeFunc(easefunc_, currX<0.0?0.0:currX, 0.0, 1.0, 1.0, false, false);
30136
ret.set_float(a_ + factor * (b_-a_));
30137
};
30138
}());
30139
;
30140
;
30141
cr.behaviors.scrollto = function(runtime)
30142
{
30143
this.runtime = runtime;
30144
this.shakeMag = 0;
30145
this.shakeStart = 0;
30146
this.shakeEnd = 0;
30147
this.shakeMode = 0;
30148
};
30149
(function ()
30150
{
30151
var behaviorProto = cr.behaviors.scrollto.prototype;
30152
behaviorProto.Type = function(behavior, objtype)
30153
{
30154
this.behavior = behavior;
30155
this.objtype = objtype;
30156
this.runtime = behavior.runtime;
30157
};
30158
var behtypeProto = behaviorProto.Type.prototype;
30159
behtypeProto.onCreate = function()
30160
{
30161
};
30162
behaviorProto.Instance = function(type, inst)
30163
{
30164
this.type = type;
30165
this.behavior = type.behavior;
30166
this.inst = inst; // associated object instance to modify
30167
this.runtime = type.runtime;
30168
};
30169
var behinstProto = behaviorProto.Instance.prototype;
30170
behinstProto.onCreate = function()
30171
{
30172
this.enabled = (this.properties[0] !== 0);
30173
};
30174
behinstProto.saveToJSON = function ()
30175
{
30176
return {
30177
"smg": this.behavior.shakeMag,
30178
"ss": this.behavior.shakeStart,
30179
"se": this.behavior.shakeEnd,
30180
"smd": this.behavior.shakeMode
30181
};
30182
};
30183
behinstProto.loadFromJSON = function (o)
30184
{
30185
this.behavior.shakeMag = o["smg"];
30186
this.behavior.shakeStart = o["ss"];
30187
this.behavior.shakeEnd = o["se"];
30188
this.behavior.shakeMode = o["smd"];
30189
};
30190
behinstProto.tick = function ()
30191
{
30192
};
30193
function getScrollToBehavior(inst)
30194
{
30195
var i, len, binst;
30196
for (i = 0, len = inst.behavior_insts.length; i < len; ++i)
30197
{
30198
binst = inst.behavior_insts[i];
30199
if (binst.behavior instanceof cr.behaviors.scrollto)
30200
return binst;
30201
}
30202
return null;
30203
};
30204
behinstProto.tick2 = function ()
30205
{
30206
if (!this.enabled)
30207
return;
30208
var all = this.behavior.my_instances.valuesRef();
30209
var sumx = 0, sumy = 0;
30210
var i, len, binst, count = 0;
30211
for (i = 0, len = all.length; i < len; i++)
30212
{
30213
binst = getScrollToBehavior(all[i]);
30214
if (!binst || !binst.enabled)
30215
continue;
30216
sumx += all[i].x;
30217
sumy += all[i].y;
30218
++count;
30219
}
30220
var layout = this.inst.layer.layout;
30221
var now = this.runtime.kahanTime.sum;
30222
var offx = 0, offy = 0;
30223
if (now >= this.behavior.shakeStart && now < this.behavior.shakeEnd)
30224
{
30225
var mag = this.behavior.shakeMag * Math.min(this.runtime.timescale, 1);
30226
if (this.behavior.shakeMode === 0)
30227
mag *= 1 - (now - this.behavior.shakeStart) / (this.behavior.shakeEnd - this.behavior.shakeStart);
30228
var a = Math.random() * Math.PI * 2;
30229
var d = Math.random() * mag;
30230
offx = Math.cos(a) * d;
30231
offy = Math.sin(a) * d;
30232
}
30233
layout.scrollToX(sumx / count + offx);
30234
layout.scrollToY(sumy / count + offy);
30235
};
30236
function Acts() {};
30237
Acts.prototype.Shake = function (mag, dur, mode)
30238
{
30239
this.behavior.shakeMag = mag;
30240
this.behavior.shakeStart = this.runtime.kahanTime.sum;
30241
this.behavior.shakeEnd = this.behavior.shakeStart + dur;
30242
this.behavior.shakeMode = mode;
30243
};
30244
Acts.prototype.SetEnabled = function (e)
30245
{
30246
this.enabled = (e !== 0);
30247
};
30248
behaviorProto.acts = new Acts();
30249
}());
30250
;
30251
;
30252
cr.behaviors.solid = function(runtime)
30253
{
30254
this.runtime = runtime;
30255
};
30256
(function ()
30257
{
30258
var behaviorProto = cr.behaviors.solid.prototype;
30259
behaviorProto.Type = function(behavior, objtype)
30260
{
30261
this.behavior = behavior;
30262
this.objtype = objtype;
30263
this.runtime = behavior.runtime;
30264
};
30265
var behtypeProto = behaviorProto.Type.prototype;
30266
behtypeProto.onCreate = function()
30267
{
30268
};
30269
behaviorProto.Instance = function(type, inst)
30270
{
30271
this.type = type;
30272
this.behavior = type.behavior;
30273
this.inst = inst; // associated object instance to modify
30274
this.runtime = type.runtime;
30275
};
30276
var behinstProto = behaviorProto.Instance.prototype;
30277
behinstProto.onCreate = function()
30278
{
30279
this.inst.extra["solidEnabled"] = (this.properties[0] !== 0);
30280
};
30281
behinstProto.tick = function ()
30282
{
30283
};
30284
function Cnds() {};
30285
Cnds.prototype.IsEnabled = function ()
30286
{
30287
return this.inst.extra["solidEnabled"];
30288
};
30289
behaviorProto.cnds = new Cnds();
30290
function Acts() {};
30291
Acts.prototype.SetEnabled = function (e)
30292
{
30293
this.inst.extra["solidEnabled"] = !!e;
30294
};
30295
behaviorProto.acts = new Acts();
30296
}());
30297
cr.getObjectRefTable = function () { return [
30298
cr.plugins_.GoogleAnalytics_ST,
30299
cr.plugins_.Arr,
30300
cr.plugins_.Audio,
30301
cr.plugins_.Browser,
30302
cr.plugins_.GD_SDK,
30303
cr.plugins_.Mouse,
30304
cr.plugins_.Dictionary,
30305
cr.plugins_.Keyboard,
30306
cr.plugins_.Function,
30307
cr.plugins_.Photon,
30308
cr.plugins_.Sprite,
30309
cr.plugins_.TiledBg,
30310
cr.plugins_.SpriteFontPlus,
30311
cr.plugins_.Text,
30312
cr.plugins_.Tilemap,
30313
cr.plugins_.Touch,
30314
cr.behaviors.solid,
30315
cr.behaviors.Platform,
30316
cr.behaviors.scrollto,
30317
cr.behaviors.Flash,
30318
cr.behaviors.lunarray_LiteTween,
30319
cr.behaviors.Rotate,
30320
cr.behaviors.Pin,
30321
cr.behaviors.Anchor,
30322
cr.behaviors.Fade,
30323
cr.behaviors.Sin,
30324
cr.system_object.prototype.cnds.Every,
30325
cr.system_object.prototype.acts.AddVar,
30326
cr.system_object.prototype.cnds.CompareVar,
30327
cr.system_object.prototype.acts.SetVar,
30328
cr.plugins_.Sprite.prototype.acts.SetAnimFrame,
30329
cr.system_object.prototype.acts.SetLayerBackground,
30330
cr.system_object.prototype.exps.rgb,
30331
cr.system_object.prototype.cnds.Repeat,
30332
cr.system_object.prototype.exps.random,
30333
cr.system_object.prototype.acts.CreateObject,
30334
cr.behaviors.Platform.prototype.acts.SetGravity,
30335
cr.plugins_.Sprite.prototype.acts.SetInstanceVar,
30336
cr.system_object.prototype.cnds.ForEach,
30337
cr.plugins_.Sprite.prototype.cnds.CompareInstanceVar,
30338
cr.plugins_.Sprite.prototype.acts.Destroy,
30339
cr.system_object.prototype.cnds.Else,
30340
cr.system_object.prototype.cnds.TriggerOnce,
30341
cr.system_object.prototype.acts.SetLayerVisible,
30342
cr.behaviors.lunarray_LiteTween.prototype.acts.Start,
30343
cr.plugins_.SpriteFontPlus.prototype.cnds.CompareInstanceVar,
30344
cr.plugins_.SpriteFontPlus.prototype.acts.SetText,
30345
cr.plugins_.Touch.prototype.cnds.OnTouchObject,
30346
cr.system_object.prototype.cnds.LayerVisible,
30347
cr.plugins_.GD_SDK.prototype.acts.ShowAd,
30348
cr.behaviors.Flash.prototype.cnds.IsFlashing,
30349
cr.system_object.prototype.acts.SubVar,
30350
cr.behaviors.Flash.prototype.acts.Flash,
30351
cr.plugins_.Sprite.prototype.exps.AnimationFrame,
30352
cr.plugins_.Sprite.prototype.cnds.CompareFrame,
30353
cr.plugins_.Sprite.prototype.cnds.IsOverlapping,
30354
cr.plugins_.Sprite.prototype.exps.X,
30355
cr.plugins_.Sprite.prototype.exps.Y,
30356
cr.plugins_.Audio.prototype.acts.Play,
30357
cr.behaviors.scrollto.prototype.acts.Shake,
30358
cr.plugins_.Sprite.prototype.acts.SetVisible,
30359
cr.plugins_.Sprite.prototype.acts.SetAnim,
30360
cr.plugins_.Sprite.prototype.cnds.OnCreated,
30361
cr.system_object.prototype.acts.Wait,
30362
cr.plugins_.Sprite.prototype.cnds.IsAnimPlaying,
30363
cr.behaviors.Platform.prototype.acts.SimulateControl,
30364
cr.plugins_.Sprite.prototype.acts.SetWidth,
30365
cr.system_object.prototype.exps.abs,
30366
cr.plugins_.Sprite.prototype.exps.Width,
30367
cr.behaviors.Platform.prototype.cnds.IsByWall,
30368
cr.plugins_.Sprite.prototype.cnds.PickDistance,
30369
cr.system_object.prototype.cnds.Compare,
30370
cr.system_object.prototype.exps.distance,
30371
cr.plugins_.Sprite.prototype.cnds.CompareX,
30372
cr.plugins_.Function.prototype.acts.CallFunction,
30373
cr.plugins_.Sprite.prototype.cnds.IsOverlappingOffset,
30374
cr.system_object.prototype.cnds.EveryTick,
30375
cr.system_object.prototype.cnds.ForEachOrdered,
30376
cr.system_object.prototype.exps.loopindex,
30377
cr.plugins_.Sprite.prototype.acts.SetPosToObject,
30378
cr.plugins_.Keyboard.prototype.cnds.IsKeyDown,
30379
cr.plugins_.Touch.prototype.cnds.IsTouchingObject,
30380
cr.behaviors.Platform.prototype.acts.SetVectorY,
30381
cr.behaviors.lunarray_LiteTween.prototype.cnds.OnEnd,
30382
cr.behaviors.Platform.prototype.acts.SetMaxSpeed,
30383
cr.behaviors.Platform.prototype.acts.SetMaxFallSpeed,
30384
cr.behaviors.solid.prototype.acts.SetEnabled,
30385
cr.plugins_.Audio.prototype.cnds.IsTagPlaying,
30386
cr.plugins_.Audio.prototype.acts.SetMasterVolume,
30387
cr.plugins_.Sprite.prototype.acts.AddInstanceVar,
30388
cr.plugins_.Sprite.prototype.acts.SubInstanceVar,
30389
cr.plugins_.Photon.prototype.acts.raiseEvent,
30390
cr.system_object.prototype.exps.zeropad,
30391
cr.plugins_.Function.prototype.cnds.OnFunction,
30392
cr.plugins_.Function.prototype.exps.Param,
30393
cr.plugins_.Tilemap.prototype.cnds.CompareTileAt,
30394
cr.plugins_.Tilemap.prototype.exps.PositionToTileX,
30395
cr.plugins_.Tilemap.prototype.exps.PositionToTileY,
30396
cr.plugins_.Tilemap.prototype.exps.TileAt,
30397
cr.plugins_.Tilemap.prototype.exps.UID,
30398
cr.plugins_.Tilemap.prototype.acts.EraseTile,
30399
cr.plugins_.Sprite.prototype.cnds.OnDestroyed,
30400
cr.plugins_.Tilemap.prototype.exps.LayerName,
30401
cr.plugins_.GD_SDK.prototype.cnds.onPauseGame,
30402
cr.system_object.prototype.acts.SetTimescale,
30403
cr.plugins_.GD_SDK.prototype.cnds.onResumeGame,
30404
cr.system_object.prototype.acts.GoToLayout,
30405
cr.system_object.prototype.cnds.OnLayoutStart,
30406
cr.plugins_.Arr.prototype.acts.Clear,
30407
cr.plugins_.Sprite.prototype.acts.SetPos,
30408
cr.plugins_.Mouse.prototype.cnds.IsOverObject,
30409
cr.plugins_.Mouse.prototype.acts.SetCursor,
30410
cr.behaviors.lunarray_LiteTween.prototype.acts.Reverse,
30411
cr.plugins_.Touch.prototype.cnds.OnTapGestureObject,
30412
cr.plugins_.Browser.prototype.acts.GoToURLWindow,
30413
cr.plugins_.Sprite.prototype.acts.SetOpacity,
30414
cr.plugins_.GD_SDK.prototype.acts.InitAds,
30415
cr.system_object.prototype.exps.floor,
30416
cr.plugins_.TiledBg.prototype.acts.SetWidth,
30417
cr.system_object.prototype.exps.loadingprogress,
30418
cr.system_object.prototype.cnds.OnLoadFinished,
30419
cr.plugins_.Touch.prototype.cnds.OnTouchStart,
30420
cr.system_object.prototype.cnds.PickOverlappingPoint,
30421
cr.plugins_.Touch.prototype.exps.X,
30422
cr.plugins_.Touch.prototype.exps.Y,
30423
cr.plugins_.Tilemap.prototype.exps.SnapX,
30424
cr.plugins_.Tilemap.prototype.exps.SnapY,
30425
cr.plugins_.Sprite.prototype.cnds.IsMirrored,
30426
cr.behaviors.Platform.prototype.acts.SetVectorX,
30427
cr.plugins_.Tilemap.prototype.cnds.PickByUID,
30428
cr.plugins_.Sprite.prototype.acts.MoveToBottom,
30429
cr.plugins_.Sprite.prototype.acts.SetX,
30430
cr.plugins_.Sprite.prototype.exps.UID,
30431
cr.plugins_.Sprite.prototype.exps.Count,
30432
cr.plugins_.Touch.prototype.cnds.OnTouchEnd,
30433
cr.plugins_.Keyboard.prototype.cnds.OnKeyReleased,
30434
cr.plugins_.Keyboard.prototype.cnds.OnKey,
30435
cr.plugins_.Sprite.prototype.acts.SetAnimSpeed,
30436
cr.plugins_.Sprite.prototype.cnds.OnAnimFinished,
30437
cr.plugins_.Sprite.prototype.acts.Spawn,
30438
cr.plugins_.Sprite.prototype.exps.LayerName,
30439
cr.plugins_.Tilemap.prototype.acts.SetTile,
30440
cr.plugins_.Mouse.prototype.exps.X,
30441
cr.plugins_.Mouse.prototype.exps.Y,
30442
cr.system_object.prototype.exps.str,
30443
cr.plugins_.Sprite.prototype.exps.AnimationFrameCount,
30444
cr.behaviors.Platform.prototype.cnds.IsOnFloor,
30445
cr.behaviors.Platform.prototype.cnds.IsMoving,
30446
cr.behaviors.Platform.prototype.exps.VectorX,
30447
cr.plugins_.Sprite.prototype.acts.SetMirrored,
30448
cr.behaviors.Platform.prototype.cnds.OnJump,
30449
cr.plugins_.Photon.prototype.exps.MyActorNr,
30450
cr.behaviors.Pin.prototype.acts.Pin,
30451
cr.plugins_.Dictionary.prototype.acts.AddKey,
30452
cr.plugins_.Sprite.prototype.acts.MoveToLayer,
30453
cr.plugins_.SpriteFontPlus.prototype.acts.SetInstanceVar,
30454
cr.plugins_.SpriteFontPlus.prototype.acts.SetVisible,
30455
cr.system_object.prototype.cnds.PickRandom,
30456
cr.plugins_.Sprite.prototype.acts.MoveToTop,
30457
cr.plugins_.Arr.prototype.exps.At,
30458
cr.plugins_.Arr.prototype.cnds.CompareX,
30459
cr.plugins_.Arr.prototype.cnds.ArrForEach,
30460
cr.plugins_.Arr.prototype.exps.CurX,
30461
cr.system_object.prototype.exps.lerp,
30462
cr.plugins_.Sprite.prototype.exps.ImagePointX,
30463
cr.plugins_.Sprite.prototype.exps.ImagePointY,
30464
cr.plugins_.Arr.prototype.acts.SetX,
30465
cr.plugins_.Arr.prototype.acts.SetXY,
30466
cr.plugins_.Arr.prototype.acts.SetXYZ,
30467
cr.plugins_.Sprite.prototype.exps.AnimationName,
30468
cr.plugins_.Sprite.prototype.cnds.IsVisible,
30469
cr.plugins_.Function.prototype.acts.SetReturnValue,
30470
cr.system_object.prototype.cnds.IsGroupActive,
30471
cr.plugins_.Dictionary.prototype.acts.Clear,
30472
cr.system_object.prototype.exps["int"],
30473
cr.plugins_.Dictionary.prototype.exps.Get,
30474
cr.plugins_.Function.prototype.exps.Call,
30475
cr.behaviors.Flash.prototype.acts.StopFlashing,
30476
cr.plugins_.Text.prototype.acts.SetText,
30477
cr.system_object.prototype.exps.newline
30478
];};
30479