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
This commit is contained in:
AdAstra-LD 2021-04-28 17:42:07 +02:00
parent de368527c8
commit 59bf4f87f9
5 changed files with 203 additions and 92 deletions

View File

@ -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;
}
}
}

View File

@ -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;
}
}

View File

@ -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;

View File

@ -1191,7 +1191,7 @@
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABk
EAAAAk1TRnQBSQFMAgEBCAEAAeQBEQHkAREBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
EAAAAk1TRnQBSQFMAgEBCAEAATQBEgE0ARIBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
AwABQAMAATADAAEBAQABCAYAAQwYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA
AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5
AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA

View File

@ -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<List<uint>, (Color background, Color foreground)> MapCellsColorDictionary { get; private set; }
public static Dictionary<ushort, string> ScriptCommandNamesDict { get; private set; }
@ -75,6 +76,7 @@ namespace DSPRE {
interiorBuildingModels
};
public static Dictionary<DirNames, (string packedDir, string unpackedDir)> 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":