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(); } }
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(); } }