private void InternalUpdate(SAMTime timeVirtual, InputState state, SAMTime timeReal)
        {
            // Update Top Down  (Debug -> HUD -> Entities -> BG)
            // Render Bottom Up (BG -> Entities -> HUD -> Debug)

            DebugDisp.Update(timeReal, state);

            GameHUD.Update(timeReal, state);

            Entities.Update(timeVirtual, state);

            Background.Update(timeVirtual, state);

            UpdateAgents(timeVirtual, state);

            OnUpdate(timeVirtual, state);
        }
        private void InternalDraw(SAMTime gameTime, Rectangle?scissor)
        {
#if DEBUG
            FPSCounter.StartCycle(gameTime);
#endif
            VAdapterGame.Update();
            VAdapterHUD.Update();

            if (_clearScreenOnDraw)
            {
                Graphics.GraphicsDevice.Clear(Color.Magenta);
            }

            // Update Top Down  (Debug -> HUD -> Entities -> BG)
            // Render Bottom Up (BG -> Entities -> GPU_Particle -> HUD -> Debug)

            var bts = GetBaseTextureScale();
            var mat = Matrix.CreateTranslation(MapOffsetX, MapOffsetY, 0) * VAdapterGame.GetScaleMatrix();

            // ======== GAME =========

#if DEBUG
            if (_updateDebugSettings)
            {
                TIMING_DRAW_BATCH_GAME.Start();
            }
#endif

            TranslatedBatch.OnBegin(bts);
            if (scissor == null)
            {
                InternalBatch.Begin(transformMatrix: mat);
            }
            else
            {
                GraphicsDevice.ScissorRectangle = scissor.Value;
                InternalBatch.Begin(transformMatrix: mat, rasterizerState: new RasterizerState {
                    ScissorTestEnable = true
                });
            }
            try
            {
#if DEBUG
                if (_updateDebugSettings)
                {
                    TIMING_DRAW_BACKGROUND.Start();
                }
#endif
                Background.Draw(TranslatedBatch);
#if DEBUG
                if (_updateDebugSettings)
                {
                    TIMING_DRAW_BACKGROUND.Stop();
                }
#endif

#if DEBUG
                if (_updateDebugSettings)
                {
                    TIMING_DRAW_ENTITIES.Start();
                }
#endif
                Entities.Draw(TranslatedBatch);
#if DEBUG
                if (_updateDebugSettings)
                {
                    TIMING_DRAW_ENTITIES.Stop();
                }
#endif

#if DEBUG
                if (_updateDebugSettings)
                {
                    TIMING_DRAW_SCREEN.Start();
                }
#endif
                OnDrawGame(TranslatedBatch);
#if DEBUG
                if (_updateDebugSettings)
                {
                    TIMING_DRAW_SCREEN.Stop();
                }
#endif

#if DEBUG
                if (_updateDebugSettings)
                {
                    TIMING_DRAW_BACKGROUNDPOST.Start();
                }
#endif
                Background.DrawOverlay(TranslatedBatch);
#if DEBUG
                if (_updateDebugSettings)
                {
                    TIMING_DRAW_BACKGROUNDPOST.Stop();
                }
#endif

#if DEBUG
                DrawScreenDebug(TranslatedBatch);
#endif
            }
            finally
            {
                InternalBatch.End();
                TranslatedBatch.OnEnd();
            }

#if DEBUG
            if (_updateDebugSettings)
            {
                TIMING_DRAW_BATCH_GAME.Stop();
            }
#endif

            // ======== STUFF ========

#if DEBUG
            if (_updateDebugSettings)
            {
                TIMING_DRAW_ENTITIESPOST.Start();
            }
#endif
            Entities.PostDraw();
#if DEBUG
            if (_updateDebugSettings)
            {
                TIMING_DRAW_ENTITIESPOST.Stop();
            }
#endif

            // ======== HUD ==========

#if DEBUG
            if (_updateDebugSettings)
            {
                TIMING_DRAW_BATCH_HUD.Start();
            }
#endif

            FixedBatch.OnBegin(bts);

            if (scissor == null)
            {
                InternalBatch.Begin(transformMatrix: VAdapterHUD.GetScaleMatrix());
            }
            else
            {
                GraphicsDevice.ScissorRectangle = scissor.Value;
                InternalBatch.Begin(transformMatrix: VAdapterHUD.GetScaleMatrix(), rasterizerState: new RasterizerState {
                    ScissorTestEnable = true
                });
            }
            try
            {
#if DEBUG
                if (_updateDebugSettings)
                {
                    TIMING_DRAW_HUD.Start();
                }
#endif
                GameHUD.Draw(FixedBatch);
#if DEBUG
                using (FixedBatch.BeginDebugDraw()) DebugMap.Draw(FixedBatch);
                if (_updateDebugSettings)
                {
                    TIMING_DRAW_HUD.Stop();
                }
#endif
                OnDrawHUD(TranslatedBatch);
            }
            finally
            {
                InternalBatch.End();
                FixedBatch.OnEnd();
            }

#if DEBUG
            if (_updateDebugSettings)
            {
                TIMING_DRAW_BATCH_HUD.Stop();
            }
#endif

            // =======================

#if DEBUG
            if (_updateDebugSettings)
            {
                TIMING_DRAW_DEBUGSCREEN.Start();
            }
            using (FixedBatch.BeginDebugDraw())
                using (TranslatedBatch.BeginDebugDraw())
                {
                    Entities.DrawOuterDebug();
                    DebugDisp.Draw();
                }
            if (_updateDebugSettings)
            {
                TIMING_DRAW_DEBUGSCREEN.Stop();
            }
#endif

#if DEBUG
            if (_updateDebugSettings)
            {
                TIMING_DRAW_PROXIES.Start();
            }
#endif
            foreach (var proxy in _proxyScreens)
            {
                if (proxy.ProxyTargetBounds.IsEmpty)
                {
                    continue;
                }
                proxy.Proxy._clearScreenOnDraw   = false;
                proxy.Proxy._updateDebugSettings = false;

                proxy.Proxy.InternalDraw(gameTime, proxy.ProxyTargetBounds.CeilOutwards());
            }
#if DEBUG
            if (_updateDebugSettings)
            {
                TIMING_DRAW_PROXIES.Stop();
            }
#endif

#if DEBUG
            FPSCounter.EndCycle();
#endif
        }
 public virtual void Draw(SAMTime gameTime)
 {
     InternalDraw(gameTime, null);
 }