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();
            }
        }
        public void Run(Control root)
        {
            SDCardManager.Mount();

            // load in the system font
            _systemFont = Font.LoadFromFile("DEJAVU.FNT");

            var timer = new Timer();
            timer.start();

            // for fps info update
            float lastDebugTime = 0;
            float lastUpdateTime = 0;

            string infoString = "";

            while (true)
            {
                FrameTime = timer.read();

                // fixed time step - both for update and draw
                if (FrameTime - lastUpdateTime >= DeltaTime)
                {
                    int touches = Touch.GetTouchInfo();

                    for (int i = 0; i < touches; i++)
                    {
                        // near a touch we have seen recently ?
                        var previous = _activeTouches.Find(x => Math.Abs(x.Position.X - Touch.X[i]) < TouchTrackTolerance &&
                                                                Math.Abs(x.Position.Y - Touch.Y[i]) < TouchTrackTolerance);

                        if (previous == null)
                        {
                            _nextTouchId++;

                            // remember this touch
                            _activeTouches.Add(new TouchInfo { Position = new Point((int)Touch.X[i], (int)Touch.Y[i]), LastSeenTime = FrameTime, Id = _nextTouchId });

                            // new touch so send message to root control
                            root.SendMessage(UIMessage.TouchStart, new TouchEventArgs(_nextTouchId, new Point((int)Touch.X[i], (int)Touch.Y[i])));
                        }
                        else
                        {
                            bool hasMoved = (Math.Abs(previous.Position.X - Touch.X[i]) > 0 || Math.Abs(previous.Position.Y - Touch.Y[i]) > 0);

                            // touch seen again - update for tracking
                            previous.Position = new Point((int)Touch.X[i], (int)Touch.Y[i]);
                            previous.LastSeenTime = FrameTime;

                            // moved at all ?
                            if (hasMoved)
                            {
                                root.SendMessage(UIMessage.TouchMove, new TouchEventArgs(previous.Id, previous.Position));
                            }
                        }
                    }

                    // get rid of old touches
                    for (int i = _activeTouches.Count - 1; i >= 0; i--)
                    {
                        if (FrameTime - _activeTouches[i].LastSeenTime > 0.1f)
                        {
                            root.SendMessage(UIMessage.TouchEnd, new TouchEventArgs(_activeTouches[i].Id, _activeTouches[i].Position));

                            _activeTouches.RemoveAt(i);
                        }
                    }

                    lastUpdateTime = FrameTime;

                    Display.Clear(0xFFFFFFFF);

                    root.Update(DeltaTime);
                    root.Draw();

                    if (ShowDebug)
                    {
                        // show debug info every couple of seconds
                        if (timer.read_ms() - lastDebugTime > 2.0f)
                        {
                            // 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: " + Display.Fps.ToString() + " MEMAVAIL: " + Microsoft.Zelig.Runtime.MemoryManager.Instance.AvailableMemory.ToString();

                            lastDebugTime = timer.read();
                        }

                        //Display.DrawString(infoString, 0, 0);
                    }

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