private void BlastCorpsViewer_MouseUp(object sender, MouseEventArgs e)
 {
     if (level != null && e.Button == System.Windows.Forms.MouseButtons.Left)
      {
     switch (Mode)
     {
        case MouseMode.Move:
           if (dragItem != null)
           {
              selectedItem = dragItem;
              OnSelectionChangedEvent(new SelectionChangedEventArgs(selectedItem, false, false));
              dragItem = null;
              Invalidate();
           }
           break;
        case MouseMode.Add:
           Int16 x = (Int16)levelX(e.X);
           Int16 z = (Int16)levelZ(e.Y);
           if (AddType == typeof(AmmoBox))
           {
              AmmoBox box = new AmmoBox(x, level.carrier.y, z, 0);
              selectedItem = box;
              level.ammoBoxes.Add(box);
           }
           else if (AddType == typeof(CommPoint))
           {
              CommPoint comm = new CommPoint(x, level.carrier.y, z, 0);
              selectedItem = comm;
              level.commPoints.Add(comm);
           }
           else if (AddType == typeof(RDU))
           {
              RDU rdu = new RDU(x, level.carrier.y, z);
              selectedItem = rdu;
              level.rdus.Add(rdu);
           }
           else if (AddType == typeof(TNTCrate))
           {
              TNTCrate tnt = new TNTCrate(x, level.carrier.y, z, 0, 0, 0, 0);
              selectedItem = tnt;
              level.tntCrates.Add(tnt);
           }
           else if (AddType == typeof(SquareBlock))
           {
              SquareBlock block = new SquareBlock(x, level.carrier.y, z, SquareBlock.Type.Block, SquareBlock.Shape.Square);
              selectedItem = block;
              level.squareBlocks.Add(block);
           }
           else if (AddType == typeof(Vehicle))
           {
              Vehicle vehicle = new Vehicle(0, x, level.carrier.y, z, 0);
              selectedItem = vehicle;
              level.vehicles.Add(vehicle);
           }
           else if (AddType == typeof(Building))
           {
              Building building = new Building(x, level.carrier.y, z, 0, 0, 0, 0, 0);
              selectedItem = building;
              level.buildings.Add(building);
           }
           OnSelectionChangedEvent(new SelectionChangedEventArgs(selectedItem, true, false));
           Invalidate();
           break;
     }
      }
 }
 // 0x3C: Square blocks and holes
 // [NN NN] {[XX XX] [YY YY] [ZZ ZZ] [T1] [T2] (CC CC) {[X1 X1] [Y1 Y1] [Z1 Z1]... [AA] [BB] [CC] [DD]}}
 private void decodeSquareBlocks(byte[] data)
 {
     uint start = BE.U32(data, 0x3C);
      uint end = BE.U32(data, 0x40);
      uint idx = start;
      while (end > idx)
      {
     UInt16 num = BE.U16(data, idx);
     // TODO: is this proper termination condition?
     if (num == 0)
     {
        break;
     }
     idx += 2;
     for (int g = 0; g < num; g++)
     {
        Int16 x, y, z;
        byte type1, type2;
        x = BE.I16(data, idx);
        y = BE.I16(data, idx + 2);
        z = BE.I16(data, idx + 4);
        type1 = data[idx + 6];
        type2 = data[idx + 7];
        SquareBlock block = new SquareBlock(x, y, z, type1, type2);
        squareBlocks.Add(block);
        idx += 8;
        if (block.type == SquareBlock.Type.Hole)
        {
           block.isCounted = BE.U16(data, idx) > 0;
           idx += 2;
           for (int i = 0; i < 8; i++)
           {
              Int16 x2, y2, z2, x3, y3, z3;
              x = BE.I16(data, idx);
              y = BE.I16(data, idx + 2);
              z = BE.I16(data, idx + 4);
              x2 = BE.I16(data, idx + 6);
              y2 = BE.I16(data, idx + 8);
              z2 = BE.I16(data, idx + 0xA);
              x3 = BE.I16(data, idx + 0xC);
              y3 = BE.I16(data, idx + 0xE);
              z3 = BE.I16(data, idx + 0x10);
              block.addNode(x, y, z, x2, y2, z2, x3, y3, z3, data, (int)(idx + 0x12));
              idx += 22;
           }
        }
     }
      }
 }
        void drawHole(SquareBlock block, Color color)
        {
            GL.Enable(EnableCap.LineSmooth);
             GL.Enable(EnableCap.Blend);
             GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
             GL.Hint(HintTarget.LineSmoothHint, HintMode.DontCare);
             GL.Enable(EnableCap.PolygonOffsetLine);
             GL.PolygonOffset(-1.0f, -1.0f);
             GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
             GL.LineWidth(1.0f);
             GL.Color3(color);

             GL.Begin(PrimitiveType.Triangles);
             foreach (SquareBlock.Node v in block.nodes)
             {
            GL.Vertex3((float)v.x[0], (float)v.y[0], (float)v.z[0]);
            GL.Vertex3((float)v.x[1], (float)v.y[1], (float)v.z[1]);
            GL.Vertex3((float)v.x[2], (float)v.y[2], (float)v.z[2]);
             }
             GL.End();

             GL.Disable(EnableCap.LineSmooth);
             GL.Disable(EnableCap.Blend);
             GL.Disable(EnableCap.PolygonOffsetLine);
        }