1. // forked from ABA's UpDownRoad
  2. // UpDownRoad.as
  3. //  Display a 3d updown road with 3d particles.
  4. package
  5. {
  6.   import flash.display.Sprite;
  7.   import flash.display.BitmapData;
  8.   import flash.display.Bitmap;
  9.   import flash.geom.Rectangle;
  10.   import flash.events.Event;
  11.   import flash.events.SampleDataEvent;
  12.   import flash.media.Sound;
  13.   [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]
  14.   public class UpDownRoad extends Sprite
  15.   {
  16.     private const SCREEN_WIDTH:int = 465;
  17.     private const SCREEN_HEIGHT:int = 465;
  18.     private const DRAWN_PARTICLES_MAX_COUNT:int = 2000;
  19.     private const PROJECTION_RATIO:Number = 128;
  20.     private const LOD_DISTANCE:Number = 200;
  21.     private const MAX_DEPTH:Number = 500;
  22.     private const ROAD_SPACING:Number = 5;
  23.     private const ROAD_WIDTH:Number = 64;
  24.     private const ROAD_HEIGHT:Number = 6;
  25.     private const SIGHT_HEIGHT:Number = 30;
  26.     private const BACKGROUND_BOX_SIZE:int = 16;
  27.     private const BACKGROUND_R:int = 0x88;
  28.     private const BACKGROUND_G:int = 0xcc;
  29.     private const BACKGROUND_B:int = 0xff;
  30.     private var buffer:BitmapData = new BitmapData(SCREEN_WIDTH, SCREEN_HEIGHT, false0);
  31.     private var rect:Rectangle = new Rectangle;
  32.     private var roads:Vector.<Road> = new Vector.<Road>;
  33.     private var particles:Vector.<Particle> = new Vector.<Particle>;
  34.     private var drawnParticles:Vector.<DrawnParticle> = new Vector.<DrawnParticle>;
  35.     private var dpIndex:int;
  36.     private var viewpoint:Vector3 = new Vector3;
  37.     private var yaw:Number, pitch:Number, roll:Number;
  38.     private var offset:Vector3 = new Vector3;
  39.     private var carPosIndex:Number;
  40.     private var roadIndex:int;
  41.     public function UpDownRoad()
  42.     {
  43.       addChild(new Bitmap(buffer));
  44.       yaw = pitch = roll = 0;
  45.       createRoad();
  46.       for (var i:int = 0; i < DRAWN_PARTICLES_MAX_COUNT; i++)
  47.         drawnParticles.push(new DrawnParticle);
  48.       carPosIndex = roads.length - 10;
  49.       addEventListener(Event.ENTER_FRAME, onEnterFrame);
  50.       _initializeSound();
  51.     }
  52.     private function onEnterFrame(evt:Event):void
  53.     {
  54.       buffer.fillRect(buffer.rect, 0x99ffdd);
  55.       carPosIndex += 1.7;
  56.       if (carPosIndex >= roads.length)
  57.         carPosIndex -= roads.length;
  58.       var cpi:int = carPosIndex;
  59.       var ncpi:int = carPosIndex + 1;
  60.       if (ncpi >= roads.length)
  61.         ncpi -= roads.length;
  62.       var co:Number = carPosIndex - cpi;
  63.       var rp:Vector3 = roads[cpi].pos;
  64.       var nrp:Vector3 = roads[ncpi].pos;
  65.       viewpoint.x += (rp.x * (1 - co) + nrp.x * co - viewpoint.x) * 0.2;
  66.       viewpoint.y += (rp.y * (1 - co) + nrp.y * co - viewpoint.y - SIGHT_HEIGHT) * 0.2;
  67.       viewpoint.z += (rp.z * (1 - co) + nrp.z * co - viewpoint.z) * 0.2;
  68.       var oa:Number = roads[ncpi].angle - roads[cpi].angle;
  69.       oa = normalizeAngle(oa);
  70.       oa = roads[cpi].angle + oa * co - yaw;
  71.       oa = normalizeAngle(oa);
  72.       yaw += oa * 0.1;
  73.       yaw = normalizeAngle(yaw);
  74.       pitch += ((roads[cpi].upDown * (1 - co) + roads[ncpi].upDown * co) * 0.5 - pitch) * 0.2;
  75.       roll += (-oa * 0.7 - roll) * 0.1;
  76.       drawBackground();
  77.       dpIndex = 0;
  78.       for each (var p:Particle in particles)
  79.         drawParticle(p);
  80.       drawnParticles.sort(sortOnZ);
  81.       function sortOnZ(v1:DrawnParticle, v2:DrawnParticle):Number
  82.       {
  83.         if (v1.pos.z < v2.pos.z)
  84.           return 1;
  85.         else if (v1.pos.z > v2.pos.z)
  86.           return -1;
  87.         else
  88.           return 0;
  89.       }
  90.       for (var i:int = 0; i < dpIndex; i++)
  91.       {
  92.         var dp:DrawnParticle = drawnParticles[i];
  93.         rect.x = dp.pos.x - dp.width;
  94.         rect.y = dp.pos.y - dp.height;
  95.         rect.width = dp.width * 2;
  96.         rect.height = dp.height * 2;
  97.         buffer.fillRect(rect, dp.color);
  98.       }
  99.     }
  100.     private function drawParticle(p:Particle):void
  101.     {
  102.       offset.x = p.pos.x - viewpoint.x;
  103.       offset.y = p.pos.y - viewpoint.y;
  104.       offset.z = p.pos.z - viewpoint.z;
  105.       offset.rotationYaw(yaw);
  106.       offset.rotationPitch(pitch);
  107.       offset.rotationRoll(roll);
  108.       if (offset.z < -10 || offset.z > MAX_DEPTH)
  109.         return;
  110.       if (p.detail != null && offset.length < LOD_DISTANCE)
  111.       {
  112.         for each (var pp:Particle in p.detail)
  113.           drawParticle(pp);
  114.         return;
  115.       }
  116.       if (offset.z < 1 || p.width <= 0)
  117.         return;
  118.       var ar:Number = 1.0 - offset.z / MAX_DEPTH;
  119.       if (ar < 0)
  120.         return;
  121.       var dp:DrawnParticle = drawnParticles[dpIndex];
  122.       var zr:Number = 1.0 / offset.z * PROJECTION_RATIO;
  123.       dp.pos.x = offset.x * zr + SCREEN_WIDTH / 2;
  124.       dp.pos.y = offset.y * zr + SCREEN_HEIGHT / 2;
  125.       dp.pos.z = offset.z;
  126.       dp.width = p.width * zr;
  127.       dp.height = p.height * zr;
  128.       dp.color = createColor(p.r, p.g, p.b, 250 * ar);
  129.       dpIndex++;
  130.     }
  131.     private function createColor(r:int, g:int, b:int, a:int):int
  132.     {
  133.       return int((r * a + BACKGROUND_R * (256 - a)) / 256) * 0x10000 +
  134.              int((g * a + BACKGROUND_G * (256 - a)) / 256) * 0x100 +
  135.              int((b * a + BACKGROUND_B * (256 - a)) / 256);
  136.     }
  137.     private function drawBackground():void
  138.     {
  139.       offset.x = 0;
  140.       offset.y = 0;
  141.       offset.z = 99999;
  142.       offset.rotationPitch(pitch);
  143.       var zr:Number = 1.0 / offset.z * PROJECTION_RATIO;
  144.       var bc:int = SCREEN_WIDTH / BACKGROUND_BOX_SIZE + 1;
  145.       var bx:Number, by:Number;
  146.       var vby:Number = BACKGROUND_BOX_SIZE * Math.sin(roll);
  147.       var bh:Number, bby:Number;
  148.       for (var j:int = 0; j < 3; j++)
  149.       {
  150.         switch (j)
  151.         {
  152.           case 0:
  153.           {
  154.             bh = 8;
  155.             bby = 0;
  156.             break;
  157.           }
  158.           case 1:
  159.           {
  160.             bh = 16;
  161.             bby = 16;
  162.             break;
  163.           }
  164.           case 2:
  165.           {
  166.             bh = SCREEN_HEIGHT / 3;
  167.             bby = 48;
  168.             break;
  169.           }
  170.         }
  171.         bx = SCREEN_WIDTH / 2 - BACKGROUND_BOX_SIZE * bc / 2;
  172.         by = offset.y * zr + SCREEN_HEIGHT / 2 - vby * bc / 2 + bby + bh;
  173.         rect.width = BACKGROUND_BOX_SIZE;
  174.         rect.height = bh * 2;
  175.         for (var i:int = 0; i < bc; i++)
  176.         {
  177.           rect.x = bx - BACKGROUND_BOX_SIZE / 2;
  178.           rect.y = by - bh;
  179.           buffer.fillRect(rect, createColor(0x88 - j * 0x33, 0x88 - j * 0x33, 0xff, 255));
  180.           bx += BACKGROUND_BOX_SIZE;
  181.           by += vby;
  182.         }
  183.       }
  184.     }
  185.     private var roadPattern:Array = [2000.21160, -3016030800.050.0519000080, -0.05, -1.012001.751];
  186.     private function createRoad():void
  187.     {
  188.       var r:Road = new Road;
  189.       var a:Number = 0;
  190.       var ud:Number = roadPattern[2];
  191.       r.angle = a;
  192.       r.upDown = ud;
  193.       var c:int;
  194.       var ta:Number, tud:Number;
  195.       var polePattern:int;
  196.       var i:int;
  197.       roadIndex = 0;
  198.       for (i = 0; i < roadPattern.length; i += 4)
  199.       {
  200.         c = roadPattern[i];
  201.         ta = roadPattern[i + 1];
  202.         tud = roadPattern[i + 2];
  203.         polePattern = roadPattern[i + 3];
  204.         for (var j:int = 0; j < c; j++)
  205.         {
  206.           a += (ta - a) * 0.2;
  207.           ud += (tud - ud) * 0.1;
  208.           r.angle += a;
  209.           r.angle = normalizeAngle(r.angle);
  210.           r.upDown = ud;
  211.           addRoadAndPole(r, polePattern);
  212.           r = getNextRoad(r);
  213.         }
  214.       }
  215.       c = Math.sqrt(r.pos.x * r.pos.x + r.pos.z * r.pos.z) / ROAD_SPACING;
  216.       var vrp:Vector3 = new Vector3;
  217.       vrp.x = -r.pos.x / c;
  218.       vrp.y = -r.pos.y / c;
  219.       vrp.z = -r.pos.z / c;
  220.       var va:Number = -r.angle / c;
  221.       var vud:Number = -r.upDown / c;
  222.       for (i = 0; i < c; i++)
  223.       {
  224.         addRoadAndPole(r, polePattern);
  225.         var nr:Road = new Road;
  226.         nr.pos.x = r.pos.x + vrp.x;
  227.         nr.pos.y = r.pos.y + vrp.y;
  228.         nr.pos.z = r.pos.z + vrp.z;
  229.         nr.angle = r.angle + va;
  230.         nr.upDown = r.upDown + vud;
  231.         r = nr;
  232.       }
  233.     }
  234.     private function addRoadAndPole(r:Road, polePattern:int):void
  235.     {
  236.       addRoadParticles(r);
  237.       roads.push(r);
  238.       if (polePattern > 0 && roadIndex % 7 == 0)
  239.       {
  240.         addPoleParticles(r);
  241.       }
  242.       roadIndex++;
  243.     }
  244.     private function getNextRoad(r:Road):Road
  245.     {
  246.       var nr:Road = new Road;
  247.       nr.pos.x = r.pos.x + Math.sin(r.angle) * ROAD_SPACING;
  248.       nr.pos.z = r.pos.z + Math.cos(r.angle) * ROAD_SPACING;
  249.       nr.pos.y = r.pos.y + Math.sin(r.upDown) * ROAD_SPACING;
  250.       nr.angle = r.angle;
  251.       nr.upDown = r.upDown;
  252.       return nr;
  253.     }
  254.     private function addRoadParticles(r:Road):void
  255.     {
  256.       for (var j:int = 0; j < 3; j++)
  257.       {
  258.         var p:Particle = new Particle;
  259.         var ox:Number = Math.cos(r.angle) * ROAD_WIDTH / 3 * 2;
  260.         var oz:Number = -Math.sin(r.angle) * ROAD_WIDTH / 3 * 2;
  261.         p.pos.x = r.pos.x + ox * (j - 1);
  262.         p.pos.y = r.pos.y;
  263.         p.pos.z = r.pos.z + oz * (j - 1);
  264.         p.width = ROAD_WIDTH / 3 * 1.05;
  265.         p.height = ROAD_HEIGHT;
  266.         p.detail = new Vector.<Particle>;
  267.         var pc:int = p.width / p.height + 2;
  268.         ox = Math.cos(r.angle) * p.width / pc * 2;
  269.         oz = -Math.sin(r.angle) * p.width / pc * 2;
  270.         var c:int = 0;
  271.         var i:int;
  272.         var pp:Particle;
  273.         for (i = 0; i < pc; i++)
  274.         {
  275.           pp = new Particle;
  276.           pp.pos.x = p.pos.x + ox * (i - pc / 2);
  277.           pp.pos.y = p.pos.y;
  278.           pp.pos.z = p.pos.z + oz * (i - pc / 2);
  279.           pp.width = pp.height = p.height;
  280.           pp.r = pp.g = pp.b = 190 + Math.random() * 30;
  281.           c += pp.r;
  282.           pp.detail = null;
  283.           p.detail.push(pp);
  284.         }
  285.         p.r = p.g = p.b = c / pc;
  286.         particles.push(p);
  287.         if (roadIndex % 3 == 0 && j != 1)
  288.         {
  289.           pp = new Particle;
  290.           pp.pos.x = p.pos.x + ox * pc / 2 * 1.2 * (j - 1);
  291.           pp.pos.y = p.pos.y - p.height * 0.5;
  292.           pp.pos.z = p.pos.z + oz * pc / 2 * 1.2 * (j - 1);
  293.           pp.width = p.height;
  294.           pp.height = p.height * 0.6;
  295.           pp.r = pp.g = pp.b = 32;
  296.           pp.detail = null;
  297.           particles.push(pp);
  298.         }
  299.       }
  300.     }
  301.     private function addPoleParticles(r:Road):void
  302.     {
  303.       for (var i:int = 0; i < 2; i++)
  304.       {
  305.         var p:Particle = new Particle;
  306.         p.width = 4;
  307.         p.height = 36;
  308.         p.pos.x = r.pos.x - Math.cos(r.angle) * ROAD_WIDTH * (i * 2 - 1) * 1.1;
  309.         p.pos.y = r.pos.y - p.height / 2;
  310.         p.pos.z = r.pos.z + Math.sin(r.angle) * ROAD_WIDTH * (i * 2 - 1) * 1.1;
  311.         p.r = 250; p.g = 60; p.b = 60;
  312.         p.detail = new Vector.<Particle>;
  313.         for (var j:int = 0; j < 8; j++)
  314.         {
  315.           var pp:Particle = new Particle;
  316.           pp.pos.x = p.pos.x;
  317.           pp.pos.y = p.pos.y - j * p.height / 8;
  318.           pp.pos.z = p.pos.z;
  319.           pp.width = p.width;
  320.           pp.height = p.height / 8;
  321.           pp.r = p.r;
  322.           pp.g = p.g;
  323.           pp.b = p.b;
  324.           pp.detail = null;
  325.           p.detail.push(pp);
  326.         }
  327.         particles.push(p);
  328.       }
  329.     }
  330.     private function normalizeAngle(v:Number):Number {
  331.       if (v > Math.PI)
  332.         return v - Math.PI * 2;
  333.       else if (v < -Math.PI)
  334.         return v + Math.PI * 2;
  335.       else
  336.         return v;
  337.     }
  338.     private var _sound:Sound;
  339.     private var _module:TinySiOPM;
  340.     private var _sequencer:Sequencer;
  341.     private function _initializeSound():void {
  342.         var mml:String =""
  343.         mml+="#BS=r28$s10l4[3e8[22e]er<s2c12>s10brg]s1a36g12f+16s12e8[5e]l2egabl4ers2e20";
  344.         mml+="s10[[3e8[22e]er<s2c12>s10brg]e8[15e]gabf+8gae8eeegab";
  345.         mml+="[[<c8[6c]>b8[6b]a8[6a]|g8ggggab]|a8aaaabr]a8[6a]<d8[14d]>]";
  346.         mml+="erer20[8[erer20|erer20]|er28]erer20";
  347.         mml+="[[[<c8[6c]>b8[6b]a8[6a]|g8ggggab]|a8aaaabr]a8[6a]]<d8[14d]>;";
  348.         mml+="@0@o1o2BS; v7@0@i3o4BS;";
  349.         mml+="#BD=r8l4v14s32cc2<v5e2c2>g2v14crl4c$[rcrr[15ccrr]] [[rcrr[15ccrr]]";
  350.         mml+="[rcrr[15ccrr]] [2ccrr]cl2<v6ggggeeeecccc>l4v14c]";
  351.         mml+="rcr20[6[crcr20|crcr20]|cr28][8crcrrccr]crcrrcccr";
  352.         mml+="[4rcrr[15ccrr]] [2ccrr]cl2<v6ggggeeeecccc>l4v14c;";
  353.         mml+="#SN=r8l4v14s12k8cc2k4s32c2c2c6k8s12l8c$k8[14rc]l4ck4ccrk8ccl8c[7rc]r4c4c[5rc]rl2k4ccc8r4k8c8c4c4r8";
  354.         mml+="l8[[[15rc]r4c4c] [k8[13rc]|r4c2c2c4k4l4crccrccl8r] rc[rcr4c4c]c4k4l2s32[3c1c1ccc]r4l8k8s12]";
  355.         mml+="l16[[2rc]|rc4s24k4c4c8s12k8rc4c12]rc4c12k4s32l2[ccc4]k8s12c4c4c8 l8[6[7rc]r4c4c]r16c4c4c8";
  356.         mml+="[4k8[13rc]|r4c2c2c4k4l4crccrccl8r] rc[rcr4c4c]c4k4l2s32[3c1c1ccc]r4l8k8s12;";
  357.         mml+="#CY=r8l8s4v8c+20$l8[3s6p3v16d12s10p5v6[14d]d4]s6v16d12p5v6[3d]p2v12d12p5d16p3v16d44p4d20";
  358.         mml+="[l4[4p5s6v16d12s24p6v6[29d]]l8p5[4s6v16d16s10v8[14d]][4d]p3s4v12c+32]";
  359.         mml+="s64v3l2[512d]v12s6c+8v15c+2r22";
  360.         mml+="l8p5[8s6v16d16s10v8[14d]][4d]p3s4v12c+32;";
  361.         mml+="@0w32o4BD; @3o0SN; @3o0CY;";
  362.         mml+="#GT=r28$l4[3[3[s2e8s12e]ee]ers2b2<c10>brg]s1a36g12f+16s2e40re20";
  363.         mml+="[l4[3[3[s2e8s12e]ee]ers2b2<c10>brg][[s2e8s12e]ee]es1g16f+12e20s12eer";
  364.         mml+="s1l8[<c24c>b24b<d24d>g24g<c24c>b24b|a56b]a64<d64>]";
  365.         mml+="r256s24l4[192e]s12erer20";
  366.         mml+="s1l8[[<c24c>b24b<d24d>g24g<c24c>b24b|a56b]a64]<d64>;";
  367.         mml+="@2@o1o6    GT; @0@i3@o1o4k112GT; p1v5@1@i4o3    GT;";
  368.         mml+="@2@o1o6k112GT; @0@i3@o1o4k224GT; p7v4@1@i4o3k112GT;";
  369.         mml+="#S1=v5r28$o6s6l4e8[4e|r36drdrer]r28[3dr]e8[er36drdr|er]s1c36>b12a12r<erer32d20";
  370.         mml+="s2[[[e32d32|d24crc20d8r]rd28dr|c12>b<rd]g12f+rd";
  371.         mml+="[[er20erdr20dr|dr20drdr12d16]|d24drd24d8]d64d56dr]";
  372.         mml+="v7drdrv1drdr[8[v6drdrv1dv6c+12|v6drdrv1drdr]|drrrv1drrr]drdr20";
  373.         mml+="[[[er20erdr20dr|dr20drdr12d16]|d24drd24d8]d64]d56dr;";
  374.         mml+="#S2=v6r28$o5s6l4g8[4g|r36f+rf+rgr]r28[3f+r]g8[gr36f+rf+r|gr]s1e36e12dr12erer32f+20";
  375.         mml+="s2[[[g32f+32|f+24f+re20f+8r]rf+28f+r|e12drf+]b12brf+";
  376.         mml+="[[gr20grgr20gr|f+r20f+rgr12fgb8]|g24grf+24f+8]g64f+56f+r]";
  377.         mml+="v8grgrv1grgr[8[v6grgrv1gv6g12|v6grgrv1grgr]|grrrv1grrr]grgr20";
  378.         mml+="[[[gr20grgr20gr|f+r20f+rgr12fgb8]|g24grf+24f+8]g64]f+56f+r;";
  379.         mml+="#S3=v6r28$o5s6l4b8[4b|r36ararbr]r28[3ar]b8[br36arar|br]s1a36g12f+12rbrbr32a20";
  380.         mml+="s2>[[[b32a32|a24grg20a8r]ra28ar|g12ara]<<d12d>ra";
  381.         mml+="[[cr20cr>br20br|ar20arbr12b16<]|a56a8<]a64a56ar]<";
  382.         mml+="v8ererv1erer[8[v6ererv1ev6e12|v6ererv1erer]|errrv1errr]erer20";    
  383.         mml+="[[[cr20cr>br20br|ar20arbr12b16<]|a56a8<]a64]a56ar<;";
  384.         mml+="p6@1S1; p2@1S2; @1S3;";
  385.         mml+="#MA=r28$@1s3[l16f+1g19f+d>a12b48l4|f+gargre8r112<]r8<cde36g8el8aea+2b2l4rer32d20";
  386.         mml+="@10[s6l4[>[b8bbbbab<c+2d2r>a24|a8aaaagab8<c>ba8eg]r|<f+16g8f+e24r8]<g16f+12e20>";
  387.         mml+="s3b<d>b<e20re8d16>brgra24gab16 fgb<de24f+gd16cr>b8a52<ef+r";
  388.         mml+="g28f+g8d16grf+12gargrarb16<c+1d3rdr>g16<d+1e7dr>g12<cr>ba64f+64];";
  389.         mml+="#MB=r20@2s1w12o9c64s4w-32o4[4c8]r16s2w6o8c64s4w24o5[5c6]r2s1w-12o4c64s0w-2o5c224";
  390.         mml+="@10s3w0o6l4[8rf+de>gb<d>f+abegaf+de<];";
  391.         mml+="#MB2=r772l4<[4raf+g>b<df+>a<de>ab<d>af+g<]>;";
  392.         mml+="#MC=r16>[s3b<d>b<e20re8d16>brgra24gab16 fgb<de24f+gd16cr>b8a52<ef+r";
  393.         mml+="g28f+g8d16grf+12gargrarb16<c+1d3rdr>g16<d+1e7dr>g12<cr>b|a52>]a64<d64>;";
  394.         mml+="v8o6k-1MAv6MBv8MC; v10o5k1MAv3MB2v10MC; v3p1o6r4MAv4MBv3MC;";
  395.         _module = new TinySiOPM(20481024, _onSoundFrame);
  396.         _sequencer = new Sequencer(2, _expandMML(mml));
  397.         _sound = new Sound();
  398.         _sound.addEventListener("sampleData", _onStream);
  399.         _sound.play();
  400.     }
  401.         
  402.     private function _onSoundFrame() : void {
  403.         _sequencer.onSoundFrame();
  404.     }
  405.         
  406.     private function _onStream(e:SampleDataEvent) : void {
  407.         var moduleOut:Vector.<Number> = _module.render();
  408.         for (var i:int = 0; i<4096; i++) {
  409.             e.data.writeFloat(moduleOut[i]);
  410.         }
  411.     }
  412.     private function _expandMML(mml:String) : Array {
  413.         var split:Array = mml.replace(/\s+/g, "").split(/;/);
  414.         var list:Array = [], macro:* = {};
  415.         var defMacro:RegExp = /^#([_A-Z][_A-Z0-9]*)=?(.*)/m;
  416.         for each (var seq:String in split) {
  417.             var res:* = defMacro.exec(seq);
  418.             if (res) macro[res[1]] = res[2];
  419.             else list.push(seq.replace(/[_A-Z][_A-Z0-9]*/g, function() : String {
  420.                 if (!arguments[0in macro) return "";
  421.                 return macro[arguments[0]];
  422.             }));
  423.         }
  424.         return list;
  425.     }
  426.   }
  427. }
  428. class Road
  429. {
  430.   public var pos:Vector3 = new Vector3;
  431.   public var angle:Number, upDown:Number;
  432. }
  433. class Particle
  434. {
  435.   public var pos:Vector3 = new Vector3;
  436.   public var width:Number;
  437.   public var height:Number;
  438.   public var r:int, g:int, b:int;
  439.   public var detail:Vector.<Particle>;
  440. }
  441. class DrawnParticle
  442. {
  443.   public var pos:Vector3 = new Vector3;
  444.   public var width:Number;
  445.   public var height:Number;
  446.   public var color:int;
  447. }
  448. class Vector3
  449. {
  450.   public var x:Number = 0;
  451.   public var y:Number = 0;
  452.   public var z:Number = 0;
  453.   public function rotationYaw(v:Number):void
  454.   {
  455.     var sv:Number = Math.sin(v);
  456.     var cv:Number = Math.cos(v);
  457.     var rx:Number = cv * x - sv * z;
  458.     z = sv * x + cv * z;
  459.     x = rx;
  460.   }
  461.   public function rotationPitch(v:Number):void
  462.   {
  463.     var sv:Number = Math.sin(v);
  464.     var cv:Number = Math.cos(v);
  465.     var ry:Number = cv * y - sv * z;
  466.     z = sv * y + cv * z;
  467.     y = ry;
  468.   }
  469.   public function rotationRoll(v:Number):void
  470.   {
  471.     var sv:Number = Math.sin(v);
  472.     var cv:Number = Math.cos(v);
  473.     var rx:Number = cv * x - sv * y;
  474.     y = sv * x + cv * y;
  475.     x = rx;
  476.   }
  477.   public function get length():Number
  478.   {
  479.     return Math.sqrt(x * x + y * y + z * z);
  480.   }
  481. }
  482. // MML Sequencer
  483. //   http://wonderfl.kayac.com/user/keim_at_Si
  484. //--------------------------------------------------
  485. class Sequencer {
  486.     private var _tracks:Array, _count:int=Track.speed+1;
  487.     function Sequencer(speed:int, mmls:Array=null) { Track.speed=speed; mml=mmls; }
  488.     public function onSoundFrame() : Boolean {
  489.         if (++_count == Track.speed) {
  490.             for each (var tr:Track in _tracks) tr.execute();
  491.             _count = 0;
  492.             return true;
  493.         }
  494.         return false;
  495.     }
  496.     public function set mml(list:Array) : void {
  497.         _tracks = [];
  498.         if (list) {
  499.             for each (var seq:String in list) _tracks.push(new Track(seq));
  500.         }
  501.         _count = 0;
  502.     }
  503. }
  504. class Track {
  505.     static public var codeA:int="a".charCodeAt(), nt:Array=[9,11,0,2,4,5,7], speed:int=3;
  506.     public var oct:int, len:int, tl:int, dt:int, cnt:int, seq:String, sgn:int, stac:Array, osc:Osc;
  507.     private var _rex:RegExp=/(@i|@o|[a-gkloprsvw<>[|\]$@])([#+])?(-?\d+)?/g;
  508.     function Track(seq:String) {
  509.         osc = Osc.alloc().reset().activate(false);
  510.         reset(seq);
  511.     }
  512.     public function reset(seq_:String) : void {
  513.         seq=seq_; oct=5; len=4; tl=256; dt=0; cnt=0; sgn=0; _rex.lastIndex=0; stac=[];
  514.     }
  515.     public function execute() : void {
  516.         if (--cnt <= 0) {
  517.             for (var i:int=0; i<100; i++) {
  518.                 var res:* = _rex.exec(seq);
  519.                 if (!res) {
  520.                     if (sgn) { _rex.lastIndex = sgn; continue; }
  521.                     else     { cnt = int.MAX_VALUE; break; }
  522.                 }
  523.                 var cmd:int = res[1].charCodeAt();
  524.                 if (cmd>=codeA && cmd<=codeA+6) {
  525.                     cnt = (res[3]) ? int(res[3]) : len;
  526.                     osc.len = cnt * speed;
  527.                     osc.pt = ((nt[cmd-codeA]+oct*12+((res[2])?1:0))<<4) + dt;
  528.                     osc.tl = tl;
  529.                     break;
  530.                 } else if (res[1] == 'r') {
  531.                     cnt = (res[3]) ? int(res[3]) : len;
  532.                     break;
  533.                 } else {
  534.                     switch(res[1]){
  535.                     case 'k': dt  = int(res[3]); break;
  536.                     case 'l': len = int(res[3]); break;
  537.                     case 'o': oct = int(res[3]); break;
  538.                     case 'v': tl  = TinySiOPM.log(int(res[3])*0.0625); break;
  539.                     case '<': oct++; break;
  540.                     case '>': oct--; break;
  541.                     case '@':  osc.ws = int(res[3]);    break;
  542.                     case 's':  osc.dr = int(res[3])<<2break;
  543.                     case 'w':  osc.sw = -int(res[3]);   break;
  544.                     case 'p':  osc.pan = (int(res[3])<<4)-64break;
  545.                     case '@i': osc.mod = int(res[3]);   break;
  546.                     case '@o': osc.out = int(res[3]);   break;
  547.                     case '$': sgn = _rex.lastIndex; break;
  548.                     case '[': stac.unshift({p:_rex.lastIndex,c:((res[3])?int(res[3]):2),j:0}); break;
  549.                     case '|'if (stac[0].c == 1) { _rex.lastIndex = stac[0].j; stac.shift(); } break;
  550.                     case ']'
  551.                         stac[0].j = _rex.lastIndex;
  552.                         if (--stac[0].c == 0) stac.shift();
  553.                         else _rex.lastIndex = stac[0].p;
  554.                         break;
  555.                     }
  556.                 }
  557.             }
  558.         }
  559.     }
  560. }
  561. class TinySiOPM {
  562.     private var _output:Vector.<Number>, _zero:Vector.<int>, _pipe:Vector.<int>;
  563.     private var _pitchTable:Vector.<int> = new Vector.<int>(2048true);
  564.     private var _logTable:Vector.<int> = new Vector.<int>(6144true);
  565.     private var _panTable:Vector.<Number> = new Vector.<Number>(129true);
  566.     private var _bufferSize:int, _callbackFrams:int, _onSoundFrame:Function;
  567.     
  568.     // Pass the buffer size and the function calls in each frame.
  569.     function TinySiOPM(bufferSize:int=2048, callbackFrams:int=1024, onSoundFrame:Function=null) {
  570.         var i:int, j:int, p:Number, v:Number, t:Vector.<int>, ft:Array=[0,1,2,3,4,5,6,7,7,6,5,4,3,2,1,0];
  571.         for (i=0, p=0; i<192; i++, p+=0.00520833333)                            // create pitchTable[128*16]
  572.             for(v=Math.pow(2, p)*12441.464342886, j=i; j<2048; v*=2, j+=192) _pitchTable[j] = int(v);
  573.         for (i=0; i<32; i++) _pitchTable[i] = (i+1)<<6;                         // [0:31] for white noize
  574.         for (i=0, p=0.0078125; i<256; i+=2, p+=0.0078125)                       // create logTable[12*256*2]
  575.             for(v=Math.pow(213-p), j=i; j<3328; v*=0.5, j+=256) _logTable[j+1] = -(_logTable[j]=int(v));
  576.         for (i=3328; i<6144; i++) _logTable[i] = 0;                             // [3328:6144] is 0-fill area
  577.         for (i=0, p=0; i<129; i++, p+=0.01217671571) _panTable[i]=Math.sin(p)*0.5;  // pan table;
  578.         for (t=Osc.createTable(10), i=0, p=0; i<1024; i++, p+=0.00613592315) t[i] = log(Math.sin(p)); // sin=0
  579.         for (t=Osc.createTable(10), i=0, p=0.75; i<1024; i++, p-=0.00146484375) t[i] = log(p);        // saw=1
  580.         for (t=Osc.createTable(5),  i=0; i<16; i++) t[i+16] = (t[i] = log(ft[i]*0.0625)) + 1;         // famtri=2
  581.         for (t=Osc.createTable(15), i=0; i<32768; i++) t[i] = log(Math.random()-0.5);                 // wnoize=3
  582.         for (i=0; i<8; i++) for (t=Osc.createTable(4), j=0; j<16; j++) t[j] = (j<=i) ? 192 : 193;     // pulse=4-11
  583.         _zero = new Vector.<int>(bufferSize, true);                             // allocate zero buffer
  584.         _pipe = new Vector.<int>(bufferSize, true);                             // allocate fm pipe buffer
  585.         _output = new Vector.<Number>(bufferSize*2true);                      // allocate stereo out
  586.         _bufferSize = bufferSize;
  587.         _callbackFrams = callbackFrams; 
  588.         _onSoundFrame = onSoundFrame;                                           // set parameters
  589.         for (i=0; i<bufferSize; i++) { _pipe[i]=_zero[i]=0; }                   // clear buffers
  590.     }
  591.     
  592.     // calculate index of logTable
  593.     static public function log(n:Number) : int {
  594.         return (n<0) ? ((n<-0.00390625) ? (((int(Math.log(-n) * -184.66496523 + 0.5) + 1) << 1) + 1) : 2047)
  595.                      : ((n> 0.00390625) ? (( int(Math.log( n) * -184.66496523 + 0.5) + 1) << 1)      : 2046);
  596.     }
  597.     // reset all oscillators
  598.     public function reset() : void {
  599.         for (var o:Osc=Osc._tm.n; o!=Osc._tm; o=o.inactivate().n) { o.fl = Osc._fl; }
  600.     }
  601.     // Returns stereo output as Vector.<Number>(bufferSize*2).
  602.     public function render() : Vector.<Number> {
  603.         var i:int, j:int, ph:int, dph:int, mod:int, sh:int, tl:int, lout:int, v:int, imax:int
  604.             osc:Osc, tm:Osc, l:Number, r:Number, wv:Vector.<int>, fm:Vector.<int>, base:Vector.<int>, 
  605.             out:Vector.<int>=_pipe, lt:Vector.<int>=_logTable, stereoOut:Vector.<Number> = _output;
  606.         imax = _bufferSize<<1;
  607.         for (i=0; i<imax; i++) stereoOut[i] = 0;
  608.         for (imax=_callbackFrams; imax<=_bufferSize; imax+=_callbackFrams) {
  609.             if (_onSoundFrame!=null) _onSoundFrame();
  610.             tm = Osc._tm;
  611.             for (osc=tm.n; osc!=tm; osc=osc.update()) {
  612.                 dph=_pitchTable[osc.pt]; ph=osc.ph; mod=osc.mod+10; sh=osc.sh; tl=osc.tl; wv=osc.wv;
  613.                 fm=(osc.mod==0)?_zero:_pipe; base=(osc.out!=2)?_zero:_pipe;
  614.                 for (i = imax-_callbackFrams; i < imax; i++) {
  615.                     v = ((ph + (fm[i] << mod))& 0x3ffffff) >> sh;
  616.                     lout = wv[v] + tl;
  617.                     out[i] = lt[lout] + base[i];
  618.                     ph = (ph + dph) & 0x3ffffff;
  619.                 }
  620.                 osc.ph = ph;
  621.                 if (osc.out==0) {
  622.                     l = _panTable[64-osc.pan] * 0.0001220703125;
  623.                     r = _panTable[64+osc.pan] * 0.0001220703125;
  624.                     for (i=imax-_callbackFrams, j=i*2; i<imax; i++) {
  625.                         stereoOut[j] += out[i]*l; j++;
  626.                         stereoOut[j] += out[i]*r; j++;
  627.                     }
  628.                 }
  629.             }
  630.         }
  631.         return stereoOut;
  632.     }
  633.     
  634.     // note on
  635.     public function noteOn(pitch:int, length:int=0, vol:Number=0.5, wave:int=0, decay:int=6, sweep:int=0, pan:int=0) : Osc {
  636.         var osc:Osc = Osc.alloc().reset();
  637.         osc.pt = pitch;
  638.         osc.len = length;
  639.         osc.tl = log(vol);
  640.         osc.ws = wave;
  641.         osc.dr = decay<<2;
  642.         osc.sw = sweep; 
  643.         osc.pan = pan;
  644.         return osc.activate(true);
  645.     }
  646. }
  647. class Osc {
  648.     // create new wave table and you can refer the table by '@' command.
  649.     static public function createTable(b:int) : Vector.<int> {
  650.         _w.push(new Vector.<int>(1<<b,true)); _s.push(26-b);
  651.         return _w[_w.length-1];
  652.     }
  653.     static public var _w:Array=[], _s:Array=[], _fl:Osc=new Osc(), _tm:Osc=new Osc();
  654.     static public function alloc():Osc{ if(_fl.p==_fl)return new Osc();var r:Osc=_fl.p;_fl.p=r.p;r.p.n=_fl;return r; }
  655.     public function into(x:Osc):Osc{ p=x.p;n=x;p.n=this;n.p=this;return this; }
  656.     public var p:Osc, n:Osc, fl:Osc, pt:int, len:int, ph:int;
  657.     public var tl:int, sw:int, dr:int, wv:Vector.<int>, sh:int, mod:int, out:int, pan:int;
  658.     public function set ws(t:int) : void { wv=_w[t]; sh=_s[t]; }
  659.     public function Osc() { p = n = this; }
  660.     public function update() : Osc { tl+=dr; pt+=sw; pt&=2047return (--len==0||tl>3328) ? (inactivate().n) : n; }
  661.     public function reset() : Osc { ph=0; pt=0; len=0; tl=3328; sw=0; dr=24; pan=0; ws=0; mod=0; out=0return this; }
  662.     public function activate(autoFree:Boolean=false) : Osc { into(_tm); fl=(autoFree)?_fl:nullreturn this; }
  663.     public function inactivate() : Osc { tl=3328if(!fl)return thisvar r:Osc=p; p.n=n; n.p=p; into(fl); return r; }
  664.     public function isActive() : Boolean { return (tl<3328); }
  665. }
flash swf thumbnail play
FORKED
  1. // forked from keim_at_Si's wonderflで音楽♪Like the wind forked from: UpDownRoad
  2. // forked from ABA's UpDownRoad
  3. // UpDownRoad.as
  4. //  Display a 3d updown road with 3d particles.
  5. package
  6. {
  7.   import flash.display.Sprite;
  8.   import flash.display.BitmapData;
  9.   import flash.display.Bitmap;
  10.   import flash.geom.Rectangle;
  11.   import flash.events.Event;
  12.   import flash.events.SampleDataEvent;
  13.   import flash.media.Sound;
  14.   [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]
  15.   public class UpDownRoad extends Sprite
  16.   {
  17.     private const SCREEN_WIDTH:int = 465;
  18.     private const SCREEN_HEIGHT:int = 465;
  19.     private const DRAWN_PARTICLES_MAX_COUNT:int = 3000;
  20.     private const PROJECTION_RATIO:Number = 128;
  21.     private const LOD_DISTANCE:Number = 200;
  22.     private const MAX_DEPTH:Number = 500;
  23.     private const ROAD_SPACING:Number = 5;
  24.     private const ROAD_WIDTH:Number = 64;
  25.     private const ROAD_HEIGHT:Number = 7;
  26.     private const SIGHT_HEIGHT:Number = 36;
  27.     private const BACKGROUND_BOX_SIZE:int = 16;
  28.     private const BACKGROUND_R:int = 0xcc;
  29.     private const BACKGROUND_G:int = 0xdd;
  30.     private const BACKGROUND_B:int = 0xaa;
  31.     private var buffer:BitmapData = new BitmapData(SCREEN_WIDTH, SCREEN_HEIGHT, false0);
  32.     private var rect:Rectangle = new Rectangle;
  33.     private var roads:Vector.<Road> = new Vector.<Road>;
  34.     private var roadStartY:Number;
  35.     private var particles:Vector.<Particle> = new Vector.<Particle>;
  36.     private var drawnParticles:Vector.<DrawnParticle> = new Vector.<DrawnParticle>;
  37.     private var dpIndex:int;
  38.     private var viewpoint:Vector3 = new Vector3;
  39.     private var yaw:Number, pitch:Number, roll:Number;
  40.     private var offset:Vector3 = new Vector3;
  41.     private var carPosIndex:Number;
  42.     private var roadIndex:int;
  43.     public function UpDownRoad()
  44.     {
  45.       stage.scaleMode = "noScale";
  46.       addChild(new Bitmap(buffer));
  47.       yaw = pitch = roll = 0;
  48.       createRoad();
  49.       addTrees();
  50.       for (var i:int = 0; i < DRAWN_PARTICLES_MAX_COUNT; i++)
  51.         drawnParticles.push(new DrawnParticle);
  52.       carPosIndex = roads.length - 10;
  53.       viewpoint.x = roads[carPosIndex].pos.x;
  54.       viewpoint.y = roads[carPosIndex].pos.y;
  55.       viewpoint.z = roads[carPosIndex].pos.z;
  56.       addEventListener(Event.ENTER_FRAME, onEnterFrame);
  57.       _initializeSound();
  58.     }
  59.     private function onEnterFrame(evt:Event):void
  60.     {
  61.       buffer.fillRect(buffer.rect, 0x99ffdd);
  62.       carPosIndex += 1.7;
  63.       if (carPosIndex >= roads.length)
  64.         carPosIndex -= roads.length;
  65.       var cpi:int = carPosIndex;
  66.       var ncpi:int = carPosIndex + 1;
  67.       if (ncpi >= roads.length)
  68.         ncpi -= roads.length;
  69.       var co:Number = carPosIndex - cpi;
  70.       var rp:Vector3 = roads[cpi].pos;
  71.       var nrp:Vector3 = roads[ncpi].pos;
  72.       viewpoint.x += (rp.x * (1 - co) + nrp.x * co - viewpoint.x) * 0.2;
  73.       viewpoint.y += (rp.y * (1 - co) + nrp.y * co - viewpoint.y - SIGHT_HEIGHT) * 0.2;
  74.       viewpoint.z += (rp.z * (1 - co) + nrp.z * co - viewpoint.z) * 0.2;
  75.       var oa:Number = roads[ncpi].angle - roads[cpi].angle;
  76.       oa = normalizeAngle(oa);
  77.       oa = roads[cpi].angle + oa * co - yaw;
  78.       oa = normalizeAngle(oa);
  79.       yaw += oa * 0.1;
  80.       yaw = normalizeAngle(yaw);
  81.       pitch += ((roads[cpi].upDown * (1 - co) + roads[ncpi].upDown * co) * 0.5 - pitch) * 0.2;
  82.       roll += (-oa * 0.7 - roll) * 0.1;
  83.       dpIndex = 0;
  84.       for each (var p:Particle in particles)
  85.         drawParticle(p);
  86.       drawnParticles.sort(sortOnZ);
  87.       function sortOnZ(v1:DrawnParticle, v2:DrawnParticle):Number
  88.       {
  89.         if (v1.pos.z < v2.pos.z)
  90.           return 1;
  91.         else if (v1.pos.z > v2.pos.z)
  92.           return -1;
  93.         else
  94.           return 0;
  95.       }
  96.       buffer.lock();
  97.       drawBackground();
  98.       for (var i:int = 0; i < dpIndex; i++)
  99.       {
  100.         var dp:DrawnParticle = drawnParticles[i];
  101.         rect.x = dp.pos.x - dp.width;
  102.         rect.y = dp.pos.y - dp.height;
  103.         rect.width = dp.width * 2;
  104.         rect.height = dp.height * 2;
  105.         buffer.fillRect(rect, dp.color);
  106.       }
  107.       buffer.unlock();
  108.     }
  109.     private function drawParticle(p:Particle):void
  110.     {
  111.       offset.x = p.pos.x - viewpoint.x;
  112.       offset.y = p.pos.y - viewpoint.y;
  113.       offset.z = p.pos.z - viewpoint.z;
  114.       offset.rotationYaw(yaw);
  115.       offset.rotationPitch(pitch);
  116.       offset.rotationRoll(roll);
  117.       if (offset.z < -10 || offset.z > MAX_DEPTH)
  118.         return;
  119.       if (p.detail != null && offset.length < LOD_DISTANCE)
  120.       {
  121.         for each (var pp:Particle in p.detail)
  122.           drawParticle(pp);
  123.         return;
  124.       }
  125.       if (offset.z < 1 || p.width <= 0)
  126.         return;
  127.       var ar:Number = 1.0 - offset.z / MAX_DEPTH;
  128.       if (ar < 0)
  129.         return;
  130.       var dp:DrawnParticle = drawnParticles[dpIndex];
  131.       var zr:Number = 1.0 / offset.z * PROJECTION_RATIO;
  132.       dp.pos.x = offset.x * zr + SCREEN_WIDTH / 2;
  133.       dp.pos.y = offset.y * zr + SCREEN_HEIGHT / 2;
  134.       dp.pos.z = offset.z;
  135.       dp.width = p.width * zr;
  136.       dp.height = p.height * zr;
  137.       dp.color = createColor(p.r, p.g, p.b, 250 * ar);
  138.       dpIndex++;
  139.     }
  140.     private function createColor(r:int, g:int, b:int, a:int):int
  141.     {
  142.       return int((r * a + BACKGROUND_R * (256 - a)) / 256) * 0x10000 +
  143.              int((g * a + BACKGROUND_G * (256 - a)) / 256) * 0x100 +
  144.              int((b * a + BACKGROUND_B * (256 - a)) / 256);
  145.     }
  146.     private function drawBackground():void
  147.     {
  148.       offset.x = 0;
  149.       offset.y = 0;
  150.       offset.z = 99999;
  151.       offset.rotationPitch(pitch);
  152.       var zr:Number = 1.0 / offset.z * PROJECTION_RATIO;
  153.       var bc:int = SCREEN_WIDTH / BACKGROUND_BOX_SIZE + 1;
  154.       var bx:Number, by:Number;
  155.       var vby:Number = BACKGROUND_BOX_SIZE * Math.sin(roll);
  156.       var bh:Number, bby:Number;
  157.       for (var j:int = 0; j < 3; j++)
  158.       {
  159.         switch (j)
  160.         {
  161.           case 0:
  162.             bh = 4;
  163.             bby = 0;
  164.             break;
  165.           case 1:
  166.             bh = 8;
  167.             bby = 8;
  168.             break;
  169.           case 2:
  170.             bh = SCREEN_HEIGHT / 3;
  171.             bby = 24;
  172.             break;
  173.         }
  174.         bx = SCREEN_WIDTH / 2 - BACKGROUND_BOX_SIZE * bc / 2;
  175.         by = offset.y * zr + SCREEN_HEIGHT / 2 - vby * bc / 2 + bby + bh;
  176.         rect.width = BACKGROUND_BOX_SIZE;
  177.         rect.height = bh * 2;
  178.         for (var i:int = 0; i < bc; i++)
  179.         {
  180.           rect.x = bx - BACKGROUND_BOX_SIZE / 2;
  181.           rect.y = by - bh;
  182.           buffer.fillRect(rect, createColor(0xff - j * 0x33, 0xee, 0x88 - j * 0x33, 255));
  183.           bx += BACKGROUND_BOX_SIZE;
  184.           by += vby;
  185.         }
  186.       }
  187.     }
  188.     private var roadPattern:Array =
  189.     [20,0,0.2,1,116,0,-3,0,116,0,3,0,180,0.05,0.05,1,1,
  190.      90,0,0,0,080,-0.05,-1,1,120,0,1.75,1,1];
  191.     private function createRoad():void
  192.     {
  193.       var r:Road = new Road;
  194.       var a:Number = 0;
  195.       var ud:Number = roadPattern[2];
  196.       roadStartY = r.pos.y = -70;
  197.       r.angle = a;
  198.       r.upDown = ud;
  199.       var c:int;
  200.       var ta:Number, tud:Number;
  201.       var polePattern:int;
  202.       var surfacePattern:int;
  203.       var i:int;
  204.       roadIndex = 0;
  205.       for (i = 0; i < roadPattern.length; i += 5)
  206.       {
  207.         c = roadPattern[i];
  208.         ta = roadPattern[i + 1];
  209.         tud = roadPattern[i + 2];
  210.         polePattern = roadPattern[i + 3];
  211.         surfacePattern = roadPattern[i + 4];
  212.         for (var j:int = 0; j < c; j++)
  213.         {
  214.           a += (ta - a) * 0.2;
  215.           ud += (tud - ud) * 0.1;
  216.           r.angle += a;
  217.           r.angle = normalizeAngle(r.angle);
  218.           r.upDown = ud;
  219.           addRoadAndPole(r, polePattern, surfacePattern);
  220.           r = getNextRoad(r);
  221.         }
  222.       }
  223.       c = Math.sqrt(r.pos.x * r.pos.x + r.pos.z * r.pos.z) / ROAD_SPACING;
  224.       var vrp:Vector3 = new Vector3;
  225.       vrp.x = -r.pos.x / c;
  226.       vrp.y = (roadStartY - r.pos.y) / c;
  227.       vrp.z = -r.pos.z / c;
  228.       var va:Number = -r.angle / c;
  229.       var vud:Number = -r.upDown / c;
  230.       for (i = 0; i < c; i++)
  231.       {
  232.         addRoadAndPole(r, polePattern, surfacePattern);
  233.         var nr:Road = new Road;
  234.         nr.pos.x = r.pos.x + vrp.x;
  235.         nr.pos.y = r.pos.y + vrp.y;
  236.         nr.pos.z = r.pos.z + vrp.z;
  237.         nr.angle = r.angle + va;
  238.         nr.upDown = r.upDown + vud;
  239.         r = nr;
  240.       }
  241.     }
  242.     private function addRoadAndPole(r:Road, polePattern:int, surfacePattern:int):void
  243.     {
  244.       addRoadParticles(r, surfacePattern);
  245.       roads.push(r);
  246.       if (polePattern > 0 && roadIndex % 7 == 0)
  247.         addPoleParticles(r);
  248.       roadIndex++;
  249.     }
  250.     private function getNextRoad(r:Road):Road
  251.     {
  252.       var nr:Road = new Road;
  253.       nr.pos.x = r.pos.x + Math.sin(r.angle) * ROAD_SPACING;
  254.       nr.pos.z = r.pos.z + Math.cos(r.angle) * ROAD_SPACING;
  255.       nr.pos.y = r.pos.y + Math.sin(r.upDown) * ROAD_SPACING;
  256.       nr.angle = r.angle;
  257.       nr.upDown = r.upDown;
  258.       return nr;
  259.     }
  260.     private function addRoadParticles(r:Road, surfacePattern:int):void
  261.     {
  262.       var i:int, sr:int, sg:int, sb:int;
  263.       switch (surfacePattern)
  264.       {
  265.         case 0:
  266.           sr = sg = sb = 210;
  267.           break;
  268.         case 1:
  269.           sr = 180; sg = 150; sb = 50;
  270.           break;
  271.       }
  272.       for (i = 0; i < 3; i++)
  273.       {
  274.         addBoxParticle
  275.         (r.pos.x + Math.cos(r.angle) * ROAD_WIDTH / 3 * 2 * (i - 1),
  276.          r.pos.y,
  277.          r.pos.z - Math.sin(r.angle) * ROAD_WIDTH / 3 * 2 * (i - 1),
  278.          ROAD_WIDTH / 3 * 1.4, ROAD_HEIGHT, 41, r.angle, 0,
  279.          sr, sg, sb, 1);
  280.       }
  281.       if (roadIndex % 3 == 0)
  282.       {
  283.         for (i = 0; i < 2; i++)
  284.         {
  285.           var p:Particle = new Particle;
  286.           p.pos.x = r.pos.x + Math.cos(r.angle) * ROAD_WIDTH * 1.2 * (i * 2 - 1);
  287.           p.pos.y = r.pos.y - ROAD_HEIGHT * 2;
  288.           p.pos.z = r.pos.z - Math.sin(r.angle) * ROAD_WIDTH * 1.2 * (i * 2 - 1);
  289.           p.width = ROAD_HEIGHT;
  290.           p.height = ROAD_HEIGHT * 0.75;
  291.           p.r = p.g = p.b = 32;
  292.           p.detail = null;
  293.           particles.push(p);
  294.         }
  295.       }
  296.     }
  297.     private function addPoleParticles(r:Road):void
  298.     {
  299.       for (var i:int = 0; i < 2; i++)
  300.         addBoxParticle(r.pos.x - Math.cos(r.angle) * ROAD_WIDTH * (i * 2 - 1) * 1.1,
  301.                        r.pos.y - 32,
  302.                        r.pos.z + Math.sin(r.angle) * ROAD_WIDTH * (i * 2 - 1) * 1.1,
  303.                        63216, r.angle, 0,
  304.                        25060600);
  305.     }
  306.     private function addTrees():void
  307.     {
  308.       for (var i:int = 0; i < 480; i++)
  309.       {
  310.         var x:Number = (Math.random() * 2 - 1) * 1000;
  311.         var z:Number = (Math.random() * 2 - 1) * 1000;
  312.         if (getDistanceFromRoad(x, z) < 100)
  313.           continue;
  314.         var wh:Number = Math.random() * 10 + 10;
  315.         var lh:Number = Math.random() * 20 + 20;
  316.         addBoxParticle(x, -wh, z, 3 + Math.random() * 2, wh, 1300150100501);
  317.         addBoxParticle(x, -wh - lh, z, 12 + Math.random() * 5, lh, 5100140240201);
  318.       }
  319.     }
  320.     private function getDistanceFromRoad(x:Number, z:Number):Number
  321.     {
  322.       var d:Number = 99999;
  323.       offset.y = 0;
  324.       for each (var r:Road in roads)
  325.       {
  326.         offset.x = r.pos.x - x;
  327.         offset.z = r.pos.z - z;
  328.         var l:Number = offset.length;
  329.         if (l < d)
  330.           d = l;
  331.       }
  332.       return d;
  333.     }
  334.     private function addBoxParticle(x:Number, y:Number, z:Number,
  335.                                     width:Number, height:Number, wDiv:int, hDiv:int,
  336.                                     angle:Number, anglePattern:int,
  337.                                     r:int, g:int, b:int, colorPattern:int):void
  338.     {
  339.       var p:Particle = new Particle;
  340.       p.width = width; p.height = height;
  341.       p.pos.x = x; p.pos.y = y; p.pos.z = z;
  342.       p.r = r; p.g = g; p.b = b;
  343.       p.detail = new Vector.<Particle>;
  344.       var ox:Number = Math.cos(angle) * width * 2 / wDiv;
  345.       var oz:Number = -Math.sin(angle) * width * 2 / wDiv;
  346.       for (var dx:int = 0 ; dx < wDiv; dx++)
  347.       {
  348.         for (var dy:int = 0; dy < hDiv; dy++)
  349.         {
  350.           if (anglePattern == 1)
  351.           {
  352.             var a:Number = Math.random() * Math.PI * 2;
  353.             ox = Math.cos(a) * width * 2 / wDiv;
  354.             oz = -Math.sin(a) * width * 2 / wDiv;
  355.           }
  356.           var pp:Particle = new Particle;
  357.           pp.pos.x = p.pos.x + (dx - wDiv / 2) * ox;
  358.           pp.pos.y = p.pos.y + (dy - hDiv / 2) * height * 2 / hDiv;
  359.           pp.pos.z = p.pos.z + (dx - wDiv / 2) * oz;
  360.           pp.width = width / wDiv * 1.4;
  361.           pp.height = height / hDiv * 1.1;
  362.           switch (colorPattern)
  363.           {
  364.             case 0:
  365.               pp.r = r; pp.g = g; pp.b = b;
  366.               break;
  367.             case 1:
  368.               var co:int = Math.random() * 30 - 15;
  369.               pp.r = r + co; pp.g = g + co; pp.b = b + co;
  370.               break;
  371.           }
  372.           pp.detail = null;
  373.           p.detail.push(pp);
  374.         }
  375.       }
  376.       particles.push(p);
  377.     }
  378.     private function normalizeAngle(v:Number):Number
  379.     {
  380.       if (v > Math.PI)
  381.         return v - Math.PI * 2;
  382.       else if (v < -Math.PI)
  383.         return v + Math.PI * 2;
  384.       else
  385.         return v;
  386.     }
  387.     private var _sound:Sound;
  388.     private var _module:TinySiOPM;
  389.     private var _sequencer:Sequencer;
  390.     private function _initializeSound():void {
  391.         var mml:String =""
  392.         mml+="#BS=r28$s10l4[3e8[22e]er<s2c12>s10brg]s1a36g12f+16s12e8[5e]l2egabl4ers2e20";
  393.         mml+="s10[[3e8[22e]er<s2c12>s10brg]e8[15e]gabf+8gae8eeegab";
  394.         mml+="[[<c8[6c]>b8[6b]a8[6a]|g8ggggab]|a8aaaabr]a8[6a]<d8[14d]>]";
  395.         mml+="erer20[8[erer20|erer20]|er28]erer20";
  396.         mml+="[[[<c8[6c]>b8[6b]a8[6a]|g8ggggab]|a8aaaabr]a8[6a]]<d8[14d]>;";
  397.         mml+="@0@o1o2BS; v7@0@i3o4BS;";
  398.         mml+="#BD=r8l4v14s32cc2<v5e2c2>g2v14crl4c$[rcrr[15ccrr]] [[rcrr[15ccrr]]";
  399.         mml+="[rcrr[15ccrr]] [2ccrr]cl2<v6ggggeeeecccc>l4v14c]";
  400.         mml+="rcr20[6[crcr20|crcr20]|cr28][8crcrrccr]crcrrcccr";
  401.         mml+="[4rcrr[15ccrr]] [2ccrr]cl2<v6ggggeeeecccc>l4v14c;";
  402.         mml+="#SN=r8l4v14s12k8cc2k4s32c2c2c6k8s12l8c$k8[14rc]l4ck4ccrk8ccl8c[7rc]r4c4c[5rc]rl2k4ccc8r4k8c8c4c4r8";
  403.         mml+="l8[[[15rc]r4c4c] [k8[13rc]|r4c2c2c4k4l4crccrccl8r] rc[rcr4c4c]c4k4l2s32[3c1c1ccc]r4l8k8s12]";
  404.         mml+="l16[[2rc]|rc4s24k4c4c8s12k8rc4c12]rc4c12k4s32l2[ccc4]k8s12c4c4c8 l8[6[7rc]r4c4c]r16c4c4c8";
  405.         mml+="[4k8[13rc]|r4c2c2c4k4l4crccrccl8r] rc[rcr4c4c]c4k4l2s32[3c1c1ccc]r4l8k8s12;";
  406.         mml+="#CY=r8l8s4v8c+20$l8[3s6p3v16d12s10p5v6[14d]d4]s6v16d12p5v6[3d]p2v12d12p5d16p3v16d44p4d20";
  407.         mml+="[l4[4p5s6v16d12s24p6v6[29d]]l8p5[4s6v16d16s10v8[14d]][4d]p3s4v12c+32]";
  408.         mml+="s64v3l2[512d]v12s6c+8v15c+2r22";
  409.         mml+="l8p5[8s6v16d16s10v8[14d]][4d]p3s4v12c+32;";
  410.         mml+="@0w32o4BD; @3o0SN; @3o0CY;";
  411.         mml+="#GT=r28$l4[3[3[s2e8s12e]ee]ers2b2<c10>brg]s1a36g12f+16s2e40re20";
  412.         mml+="[l4[3[3[s2e8s12e]ee]ers2b2<c10>brg][[s2e8s12e]ee]es1g16f+12e20s12eer";
  413.         mml+="s1l8[<c24c>b24b<d24d>g24g<c24c>b24b|a56b]a64<d64>]";
  414.         mml+="r256s24l4[192e]s12erer20";
  415.         mml+="s1l8[[<c24c>b24b<d24d>g24g<c24c>b24b|a56b]a64]<d64>;";
  416.         mml+="@2@o1o6    GT; @0@i3@o1o4k112GT; p1v5@1@i4o3    GT;";
  417.         mml+="@2@o1o6k112GT; @0@i3@o1o4k224GT; p7v4@1@i4o3k112GT;";
  418.         mml+="#S1=v5r28$o6s6l4e8[4e|r36drdrer]r28[3dr]e8[er36drdr|er]s1c36>b12a12r<erer32d20";
  419.         mml+="s2[[[e32d32|d24crc20d8r]rd28dr|c12>b<rd]g12f+rd";
  420.         mml+="[[er20erdr20dr|dr20drdr12d16]|d24drd24d8]d64d56dr]";
  421.         mml+="v7drdrv1drdr[8[v6drdrv1dv6c+12|v6drdrv1drdr]|drrrv1drrr]drdr20";
  422.         mml+="[[[er20erdr20dr|dr20drdr12d16]|d24drd24d8]d64]d56dr;";
  423.         mml+="#S2=v6r28$o5s6l4g8[4g|r36f+rf+rgr]r28[3f+r]g8[gr36f+rf+r|gr]s1e36e12dr12erer32f+20";
  424.         mml+="s2[[[g32f+32|f+24f+re20f+8r]rf+28f+r|e12drf+]b12brf+";
  425.         mml+="[[gr20grgr20gr|f+r20f+rgr12fgb8]|g24grf+24f+8]g64f+56f+r]";
  426.         mml+="v8grgrv1grgr[8[v6grgrv1gv6g12|v6grgrv1grgr]|grrrv1grrr]grgr20";
  427.         mml+="[[[gr20grgr20gr|f+r20f+rgr12fgb8]|g24grf+24f+8]g64]f+56f+r;";
  428.         mml+="#S3=v6r28$o5s6l4b8[4b|r36ararbr]r28[3ar]b8[br36arar|br]s1a36g12f+12rbrbr32a20";
  429.         mml+="s2>[[[b32a32|a24grg20a8r]ra28ar|g12ara]<<d12d>ra";
  430.         mml+="[[cr20cr>br20br|ar20arbr12b16<]|a56a8<]a64a56ar]<";
  431.         mml+="v8ererv1erer[8[v6ererv1ev6e12|v6ererv1erer]|errrv1errr]erer20";    
  432.         mml+="[[[cr20cr>br20br|ar20arbr12b16<]|a56a8<]a64]a56ar<;";
  433.         mml+="p6@1S1; p2@1S2; @1S3;";
  434.         mml+="#MA=r28$@1s3[l16f+1g19f+d>a12b48l4|f+gargre8r112<]r8<cde36g8el8aea+2b2l4rer32d20";
  435.         mml+="@10[s6l4[>[b8bbbbab<c+2d2r>a24|a8aaaagab8<c>ba8eg]r|<f+16g8f+e24r8]<g16f+12e20>";
  436.         mml+="s3b<d>b<e20re8d16>brgra24gab16 fgb<de24f+gd16cr>b8a52<ef+r";
  437.         mml+="g28f+g8d16grf+12gargrarb16<c+1d3rdr>g16<d+1e7dr>g12<cr>ba64f+64];";
  438.         mml+="#MB=r20@2s1w12o9c64s4w-32o4[4c8]r16s2w6o8c64s4w24o5[5c6]r2s1w-12o4c64s0w-2o5c224";
  439.         mml+="@10s3w0o6l4[8rf+de>gb<d>f+abegaf+de<];";
  440.         mml+="#MB2=r772l4<[4raf+g>b<df+>a<de>ab<d>af+g<]>;";
  441.         mml+="#MC=r16>[s3b<d>b<e20re8d16>brgra24gab16 fgb<de24f+gd16cr>b8a52<ef+r";
  442.         mml+="g28f+g8d16grf+12gargrarb16<c+1d3rdr>g16<d+1e7dr>g12<cr>b|a52>]a64<d64>;";
  443.         mml+="v8o6k-1MAv6MBv8MC; v10o5k1MAv3MB2v10MC; v3p1o6r4MAv4MBv3MC;";
  444.         _module = new TinySiOPM(20481024, _onSoundFrame);
  445.         _sequencer = new Sequencer(2, _expandMML(mml));
  446.         _sound = new Sound();
  447.         _sound.addEventListener("sampleData", _onStream);
  448.         _sound.play();
  449.     }
  450.         
  451.     private function _onSoundFrame() : void {
  452.         _sequencer.onSoundFrame();
  453.     }
  454.         
  455.     private function _onStream(e:SampleDataEvent) : void {
  456.         var moduleOut:Vector.<Number> = _module.render();
  457.         for (var i:int = 0; i<4096; i++) {
  458.             e.data.writeFloat(moduleOut[i]);
  459.         }
  460.     }
  461.     private function _expandMML(mml:String) : Array {
  462.         var split:Array = mml.replace(/\s+/g, "").split(/;/);
  463.         var list:Array = [], macro:* = {};
  464.         var defMacro:RegExp = /^#([_A-Z][_A-Z0-9]*)=?(.*)/m;
  465.         for each (var seq:String in split) {
  466.             var res:* = defMacro.exec(seq);
  467.             if (res) macro[res[1]] = res[2];
  468.             else list.push(seq.replace(/[_A-Z][_A-Z0-9]*/g, function() : String {
  469.                 if (!arguments[0in macro) return "";
  470.                 return macro[arguments[0]];
  471.             }));
  472.         }
  473.         return list;
  474.     }
  475.   }
  476. }
  477. class Road
  478. {
  479.   public var pos:Vector3 = new Vector3;
  480.   public var angle:Number, upDown:Number;
  481. }
  482. class Particle
  483. {
  484.   public var pos:Vector3 = new Vector3;
  485.   public var width:Number;
  486.   public var height:Number;
  487.   public var r:int, g:int, b:int;
  488.   public var detail:Vector.<Particle>;
  489. }
  490. class DrawnParticle
  491. {
  492.   public var pos:Vector3 = new Vector3;
  493.   public var width:Number;
  494.   public var height:Number;
  495.   public var color:int;
  496. }
  497. class Vector3
  498. {
  499.   public var x:Number = 0;
  500.   public var y:Number = 0;
  501.   public var z:Number = 0;
  502.   public function rotationYaw(v:Number):void
  503.   {
  504.     var sv:Number = Math.sin(v);
  505.     var cv:Number = Math.cos(v);
  506.     var rx:Number = cv * x - sv * z;
  507.     z = sv * x + cv * z;
  508.     x = rx;
  509.   }
  510.   public function rotationPitch(v:Number):void
  511.   {
  512.     var sv:Number = Math.sin(v);
  513.     var cv:Number = Math.cos(v);
  514.     var ry:Number = cv * y - sv * z;
  515.     z = sv * y + cv * z;
  516.     y = ry;
  517.   }
  518.   public function rotationRoll(v:Number):void
  519.   {
  520.     var sv:Number = Math.sin(v);
  521.     var cv:Number = Math.cos(v);
  522.     var rx:Number = cv * x - sv * y;
  523.     y = sv * x + cv * y;
  524.     x = rx;
  525.   }
  526.   public function get length():Number
  527.   {
  528.     return Math.sqrt(x * x + y * y + z * z);
  529.   }
  530. }
  531. // MML Sequencer
  532. //   http://wonderfl.kayac.com/user/keim_at_Si
  533. //--------------------------------------------------
  534. class Sequencer {
  535.     private var _tracks:Array, _count:int=Track.speed+1;
  536.     function Sequencer(speed:int, mmls:Array=null) { Track.speed=speed; mml=mmls; }
  537.     public function onSoundFrame() : Boolean {
  538.         if (++_count == Track.speed) {
  539.             for each (var tr:Track in _tracks) tr.execute();
  540.             _count = 0;
  541.             return true;
  542.         }
  543.         return false;
  544.     }
  545.     public function set mml(list:Array) : void {
  546.         _tracks = [];
  547.         if (list) {
  548.             for each (var seq:String in list) _tracks.push(new Track(seq));
  549.         }
  550.         _count = 0;
  551.     }
  552. }
  553. class Track {
  554.     static public var codeA:int="a".charCodeAt(), nt:Array=[9,11,0,2,4,5,7], speed:int=3;
  555.     public var oct:int, len:int, tl:int, dt:int, cnt:int, seq:String, sgn:int, stac:Array, osc:Osc;
  556.     private var _rex:RegExp=/(@i|@o|[a-gkloprsvw<>[|\]$@])([#+])?(-?\d+)?/g;
  557.     function Track(seq:String) {
  558.         osc = Osc.alloc().reset().activate(false);
  559.         reset(seq);
  560.     }
  561.     public function reset(seq_:String) : void {
  562.         seq=seq_; oct=5; len=4; tl=256; dt=0; cnt=0; sgn=0; _rex.lastIndex=0; stac=[];
  563.     }
  564.     public function execute() : void {
  565.         if (--cnt <= 0) {
  566.             for (var i:int=0; i<100; i++) {
  567.                 var res:* = _rex.exec(seq);
  568.                 if (!res) {
  569.                     if (sgn) { _rex.lastIndex = sgn; continue; }
  570.                     else     { cnt = int.MAX_VALUE; break; }
  571.                 }
  572.                 var cmd:int = res[1].charCodeAt();
  573.                 if (cmd>=codeA && cmd<=codeA+6) {
  574.                     cnt = (res[3]) ? int(res[3]) : len;
  575.                     osc.len = cnt * speed;
  576.                     osc.pt = ((nt[cmd-codeA]+oct*12+((res[2])?1:0))<<4) + dt;
  577.                     osc.tl = tl;
  578.                     break;
  579.                 } else if (res[1] == 'r') {
  580.                     cnt = (res[3]) ? int(res[3]) : len;
  581.                     break;
  582.                 } else {
  583.                     switch(res[1]){
  584.                     case 'k': dt  = int(res[3]); break;
  585.                     case 'l': len = int(res[3]); break;
  586.                     case 'o': oct = int(res[3]); break;
  587.                     case 'v': tl  = TinySiOPM.log(int(res[3])*0.0625); break;
  588.                     case '<': oct++; break;
  589.                     case '>': oct--; break;
  590.                     case '@':  osc.ws = int(res[3]);    break;
  591.                     case 's':  osc.dr = int(res[3])<<2break;
  592.                     case 'w':  osc.sw = -int(res[3]);   break;
  593.                     case 'p':  osc.pan = (int(res[3])<<4)-64break;
  594.                     case '@i': osc.mod = int(res[3]);   break;
  595.                     case '@o': osc.out = int(res[3]);   break;
  596.                     case '$': sgn = _rex.lastIndex; break;
  597.                     case '[': stac.unshift({p:_rex.lastIndex,c:((res[3])?int(res[3]):2),j:0}); break;
  598.                     case '|'if (stac[0].c == 1) { _rex.lastIndex = stac[0].j; stac.shift(); } break;
  599.                     case ']'
  600.                         stac[0].j = _rex.lastIndex;
  601.                         if (--stac[0].c == 0) stac.shift();
  602.                         else _rex.lastIndex = stac[0].p;
  603.                         break;
  604.                     }
  605.                 }
  606.             }
  607.         }
  608.     }
  609. }
  610. class TinySiOPM {
  611.     private var _output:Vector.<Number>, _zero:Vector.<int>, _pipe:Vector.<int>;
  612.     private var _pitchTable:Vector.<int> = new Vector.<int>(2048true);
  613.     private var _logTable:Vector.<int> = new Vector.<int>(6144true);
  614.     private var _panTable:Vector.<Number> = new Vector.<Number>(129true);
  615.     private var _bufferSize:int, _callbackFrams:int, _onSoundFrame:Function;
  616.     
  617.     // Pass the buffer size and the function calls in each frame.
  618.     function TinySiOPM(bufferSize:int=2048, callbackFrams:int=1024, onSoundFrame:Function=null) {
  619.         var i:int, j:int, p:Number, v:Number, t:Vector.<int>, ft:Array=[0,1,2,3,4,5,6,7,7,6,5,4,3,2,1,0];
  620.         for (i=0, p=0; i<192; i++, p+=0.00520833333)                            // create pitchTable[128*16]
  621.             for(v=Math.pow(2, p)*12441.464342886, j=i; j<2048; v*=2, j+=192) _pitchTable[j] = int(v);
  622.         for (i=0; i<32; i++) _pitchTable[i] = (i+1)<<6;                         // [0:31] for white noize
  623.         for (i=0, p=0.0078125; i<256; i+=2, p+=0.0078125)                       // create logTable[12*256*2]
  624.             for(v=Math.pow(213-p), j=i; j<3328; v*=0.5, j+=256) _logTable[j+1] = -(_logTable[j]=int(v));
  625.         for (i=3328; i<6144; i++) _logTable[i] = 0;                             // [3328:6144] is 0-fill area
  626.         for (i=0, p=0; i<129; i++, p+=0.01217671571) _panTable[i]=Math.sin(p)*0.5;  // pan table;
  627.         for (t=Osc.createTable(10), i=0, p=0; i<1024; i++, p+=0.00613592315) t[i] = log(Math.sin(p)); // sin=0
  628.         for (t=Osc.createTable(10), i=0, p=0.75; i<1024; i++, p-=0.00146484375) t[i] = log(p);        // saw=1
  629.         for (t=Osc.createTable(5),  i=0; i<16; i++) t[i+16] = (t[i] = log(ft[i]*0.0625)) + 1;         // famtri=2
  630.         for (t=Osc.createTable(15), i=0; i<32768; i++) t[i] = log(Math.random()-0.5);                 // wnoize=3
  631.         for (i=0; i<8; i++) for (t=Osc.createTable(4), j=0; j<16; j++) t[j] = (j<=i) ? 192 : 193;     // pulse=4-11
  632.         _zero = new Vector.<int>(bufferSize, true);                             // allocate zero buffer
  633.         _pipe = new Vector.<int>(bufferSize, true);                             // allocate fm pipe buffer
  634.         _output = new Vector.<Number>(bufferSize*2true);                      // allocate stereo out
  635.         _bufferSize = bufferSize;
  636.         _callbackFrams = callbackFrams; 
  637.         _onSoundFrame = onSoundFrame;                                           // set parameters
  638.         for (i=0; i<bufferSize; i++) { _pipe[i]=_zero[i]=0; }                   // clear buffers
  639.     }
  640.     
  641.     // calculate index of logTable
  642.     static public function log(n:Number) : int {
  643.         return (n<0) ? ((n<-0.00390625) ? (((int(Math.log(-n) * -184.66496523 + 0.5) + 1) << 1) + 1) : 2047)
  644.                      : ((n> 0.00390625) ? (( int(Math.log( n) * -184.66496523 + 0.5) + 1) << 1)      : 2046);
  645.     }
  646.     // reset all oscillators
  647.     public function reset() : void {
  648.         for (var o:Osc=Osc._tm.n; o!=Osc._tm; o=o.inactivate().n) { o.fl = Osc._fl; }
  649.     }
  650.     // Returns stereo output as Vector.<Number>(bufferSize*2).
  651.     public function render() : Vector.<Number> {
  652.         var i:int, j:int, ph:int, dph:int, mod:int, sh:int, tl:int, lout:int, v:int, imax:int
  653.             osc:Osc, tm:Osc, l:Number, r:Number, wv:Vector.<int>, fm:Vector.<int>, base:Vector.<int>, 
  654.             out:Vector.<int>=_pipe, lt:Vector.<int>=_logTable, stereoOut:Vector.<Number> = _output;
  655.         imax = _bufferSize<<1;
  656.         for (i=0; i<imax; i++) stereoOut[i] = 0;
  657.         for (imax=_callbackFrams; imax<=_bufferSize; imax+=_callbackFrams) {
  658.             if (_onSoundFrame!=null) _onSoundFrame();
  659.             tm = Osc._tm;
  660.             for (osc=tm.n; osc!=tm; osc=osc.update()) {
  661.                 dph=_pitchTable[osc.pt]; ph=osc.ph; mod=osc.mod+10; sh=osc.sh; tl=osc.tl; wv=osc.wv;
  662.                 fm=(osc.mod==0)?_zero:_pipe; base=(osc.out!=2)?_zero:_pipe;
  663.                 for (i = imax-_callbackFrams; i < imax; i++) {
  664.                     v = ((ph + (fm[i] << mod))& 0x3ffffff) >> sh;
  665.                     lout = wv[v] + tl;
  666.                     out[i] = lt[lout] + base[i];
  667.                     ph = (ph + dph) & 0x3ffffff;
  668.                 }
  669.                 osc.ph = ph;
  670.                 if (osc.out==0) {
  671.                     l = _panTable[64-osc.pan] * 0.0001220703125;
  672.                     r = _panTable[64+osc.pan] * 0.0001220703125;
  673.                     for (i=imax-_callbackFrams, j=i*2; i<imax; i++) {
  674.                         stereoOut[j] += out[i]*l; j++;
  675.                         stereoOut[j] += out[i]*r; j++;
  676.                     }
  677.                 }
  678.             }
  679.         }
  680.         return stereoOut;
  681.     }
  682.     
  683.     // note on
  684.     public function noteOn(pitch:int, length:int=0, vol:Number=0.5, wave:int=0, decay:int=6, sweep:int=0, pan:int=0) : Osc {
  685.         var osc:Osc = Osc.alloc().reset();
  686.         osc.pt = pitch;
  687.         osc.len = length;
  688.         osc.tl = log(vol);
  689.         osc.ws = wave;
  690.         osc.dr = decay<<2;
  691.         osc.sw = sweep; 
  692.         osc.pan = pan;
  693.         return osc.activate(true);
  694.     }
  695. }
  696. class Osc {
  697.     // create new wave table and you can refer the table by '@' command.
  698.     static public function createTable(b:int) : Vector.<int> {
  699.         _w.push(new Vector.<int>(1<<b,true)); _s.push(26-b);
  700.         return _w[_w.length-1];
  701.     }
  702.     static public var _w:Array=[], _s:Array=[], _fl:Osc=new Osc(), _tm:Osc=new Osc();
  703.     static public function alloc():Osc{ if(_fl.p==_fl)return new Osc();var r:Osc=_fl.p;_fl.p=r.p;r.p.n=_fl;return r; }
  704.     public function into(x:Osc):Osc{ p=x.p;n=x;p.n=this;n.p=this;return this; }
  705.     public var p:Osc, n:Osc, fl:Osc, pt:int, len:int, ph:int;
  706.     public var tl:int, sw:int, dr:int, wv:Vector.<int>, sh:int, mod:int, out:int, pan:int;
  707.     public function set ws(t:int) : void { wv=_w[t]; sh=_s[t]; }
  708.     public function Osc() { p = n = this; }
  709.     public function update() : Osc { tl+=dr; pt+=sw; pt&=2047return (--len==0||tl>3328) ? (inactivate().n) : n; }
  710.     public function reset() : Osc { ph=0; pt=0; len=0; tl=3328; sw=0; dr=24; pan=0; ws=0; mod=0; out=0return this; }
  711.     public function activate(autoFree:Boolean=false) : Osc { into(_tm); fl=(autoFree)?_fl:nullreturn this; }
  712.     public function inactivate() : Osc { tl=3328if(!fl)return thisvar r:Osc=p; p.n=n; n.p=p; into(fl); return r; }
  713.     public function isActive() : Boolean { return (tl<3328); }
  714. }
noswf
  1. // forked from keim_at_Si's wonderflで音楽♪Like the wind【フルコーラス版】from:UpDownRoad
  2. // forked from ABA's UpDownRoad
  3. // UpDownRoad.as
  4. //  Display a 3d updown road with 3d particles.
  5. package
  6. {
  7.   import flash.display.Sprite;
  8.   import flash.display.BitmapData;
  9.   import flash.display.Bitmap;
  10.   import flash.geom.Rectangle;
  11.   import flash.events.Event;
  12.   import flash.events.SampleDataEvent;
  13.   import flash.media.Sound;
  14.   [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]
  15.   public class UpDownRoad extends Sprite
  16.   {
  17.     private const SCREEN_WIDTH:int = 465;
  18.     private const SCREEN_HEIGHT:int = 465;
  19.     private const DRAWN_PARTICLES_MAX_COUNT:int = 2000;
  20.     private const PROJECTION_RATIO:Number = 128;
  21.     private const LOD_DISTANCE:Number = 200;
  22.     private const MAX_DEPTH:Number = 500;
  23.     private const ROAD_SPACING:Number = 5;
  24.     private const ROAD_WIDTH:Number = 64;
  25.     private const ROAD_HEIGHT:Number = 6;
  26.     private const SIGHT_HEIGHT:Number = 30;
  27.     private const BACKGROUND_BOX_SIZE:int = 16;
  28.     private const BACKGROUND_R:int = 0x88;
  29.     private const BACKGROUND_G:int = 0xcc;
  30.     private const BACKGROUND_B:int = 0xff;
  31.     private var buffer:BitmapData = new BitmapData(SCREEN_WIDTH, SCREEN_HEIGHT, false0);
  32.     private var rect:Rectangle = new Rectangle;
  33.     private var roads:Vector.<Road> = new Vector.<Road>;
  34.     private var particles:Vector.<Particle> = new Vector.<Particle>;
  35.     private var drawnParticles:Vector.<DrawnParticle> = new Vector.<DrawnParticle>;
  36.     private var dpIndex:int;
  37.     private var viewpoint:Vector3 = new Vector3;
  38.     private var yaw:Number, pitch:Number, roll:Number;
  39.     private var offset:Vector3 = new Vector3;
  40.     private var carPosIndex:Number;
  41.     private var roadIndex:int;
  42.     public function UpDownRoad()
  43.     {
  44.       addChild(new Bitmap(buffer));
  45.       yaw = pitch = roll = 0;
  46.       createRoad();
  47.       for (var i:int = 0; i < DRAWN_PARTICLES_MAX_COUNT; i++)
  48.         drawnParticles.push(new DrawnParticle);
  49.       carPosIndex = roads.length - 10;
  50.       addEventListener(Event.ENTER_FRAME, onEnterFrame);
  51.       _initializeSound();
  52.     }
  53.     private function onEnterFrame(evt:Event):void
  54.     {
  55.       buffer.fillRect(buffer.rect, 0x99ffdd);
  56.       carPosIndex += 1.7;
  57.       if (carPosIndex >= roads.length)
  58.         carPosIndex -= roads.length;
  59.       var cpi:int = carPosIndex;
  60.       var ncpi:int = carPosIndex + 1;
  61.       if (ncpi >= roads.length)
  62.         ncpi -= roads.length;
  63.       var co:Number = carPosIndex - cpi;
  64.       var rp:Vector3 = roads[cpi].pos;
  65.       var nrp:Vector3 = roads[ncpi].pos;
  66.       viewpoint.x += (rp.x * (1 - co) + nrp.x * co - viewpoint.x) * 0.2;
  67.       viewpoint.y += (rp.y * (1 - co) + nrp.y * co - viewpoint.y - SIGHT_HEIGHT) * 0.2;
  68.       viewpoint.z += (rp.z * (1 - co) + nrp.z * co - viewpoint.z) * 0.2;
  69.       var oa:Number = roads[ncpi].angle - roads[cpi].angle;
  70.       oa = normalizeAngle(oa);
  71.       oa = roads[cpi].angle + oa * co - yaw;
  72.       oa = normalizeAngle(oa);
  73.       yaw += oa * 0.1;
  74.       yaw = normalizeAngle(yaw);
  75.       pitch += ((roads[cpi].upDown * (1 - co) + roads[ncpi].upDown * co) * 0.5 - pitch) * 0.2;
  76.       roll += (-oa * 0.7 - roll) * 0.1;
  77.       drawBackground();
  78.       dpIndex = 0;
  79.       for each (var p:Particle in particles)
  80.         drawParticle(p);
  81.       drawnParticles.sort(sortOnZ);
  82.       function sortOnZ(v1:DrawnParticle, v2:DrawnParticle):Number
  83.       {
  84.         if (v1.pos.z < v2.pos.z)
  85.           return 1;
  86.         else if (v1.pos.z > v2.pos.z)
  87.           return -1;
  88.         else
  89.           return 0;
  90.       }
  91.       for (var i:int = 0; i < dpIndex; i++)
  92.       {
  93.         var dp:DrawnParticle = drawnParticles[i];
  94.         rect.x = dp.pos.x - dp.width;
  95.         rect.y = dp.pos.y - dp.height;
  96.         rect.width = dp.width * 2;
  97.         rect.height = dp.height * 2;
  98.         buffer.fillRect(rect, dp.color);
  99.       }
  100.     }
  101.     private function drawParticle(p:Particle):void
  102.     {
  103.       offset.x = p.pos.x - viewpoint.x;
  104.       offset.y = p.pos.y - viewpoint.y;
  105.       offset.z = p.pos.z - viewpoint.z;
  106.       offset.rotationYaw(yaw);
  107.       offset.rotationPitch(pitch);
  108.       offset.rotationRoll(roll);
  109.       if (offset.z < -10 || offset.z > MAX_DEPTH)
  110.         return;
  111.       if (p.detail != null && offset.length < LOD_DISTANCE)
  112.       {
  113.         for each (var pp:Particle in p.detail)
  114.           drawParticle(pp);
  115.         return;
  116.       }
  117.       if (offset.z < 1 || p.width <= 0)
  118.         return;
  119.       var ar:Number = 1.0 - offset.z / MAX_DEPTH;
  120.       if (ar < 0)
  121.         return;
  122.       var dp:DrawnParticle = drawnParticles[dpIndex];
  123.       var zr:Number = 1.0 / offset.z * PROJECTION_RATIO;
  124.       dp.pos.x = offset.x * zr + SCREEN_WIDTH / 2;
  125.       dp.pos.y = offset.y * zr + SCREEN_HEIGHT / 2;
  126.       dp.pos.z = offset.z;
  127.       dp.width = p.width * zr;
  128.       dp.height = p.height * zr;
  129.       dp.color = createColor(p.r, p.g, p.b, 250 * ar);
  130.       dpIndex++;
  131.     }
  132.     private function createColor(r:int, g:int, b:int, a:int):int
  133.     {
  134.       return int((r * a + BACKGROUND_R * (256 - a)) / 256) * 0x10000 +
  135.              int((g * a + BACKGROUND_G * (256 - a)) / 256) * 0x100 +
  136.              int((b * a + BACKGROUND_B * (256 - a)) / 256);
  137.     }
  138.     private function drawBackground():void
  139.     {
  140.       offset.x = 0;
  141.       offset.y = 0;
  142.       offset.z = 99999;
  143.       offset.rotationPitch(pitch);
  144.       var zr:Number = 1.0 / offset.z * PROJECTION_RATIO;
  145.       var bc:int = SCREEN_WIDTH / BACKGROUND_BOX_SIZE + 1;
  146.       var bx:Number, by:Number;
  147.       var vby:Number = BACKGROUND_BOX_SIZE * Math.sin(roll);
  148.       var bh:Number, bby:Number;
  149.       for (var j:int = 0; j < 3; j++)
  150.       {
  151.         switch (j)
  152.         {
  153.           case 0:
  154.           {
  155.             bh = 8;
  156.             bby = 0;
  157.             break;
  158.           }
  159.           case 1:
  160.           {
  161.             bh = 16;
  162.             bby = 16;
  163.             break;
  164.           }
  165.           case 2:
  166.           {
  167.             bh = SCREEN_HEIGHT / 3;
  168.             bby = 48;
  169.             break;
  170.           }
  171.         }
  172.         bx = SCREEN_WIDTH / 2 - BACKGROUND_BOX_SIZE * bc / 2;
  173.         by = offset.y * zr + SCREEN_HEIGHT / 2 - vby * bc / 2 + bby + bh;
  174.         rect.width = BACKGROUND_BOX_SIZE;
  175.         rect.height = bh * 2;
  176.         for (var i:int = 0; i < bc; i++)
  177.         {
  178.           rect.x = bx - BACKGROUND_BOX_SIZE / 2;
  179.           rect.y = by - bh;
  180.           buffer.fillRect(rect, createColor(0x88 - j * 0x33, 0x88 - j * 0x33, 0xff, 255));
  181.           bx += BACKGROUND_BOX_SIZE;
  182.           by += vby;
  183.         }
  184.       }
  185.     }
  186.     private var roadPattern:Array = [2000.21160, -3016030800.050.0519000080, -0.05, -1.012001.751];
  187.     private function createRoad():void
  188.     {
  189.       var r:Road = new Road;
  190.       var a:Number = 0;
  191.       var ud:Number = roadPattern[2];
  192.       r.angle = a;
  193.       r.upDown = ud;
  194.       var c:int;
  195.       var ta:Number, tud:Number;
  196.       var polePattern:int;
  197.       var i:int;
  198.       roadIndex = 0;
  199.       for (i = 0; i < roadPattern.length; i += 4)
  200.       {
  201.         c = roadPattern[i];
  202.         ta = roadPattern[i + 1];
  203.         tud = roadPattern[i + 2];
  204.         polePattern = roadPattern[i + 3];
  205.         for (var j:int = 0; j < c; j++)
  206.         {
  207.           a += (ta - a) * 0.2;
  208.           ud += (tud - ud) * 0.1;
  209.           r.angle += a;
  210.           r.angle = normalizeAngle(r.angle);
  211.           r.upDown = ud;
  212.           addRoadAndPole(r, polePattern);
  213.           r = getNextRoad(r);
  214.         }
  215.       }
  216.       c = Math.sqrt(r.pos.x * r.pos.x + r.pos.z * r.pos.z) / ROAD_SPACING;
  217.       var vrp:Vector3 = new Vector3;
  218.       vrp.x = -r.pos.x / c;
  219.       vrp.y = -r.pos.y / c;
  220.       vrp.z = -r.pos.z / c;
  221.       var va:Number = -r.angle / c;
  222.       var vud:Number = -r.upDown / c;
  223.       for (i = 0; i < c; i++)
  224.       {
  225.         addRoadAndPole(r, polePattern);
  226.         var nr:Road = new Road;
  227.         nr.pos.x = r.pos.x + vrp.x;
  228.         nr.pos.y = r.pos.y + vrp.y;
  229.         nr.pos.z = r.pos.z + vrp.z;
  230.         nr.angle = r.angle + va;
  231.         nr.upDown = r.upDown + vud;
  232.         r = nr;
  233.       }
  234.     }
  235.     private function addRoadAndPole(r:Road, polePattern:int):void
  236.     {
  237.       addRoadParticles(r);
  238.       roads.push(r);
  239.       if (polePattern > 0 && roadIndex % 7 == 0)
  240.       {
  241.         addPoleParticles(r);
  242.       }
  243.       roadIndex++;
  244.     }
  245.     private function getNextRoad(r:Road):Road
  246.     {
  247.       var nr:Road = new Road;
  248.       nr.pos.x = r.pos.x + Math.sin(r.angle) * ROAD_SPACING;
  249.       nr.pos.z = r.pos.z + Math.cos(r.angle) * ROAD_SPACING;
  250.       nr.pos.y = r.pos.y + Math.sin(r.upDown) * ROAD_SPACING;
  251.       nr.angle = r.angle;
  252.       nr.upDown = r.upDown;
  253.       return nr;
  254.     }
  255.     private function addRoadParticles(r:Road):void
  256.     {
  257.       for (var j:int = 0; j < 3; j++)
  258.       {
  259.         var p:Particle = new Particle;
  260.         var ox:Number = Math.cos(r.angle) * ROAD_WIDTH / 3 * 2;
  261.         var oz:Number = -Math.sin(r.angle) * ROAD_WIDTH / 3 * 2;
  262.         p.pos.x = r.pos.x + ox * (j - 1);
  263.         p.pos.y = r.pos.y;
  264.         p.pos.z = r.pos.z + oz * (j - 1);
  265.         p.width = ROAD_WIDTH / 3 * 1.05;
  266.         p.height = ROAD_HEIGHT;
  267.         p.detail = new Vector.<Particle>;
  268.         var pc:int = p.width / p.height + 2;
  269.         ox = Math.cos(r.angle) * p.width / pc * 2;
  270.         oz = -Math.sin(r.angle) * p.width / pc * 2;
  271.         var c:int = 0;
  272.         var i:int;
  273.         var pp:Particle;
  274.         for (i = 0; i < pc; i++)
  275.         {
  276.           pp = new Particle;
  277.           pp.pos.x = p.pos.x + ox * (i - pc / 2);
  278.           pp.pos.y = p.pos.y;
  279.           pp.pos.z = p.pos.z + oz * (i - pc / 2);
  280.           pp.width = pp.height = p.height;
  281.           pp.r = pp.g = pp.b = 190 + Math.random() * 30;
  282.           c += pp.r;
  283.           pp.detail = null;
  284.           p.detail.push(pp);
  285.         }
  286.         p.r = p.g = p.b = c / pc;
  287.         particles.push(p);
  288.         if (roadIndex % 3 == 0 && j != 1)
  289.         {
  290.           pp = new Particle;
  291.           pp.pos.x = p.pos.x + ox * pc / 2 * 1.2 * (j - 1);
  292.           pp.pos.y = p.pos.y - p.height * 0.5;
  293.           pp.pos.z = p.pos.z + oz * pc / 2 * 1.2 * (j - 1);
  294.           pp.width = p.height;
  295.           pp.height = p.height * 0.6;
  296.           pp.r = pp.g = pp.b = 32;
  297.           pp.detail = null;
  298.           particles.push(pp);
  299.         }
  300.       }
  301.     }
  302.     private function addPoleParticles(r:Road):void
  303.     {
  304.       for (var i:int = 0; i < 2; i++)
  305.       {
  306.         var p:Particle = new Particle;
  307.         p.width = 4;
  308.         p.height = 36;
  309.         p.pos.x = r.pos.x - Math.cos(r.angle) * ROAD_WIDTH * (i * 2 - 1) * 1.1;
  310.         p.pos.y = r.pos.y - p.height / 2;
  311.         p.pos.z = r.pos.z + Math.sin(r.angle) * ROAD_WIDTH * (i * 2 - 1) * 1.1;
  312.         p.r = 250; p.g = 60; p.b = 60;
  313.         p.detail = new Vector.<Particle>;
  314.         for (var j:int = 0; j < 8; j++)
  315.         {
  316.           var pp:Particle = new Particle;
  317.           pp.pos.x = p.pos.x;
  318.           pp.pos.y = p.pos.y - j * p.height / 8;
  319.           pp.pos.z = p.pos.z;
  320.           pp.width = p.width;
  321.           pp.height = p.height / 8;
  322.           pp.r = p.r;
  323.           pp.g = p.g;
  324.           pp.b = p.b;
  325.           pp.detail = null;
  326.           p.detail.push(pp);
  327.         }
  328.         particles.push(p);
  329.       }
  330.     }
  331.     private function normalizeAngle(v:Number):Number {
  332.       if (v > Math.PI)
  333.         return v - Math.PI * 2;
  334.       else if (v < -Math.PI)
  335.         return v + Math.PI * 2;
  336.       else
  337.         return v;
  338.     }
  339.     private var _sound:Sound;
  340.     private var _module:TinySiOPM;
  341.     private var _sequencer:Sequencer;
  342.     private function _initializeSound():void {
  343.         var mml:String =""
  344.         mml+="#BS=r28$s10l4[3e8[22e]er<s2c12>s10brg]s1a36g12f+16s12e8[5e]l2egabl4ers2e20";
  345.         mml+="s10[[3e8[22e]er<s2c12>s10brg]e8[15e]gabf+8gae8eeegab";
  346.         mml+="[[<c8[6c]>b8[6b]a8[6a]|g8ggggab]|a8aaaabr]a8[6a]<d8[14d]>]";
  347.         mml+="erer20[8[erer20|erer20]|er28]erer20";
  348.         mml+="[[[<c8[6c]>b8[6b]a8[6a]|g8ggggab]|a8aaaabr]a8[6a]]<d8[14d]>;";
  349.         mml+="@0@o1o2BS; v7@0@i3o4BS;";
  350.         mml+="#BD=r8l4v14s32cc2<v5e2c2>g2v14crl4c$[rcrr[15ccrr]] [[rcrr[15ccrr]]";
  351.         mml+="[rcrr[15ccrr]] [2ccrr]cl2<v6ggggeeeecccc>l4v14c]";
  352.         mml+="rcr20[6[crcr20|crcr20]|cr28][8crcrrccr]crcrrcccr";
  353.         mml+="[4rcrr[15ccrr]] [2ccrr]cl2<v6ggggeeeecccc>l4v14c;";
  354.         mml+="#SN=r8l4v14s12k8cc2k4s32c2c2c6k8s12l8c$k8[14rc]l4ck4ccrk8ccl8c[7rc]r4c4c[5rc]rl2k4ccc8r4k8c8c4c4r8";
  355.         mml+="l8[[[15rc]r4c4c] [k8[13rc]|r4c2c2c4k4l4crccrccl8r] rc[rcr4c4c]c4k4l2s32[3c1c1ccc]r4l8k8s12]";
  356.         mml+="l16[[2rc]|rc4s24k4c4c8s12k8rc4c12]rc4c12k4s32l2[ccc4]k8s12c4c4c8 l8[6[7rc]r4c4c]r16c4c4c8";
  357.         mml+="[4k8[13rc]|r4c2c2c4k4l4crccrccl8r] rc[rcr4c4c]c4k4l2s32[3c1c1ccc]r4l8k8s12;";
  358.         mml+="#CY=r8l8s4v8c+20$l8[3s6p3v16d12s10p5v6[14d]d4]s6v16d12p5v6[3d]p2v12d12p5d16p3v16d44p4d20";
  359.         mml+="[l4[4p5s6v16d12s24p6v6[29d]]l8p5[4s6v16d16s10v8[14d]][4d]p3s4v12c+32]";
  360.         mml+="s64v3l2[512d]v12s6c+8v15c+2r22";
  361.         mml+="l8p5[8s6v16d16s10v8[14d]][4d]p3s4v12c+32;";
  362.         mml+="@0w32o4BD; @3o0SN; @3o0CY;";
  363.         mml+="#GT=r28$l4[3[3[s2e8s12e]ee]ers2b2<c10>brg]s1a36g12f+16s2e40re20";
  364.         mml+="[l4[3[3[s2e8s12e]ee]ers2b2<c10>brg][[s2e8s12e]ee]es1g16f+12e20s12eer";
  365.         mml+="s1l8[<c24c>b24b<d24d>g24g<c24c>b24b|a56b]a64<d64>]";
  366.         mml+="r256s24l4[192e]s12erer20";
  367.         mml+="s1l8[[<c24c>b24b<d24d>g24g<c24c>b24b|a56b]a64]<d64>;";
  368.         mml+="@2@o1o6    GT; @0@i3@o1o4k112GT; p1v5@1@i4o3    GT;";
  369.         mml+="@2@o1o6k112GT; @0@i3@o1o4k224GT; p7v4@1@i4o3k112GT;";
  370.         mml+="#S1=v5r28$o6s6l4e8[4e|r36drdrer]r28[3dr]e8[er36drdr|er]s1c36>b12a12r<erer32d20";
  371.         mml+="s2[[[e32d32|d24crc20d8r]rd28dr|c12>b<rd]g12f+rd";
  372.         mml+="[[er20erdr20dr|dr20drdr12d16]|d24drd24d8]d64d56dr]";
  373.         mml+="v7drdrv1drdr[8[v6drdrv1dv6c+12|v6drdrv1drdr]|drrrv1drrr]drdr20";
  374.         mml+="[[[er20erdr20dr|dr20drdr12d16]|d24drd24d8]d64]d56dr;";
  375.         mml+="#S2=v6r28$o5s6l4g8[4g|r36f+rf+rgr]r28[3f+r]g8[gr36f+rf+r|gr]s1e36e12dr12erer32f+20";
  376.         mml+="s2[[[g32f+32|f+24f+re20f+8r]rf+28f+r|e12drf+]b12brf+";
  377.         mml+="[[gr20grgr20gr|f+r20f+rgr12fgb8]|g24grf+24f+8]g64f+56f+r]";
  378.         mml+="v8grgrv1grgr[8[v6grgrv1gv6g12|v6grgrv1grgr]|grrrv1grrr]grgr20";
  379.         mml+="[[[gr20grgr20gr|f+r20f+rgr12fgb8]|g24grf+24f+8]g64]f+56f+r;";
  380.         mml+="#S3=v6r28$o5s6l4b8[4b|r36ararbr]r28[3ar]b8[br36arar|br]s1a36g12f+12rbrbr32a20";
  381.         mml+="s2>[[[b32a32|a24grg20a8r]ra28ar|g12ara]<<d12d>ra";
  382.         mml+="[[cr20cr>br20br|ar20arbr12b16<]|a56a8<]a64a56ar]<";
  383.         mml+="v8ererv1erer[8[v6ererv1ev6e12|v6ererv1erer]|errrv1errr]erer20";    
  384.         mml+="[[[cr20cr>br20br|ar20arbr12b16<]|a56a8<]a64]a56ar<;";
  385.         mml+="p6@1S1; p2@1S2; @1S3;";
  386.         mml+="#MA=r28$@1s3[l16f+1g19f+d>a12b48l4|f+gargre8r112<]r8<cde36g8el8aea+2b2l4rer32d20";
  387.         mml+="@10[s6l4[>[b8bbbbab<c+2d2r>a24|a8aaaagab8<c>ba8eg]r|<f+16g8f+e24r8]<g16f+12e20>";
  388.         mml+="s3b<d>b<e20re8d16>brgra24gab16 fgb<de24f+gd16cr>b8a52<ef+r";
  389.         mml+="g28f+g8d16grf+12gargrarb16<c+1d3rdr>g16<d+1e7dr>g12<cr>ba64f+64];";
  390.         mml+="#MB=r20@2s1w12o9c64s4w-32o4[4c8]r16s2w6o8c64s4w24o5[5c6]r2s1w-12o4c64s0w-2o5c224";
  391.         mml+="@10s3w0o6l4[8rf+de>gb<d>f+abegaf+de<];";
  392.         mml+="#MB2=r772l4<[4raf+g>b<df+>a<de>ab<d>af+g<]>;";
  393.         mml+="#MC=r16>[s3b<d>b<e20re8d16>brgra24gab16 fgb<de24f+gd16cr>b8a52<ef+r";
  394.         mml+="g28f+g8d16grf+12gargrarb16<c+1d3rdr>g16<d+1e7dr>g12<cr>b|a52>]a64<d64>;";
  395.         mml+="v8o6k-1MAv6MBv8MC; v10o5k1MAv3MB2v10MC; v3p1o6r4MAv4MBv3MC;";
  396.         _module = new TinySiOPM(20481024, _onSoundFrame);
  397.         _sequencer = new Sequencer(2, _expandMML(mml));
  398.         _sound = new Sound();
  399.         _sound.addEventListener("sampleData", _onStream);
  400.         _sound.play();
  401.     }
  402.         
  403.     private function _onSoundFrame() : void {
  404.         _sequencer.onSoundFrame();
  405.     }
  406.         
  407.     private function _onStream(e:SampleDataEvent) : void {
  408.         var moduleOut:Vector.<Number> = _module.render();
  409.         for (var i:int = 0; i<4096; i++) {
  410.             e.data.writeFloat(moduleOut[i]);
  411.         }
  412.     }
  413.     private function _expandMML(mml:String) : Array {
  414.         var split:Array = mml.replace(/\s+/g, "").split(/;/);
  415.         var list:Array = [], macro:* = {};
  416.         var defMacro:RegExp = /^#([_A-Z][_A-Z0-9]*)=?(.*)/m;
  417.         for each (var seq:String in split) {
  418.             var res:* = defMacro.exec(seq);
  419.             if (res) macro[res[1]] = res[2];
  420.             else list.push(seq.replace(/[_A-Z][_A-Z0-9]*/g, function() : String {
  421.                 if (!arguments[0in macro) return "";
  422.                 return macro[arguments[0]];
  423.             }));
  424.         }
  425.         return list;
  426.     }
  427.   }
  428. }
  429. class Road
  430. {
  431.   public var pos:Vector3 = new Vector3;
  432.   public var angle:Number, upDown:Number;
  433. }
  434. class Particle
  435. {
  436.   public var pos:Vector3 = new Vector3;
  437.   public var width:Number;
  438.   public var height:Number;
  439.   public var r:int, g:int, b:int;
  440.   public var detail:Vector.<Particle>;
  441. }
  442. class DrawnParticle
  443. {
  444.   public var pos:Vector3 = new Vector3;
  445.   public var width:Number;
  446.   public var height:Number;
  447.   public var color:int;
  448. }
  449. class Vector3
  450. {
  451.   public var x:Number = 0;
  452.   public var y:Number = 0;
  453.   public var z:Number = 0;
  454.   public function rotationYaw(v:Number):void
  455.   {
  456.     var sv:Number = Math.sin(v);
  457.     var cv:Number = Math.cos(v);
  458.     var rx:Number = cv * x - sv * z;
  459.     z = sv * x + cv * z;
  460.     x = rx;
  461.   }
  462.   public function rotationPitch(v:Number):void
  463.   {
  464.     var sv:Number = Math.sin(v);
  465.     var cv:Number = Math.cos(v);
  466.     var ry:Number = cv * y - sv * z;
  467.     z = sv * y + cv * z;
  468.     y = ry;
  469.   }
  470.   public function rotationRoll(v:Number):void
  471.   {
  472.     var sv:Number = Math.sin(v);
  473.     var cv:Number = Math.cos(v);
  474.     var rx:Number = cv * x - sv * y;
  475.     y = sv * x + cv * y;
  476.     x = rx;
  477.   }
  478.   public function get length():Number
  479.   {
  480.     return Math.sqrt(x * x + y * y + z * z);
  481.   }
  482. }
  483. // MML Sequencer
  484. //   http://wonderfl.kayac.com/user/keim_at_Si
  485. //--------------------------------------------------
  486. class Sequencer {
  487.     private var _tracks:Array, _count:int=Track.speed+1;
  488.     function Sequencer(speed:int, mmls:Array=null) { Track.speed=speed; mml=mmls; }
  489.     public function onSoundFrame() : Boolean {
  490.         if (++_count == Track.speed) {
  491.             for each (var tr:Track in _tracks) tr.execute();
  492.             _count = 0;
  493.             return true;
  494.         }
  495.         return false;
  496.     }
  497.     public function set mml(list:Array) : void {
  498.         _tracks = [];
  499.         if (list) {
  500.             for each (var seq:String in list) _tracks.push(new Track(seq));
  501.         }
  502.         _count = 0;
  503.     }
  504. }
  505. class Track {
  506.     static public var codeA:int="a".charCodeAt(), nt:Array=[9,11,0,2,4,5,7], speed:int=3;
  507.     public var oct:int, len:int, tl:int, dt:int, cnt:int, seq:String, sgn:int, stac:Array, osc:Osc;
  508.     private var _rex:RegExp=/(@i|@o|[a-gkloprsvw<>[|\]$@])([#+])?(-?\d+)?/g;
  509.     function Track(seq:String) {
  510.         osc = Osc.alloc().reset().activate(false);
  511.         reset(seq);
  512.     }
  513.     public function reset(seq_:String) : void {
  514.         seq=seq_; oct=5; len=4; tl=256; dt=0; cnt=0; sgn=0; _rex.lastIndex=0; stac=[];
  515.     }
  516.     public function execute() : void {
  517.         if (--cnt <= 0) {
  518.             for (var i:int=0; i<100; i++) {
  519.                 var res:* = _rex.exec(seq);
  520.                 if (!res) {
  521.                     if (sgn) { _rex.lastIndex = sgn; continue; }
  522.                     else     { cnt = int.MAX_VALUE; break; }
  523.                 }
  524.                 var cmd:int = res[1].charCodeAt();
  525.                 if (cmd>=codeA && cmd<=codeA+6) {
  526.                     cnt = (res[3]) ? int(res[3]) : len;
  527.                     osc.len = cnt * speed;
  528.                     osc.pt = ((nt[cmd-codeA]+oct*12+((res[2])?1:0))<<4) + dt;
  529.                     osc.tl = tl;
  530.                     break;
  531.                 } else if (res[1] == 'r') {
  532.                     cnt = (res[3]) ? int(res[3]) : len;
  533.                     break;
  534.                 } else {
  535.                     switch(res[1]){
  536.                     case 'k': dt  = int(res[3]); break;
  537.                     case 'l': len = int(res[3]); break;
  538.                     case 'o': oct = int(res[3]); break;
  539.                     case 'v': tl  = TinySiOPM.log(int(res[3])*0.0625); break;
  540.                     case '<': oct++; break;
  541.                     case '>': oct--; break;
  542.                     case '@':  osc.ws = int(res[3]);    break;
  543.                     case 's':  osc.dr = int(res[3])<<2break;
  544.                     case 'w':  osc.sw = -int(res[3]);   break;
  545.                     case 'p':  osc.pan = (int(res[3])<<4)-64break;
  546.                     case '@i': osc.mod = int(res[3]);   break;
  547.                     case '@o': osc.out = int(res[3]);   break;
  548.                     case '$': sgn = _rex.lastIndex; break;
  549.                     case '[': stac.unshift({p:_rex.lastIndex,c:((res[3])?int(res[3]):2),j:0}); break;
  550.                     case '|'if (stac[0].c == 1) { _rex.lastIndex = stac[0].j; stac.shift(); } break;
  551.                     case ']'
  552.                         stac[0].j = _rex.lastIndex;
  553.                         if (--stac[0].c == 0) stac.shift();
  554.                         else _rex.lastIndex = stac[0].p;
  555.                         break;
  556.                     }
  557.                 }
  558.             }
  559.         }
  560.     }
  561. }
  562. class TinySiOPM {
  563.     private var _output:Vector.<Number>, _zero:Vector.<int>, _pipe:Vector.<int>;
  564.     private var _pitchTable:Vector.<int> = new Vector.<int>(2048true);
  565.     private var _logTable:Vector.<int> = new Vector.<int>(6144true);
  566.     private var _panTable:Vector.<Number> = new Vector.<Number>(129true);
  567.     private var _bufferSize:int, _callbackFrams:int, _onSoundFrame:Function;
  568.     
  569.     // Pass the buffer size and the function calls in each frame.
  570.     function TinySiOPM(bufferSize:int=2048, callbackFrams:int=1024, onSoundFrame:Function=null) {
  571.         var i:int, j:int, p:Number, v:Number, t:Vector.<int>, ft:Array=[0,1,2,3,4,5,6,7,7,6,5,4,3,2,1,0];
  572.         for (i=0, p=0; i<192; i++, p+=0.00520833333)                            // create pitchTable[128*16]
  573.             for(v=Math.pow(2, p)*12441.464342886, j=i; j<2048; v*=2, j+=192) _pitchTable[j] = int(v);
  574.         for (i=0; i<32; i++) _pitchTable[i] = (i+1)<<6;                         // [0:31] for white noize
  575.         for (i=0, p=0.0078125; i<256; i+=2, p+=0.0078125)                       // create logTable[12*256*2]
  576.             for(v=Math.pow(213-p), j=i; j<3328; v*=0.5, j+=256) _logTable[j+1] = -(_logTable[j]=int(v));
  577.         for (i=3328; i<6144; i++) _logTable[i] = 0;                             // [3328:6144] is 0-fill area
  578.         for (i=0, p=0; i<129; i++, p+=0.01217671571) _panTable[i]=Math.sin(p)*0.5;  // pan table;
  579.         for (t=Osc.createTable(10), i=0, p=0; i<1024; i++, p+=0.00613592315) t[i] = log(Math.sin(p)); // sin=0
  580.         for (t=Osc.createTable(10), i=0, p=0.75; i<1024; i++, p-=0.00146484375) t[i] = log(p);        // saw=1
  581.         for (t=Osc.createTable(5),  i=0; i<16; i++) t[i+16] = (t[i] = log(ft[i]*0.0625)) + 1;         // famtri=2
  582.         for (t=Osc.createTable(15), i=0; i<32768; i++) t[i] = log(Math.random()-0.5);                 // wnoize=3
  583.         for (i=0; i<8; i++) for (t=Osc.createTable(4), j=0; j<16; j++) t[j] = (j<=i) ? 192 : 193;     // pulse=4-11
  584.         _zero = new Vector.<int>(bufferSize, true);                             // allocate zero buffer
  585.         _pipe = new Vector.<int>(bufferSize, true);                             // allocate fm pipe buffer
  586.         _output = new Vector.<Number>(bufferSize*2true);                      // allocate stereo out
  587.         _bufferSize = bufferSize;
  588.         _callbackFrams = callbackFrams; 
  589.         _onSoundFrame = onSoundFrame;                                           // set parameters
  590.         for (i=0; i<bufferSize; i++) { _pipe[i]=_zero[i]=0; }                   // clear buffers
  591.     }
  592.     
  593.     // calculate index of logTable
  594.     static public function log(n:Number) : int {
  595.         return (n<0) ? ((n<-0.00390625) ? (((int(Math.log(-n) * -184.66496523 + 0.5) + 1) << 1) + 1) : 2047)
  596.                      : ((n> 0.00390625) ? (( int(Math.log( n) * -184.66496523 + 0.5) + 1) << 1)      : 2046);
  597.     }
  598.     // reset all oscillators
  599.     public function reset() : void {
  600.         for (var o:Osc=Osc._tm.n; o!=Osc._tm; o=o.inactivate().n) { o.fl = Osc._fl; }
  601.     }
  602.     // Returns stereo output as Vector.<Number>(bufferSize*2).
  603.     public function render() : Vector.<Number> {
  604.         var i:int, j:int, ph:int, dph:int, mod:int, sh:int, tl:int, lout:int, v:int, imax:int
  605.             osc:Osc, tm:Osc, l:Number, r:Number, wv:Vector.<int>, fm:Vector.<int>, base:Vector.<int>, 
  606.             out:Vector.<int>=_pipe, lt:Vector.<int>=_logTable, stereoOut:Vector.<Number> = _output;
  607.         imax = _bufferSize<<1;
  608.         for (i=0; i<imax; i++) stereoOut[i] = 0;
  609.         for (imax=_callbackFrams; imax<=_bufferSize; imax+=_callbackFrams) {
  610.             if (_onSoundFrame!=null) _onSoundFrame();
  611.             tm = Osc._tm;
  612.             for (osc=tm.n; osc!=tm; osc=osc.update()) {
  613.                 dph=_pitchTable[osc.pt]; ph=osc.ph; mod=osc.mod+10; sh=osc.sh; tl=osc.tl; wv=osc.wv;
  614.                 fm=(osc.mod==0)?_zero:_pipe; base=(osc.out!=2)?_zero:_pipe;
  615.                 for (i = imax-_callbackFrams; i < imax; i++) {
  616.                     v = ((ph + (fm[i] << mod))& 0x3ffffff) >> sh;
  617.                     lout = wv[v] + tl;
  618.                     out[i] = lt[lout] + base[i];
  619.                     ph = (ph + dph) & 0x3ffffff;
  620.                 }
  621.                 osc.ph = ph;
  622.                 if (osc.out==0) {
  623.                     l = _panTable[64-osc.pan] * 0.0001220703125;
  624.                     r = _panTable[64+osc.pan] * 0.0001220703125;
  625.                     for (i=imax-_callbackFrams, j=i*2; i<imax; i++) {
  626.                         stereoOut[j] += out[i]*l; j++;
  627.                         stereoOut[j] += out[i]*r; j++;
  628.                     }
  629.                 }
  630.             }
  631.         }
  632.         return stereoOut;
  633.     }
  634.     
  635.     // note on
  636.     public function noteOn(pitch:int, length:int=0, vol:Number=0.5, wave:int=0, decay:int=6, sweep:int=0, pan:int=0) : Osc {
  637.         var osc:Osc = Osc.alloc().reset();
  638.         osc.pt = pitch;
  639.         osc.len = length;
  640.         osc.tl = log(vol);
  641.         osc.ws = wave;
  642.         osc.dr = decay<<2;
  643.         osc.sw = sweep; 
  644.         osc.pan = pan;
  645.         return osc.activate(true);
  646.     }
  647. }
  648. class Osc {
  649.     // create new wave table and you can refer the table by '@' command.
  650.     static public function createTable(b:int) : Vector.<int> {
  651.         _w.push(new Vector.<int>(1<<b,true)); _s.push(26-b);
  652.         return _w[_w.length-1];
  653.     }
  654.     static public var _w:Array=[], _s:Array=[], _fl:Osc=new Osc(), _tm:Osc=new Osc();
  655.     static public function alloc():Osc{ if(_fl.p==_fl)return new Osc();var r:Osc=_fl.p;_fl.p=r.p;r.p.n=_fl;return r; }
  656.     public function into(x:Osc):Osc{ p=x.p;n=x;p.n=this;n.p=this;return this; }
  657.     public var p:Osc, n:Osc, fl:Osc, pt:int, len:int, ph:int;
  658.     public var tl:int, sw:int, dr:int, wv:Vector.<int>, sh:int, mod:int, out:int, pan:int;
  659.     public function set ws(t:int) : void { wv=_w[t]; sh=_s[t]; }
  660.     public function Osc() { p = n = this; }
  661.     public function update() : Osc { tl+=dr; pt+=sw; pt&=2047return (--len==0||tl>3328) ? (inactivate().n) : n; }
  662.     public function reset() : Osc { ph=0; pt=0; len=0; tl=3328; sw=0; dr=24; pan=0; ws=0; mod=0; out=0return this; }
  663.     public function activate(autoFree:Boolean=false) : Osc { into(_tm); fl=(autoFree)?_fl:nullreturn this; }
  664.     public function inactivate() : Osc { tl=3328if(!fl)return thisvar r:Osc=p; p.n=n; n.p=p; into(fl); return r; }
  665.     public function isActive() : Boolean { return (tl<3328); }
  666. }
noswf
Get Adobe Flash Player