Пример #1
0
        public void Render(uint adr, bool call = false, OpenGLHelpers.DisplayListEx gldl = null)
        {
            try
            {
                ActiveGLDL.Push(gldl);

                /* Set some defaults */
                if (!call)
                {
                    GL.DepthMask(true);
                    if (OpenGLHelpers.Initialization.SupportsFunction("glGenProgramsARB"))
                    {
                        GL.Disable((EnableCap)All.FragmentProgram);
                    }
                    if (OpenGLHelpers.Initialization.SupportsFunction("glCreateShader"))
                    {
                        GL.UseProgram(0);
                    }

                    PrimColor = EnvColor = new Color4(0.5f, 0.5f, 0.5f, 0.5f);

                    /* If emulating combiner, set more defaults / load values */
                    if (Configuration.CombinerType == CombinerTypes.ArbCombiner)
                    {
                        GL.Arb.BindProgram(AssemblyProgramTargetArb.FragmentProgram, 0);
                        GL.Arb.ProgramEnvParameter4(AssemblyProgramTargetArb.FragmentProgram, 0, PrimColor.R, PrimColor.G, PrimColor.B, PrimColor.A);
                        GL.Arb.ProgramEnvParameter4(AssemblyProgramTargetArb.FragmentProgram, 1, EnvColor.R, EnvColor.G, EnvColor.B, EnvColor.A);
                    }

                    /* Clear out texture units */
                    for (int i = 0; i < (OpenGLHelpers.Initialization.SupportsFunction("glActiveTextureARB") ? 2 : 1); i++)
                    {
                        OpenGLHelpers.Initialization.ActiveTextureChecked(TextureUnit.Texture0 + i);
                        GL.BindTexture(TextureTarget.Texture2D, OpenGLHelpers.MiscDrawingHelpers.DummyTextureID);
                    }
                }

                /* Ucode interpreter starts here */
                byte seg = (byte)(adr >> 24);
                adr &= 0xFFFFFF;

                byte[] segdata = (byte[])ROM.SegmentMapping[seg];

                while (adr < segdata.Length)
                {
                    byte cmd = segdata[adr];

                    /* EndDL */
                    if (cmd == (byte)General.UcodeCmds.ENDDL)
                    {
                        break;
                    }

                    /* Try to detect macros if any are defined */
                    inmacro = false;
                    if (macros != null)
                    {
                        foreach (Macro m in macros)
                        {
                            if (adr + ((m.Commands.Length + 3) * 8) > segdata.Length)
                            {
                                break;
                            }

                            General.UcodeCmds[] nextcmd = new General.UcodeCmds[m.Commands.Length];
                            uint[] nextw0 = new uint[nextcmd.Length + 2];
                            uint[] nextw1 = new uint[nextcmd.Length + 2];

                            for (int i = 0; i < nextw0.Length; i++)
                            {
                                nextw0[i] = Endian.SwapUInt32(BitConverter.ToUInt32(segdata, (int)adr + (i * 8)));
                                nextw1[i] = Endian.SwapUInt32(BitConverter.ToUInt32(segdata, (int)adr + (i * 8) + 4));
                                if (i < m.Commands.Length)
                                {
                                    nextcmd[i] = (General.UcodeCmds)(nextw0[i] >> 24);
                                }
                            }

                            if (inmacro = (Enumerable.SequenceEqual(m.Commands, nextcmd)))
                            {
                                m.Function(nextw0, nextw1);
                                adr += (uint)(m.Commands.Length * 8);
                                break;
                            }
                        }
                    }

                    /* No macro detected */
                    if (!inmacro)
                    {
                        /* Execute command */
                        ucodecmds[cmd](Endian.SwapUInt32(BitConverter.ToUInt32(segdata, (int)adr)), Endian.SwapUInt32(BitConverter.ToUInt32(segdata, (int)adr + 4)));
                        adr += 8;

                        /* Texture loading hack; if SetCombine OR LoadBlock command detected, try loading textures again (fixes Water Temple 1st room, borked walls; SM64toZ64 conversions?) */
                        if (Configuration.RenderTextures && (cmd == (byte)General.UcodeCmds.SETCOMBINE || cmd == (byte)General.UcodeCmds.LOADBLOCK) && Textures[0] != null)
                        {
                            LoadTextures();
                        }
                    }
                }
            }
            catch (EntryPointNotFoundException)
            {
                //TODO handle this?
            }
            finally
            {
                ActiveGLDL.Pop();
            }
        }
Пример #2
0
        public void Render(uint adr, bool call = false, OpenGLHelpers.DisplayListEx gldl = null)
        {
            try
            {
                ActiveGLDL.Push(gldl);

                /* Set some defaults */
                if (!call)
                {
                    GL.DepthMask(true);
                    if (OpenGLHelpers.Initialization.SupportsFunction("glGenProgramsARB")) GL.Disable((EnableCap)All.FragmentProgram);
                    if (OpenGLHelpers.Initialization.SupportsFunction("glCreateShader")) GL.UseProgram(0);

                    PrimColor = EnvColor = new Color4(0.5f, 0.5f, 0.5f, 0.5f);

                    /* If emulating combiner, set more defaults / load values */
                    if (Configuration.CombinerType == CombinerTypes.ArbCombiner)
                    {
                        GL.Arb.BindProgram(AssemblyProgramTargetArb.FragmentProgram, 0);
                        GL.Arb.ProgramEnvParameter4(AssemblyProgramTargetArb.FragmentProgram, 0, PrimColor.R, PrimColor.G, PrimColor.B, PrimColor.A);
                        GL.Arb.ProgramEnvParameter4(AssemblyProgramTargetArb.FragmentProgram, 1, EnvColor.R, EnvColor.G, EnvColor.B, EnvColor.A);
                    }

                    /* Clear out texture units */
                    for (int i = 0; i < (OpenGLHelpers.Initialization.SupportsFunction("glActiveTextureARB") ? 2 : 1); i++)
                    {
                        OpenGLHelpers.Initialization.ActiveTextureChecked(TextureUnit.Texture0 + i);
                        GL.BindTexture(TextureTarget.Texture2D, OpenGLHelpers.MiscDrawingHelpers.DummyTextureID);
                    }
                }

                /* Ucode interpreter starts here */
                byte seg = (byte)(adr >> 24);
                adr &= 0xFFFFFF;

                byte[] segdata = (byte[])ROM.SegmentMapping[seg];

                while (adr < segdata.Length)
                {
                    byte cmd = segdata[adr];

                    /* EndDL */
                    if (cmd == (byte)General.UcodeCmds.ENDDL) break;

                    /* Try to detect macros if any are defined */
                    inmacro = false;
                    if (macros != null)
                    {
                        foreach (Macro m in macros)
                        {
                            if (adr + ((m.Commands.Length + 3) * 8) > segdata.Length) break;

                            General.UcodeCmds[] nextcmd = new General.UcodeCmds[m.Commands.Length];
                            uint[] nextw0 = new uint[nextcmd.Length + 2];
                            uint[] nextw1 = new uint[nextcmd.Length + 2];

                            for (int i = 0; i < nextw0.Length; i++)
                            {
                                nextw0[i] = Endian.SwapUInt32(BitConverter.ToUInt32(segdata, (int)adr + (i * 8)));
                                nextw1[i] = Endian.SwapUInt32(BitConverter.ToUInt32(segdata, (int)adr + (i * 8) + 4));
                                if (i < m.Commands.Length) nextcmd[i] = (General.UcodeCmds)(nextw0[i] >> 24);
                            }

                            if (inmacro = (Enumerable.SequenceEqual(m.Commands, nextcmd)))
                            {
                                m.Function(nextw0, nextw1);
                                adr += (uint)(m.Commands.Length * 8);
                                break;
                            }
                        }
                    }

                    /* No macro detected */
                    if (!inmacro)
                    {
                        /* Execute command */
                        ucodecmds[cmd](Endian.SwapUInt32(BitConverter.ToUInt32(segdata, (int)adr)), Endian.SwapUInt32(BitConverter.ToUInt32(segdata, (int)adr + 4)));
                        adr += 8;

                        /* Texture loading hack; if SetCombine OR LoadBlock command detected, try loading textures again (fixes Water Temple 1st room, borked walls; SM64toZ64 conversions?) */
                        if (Configuration.RenderTextures && (cmd == (byte)General.UcodeCmds.SETCOMBINE || cmd == (byte)General.UcodeCmds.LOADBLOCK) && Textures[0] != null) LoadTextures();
                    }
                }
            }
            catch (EntryPointNotFoundException)
            {
                //TODO handle this?
            }
            finally
            {
                ActiveGLDL.Pop();
            }
        }