From 59bf4f87f97b7cb59f74917375aa2bbfb07cc12c Mon Sep 17 00:00:00 2001 From: AdAstra-LD Date: Wed, 28 Apr 2021 17:42:07 +0200 Subject: [PATCH] Added a couple missing features [Camera Editor] - Import/Export buttons are now fully working - Added "Blank BGS" button to Map Editor - Fixed "Lock X" and "Lock Z" mutex --- DS_Map/GameCamera.cs | 150 +++++++++++++++++++++------------ DS_Map/Main Window.Designer.cs | 22 ++++- DS_Map/Main Window.cs | 112 ++++++++++++++++-------- DS_Map/Main Window.resx | 2 +- DS_Map/RomInfo.cs | 9 +- 5 files changed, 203 insertions(+), 92 deletions(-) diff --git a/DS_Map/GameCamera.cs b/DS_Map/GameCamera.cs index 802e691..6b80be3 100644 --- a/DS_Map/GameCamera.cs +++ b/DS_Map/GameCamera.cs @@ -57,41 +57,46 @@ public class GameCamera { } } set { - switch (index) { - case 0: - distance = Convert.ToUInt32(value); - break; - case 1: - vertRot = Convert.ToInt16(value); - break; - case 2: - horiRot = Convert.ToInt16(value); - break; - case 3: - zRot = Convert.ToInt16(value); - break; - case 4: - perspMode = (byte)(Convert.ToBoolean(value) ? 1 : 0); - break; - case 5: - fov = Convert.ToUInt16(value); - break; - case 6: - nearClip = Convert.ToUInt32(value); - break; - case 7: - farClip = Convert.ToUInt32(value); - break; - case 8: - xOffset = Convert.ToInt32(value); - break; - case 9: - yOffset = Convert.ToInt32(value); - break; - case 10: - zOffset = Convert.ToInt32(value); - break; - + try { + switch (index) { + case 0: + distance = Convert.ToUInt32(value); + break; + case 1: + vertRot = Convert.ToInt16(value); + break; + case 2: + horiRot = Convert.ToInt16(value); + break; + case 3: + zRot = Convert.ToInt16(value); + break; + case 4: + perspMode = (byte)(Convert.ToBoolean(value) ? 1 : 0); + break; + case 5: + fov = Convert.ToUInt16(value); + break; + case 6: + nearClip = Convert.ToUInt32(value); + break; + case 7: + farClip = Convert.ToUInt32(value); + break; + case 8: + xOffset = Convert.ToInt32(value); + break; + case 9: + yOffset = Convert.ToInt32(value); + break; + case 10: + zOffset = Convert.ToInt32(value); + break; + } + } catch (OverflowException e) { + MessageBox.Show("The value you selected is invalid.\n\n" + '"' + e.Message + '"', "Overflow", MessageBoxButtons.OK, MessageBoxIcon.Error); + } catch (FormatException) { + MessageBox.Show("Only numeric values are allowed.", "Invalid input", MessageBoxButtons.OK, MessageBoxIcon.Error); } } } @@ -104,9 +109,11 @@ public class GameCamera { this.distance = distance; this.vertRot = vertRot; this.horiRot = horiRot; + this.zRot = zRot; this.unk1 = unk1; this.perspMode = perspMode; + this.unk2 = unk2; this.fov = fov; this.nearClip = nearClip; @@ -116,6 +123,37 @@ public class GameCamera { this.yOffset = yOffset; this.zOffset = zOffset; } + + public GameCamera(byte[] camData) { + if (camData.Length != 36 && camData.Length != 24) { + MessageBox.Show("This is not a camera file.\nMake sure the file is 36 or 24 bytes long and try again.", "Wrong file!", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + try { + using (BinaryReader b = new BinaryReader(new MemoryStream(camData))) { + distance = b.ReadUInt32(); + vertRot = b.ReadInt16(); + horiRot = b.ReadInt16(); + zRot = b.ReadInt16(); + + unk1 = b.ReadInt16(); + perspMode = b.ReadByte(); + unk2 = b.ReadByte(); + + fov = b.ReadUInt16(); + nearClip = b.ReadUInt32(); + farClip = b.ReadUInt32(); + + if (DSPRE.RomInfo.gameFamily.Equals("HGSS")) { + xOffset = b.ReadInt32(); + yOffset = b.ReadInt32(); + zOffset = b.ReadInt32(); + } + } + } catch (EndOfStreamException) { + MessageBox.Show("You might have to manually fill in the last three camera fields, since DPPt cameras don't have them.", "DPPt Cam detected", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } public byte[] ToByteArray() { MemoryStream newData = new MemoryStream(); using (BinaryWriter writer = new BinaryWriter(newData)) { @@ -143,29 +181,33 @@ public class GameCamera { return newData.ToArray(); } - public void AddToGridView(DataGridView dgv) { - dgv.Rows.Add(); - int cRows = dgv.RowCount; - int cellIndex = 0; + public void ShowInGridView(DataGridView dgv, int rowIndex) { + if (rowIndex > dgv.Rows.Count - 1) { + dgv.Rows.Add(); + } - dgv.Rows[cRows-1].HeaderCell.Value = String.Format("{0}", dgv.Rows[cRows - 1].Index); + int colIndex = 0; - dgv.Rows[cRows - 1].Cells[cellIndex++].Value = distance; - dgv.Rows[cRows - 1].Cells[cellIndex++].Value = vertRot; - dgv.Rows[cRows - 1].Cells[cellIndex++].Value = horiRot; - dgv.Rows[cRows - 1].Cells[cellIndex++].Value = zRot; + dgv.Rows[rowIndex].HeaderCell.Value = String.Format("{0}", dgv.Rows[rowIndex].Index); - dgv.Rows[cRows - 1].Cells[cellIndex++].Value = perspMode == ORTHO; + dgv.Rows[rowIndex].Cells[colIndex++].Value = distance; + dgv.Rows[rowIndex].Cells[colIndex++].Value = vertRot; + dgv.Rows[rowIndex].Cells[colIndex++].Value = horiRot; + dgv.Rows[rowIndex].Cells[colIndex++].Value = zRot; - dgv.Rows[cRows - 1].Cells[cellIndex++].Value = fov; - dgv.Rows[cRows - 1].Cells[cellIndex++].Value = nearClip; - dgv.Rows[cRows - 1].Cells[cellIndex++].Value = farClip; + dgv.Rows[rowIndex].Cells[colIndex++].Value = perspMode == ORTHO; - if (xOffset != null) - dgv.Rows[cRows - 1].Cells[cellIndex++].Value = xOffset; - if (yOffset != null) - dgv.Rows[cRows - 1].Cells[cellIndex++].Value = yOffset; - if (zOffset != null) - dgv.Rows[cRows - 1].Cells[cellIndex++].Value = zOffset; + dgv.Rows[rowIndex].Cells[colIndex++].Value = fov; + dgv.Rows[rowIndex].Cells[colIndex++].Value = nearClip; + dgv.Rows[rowIndex].Cells[colIndex++].Value = farClip; + + if (colIndex < dgv.Columns.Count-3) { + if (xOffset != null) + dgv.Rows[rowIndex].Cells[colIndex++].Value = xOffset; + if (yOffset != null) + dgv.Rows[rowIndex].Cells[colIndex++].Value = yOffset; + if (zOffset != null) + dgv.Rows[rowIndex].Cells[colIndex++].Value = zOffset; + } } } diff --git a/DS_Map/Main Window.Designer.cs b/DS_Map/Main Window.Designer.cs index d368623..81bd4e2 100644 --- a/DS_Map/Main Window.Designer.cs +++ b/DS_Map/Main Window.Designer.cs @@ -271,6 +271,7 @@ this.bdhcImportButton = new System.Windows.Forms.Button(); this.bdhcExportButton = new System.Windows.Forms.Button(); this.bgsTabPage = new System.Windows.Forms.TabPage(); + this.blankBGSButton = new System.Windows.Forms.Button(); this.BGSSizeTXT = new System.Windows.Forms.TextBox(); this.textBox7 = new System.Windows.Forms.TextBox(); this.textBox2 = new System.Windows.Forms.TextBox(); @@ -3558,6 +3559,7 @@ // // bgsTabPage // + this.bgsTabPage.Controls.Add(this.blankBGSButton); this.bgsTabPage.Controls.Add(this.BGSSizeTXT); this.bgsTabPage.Controls.Add(this.textBox7); this.bgsTabPage.Controls.Add(this.textBox2); @@ -3570,6 +3572,19 @@ this.bgsTabPage.Text = "Sound Plates"; this.bgsTabPage.UseVisualStyleBackColor = true; // + // blankBGSButton + // + this.blankBGSButton.Image = global::DSPRE.Properties.Resources.destroyLevelScript; + this.blankBGSButton.ImageAlign = System.Drawing.ContentAlignment.MiddleRight; + this.blankBGSButton.Location = new System.Drawing.Point(277, 109); + this.blankBGSButton.Name = "blankBGSButton"; + this.blankBGSButton.Size = new System.Drawing.Size(120, 38); + this.blankBGSButton.TabIndex = 34; + this.blankBGSButton.Text = "Blank BGS"; + this.blankBGSButton.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.blankBGSButton.UseVisualStyleBackColor = true; + this.blankBGSButton.Click += new System.EventHandler(this.soundPlatesBlankButton_Click); + // // BGSSizeTXT // this.BGSSizeTXT.BackColor = System.Drawing.SystemColors.Window; @@ -7606,6 +7621,7 @@ this.importCameraTableButton.Text = "Import\r\nCamera Table"; this.importCameraTableButton.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; this.importCameraTableButton.UseVisualStyleBackColor = true; + this.importCameraTableButton.Click += new System.EventHandler(this.importCameraTableButton_Click); // // saveCameraTableButton // @@ -7657,12 +7673,13 @@ this.cameraEditorDataGridView.MultiSelect = false; this.cameraEditorDataGridView.Name = "cameraEditorDataGridView"; this.cameraEditorDataGridView.RowHeadersWidth = 60; - this.cameraEditorDataGridView.RowTemplate.DividerHeight = 2; - this.cameraEditorDataGridView.RowTemplate.Height = 30; + this.cameraEditorDataGridView.RowTemplate.DividerHeight = 1; + this.cameraEditorDataGridView.RowTemplate.Height = 32; this.cameraEditorDataGridView.ScrollBars = System.Windows.Forms.ScrollBars.None; this.cameraEditorDataGridView.Size = new System.Drawing.Size(1172, 551); this.cameraEditorDataGridView.TabIndex = 0; this.cameraEditorDataGridView.TabStop = false; + this.cameraEditorDataGridView.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.cameraEditorDataGridView_CellContentClick); this.cameraEditorDataGridView.CellEndEdit += new System.Windows.Forms.DataGridViewCellEventHandler(this.cameraEditorDataGridView_CellValidated); // // DistanceGVCol @@ -9178,6 +9195,7 @@ private System.Windows.Forms.RadioButton bldRoundCentMil; private System.Windows.Forms.CheckBox bldPlaceWithMouseCheckbox; private System.Windows.Forms.GroupBox lockXZgroupbox; + private System.Windows.Forms.Button blankBGSButton; } } diff --git a/DS_Map/Main Window.cs b/DS_Map/Main Window.cs index 2e0f3a3..101c08b 100644 --- a/DS_Map/Main Window.cs +++ b/DS_Map/Main Window.cs @@ -606,7 +606,7 @@ namespace DSPRE { statusLabel.Text = "Ready"; } private void SetupCameraEditor() { - RomInfo.SetCameraTableOverlayAndOffsets(); + RomInfo.PrepareCameraData(); if (DSUtils.CheckOverlayHasCompressionFlag(RomInfo.cameraTblOverlayNumber)) { if (DSUtils.OverlayIsCompressed(RomInfo.cameraTblOverlayNumber)) { @@ -654,8 +654,8 @@ namespace DSPRE { br.ReadUInt16(), br.ReadUInt32(), br.ReadUInt32()); } } - foreach (GameCamera v in currentCameraTable) { - v.AddToGridView(cameraEditorDataGridView); + for (int i = 0; i < currentCameraTable.Length; i++) { + currentCameraTable[i].ShowInGridView(cameraEditorDataGridView, i); } } } @@ -2855,7 +2855,6 @@ namespace DSPRE { Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT); } #endregion - private void addMapFileButton_Click(object sender, EventArgs e) { /* Add new map file to map folder */ new MapFile(0).SaveToFileDefaultDir(selectMapComboBox.Items.Count); @@ -2910,8 +2909,6 @@ namespace DSPRE { } } //buildTextureComboBox.Items[buildTextureComboBox.SelectedIndex] = "Error - Building Texture Pack too small [" + (buildTextureComboBox.SelectedIndex - 1).ToString("D2") + "]"; - - } RenderMap(ref mapRenderer, ref buildingsRenderer, ref currentMapFile, ang, dist, elev, perspective, mapOpenGlControl.Width, mapOpenGlControl.Height, mapTexturesOn, showBuildingTextures); @@ -2975,29 +2972,42 @@ namespace DSPRE { } } } - private void bldRoundWhole_CheckedChanged(object sender, EventArgs e) { bldDecimalPositions = 0; } - private void bldRoundDec_CheckedChanged(object sender, EventArgs e) { bldDecimalPositions = 1; } - private void bldRoundCent_CheckedChanged(object sender, EventArgs e) { bldDecimalPositions = 2; } - private void bldRoundMil_CheckedChanged(object sender, EventArgs e) { bldDecimalPositions = 3; } - private void bldRoundDecmil_CheckedChanged(object sender, EventArgs e) { bldDecimalPositions = 4; } private void bldRoundCentMil_CheckedChanged(object sender, EventArgs e) { bldDecimalPositions = 5; } + private void bldPlaceWithMouseCheckbox_CheckedChanged(object sender, EventArgs e) { + bool status = bldPlaceWithMouseCheckbox.Checked && radio2D.Checked; + bldPlaceLockXcheckbox.Enabled = status; + bldPlaceLockZcheckbox.Enabled = status; + bldRoundGroupbox.Enabled = status; + lockXZgroupbox.Enabled = status; + + if (status) { + SetCam2D(); + } + } + private void bldPlaceLockXcheckbox_CheckedChanged(object sender, EventArgs e) { + ExclusiveCBInvert(bldPlaceLockZcheckbox); + } + + private void bldPlaceLockZcheckbox_CheckedChanged(object sender, EventArgs e) { + ExclusiveCBInvert(bldPlaceLockXcheckbox); + } private void mapPartsTabControl_SelectedIndexChanged(object sender, EventArgs e) { if (mapPartsTabControl.SelectedTab == buildingsTabPage) { radio2D.Checked = false; @@ -4031,6 +4041,11 @@ namespace DSPRE { BGSSizeTXT.Text = currentMapFile.bgs.Length.ToString() + " B"; MessageBox.Show("BackGround Sound data exported successfully!", "", MessageBoxButtons.OK, MessageBoxIcon.Information); } + private void soundPlatesBlankButton_Click(object sender, EventArgs e) { + currentMapFile.bgs = new byte[] { 0x34, 0x12, 0x00, 0x00 }; + BGSSizeTXT.Text = currentMapFile.bgs.Length.ToString() + " B"; + MessageBox.Show("BackGround Sound data successfull blanked.\nRemember to save the current map file.", "", MessageBoxButtons.OK, MessageBoxIcon.Information); + } #endregion #endregion @@ -6667,12 +6682,11 @@ namespace DSPRE { string path = DSUtils.GetOverlayPath(RomInfo.cameraTblOverlayNumber); SaveCameraTable(path, overlayCameraTblOffset); } - private void cameraEditorDataGridView_CellValidated(object sender, DataGridViewCellEventArgs e) { - cameraEditorDataGridView.Columns[0].ValueType = typeof(int); + //cameraEditorDataGridView.Columns[0].ValueType = typeof(int); currentCameraTable[e.RowIndex][e.ColumnIndex] = cameraEditorDataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value; + cameraEditorDataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = currentCameraTable[e.RowIndex][e.ColumnIndex]; } - private void exportCameraTableButton_Click(object sender, EventArgs e) { SaveFileDialog of = new SaveFileDialog { Filter = "Camera Table File (*.bin)|*.bin", @@ -6684,37 +6698,69 @@ namespace DSPRE { File.Delete(of.FileName); SaveCameraTable(of.FileName, 0); } - private void SaveCameraTable (string path, uint destFileOffset) { - int size = RomInfo.gameFamily.Equals("HGSS") ? 36 : 24; - for (int i = 0; i < currentCameraTable.Length; i++) { - DSUtils.WriteToFile(path, currentCameraTable[i].ToByteArray(), (uint)(destFileOffset + i * size)); + DSUtils.WriteToFile(path, currentCameraTable[i].ToByteArray(), (uint)(destFileOffset + i * RomInfo.cameraSize)); } MessageBox.Show("Camera table correctly saved.", "Success!", MessageBoxButtons.OK, MessageBoxIcon.Information); } - #endregion + private void cameraEditorDataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e) { + var senderTable = (DataGridView)sender; - private void bldPlaceWithMouseCheckbox_CheckedChanged(object sender, EventArgs e) { - bool status = bldPlaceWithMouseCheckbox.Checked && radio2D.Checked; - bldPlaceLockXcheckbox.Enabled = status; - bldPlaceLockZcheckbox.Enabled = status; - bldRoundGroupbox.Enabled = status; - lockXZgroupbox.Enabled = status; + if (senderTable.Columns[e.ColumnIndex] is DataGridViewButtonColumn && e.RowIndex >= 0) { + string type = "Camera File"; + if (e.ColumnIndex == cameraEditorDataGridView.Columns.Count - 2) { //Export + SaveFileDialog sf = new SaveFileDialog { + Filter = type + " (*.bin)|*.bin", + FileName = Path.GetFileNameWithoutExtension(RomInfo.workDir) + " - Camera " + e.RowIndex + ".bin" + }; - if (status) { - SetCam2D(); + if (sf.ShowDialog(this) != DialogResult.OK) { + return; + } + + DSUtils.WriteToFile(sf.FileName, currentCameraTable[e.RowIndex].ToByteArray(), fromScratch: true); + MessageBox.Show("Camera correctly saved.", "Success!", MessageBoxButtons.OK, MessageBoxIcon.Information); + } else if (e.ColumnIndex == cameraEditorDataGridView.Columns.Count - 1) { //Import + OpenFileDialog of = new OpenFileDialog { + Filter = type + " (*.bin)|*.bin", + }; + + if (of.ShowDialog(this) != DialogResult.OK) { + return; + } + + currentCameraTable[e.RowIndex] = new GameCamera(File.ReadAllBytes(of.FileName)); + currentCameraTable[e.RowIndex].ShowInGridView(senderTable, e.RowIndex); + MessageBox.Show("Camera correctly imported.", "Success!", MessageBoxButtons.OK, MessageBoxIcon.Information); + } } } + private void importCameraTableButton_Click(object sender, EventArgs e) { + string fileType = "Camera Table File"; + OpenFileDialog of = new OpenFileDialog { + Filter = fileType + " (*.bin)|*.bin", + }; - private void bldPlaceLockXcheckbox_CheckedChanged(object sender, EventArgs e) { - ExclusiveCBInvert(bldPlaceLockZcheckbox); - } + if (of.ShowDialog(this) != DialogResult.OK) { + return; + } - private void bldPlaceLockZcheckbox_CheckedChanged(object sender, EventArgs e) { - ExclusiveCBInvert(bldPlaceLockXcheckbox); + long l = new FileInfo(of.FileName).Length; + if (l % RomInfo.cameraSize != 0) { + MessageBox.Show("This is not a " + RomInfo.gameFamily + ' ' + fileType + + "\nMake sure the file length is a multiple of " + RomInfo.cameraSize + " and try again.", "Wrong file!", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + byte nCameras = (byte)(l / RomInfo.cameraSize); + for (byte b = 0; b < nCameras; b++) { + currentCameraTable[b] = new GameCamera(DSUtils.ReadFromFile(of.FileName, b*RomInfo.cameraSize, RomInfo.cameraSize)); + currentCameraTable[b].ShowInGridView(cameraEditorDataGridView, b); + } + MessageBox.Show("Camera Table imported correctly.", "Success!", MessageBoxButtons.OK, MessageBoxIcon.Information); } - + #endregion private void ExclusiveCBInvert (CheckBox cb) { if (disableHandlers) return; diff --git a/DS_Map/Main Window.resx b/DS_Map/Main Window.resx index 4c98851..762bf95 100644 --- a/DS_Map/Main Window.resx +++ b/DS_Map/Main Window.resx @@ -1191,7 +1191,7 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABk - EAAAAk1TRnQBSQFMAgEBCAEAAeQBEQHkAREBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo + EAAAAk1TRnQBSQFMAgEBCAEAATQBEgE0ARIBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo AwABQAMAATADAAEBAQABCAYAAQwYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA diff --git a/DS_Map/RomInfo.cs b/DS_Map/RomInfo.cs index 8e1b43f..b1c1826 100644 --- a/DS_Map/RomInfo.cs +++ b/DS_Map/RomInfo.cs @@ -42,8 +42,9 @@ namespace DSPRE { public static int locationNamesTextNumber { get; private set; } - public static readonly byte internalNameLength = 16; public static string internalNamesLocation { get; private set; } + public static readonly byte internalNameLength = 16; + public static int cameraSize { get; private set; } public static Dictionary, (Color background, Color foreground)> MapCellsColorDictionary { get; private set; } public static Dictionary ScriptCommandNamesDict { get; private set; } @@ -75,6 +76,7 @@ namespace DSPRE { interiorBuildingModels }; public static Dictionary gameDirs { get; private set; } + #region Constructors (1) public RomInfo(string id, string dir) { @@ -202,18 +204,21 @@ namespace DSPRE { break; } } - public static void SetCameraTableOverlayAndOffsets() { + public static void PrepareCameraData() { switch (gameFamily) { case "DP": cameraTblOverlayNumber = 5; cameraTblOffsetsToRAMaddress = new uint[] { 0 }; + cameraSize = 24; break; case "Plat": cameraTblOverlayNumber = 5; cameraTblOffsetsToRAMaddress = new uint[] { 0x4E24 }; + cameraSize = 24; break; case "HGSS": cameraTblOverlayNumber = 1; + cameraSize = 36; switch (gameLanguage) { case "ENG": case "ESP":