diff --git a/README.md b/README.md index 99304cf..592d845 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Quad64 v0.1 +# Quad64 v0.1.1 An open-source SM64 level editor written in C# 4.0, and uses Windows Forms and OpenTK. diff --git a/src/Forms/MainForm.Designer.cs b/src/Forms/MainForm.Designer.cs index 2f69e58..fcd7c07 100644 --- a/src/Forms/MainForm.Designer.cs +++ b/src/Forms/MainForm.Designer.cs @@ -28,10 +28,10 @@ protected override void Dispose(bool disposing) /// private void InitializeComponent() { - System.Windows.Forms.TreeNode treeNode1 = new System.Windows.Forms.TreeNode("3D Objects"); - System.Windows.Forms.TreeNode treeNode2 = new System.Windows.Forms.TreeNode("Macro 3D Objects"); - System.Windows.Forms.TreeNode treeNode3 = new System.Windows.Forms.TreeNode("Special 3D Objects"); - System.Windows.Forms.TreeNode treeNode4 = new System.Windows.Forms.TreeNode("Warps"); + System.Windows.Forms.TreeNode treeNode5 = new System.Windows.Forms.TreeNode("3D Objects"); + System.Windows.Forms.TreeNode treeNode6 = new System.Windows.Forms.TreeNode("Macro 3D Objects"); + System.Windows.Forms.TreeNode treeNode7 = new System.Windows.Forms.TreeNode("Special 3D Objects"); + System.Windows.Forms.TreeNode treeNode8 = new System.Windows.Forms.TreeNode("Warps"); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); this.menuStrip1 = new System.Windows.Forms.MenuStrip(); this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -479,22 +479,22 @@ private void InitializeComponent() this.treeView1.ItemHeight = 16; this.treeView1.Location = new System.Drawing.Point(1, 1); this.treeView1.Name = "treeView1"; - treeNode1.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(0)))), ((int)(((byte)(0))))); - treeNode1.Name = "objects"; - treeNode1.Text = "3D Objects"; - treeNode2.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(192))))); - treeNode2.Name = "Node0"; - treeNode2.Text = "Macro 3D Objects"; - treeNode3.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(192)))), ((int)(((byte)(0))))); - treeNode3.Name = "special3DNode"; - treeNode3.Text = "Special 3D Objects"; - treeNode4.Name = "warps"; - treeNode4.Text = "Warps"; + treeNode5.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(0)))), ((int)(((byte)(0))))); + treeNode5.Name = "objects"; + treeNode5.Text = "3D Objects"; + treeNode6.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(192))))); + treeNode6.Name = "Node0"; + treeNode6.Text = "Macro 3D Objects"; + treeNode7.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(192)))), ((int)(((byte)(0))))); + treeNode7.Name = "special3DNode"; + treeNode7.Text = "Special 3D Objects"; + treeNode8.Name = "warps"; + treeNode8.Text = "Warps"; this.treeView1.Nodes.AddRange(new System.Windows.Forms.TreeNode[] { - treeNode1, - treeNode2, - treeNode3, - treeNode4}); + treeNode5, + treeNode6, + treeNode7, + treeNode8}); this.treeView1.Size = new System.Drawing.Size(217, 206); this.treeView1.TabIndex = 0; this.treeView1.TabStop = false; @@ -942,7 +942,8 @@ private void InitializeComponent() this.MinimumSize = new System.Drawing.Size(820, 522); this.Name = "MainForm"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "Quad64 v0.1"; + this.Text = "Quad64 v0.1.1"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing); this.Shown += new System.EventHandler(this.Form1_Shown); this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown); this.menuStrip1.ResumeLayout(false); diff --git a/src/Forms/SettingsForm.Designer.cs b/src/Forms/SettingsForm.Designer.cs index cbccd1b..61b4468 100644 --- a/src/Forms/SettingsForm.Designer.cs +++ b/src/Forms/SettingsForm.Designer.cs @@ -47,7 +47,7 @@ private void InitializeComponent() this.tabs.Location = new System.Drawing.Point(0, 0); this.tabs.Name = "tabs"; this.tabs.SelectedIndex = 0; - this.tabs.Size = new System.Drawing.Size(474, 267); + this.tabs.Size = new System.Drawing.Size(474, 287); this.tabs.TabIndex = 0; this.tabs.TabStop = false; // @@ -57,7 +57,7 @@ private void InitializeComponent() this.Basic.Location = new System.Drawing.Point(4, 22); this.Basic.Name = "Basic"; this.Basic.Padding = new System.Windows.Forms.Padding(3); - this.Basic.Size = new System.Drawing.Size(466, 241); + this.Basic.Size = new System.Drawing.Size(466, 261); this.Basic.TabIndex = 0; this.Basic.Text = "Basic"; this.Basic.UseVisualStyleBackColor = true; @@ -75,7 +75,7 @@ private void InitializeComponent() // saveButton // this.saveButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.saveButton.Location = new System.Drawing.Point(299, 269); + this.saveButton.Location = new System.Drawing.Point(299, 289); this.saveButton.Name = "saveButton"; this.saveButton.Size = new System.Drawing.Size(76, 24); this.saveButton.TabIndex = 1; @@ -87,7 +87,7 @@ private void InitializeComponent() // cancelButton // this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.cancelButton.Location = new System.Drawing.Point(381, 269); + this.cancelButton.Location = new System.Drawing.Point(381, 289); this.cancelButton.Name = "cancelButton"; this.cancelButton.Size = new System.Drawing.Size(76, 24); this.cancelButton.TabIndex = 2; @@ -100,7 +100,7 @@ private void InitializeComponent() // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(472, 297); + this.ClientSize = new System.Drawing.Size(472, 317); this.Controls.Add(this.cancelButton); this.Controls.Add(this.saveButton); this.Controls.Add(this.tabs); diff --git a/src/Forms/SettingsForm.cs b/src/Forms/SettingsForm.cs index f72a92e..6db54f7 100644 --- a/src/Forms/SettingsForm.cs +++ b/src/Forms/SettingsForm.cs @@ -1,4 +1,5 @@ -using Quad64.src.JSON; +using OpenTK.Graphics.OpenGL; +using Quad64.src.JSON; using Quad64.src.TestROM; using System; using System.Collections.Generic; @@ -24,8 +25,9 @@ private void SettingsForm_Load(object sender, EventArgs e) AddAdvancedSettings(); } - TextBox emuPathTextBox; - Button setEmuPathButton; + private TextBox emuPathTextBox; + private Button setEmuPathButton; + private CheckBox autoSaveWithEmulatorBox; private void AddAdvancedSettings() { int xOffset = 0, yOffset = 10, SeperatorWidth = Advanced.Width - 6; @@ -34,6 +36,9 @@ private void AddAdvancedSettings() yOffset += 25; addButtonWithTextBox(Advanced, "Browse", Globals.pathToEmulator, true, xOffset, yOffset, Advanced.Width, ref emuPathTextBox, ref setEmuPathButton, OpenEmulatorPath_Click); + yOffset += 30; + Advanced.Controls.Add(newCheckBox("Automatically save ROM when launching emulator", xOffset, yOffset, Globals.autoSaveWhenClickEmulator)); + autoSaveWithEmulatorBox = (CheckBox)Advanced.Controls[Advanced.Controls.Count - 1]; } private void addButtonWithTextBox(TabPage page, string buttonText, string textBoxText, bool isTextBoxReadOnly, int x, int y, int screenWidth, ref TextBox box, ref Button button, EventHandler buttonClickEvent) @@ -49,8 +54,8 @@ private void OpenEmulatorPath_Click(object sender, EventArgs e) LaunchROM.setEmulatorPath(); emuPathTextBox.Text = Globals.pathToEmulator; } - - private CheckBox enableWireframe, drawObjMdls, autoLoadROM; + + private CheckBox enableWireframe, enableBFculling, drawObjMdls, autoLoadROM; private ComboBox renderMap, useHex; private void AddBasicSettings() { @@ -62,6 +67,9 @@ private void AddBasicSettings() Basic.Controls.Add(newCheckBox("Enable wireframe", xOffset, yOffset, Globals.doWireframe)); enableWireframe = (CheckBox)Basic.Controls[Basic.Controls.Count - 1]; yOffset += 25; + Basic.Controls.Add(newCheckBox("Enable backface culling", xOffset, yOffset, Globals.doBackfaceCulling)); + enableBFculling = (CheckBox)Basic.Controls[Basic.Controls.Count - 1]; + yOffset += 25; Basic.Controls.Add(newCheckBox("Draw Object Models", xOffset, yOffset, Globals.drawObjectModels)); drawObjMdls = (CheckBox)Basic.Controls[Basic.Controls.Count - 1]; yOffset += 30; @@ -179,9 +187,16 @@ private void updateGlobalSettings() Globals.doWireframe = enableWireframe.Checked; Globals.drawObjectModels = drawObjMdls.Checked; Globals.autoLoadROMOnStartup = autoLoadROM.Checked; + Globals.doBackfaceCulling = enableBFculling.Checked; Globals.renderCollisionMap = (renderMap.SelectedIndex == 1); Globals.useHexadecimal = (useHex.SelectedIndex != 0); Globals.useSignedHex = (useHex.SelectedIndex == 1); + Globals.autoSaveWhenClickEmulator = autoSaveWithEmulatorBox.Checked; + + if (Globals.doBackfaceCulling) + GL.Enable(EnableCap.CullFace); + else + GL.Disable(EnableCap.CullFace); } private void saveButton_Click(object sender, EventArgs e) diff --git a/src/Globals.cs b/src/Globals.cs index 611ac3f..d0e50f8 100644 --- a/src/Globals.cs +++ b/src/Globals.cs @@ -1,4 +1,5 @@ -using Quad64.src.JSON; +using OpenTK.Graphics.OpenGL; +using Quad64.src.JSON; using System; using System.Collections.Generic; using System.Drawing; @@ -13,14 +14,18 @@ class Globals public static bool doWireframe = false; public static bool drawObjectModels = true; public static bool renderCollisionMap = false; + public static bool doBackfaceCulling = false; // Editor Options public static bool autoLoadROMOnStartup = false; public static string pathToAutoLoadROM = ""; - public static bool useHexadecimal = true; - public static bool useSignedHex = true; + public static bool useHexadecimal = false; + public static bool useSignedHex = false; + + // Advanced Options public static string pathToEmulator = ""; - + public static bool autoSaveWhenClickEmulator = false; + // Speed multipliers public static float camSpeedMultiplier = 1.0f; public static float objSpeedMultiplier = 1.0f; @@ -28,6 +33,9 @@ class Globals // TreeView selection public static int list_selected = -1; public static int item_selected = -1; + + // Keeps track if the user needs to save their changes. + public static bool needToSave = false; // For the bounding boxes in the area public static Color ObjectColor = Color.Red; diff --git a/src/JSON/SettingsFile.cs b/src/JSON/SettingsFile.cs index 1210647..7c46fad 100644 --- a/src/JSON/SettingsFile.cs +++ b/src/JSON/SettingsFile.cs @@ -13,6 +13,7 @@ public static void SaveGlobalSettings(string profileName) { JObject s = new JObject(); s["EnableWireframe"] = Globals.doWireframe.ToString(); + s["EnableBackfaceCulling"] = Globals.doBackfaceCulling.ToString(); s["DrawObjectModels"] = Globals.drawObjectModels.ToString(); s["RenderCollisionMap"] = Globals.renderCollisionMap.ToString(); s["AutoLoadROMFile"] = Globals.autoLoadROMOnStartup.ToString(); @@ -20,6 +21,7 @@ public static void SaveGlobalSettings(string profileName) s["EnableHex"] = Globals.useHexadecimal.ToString(); s["SignedHex"] = Globals.useSignedHex.ToString(); s["EmulatorPath"] = Globals.pathToEmulator; + s["AutoSaveOnLaunchROM"] = Globals.autoSaveWhenClickEmulator; string savePath = "./data/profiles/" + profileName + "/"; Directory.CreateDirectory(savePath); // Create directory if it doesn't exist! @@ -35,6 +37,8 @@ public static void LoadGlobalSettings(string profileName) JObject o = JObject.Parse(json); if (o["EnableWireframe"] != null) Globals.doWireframe = bool.Parse(o["EnableWireframe"].ToString()); + if (o["EnableBackfaceCulling"] != null) + Globals.doBackfaceCulling = bool.Parse(o["EnableBackfaceCulling"].ToString()); if (o["DrawObjectModels"] != null) Globals.drawObjectModels = bool.Parse(o["DrawObjectModels"].ToString()); if (o["RenderCollisionMap"] != null) @@ -49,6 +53,8 @@ public static void LoadGlobalSettings(string profileName) Globals.useSignedHex = bool.Parse(o["SignedHex"].ToString()); if(o["EmulatorPath"] != null) Globals.pathToEmulator = o["EmulatorPath"].ToString(); + if (o["AutoSaveOnLaunchROM"] != null) + Globals.autoSaveWhenClickEmulator = bool.Parse(o["AutoSaveOnLaunchROM"].ToString()); } } } diff --git a/src/LevelInfo/Object3D.cs b/src/LevelInfo/Object3D.cs index b2e2e18..8867010 100644 --- a/src/LevelInfo/Object3D.cs +++ b/src/LevelInfo/Object3D.cs @@ -250,8 +250,8 @@ public void updateROMData() } else if (Globals.list_selected == 1) // Macro Object { - //ushort presetNum = (ushort)(rom.readHalfwordUnsigned(romAddr) & 0x1FF); - ushort first = (ushort)(((int)(yRot / 22.5f) << 9) | (presetID & 0x1FF)); + //Console.WriteLine("Preset ID = 0x" + presetID.ToString("X")); + ushort first = (ushort)((ushort)((yRot << 9) / 2.8125f) | (presetID & 0x1FF)); rom.writeHalfword(romAddr, first); rom.writeHalfword(romAddr + 2, xPos); rom.writeHalfword(romAddr + 4, yPos); @@ -261,6 +261,7 @@ public void updateROMData() } else if (Globals.list_selected == 2) // Special Object { + Console.WriteLine("Special Preset ID = 0x" + presetID.ToString("X")); rom.writeHalfword(romAddr, presetID); rom.writeHalfword(romAddr + 2, xPos); rom.writeHalfword(romAddr + 4, yPos); diff --git a/src/Prompts.cs b/src/Prompts.cs index 39e952f..631c488 100644 --- a/src/Prompts.cs +++ b/src/Prompts.cs @@ -8,6 +8,18 @@ namespace Quad64.src { class Prompts { + public static DialogResult ShowShouldSaveDialog() + { + if (Globals.needToSave) + { + DialogResult result = MessageBox.Show("You have unsaved changes, would you like to save the ROM?", "Save ROM?", MessageBoxButtons.YesNoCancel); + if (result == DialogResult.Yes) + ROM.Instance.saveFileAs(ROM.Instance.Filepath, ROM.Instance.Endian); + return result; + } + return DialogResult.None; + } + public static string ShowInputDialog(string text, string title) { Form prompt = new Form() diff --git a/src/ROM.cs b/src/ROM.cs index 826a901..58500e5 100644 --- a/src/ROM.cs +++ b/src/ROM.cs @@ -201,6 +201,7 @@ public void readFile(string filename) bytes = File.ReadAllBytes(filename); checkROM(); Globals.pathToAutoLoadROM = filepath; + Globals.needToSave = false; SettingsFile.SaveGlobalSettings("default"); } @@ -223,6 +224,7 @@ public void saveFile() File.WriteAllBytes(filepath, bytes); } Globals.pathToAutoLoadROM = filepath; + Globals.needToSave = false; SettingsFile.SaveGlobalSettings("default"); } @@ -247,6 +249,7 @@ public void saveFileAs(string filename, ROM_Endian saveType) File.WriteAllBytes(filename, bytes); endian = ROM_Endian.BIG; } + Globals.needToSave = false; filepath = filename; Globals.pathToAutoLoadROM = filepath; SettingsFile.SaveGlobalSettings("default"); @@ -310,13 +313,18 @@ public byte[] getDataFromSegmentAddress_safe(uint segOffset, uint size) { byte seg = (byte)(segOffset >> 24); uint off = segOffset & 0x00FFFFFF; - - return getSubArray_safe(segData[seg], off, size); + if(segData[seg] != null) + return getSubArray_safe(segData[seg], off, size); + else + return new byte[size]; } public byte[] getSubArray_safe(byte[] arr, uint offset, uint size) { + if (arr == null) + return new byte[size]; + byte[] newArr = new byte[size]; for (uint i = 0; i < size; i++) { diff --git a/src/Scripts/CollisionMap.cs b/src/Scripts/CollisionMap.cs index 8eec4a7..4233317 100644 --- a/src/Scripts/CollisionMap.cs +++ b/src/Scripts/CollisionMap.cs @@ -59,7 +59,7 @@ public void AddVertex(Vector3 newVert) public void AddTriangle(uint a, uint b, uint c) { - if(triangles.Count > 0) + if (triangles.Count > 0) triangles[triangles.Count - 1].AddTriangle(a, b, c); } @@ -104,7 +104,7 @@ private struct tempTriangle public short dropToGround(Vector3 pos) { List found = new List(); - for (int i = 0; i < triangles.Count; i ++) + for (int i = 0; i < triangles.Count; i++) { CollisionTriangleList list = triangles[i]; for (int j = 0; j < list.indices.Length; j += 3) @@ -123,7 +123,7 @@ public short dropToGround(Vector3 pos) return (short)pos.Y; float highestY = -0x2000; - // Console.WriteLine("Found " + found.Count + " triangles under position"); + // Console.WriteLine("Found " + found.Count + " triangles under position"); for (int i = 0; i < found.Count; i++) { if (found[i] > highestY) @@ -144,7 +144,7 @@ public void buildCollisionMap() verts, BufferUsageHint.StaticDraw ); - + for (int i = 0; i < triangles.Count; i++) { triangles[i].buildList(); @@ -163,7 +163,7 @@ public void drawCollisionMap(bool drawAsBlack) { GL.PushMatrix(); GL.EnableClientState(ArrayCap.VertexArray); - if(drawAsBlack) // Used as part of color picking + if (drawAsBlack) // Used as part of color picking GL.BlendFunc(BlendingFactorSrc.Zero, BlendingFactorDest.Zero); for (int i = 0; i < triangles.Count; i++) { @@ -172,18 +172,49 @@ public void drawCollisionMap(bool drawAsBlack) GL.BindTexture(TextureTarget.Texture2D, l.texture.ID); GL.BindBuffer(BufferTarget.ArrayBuffer, vbo); GL.VertexPointer(3, VertexPointerType.Float, 0, IntPtr.Zero); - GL.BindBuffer(BufferTarget.ElementArrayBuffer, l.ibo); - if (!Globals.doWireframe) - GL.DrawElements(PrimitiveType.Triangles, l.indices.Length, - DrawElementsType.UnsignedInt, IntPtr.Zero); + if (Globals.doWireframe) + GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line); else - GL.DrawElements(PrimitiveType.Lines, l.indices.Length, - DrawElementsType.UnsignedInt, IntPtr.Zero); + GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); + + GL.BindBuffer(BufferTarget.ElementArrayBuffer, l.ibo); + GL.DrawElements(PrimitiveType.Triangles, l.indices.Length, + DrawElementsType.UnsignedInt, IntPtr.Zero); + + if (Globals.doWireframe) + GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); } if (drawAsBlack) GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); GL.DisableClientState(ArrayCap.VertexArray); GL.PopMatrix(); + + if (!drawAsBlack && !Globals.doWireframe) + drawCollisionMapOutline(); + } + + public void drawCollisionMapOutline() + { + GL.PushMatrix(); + GL.EnableClientState(ArrayCap.VertexArray); + GL.BlendFunc(BlendingFactorSrc.Zero, BlendingFactorDest.Zero); + for (int i = 0; i < triangles.Count; i++) + { + CollisionTriangleList l = triangles[i]; + //if (m.vertices == null || m.indices == null) return; + GL.BindTexture(TextureTarget.Texture2D, l.texture.ID); + GL.BindBuffer(BufferTarget.ArrayBuffer, vbo); + GL.VertexPointer(3, VertexPointerType.Float, 0, IntPtr.Zero); + GL.BindBuffer(BufferTarget.ElementArrayBuffer, l.ibo); + GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line); + GL.BindBuffer(BufferTarget.ElementArrayBuffer, l.ibo); + GL.DrawElements(PrimitiveType.Triangles, l.indices.Length, + DrawElementsType.UnsignedInt, IntPtr.Zero); + GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); + } + GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); + GL.DisableClientState(ArrayCap.VertexArray); + GL.PopMatrix(); } } } diff --git a/src/Scripts/Fast3DScripts.cs b/src/Scripts/Fast3DScripts.cs index 605b09e..7d678b3 100644 --- a/src/Scripts/Fast3DScripts.cs +++ b/src/Scripts/Fast3DScripts.cs @@ -80,15 +80,22 @@ public static void parse(ref Model3D mdl, ref Level lvl, byte seg, uint off) bool end = false; while (!end) { + if (off + 8 > data.Length) + return; byte[] cmd = rom.getSubArray(data, off, 8); - if(!Enum.IsDefined(typeof(CMD), (int)cmd[0])) + if (!Enum.IsDefined(typeof(CMD), (int)cmd[0])) { return; //throw new Exception("UNDEFINED FAST3D COMMAND: 0x"+cmd[0].ToString("X2")); } + //rom.printArray(cmd, 8); switch ((CMD)cmd[0]) { + case CMD.F3D_NOOP: + if (bytesToInt(cmd, 0, 4) != 0) + return; + break; case CMD.F3D_MOVEMEM: switchTextureStatus(ref mdl, ref tempMaterial, true); F3D_MOVEMEM(ref tempMaterial, ref lvl, cmd); @@ -96,7 +103,8 @@ public static void parse(ref Model3D mdl, ref Level lvl, byte seg, uint off) case CMD.F3D_VTX: switchTextureStatus(ref mdl, ref tempMaterial, false); //if (tempMaterial.id != 0) return; - F3D_VTX(vertices, ref lvl, cmd); + if(!F3D_VTX(vertices, ref lvl, cmd)) + return; break; case CMD.F3D_DL: F3D_DL(ref mdl, ref lvl, cmd); @@ -158,7 +166,7 @@ private static void switchTextureStatus(ref Model3D mdl, ref TempMaterial temp, mdl.builder.AddTexture( TextureFormats.decodeTexture( temp.format, - rom.getDataFromSegmentAddress( + rom.getDataFromSegmentAddress_safe( temp.segOff, (uint)(temp.w * temp.h * 2) ), @@ -192,13 +200,15 @@ private static void F3D_MOVEMEM(ref TempMaterial temp, ref Level lvl, byte[] cmd } } - private static void F3D_VTX(F3D_Vertex[] vertices, ref Level lvl, byte[] cmd) + private static bool F3D_VTX(F3D_Vertex[] vertices, ref Level lvl, byte[] cmd) { ROM rom = ROM.Instance; int amount = ((cmd[2] << 8) | cmd[3]) / 0x10; byte seg = cmd[4]; uint off = bytesToInt(cmd, 5, 3); // Console.WriteLine("04: Amt = " + amount + ", Seg = " + seg.ToString("X2")+", Off = "+off.ToString("X6")); + if (rom.getSegment(seg) == null) + return false; byte[] vData = rom.getSubArray(rom.getSegment(seg), off, (uint)amount * 0x10); for (int i = 0; i < amount; i++) { @@ -213,6 +223,7 @@ private static void F3D_VTX(F3D_Vertex[] vertices, ref Level lvl, byte[] cmd) vertices[i].nz_b = vData[i * 0x10 + 14]; vertices[i].a = vData[i * 0x10 + 15]; } + return true; } private static void F3D_DL(ref Model3D mdl, ref Level lvl, byte[] cmd) diff --git a/src/Scripts/LevelScripts.cs b/src/Scripts/LevelScripts.cs index 91b5c12..3ef420d 100644 --- a/src/Scripts/LevelScripts.cs +++ b/src/Scripts/LevelScripts.cs @@ -530,8 +530,9 @@ private static void CMD_39(ref Level lvl, byte[] cmd, ROM rom) newObj.HideProperty(Object3D.FLAGS.BPARAM_3); newObj.HideProperty(Object3D.FLAGS.BPARAM_4); newObj.ModelID = entryData[5]; - newObj.setPresetID((ushort)(data[0] & 0x1FF)); - newObj.yRot = (short)((data[0] >> 4) * 22.5f); + ushort firstAndSecond = (ushort)bytesToInt(data, 0, 2); + newObj.setPresetID((ushort)(firstAndSecond & 0x1FF)); + newObj.yRot = (short)((firstAndSecond >> 9) * 2.8125); newObj.xPos = (short)bytesToInt(data, 2, 2); newObj.yPos = (short)bytesToInt(data, 4, 2); newObj.zPos = (short)bytesToInt(data, 6, 2); diff --git a/src/TestROM/LaunchROM.cs b/src/TestROM/LaunchROM.cs index 13098df..268569e 100644 --- a/src/TestROM/LaunchROM.cs +++ b/src/TestROM/LaunchROM.cs @@ -41,6 +41,18 @@ public static void OpenEmulator() } if (runProgram) { + + if (Globals.needToSave && !Globals.autoSaveWhenClickEmulator) + { + DialogResult saveResult = Prompts.ShowShouldSaveDialog(); + if (saveResult == DialogResult.Cancel) + return; + } + else if (Globals.needToSave && Globals.autoSaveWhenClickEmulator) + { + ROM.Instance.saveFileAs(ROM.Instance.Filepath, ROM.Instance.Endian); + } + Process p = new Process(); p.StartInfo.FileName = Globals.pathToEmulator; p.StartInfo.Arguments = ROM.Instance.Filepath; diff --git a/src/Viewer/Model3D.cs b/src/Viewer/Model3D.cs index c765c23..adeea8a 100644 --- a/src/Viewer/Model3D.cs +++ b/src/Viewer/Model3D.cs @@ -174,15 +174,17 @@ public void drawModel(Vector3 scale, Quaternion rot, Vector3 pos) GL.BindBuffer(BufferTarget.ArrayBuffer, m.colorBuf); GL.ColorPointer(4, ColorPointerType.Float, 0, IntPtr.Zero); GL.BindBuffer(BufferTarget.ElementArrayBuffer, m.ibo); - if(!Globals.doWireframe) - GL.DrawElements(PrimitiveType.Triangles, m.indices.Length, - DrawElementsType.UnsignedInt, IntPtr.Zero); + + if (Globals.doWireframe) + GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line); else - GL.DrawElements(PrimitiveType.Lines, m.indices.Length, - DrawElementsType.UnsignedInt, IntPtr.Zero); - - // GL.BindBuffer(BufferTarget.ArrayBuffer, 0); - // GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); + GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); + + GL.DrawElements(PrimitiveType.Triangles, m.indices.Length, + DrawElementsType.UnsignedInt, IntPtr.Zero); + + if (Globals.doWireframe) + GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); } GL.DisableClientState(ArrayCap.VertexArray);