public GraphicsEssentials(string modFolder, IReloadedHooks hooks)
        {
            _config = new ConfigReadWriter(modFolder).FromJson();
            _defaultSettingsHook = new DefaultSettingsHook(_config.DefaultSettings, hooks);

            NativeResolutionPatcher.Patch(_config.Width, _config.Height);
            WindowStylePatcher.Patch(_config.BorderlessWindowed, _config.ResizableWindowed);

            if (_config.StupidlyFastLoadTimes)
            {
                LoadTimeHack.Patch();
            }

            if (_config.Disable2PFrameskip)
            {
                DisableFrameskipPatch.Patch();
            }

            if (_config.HighAspectRatioCrashFix)
            {
                _crashFixHook = new StageLoadCrashFixHook(hooks);
            }

            _clippingPlanesHook = new ClippingPlanesHook(_config.AspectRatioLimit, hooks);
            _aspectRatioHook    = new AspectRatioHook(_config.AspectRatioLimit, hooks);

            _resolutionVariablePatcher = new ResolutionVariablePatcher(_config.AspectRatioLimit);
            _renderHooks = new RenderHooks(_config.AspectRatioLimit, hooks);

            Task.Run(MessagePump);
        }
    public GraphicsEssentials(string modFolder, string configDirectory, IReloadedHooks hooks)
    {
        _configurator = new Configurator(configDirectory);
        _configurator.Migrate(modFolder, configDirectory);

        _config = _configurator.GetConfiguration <Config.Config>(0);
        _defaultSettingsHook = new DefaultSettingsHook(_config.DefaultSettings);

        NativeResolutionPatcher.Patch(_config.Width, _config.Height);
        WindowStylePatcher.Patch(_config.BorderlessWindowed, _config.ResizableWindowed);

        if (_config.StupidlyFastLoadTimes)
        {
            LoadTimeHack.Patch();
        }

        if (_config.Disable2PFrameskip)
        {
            DisableFrameskipPatch.Patch();
        }

        if (_config.HighAspectRatioCrashFix)
        {
            _crashPatch = new StageLoadCrashPatch();
        }

        if (_config.DontSlowdownOnFocusLost)
        {
            DontSlowdownOnFocusLoss.Patch();
        }

        _clippingPlanesHook = new ClippingPlanesHook(_config.AspectRatioLimit);
        _aspectRatioHook    = new AspectRatioHook(_config.AspectRatioLimit);

        _resolutionVariablePatcher = new ResolutionVariablePatcher();
        _renderHooks = new RenderHooks(_config.AspectRatioLimit, hooks);

        Task.Run(MessagePump);
        Task.Run(async() =>
        {
            while (Window.WindowHandle == IntPtr.Zero)
            {
                await Task.Delay(32);
            }

            int left = 0;
            int top  = 0;

            if (_config.CenterWindow)
            {
                var monitor = User32.MonitorFromWindow(Window.WindowHandle, User32.MonitorFlags.MONITOR_DEFAULTTONEAREST);
                var info    = new User32.MONITORINFO {
                    cbSize = (uint)Struct.GetSize <User32.MONITORINFO>()
                };
                if (User32.GetMonitorInfo(monitor, ref info))
                {
                    left += (info.rcMonitor.Width - _config.Width) / 2;
                    top  += (info.rcMonitor.Height - _config.Height) / 2;
                }
            }

            User32.MoveWindow(Window.WindowHandle, left, top, _config.Width, _config.Height, false);

            await Task.Delay(32);
            _resizeEventHook.ForceSizeChangeCheck();
        }).ConfigureAwait(false);
    }