public static void ForceVertRGBA(bool Opaque) { int addresscount; if (Opaque) { addresscount = GeoLayouts.OpaqueModels.Length; } else { addresscount = GeoLayouts.AlphaModels.Length; } for (int i = 0; i < addresscount; i++) { if (Opaque) { ForceVertRGBAJump(GeoLayouts.OpaqueModels[i], true); } else { ForceVertRGBAJump(GeoLayouts.AlphaModels[i], false); } InitialiseModelLoad(Rectangle.Empty, new GLControl()); //init without rendering GeoLayouts.ParseGeoLayout(ROMManager.SM64ROM, LevelScripts.getGeoAddress(Renderer.LevelArea), false); } }
public static void SpecificConversions(String[] Sås, ROM SM64ROM) //Sås = source file { bool Geo = false; for (uint i = 0; i < Sås.Length; i++) { string CMD = Sås[i].ToLower(); if (CMD.StartsWith("geo")) { Geo = true; } else if (CMD.StartsWith("dl") || CMD.StartsWith("f3d")) { Geo = false; } else if (CMD.StartsWith("#")) { string[] portions = Sås[i].Split(' '); StringBuilder removehash = new StringBuilder(portions[0]); //remove the # for raw segment number removehash.Remove(0, 1); portions[0] = removehash.ToString(); byte Segment = byte.Parse(portions[0], System.Globalization.NumberStyles.HexNumber); uint StartAddr = UInt32.Parse(portions[1], System.Globalization.NumberStyles.HexNumber); SM64ROM.setSegment(Segment, StartAddr); } else if (CMD.StartsWith("addr")) { string[] portions = Sås[i].Split(' '); uint Addr = UInt32.Parse(portions[1], System.Globalization.NumberStyles.HexNumber); if (!Geo) { ConvertDL(SM64ROM, Addr, true); //Force ROM addr here for raw DL conversion } else { GeoLayouts.DecodeGeoLayout(SM64ROM, Addr); } } else if (CMD.StartsWith("segaddr")) { string[] portions = Sås[i].Split(' '); uint SegAddr = UInt32.Parse(portions[1], System.Globalization.NumberStyles.HexNumber); if (!Geo) { ConvertDL(SM64ROM, SegAddr, false); //Force ROM addr here for raw DL conversion } else { GeoLayouts.DecodeGeoLayout(SM64ROM, SM64ROM.readSegmentAddr(SegAddr)); } } } }
public static void LayerSwap(byte layer1, byte layer2, uint LevelArea) { for (uint i = 0; i < GeoLayouts.ExtDLPointers[layer1].Length; i++) { UInt32 Addr = GeoLayouts.ExtDLPointers[1][i] + 1; ROMManager.SM64ROM.changeByte(Addr, layer2); if (debug) { Console.Write("Wrote 0x" + layer2.ToString("x1") + " to ROM addr 0x" + Addr.ToString("x8") + " (GeoLayout LayerSwap)\n"); } GeoLayouts.ParseGeoLayout(ROMManager.SM64ROM, LevelScripts.getGeoAddress(LevelArea), false); } }
public static void RenderColourBuffer(Rectangle ClientRectangle, int Width, int Height, GLControl RenderPanel) { GL.Viewport(ClientRectangle.X, ClientRectangle.Y, RenderPanel.Width, RenderPanel.Height); projection = cam.GetViewMatrix() * Matrix4.CreatePerspectiveFieldOfView(1.0f, Width / (float)Height, 0.0000001f, 1.0f); GL.MatrixMode(MatrixMode.Projection); GL.LoadMatrix(ref projection); InitialiseView(); GL.Scale(0.000001, 0.000001, 0.000001); if (ROMManager.ReadytoLoad) { GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); GL.Scale(0.01, 0.01, 0.01); GeoLayouts.ParseGeoLayout(ROMManager.SM64ROM, LevelScripts.getGeoAddress(LevelArea), true); } //RenderPanel.SwapBuffers(); //We don't want people to see the vertex selection colour map so don't invalidate here! }
public static void Render(Rectangle ClientRectangle, int Width, int Height, GLControl RenderPanel) { TriCount = 0; VertexCount = 0; GL.Viewport(ClientRectangle.X, ClientRectangle.Y, RenderPanel.Width, RenderPanel.Height); projection = cam.GetViewMatrix() * Matrix4.CreatePerspectiveFieldOfView(1.0f, Width / (float)Height, 0.00000001f, 0.001f); GL.MatrixMode(MatrixMode.Projection); GL.LoadMatrix(ref projection); InitialiseView(); if (WireFrameMode) { GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line); } else { GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); } GL.Scale(WorldScale); if (ROMManager.ReadytoLoad && ROMManager.SM64ROM != null) { GL.Scale(GameScale); if (!ObjectView) { GeoLayouts.ParseGeoLayout(ROMManager.SM64ROM, LevelScripts.getGeoAddress(LevelArea), false); } else { GeoLayouts.ParseGeoLayout(ROMManager.SM64ROM, LevelScripts.ObjectGeoOffsets[SelectedSegment][SelectedObject], false); } if (EdgesOption) { GL.Disable(EnableCap.CullFace); F3D.RenderEdges = true; GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line); if (!ObjectView) { GeoLayouts.ParseGeoLayout(ROMManager.SM64ROM, LevelScripts.getGeoAddress(LevelArea), false); } else { GeoLayouts.ParseGeoLayout(ROMManager.SM64ROM, LevelScripts.ObjectGeoOffsets[SelectedSegment][SelectedObject], false); } F3D.RenderEdges = false; } } else //Rotate cubes for fun idle :) { if (CubeSampleRotate >= Math.PI * 1.5) { CubeSampleRotate = Math.PI / 2; CubeSampleColour = new Color4(0f, 0f, 1f, 1f); } if (CubeSampleScale >= Math.PI * 2) { CubeSampleScale = 0; } GL.Scale(1 + 0.25 * Math.Sin(CubeSampleScale), Math.Sin(CubeSampleScale), Math.Sin(CubeSampleScale)); float rotation = 90 * (float)Math.Sin(CubeSampleRotate); CubeRealRotation = rotation; float newcolour = Math.Abs(rotation); GL.Rotate(rotation, 1, 0, 0); CubeSampleColour.R = (newcolour) / 45; CubeSampleColour.G = (newcolour) / 45; DrawCube(); GL.Rotate(rotation, 1, 0, 0); CubeSampleColour.R = (newcolour) / 45; CubeSampleColour.G = (newcolour) / 45; DrawCube(); GL.Rotate(rotation, 1, 0, 0); CubeSampleColour.R = (newcolour) / 45; CubeSampleColour.G = (newcolour) / 45; DrawCube(); GL.Rotate(rotation, 1, 0, 0); CubeSampleColour.R = (newcolour) / 45; CubeSampleColour.G = (newcolour) / 45; DrawCube(); KeyboardState state = Keyboard.GetState(); CubeSampleScale += 0.015; CubeSampleRotate += 0.015; } RenderPanel.SwapBuffers(); }
public static void DecodeGeoLayout(ROM SM64ROM, uint offset, bool ColourBuffer) { for (uint i = offset; i < SM64ROM.getEndROMAddr();) { if (SM64ROM.getByte(i) > 0x20) { return; } uint segaddr; switch (SM64ROM.getByte(i)) { case 0: increment = 8; break; case 1:; return; case 2: JumpAddr = SM64ROM.readSegmentAddr(SM64ROM.ReadFourBytes(i + 4)); GeoLayouts.DecodeGeoLayout(SM64ROM, JumpAddr, ColourBuffer); if (SM64ROM.getByte(i + 1) == 0) { return; } increment = 8; break; case 3: return; case 4: //open node increment = 4; break; case 5: //close node increment = 4; break; case 8: increment = 12; break; case 9: increment = 4; break; case 0x0A: if (SM64ROM.getByte(i + 1) > 0) { increment = 12; } else { increment = 8; } break; case 0x0B: increment = 4; break; case 0x0C: increment = 4; break; case 0x0D: increment = 8; break; case 0x0E: increment = 8; break; case 0x0F: increment = 0x14; break; case 0x10: //rotate increment = 16; break; case 0x13: //Load DL with rotation increment = 12; if (SM64ROM.getByte(i + 8) == 0) { break; } drawlayer = SM64ROM.getByte(i + 1); if (drawlayer > (4 - Convert.ToInt32(LevelScripts.IsRomManager)) && !GeoLayouts.OpaqueRendered) { break; } if (drawlayer <= (4 - Convert.ToInt32(LevelScripts.IsRomManager)) && GeoLayouts.OpaqueRendered) { break; } segaddr = SM64ROM.ReadFourBytes(i + 8); DecideBufferAndAddr(SM64ROM.getByte(i + 1), segaddr, ColourBuffer); if (F3D.Culling) { F3D.GeoMode |= 0x022000; //Generate geomode for vector lighting and backface culling } else { F3D.GeoMode |= 0x020000; //If culling is off, only generate vector lighting } F3D.ParseF3DDL(SM64ROM, segaddr, ColourBuffer); break; case 0x14: //billboard increment = 8; break; case 0x15: //Load DL increment = 8; segaddr = SM64ROM.ReadFourBytes(i + 4); if (ModelsList.Contains(segaddr)) { break; } drawlayer = SM64ROM.getByte(i + 1); if (drawlayer >= (4 - Convert.ToInt32(LevelScripts.IsRomManager))) { ExtAlphaDLPointer = i; } if (drawlayer > (4 - Convert.ToInt32(LevelScripts.IsRomManager)) && !GeoLayouts.OpaqueRendered) { break; } if (drawlayer <= (4 - Convert.ToInt32(LevelScripts.IsRomManager)) && GeoLayouts.OpaqueRendered) { break; } DecideBufferAndAddr(SM64ROM.ReadEightBytes(i), segaddr, ColourBuffer); if (F3D.Culling) { F3D.GeoMode |= 0x022000; //Generate geomode for vector lighting and backface culling } else { F3D.GeoMode |= 0x020000; //If culling is off, only generate vector lighting } F3D.ParseF3DDL(SM64ROM, segaddr, ColourBuffer); Array.Resize(ref ModelsList, ModelsList.Length + 1); ModelsList[ModelsList.Length - 1] = segaddr; if (!Textures.FirstTexLoad) { break; } Array.Resize(ref ExtDLPointers[drawlayer], ExtDLPointers[drawlayer].Length + 1); //Increase size by one to add ExtDLPointers[drawlayer][ExtDLPointers[drawlayer].Length - 1] = i; //set last index to addr break; case 0x16: increment = 8; break; case 0x17: increment = 4; break; case 0x18: increment = 8; break; case 0x19: increment = 8; break; case 0x1A: increment = 8; break; case 0x1D: //scale, can be 12 length in rare occurence increment = 8; break; case 0x1E: increment = 8; break; case 0x1F: increment = 16; break; case 0x20: increment = 4; break; } if (Textures.FirstTexLoad && ROMManager.debug) // Debug TXT { Array.Resize(ref LevelScripts.DebugScript, LevelScripts.DebugScript.Length + 1); LevelScripts.DebugScript[LevelScripts.DebugScript.Length - 1] = i.ToString("x") + ": "; for (uint j = i; j < i + increment; j++) { LevelScripts.DebugScript[LevelScripts.DebugScript.Length - 1] += SM64ROM.getByte(j).ToString("x") + " "; } } i += increment; } }
public static void DecodeGeoLayout(ROM SM64ROM, uint offset, bool ColourBuffer) { for (uint i = offset; i < SM64ROM.getEndROMAddr();) { if (SM64ROM.getByte(i) > 0x20) { return; } uint segaddr; switch (SM64ROM.getByte(i)) { case 0: increment = 8; break; case 1:; return; case 2: JumpAddr = SM64ROM.readSegmentAddr(SM64ROM.ReadFourBytes(i + 4)); GeoLayouts.DecodeGeoLayout(SM64ROM, JumpAddr, ColourBuffer); if (SM64ROM.getByte(i + 1) == 0) { return; } increment = 8; break; case 3: return; case 4: //open node increment = 4; break; case 5: //close node increment = 4; break; case 8: increment = 12; break; case 9: increment = 4; break; case 0x0A: if (SM64ROM.getByte(i + 1) > 0) { increment = 12; } else { increment = 8; } break; case 0x0B: increment = 4; break; case 0x0C: increment = 4; break; case 0x0D: increment = 8; break; case 0x0E: increment = 8; break; case 0x0F: increment = 0x14; break; case 0x10: //rotate increment = 16; break; case 0x13: //Load DL with rotation increment = 12; if (SM64ROM.getByte(i + 8) == 0) { break; } drawlayer = SM64ROM.getByte(i + 1); if (drawlayer > 4 && !GeoLayouts.OpaqueRendered) { break; } if (drawlayer <= 4 && GeoLayouts.OpaqueRendered) { break; } segaddr = SM64ROM.ReadFourBytes(i + 8); DecideBufferAndAddr(SM64ROM.getByte(i + 1), segaddr, ColourBuffer); F3D.ParseF3DDL(SM64ROM, segaddr, ColourBuffer); break; case 0x14: //billboard increment = 8; break; case 0x15: //Load DL increment = 8; drawlayer = SM64ROM.getByte(i + 1); if (drawlayer >= 4) { ExtAlphaDLPointer = i; } if (drawlayer > 4 && !GeoLayouts.OpaqueRendered) { break; } if (drawlayer <= 4 && GeoLayouts.OpaqueRendered) { break; } segaddr = SM64ROM.ReadFourBytes(i + 4); DecideBufferAndAddr(SM64ROM.ReadEightBytes(i), segaddr, ColourBuffer); F3D.ParseF3DDL(SM64ROM, segaddr, ColourBuffer); if (!Textures.FirstTexLoad) { break; } Array.Resize(ref ExtDLPointers[drawlayer], ExtDLPointers[drawlayer].Length + 1); //Increase size by one to add ExtDLPointers[drawlayer][ExtDLPointers[drawlayer].Length - 1] = i; //set last index to addr break; case 0x16: increment = 8; break; case 0x17: increment = 4; break; case 0x18: increment = 8; break; case 0x19: increment = 8; break; case 0x1A: increment = 8; break; case 0x1D: //scale, can be 12 length in rare occurence increment = 8; break; case 0x1E: increment = 8; break; case 0x1F: increment = 16; break; case 0x20: increment = 4; break; } /*if(Textures.FirstTexLoad)using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"e:\test4.txt", true)) //Debug Txt * { * file.Write(i.ToString("x") + ": "); * for (uint j = i; j < i + increment; j++) * { * file.Write(SM64ROM.getByte(j).ToString("x") + " "); * } * file.WriteLine("\n"); * file.Close(); * }*/ i += increment; } }
public static void DecodeLevelScripts(ROM SM64ROM, UInt32 offset) { for (UInt32 i = offset; i < SM64ROM.getEndROMAddr();) { if (DebugScript.Length > 10000) { ExitDecode = true; } if (ExitDecode) { return; } uint increment = SM64ROM.getByte(i + 1); if (increment == 0 || SM64ROM.getByte(i) > 0x3C) { return; } Array.Resize(ref LevelScripts.DebugScript, LevelScripts.DebugScript.Length + 1); uint newindex = (uint)(LevelScripts.DebugScript.Length - 1); for (uint j = 0; j < stackcounter; j++) { LevelScripts.DebugScript[newindex] += " "; //tab further each stack increase for debug txt } LevelScripts.DebugScript[newindex] += i.ToString("x") + ": "; for (uint j = i; j < i + increment; j++) { LevelScripts.DebugScript[newindex] += SM64ROM.getByte(j).ToString("x2") + " "; } SkipCMDDetermination(i); //see if the command has already been processed before if (!skipCMD) { switch (SM64ROM.getByte(i)) //if not skipping command, process it { case 0x00: //Load raw data and jump NewSegment = SM64ROM.getByte(i + 3); NewSegAddr = SM64ROM.ReadFourBytes(i + 4); SM64ROM.setSegment(NewSegment, NewSegAddr); JumpSegAddr = SM64ROM.ReadFourBytes(i + 12); if (CheckExistingJumps(SM64ROM.readSegmentAddr(JumpSegAddr))) { break; //Don't jump to a spot previously jumped to } stackcounter++; LevelScripts.DecodeLevelScripts(SM64ROM, SM64ROM.readSegmentAddr(JumpSegAddr)); break; case 0x01: //Load raw data and jump NewSegment = SM64ROM.getByte(i + 3); NewSegAddr = SM64ROM.ReadFourBytes(i + 4); SM64ROM.setSegment(NewSegment, NewSegAddr); JumpSegAddr = SM64ROM.ReadFourBytes(i + 12); if (CheckExistingJumps(SM64ROM.readSegmentAddr(JumpSegAddr))) { break; //Don't jump to a spot previously jumped to } LevelScripts.DecodeLevelScripts(SM64ROM, SM64ROM.readSegmentAddr(JumpSegAddr)); break; case 0x02: //End level data return; case 0x03: //delayframes break; case 0x04: //delayframes break; case 0x05: //Jump to addr JumpSegAddr = SM64ROM.ReadFourBytes(i + 4); if (SM64ROM.readSegmentAddr(JumpSegAddr) == (i - 4)) { return; //The cake is a f*****g lie } if (CheckExistingJumps(SM64ROM.readSegmentAddr(JumpSegAddr))) { break; //Don't jump to a spot previously jumped to } LevelScripts.DecodeLevelScripts(SM64ROM, SM64ROM.readSegmentAddr(JumpSegAddr)); break; case 0x06: //Push stack JumpSegAddr = SM64ROM.ReadFourBytes(i + 4); if (CheckExistingJumps(SM64ROM.readSegmentAddr(JumpSegAddr))) { break; //Don't jump to a spot previously jumped to } stackcounter++; LevelScripts.DecodeLevelScripts(SM64ROM, SM64ROM.readSegmentAddr(JumpSegAddr)); break; case 0x07: //Pop stack stackcounter--; return; case 0x0B: //Conditional Pop break; case 0x0C: //Conditional Jump LevelID = SM64ROM.getByte(i + 7); if (LevelID == 0xFF) { break; } //if (LevelID == 0x00) throw new Exception(SM64ROM.getSegmentStart(0x14).ToString("x")); if (LevelID < 5) { SM64ROM.BackupAllSegments(); } SM64ROM.LoadBackupSegments(); JumpSegAddr = SM64ROM.ReadFourBytes(i + 8); if (CheckExistingJumps(SM64ROM.readSegmentAddr(JumpSegAddr))) { break; //Don't jump to a spot previously jumped to } LevelScripts.DecodeLevelScripts(SM64ROM, SM64ROM.readSegmentAddr(JumpSegAddr)); break; case 0x0D: //Conditional Push break; case 0x0E: //Conditional Skip break; case 0x0F: //Skip next break; case 0x10: //No-op break; case 0x11: //Set Accumulator From ASM break; case 0x12: //Actively set accumulator break; case 0x13: //Set accumulator break; case 0x16: //Loads directly to ram, no segment break; case 0x17: NewSegment = SM64ROM.getByte(i + 3); NewSegAddr = SM64ROM.ReadFourBytes(i + 4); SM64ROM.setSegment(NewSegment, NewSegAddr); break; case 0x18: //MIO0 segment case 0x1A: //MIO0 segment NewSegment = SM64ROM.getByte(i + 3); BeginMIO0 = SM64ROM.ReadFourBytes(i + 4); NewSegAddr = SM64ROM.ReadFourBytes(BeginMIO0 + 12) + BeginMIO0; SM64ROM.setSegment(NewSegment, NewSegAddr); break; case 0x1F: //LEVEL MODEL uint SegAddr = SM64ROM.ReadFourBytes(i + 4); GeoLayouts.DecodeGeoLayout(SM64ROM, SM64ROM.readSegmentAddr(SegAddr)); break; case 0x21: uint DLSegAddr = SM64ROM.ReadFourBytes(i + 4); DLConversion.ConvertDL(SM64ROM, DLSegAddr, false); break; case 0x22: uint ModelSegAddr = SM64ROM.ReadFourBytes(i + 4); GeoLayouts.DecodeGeoLayout(SM64ROM, SM64ROM.readSegmentAddr(ModelSegAddr)); break; case 0x2B: //Default Mario Position break; case 0x2E: //Collision break; default: break; } } i += increment; } }
public static void DecodeGeoLayout(ROM SM64ROM, uint offset) { for (uint i = offset; i < SM64ROM.getEndROMAddr();) { if (SM64ROM.getByte(i) > 0x20) { return; } uint segaddr; switch (SM64ROM.getByte(i)) { case 0: increment = 8; break; case 1: return; case 2: JumpAddr = SM64ROM.readSegmentAddr(SM64ROM.ReadFourBytes(i + 4)); GeoLayouts.DecodeGeoLayout(SM64ROM, JumpAddr); if (SM64ROM.getByte(i + 1) == 0) { return; } increment = 8; break; case 3: return; case 4: //open node increment = 4; break; case 5: //close node increment = 4; break; case 8: increment = 12; break; case 9: increment = 4; break; case 0x0A: if (SM64ROM.getByte(i + 1) > 0) { increment = 12; } else { increment = 8; } break; case 0x0B: increment = 4; break; case 0x0C: increment = 4; break; case 0x0D: increment = 8; break; case 0x0E: increment = 8; break; case 0x0F: increment = 0x14; break; case 0x10: //rotate increment = 16; break; case 0x13: //Load DL with rotation increment = 12; if (SM64ROM.getByte(i + 8) == 0) { break; } segaddr = SM64ROM.ReadFourBytes(i + 8); DLConversion.ConvertDL(SM64ROM, segaddr, false); break; case 0x14: //billboard increment = 8; break; case 0x15: //Load DL increment = 8; segaddr = SM64ROM.ReadFourBytes(i + 4); DLConversion.ConvertDL(SM64ROM, segaddr, false); break; case 0x16: increment = 8; break; case 0x17: increment = 4; break; case 0x18: increment = 8; break; case 0x19: increment = 8; break; case 0x1A: increment = 8; break; case 0x1D: //scale, can be 12 length in rare occurence increment = 8; break; case 0x1E: increment = 8; break; case 0x1F: increment = 16; break; case 0x20: increment = 4; break; } //Debug text for geo layouts /*Array.Resize(ref LevelScripts.DebugScript, LevelScripts.DebugScript.Length + 1); * LevelScripts.DebugScript[LevelScripts.DebugScript.Length - 1] = i.ToString("x") + ": "; * for (uint j = i; j < i + increment; j++) * { * LevelScripts.DebugScript[LevelScripts.DebugScript.Length - 1] += SM64ROM.getByte(j).ToString("x2") + " "; * }*/ i += increment; } }