Example #1
0
		public DisplayManager(PresentationPanel presentationPanel)
		{
			GL = GlobalWin.GL;
			this.presentationPanel = presentationPanel;
			GraphicsControl = this.presentationPanel.GraphicsControl;
			CR_GraphicsControl = GlobalWin.GLManager.GetContextForGraphicsControl(GraphicsControl);

			//it's sort of important for these to be initialized to something nonzero
			currEmuWidth = currEmuHeight = 1;

			if (GL is BizHawk.Bizware.BizwareGL.Drivers.OpenTK.IGL_TK)
				Renderer = new GuiRenderer(GL);
			else if (GL is BizHawk.Bizware.BizwareGL.Drivers.SlimDX.IGL_SlimDX9)
				Renderer = new GuiRenderer(GL);
			else
				Renderer = new GDIPlusGuiRenderer((BizHawk.Bizware.BizwareGL.Drivers.GdiPlus.IGL_GdiPlus)GL);

			VideoTextureFrugalizer = new TextureFrugalizer(GL);

			ShaderChainFrugalizers = new RenderTargetFrugalizer[16]; //hacky hardcoded limit.. need some other way to manage these
			for (int i = 0; i < 16; i++)
			{
				ShaderChainFrugalizers[i] = new RenderTargetFrugalizer(GL);
			}

			using (var xml = typeof(Program).Assembly.GetManifestResourceStream("BizHawk.Client.EmuHawk.Resources.courier16px.fnt"))
			using (var tex = typeof(Program).Assembly.GetManifestResourceStream("BizHawk.Client.EmuHawk.Resources.courier16px_0.png"))
				TheOneFont = new StringRenderer(GL, xml, tex);

			using (var gens = typeof(Program).Assembly.GetManifestResourceStream("BizHawk.Client.EmuHawk.Resources.gens.ttf"))
				LoadCustomFont(gens);
			using (var fceux = typeof(Program).Assembly.GetManifestResourceStream("BizHawk.Client.EmuHawk.Resources.fceux.ttf"))
				LoadCustomFont(fceux);

			if (GL is BizHawk.Bizware.BizwareGL.Drivers.OpenTK.IGL_TK || GL is BizHawk.Bizware.BizwareGL.Drivers.SlimDX.IGL_SlimDX9)
			{
				var fiHq2x = new FileInfo(Path.Combine(PathManager.GetExeDirectoryAbsolute(), "Shaders/BizHawk/hq2x.cgp"));
				if (fiHq2x.Exists)
					using (var stream = fiHq2x.OpenRead())
						ShaderChain_hq2x = new Filters.RetroShaderChain(GL, new Filters.RetroShaderPreset(stream), Path.Combine(PathManager.GetExeDirectoryAbsolute(), "Shaders/BizHawk"));
				var fiScanlines = new FileInfo(Path.Combine(PathManager.GetExeDirectoryAbsolute(), "Shaders/BizHawk/BizScanlines.cgp"));
				if (fiScanlines.Exists)
					using (var stream = fiScanlines.OpenRead())
						ShaderChain_scanlines = new Filters.RetroShaderChain(GL, new Filters.RetroShaderPreset(stream), Path.Combine(PathManager.GetExeDirectoryAbsolute(), "Shaders/BizHawk"));
				string bicubic_path = "Shaders/BizHawk/bicubic-fast.cgp";
				if(GL is BizHawk.Bizware.BizwareGL.Drivers.SlimDX.IGL_SlimDX9)
					bicubic_path = "Shaders/BizHawk/bicubic-normal.cgp";
				var fiBicubic = new FileInfo(Path.Combine(PathManager.GetExeDirectoryAbsolute(), bicubic_path));
				if (fiBicubic.Exists)
					using (var stream = fiBicubic.Open(FileMode.Open, FileAccess.Read, FileShare.Read))
						ShaderChain_bicubic = new Filters.RetroShaderChain(GL, new Filters.RetroShaderPreset(stream), Path.Combine(PathManager.GetExeDirectoryAbsolute(), "Shaders/BizHawk"));
			}

			LuaSurfaceSets["emu"] = new SwappableDisplaySurfaceSet();
			LuaSurfaceSets["native"] = new SwappableDisplaySurfaceSet();
			LuaSurfaceFrugalizers["emu"] = new TextureFrugalizer(GL);
			LuaSurfaceFrugalizers["native"] = new TextureFrugalizer(GL);

			RefreshUserShader();
		}
Example #2
0
 public void RefreshUserShader()
 {
     ShaderChain_user?.Dispose();
     if (File.Exists(Global.Config.DispUserFilterPath))
     {
         var fi = new FileInfo(Global.Config.DispUserFilterPath);
         using var stream = fi.OpenRead();
         ShaderChain_user = new Filters.RetroShaderChain(GL, new Filters.RetroShaderPreset(stream), Path.GetDirectoryName(Global.Config.DispUserFilterPath));
     }
 }
Example #3
0
 void AppendRetroShaderChain(FilterProgram program, string name, Filters.RetroShaderChain retroChain, Dictionary <string, object> properties)
 {
     for (int i = 0; i < retroChain.Passes.Length; i++)
     {
         var    pass  = retroChain.Passes[i];
         var    rsp   = new Filters.RetroShaderPass(retroChain, i);
         string fname = $"{name}[{i}]";
         program.AddFilter(rsp, fname);
         rsp.Parameters = properties;
     }
 }
Example #4
0
        public DisplayManager(PresentationPanel presentationPanel)
        {
            GL = GlobalWin.GL;
            this.presentationPanel = presentationPanel;
            GraphicsControl        = this.presentationPanel.GraphicsControl;
            CR_GraphicsControl     = GlobalWin.GLManager.GetContextForGraphicsControl(GraphicsControl);

            //it's sort of important for these to be initialized to something nonzero
            currEmuWidth = currEmuHeight = 1;

            Renderer = new GuiRenderer(GL);

            VideoTextureFrugalizer = new TextureFrugalizer(GL);

            ShaderChainFrugalizers = new RenderTargetFrugalizer[16];             //hacky hardcoded limit.. need some other way to manage these
            for (int i = 0; i < 16; i++)
            {
                ShaderChainFrugalizers[i] = new RenderTargetFrugalizer(GL);
            }

            using (var xml = typeof(Program).Assembly.GetManifestResourceStream("BizHawk.Client.EmuHawk.Resources.courier16px.fnt"))
                using (var tex = typeof(Program).Assembly.GetManifestResourceStream("BizHawk.Client.EmuHawk.Resources.courier16px_0.png"))
                    TheOneFont = new StringRenderer(GL, xml, tex);

            var fiHq2x = new FileInfo(Path.Combine(PathManager.GetExeDirectoryAbsolute(), "Shaders/BizHawk/hq2x.cgp"));

            if (fiHq2x.Exists)
            {
                using (var stream = fiHq2x.OpenRead())
                    ShaderChain_hq2x = new Filters.RetroShaderChain(GL, new Filters.RetroShaderPreset(stream), Path.Combine(PathManager.GetExeDirectoryAbsolute(), "Shaders/BizHawk"));
            }
            var fiScanlines = new FileInfo(Path.Combine(PathManager.GetExeDirectoryAbsolute(), "Shaders/BizHawk/BizScanlines.cgp"));

            if (fiScanlines.Exists)
            {
                using (var stream = fiScanlines.OpenRead())
                    ShaderChain_scanlines = new Filters.RetroShaderChain(GL, new Filters.RetroShaderPreset(stream), Path.Combine(PathManager.GetExeDirectoryAbsolute(), "Shaders/BizHawk"));
            }
            var fiBicubic = new FileInfo(Path.Combine(PathManager.GetExeDirectoryAbsolute(), "Shaders/BizHawk/bicubic-fast.cgp"));

            if (fiBicubic.Exists)
            {
                using (var stream = fiBicubic.OpenRead())
                    ShaderChain_bicubic = new Filters.RetroShaderChain(GL, new Filters.RetroShaderPreset(stream), Path.Combine(PathManager.GetExeDirectoryAbsolute(), "Shaders/BizHawk"));
            }

            LuaSurfaceSets["emu"]           = new SwappableDisplaySurfaceSet();
            LuaSurfaceSets["native"]        = new SwappableDisplaySurfaceSet();
            LuaSurfaceFrugalizers["emu"]    = new TextureFrugalizer(GL);
            LuaSurfaceFrugalizers["native"] = new TextureFrugalizer(GL);

            RefreshUserShader();
        }
Example #5
0
		public DisplayManager(PresentationPanel presentationPanel)
		{
			GL = GlobalWin.GL;
			this.presentationPanel = presentationPanel;
			GraphicsControl = this.presentationPanel.GraphicsControl;
			CR_GraphicsControl = GlobalWin.GLManager.GetContextForGraphicsControl(GraphicsControl);

			//it's sort of important for these to be initialized to something nonzero
			currEmuWidth = currEmuHeight = 1;

			Renderer = new GuiRenderer(GL);

			VideoTextureFrugalizer = new TextureFrugalizer(GL);

			ShaderChainFrugalizers = new RenderTargetFrugalizer[16]; //hacky hardcoded limit.. need some other way to manage these
			for (int i = 0; i < 16; i++)
			{
				ShaderChainFrugalizers[i] = new RenderTargetFrugalizer(GL);
			}

			using (var xml = typeof(Program).Assembly.GetManifestResourceStream("BizHawk.Client.EmuHawk.Resources.courier16px.fnt"))
			using (var tex = typeof(Program).Assembly.GetManifestResourceStream("BizHawk.Client.EmuHawk.Resources.courier16px_0.png"))
				TheOneFont = new StringRenderer(GL, xml, tex);

			var fiHq2x = new FileInfo(Path.Combine(PathManager.GetExeDirectoryAbsolute(),"Shaders/BizHawk/hq2x.cgp"));
			if(fiHq2x.Exists)
				using(var stream = fiHq2x.OpenRead())
					ShaderChain_hq2x = new Filters.RetroShaderChain(GL, new Filters.RetroShaderPreset(stream), Path.Combine(PathManager.GetExeDirectoryAbsolute(), "Shaders/BizHawk"));
			var fiScanlines = new FileInfo(Path.Combine(PathManager.GetExeDirectoryAbsolute(), "Shaders/BizHawk/BizScanlines.cgp"));
			if (fiScanlines.Exists)
				using (var stream = fiScanlines.OpenRead())
					ShaderChain_scanlines = new Filters.RetroShaderChain(GL, new Filters.RetroShaderPreset(stream), Path.Combine(PathManager.GetExeDirectoryAbsolute(), "Shaders/BizHawk"));
			var fiBicubic = new FileInfo(Path.Combine(PathManager.GetExeDirectoryAbsolute(), "Shaders/BizHawk/bicubic-fast.cgp"));
			if (fiBicubic.Exists)
				using (var stream = fiBicubic.OpenRead())
					ShaderChain_bicubic = new Filters.RetroShaderChain(GL, new Filters.RetroShaderPreset(stream), Path.Combine(PathManager.GetExeDirectoryAbsolute(), "Shaders/BizHawk"));

			LuaSurfaceSets["emu"] = new SwappableDisplaySurfaceSet();
			LuaSurfaceSets["native"] = new SwappableDisplaySurfaceSet();
			LuaSurfaceFrugalizers["emu"] = new TextureFrugalizer(GL);
			LuaSurfaceFrugalizers["native"] = new TextureFrugalizer(GL);

			RefreshUserShader();
		}
Example #6
0
 public RetroShaderPass(RetroShaderChain RSC, int index)
 {
     this.RSC = RSC;
     this.RSI = index;
     this.SP  = RSC.Passes[index];
 }
Example #7
0
 public RetroShaderPass(RetroShaderChain rsc, int index)
 {
     _rsc = rsc;
     _rsi = index;
     _sp  = _rsc.Passes[index];
 }
Example #8
0
        FilterProgram BuildDefaultChain(Size chainInSize, Size chainOutSize, bool includeOSD)
        {
            // select user special FX shader chain
            var selectedChainProperties = new Dictionary <string, object>();

            Filters.RetroShaderChain selectedChain = null;
            if (Global.Config.TargetDisplayFilter == 1 && ShaderChain_hq2x != null && ShaderChain_hq2x.Available)
            {
                selectedChain = ShaderChain_hq2x;
            }

            if (Global.Config.TargetDisplayFilter == 2 && ShaderChain_scanlines != null && ShaderChain_scanlines.Available)
            {
                selectedChain = ShaderChain_scanlines;
                selectedChainProperties["uIntensity"] = 1.0f - Global.Config.TargetScanlineFilterIntensity / 256.0f;
            }

            if (Global.Config.TargetDisplayFilter == 3 && ShaderChain_user != null && ShaderChain_user.Available)
            {
                selectedChain = ShaderChain_user;
            }

            var fPresent = new Filters.FinalPresentation(chainOutSize);
            var fInput   = new Filters.SourceImage(chainInSize);
            var fOSD     = new Filters.OSD();

            fOSD.RenderCallback = () =>
            {
                if (!includeOSD)
                {
                    return;
                }

                var size = fOSD.FindInput().SurfaceFormat.Size;
                Renderer.Begin(size.Width, size.Height);
                var myBlitter = new MyBlitter(this)
                {
                    ClipBounds = new Rectangle(0, 0, size.Width, size.Height)
                };
                Renderer.SetBlendState(GL.BlendNormal);
                GlobalWin.OSD.Begin(myBlitter);
                GlobalWin.OSD.DrawScreenInfo(myBlitter);
                GlobalWin.OSD.DrawMessages(myBlitter);
                Renderer.End();
            };

            var chain = new FilterProgram();

            //add the first filter, encompassing output from the emulator core
            chain.AddFilter(fInput, "input");

            // if a non-zero padding is required, add a filter to allow for that
            // note, we have two sources of padding right now.. one can come from the VideoProvider and one from the user.
            // we're combining these now and just using black, for sake of being lean, despite the discussion below:
            // keep in mind, the VideoProvider design in principle might call for another color.
            // we haven't really been using this very hard, but users will probably want black there (they could fill it to another color if needed tho)
            var padding = CalculateCompleteContentPadding(true, true);

            if (padding.Vertical != 0 || padding.Horizontal != 0)
            {
                // TODO - add another filter just for this, its cumbersome to use final presentation... I think. but maybe there's enough similarities to justify it.
                Size size = chainInSize;
                size.Width  += padding.Horizontal;
                size.Height += padding.Vertical;
                Filters.FinalPresentation fPadding = new Filters.FinalPresentation(size);
                chain.AddFilter(fPadding, "padding");
                fPadding.GuiRenderer    = Renderer;
                fPadding.GL             = GL;
                fPadding.Config_PadOnly = true;
                fPadding.Padding        = padding;
            }

            //add lua layer 'emu'
            AppendLuaLayer(chain, "emu");

            if (Global.Config.DispPrescale != 1)
            {
                var fPrescale = new Filters.PrescaleFilter()
                {
                    Scale = Global.Config.DispPrescale
                };
                chain.AddFilter(fPrescale, "user_prescale");
            }

            // add user-selected retro shader
            if (selectedChain != null)
            {
                AppendRetroShaderChain(chain, "retroShader", selectedChain, selectedChainProperties);
            }

            // AutoPrescale makes no sense for a None final filter
            if (Global.Config.DispAutoPrescale && Global.Config.DispFinalFilter != (int)Filters.FinalPresentation.eFilterOption.None)
            {
                var apf = new Filters.AutoPrescaleFilter();
                chain.AddFilter(apf, "auto_prescale");
            }

            //choose final filter
            var finalFilter = Filters.FinalPresentation.eFilterOption.None;

            if (Global.Config.DispFinalFilter == 1)
            {
                finalFilter = Filters.FinalPresentation.eFilterOption.Bilinear;
            }

            if (Global.Config.DispFinalFilter == 2)
            {
                finalFilter = Filters.FinalPresentation.eFilterOption.Bicubic;
            }

            //if bicubic is selected and unavailable, don't use it. use bilinear instead I guess
            if (finalFilter == Filters.FinalPresentation.eFilterOption.Bicubic)
            {
                if (ShaderChain_bicubic == null || !ShaderChain_bicubic.Available)
                {
                    finalFilter = Filters.FinalPresentation.eFilterOption.Bilinear;
                }
            }

            fPresent.FilterOption = finalFilter;

            // now if bicubic is chosen, insert it
            if (finalFilter == Filters.FinalPresentation.eFilterOption.Bicubic)
            {
                AppendRetroShaderChain(chain, "bicubic", ShaderChain_bicubic, null);
            }

            // add final presentation
            chain.AddFilter(fPresent, "presentation");

            //add lua layer 'native'
            AppendLuaLayer(chain, "native");

            // and OSD goes on top of that
            // TODO - things break if this isn't present (the final presentation filter gets messed up when used with prescaling)
            // so, always include it (we'll handle this flag in the callback to do no rendering)
            //if (includeOSD)
            chain.AddFilter(fOSD, "osd");

            return(chain);
        }
Example #9
0
        FilterProgram BuildDefaultChain(Size chain_insize, Size chain_outsize, bool includeOSD)
        {
            //select user special FX shader chain
            Dictionary <string, object> selectedChainProperties = new Dictionary <string, object>();

            Filters.RetroShaderChain selectedChain = null;
            if (Global.Config.TargetDisplayFilter == 1 && ShaderChain_hq2x != null && ShaderChain_hq2x.Available)
            {
                selectedChain = ShaderChain_hq2x;
            }
            if (Global.Config.TargetDisplayFilter == 2 && ShaderChain_scanlines != null && ShaderChain_scanlines.Available)
            {
                //shader.Pipeline["uIntensity"].Set(1.0f - Global.Config.TargetScanlineFilterIntensity / 256.0f);
                selectedChain = ShaderChain_scanlines;
                selectedChainProperties["uIntensity"] = 1.0f - Global.Config.TargetScanlineFilterIntensity / 256.0f;
            }
            if (Global.Config.TargetDisplayFilter == 3 && ShaderChain_user != null && ShaderChain_user.Available)
            {
                selectedChain = ShaderChain_user;
            }

            Filters.FinalPresentation fPresent = new Filters.FinalPresentation(chain_outsize);
            Filters.SourceImage       fInput   = new Filters.SourceImage(chain_insize);
            Filters.OSD fOSD = new Filters.OSD();
            fOSD.RenderCallback = () =>
            {
                if (!includeOSD)
                {
                    return;
                }
                var size = fOSD.FindInput().SurfaceFormat.Size;
                Renderer.Begin(size.Width, size.Height);
                MyBlitter myBlitter = new MyBlitter(this);
                myBlitter.ClipBounds = new Rectangle(0, 0, size.Width, size.Height);
                Renderer.SetBlendState(GL.BlendNormal);
                GlobalWin.OSD.Begin(myBlitter);
                GlobalWin.OSD.DrawScreenInfo(myBlitter);
                GlobalWin.OSD.DrawMessages(myBlitter);
                Renderer.End();
            };

            var chain = new FilterProgram();

            //add the first filter, encompassing output from the emulator core
            chain.AddFilter(fInput, "input");

            //add lua layer 'emu'
            AppendLuaLayer(chain, "emu");

            //add user-selected retro shader
            if (selectedChain != null)
            {
                AppendRetroShaderChain(chain, "retroShader", selectedChain, selectedChainProperties);
            }

            //choose final filter
            Filters.FinalPresentation.eFilterOption finalFilter = Filters.FinalPresentation.eFilterOption.None;
            if (Global.Config.DispFinalFilter == 1)
            {
                finalFilter = Filters.FinalPresentation.eFilterOption.Bilinear;
            }
            if (Global.Config.DispFinalFilter == 2)
            {
                finalFilter = Filters.FinalPresentation.eFilterOption.Bicubic;
            }
            //if bicubic is selected and unavailable, dont use it
            if (!ShaderChain_bicubic.Available && fPresent.FilterOption == Filters.FinalPresentation.eFilterOption.Bicubic)
            {
                finalFilter = Filters.FinalPresentation.eFilterOption.None;
            }
            fPresent.FilterOption = finalFilter;

            //now if bicubic is chosen, insert it
            if (finalFilter == Filters.FinalPresentation.eFilterOption.Bicubic)
            {
                AppendRetroShaderChain(chain, "bicubic", ShaderChain_bicubic, null);
            }

            //add final presentation
            chain.AddFilter(fPresent, "presentation");

            //add lua layer 'native'
            AppendLuaLayer(chain, "native");

            //and OSD goes on top of that
            //TODO - things break if this isnt present (the final presentation filter gets messed up)
            //so, always include it (we'll handle this flag in the callback to do no rendering)
            //if (includeOSD)
            chain.AddFilter(fOSD, "osd");

            return(chain);
        }
Example #10
0
		public void RefreshUserShader()
		{
			if (ShaderChain_user != null)
				ShaderChain_user.Dispose();
			if (File.Exists(Global.Config.DispUserFilterPath))
			{
				var fi = new FileInfo(Global.Config.DispUserFilterPath);
				using (var stream = fi.OpenRead())
					ShaderChain_user = new Filters.RetroShaderChain(GL, new Filters.RetroShaderPreset(stream), Path.GetDirectoryName(Global.Config.DispUserFilterPath));
			}
		}
Example #11
0
		public RetroShaderPass(RetroShaderChain RSC, int index)
		{
			this.RSC = RSC;
			this.RSI = index;
			this.SP = RSC.Passes[index];
		}
Example #12
0
        public DisplayManager(PresentationPanel presentationPanel)
        {
            GL = GlobalWin.GL;
            this.presentationPanel = presentationPanel;
            GraphicsControl        = this.presentationPanel.GraphicsControl;
            CR_GraphicsControl     = GlobalWin.GLManager.GetContextForGraphicsControl(GraphicsControl);

            //it's sort of important for these to be initialized to something nonzero
            currEmuWidth = currEmuHeight = 1;

            if (GL is BizHawk.Bizware.BizwareGL.Drivers.OpenTK.IGL_TK)
            {
                Renderer = new GuiRenderer(GL);
            }
            else if (GL is BizHawk.Bizware.BizwareGL.Drivers.SlimDX.IGL_SlimDX9)
            {
                Renderer = new GuiRenderer(GL);
            }
            else
            {
                Renderer = new GDIPlusGuiRenderer((BizHawk.Bizware.BizwareGL.Drivers.GdiPlus.IGL_GdiPlus)GL);
            }

            VideoTextureFrugalizer = new TextureFrugalizer(GL);

            ShaderChainFrugalizers = new RenderTargetFrugalizer[16];             //hacky hardcoded limit.. need some other way to manage these
            for (int i = 0; i < 16; i++)
            {
                ShaderChainFrugalizers[i] = new RenderTargetFrugalizer(GL);
            }

            using (var xml = typeof(Program).Assembly.GetManifestResourceStream("BizHawk.Client.EmuHawk.Resources.courier16px.fnt"))
                using (var tex = typeof(Program).Assembly.GetManifestResourceStream("BizHawk.Client.EmuHawk.Resources.courier16px_0.png"))
                    TheOneFont = new StringRenderer(GL, xml, tex);

            using (var gens = typeof(Program).Assembly.GetManifestResourceStream("BizHawk.Client.EmuHawk.Resources.gens.ttf"))
                LoadCustomFont(gens);
            using (var fceux = typeof(Program).Assembly.GetManifestResourceStream("BizHawk.Client.EmuHawk.Resources.fceux.ttf"))
                LoadCustomFont(fceux);

            if (GL is BizHawk.Bizware.BizwareGL.Drivers.OpenTK.IGL_TK || GL is BizHawk.Bizware.BizwareGL.Drivers.SlimDX.IGL_SlimDX9)
            {
                var fiHq2x = new FileInfo(Path.Combine(PathManager.GetExeDirectoryAbsolute(), "Shaders/BizHawk/hq2x.cgp"));
                if (fiHq2x.Exists)
                {
                    using (var stream = fiHq2x.OpenRead())
                        ShaderChain_hq2x = new Filters.RetroShaderChain(GL, new Filters.RetroShaderPreset(stream), Path.Combine(PathManager.GetExeDirectoryAbsolute(), "Shaders/BizHawk"));
                }
                var fiScanlines = new FileInfo(Path.Combine(PathManager.GetExeDirectoryAbsolute(), "Shaders/BizHawk/BizScanlines.cgp"));
                if (fiScanlines.Exists)
                {
                    using (var stream = fiScanlines.OpenRead())
                        ShaderChain_scanlines = new Filters.RetroShaderChain(GL, new Filters.RetroShaderPreset(stream), Path.Combine(PathManager.GetExeDirectoryAbsolute(), "Shaders/BizHawk"));
                }
                string bicubic_path = "Shaders/BizHawk/bicubic-fast.cgp";
                if (GL is BizHawk.Bizware.BizwareGL.Drivers.SlimDX.IGL_SlimDX9)
                {
                    bicubic_path = "Shaders/BizHawk/bicubic-normal.cgp";
                }
                var fiBicubic = new FileInfo(Path.Combine(PathManager.GetExeDirectoryAbsolute(), bicubic_path));
                if (fiBicubic.Exists)
                {
                    using (var stream = fiBicubic.Open(FileMode.Open, FileAccess.Read, FileShare.Read))
                        ShaderChain_bicubic = new Filters.RetroShaderChain(GL, new Filters.RetroShaderPreset(stream), Path.Combine(PathManager.GetExeDirectoryAbsolute(), "Shaders/BizHawk"));
                }
            }

            LuaSurfaceSets["emu"]           = new SwappableDisplaySurfaceSet();
            LuaSurfaceSets["native"]        = new SwappableDisplaySurfaceSet();
            LuaSurfaceFrugalizers["emu"]    = new TextureFrugalizer(GL);
            LuaSurfaceFrugalizers["native"] = new TextureFrugalizer(GL);

            RefreshUserShader();
        }