AdrBog

Tululoo Netscape Patch

Jul 15th, 2026 (edited)
29
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JavaScript 51.64 KB | Software | 0 0
  1. /*********************************************
  2.  * Tululoo Game Maker //TULULOO_VERSION
  3.  *
  4.  * NETSCAPE PATCH (by AdrBog https://adrbog.neocities.org)
  5.  * This patch will make your games made with Tululoo work in Netscape.
  6.  * However, I can't make miracles:
  7.  * - Drawing text in canvas won't work, to fix this, Netscape will use <span> tags as a fallback
  8.  * - Playing audio won't work
  9.  *
  10.  * How to apply:
  11.  * - Go to your Tululoo installation folder
  12.  * - There should be a file named "export.js"
  13.  * - Replace the contents of that file with this one
  14.  * - Now Tululoo will generate games compatible with Netscape
  15.  *
  16.  * Creators
  17.  * Zoltan Percsich
  18.  * Vadim "YellowAfterlife" Dyachenko
  19.  *
  20.  * (c) SilentWorks 2011 - 2013
  21.  * All rights reserved.
  22.  * www.tululoo.com
  23.  *
  24.  * Contributors:
  25.  * Csaba Herbut
  26.  ********************************************/
  27.  
  28. function tu_detect_audio(_type) {
  29.     var _au = document.createElement('audio');
  30.     return _au.canPlayType && _au.canPlayType(_type).replace(/no/, '');
  31. }
  32. //
  33. var __path__ = window.__path__ ? window.__path__ : '',
  34.     // system variables:
  35.     tu_gameloop = tu_canvas = tu_context = tu_room_to_go = null, tu_canvas_id = 'tululoocanvas', tu_text_overlay = null,
  36.     tu_canvas_css = 'background: rgb(42, 42, 42); border: 0;',
  37.     tu_loading = tu_load_total = 0,
  38.     var_override_ = (Object.defineProperty != undefined),
  39.     // resources:
  40.     tu_sprites = [], tu_audios = [], tu_backgrounds = [], tu_fonts = [], tu_scenes = [],
  41.     // time:
  42.     tu_frame_time = tu_frame_step = tu_frame_el = tu_frame_count = tu_elapsed = 0,
  43.     tu_prev_cycle_time = tu_prev_frame_time = (new Date()).getTime(),
  44.     // math:
  45.     max = Math.max, min = Math.min, round = Math.round, floor = Math.floor, ceil = Math.ceil,
  46.     sin = Math.sin, cos = Math.cos, sqrt = Math.sqrt, tan = Math.tan, rand = Math.random,
  47.     arccos = Math.acos, arcsin = Math.asin, arctan = Math.atan, arctan2 = Math.atan2,
  48.     tu_r2d = -180 / Math.PI, tu_d2r = Math.PI / -180, tu_2pi = Math.PI * 2,
  49.     // i/o variables:
  50.     mouse_x = mouse_y = 0, mouse_down = mouse_pressed = mouse_released = false,
  51.     key_down = [], key_pressed = [], key_released = [], tu_vkeys = [],
  52.     tu_keys_pressed = [], tu_keys_released = [],
  53.     touch_x = [], touch_y = [], touch_count = 0,
  54.     tu_unpausekey = 27, tu_paused = false, tu_modal = null, tu_modaldraw = true,
  55.     // i/o constants:
  56.     vk_0 = 48, vk_1 = 49, vk_2 = 50, vk_3 = 51, vk_4 = 52, vk_5 = 53, vk_6 = 54,
  57.     vk_7 = 55, vk_8 = 56, vk_9 = 57, vk_a = 65, vk_add = 107, vk_alt = 18, vk_b = 66,
  58.     vk_backspace = 8, vk_c = 67, vk_ctrl = 17, vk_d = 68, vk_decimal = 110, vk_delete = 46,
  59.     vk_divide = 111, vk_down = 40, vk_e = 69, vk_end = 35, vk_enter = 13, vk_escape = 27,
  60.     vk_f1 = 112, vk_f2 = 113, vk_f3 = 114, vk_f4 = 115, vk_f5 = 116, vk_f6 = 117,
  61.     vk_f7 = 118, vk_f8 = 119, vk_f9 = 120, vk_f10 = 121, vk_f11 = 122, vk_f12 = 123,
  62.     vk_g = 71, vk_h = 72, vk_home = 36, vk_f = 70, vk_i = 73, vk_insert = 45, vk_j = 74, vk_k = 75,
  63.     vk_l = 76, vk_left = 37, vk_m = 77, vk_multiply = 106, vk_n = 78, vk_num0 = 96, vk_num1 = 97,
  64.     vk_num2 = 98, vk_num3 = 99, vk_num4 = 100, vk_num5 = 101, vk_num6 = 102, vk_num7 = 103,
  65.     vk_num8 = 104, vk_num9 = 105, vk_o = 79, vk_p = 80, vk_pagedown = 34, vk_pageup = 33,
  66.     vk_pause = 19, vk_q = 81, vk_r = 82, vk_right = 39, vk_s = 83, vk_shift = 16, vk_space = 32,
  67.     vk_subtract = 109, vk_t = 84, vk_tab = 9, vk_u = 85, vk_up = 38, vk_v = 86, vk_w = 87,
  68.     vk_x = 88, vk_y = 89, vk_z = 90,
  69.     // collisions:
  70.     ct_null = 0, ct_point = 1, ct_box = 2, ct_circle = 3,
  71.     // tiles:
  72.     tu_tiles = [], tu_tilesi = [], tu_tilez = 256,
  73.     // sound variables:
  74.     tu_wav_supported = tu_detect_audio('audio/wav; codecs="1"'),
  75.     tu_ogg_supported = tu_detect_audio('audio/ogg; codecs="vorbis"'),
  76.     tu_mp3_supported = tu_detect_audio('audio/mpeg;'),
  77.     // drawing:
  78.     tu_draw_alpha = 1, tu_draw_color_red = tu_draw_color_green = tu_draw_color_blue = 0,
  79.     tu_draw_font = "Arial 12px", tu_draw_halign = "left", tu_draw_valign = "top",
  80.     tu_draw_font_ = { size: 12, family: 'Arial', bold: false, italic: false },
  81.     tu_draw_color = "rgb(" + tu_draw_color_red + "," +
  82.     tu_draw_color_green + "," + tu_draw_color_blue + ")",
  83.     tu_redraw, tu_redraw_auto = true,
  84.     tu_viewport_inst = null,
  85.     // drawing constants:
  86.     fa_left = "left", fa_center = "center", fa_right = "right",
  87.     fa_top = "top", fa_middle = "middle", fa_bottom = "bottom",
  88.     // system room variables:
  89.     tu_depth = [], tu_depthi = [], tu_depthu = [], tu_types = [], tu_persist = [],
  90.     // public room variables:
  91.     room_current = null,
  92.     room_speed = 30, fps = room_speed,
  93.     room_background = null,
  94.     room_width = 0, room_height = 0,
  95.     room_background_color_show = true, room_background_color_red = 0,
  96.     room_background_color_green = 0, room_background_color_blue = 0,
  97.     room_viewport_width = 0, room_viewport_height = 0,
  98.     room_viewport_object = null,
  99.     room_viewport_hborder = 0, room_viewport_vborder = 0,
  100.     room_viewport_x = 0, room_viewport_y = 0,
  101.     global = null;
  102. // keyboard functions:
  103. function keyboard_check(_key) { return key_down[_key]; }
  104. function keyboard_check_pressed(_key) { return key_pressed[_key]; }
  105. function keyboard_check_released(_key) { return key_released[_key]; }
  106. // mouse functions:
  107. function mouse_check() { return mouse_down; }
  108. function mouse_check_pressed() { return mouse_pressed; }
  109. function mouse_check_released() { return mouse_released; }
  110. // virtual keys:
  111. function vkey() {
  112.     this.top = 0;
  113.     this.left = 0;
  114.     this.right = 0;
  115.     this.bottom = 0;
  116.     this.key = 0;
  117.     this.down = false;
  118.     this.active = true;
  119. }
  120. function vkey_add(_x, _y, _w, _h, _k) {
  121.     var _v = new vkey();
  122.     _v.left = _x;
  123.     _v.top = _y;
  124.     _v.right = _x + _w;
  125.     _v.bottom = _y + _h;
  126.     _v.width = _w;
  127.     _v.height = _h;
  128.     _v.key = _k;
  129.     tu_vkeys.push(_v);
  130.     return _v;
  131. }
  132. // misc:
  133. function trace() { console.log.apply(console, arguments); }
  134. function tu_idle() { } // left empty on purpose
  135. // minimal math:
  136. function abs(_value) { return _value < 0 ? -_value : _value; }
  137. function sign(_value) { return _value > 0 ? 1 : _value < 0 ? -1 : 0; }
  138. function choose() { return arguments[~~(Math.random() * arguments.length)]; }
  139. function random(_value) { return Math.random() * _value; }
  140. function irandom(_value) { return ~~(Math.random() * _value + 1); }
  141. // trig functions:
  142. function lengthdir_x(_length, _direction) { return _length * Math.cos(_direction * tu_d2r); }
  143. function lengthdir_y(_length, _direction) { return _length * Math.sin(_direction * tu_d2r); }
  144. function point_distance(_x1, _y1, _x2, _y2) { return Math.sqrt(Math.pow(( _x1 - _x2), 2) + Math.pow((_y1 - _y2), 2)); }
  145. function point_direction(_x1, _y1, _x2, _y2) { return Math.atan2(_y2 - _y1, _x2 - _x1) * tu_r2d; }
  146. function degtorad(_degree) { return _degree * tu_d2r; }
  147. function radtodeg(_degree) { return _degree * tu_r2d; }
  148. // sound functions:
  149. function sound_mode(_sound, _mode) {
  150.     if (!_sound.audio) return;
  151.     if (_sound.audio.networkState == _sound.audio.NETWORK_NO_SOURCE) return;
  152.     switch (_sound.type) {
  153.     case "wav": if (!tu_wav_supported) return; break;
  154.     case "ogg": if (!tu_ogg_supported) return; break;
  155.     case "mp3": if (!tu_mp3_supported) return; break;
  156.     }
  157.     if (_mode != 3) {
  158.         _sound.audio.pause();
  159.         if (_mode != 0) {
  160.             _sound.audio.currentTime = 0;
  161.         } else return;
  162.         _sound.audio.loop = _mode > 1;
  163.     }
  164.     _sound.audio.play();
  165. }
  166. function sound_play(_sound) { sound_mode(_sound, 1); }
  167. function sound_loop(_sound) { sound_mode(_sound, 2); }
  168. function sound_resume(_sound) { sound_mode(_sound, 3); }
  169. function sound_stop(_sound) { sound_mode(_sound, 0); }
  170. function sound_stop_all() { for ( var _s = 0; _s < tu_audios.length; _s++) sound_stop( tu_audios[_s] ); }
  171. function sound_volume( _sound, _volume) {
  172.     if (!_sound.audio) return;
  173.     if (_sound.audio.networkState == _sound.audio.NETWORK_NO_SOURCE) return;
  174.     _sound.audio.volume = _volume;
  175. }
  176. // draw sprite:
  177. function draw_sprite(_sprite_index, _sub_image, _x, _y) {
  178.     if (_sprite_index == null) return;
  179.     if (_sub_image > _sprite_index.frames.length - 1) _sub_image = 0;
  180.     tu_context.save();
  181.     tu_context.translate(_x - room_viewport_x, _y - room_viewport_y);
  182.     tu_context.globalAlpha = tu_draw_alpha;
  183.     tu_context.drawImage(_sprite_index.frames[~~_sub_image], -_sprite_index.xoffset, -_sprite_index.yoffset);
  184.     tu_context.restore();
  185. }
  186. function draw_sprite_part(_sprite_index, _sub_image, _left, _top, _width, _height, _x, _y) {
  187.     if (_sprite_index == null) return;
  188.     if (_sub_image >= _sprite_index.frames.length) _sub_image = _sub_image % _sprite_index.frames.length;
  189.     tu_context.save();
  190.     tu_context.translate(_x - room_viewport_x, _y - room_viewport_y);
  191.     tu_context.globalAlpha = tu_draw_alpha;
  192.     tu_context.drawImage(_sprite_index.frames[~~_sub_image], _left, _top, _width, _height, 0, 0, _width, _height);
  193.     tu_context.restore();
  194. }
  195. function draw_sprite_ext(_sprite_index, _sub_image, _x, _y, _xscale, _yscale, _rotation, _alpha) {
  196.     if (_sprite_index == null) return;
  197.     if (_sub_image >= _sprite_index.frames.length) _sub_image = _sub_image % _sprite_index.frames.length;
  198.     tu_context.save();
  199.     tu_context.translate(_x - room_viewport_x, _y - room_viewport_y);
  200.     tu_context.rotate(degtorad(_rotation) + 0.0001);
  201.     tu_context.scale(_xscale, _yscale);
  202.     tu_context.globalAlpha = _alpha;
  203.     tu_context.drawImage(_sprite_index.frames[~~_sub_image], -_sprite_index.xoffset, -_sprite_index.yoffset);
  204.     tu_context.restore();
  205. }
  206. // draw text:
  207. function draw_text(_x, _y, _text) {
  208.     tu_context.font = tu_draw_font;
  209.     tu_context.textAlign = tu_draw_halign;
  210.     tu_context.textBaseline = tu_draw_valign;
  211.     if (tu_canvas_text_supported) {
  212.         tu_context.fillStyle = tu_context.strokeStyle = "rgba(" + tu_draw_color + ", " + tu_draw_alpha + ")";
  213.         tu_context.fillText( _text, _x - room_viewport_x, _y - room_viewport_y );
  214.     } else if (tu_text_overlay) {
  215.         var el = document.createElement('span');
  216.         el.textContent = _text;
  217.         el.style.cssText = 'position:absolute;white-space:nowrap;pointer-events:none;';
  218.         el.style.left = (_x - room_viewport_x) + 'px';
  219.         el.style.top = (_y - room_viewport_y) + 'px';
  220.         el.style.color = "rgba(" + tu_draw_color + ", " + tu_draw_alpha + ")";
  221.         el.style.font = tu_draw_font;
  222.         var tx = '0', ty = '0';
  223.         if (tu_draw_halign == 'center') tx = '-50%';
  224.         else if (tu_draw_halign == 'right') tx = '-100%';
  225.         if (tu_draw_valign == 'middle') ty = '-50%';
  226.         else if (tu_draw_valign == 'bottom') ty = '-100%';
  227.         el.style.transform = 'translate(' + tx + ', ' + ty + ')';
  228.         tu_text_overlay.appendChild(el);
  229.     }
  230. }
  231. // draw shapes:
  232. function draw_rectangle(_x1, _y1, _x2, _y2, _outline) {
  233.     tu_context.fillStyle = tu_context.strokeStyle = "rgba(" + tu_draw_color + ", " + tu_draw_alpha + ")";
  234.     tu_context.beginPath();
  235.     if (_outline) tu_context.strokeRect( _x1- room_viewport_x, _y1 - room_viewport_y, _x2 - _x1, _y2 - _y1 );
  236.     else tu_context.fillRect( _x1- room_viewport_x, _y1 - room_viewport_y, _x2 - _x1, _y2 - _y1 );
  237.     tu_context.closePath();
  238. }
  239. function draw_circle(_x, _y, _r, _outline) {
  240.     tu_context.fillStyle = tu_context.strokeStyle = "rgba(" + tu_draw_color + ", " + tu_draw_alpha + ")";
  241.     tu_context.beginPath();
  242.     tu_context.arc( _x - room_viewport_x, _y - room_viewport_y, _r, 0, tu_2pi, true );
  243.     tu_context.closePath();
  244.     !_outline ? tu_context.fill() : tu_context.stroke();
  245. }
  246.  
  247. function draw_line(_x1, _y1, _x2, _y2) {
  248.     tu_context.strokeStyle = "rgba(" + tu_draw_color + ", " + tu_draw_alpha + ")";
  249.     tu_context.beginPath();
  250.     tu_context.moveTo( _x1 - room_viewport_x, _y1 - room_viewport_y );
  251.     tu_context.lineTo( _x2 - room_viewport_x, _y2 - room_viewport_y );
  252.     tu_context.closePath();
  253.     tu_context.stroke();   
  254. }
  255. // draw settings:
  256. function draw_set_alpha(_alpha) {
  257.     tu_draw_alpha = _alpha;
  258. }
  259. function draw_set_color( _r, _g, _b) {
  260.     tu_draw_color_red = _r;
  261.     tu_draw_color_green = _g;
  262.     tu_draw_color_blue = _b;
  263.     tu_draw_color = tu_draw_color_red + "," + tu_draw_color_green + "," + tu_draw_color_blue;
  264.     tu_context.fillStyle = "rgba(" + tu_draw_color + ", " + tu_draw_alpha + ")";
  265.     tu_context.strokeStyle = "rgb(" + tu_draw_color + ")";
  266. }
  267. function draw_set_linewidth(_width) { tu_context.lineWidth = _width; }
  268. // draw settings - font:
  269. function draw_set_font (_font) {
  270.     tu_draw_font_ = _font;
  271.     tu_draw_font = (_font.bold == 1 ? "bold" : "") + " " + (_font.italic == 1 ? "italic" : "") + " " + _font.size + "px " + _font.family;
  272.     tu_context.font = tu_draw_font;
  273.     tu_context.textAlign = tu_draw_halign;
  274.     tu_context.textBaseline = tu_draw_valign;
  275. }
  276. function draw_set_halign(_halign) { tu_draw_halign = _halign; }
  277. function draw_set_valign(_valign) { tu_draw_valign = _valign; }
  278. // room translations:
  279. function room_goto(_scene) {
  280.     tu_viewport_inst = null;
  281.     tu_room_to_go = _scene;
  282. }
  283. function room_goto_next() {
  284.     var _ri = 0, _r;
  285.     for (_r = 0; _r < tu_scenes.length; _r++) if (tu_scenes[_r] == room_current) _ri = _r;
  286.     if (typeof tu_scenes[(_ri + 1)] == "object") room_goto(tu_scenes[_ri + 1]);
  287. }
  288. function room_goto_previous() {
  289.     var _ri = 0, _r;
  290.     for (_r = 0; _r < tu_scenes.length; _r++) if (tu_scenes[_r] == room_current) _ri = _r;
  291.     if (typeof tu_scenes[(_ri - 1)] == "object") room_goto(tu_scenes[_ri - 1]);
  292. }
  293. function room_goto_first() { room_goto(tu_scenes[0]); }
  294. function room_goto_last() { room_goto(tu_scenes[(tu_scenes.length - 1)]); }
  295. function room_restart() { room_goto(room_current); }
  296. // instance functions:
  297. function instance_create_(_x, _y, _object) {
  298.     var o = new _object.constructor;
  299.     o.parameters = arguments.length > 3 ? Array.prototype.slice.call(arguments, 3) : [];
  300.     o.object_index = _object;
  301.     o.__instance = true;
  302.     o.xstart = o.x = _x;
  303.     o.ystart = o.y = _y;
  304.     o._depth = o.depthstart;
  305.     instance_activate(o);
  306.     return o;
  307. }
  308. function instance_create(_x, _y, _object) {
  309.     var o = instance_create_.apply(this, arguments);
  310.     o.on_creation();
  311.     return o;
  312. }
  313. function instance_number(_object) {
  314.     return instance_list(_object).length;
  315. }
  316. function instance_first(_object) {
  317.     var l = instance_list(_object);
  318.     return l.length ? l[0] : null;
  319. }
  320. // BBox <> BBox
  321. function collide_bbox_bbox(l1, t1, r1, b1, l2, t2, r2, b2) {
  322.     return !(b1 <= t2 || t1 >= b2 || r1 <= l2 || l1 >= r2);
  323. }
  324. // BBox <> SpriteBox
  325. // (left, top, right, bottom, instX, instY, scaleX, scaleY, sprite, ofsX, ofsY)
  326. function collide_bbox_sbox(l1, t1, r1, b1, x2, y2, h2, v2, s2) {
  327.     return
  328.     !( b1 <= y2 + v2 * (s2.collision_top - s2.yoffset)
  329.     || t1 >= y2 + v2 * (s2.collision_bottom - s2.yoffset)
  330.     || r1 <= x2 + h2 * (s2.collision_left - s2.xoffset)
  331.     || l1 <= x2 + h2 * (s2.collision_right - s2.xoffset));
  332. }
  333. // SpriteBox <> BBox
  334. function collide_sbox_point(x2, y2, h2, v2, s2, x1, y1) {
  335.     return
  336.     !( y1 <= y2 + v2 * (s2.collision_top - s2.yoffset)
  337.     || y1 >= y2 + v2 * (s2.collision_bottom - s2.yoffset)
  338.     || x1 <= x2 + h2 * (s2.collision_left - s2.xoffset)
  339.     || x1 <= x2 + h2 * (s2.collision_right - s2.xoffset));
  340. }
  341. // SpriteBox <> Circle
  342. function collide_sbox_circle(x2, y2, h2, v2, s2, x1, y1, r1) {
  343.     var u, v, dx, dy;
  344.     u = x2 + h2 * (s2.collision_left - s2.xoffset);
  345.     v = x2 + h2 * (s2.collision_right - s2.xoffset);
  346.     dx = (x2 < u ? u : x2 > v ? v : x2) - x2;
  347.     u = y2 + v2 * (s2.collision_top - s2.yoffset);
  348.     v = y2 + v2 * (s2.collision_bottom - s2.yoffset);
  349.     dy = (y2 < u ? u : y2 > v ? v : y2) - y2;
  350.     return (dx * dx + dy * dy < r1 * r1);
  351. }
  352. // BBox <> Point
  353. function collide_bbox_point(l1, t1, r1, b1, x2, y2) {
  354.     return (x2 > l1 && x2 < r1 && y2 > t1 && y2 < b1);
  355. }
  356. // BBox <> Circle
  357. function collide_bbox_circle(l1, t1, r1, b1, x2, y2, r2) {
  358.     var dx = (x2 < l1 ? l1 : x2 > r1 ? r1 : x2) - x2,
  359.         dy = (y2 < t1 ? t1 : y2 > b1 ? b1 : y2) - y2;
  360.     return (dx * dx + dy * dy < r2 * r2);
  361. }
  362. // Circle <> Range
  363. function collide_circle_range(dx, dy, dr) {
  364.     return (dx * dx + dy * dy < dr * dr);
  365. }
  366. // Circle <> Circle
  367. function collide_circle_circle(x1, y1, r1, x2, y2, r2) {
  368.     return collide_circle_range(x1 - x2, y1 - y2, r1 + r2);
  369. }
  370. // Circle <> Point
  371. function collide_circle_point(x1, y1, r1, x2, y2) {
  372.     return collide_circle_range(x1 - x2, y1 - y2, r1);
  373. }
  374. // instance collision checking:
  375. function instance_position(_px, _py, _object, _mult) {
  376.     var _x, _y, _ox, _oy, _sx, _sy, _o, _s, _i, _il, _r, _dx, _dy,
  377.         _q = (_object.__instance ? [_object] : instance_list(_object)),
  378.         _tm = (_mult) ? true : false;
  379.     if (_tm) _ta = [];
  380.     _il = _q.length;
  381.     for (_i = 0; _i < _il; _i++) {
  382.         _o = _q[_i];
  383.         if (!_o.collision_checking) continue;
  384.         _s = _o.sprite_index;
  385.         if (!_s) continue;
  386.         _x = _o.x; _sx = _o.image_xscale;
  387.         _y = _o.y; _sy = _o.image_yscale;
  388.         switch (_s.collision_shape)
  389.         {
  390.         case 0x2:
  391.             if (_sx == 1 && _sy == 1) {
  392.                 _ox = _s.xoffset; _oy = _s.yoffset;
  393.                 if (!collide_bbox_point(_x + _s.collision_left - _ox, _y + _s.collision_top - _oy,
  394.                 _x + _s.collision_right - _ox, _y + _s.collision_bottom - _oy, _px, _py)) break;
  395.             } else if (!collide_sbox_point(_x, _y, _sx, _sy, _s)) break;
  396.             if (!_tm) return _o;
  397.             _ta.push(_o);
  398.             break;
  399.         case 0x3:
  400.             _r = _s.collision_radius * Math.max(_o.image_xscale, _o.image_yscale);
  401.             _dx = _o.x + (_s.width / 2 - _s.xoffset) - _px;
  402.             _dy = _o.y + (_s.height / 2 - _s.yoffset) - _py;
  403.             if ((_dx * _dx) + (_dy * _dy) > _r * _r) break;
  404.             if (!_tm) return _o;
  405.             _ta.push(_o);
  406.             break;
  407.         }
  408.     }
  409.     return _tm ? _ta : null;
  410. }
  411. //
  412. function __place_meeting__(nx, ny, what, many) {
  413.     this.other = null;
  414.     var i, l,
  415.         // sprite, scale:
  416.         ts = this.sprite_index,
  417.         tsx, tsy, tfx, tfy, tst,
  418.         // circle:
  419.         tcx, tcy, tcr,
  420.         // bbox:
  421.         tbl, tbr, tbt, tbb,
  422.         // instances, multiple, output, types:
  423.         tz, tm, ct, ch, ra,
  424.         // other:
  425.         o, ox, oy, os, ost, osx, osy, ofx, ofy, ofr;
  426.     if (ts == null) return false;
  427.     tfx = ts.xoffset;
  428.     tfy = ts.yoffset;
  429.     tsx = this.image_xscale;
  430.     tsy = this.image_yscale;
  431.     tst = ts.collision_shape;
  432.     // bbox:
  433.     if (tst == 2) {
  434.         tbl = nx + tsx * (ts.collision_left - tfx);
  435.         tbr = nx + tsx * (ts.collision_right - tfx);
  436.         tbt = ny + tsy * (ts.collision_top - tfy);
  437.         tbb = ny + tsy * (ts.collision_bottom - tfy);
  438.     }
  439.     // circle:
  440.     if (tst == 3) {
  441.         tcr = ts.collision_radius * (tsx > tsy ? tsx : tsy);
  442.         tcx = nx + tsx * (ts.width / 2 - tfx);
  443.         tcy = ny + tsy * (ts.height / 2 - tfy);
  444.     }
  445.     //
  446.     tz = (what.__instance ? [what] : instance_list(what));
  447.     tm = many ? true : false;
  448.     if (tm) ra = [];
  449.     l = tz.length;
  450.     for (i = 0; i < l; i++) {
  451.         o = tz[i];
  452.         if (!o.collision_checking) continue;
  453.         os = o.sprite_index;
  454.         if (os == null) continue;
  455.         ox = o.x; osx = o.image_xscale;
  456.         oy = o.y; osy = o.image_yscale;
  457.         ost = os.collision_shape;
  458.         ct = (tst << 4) | ost;
  459.         ch = false;
  460.         switch(ct) {
  461.         case 0x22:
  462.             if (osx == 1 && osy == 1) {
  463.                 ofx = os.xoffset; ofy = os.yoffset;
  464.                 if (!collide_bbox_bbox(tbl, tbt, tbr, tbb,
  465.                 ox + os.collision_left - ofx, oy + os.collision_top - ofy,
  466.                 ox + os.collision_right - ofx, oy + os.collision_bottom - ofy)) break;
  467.             } else if (!collide_bbox_sbox(tbl, tbt, tbr, tbb, ox, oy, osx, osy, os)) break;
  468.             ch = true;
  469.             break;
  470.         case 0x23:
  471.             ofr = os.collision_radius * (osx > osy ? osx : osy);
  472.             ofx = ox + osx * (os.width / 2 - os.xoffset);
  473.             ofy = oy + osy * (os.height / 2 - os.yoffset);
  474.             if (!collide_bbox_circle(tbl, tbt, tbr, tbb, ofx, ofy, ofr)) break;
  475.             ch = true;
  476.             break;
  477.         case 0x32:
  478.             if (osx == 1 && osy == 1) {
  479.                 ofx = os.xoffset; ofy = os.yoffset;
  480.                 if (!collide_bbox_circle(
  481.                 ox + os.collision_left - ofx, oy + os.collision_top - ofy,
  482.                 ox + os.collision_right - ofx, oy + os.collision_bottom - ofy,
  483.                 tcx, tcy, tcr)) break;
  484.             } else if (!collide_sbox_circle(ox, oy, osx, osy, os, tcx, tcy, tcr)) break;
  485.             ch = true;
  486.             break;
  487.         case 0x33:
  488.             ofr = os.collision_radius * (osx > osy ? osx : osy);
  489.             ofx = ox + osx * (os.width / 2 - os.xoffset);
  490.             ofy = oy + osy * (os.height / 2 - os.yoffset);
  491.             if (!collide_circle_circle(tcx, tcy, tcr, ofx, ofy, ofr)) break;
  492.             ch = true;
  493.             break;
  494.         } if (!ch) continue;
  495.         this.other = o;
  496.         o.other = this;
  497.         if (!tm) return (o);
  498.         ra.push(o);
  499.     } return ra;
  500. }
  501. function position_meeting(_x, _y, _object) {
  502.     return instance_position(_x, _y, _object) != null;
  503. }
  504. function __move_towards_point__(_x, _y, _speed) {
  505.     if (_speed == 0) return;
  506.     if (this.x == _x && this.y == _y) return;
  507.     var _dx = _x - this.x,
  508.         _dy = _y - this.y,
  509.         _dist = _dx * _dx + _dy * _dy;
  510.     if (_dist < _speed * _speed) {
  511.         this.x = _x;
  512.         this.y = _y;
  513.     } else {
  514.         _dist = Math.sqrt(_dist);
  515.         this.x += _dx * _speed / _dist;
  516.         this.y += _dy * _speed / _dist;
  517.     }
  518. }
  519.  
  520. function __instance_destroy__() {
  521.     tu_trash.push( this );
  522. }
  523. // web data:
  524. function save_web_data(_name, _value) { if (window.localStorage) window.localStorage.setItem(_name, _value); }
  525. function save_web_integer(_name, _value) { if (window.localStorage) window.localStorage.setItem("int_" + _name, _value); }
  526. function save_web_float(_name, _value) { if (window.localStorage) window.localStorage.setItem("float_" + _name, _value); }
  527. function save_web_string(_name, _value) { if (window.localStorage) window.localStorage.setItem("string_" + _name, _value); }
  528. function load_web_data(_name) { if (window.localStorage) return window.localStorage.getItem(_name); }
  529. function load_web_integer(_name) { if (window.localStorage) return parseInt(window.localStorage.getItem("int_" + _name)); }
  530. function load_web_float(_name) { if (window.localStorage) return parseFloat(window.localStorage.getItem("float_" + _name)); }
  531. function load_web_string(_name) { if (window.localStorage) return '' + window.localStorage.getItem("string_" + _name); }
  532. function delete_web_data(_name) { if (window.localStorage) window.localStorage.removeItem(_name); }
  533. function delete_web_integer(_name) { if (window.localStorage) window.localStorage.removeItem("int_" + _name); }
  534. function delete_web_float(_name) { if (window.localStorage) window.localStorage.removeItem("float_" + _name); }
  535. function delete_web_string(_name) { if (window.localStorage) window.localStorage.removeItem("string_" + _name); }
  536. function clear_web_data() { if (window.localStorage) window.localStorage.clear(); }
  537. function web_data_number() { if (window.localStorage) return window.localStorage.length; }
  538. // misc functions:
  539. function pause_game( _key) {
  540.     tu_paused = true;
  541.     tu_unpausekey = _key;
  542. }
  543. function modal_end() {
  544.     if (tu_modal == null) return;
  545.     tu_modal.instance_destroy();
  546.     tu_modal = null;
  547. }
  548. function modal_start(_inst, _draw) {
  549.     if (tu_modal != null) modal_end();
  550.     tu_modal = _inst;
  551.     tu_modaldraw = _draw;
  552. }
  553. //
  554. function show_mouse() { tu_canvas.style.cursor = "default"; }
  555. function hide_mouse() { tu_canvas.style.cursor = "none"; }
  556. //
  557. function tu_gettime() { return (new Date()).getTime(); }
  558.  
  559. /***********************************************************************
  560.  * ENGINE
  561.  ***********************************************************************/
  562.  
  563. function tu_global () { }
  564. global = new tu_global();
  565. //{ Events
  566. function __keydownlistener__(e) {
  567.     var r = true;
  568.     if (!e) e = window.event;
  569.     if (document.activeElement && document.activeElement == tu_canvas || document.activeElement == document.body) r = false;
  570.     if (e.repeat) return;
  571.     var keyCode = window.event ? e.which : e.keyCode;
  572.     if (!key_down[keyCode]) {
  573.         key_pressed[keyCode] = true;
  574.         tu_keys_pressed.push(keyCode);
  575.     }
  576.     key_down[keyCode] = true;
  577.     if (!r) e.preventDefault();
  578.     return r;
  579. };
  580. function __keyuplistener__(e) {
  581.     var r = true;
  582.     if (!e) e = window.event;
  583.     if (document.activeElement && document.activeElement == tu_canvas || document.activeElement == document.body) r = false;
  584.     var keyCode = window.event ? e.which : e.keyCode;
  585.     if (key_down[keyCode])
  586.     {
  587.         key_released[keyCode] = true;
  588.         tu_keys_released.push(keyCode);
  589.     }
  590.     key_down[keyCode] = false;
  591.     if (!r) e.preventDefault();
  592.     return r;
  593. };
  594. function __touchsim__(_x, _y) {
  595.     var r = [{}];
  596.     r[0].pageX = tu_canvas.offsetLeft + _x;
  597.     r[0].pageY = tu_canvas.offsetTop + _y;
  598.     __touchvkey__(r);
  599. }
  600. function __mousemovelistener__(_e) {
  601.     if (_e.pageX != undefined && _e.pageY != undefined) {
  602.         mouse_x = _e.pageX;
  603.         mouse_y = _e.pageY;
  604.     } else {
  605.         mouse_x = _e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
  606.         mouse_y = _e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
  607.     }
  608.     if (room_current != null) {
  609.         mouse_x -= tu_canvas.offsetLeft;
  610.         mouse_y -= tu_canvas.offsetTop;        
  611.     }
  612.     if (mouse_down) __touchsim__(mouse_x, mouse_y);
  613. };
  614. function __mousedownlistener__(_e) {
  615.     //if (!mouse_down) mouse_pressed = true;
  616.     //mouse_down = true;
  617.     __touchsim__(mouse_x, mouse_y);
  618. };
  619. function __mouseuplistener__(_e) {
  620.     //if (mouse_down) mouse_released = true;
  621.     //mouse_down = false;
  622.     __touchvkey__([]);
  623. };
  624. function __touchvkey__(_t) {
  625.     var _tx = 0, _ty = 0, _tc = 0, _tl = _t.length, _vl = tu_vkeys.length, _i, _j, _c, _k,
  626.         _dx = tu_canvas.offsetLeft, _dy = tu_canvas.offsetTop, _mx = _my = 1;
  627.     if (tu_canvas.style.width) _mx
  628.     touch_x = []; touch_y = []; touch_count = 0;
  629.     for (_i = 0; _i < _vl; _i++) tu_vkeys[_i].count = 0;
  630.     for (_i = 0; _i < _tl; _i++) {
  631.         _c = 0;
  632.         for (_j = 0; _j < _vl; _j++) {
  633.             if (!tu_vkeys[_j].active) continue;
  634.             if (_t[_i].pageX - _dx > tu_vkeys[_j].right) continue;
  635.             if (_t[_i].pageX - _dx < tu_vkeys[_j].left) continue;
  636.             if (_t[_i].pageY - _dy < tu_vkeys[_j].top) continue;
  637.             if (_t[_i].pageY - _dy > tu_vkeys[_j].bottom) continue;
  638.             tu_vkeys[_j].count++;
  639.             if (!tu_vkeys[_j].down) {
  640.                 tu_vkeys[_j].down = true;
  641.                 _k = tu_vkeys[_j].key;
  642.                 if (!key_down[_k]) {
  643.                     key_down[_k] = true;
  644.                     key_pressed[_k] = true;
  645.                     tu_keys_pressed.push(_k);
  646.                 }
  647.             }
  648.             _c++;
  649.         }
  650.         if (_c == 0) {
  651.             _tx += _t[_i].pageX;
  652.             _ty += _t[_i].pageY;
  653.             touch_x[_tc] = _t[_i].pageX - _dx;
  654.             touch_y[_tc] = _t[_i].pageY - _dy;
  655.             _tc++;
  656.         }
  657.     }
  658.     for (_i = 0; _i < _vl; _i++) {
  659.         if (tu_vkeys[_i].count != 0) continue;
  660.         if (!tu_vkeys[_i].down) continue;
  661.         tu_vkeys[_i].down = false;
  662.         _k = tu_vkeys[_i].key;
  663.         if (key_down[_k]) {
  664.             key_down[_k] = false;
  665.             key_released[_k] = true;
  666.             tu_keys_released.push(_k);
  667.         }
  668.     }
  669.     touch_count = _tc;
  670.     if (_tc != 0) {
  671.         mouse_x = (_tx / _tc) - _dx;
  672.         mouse_y = (_ty / _tc) - _dy;
  673.         if (!mouse_down) {
  674.             mouse_down = true;
  675.             mouse_pressed = true;
  676.         }
  677.     } else if (mouse_down) {
  678.         mouse_down = false;
  679.         mouse_released = true;
  680.     }
  681. };
  682. function __touchlistener__(e) {
  683.     e.preventDefault();
  684.     __touchvkey__(e.targetTouches);
  685. };
  686. //}
  687. function tu_init () {
  688.     if (document.addEventListener) {
  689.         document.addEventListener("keydown", __keydownlistener__, false);
  690.         document.addEventListener("keyup", __keyuplistener__, false);
  691.         document.addEventListener("mousemove", __mousemovelistener__, false);
  692.         document.addEventListener("mousedown", __mousedownlistener__, false);
  693.         document.addEventListener("mouseup", __mouseuplistener__, false);
  694.         document.addEventListener("touchstart", __touchlistener__, false);
  695.         document.addEventListener("touchend", __touchlistener__, false);
  696.         document.addEventListener("touchmove", __touchlistener__, false);
  697.         document.addEventListener("touchenter", __touchlistener__, false);
  698.         document.addEventListener("touchleave", __touchlistener__, false);
  699.         document.addEventListener("touchcancel", __touchlistener__, false);
  700.     } else {
  701.         document.attachEvent("onkeydown", __keydownlistener__);
  702.         document.attachEvent("onkeyup", __keyuplistener__);
  703.         document.attachEvent("onmousemove", __mousemovelistener__);
  704.         document.attachEvent("onmousedown", __mousedownlistener__);
  705.         document.attachEvent("onmouseup", __mouseuplistener__);
  706.     }
  707.     // initialize keycodes
  708.     for (var _k = 0; _k < 256; _k++) {
  709.         key_down[_k] = key_pressed[_k] = key_released[_k] = false;
  710.     }
  711. }
  712.  
  713. function tu_loading_inc() { tu_loading++; tu_load_total++; }
  714. function tu_loading_dec() { tu_loading--; }
  715.  
  716. function _$_(_id_) {
  717.     return document.getElementById( _id_ );
  718. }
  719.  
  720. function var_override(_what, _svar, _fget, _fset) {
  721.     if (var_override_) {
  722.         if (_what.hasOwnProperty(_svar)) return;
  723.         Object.defineProperty(_what, _svar, {
  724.             get: _fget,
  725.             set: _fset
  726.         });
  727.     } else {
  728.         if (_what.__lookupGetter__(_svar) != undefined) return;
  729.         _what.__defineGetter__(_svar, _fget);
  730.         _what.__defineSetter__(_svar, _fset);
  731.     }
  732. }
  733.  
  734. //{ Depth
  735. function _tu_depth_find(_d) {
  736.     var _tl = tu_depthi.length, _td, _ti;
  737.     for (_ti = 0; _ti < _tl; _ti++) {
  738.         _td = tu_depthi[_ti];
  739.         if (_d > _td) return _ti;
  740.     }
  741.     return _tl;
  742. }
  743. function _tu_depth_new(_d) {
  744.     var _i = _tu_depth_find(_d), _o = [];
  745.     tu_depth.splice(_i, 0, _o);
  746.     tu_depthi.splice(_i, 0, _d);
  747.     return _i;
  748. }
  749. function tu_depth_add(_d, _o) {
  750.     var _t = tu_depthi.indexOf(_d);
  751.     if (_t == -1) _t = _tu_depth_new(_d); // create array if none
  752.     tu_depth[_t].push(_o);
  753. }
  754. function tu_depth_delete(_d, _o) {
  755.     var _t = tu_depth[tu_depthi.indexOf(_d)], _ti = _t.indexOf(_o);
  756.     if (_ti == -1) return;
  757.     _t.splice(_ti, 1);
  758. }
  759. function tu_depth_update() {
  760.     var i, l = tu_depthu.length, o;
  761.     if (l == 0) return;
  762.     for (i = 0; i < l; i++) {
  763.         o = tu_depthu[i];
  764.         if (o.instance_active && o._depth !== undefined) tu_depth_delete(o._depth, o);
  765.         o._depth = o._depthn;
  766.         if (o.instance_active && o._depth !== undefined) tu_depth_add(o._depth, o);
  767.         o._depthu = false;
  768.     }
  769.     tu_depthu = [];
  770. }
  771. // Accessors:
  772. function tu_depth_get() { return this._depth; }
  773. function tu_depth_set(_d) {
  774.     if (this._depth == _d) return; // don't change on depth match
  775.     this._depthn = _d;
  776.     if (this._depthu) return;
  777.     this._depthu = true;
  778.     tu_depthu.push(this);
  779. }
  780. //}
  781. //{ Types
  782. function instance_list(_o) {
  783.     var _t = _o._object_index_;
  784.     if (tu_types[_t] == undefined) tu_types[_t] = [];
  785.     return tu_types[_t];
  786. }
  787. function tu_type_add(_d, _o) {
  788.     instance_list(_d).push(_o);
  789. }
  790. function tu_type_delete(_o, _p) {
  791.     var _d = tu_types[_p], _t = _d.indexOf(_o);
  792.     _d.splice(_t, 1);
  793. }
  794. function tu_type_get() { return this._object_index; }
  795. //}
  796. //{ Tileset functions
  797. function tile_layer_find(_d) {
  798.     var _tl = tu_tilesi.length, _td, _ti;
  799.     for (_ti = 0; _ti < _tl; _ti++) {
  800.         _td = tu_tilesi[_ti];
  801.         if (_d > _td) return _ti;
  802.     }
  803.     return _tl;
  804. }
  805. function tile_layer_add(_d) {
  806.     var _i = tile_layer_find(_d), _o = [];
  807.     tu_tiles.splice(_i, 0, _o);
  808.     tu_tilesi.splice(_i, 0, _d);
  809.     return _o;
  810. }
  811. function tile(_s, _x, _y, _l, _t, _w, _h) {
  812.     this.source = _s;
  813.     this.x = _x;
  814.     this.y = _y;
  815.     this.left = _l;
  816.     this.top = _t;
  817.     this.width = _w;
  818.     this.height = _h;
  819.     this.width2 = _w;
  820.     this.height2 = _h;
  821.     this.sectors = [];
  822. }
  823. function tile_add(_b, _l, _t, _w, _h, _x, _y, _z) {
  824.     var _tx1 = Math.floor(_x / tu_tilez),
  825.         _ty1 = Math.floor(_y / tu_tilez),
  826.         _tx2 = Math.floor((_x + _w) / tu_tilez),
  827.         _ty2 = Math.floor((_y + _h) / tu_tilez),
  828.         _tt = new tile(_b, _x, _y, _l, _t, _w, _h),
  829.         _tx, _ty, _ts,
  830.         _d, _e = tu_tilesi.indexOf(_z);
  831.     if (_e != -1) _d = tu_tiles[_e];
  832.     else _d = tile_layer_add(_z);
  833.     for (_tx = _tx1; _tx <= _tx2; _tx++) {
  834.         if (_d[_tx] == null) _d[_tx] = [];
  835.         for (_ty = _ty1; _ty <= _ty2; _ty++) {
  836.             if (_d[_tx][_ty] == null) _d[_tx][_ty] = [];
  837.             _ts = _d[_tx][_ty];
  838.             _ts.push(_tt);
  839.             _tt.sectors.push(_ts);
  840.         }
  841.     }
  842.     return _tt;
  843. }
  844. function tile_find(_x, _y, _w, _h, _d) {
  845.     var _xw = _x + _w,
  846.         _yh = _y + _h,
  847.         _r = [],
  848.         _tx, _ty, _ti, _tl, _ts, _tt, _ta,
  849.         _tx1, _ty1, _tx2, _ty2;
  850.     _ti = tu_tilesi.indexOf(_d);
  851.     if (_ti == -1) return _r;
  852.     _ta = tu_tiles[_ti];
  853.     _tx1 = Math.floor(_x / tu_tilez);
  854.     _ty1 = Math.floor(_y / tu_tilez);
  855.     _tx2 = Math.floor((_x + _w) / tu_tilez);
  856.     _ty2 = Math.floor((_y + _h) / tu_tilez);
  857.     for (_tx = _tx1; _tx <= _tx2; _tx++) {
  858.         if (_ta[_tx] == null) continue;
  859.         for (_ty = _ty1; _ty <= _ty2; _ty++) {
  860.             if (_ta[_tx][_ty] == null) continue;
  861.             _ts = _ta[_tx][_ty];
  862.             _tl = _ts.length;
  863.             for (_ti = 0; _ti < _tl; _ti++) {
  864.                 _tt = _ts[_ti];
  865.                 if (_tt.x >= _xw) continue;
  866.                 if (_tt.y >= _yh) continue;
  867.                 if (_tt.x + _tt.width2 < _x) continue;
  868.                 if (_tt.y + _tt.height2 < _y) continue;
  869.                 _r.push(_tt);
  870.             }
  871.         }
  872.     }
  873.     return _r;
  874. }
  875. function tile_delete(_t) {
  876.     var _ti, _tl, _ts;
  877.     _tl = _t.sectors.length;
  878.     for (_ti = 0; _ti < _tl; _ti++) {
  879.         _ts = _t.sectors[_ti];
  880.         _ts.splice(_ts.indexOf(_t), 1);
  881.     }
  882. }
  883. function tile_srender(_s) {
  884.     var _ti, _tt;
  885.     for (_ti = 0; _ti < _s.length; _ti++) {
  886.         if (_s[_ti] == null) continue;
  887.         _tt = _s[_ti];
  888.         if (_tt.source == null) continue;
  889.         if (_tt.source.image == null) continue;
  890.         tu_context.drawImage(_tt.source.image, _tt.left, _tt.top, _tt.width, _tt.height, _tt.x - room_viewport_x, _tt.y - room_viewport_y, _tt.width2, _tt.height2);
  891.     }
  892. }
  893. function tile_lrender(_l) {
  894.     var _tx, _ty,
  895.         _tx1 = Math.floor(room_viewport_x / tu_tilez),
  896.         _tx2 = Math.floor((room_viewport_x + room_viewport_width) / tu_tilez),
  897.         _ty1 = Math.floor(room_viewport_y / tu_tilez),
  898.         _ty2 = Math.floor((room_viewport_y + room_viewport_height) / tu_tilez);
  899.     for (_tx = _tx1; _tx <= _tx2; _tx++) {
  900.         if (_l[_tx] == null) continue;
  901.         for (_ty = _ty1; _ty <= _ty2; _ty++) {
  902.             if (_l[_tx][_ty] == null) continue;
  903.             tile_srender(_l[_tx][_ty]);
  904.         }
  905.     }
  906. }
  907. //} /Tileset functions
  908. //{ Some events & accessors
  909. function tu_id_get() { return this; }
  910. function tu_parent_get() { return this._parent_index; }
  911. function image_single_get() { return (this.image_speed == 0 ? this.image_index : -1); }
  912. function image_single_set(_o) { this.image_speed = 0; this.image_index = _o; }
  913. // Handles object size & sprite updates. Should get rid of this in favor of accessors.
  914. function __handle_sprite__(_object_) {
  915.     if (_object_.sprite_index == null) return;
  916.     _object_.sprite_width = _object_.sprite_index.width;
  917.     _object_.sprite_height = _object_.sprite_index.height;
  918.     _object_.sprite_xoffset = _object_.sprite_index.xoffset;
  919.     _object_.sprite_yoffset = _object_.sprite_index.yoffset;
  920.     _object_.image_number = _object_.sprite_index.frames.length;
  921.     _object_.image_index += _object_.image_speed;
  922.     if (_object_.image_index >= _object_.image_number) _object_.image_index = _object_.image_index % _object_.image_number;
  923.     if (_object_.image_index < 0) _object_.image_index = _object_.image_number - 1 + (_object_.image_index % _object_.image_number);
  924. }
  925. function __draw_self__() {
  926.     draw_sprite_ext(this.sprite_index, this.image_index, this.x, this.y, this.image_xscale, this.image_yscale, this.image_angle, this.image_alpha);
  927. }
  928. //}
  929. //{ Inherited event lookup functions.
  930. // There's also a way to do this with much shorter code.
  931. function on_creation_i() {
  932.     for (var o = this.parent; o; o = o.parent)
  933.     if (o.on_creation !== on_creation_i)
  934.     return o.on_creation.apply(this);
  935. }
  936. function on_destroy_i() {
  937.     for (var o = this.parent; o; o = o.parent)
  938.     if (o.on_destroy !== on_destroy_i)
  939.     return o.on_destroy.apply(this);
  940. }
  941. function on_step_i() {
  942.     for (var o = this.parent; o; o = o.parent)
  943.     if (o.on_step !== on_step_i)
  944.     return o.on_step.apply(this);
  945. }
  946. function on_end_step_i() {
  947.     for (var o = this.parent; o; o = o.parent)
  948.     if (o.on_end_step !== on_end_step_i)
  949.     return o.on_end_step.apply(this);
  950. }
  951. function on_draw_d() {
  952.     __handle_sprite__(this);
  953.     __draw_self__.apply(this);
  954. }
  955. function on_draw_i() {
  956.     for (var o = this.parent; o; o = o.parent)
  957.     if (o.on_draw !== on_draw_i)
  958.     return o.on_draw.apply(this);
  959.     on_draw_d.apply(this);
  960. }
  961. function on_collision_i() {
  962.     for (var o = this.parent; o; o = o.parent)
  963.     if (o.on_collision !== on_collision_i)
  964.     return o.on_collision.apply(this);
  965. }
  966. function on_animationend_i() {
  967.     for (var o = this.parent; o; o = o.parent)
  968.     if (o.on_animationend !== on_animationend_i)
  969.     return o.on_animationend.apply(this);
  970. }
  971. function on_roomstart_i() {
  972.     for (var o = this.parent; o; o = o.parent)
  973.     if (o.on_roomstart !== on_roomstart_i)
  974.     return o.on_roomstart.apply(this);
  975. }
  976. function on_roomend_i() {
  977.     for (var o = this.parent; o; o = o.parent)
  978.     if (o.on_roomend !== on_roomend_i)
  979.     return o.on_roomend.apply(this);
  980. }
  981. //} /Inherited event handles
  982.  
  983. // instance_init(this, object_index, parent_index, visible, depth, sprite, collideable, inner index)
  984. // Universal object constructor:
  985. function __instance_init__(_this, _oi, _p, _v, _d, _si, _c, _io) {
  986.     _this._object_index = undefined;
  987.     _this._object_index_ = _io;
  988.     _this._depth = undefined;
  989.     _this._depthn = undefined;
  990.     _this._depthu = false;
  991.     var_override(_this, 'depth', tu_depth_get, tu_depth_set );
  992.     var_override(_this, 'object_index', tu_type_get, tu_idle );
  993.     var_override(_this, 'image_single', image_single_get, image_single_set );
  994.     var_override(_this, 'id', tu_id_get, tu_idle);
  995.     var_override(_this, 'parent', tu_parent_get, tu_idle);
  996.     _this._object_index = _oi;
  997.     _this._parent_index = _p;
  998.     _this.xstart = _this.xprevious = _this.x = 0;
  999.     _this.ystart = _this.yprevious = _this.y = 0;
  1000.     _this.depthstart = _d;
  1001.     _this.image_angle = _this.direction = 0;
  1002.     _this.visible = _v;
  1003.     _this.image_yscale = _this.image_xscale = 1;
  1004.     _this.image_alpha = 1;
  1005.     _this.image_index = 0;
  1006.     _this.image_speed = 1;
  1007.     _this.sprite_index = _si;
  1008.     _this.speed = 0;
  1009.     _this.other = null;
  1010.     _this.collision_checking = _c;
  1011.     _this.persistent = false;
  1012.     _this.instance_active = false;
  1013.     // Instance-specific functions:
  1014.     _this.place_meeting = __place_meeting__;
  1015.     _this.move_towards_point = __move_towards_point__;
  1016.     _this.instance_destroy = __instance_destroy__;
  1017.     _this.draw_self = __draw_self__;
  1018. }
  1019. // Universal sprite constructor:
  1020. function __sprite_init__(_this, _name, _width, _height, _xofs, _yofs, _cshape, _crad, _cl, _cr, _ct, _cb, _frames) {
  1021.     _this.frames = [];
  1022.     var _frame, _fi;
  1023.     for (_fi = 0; _fi < _frames.length; _fi++) {
  1024.         _frame = new Image();
  1025.         if (_frames[_fi]) {
  1026.             tu_loading_inc();
  1027.             _frame.onload = tu_loading_dec;
  1028.             _frame.onerror = tu_loading_dec;
  1029.             _frame.src = _frames[_fi];
  1030.         }
  1031.         _this.frames.push(_frame);
  1032.     }
  1033.     _this.width = _width;
  1034.     _this.height = _height;
  1035.     _this.xoffset = _xofs;
  1036.     _this.yoffset = _yofs;
  1037.     _this.collision_shape = (_cshape == 'Circle' ? ct_circle : _cshape == 'Box' ? ct_box : 0);
  1038.     _this.collision_radius = _crad;
  1039.     _this.collision_left = _cl;
  1040.     _this.collision_right = _cr;
  1041.     _this.collision_top = _ct;
  1042.     _this.collision_bottom = _cb;
  1043.     tu_sprites.push(_this);
  1044. }
  1045. // Universal audio constructor:
  1046. function __audio_init__(_this, _name, _wav, _mp3, _ogg) {
  1047.     var _src = '';
  1048.     _this.type = 'none';
  1049.     if (tu_ogg_supported && (_ogg != '')) {
  1050.         _this.type = 'ogg';
  1051.         _src = _ogg;
  1052.     } else if (tu_mp3_supported && (_mp3 != '')) {
  1053.         _this.type = 'mp3';
  1054.         _src = _mp3;
  1055.     } else if (tu_wav_supported && (_wav != '')) {
  1056.         _this.type = 'wav';
  1057.         _src = _wav;
  1058.     }
  1059.     if (_src != '') {
  1060.         _this.audio = document.createElement('audio');
  1061.         _this.audio.setAttribute('src', _src);
  1062.     } else {
  1063.         _this.audio = null;
  1064.     }
  1065.     tu_audios.push(_this);
  1066. }
  1067.  
  1068. function __background_init__(_this, _name, _file) {
  1069.     _this.image = new Image();
  1070.     tu_loading_inc();
  1071.     _this.image.onload = tu_loading_dec;
  1072.     _this.image.onerror = tu_loading_dec;
  1073.     _this.image.src = _file;
  1074.     tu_backgrounds.push(_this);
  1075. }
  1076.  
  1077. function __font_init__(_this, _name, _family, _size, _bold, _italic) {
  1078.     _this.family = _family;
  1079.     _this.size = _size;
  1080.     _this.bold = _bold;
  1081.     _this.italic = _italic;
  1082.     tu_fonts.push(_this);
  1083. }
  1084.  
  1085. // (this, name, width, height, speed, back. red, back. green, back. blue, background, back. tilex, back. tiley, back. stretch, view width, view height, view object, view hborder, view vborder)
  1086. function __room_start__(_this, _name, _rw, _rh, _rs, _br, _bg, _bb, _bi, _bx, _by, _bs, _vw, _vh, _vo, _vx, _vy) {
  1087.     _$_('tululoogame').innerHTML = "<canvas id='" + tu_canvas_id + "' width='" + _vw + "' height='" + _vh + "' style='" + tu_canvas_css + "'></canvas>";
  1088.     tu_canvas = _$_(tu_canvas_id);
  1089.     tu_context = tu_canvas.getContext('2d');
  1090.     tu_canvas_text_supported = typeof tu_context.fillText != 'undefined';
  1091.     if (!tu_canvas_text_supported) {
  1092.         tu_text_overlay = document.createElement('div');
  1093.         tu_text_overlay.style.cssText = 'position:absolute;top:0;left:0;pointer-events:none;overflow:hidden;';
  1094.         tu_text_overlay.style.width = _vw + 'px';
  1095.         tu_text_overlay.style.height = _vh + 'px';
  1096.         _$_('tululoogame').appendChild(tu_text_overlay);
  1097.     }
  1098.     room_current = _this;
  1099.     // generic:
  1100.     room_speed = _rs;
  1101.     room_width = _rw;
  1102.     room_height = _rh;
  1103.     // background color:
  1104.     room_background_color_red = _br;
  1105.     room_background_color_green = _bg;
  1106.     room_background_color_blue = _bb;
  1107.     // background image:
  1108.     room_background = _bi;
  1109.     room_background_x = 0;
  1110.     room_background_y = 0;
  1111.     room_background_tile_x = _bx;
  1112.     room_background_tile_y = _by;
  1113.     room_background_tile_stretch = _bs;
  1114.     // view:
  1115.     room_viewport_width = _vw;
  1116.     room_viewport_height = _vh;
  1117.     room_viewport_x = room_viewport_y = 0;
  1118.     room_viewport_object = _vo;
  1119.     room_viewport_hborder = _vx;
  1120.     room_viewport_vborder = _vy;
  1121.     // tiles:
  1122.     var _l, _b, _t, _i, _il, _tls_, i, l, d, o, a;
  1123.     _tls_ = _this.tiles; tu_tiles = []; tu_tilesi = [];
  1124.     for (_l = 0; _l < _tls_.length; _l++)
  1125.     for (_b = 1; _b < _tls_[_l].length; _b++)
  1126.     for (_t = 1; _t < _tls_[_l][_b].length; _t++)
  1127.     tile_add(_tls_[_l][_b][0], _tls_[_l][_b][_t][0], _tls_[_l][_b][_t][1], _tls_[_l][_b][_t][2], _tls_[_l][_b][_t][3], _tls_[_l][_b][_t][4], _tls_[_l][_b][_t][5], _tls_[_l][0]);
  1128.     // objects:
  1129.     tu_depth = []; tu_depthi = []; tu_depthu = []; tu_types = [];
  1130.     a = _this.objects;
  1131.     l = a.length;
  1132.     for (i = 0; i < l; i++) {
  1133.         d = a[i];
  1134.         d = d[0]; // temp.fix for rc2
  1135.         if (d.o === undefined) continue;
  1136.         o = instance_create_(d.x, d.y, d.o);
  1137.         if (d.s !== undefined) o.sprite_index = d.s;
  1138.         if (d.d !== undefined) o.direction = d.d;
  1139.         if (d.a !== undefined) o.image_angle = d.a;
  1140.         if (d.u !== undefined) o.image_xscale = d.u;
  1141.         if (d.v !== undefined) o.image_yscale = d.v;
  1142.         if (d.c !== undefined) d.c.apply(o);
  1143.     }
  1144.     // persistent objects:
  1145.     _l = tu_persist.length
  1146.     for (_t = 0; _t < _l; _t++) instance_activate(tu_persist[_t]);
  1147.     instance_foreach(function(o) {
  1148.         if (tu_persist.indexOf(o) != -1) return;
  1149.         o.on_creation();
  1150.     });
  1151.     tu_persist = [];
  1152.     //
  1153.     instance_foreach(function(o) {
  1154.         o.on_roomstart();
  1155.     });
  1156. }
  1157.  
  1158. function tu_preloader() {
  1159.     var _w = Math.min(400, (tu_canvas.width * 0.6) >> 0), _h = 16,
  1160.         _x = (tu_canvas.width - _w) >> 1, _y = (tu_canvas.height - _h) >> 1,
  1161.         _p = (tu_load_total - tu_loading) / tu_load_total,
  1162.         _s = "Loading resources: " + (tu_load_total - tu_loading) + "/" + (tu_load_total);
  1163.     tu_canvas.width = tu_canvas.width;
  1164.     tu_canvas.height = tu_canvas.height;
  1165.     tu_canvas.style.backgroundColor = "rgb(42, 42, 42)";
  1166.     tu_context.font = "italic 12px Verdana";
  1167.     tu_context.textAlign = "left";
  1168.     tu_context.textBaseline = "bottom";
  1169.     tu_context.fillStyle = tu_context.strokeStyle = "rgba(192, 192, 192, 1)";
  1170.     tu_context.fillRect(_x - 1, _y - 1, _w + 2, _h + 2);
  1171.     tu_context.fillStyle = tu_context.strokeStyle = "rgba(0, 0, 0, 1)";
  1172.     tu_context.fillRect(_x, _y, _w, _h);
  1173.     tu_context.fillStyle = tu_context.strokeStyle = "rgba(255, 255, 255, 1)";
  1174.     tu_context.fillRect(_x + 2, _y + 2, (_w - 4) * _p, _h - 4);
  1175.     if (tu_canvas_text_supported) tu_context.fillText(_s, _x, _y - 2);
  1176. }
  1177.  
  1178. function tu_render_back() {
  1179.     if (room_background == null) return;
  1180.     if (room_background_tile_stretch) {
  1181.         tu_context.drawImage(room_background, 0 - room_viewport_x, 0 - room_viewport_y, room_width, room_height);
  1182.         return;
  1183.     }
  1184.     var _bw, _bh, _bx, _by, _vx, _vy, _vw, _vh, _x1, _x2, _y1, _y2, _ht, _vt;
  1185.     _bw = room_background.width;
  1186.     _bh = room_background.height;
  1187.     _bx = room_background_x;
  1188.     if (room_background_tile_x) { _bx = _bx < 0 ? _bw - _bx % _bw : _bx % _bw; }
  1189.     _by = room_background_y;
  1190.     if (room_background_tile_y) { _bx = _by < 0 ? _bh - _by % _bh : _by % _bh; }
  1191.     //
  1192.     _vx = room_viewport_x;
  1193.     _vy = room_viewport_y;
  1194.     _vw = room_viewport_width;
  1195.     _vh = room_viewport_height;
  1196.     //
  1197.     _x1 = room_background_tile_x ? Math.floor(_vx / _bw) * _bw - _bx : -_bx;
  1198.     _x2 = room_background_tile_x ? Math.floor((_vx + _vw + _bw) / _bw) * _bw : _x1 + _bw;
  1199.     _y1 = room_background_tile_y ? Math.floor(_vy / _bh) * _bh - _by : -_by;
  1200.     _y2 = room_background_tile_y ? Math.floor((_vy + _vh + _bh) / _bh) * _bh : _y1 + _bh;
  1201.     for (_ht = _x1; _ht < _x2; _ht += _bw)
  1202.     for (_vt = _y1; _vt < _y2; _vt += _bh)
  1203.     tu_context.drawImage(room_background, _ht - _vx, _vt - _vy);
  1204. }
  1205. // @1.2.6
  1206. function instance_activate(_i) {
  1207.     if (_i.instance_active) return;
  1208.     for (var o = _i._object_index; o; o = o.parent) tu_type_add(o, _i);
  1209.     //tu_type_add(_i._object_index, _i);
  1210.     //if (_i.parent != null) tu_type_add(_i.parent, _i);
  1211.     tu_depth_add(_i._depth, _i);
  1212.     _i.instance_active = true;
  1213. }
  1214. // @1.2.6
  1215. function instance_deactivate(_i) {
  1216.     if (!_i.instance_active) return;
  1217.     for (var o = _i._object_index; o; o = o.parent) tu_type_delete(o._object_index_, _i);
  1218.     //tu_type_delete(_i, _i._object_index_);
  1219.     //if (_i.parent != null) tu_type_delete(_i, _i.parent._object_index_);
  1220.     tu_depth_delete(_i._depth, _i);
  1221.     _i.instance_active = false;
  1222. }
  1223. // @1.2.6 Performs function for all instances
  1224. function instance_foreach(_function) {
  1225.     var _d, _l, _o;
  1226.     for (_d in tu_depth) {
  1227.         _l = tu_depth[_d];
  1228.         for (_o = 0; _o < _l.length; _o++) _function(_l[_o]);
  1229.     }
  1230. }
  1231. // @1.2.6 Performs function for all instances on specific depth
  1232. function instance_fordepth(_depth, _function) {
  1233.     var _o, _d = tu_depthc[_depth], _l;
  1234.     if (_d == null) return;
  1235.     _l = _d.length;
  1236.     for (_o = 0; _o < _l; _o++) _function(_d[_o]);
  1237. }
  1238. // @1.2.6 Actions performed on room switch
  1239. function tu_room_switchto_(_o) {
  1240.     _o.on_roomend();
  1241.     if (!_o.persistent) return;
  1242.     tu_persist.push(_o);
  1243.     instance_deactivate(_o);
  1244. }
  1245. function tu_room_switchto(_dest) {
  1246.     tu_persist = [];
  1247.     instance_foreach(tu_room_switchto_);
  1248.     room_current = _dest;
  1249.     tu_room_to_go = null;
  1250.     room_current.start();
  1251. }
  1252. // @1.0.0 Global step event
  1253. function tu_step() {
  1254.     // object step events:
  1255.     tu_trash = [];
  1256.     var tu_deptho, tu_depthl, _obj_, _objd_, _h, _v;
  1257.     for (tu_depthd in tu_depth) {
  1258.         tu_depthc = tu_depth[tu_depthd];
  1259.         tu_depthl = tu_depthc.length;
  1260.         for (tu_deptho = 0; tu_deptho < tu_depthl; tu_deptho++) {
  1261.             _obj_ = tu_depthc[tu_deptho];
  1262.             // is viewport object?
  1263.             if (room_viewport_object != null && tu_viewport_inst == null && (_obj_.object_index == room_viewport_object || _obj_.parent == room_viewport_object)) {
  1264.                 tu_viewport_inst = _obj_;
  1265.             }
  1266.             // step events:
  1267.             _obj_.on_step();
  1268.             // move object:
  1269.             if (_obj_.speed != 0) {
  1270.                 _objd_ = _obj_.direction * tu_d2r;
  1271.                 _obj_.x += _obj_.speed * Math.cos(_objd_);
  1272.                 _obj_.y += _obj_.speed * Math.sin(_objd_);
  1273.             }
  1274.             // post-step events:
  1275.             _obj_.on_collision();
  1276.             _obj_.on_end_step();
  1277.             // post:
  1278.             _obj_.xprevious = _obj_.x;
  1279.             _obj_.yprevious = _obj_.y;
  1280.         }
  1281.     }
  1282.     // follow object
  1283.     if (tu_viewport_inst != null) {
  1284.         _h = min(room_viewport_hborder, room_viewport_width / 2);
  1285.         _v = min(room_viewport_vborder, room_viewport_height / 2);
  1286.         // hborder:
  1287.         if (tu_viewport_inst.x < room_viewport_x + _h) room_viewport_x = tu_viewport_inst.x - _h;
  1288.         if (tu_viewport_inst.x > room_viewport_x + room_viewport_width - _h) room_viewport_x = tu_viewport_inst.x - room_viewport_width + _h;
  1289.         // vborder:
  1290.         if (tu_viewport_inst.y < room_viewport_y + _v) room_viewport_y = tu_viewport_inst.y - _v;
  1291.         if (tu_viewport_inst.y > room_viewport_y + room_viewport_height - _v) room_viewport_y = tu_viewport_inst.y - room_viewport_height + _v;
  1292.         // limits:
  1293.         room_viewport_x = Math.max(0, Math.min(room_viewport_x, room_width - room_viewport_width)) >> 0;
  1294.         room_viewport_y = Math.max(0, Math.min(room_viewport_y, room_height - room_viewport_height)) >> 0;
  1295.     }
  1296. }
  1297.  
  1298. function tu_draw() {
  1299.     if (tu_text_overlay) tu_text_overlay.innerHTML = '';
  1300.     // clear canvas:
  1301.     if (room_background_color_show) {
  1302.         tu_canvas.width = tu_canvas.width;
  1303.         tu_canvas.height = tu_canvas.height;
  1304.         // set background color:
  1305.         tu_canvas.style.backgroundColor = "rgb(" + room_background_color_red + "," + room_background_color_green + "," + room_background_color_blue + ")";
  1306.     }
  1307.     tu_render_back();
  1308.     tile_layer_last = 0;
  1309.     var tu_depthc, tu_depthv, tu_deptho, tu_depthl, _obj_;
  1310.     for (tu_depthd in tu_depth) {
  1311.         tu_depthc = tu_depth[tu_depthd];
  1312.         tu_depthv = tu_depthi[tu_depthd];
  1313.         for (; tu_tilesi[tile_layer_last] >= tu_depthv && tile_layer_last < tu_tiles.length; tile_layer_last++)
  1314.         {
  1315.             tile_lrender(tu_tiles[tile_layer_last]);
  1316.         }
  1317.         tu_depthl = tu_depthc.length;
  1318.         for (tu_deptho = 0; tu_deptho < tu_depthl; tu_deptho++) {
  1319.             _obj_ = tu_depthc[tu_deptho];
  1320.             if (_obj_.visible) _obj_.on_draw();
  1321.             _obj_.on_animationend();
  1322.         }
  1323.     }
  1324.     // render remaining tile layers:
  1325.     for (; tile_layer_last < tu_tiles.length; tile_layer_last++) {
  1326.         tile_lrender(tu_tiles[tile_layer_last]);
  1327.     }
  1328. }
  1329.  
  1330. function tu_prestep() {
  1331.     // clear mouse states and keypressed / keyrelesed statuses
  1332.     mouse_pressed = false;
  1333.     mouse_released = false;
  1334.     var _k, _r, _obj_;
  1335.     for (_k = 0; _k < tu_keys_pressed.length; _k++) key_pressed[tu_keys_pressed[_k]] = false;
  1336.     for (_k = 0; _k < tu_keys_released.length; _k++) key_released[tu_keys_released[_k]] = false;
  1337.     tu_keys_pressed = [];
  1338.     tu_keys_released = [];
  1339.     // remove objects from destroy stack
  1340.     for (_r = 0; _r < tu_trash.length; _r++) {
  1341.         _obj_ = tu_trash[_r];
  1342.         if (tu_modal == _obj_) tu_modal = null;
  1343.         _obj_.depth = undefined;
  1344.         tu_type_delete(_obj_, _obj_._object_index_);
  1345.         if (_obj_.parent != null) tu_type_delete(_obj_, _obj_.parent._object_index_);
  1346.         _obj_.on_destroy();
  1347.     }
  1348. }
  1349.  
  1350. function tu_loop() {
  1351.     // calculate render time
  1352.     tu_frame_time = tu_gettime();
  1353.     tu_elapsed = (tu_frame_time - tu_prev_frame_time);
  1354.     tu_frame_step += tu_elapsed;
  1355.     tu_frame_el += tu_elapsed;
  1356.     // continue game with the UN-Pause key
  1357.     if (tu_paused && keyboard_check_pressed(tu_unpausekey)) tu_paused = false;
  1358.     //
  1359.     if (tu_room_to_go != null && tu_canvas == null) tu_room_switchto(tu_room_to_go);
  1360.     // render game:
  1361.     if (tu_frame_step >= 1000 / room_speed && tu_loading == 0 && tu_canvas != null && !tu_paused) {
  1362.         tu_frame_count++;
  1363.         tu_elapsed = tu_frame_time - tu_prev_cycle_time;
  1364.         tu_prev_cycle_time = tu_frame_time;
  1365.         tu_frame_step -= 1000 / room_speed;
  1366.         if (tu_frame_step < 0 || tu_frame_step > 1024) tu_frame_step = 0;
  1367.         // start next room, if any:
  1368.         if (tu_room_to_go != null) tu_room_switchto(tu_room_to_go);
  1369.         //
  1370.         tu_redraw = tu_redraw_auto;
  1371.         if (tu_modal != null) {
  1372.             tu_modal.on_step();
  1373.             if (tu_modal != null) tu_modal.on_end_step();
  1374.         } else tu_step();
  1375.         tu_depth_update();
  1376.         if (tu_redraw) {
  1377.             if (tu_modal == null || tu_modaldraw) tu_draw();
  1378.             else tu_modal.on_draw();
  1379.         }
  1380.         tu_depth_update();
  1381.         tu_prestep();
  1382.         tu_depth_update();
  1383.     } else if (tu_loading > 0) tu_preloader();
  1384.     // calculate fps:
  1385.     if (tu_frame_el >= Math.floor(200 / room_speed) * 5 * room_speed)
  1386.     {
  1387.         fps = Math.ceil(tu_frame_count * 1000 / tu_frame_el);
  1388.         if (fps > room_speed) fps = room_speed;
  1389.         tu_frame_el = tu_frame_count = 0;
  1390.     }
  1391.     // repeat
  1392.     tu_prev_frame_time = tu_frame_time;
  1393.     setTimeout(tu_gameloop, 5);
  1394. }
  1395. tu_init();
  1396.  
  1397. /***********************************************************************
  1398.  * EXTENSIONS
  1399.  ***********************************************************************/
  1400. //TULULOO_EXTENSIONS
  1401.  
  1402. /***********************************************************************
  1403.  * SPRITES
  1404.  ***********************************************************************/
  1405. //TULULOO_SPRITES
  1406.  
  1407. /***********************************************************************
  1408.  * SOUNDS
  1409.  ***********************************************************************/
  1410. //TULULOO_SOUNDS
  1411.  
  1412. /***********************************************************************
  1413.  * MUSICS
  1414.  ***********************************************************************/
  1415. //TULULOO_MUSICS
  1416.  
  1417. /***********************************************************************
  1418.  * BACKGROUNDS
  1419.  ***********************************************************************/
  1420. //TULULOO_BACKGROUNDS
  1421.  
  1422. /***********************************************************************
  1423.  * FONTS
  1424.  ***********************************************************************/
  1425. //TULULOO_FONTS
  1426.  
  1427. /***********************************************************************
  1428.  * OBJECTS
  1429.  ***********************************************************************/
  1430. //TULULOO_OBJECTS
  1431.  
  1432. /***********************************************************************
  1433.  * SCENES
  1434.  ***********************************************************************/
  1435. //TULULOO_SCENES
  1436.  
  1437. /***********************************************************************
  1438.  * CUSTOM GLOBAL VARIABLES
  1439.  ***********************************************************************/
  1440. //TULULOO_GLOBAL_VARIABLES
  1441.  
  1442. /***********************************************************************
  1443.  * CUSTOM GLOBAL FUNCTIONS
  1444.  ***********************************************************************/
  1445. //TULULOO_GLOBAL_FUNCTIONS
  1446.  
  1447. tu_gameloop = tu_loop;
  1448. tu_loop();
  1449.  
Advertisement
Add Comment
Please, Sign In to add comment