Merge branch 'main' into '3dSkinRenderer'

This commit is contained in:
miku-666
2024-04-06 12:22:06 +02:00
15 changed files with 1703 additions and 1677 deletions

View File

@@ -10,9 +10,12 @@ using System.Drawing.Imaging;
using OMI.Formats.Pck;
using OMI.Formats.GameRule;
using OMI.Formats.Languages;
using OMI.Formats.Model;
using OMI.Workers.Archive;
using OMI.Workers.Pck;
using OMI.Workers.GameRule;
using OMI.Workers.Language;
using OMI.Workers.Model;
using PckStudio.Properties;
using PckStudio.Internal.FileFormats;
using PckStudio.Forms;
@@ -30,6 +33,9 @@ using PckStudio.Classes.Utils;
using PckStudio.Helper;
using System.Text.RegularExpressions;
using PckStudio.Internal.Json;
using PckStudio.Internal.Deserializer;
using PckStudio.Internal.Serializer;
using OMI.Workers;
namespace PckStudio
{
@@ -92,44 +98,38 @@ namespace PckStudio
[PckFileType.TextureFile] = HandleTextureFile,
[PckFileType.UIDataFile] = _ => throw new NotSupportedException("unused in-game"),
[PckFileType.InfoFile] = null,
[PckFileType.TexturePackInfoFile] = HandleInnerPckFile,
[PckFileType.TexturePackInfoFile] = null, // HandleInnerPckFile,
[PckFileType.LocalisationFile] = HandleLocalisationFile,
[PckFileType.GameRulesFile] = HandleGameRuleFile,
[PckFileType.AudioFile] = HandleAudioFile,
[PckFileType.ColourTableFile] = HandleColourFile,
[PckFileType.GameRulesHeader] = HandleGameRuleFile,
[PckFileType.SkinDataFile] = HandleInnerPckFile,
[PckFileType.ModelsFile] = null, //HandleModelsFile, // Note: Uncomment when implemented
[PckFileType.SkinDataFile] = null, // HandleInnerPckFile,
[PckFileType.ModelsFile] = null, //HandleModelsFile, // Note: Uncomment when implemented
[PckFileType.BehavioursFile] = HandleBehavioursFile,
[PckFileType.MaterialFile] = HandleMaterialFile,
};
}
// TODO: decide on how to handle embedded pck files
private void HandleInnerPckFile(PckFileData file)
{
// TODO: decide on how to handle embedded pck files
return;
if (Settings.Default.LoadSubPcks &&
(file.Filetype == PckFileType.SkinDataFile || file.Filetype == PckFileType.TexturePackInfoFile) &&
file.Size > 0 && treeViewMain.SelectedNode.Nodes.Count == 0)
{
using (var stream = new MemoryStream(file.Data))
try
{
try
{
var reader = new PckFileReader(LittleEndianCheckBox.Checked ? OMI.Endianness.LittleEndian : OMI.Endianness.BigEndian);
PckFile subPCKfile = reader.FromStream(stream);
BuildPckTreeView(treeViewMain.SelectedNode.Nodes, subPCKfile);
treeViewMain.SelectedNode.ExpandAll();
}
catch (OverflowException ex)
{
MessageBox.Show(this, "Failed to open pck\n" +
"Try checking the 'Open/Save as Switch/Vita/PS4 pck' checkbox in the upper right corner.",
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
Debug.WriteLine(ex.Message);
}
PckFile subPCKfile = file.GetData(new PckFileReader(LittleEndianCheckBox.Checked ? OMI.Endianness.LittleEndian : OMI.Endianness.BigEndian));
BuildPckTreeView(treeViewMain.SelectedNode.Nodes, subPCKfile);
treeViewMain.SelectedNode.ExpandAll();
}
catch (OverflowException ex)
{
MessageBox.Show(this, "Failed to open pck\n" +
"Try checking the 'Open/Save as Switch/Vita/PS4 pck' checkbox in the upper right corner.",
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
Debug.WriteLine(ex.Message);
}
return;
}
@@ -144,9 +144,9 @@ namespace PckStudio
public void LoadPckFromFile(string filepath)
{
checkSaveState();
CheckSaveState();
treeViewMain.Nodes.Clear();
currentPCK = openPck(filepath);
currentPCK = OpenPck(filepath);
if (currentPCK == null)
{
MessageBox.Show(this, string.Format("Failed to load {0}", Path.GetFileName(filepath)), "Error");
@@ -211,7 +211,7 @@ namespace PckStudio
if (!string.IsNullOrWhiteSpace(filepath))
{
string displayFilepath = Regex.Replace(filepath, @"([A-Z]{1}\:\\[Uu]sers\\)([^\\]*\\)(.*)", "~\\$3");
var item = recentlyOpenToolStripMenuItem.DropDownItems.Add(displayFilepath, null, HandleOpenFile);
ToolStripItem item = recentlyOpenToolStripMenuItem.DropDownItems.Add(displayFilepath, null, HandleOpenFile);
item.Tag = filepath;
}
}
@@ -219,7 +219,7 @@ namespace PckStudio
private void HandleOpenFile(object sender, EventArgs e)
{
if (((ToolStripMenuItem)sender).Tag is string filepath && File.Exists(filepath))
if (sender is ToolStripItem menuItem && menuItem.Tag is string filepath && File.Exists(filepath))
LoadPckFromFile(filepath);
}
@@ -232,9 +232,9 @@ namespace PckStudio
Settings.Default.RecentFiles.Insert(0, filepath);
for (int i = Settings.Default.RecentFiles.Count - 1; i >= 5; i--)
{
Settings.Default.RecentFiles.RemoveAt(i);
}
{
Settings.Default.RecentFiles.RemoveAt(i);
}
Settings.Default.Save();
LoadRecentFileList();
}
@@ -242,10 +242,23 @@ namespace PckStudio
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
PckManager?.Close();
checkSaveState();
CheckSaveState();
}
private void openToolStripMenuItem_Click(object sender, EventArgs e)
private void openPckManagerToolStripMenuItem_Click(object sender, EventArgs e)
{
PckManager ??= new PckManager();
PckManager.FormClosing += (s, e) => PckManager = null;
if (!PckManager.Visible)
{
// Passing in a parent form will make it stay on top of every other form. -miku
PckManager.Show();
}
if (PckManager.Focus())
PckManager.BringToFront();
}
private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
using (var ofd = new OpenFileDialog())
{
@@ -258,7 +271,7 @@ namespace PckStudio
}
}
private PckFile openPck(string filePath)
private PckFile OpenPck(string filePath)
{
isTemplateFile = false;
saveLocation = filePath;
@@ -501,7 +514,7 @@ namespace PckStudio
texture = _img;
}
file.SetData(texture, ImageFormat.Png);
file.SetTexture(texture);
wasModified = true;
BuildMainTreeView();
}
@@ -512,7 +525,7 @@ namespace PckStudio
!file.Filename.StartsWith(ResourceLocation.GetPathFromCategory(ResourceCategory.BlockAnimation)))
return;
Animation animation = file.Get(AnimationDeserializer.DefaultDeserializer);
Animation animation = file.GetDeserializedData(AnimationDeserializer.DefaultDeserializer);
string filename = Path.GetFileNameWithoutExtension(file.Filename);
var textureInfos = ResourceLocation.GetCategoryFromPath(file.Filename) switch
@@ -530,7 +543,7 @@ namespace PckStudio
if (animationEditor.ShowDialog(this) == DialogResult.OK)
{
wasModified = true;
file.SetData(animationEditor.Result, AnimationSerializer.DefaultSerializer);
file.SetSerializedData(animationEditor.Result, AnimationSerializer.DefaultSerializer);
BuildMainTreeView();
}
}
@@ -556,7 +569,7 @@ namespace PckStudio
_ => GameRuleFile.CompressionType.Unknown
};
GameRuleFile grf = file.Get(new GameRuleFileReader(compressiontype));
GameRuleFile grf = file.GetData(new GameRuleFileReader(compressiontype));
using GameRuleFileEditor grfEditor = new GameRuleFileEditor(grf);
if (grfEditor.ShowDialog(this) == DialogResult.OK)
@@ -1087,7 +1100,7 @@ namespace PckStudio
{
wasModified = true;
PckFileData file = currentPCK.CreateNewFile(animationFilepath, PckFileType.TextureFile);
file.SetData(animationEditor.Result, AnimationSerializer.DefaultSerializer);
file.SetSerializedData(animationEditor.Result, AnimationSerializer.DefaultSerializer);
BuildMainTreeView();
ReloadMetaTreeView();
}
@@ -1443,10 +1456,10 @@ namespace PckStudio
PckFile infoPCK = new PckFile(3);
PckFileData icon = infoPCK.CreateNewFile("icon.png", PckFileType.TextureFile);
icon.SetData(Resources.TexturePackIcon, ImageFormat.Png);
icon.SetTexture(Resources.TexturePackIcon);
PckFileData comparison = infoPCK.CreateNewFile("comparison.png", PckFileType.TextureFile);
comparison.SetData(Resources.Comparison, ImageFormat.Png);
comparison.SetTexture(Resources.Comparison);
PckFileData texturepackInfo = pack.CreateNewFile($"{res}/{res}Info.pck", PckFileType.TexturePackInfoFile);
texturepackInfo.AddProperty("PACKID", "0");
@@ -1484,7 +1497,7 @@ namespace PckStudio
private void skinPackToolStripMenuItem_Click(object sender, EventArgs e)
{
checkSaveState();
CheckSaveState();
TextPrompt namePrompt = new TextPrompt();
namePrompt.OKButtonText = "Ok";
if (namePrompt.ShowDialog(this) == DialogResult.OK)
@@ -1498,7 +1511,7 @@ namespace PckStudio
private void texturePackToolStripMenuItem_Click(object sender, EventArgs e)
{
checkSaveState();
CheckSaveState();
CreateTexturePackPrompt packPrompt = new CreateTexturePackPrompt();
if (packPrompt.ShowDialog(this) == DialogResult.OK)
{
@@ -1511,7 +1524,7 @@ namespace PckStudio
private void mashUpPackToolStripMenuItem_Click(object sender, EventArgs e)
{
checkSaveState();
CheckSaveState();
CreateTexturePackPrompt packPrompt = new CreateTexturePackPrompt();
if (packPrompt.ShowDialog(this) == DialogResult.OK)
{
@@ -1535,7 +1548,7 @@ namespace PckStudio
private void closeToolStripMenuItem_Click(object sender, EventArgs e)
{
checkSaveState();
CheckSaveState();
CloseEditorTab();
}
@@ -1835,7 +1848,7 @@ namespace PckStudio
pckOpen.Image = Resources.pckClosed;
}
private void checkSaveState()
private void CheckSaveState()
{
if (currentPCK is not null &&
wasModified &&
@@ -2053,7 +2066,7 @@ namespace PckStudio
gfx.DrawImage(originalTexture, tileArea);
}
MipMappedFile.SetData(mippedTexture, ImageFormat.Png);
MipMappedFile.SetTexture(mippedTexture);
currentPCK.InsertFile(currentPCK.IndexOfFile(file) + i - 1, MipMappedFile);
}
@@ -2237,23 +2250,6 @@ namespace PckStudio
Process.Start("https://trello.com/b/0XLNOEbe/pck-studio");
}
private void openPckManagerToolStripMenuItem_Click(object sender, EventArgs e)
{
PckManager ??= new PckManager();
PckManager.FormClosing += (s, e) =>
{
PckManager.Hide();
e.Cancel = true;
};
if (!PckManager.Visible)
{
// passing in a parent form will make it stay on top of every other form. -miku
PckManager.Show();
}
if (PckManager.Focus())
PckManager.BringToFront();
}
private void wavBinkaToolStripMenuItem_Click(object sender, EventArgs e)
{
using OpenFileDialog fileDialog = new OpenFileDialog
@@ -2408,24 +2404,21 @@ namespace PckStudio
Application.Exit();
}
private void setPCKEndiannessStripMenuItem_Click(OMI.Endianness endianness)
private void SetPckEndianness(OMI.Endianness endianness)
{
try
{
if (treeViewMain.SelectedNode.Tag is PckFileData file && (file.Filetype is PckFileType.AudioFile || file.Filetype is PckFileType.SkinDataFile || file.Filetype is PckFileType.TexturePackInfoFile))
{
using (var stream = new MemoryStream())
{
dynamic reader = file.Filetype is PckFileType.AudioFile
? new PckAudioFileReader(endianness == OMI.Endianness.BigEndian ? OMI.Endianness.LittleEndian : OMI.Endianness.BigEndian)
: new PckFileReader(endianness == OMI.Endianness.BigEndian ? OMI.Endianness.LittleEndian : OMI.Endianness.BigEndian);
var pck = reader.FromStream(new MemoryStream(file.Data));
dynamic writer = file.Filetype is PckFileType.AudioFile
? new PckAudioFileWriter(pck, endianness)
: new PckFileWriter(pck, endianness);
writer.WriteToStream(stream);
file.SetData(stream.ToArray());
}
IDataFormatReader reader = file.Filetype is PckFileType.AudioFile
? new PckAudioFileReader(endianness == OMI.Endianness.BigEndian ? OMI.Endianness.LittleEndian : OMI.Endianness.BigEndian)
: new PckFileReader(endianness == OMI.Endianness.BigEndian ? OMI.Endianness.LittleEndian : OMI.Endianness.BigEndian);
object pck = reader.FromStream(new MemoryStream(file.Data));
IDataFormatWriter writer = file.Filetype is PckFileType.AudioFile
? new PckAudioFileWriter((PckAudioFile)pck, endianness)
: new PckFileWriter((PckFile)pck, endianness);
file.SetData(writer);
wasModified = true;
MessageBox.Show($"\"{file.Filename}\" successfully converted to {(endianness == OMI.Endianness.LittleEndian ? "little" : "big")} endian.", "Converted PCK file");
}
@@ -2442,7 +2435,67 @@ namespace PckStudio
}
}
private void littleEndianToolStripMenuItem_Click(object sender, EventArgs e) => setPCKEndiannessStripMenuItem_Click(OMI.Endianness.LittleEndian);
private void bigEndianToolStripMenuItem_Click(object sender, EventArgs e) => setPCKEndiannessStripMenuItem_Click(OMI.Endianness.BigEndian);
}
private void littleEndianToolStripMenuItem_Click(object sender, EventArgs e) => SetPckEndianness(OMI.Endianness.LittleEndian);
private void bigEndianToolStripMenuItem_Click(object sender, EventArgs e) => SetPckEndianness(OMI.Endianness.BigEndian);
private void SetModelVersion(int version)
{
if (treeViewMain.SelectedNode.Tag is PckFileData file && file.Filetype is PckFileType.ModelsFile)
{
try
{
ModelContainer container = file.GetData(new ModelFileReader());
if (container.Version == version)
{
MessageBox.Show(
this,
$"This model container is already Version {version + 1}.",
"Can't convert", MessageBoxButtons.OK, MessageBoxIcon.Error
);
return;
}
if (version == 2 &&
MessageBox.Show(
this,
"Conversion to 1.14 models.bin format does not yet support parent declaration and may not be 100% accurate.\n" +
"Would you like to continue?", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) != DialogResult.Yes
)
{
return;
}
if (container.Version > 1 &&
MessageBox.Show(
this,
"Conversion from 1.14 models.bin format does not yet support parent parts and may not be 100% accurate.\n" +
"Would you like to continue?", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) != DialogResult.Yes
)
{
return;
}
file.SetData(new ModelFileWriter(container, version));
wasModified = true;
MessageBox.Show(
this,
$"\"{file.Filename}\" successfully converted to Version {version + 1} format.",
"Converted model container file"
);
}
catch (Exception ex)
{
MessageBox.Show(this, ex.Message, "Not a valid model container file.");
return;
}
}
}
private void setModelVersion1ToolStripMenuItem_Click(object sender, EventArgs e) => SetModelVersion(0);
private void setModelVersion2ToolStripMenuItem_Click(object sender, EventArgs e) => SetModelVersion(1);
private void setModelVersion3ToolStripMenuItem_Click(object sender, EventArgs e) => SetModelVersion(2);
}
}