rKVaM)BY8c3tTXX`BqL&u~^ZytZWm
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
literal 0
HcmV?d00001
diff --git a/LibW4M/PS2/Resources/icon.sys b/LibW4M/PS2/Resources/icon.sys
new file mode 100644
index 0000000000000000000000000000000000000000..95057064ec9e91d33caa275ada6e18e03e1ce879
GIT binary patch
literal 964
zcmWFtHgaKL5MZDlaIj}!H~_>AKnwy6`+)?M4da8vz~Ufzpj?A}T3Q-Z4LTpB2Rkrg
za4c^sYwB;B)YRKFxhc5OtU`NW>ZH~Yf~?FU6`Vt$@zJPdYQ@jm{LTE477ft
L9673J*oFWAML8y&
literal 0
HcmV?d00001
diff --git a/LibW4M/PS2/SaveResources.Designer.cs b/LibW4M/PS2/SaveResources.Designer.cs
new file mode 100644
index 0000000..5dcad33
--- /dev/null
+++ b/LibW4M/PS2/SaveResources.Designer.cs
@@ -0,0 +1,83 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace LibW4M.PS2 {
+ using System;
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class SaveResources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal SaveResources() {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("LibW4M.PS2.SaveResources", typeof(SaveResources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Byte[].
+ ///
+ public static byte[] IconFile {
+ get {
+ object obj = ResourceManager.GetObject("IconFile", resourceCulture);
+ return ((byte[])(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Byte[].
+ ///
+ public static byte[] IconSys {
+ get {
+ object obj = ResourceManager.GetObject("IconSys", resourceCulture);
+ return ((byte[])(obj));
+ }
+ }
+ }
+}
diff --git a/LibW4M/PS2/SaveResources.resx b/LibW4M/PS2/SaveResources.resx
new file mode 100644
index 0000000..0d1c006
--- /dev/null
+++ b/LibW4M/PS2/SaveResources.resx
@@ -0,0 +1,127 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+
+ Resources\Icon1.ico;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Resources\icon.sys;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/LibW4M/Properties/PublishProfiles/FolderProfile.pubxml b/LibW4M/Properties/PublishProfiles/FolderProfile.pubxml
deleted file mode 100644
index 5f2ccee..0000000
--- a/LibW4M/Properties/PublishProfiles/FolderProfile.pubxml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
- Release
- Any CPU
- bin\Release\net7.0\publish\win-x86\
- FileSystem
- <_TargetId>Folder
- net7.0
- win-x86
- true
- true
- true
- false
-
-
\ No newline at end of file
diff --git a/LibW4M/Properties/PublishProfiles/FolderProfile.pubxml.user b/LibW4M/Properties/PublishProfiles/FolderProfile.pubxml.user
deleted file mode 100644
index 3896d83..0000000
--- a/LibW4M/Properties/PublishProfiles/FolderProfile.pubxml.user
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
- False|2023-02-18T17:31:12.6646298Z;
-
-
-
\ No newline at end of file
diff --git a/LibW4M/W4SaveFile.cs b/LibW4M/W4SaveFile.cs
index 670fcd5..57b0118 100644
--- a/LibW4M/W4SaveFile.cs
+++ b/LibW4M/W4SaveFile.cs
@@ -9,11 +9,13 @@ using LibW4M.Data.WeaponFactory;
using LibW4M.Data.WXFE;
using LibW4M.Data.WXFE.UnlockableItem;
using LibW4M.Data.X;
+using LibW4M.PS2;
using LibXom;
using LibXom.Blocks;
using LibXom.Data;
using LibXom.Exceptions;
using LibXom.Streams;
+using System.Reflection;
using System.Runtime.InteropServices;
using System.Xml.XPath;
@@ -21,24 +23,31 @@ namespace LibW4M
{
public class W4SaveFile
{
- public const int PS2_MAX_SZ = 0x20000;
private List unlockableItems;
private XomFile xomFile;
public DataBank XDataBank;
-
public WeaponsCollective WeaponFactoryCollective;
public TeamsCollective TeamDataColective;
public SchemesCollective SchemesCollective;
public HighscoreCollective HighscoreCollective;
public StatsCollective StatsCollective;
- public StatsCollective TeamStatsCollective;
+ public TeamStatsCollective TeamStatsCollective;
public InputMappingCollective InputMappingCollective;
public TeamAwardsData TeamAwardsContainer;
+ public XomString Message;
+ public XomString FEResourceID;
+ public XomFile OriginalXom
+ {
+ get
+ {
+ return this.xomFile;
+ }
+ }
public UnlockableItemData[] UnlockableItems
{
get
@@ -84,7 +93,7 @@ namespace LibW4M
break;
case "PersistStats":
StatsCollective = new StatsCollective(this, containerResourceDetail.Value);
- TeamStatsCollective = new StatsCollective(this, containerResourceDetail.Value);
+ TeamStatsCollective = new TeamStatsCollective(this, containerResourceDetail.Value);
break;
case "Awards":
TeamAwardsContainer = new TeamAwardsData(this, containerResourceDetail.Value);
@@ -114,11 +123,15 @@ namespace LibW4M
}
}
}
+
- private void saveData()
+ internal void saveData()
{
- XDataBank.Save();
+#if !DEBUG
+ xomFile.ClearAllStrings();
+#endif
+ XDataBank.Save();
WeaponFactoryCollective.Save();
// Save Teams, Highscores
@@ -137,60 +150,44 @@ namespace LibW4M
foreach (UnlockableItemData unlockableItem in UnlockableItems)
unlockableItem.Save();
}
+ public void SavePC(Stream pcSaveStream)
+ {
+ saveData();
+ using (MemoryStream ms = new MemoryStream())
+ {
+ XomWriter.WriteXom(xomFile, pcSaveStream);
-
+ ms.Seek(0, SeekOrigin.Begin);
+ ms.CopyTo(pcSaveStream);
+ }
+ }
+ public void SavePS2PSU(Stream ps2PsuSaveStream)
+ {
+ using (ps2PsuSaveStream)
+ {
+ Ps2Save.CreatePSU(this, ps2PsuSaveStream);
+ }
+ }
+
+ public void SavePS2(Stream ps2SaveStream)
+ {
+ using (ps2SaveStream)
+ {
+ Ps2Save.CreateSaveFile(this, ps2SaveStream);
+ }
+ }
public void SavePS2(string newXom)
{
- // Remove all stats ...
- foreach(StatsContainerData stat in StatsCollective.ToArray())
- StatsCollective.Delete(stat);
-
- // Save changes
- saveData();
-
- using(FileStream fs = File.OpenWrite(newXom))
- {
- using (MemoryStream ms = new MemoryStream())
- {
- using (XomStreamReader reader = new XomStreamReader(ms))
- {
- using (XomStreamWriter writer = new XomStreamWriter(ms))
- {
- XomWriter.WriteXom(xomFile, ms);
-
- // Set size to ps2 save size.
-
- ms.SetLength(PS2_MAX_SZ);
- ms.Seek(0, SeekOrigin.Begin);
-
- // Calculate checksum
-
- Int64 chk = 0;
-
- for (int i = 0; i < (PS2_MAX_SZ - 4); i += 4)
- {
- int c = reader.ReadInt32();
- chk = (chk + c) & UInt32.MaxValue;
- }
-
- writer.WriteUInt32(Convert.ToUInt32(chk));
-
-
- ms.Seek(0, SeekOrigin.Begin);
- ms.CopyTo(fs);
- }
- }
-
- }
- }
-
+ SavePS2(File.OpenWrite(newXom));
}
- public void Save(string newXom)
+ public void SavePS2PSU(string newXom)
{
- saveData();
-
- XomWriter.WriteXom(xomFile, newXom);
+ SavePS2PSU(File.OpenWrite(newXom));
+ }
+ public void SavePC(string newXom)
+ {
+ SavePC(File.OpenWrite(newXom));
}
public void ExtractAllContainers(string path)
diff --git a/LibXom/Data/XomFile.cs b/LibXom/Data/XomFile.cs
index a012901..4a05e1a 100644
--- a/LibXom/Data/XomFile.cs
+++ b/LibXom/Data/XomFile.cs
@@ -12,6 +12,7 @@ namespace LibXom.Data
{
private int version;
private int unk0;
+
private List xomStrings = new List();
private List xomTypes = new List();
@@ -47,14 +48,25 @@ namespace LibXom.Data
xomStrings[stringId] = newStr;
}
+ internal int addString(XomString xStr)
+ {
+ xomStrings.Add(xStr);
+ return xomStrings.Count - 1;
+ }
+
+ public void ClearAllStrings()
+ {
+ xomStrings.Clear();
+ }
+
public XomString AddOrGetString(string value)
{
XomString[] strings = XomStrings;
for (int i = 0; i < strings.Length; i++)
- if (strings[i].Value == value) return strings[i];
+ if (strings[i].Equals(value)) return strings[i];
XomString str = new XomString(this, value);
- xomStrings.Add(str);
+ addString(str);
return str;
}
@@ -78,6 +90,15 @@ namespace LibXom.Data
throw new XomTypeNotFoundException("Type \"" + typeName + "\" was not found in XOM.");
}
+
+ internal int calculateIdForXomStrings(XomString searchString, XomString[] stringsList)
+ {
+ for (int i = 0; i < stringsList.Length; i++)
+ if (stringsList[i].Equals(searchString)) return i;
+
+ return addString(searchString);
+ }
+
internal int calculateIdForXomFileComponent(string searchUuid, XomFileComponent[] components)
{
for (int i = 0; i < components.Length; i++)
@@ -90,11 +111,13 @@ namespace LibXom.Data
{
XomContainer[] containers = this.XomContainers;
XomType[] types = this.XomTypes;
- XomString[] strings = XomStrings;
+ XomString[] strings = this.XomStrings;
List blocks = new List();
+
// add MOIK block
blocks.Add(new MoikBlock(this.version, containers.Length, types.Length));
+
// add type blocks
foreach (XomType type in types) blocks.Add(new TypeBlock(type.Containers.Length, type.Md5, type.Name));
diff --git a/LibXom/Data/XomString.cs b/LibXom/Data/XomString.cs
index 134e0d6..9e6c66c 100644
--- a/LibXom/Data/XomString.cs
+++ b/LibXom/Data/XomString.cs
@@ -15,7 +15,7 @@ namespace LibXom.Data
{
get
{
- return this.fileBelongs.calculateIdForXomFileComponent(this.uuid, fileBelongs.XomStrings) - 1;
+ return this.fileBelongs.calculateIdForXomStrings(this, fileBelongs.XomStrings);
}
}
public string Value
@@ -34,13 +34,23 @@ namespace LibXom.Data
}
}
- /*
- public void OverwriteXomString(string newValue)
+ public override bool Equals(object? obj)
{
- this.value = newValue;
- fileBelongs.updateStringById(this.Id, this);
+ XomString? xStr = obj as XomString;
+ if (xStr is XomString)
+ return this.Value.Equals(xStr.Value, StringComparison.InvariantCulture);
+ else
+ return false;
}
- */
+
+
+ /*
+ public void OverwriteXomString(string newValue)
+ {
+ this.value = newValue;
+ fileBelongs.updateStringById(this.Id, this);
+ }
+ */
public override string ToString()
{
return this.Value;
diff --git a/LibXom/Data/XomType.cs b/LibXom/Data/XomType.cs
index d2aa0ad..2cf983b 100644
--- a/LibXom/Data/XomType.cs
+++ b/LibXom/Data/XomType.cs
@@ -50,7 +50,10 @@ namespace LibXom.Data
return i;
}
}
- throw new XomContainerNotFoundException("Could not find Xom Container with uuid: " + container.uuid + " in type: " + this.Name);
+
+ // maybe removed this container by mistakes; so lets just add it back
+ container.Type.xomContainers.Add(container);
+ return getContainerIndex(container);
}
public void ReplaceContainerData(XomContainer container, byte[] newData)
{
diff --git a/LibXom/Streams/XomStreamReader.cs b/LibXom/Streams/XomStreamReader.cs
index 2e9591e..3694978 100644
--- a/LibXom/Streams/XomStreamReader.cs
+++ b/LibXom/Streams/XomStreamReader.cs
@@ -53,6 +53,19 @@ namespace LibXom.Streams
xStream.Read(buffer, 0, amt);
return buffer;
}
+
+ public DateTime ReadDateTime()
+ {
+ byte secs = ReadByte();
+ byte minutes = ReadByte();
+ byte hours = ReadByte();
+ byte days = ReadByte();
+ byte months = ReadByte();
+ UInt16 years = ReadUInt16();
+
+ return new DateTime(years, months, days, hours, minutes, secs);
+ }
+
public bool ReadBool()
{
return (ReadByte() == 0x01);
@@ -92,6 +105,16 @@ namespace LibXom.Streams
{
return BitConverter.ToSingle(ReadBytes(0x4));
}
+
+ public ushort ReadUInt16()
+ {
+ return BitConverter.ToUInt16(ReadBytes(0x2));
+ }
+ public short ReadInt16()
+ {
+ return BitConverter.ToInt16(ReadBytes(0x2));
+ }
+
public uint ReadUInt32()
{
return BitConverter.ToUInt32(ReadBytes(0x4));
diff --git a/LibXom/Streams/XomStreamWriter.cs b/LibXom/Streams/XomStreamWriter.cs
index 29f4b0f..abc7a8a 100644
--- a/LibXom/Streams/XomStreamWriter.cs
+++ b/LibXom/Streams/XomStreamWriter.cs
@@ -95,6 +95,26 @@ namespace LibXom.Streams
WriteBytes(buffer);
}
+ public void WriteDateTime(DateTime date)
+ {
+ WriteByte(Convert.ToByte(date.Second));
+ WriteByte(Convert.ToByte(date.Minute));
+ WriteByte(Convert.ToByte(date.Hour));
+ WriteByte(Convert.ToByte(date.Day));
+ WriteByte(Convert.ToByte(date.Month));
+ WriteUInt16(Convert.ToUInt16(date.Year));
+ }
+ public void WriteUInt16(ushort value)
+ {
+ byte[] buffer = BitConverter.GetBytes((ushort)value);
+ WriteBytes(buffer);
+ }
+
+ public void WriteInt16(short value)
+ {
+ byte[] buffer = BitConverter.GetBytes((short)value);
+ WriteBytes(buffer);
+ }
public void WriteUInt32(uint value)
{
byte[] buffer = BitConverter.GetBytes((uint)value);
diff --git a/W4Gui/Components/StringList.cs b/W4Gui/Components/StringList.cs
index f444834..53089a7 100644
--- a/W4Gui/Components/StringList.cs
+++ b/W4Gui/Components/StringList.cs
@@ -68,7 +68,7 @@ namespace W4Gui.Components
{
int sel = lst.SelectedIndex;
if (sel >= 0)
- lst.Items[sel] = newEntry.Text;
+ lst.Items[sel] = newEntry.Text.ToString();
}
private void newEntry_KeyDown(object sender, KeyEventArgs e)
@@ -93,7 +93,9 @@ namespace W4Gui.Components
private void lst_SelectedIndexChanged(object sender, EventArgs e)
{
- if (prevSelected >= 0)
+ if (prevSelected == lst.SelectedIndex) return;
+
+ if (prevSelected >= 0 && prevSelected < lst.Items.Count)
lst.Items[prevSelected] = newEntry.Text;
if (lst.SelectedIndex >= 0)
diff --git a/W4Gui/DataManager.cs b/W4Gui/DataManager.cs
index c37d2d8..bacfd2e 100644
--- a/W4Gui/DataManager.cs
+++ b/W4Gui/DataManager.cs
@@ -10,6 +10,9 @@ namespace W4Gui
{
public static class DataManager
{
+ public static SaveType LoadedSaveType;
+ public static string LoadedSavePath;
+
public static bool SaveLoaded = false;
public static W4SaveFile SaveFile;
public static void SaveAll()
diff --git a/W4Gui/Main.Designer.cs b/W4Gui/Main.Designer.cs
index ca7d9c0..294b8ed 100644
--- a/W4Gui/Main.Designer.cs
+++ b/W4Gui/Main.Designer.cs
@@ -58,6 +58,7 @@ namespace W4Gui
this.awardPanel = new W4Gui.Tabs.AwardTab();
this.variablesTab = new System.Windows.Forms.TabPage();
this.variablesPage = new W4Gui.Tabs.VariablesTab.VariablesTabs();
+ this.saveAsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.mainMenuStrip.SuspendLayout();
this.mainTabControl.SuspendLayout();
this.weaponTab.SuspendLayout();
@@ -87,7 +88,8 @@ namespace W4Gui
//
this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.openToolStripMenuItem,
- this.saveToolStripMenuItem});
+ this.saveToolStripMenuItem,
+ this.saveAsToolStripMenuItem});
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
this.fileToolStripMenuItem.Text = "File";
@@ -95,7 +97,7 @@ namespace W4Gui
// openToolStripMenuItem
//
this.openToolStripMenuItem.Name = "openToolStripMenuItem";
- this.openToolStripMenuItem.Size = new System.Drawing.Size(103, 22);
+ this.openToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.openToolStripMenuItem.Text = "Open";
this.openToolStripMenuItem.Click += new System.EventHandler(this.openToolStripMenuItem_Click);
//
@@ -103,7 +105,7 @@ namespace W4Gui
//
this.saveToolStripMenuItem.Enabled = false;
this.saveToolStripMenuItem.Name = "saveToolStripMenuItem";
- this.saveToolStripMenuItem.Size = new System.Drawing.Size(103, 22);
+ this.saveToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.saveToolStripMenuItem.Text = "Save";
this.saveToolStripMenuItem.Click += new System.EventHandler(this.saveToolStripMenuItem_Click);
//
@@ -331,6 +333,14 @@ namespace W4Gui
this.variablesPage.Size = new System.Drawing.Size(182, 62);
this.variablesPage.TabIndex = 0;
//
+ // saveAsToolStripMenuItem
+ //
+ this.saveAsToolStripMenuItem.Enabled = false;
+ this.saveAsToolStripMenuItem.Name = "saveAsToolStripMenuItem";
+ this.saveAsToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
+ this.saveAsToolStripMenuItem.Text = "Save As";
+ this.saveAsToolStripMenuItem.Click += new System.EventHandler(this.saveAsToolStripMenuItem_Click);
+ //
// Main
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
@@ -389,5 +399,6 @@ namespace W4Gui
private TabPage awardsTab;
private AwardTab awardPanel;
private InputEventMappingTab inputEventMappingsPanel;
+ private ToolStripMenuItem saveAsToolStripMenuItem;
}
}
\ No newline at end of file
diff --git a/W4Gui/Main.cs b/W4Gui/Main.cs
index b142ae4..b9d0749 100644
--- a/W4Gui/Main.cs
+++ b/W4Gui/Main.cs
@@ -1,5 +1,6 @@
using LibW4M;
using LibW4M.Data.WeaponFactory;
+using LibW4M.PS2;
using LibXom;
using LibXom.Data;
using System;
@@ -29,20 +30,47 @@ namespace W4Gui
}
+ private SaveType getTypeFromName(string filename)
+ {
+ switch (Path.GetExtension(filename))
+ {
+
+ case ".psu":
+ return SaveType.PS2;
+ case ".xom":
+ default:
+ return SaveType.PC;
+ }
+ }
+
private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
OpenFileDialog fd = new OpenFileDialog();
- fd.Filter = "Worms 4: Mayhem Save File|*.xom";
+ fd.Filter = "Worms 4: Mayhem Save Files|*.xom;*.psu|Worms 4: Mayhem PC Save File|*.xom|Worms 4: Mayhem PS2 Save File|*.psu";
fd.Title = "Open Worms 4 Save File";
if(fd.ShowDialog() == DialogResult.OK)
{
- DataManager.SaveFile = new W4SaveFile(XomReader.ReadXomFile(fd.FileName));
+ DataManager.LoadedSavePath = fd.FileName;
+ DataManager.LoadedSaveType = getTypeFromName(DataManager.LoadedSavePath);
+
+ switch (DataManager.LoadedSaveType)
+ {
+ case SaveType.PS2:
+ DataManager.SaveFile = new W4SaveFile(XomReader.ReadXomFile(PsuFile.ReadPSU(fd.FileName).GetFileByName("BESLES-53096W4MA").FileData));
+ break;
+ case SaveType.PC:
+ default:
+ DataManager.SaveFile = new W4SaveFile(XomReader.ReadXomFile(fd.FileName));
+ break;
+ }
+
this.mainTabControl.Enabled = true;
this.saveToolStripMenuItem.Enabled = true;
+ this.saveAsToolStripMenuItem.Enabled = true;
this.convertToolStripMenuItem.Enabled = true;
- this.Text = defaultTitle + " [" + fd.FileName + "]";
+ this.Text = defaultTitle + " (" + DataManager.LoadedSaveType.ToString() + ") " + "[" + fd.FileName + "]";
DataManager.LoadAll();
}
@@ -50,19 +78,22 @@ namespace W4Gui
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
- SaveFileDialog fd = new SaveFileDialog();
- fd.Filter = "Worms 4: Mayhem Save File|*.xom";
- fd.Title = "Save Worms 4 Save File";
- fd.FileName = "SaveGame.xom";
- if (fd.ShowDialog() == DialogResult.OK)
+ mainTabControl.Enabled = false;
+ DataManager.SaveAll();
+ switch (DataManager.LoadedSaveType)
{
- this.mainTabControl.Enabled = false;
-
- DataManager.SaveAll();
- DataManager.SaveFile.Save(fd.FileName);
-
- this.mainTabControl.Enabled = true;
+ case SaveType.PC:
+ DataManager.SaveFile.SavePC(DataManager.LoadedSavePath);
+ break;
+ case SaveType.PS2:
+ DataManager.SaveFile.SavePS2PSU(DataManager.LoadedSavePath);
+ break;
+ case SaveType.XBOX:
+ break;
}
+ mainTabControl.Enabled = true;
+ MessageBox.Show("File saved to: " + DataManager.LoadedSavePath, "Save Complete!", MessageBoxButtons.OK, MessageBoxIcon.Information);
+
}
private void extractAllXomContainersToolStripMenuItem_Click(object sender, EventArgs e)
@@ -131,5 +162,33 @@ namespace W4Gui
this.mainTabControl.Enabled = true;
}
}
+
+ private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
+ {
+ SaveFileDialog fd = new SaveFileDialog();
+ fd.Filter = "Worms 4: Mayhem Save Files|*.xom;*.psu|Worms 4: Mayhem PC Save File|*.xom|Worms 4: Mayhem PS2 Single Save File|*.psu";
+ fd.Title = "Save Worms 4 Save File";
+ fd.FileName = Path.GetFileName(DataManager.LoadedSavePath);
+ if (fd.ShowDialog() == DialogResult.OK)
+ {
+ this.mainTabControl.Enabled = false;
+
+ DataManager.SaveAll();
+ SaveType saveType = getTypeFromName(fd.FileName);
+
+ switch (saveType)
+ {
+ case SaveType.PS2:
+ DataManager.SaveFile.SavePS2PSU(fd.FileName);
+ break;
+ case SaveType.PC:
+ DataManager.SaveFile.SavePC(fd.FileName);
+ break;
+ }
+
+ MessageBox.Show("File saved to: " + fd.FileName, "Save Complete!", MessageBoxButtons.OK, MessageBoxIcon.Information);
+ this.mainTabControl.Enabled = true;
+ }
+ }
}
}
diff --git a/W4Gui/Properties/PublishProfiles/FolderProfile.pubxml.user b/W4Gui/Properties/PublishProfiles/FolderProfile.pubxml.user
index 6ee82eb..74e488b 100644
--- a/W4Gui/Properties/PublishProfiles/FolderProfile.pubxml.user
+++ b/W4Gui/Properties/PublishProfiles/FolderProfile.pubxml.user
@@ -4,7 +4,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
-->
- True|2023-02-28T20:19:31.4651141Z;True|2023-02-25T21:53:35.8769435+13:00;True|2023-02-20T23:18:32.2496478+13:00;True|2023-02-19T06:40:54.2502643+13:00;False|2023-02-16T17:57:46.9563146+13:00;True|2023-01-19T20:41:26.7371208+13:00;True|2023-01-15T17:06:35.5919106+13:00;True|2023-01-14T13:57:56.0824690+13:00;True|2023-01-11T22:22:28.8737310+13:00;True|2023-01-11T22:16:55.3469226+13:00;
+ True|2023-03-03T15:40:06.7859106Z;True|2023-03-01T11:45:37.3479871+13:00;True|2023-03-01T09:19:31.4651141+13:00;True|2023-02-25T21:53:35.8769435+13:00;True|2023-02-20T23:18:32.2496478+13:00;True|2023-02-19T06:40:54.2502643+13:00;False|2023-02-16T17:57:46.9563146+13:00;True|2023-01-19T20:41:26.7371208+13:00;True|2023-01-15T17:06:35.5919106+13:00;True|2023-01-14T13:57:56.0824690+13:00;True|2023-01-11T22:22:28.8737310+13:00;True|2023-01-11T22:16:55.3469226+13:00;
\ No newline at end of file
diff --git a/W4Gui/SaveType.cs b/W4Gui/SaveType.cs
new file mode 100644
index 0000000..7b6e0ef
--- /dev/null
+++ b/W4Gui/SaveType.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace W4Gui
+{
+ public enum SaveType
+ {
+ PC,
+ PS2,
+ XBOX
+ }
+}