public unsafe void Run()
        {
            var timer = new Timer();
            timer.start();

            // for fps info update
            int lastTick = timer.read_ms();
            int color = 0;
            int dir = 1;

            // create double buffered display
            var canvas = new Canvas();

            string infoString = "";

            while (true)
            {
                // fill screen with pixels
                for (UInt16 x = 0; x < 480; x++)
                {
                    for (UInt16 y = 0; y < 272; y++)
                    {
                        canvas.SetPixel(x, y, (UInt32)(0xFF000000 | (color << 16)));
                    }
                }

                // show info every couple of seconds
                if (timer.read_ms() - lastTick > 2000)
                {
                    // string.format broken?
                    //infoString = String.Format("FPS: {0} MEMAVAIL: {1} MEMALOC: {2}",
                    //    display.Fps,
                    //    Microsoft.Zelig.Runtime.MemoryManager.Instance.AvailableMemory,
                    //    Microsoft.Zelig.Runtime.MemoryManager.Instance.AllocatedMemory);

                    infoString = "FPS: " + canvas.Fps.ToString() + " MEMAVAIL: " + Microsoft.Zelig.Runtime.MemoryManager.Instance.AvailableMemory.ToString();

                    lastTick = timer.read_ms();
                }

                //canvas.DrawString(infoString, 0, 0);

                // fade in/out the pixel fill
                color += dir;

                if (color == 255)
                {
                    dir = -1;
                }
                else if (color == 0)
                {
                    dir = +1;
                }

                // show the back buffer
                canvas.Flip();
            }
        }
        public void Run()
        {
            var timer = new Timer();
            timer.start();

            // for fps info update
            int lastTick = timer.read_ms();

            // create double buffered display
            var canvas = new Canvas();
            var touch = new Touch();

            string infoString = "";

            while (true)
            {
                int touches = touch.GetTouchInfo();

                canvas.Clear(0xFFFFFFFF);

                for (int i = 0; i < touches; i++)
                {
                    canvas.DrawCircle((UInt16)Math.Max(50, Math.Min(480 - 50 - 1, touch.X[i])), (UInt16)Math.Max(50, Math.Min(272 - 50 - 1, touch.Y[i])), 50, 0xFFFF0000);
                }

                // show info every couple of seconds
                if (timer.read_ms() - lastTick > 2000)
                {
                    infoString = String.Format("FPS: {0} MEMAVAIL: {1} MEMALOC: {2}",
                        canvas.Fps,
                        Microsoft.Zelig.Runtime.MemoryManager.Instance.AvailableMemory,
                        Microsoft.Zelig.Runtime.MemoryManager.Instance.AllocatedMemory);

                    lastTick = timer.read_ms();
                }

                //canvas.DrawString(infoString, 0, 0);

                // show the back buffer
                canvas.Flip();
            }
        }
        public unsafe void Run()
        {
            var timer = new Timer();
            timer.start();

            // for fps info update
            int lastTick = timer.read_ms();

            string infoString = "";

            SDCardManager.Mount();

            _background = new Bitmap("BACK.DAT", 480, 272);
            _sprite = new Bitmap("SPRITE.DAT", 64, 64);
            _font = Font.LoadFromFile("DEJAVU.FNT");

            // create double buffered display
            var canvas = new Canvas();

            var sprites = new List<Sprite>();

            var r = new Random();

            for (int i = 0; i < 20; i++)
            {
                sprites.Add(new Sprite
                {
                    X = r.Next(480 - 64),
                    Y = r.Next(272 - 64),
                    Width = (int)_sprite.Width,
                    Height = (int)_sprite.Height,
                    Dx = r.Next(2) == 0 ? 2 : -2,
                    Dy = r.Next(2) == 0 ? 2 : -2
                });
            }

            while (true)
            {
                canvas.Clear(_background);

                foreach (var sprite in sprites)
                {
                    canvas.DrawBitmap(_sprite, 0, 0, sprite.X, sprite.Y, 64, 64);
                    sprite.Step(Canvas.ScreenWidth, Canvas.ScreenHeight);
                }

                // show info every couple of seconds
                if (timer.read_ms() - lastTick > 2000)
                {
                    // string.format broken?
                    //infoString = String.Format("FPS: {0} MEMAVAIL: {1} MEMALOC: {2}",
                    //    display.Fps,
                    //    Microsoft.Zelig.Runtime.MemoryManager.Instance.AvailableMemory,
                    //    Microsoft.Zelig.Runtime.MemoryManager.Instance.AllocatedMemory);

                    infoString = "FPS: " + canvas.Fps.ToString() + " MEMAVAIL: " + Microsoft.Zelig.Runtime.MemoryManager.Instance.AvailableMemory.ToString();

                    lastTick = timer.read_ms();
                }

                canvas.DrawString(infoString, 0, 0, _font);

                // show the back buffer
                canvas.Flip();
            }
        }