mirror of
https://gitlab.com/Syroot/Worms.git
synced 2025-04-09 19:00:06 +03:00
Added save support for Images and LandData.
This commit is contained in:
parent
ade95d4cd0
commit
feb2ed72f7
@ -19,8 +19,9 @@ namespace Syroot.Worms.Test
|
|||||||
|
|
||||||
private static void Main(string[] args)
|
private static void Main(string[] args)
|
||||||
{
|
{
|
||||||
TeamContainer teams = new TeamContainer(@"C:\Games\Worms World Party\User\Teams\Wg.wwp");
|
Image image = new Image(@"D:\Archive\Games\Worms\Worms Armageddon\3.7.2.1\custom.img");
|
||||||
teams.Save(@"D:\Pictures\test.wwp");
|
image.Save(@"D:\Pictures\test.img");
|
||||||
|
image.Load(@"D:\Pictures\test.img");
|
||||||
|
|
||||||
Console.WriteLine("Done.");
|
Console.WriteLine("Done.");
|
||||||
Console.ReadLine();
|
Console.ReadLine();
|
||||||
|
@ -12,7 +12,7 @@ namespace Syroot.Worms
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the number of bits required to describe a color per pixel.
|
/// Gets or sets the number of bits required to describe a color per pixel.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int BitsPerPixel { get; set; }
|
public byte BitsPerPixel { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the colors in the palette of the bitmap, if it has one.
|
/// Gets or sets the colors in the palette of the bitmap, if it has one.
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
namespace Syroot.Worms.Core
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Represents extension methods for <see cref="Byte"/> array instances.
|
|
||||||
/// </summary>
|
|
||||||
internal static class ByteArrayExtensions
|
|
||||||
{
|
|
||||||
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns <c>true</c> if the current byte array instance holds the same values as the given one.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="self">The extended byte array instance.</param>
|
|
||||||
/// <param name="other">The byte array instance to compare with.</param>
|
|
||||||
/// <returns><c>true</c> if both instances hold the same values, otherwise <c>false</c>.</returns>
|
|
||||||
internal static bool Compare(this byte[] self, byte[] other)
|
|
||||||
{
|
|
||||||
if (self.Length != other.Length)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < self.Length; i++)
|
|
||||||
{
|
|
||||||
if (self[i] != other[i])
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace Syroot.Worms.Core
|
namespace Syroot.Worms.Core
|
||||||
@ -11,15 +12,25 @@ namespace Syroot.Worms.Core
|
|||||||
{
|
{
|
||||||
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the data available in <see cref="bytes"/> in compressed format.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bytes">The data to compress.</param>
|
||||||
|
/// <returns>The compressed data.</returns>
|
||||||
|
internal static byte[] Compress(byte[] bytes)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException("Compressing data has not been implemented yet.");
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Decompresses the data available in the given <paramref name="stream"/> into the provided
|
/// Decompresses the data available in the given <paramref name="stream"/> into the provided
|
||||||
/// <paramref name="buffer"/>.
|
/// <paramref name="buffer"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="stream">The <see cref="Stream"/> to read the data from.</param>
|
/// <param name="stream">The <see cref="Stream"/> to read the data from.</param>
|
||||||
/// <param name="buffer">The byte array buffer to write the decompressed data to.</param>
|
/// <param name="buffer">The byte array buffer to write the decompressed data to.</param>
|
||||||
internal static void Decompress(Stream stream, ref byte[] buffer)
|
internal static void Decompress(Stream stream, byte[] buffer)
|
||||||
{
|
{
|
||||||
// TODO: This fails for compressed data in CD:\\Data\Mission\Training0-9.img.
|
// TODO: This fails for compressed data in CD:\Data\Mission\Training0-9.img.
|
||||||
int output = 0; // Offset of next write.
|
int output = 0; // Offset of next write.
|
||||||
int cmd;
|
int cmd;
|
||||||
while ((cmd = stream.ReadByte()) != -1)
|
while ((cmd = stream.ReadByte()) != -1)
|
||||||
@ -54,12 +65,12 @@ namespace Syroot.Worms.Core
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Command: 3 bytes
|
// Command: 3 bytes
|
||||||
output = CopyData(output, arg2, arg3 + 18, ref buffer);
|
output = CopyData(output, arg2, arg3 + 18, buffer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Command: 2 bytes
|
// Command: 2 bytes
|
||||||
output = CopyData(output, arg2 + 1, arg1 + 2, ref buffer);
|
output = CopyData(output, arg2 + 1, arg1 + 2, buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -67,7 +78,7 @@ namespace Syroot.Worms.Core
|
|||||||
|
|
||||||
// ---- METHODS (PRIVATE) --------------------------------------------------------------------------------------
|
// ---- METHODS (PRIVATE) --------------------------------------------------------------------------------------
|
||||||
|
|
||||||
private static int CopyData(int offset, int compressedOffset, int count, ref byte[] buffer)
|
private static int CopyData(int offset, int compressedOffset, int count, byte[] buffer)
|
||||||
{
|
{
|
||||||
for (; count > 0; count--)
|
for (; count > 0; count--)
|
||||||
{
|
{
|
||||||
|
@ -10,7 +10,7 @@ namespace Syroot.Worms.Gen2.Armageddon
|
|||||||
/// Represents map configuration stored by the land generator in LAND.DAT files.
|
/// Represents map configuration stored by the land generator in LAND.DAT files.
|
||||||
/// Used by WA and WWP. S. https://worms2d.info/Land_Data_file.
|
/// Used by WA and WWP. S. https://worms2d.info/Land_Data_file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class LandData : ILoadableFile
|
public class LandData : ILoadableFile, ISaveableFile
|
||||||
{
|
{
|
||||||
// ---- CONSTANTS ----------------------------------------------------------------------------------------------
|
// ---- CONSTANTS ----------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -61,6 +61,11 @@ namespace Syroot.Worms.Gen2.Armageddon
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public int WaterHeight { get; set; }
|
public int WaterHeight { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets an unknown value.
|
||||||
|
/// </summary>
|
||||||
|
public int Unknown { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets an array of coordinates at which objects can be placed.
|
/// Gets or sets an array of coordinates at which objects can be placed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -106,20 +111,16 @@ namespace Syroot.Worms.Gen2.Armageddon
|
|||||||
{
|
{
|
||||||
throw new InvalidDataException("Invalid LND file signature.");
|
throw new InvalidDataException("Invalid LND file signature.");
|
||||||
}
|
}
|
||||||
int fileLength = reader.ReadInt32();
|
int fileSize = reader.ReadInt32();
|
||||||
|
|
||||||
// Read the data.
|
// Read the data.
|
||||||
Size = reader.ReadStruct<Vector2>();
|
Size = reader.ReadStruct<Vector2>();
|
||||||
TopBorder = reader.ReadBoolean(BinaryBooleanFormat.NonZeroDword);
|
TopBorder = reader.ReadBoolean(BinaryBooleanFormat.NonZeroDword);
|
||||||
WaterHeight = reader.ReadInt32();
|
WaterHeight = reader.ReadInt32();
|
||||||
|
Unknown = reader.ReadInt32();
|
||||||
|
|
||||||
// Read the possible object coordinate array.
|
// Read the possible object coordinate array.
|
||||||
int unknown = reader.ReadInt32();
|
ObjectLocations = reader.ReadStructs<Vector2>(reader.ReadInt32());
|
||||||
ObjectLocations = new Vector2[reader.ReadInt32()];
|
|
||||||
for (int i = 0; i < ObjectLocations.Length; i++)
|
|
||||||
{
|
|
||||||
ObjectLocations[i] = reader.ReadStruct<Vector2>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read the image data.
|
// Read the image data.
|
||||||
Foreground = new Image(stream);
|
Foreground = new Image(stream);
|
||||||
@ -143,5 +144,52 @@ namespace Syroot.Worms.Gen2.Armageddon
|
|||||||
Load(stream);
|
Load(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Saves the data into the given <paramref name="stream"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The <see cref="Stream"/> to save the data to.</param>
|
||||||
|
public void Save(Stream stream)
|
||||||
|
{
|
||||||
|
using (BinaryDataWriter writer = new BinaryDataWriter(stream, Encoding.ASCII))
|
||||||
|
{
|
||||||
|
// Write the header.
|
||||||
|
writer.Write(_signature);
|
||||||
|
Offset fileSizeOffset = writer.ReserveOffset();
|
||||||
|
|
||||||
|
// Write the data.
|
||||||
|
writer.Write(Size);
|
||||||
|
writer.Write(TopBorder, BinaryBooleanFormat.NonZeroDword);
|
||||||
|
writer.Write(WaterHeight);
|
||||||
|
writer.Write(Unknown);
|
||||||
|
|
||||||
|
// Write the possible object coordinate array.
|
||||||
|
writer.Write(ObjectLocations.Length);
|
||||||
|
writer.Write(ObjectLocations);
|
||||||
|
|
||||||
|
// Write the image data.
|
||||||
|
Foreground.Save(writer.BaseStream);
|
||||||
|
CollisionMask.Save(writer.BaseStream);
|
||||||
|
Background.Save(writer.BaseStream);
|
||||||
|
|
||||||
|
// Write the file paths.
|
||||||
|
writer.Write(LandTexturePath, BinaryStringFormat.ByteLengthPrefix);
|
||||||
|
writer.Write(WaterDirPath, BinaryStringFormat.ByteLengthPrefix);
|
||||||
|
|
||||||
|
fileSizeOffset.Satisfy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Saves the data in the given file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileName">The name of the file to save the data in.</param>
|
||||||
|
public void Save(string fileName)
|
||||||
|
{
|
||||||
|
using (FileStream stream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
|
||||||
|
{
|
||||||
|
Save(stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Syroot.Worms.Gen2.Armageddon
|
|
||||||
{
|
|
||||||
class Mission
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Syroot.Worms.Gen2.Armageddon
|
|
||||||
{
|
|
||||||
class MonoMap
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Syroot.Worms.Gen2.Armageddon
|
|
||||||
{
|
|
||||||
class Replay
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
@ -11,7 +11,7 @@ namespace Syroot.Worms.Gen2
|
|||||||
/// Represents a (palettized) graphical image stored in an IMG file, possibly compressed.
|
/// Represents a (palettized) graphical image stored in an IMG file, possibly compressed.
|
||||||
/// Used by W2, WA and WWP. S. https://worms2d.info/Image_file.
|
/// Used by W2, WA and WWP. S. https://worms2d.info/Image_file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Image : Bitmap, ILoadableFile
|
public class Image : Bitmap, ILoadableFile, ISaveableFile
|
||||||
{
|
{
|
||||||
// ---- CONSTANTS ----------------------------------------------------------------------------------------------
|
// ---- CONSTANTS ----------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -47,11 +47,10 @@ namespace Syroot.Worms.Gen2
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="Image"/> class, loading the data from the given
|
/// Initializes a new instance of the <see cref="Image"/> class, loading the data from the given
|
||||||
/// <see cref="Stream"/>.
|
/// <see cref="Stream"/>. The data block can be aligned to a 4-bte boundary.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="stream">The <see cref="Stream"/> to load the data from.</param>
|
/// <param name="stream">The <see cref="Stream"/> to load the data from.</param>
|
||||||
/// <param name="alignData"><c>true</c> to start reading the image data at a 4-byte boundary. Used by WWP in
|
/// <param name="alignData"><c>true</c> to align the data array by 4 bytes.</param>
|
||||||
/// LAND.DAT files.</param>
|
|
||||||
internal Image(Stream stream, bool alignData)
|
internal Image(Stream stream, bool alignData)
|
||||||
{
|
{
|
||||||
Load(stream);
|
Load(stream);
|
||||||
@ -63,7 +62,7 @@ namespace Syroot.Worms.Gen2
|
|||||||
/// Gets an optional description of the image contents.
|
/// Gets an optional description of the image contents.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Description { get; private set; }
|
public string Description { get; private set; }
|
||||||
|
|
||||||
// ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
|
// ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -72,6 +71,7 @@ namespace Syroot.Worms.Gen2
|
|||||||
/// <param name="stream">The <see cref="Stream"/> to load the data from.</param>
|
/// <param name="stream">The <see cref="Stream"/> to load the data from.</param>
|
||||||
public void Load(Stream stream)
|
public void Load(Stream stream)
|
||||||
{
|
{
|
||||||
|
Load(stream, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -86,9 +86,52 @@ namespace Syroot.Worms.Gen2
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- METHODS (PRIVATE) --------------------------------------------------------------------------------------
|
/// <summary>
|
||||||
|
/// Saves the data into the given <paramref name="stream"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The <see cref="Stream"/> to save the data to.</param>
|
||||||
|
public void Save(Stream stream)
|
||||||
|
{
|
||||||
|
Save(stream, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
private void Load(Stream stream, bool alignData)
|
/// <summary>
|
||||||
|
/// Saves the optionally compressed data into the given <paramref name="stream"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The <see cref="Stream"/> to save the data to.</param>
|
||||||
|
/// <param name="compress"><c>true</c> to compress image data.</param>
|
||||||
|
public void Save(Stream stream, bool compress)
|
||||||
|
{
|
||||||
|
Save(stream, compress, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Saves the data in the given file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileName">The name of the file to save the data in.</param>
|
||||||
|
public void Save(string fileName)
|
||||||
|
{
|
||||||
|
Save(fileName, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Saves the optionally compressed data in the given file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileName">The name of the file to save the data in.</param>
|
||||||
|
/// <param name="compress"><c>true</c> to compress image data.</param>
|
||||||
|
public void Save(string fileName, bool compress)
|
||||||
|
{
|
||||||
|
Save(fileName, compress, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Loads the data from the given <see cref="Stream"/>. The data block can be aligned to a 4-bte boundary.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The <see cref="Stream"/> to load the data from.</param>
|
||||||
|
/// <param name="alignData"><c>true</c> to align the data array by 4 bytes.</param>
|
||||||
|
internal void Load(Stream stream, bool alignData)
|
||||||
{
|
{
|
||||||
using (BinaryDataReader reader = new BinaryDataReader(stream, Encoding.ASCII, true))
|
using (BinaryDataReader reader = new BinaryDataReader(stream, Encoding.ASCII, true))
|
||||||
{
|
{
|
||||||
@ -99,7 +142,7 @@ namespace Syroot.Worms.Gen2
|
|||||||
}
|
}
|
||||||
int fileSize = reader.ReadInt32();
|
int fileSize = reader.ReadInt32();
|
||||||
|
|
||||||
// Read an optional string describing the image contents or the bits per pixel.
|
// Read an optional string describing the image contents and the bits per pixel.
|
||||||
BitsPerPixel = reader.ReadByte();
|
BitsPerPixel = reader.ReadByte();
|
||||||
if (BitsPerPixel == 0)
|
if (BitsPerPixel == 0)
|
||||||
{
|
{
|
||||||
@ -111,6 +154,10 @@ namespace Syroot.Worms.Gen2
|
|||||||
Description = (char)BitsPerPixel + reader.ReadString(BinaryStringFormat.ZeroTerminated);
|
Description = (char)BitsPerPixel + reader.ReadString(BinaryStringFormat.ZeroTerminated);
|
||||||
BitsPerPixel = reader.ReadByte();
|
BitsPerPixel = reader.ReadByte();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Description = null;
|
||||||
|
}
|
||||||
|
|
||||||
// Read image flags describing the format and availability of the following contents.
|
// Read image flags describing the format and availability of the following contents.
|
||||||
Flags flags = (Flags)reader.ReadByte();
|
Flags flags = (Flags)reader.ReadByte();
|
||||||
@ -126,18 +173,23 @@ namespace Syroot.Worms.Gen2
|
|||||||
Palette[i] = new Color(reader.ReadByte(), reader.ReadByte(), reader.ReadByte());
|
Palette[i] = new Color(reader.ReadByte(), reader.ReadByte(), reader.ReadByte());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Palette = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the image size.
|
||||||
Size = new Vector2(reader.ReadInt16(), reader.ReadInt16());
|
Size = new Vector2(reader.ReadInt16(), reader.ReadInt16());
|
||||||
|
|
||||||
|
// Read the data byte array, which might be compressed or aligned.
|
||||||
if (alignData)
|
if (alignData)
|
||||||
{
|
{
|
||||||
reader.Align(4);
|
reader.Align(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the bytes, which might be compressed.
|
|
||||||
byte[] data = new byte[Size.X * Size.Y * BitsPerPixel / 8];
|
byte[] data = new byte[Size.X * Size.Y * BitsPerPixel / 8];
|
||||||
if (flags.HasFlag(Flags.Compressed))
|
if (flags.HasFlag(Flags.Compressed))
|
||||||
{
|
{
|
||||||
Team17Compression.Decompress(reader.BaseStream, ref data);
|
Team17Compression.Decompress(reader.BaseStream, data);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -148,11 +200,106 @@ namespace Syroot.Worms.Gen2
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Loads the data from the given file. The data block can be aligned to a 4-bte boundary.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileName">The name of the file to load the data from.</param>
|
||||||
|
/// <param name="alignData"><c>true</c> to align the data array by 4 bytes.</param>
|
||||||
|
internal void Load(string fileName, bool alignData)
|
||||||
|
{
|
||||||
|
using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||||
|
{
|
||||||
|
Load(stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Saves the optionally compressed data into the given <paramref name="stream"/>. The data block can be aligned
|
||||||
|
/// to a 4-bte boundary.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The <see cref="Stream"/> to save the data to.</param>
|
||||||
|
/// <param name="compress"><c>true</c> to compress image data.</param>
|
||||||
|
/// <param name="alignData"><c>true</c> to align the data array by 4 bytes.</param>
|
||||||
|
internal void Save(Stream stream, bool compress, bool alignData)
|
||||||
|
{
|
||||||
|
using (BinaryDataWriter writer = new BinaryDataWriter(stream, Encoding.ASCII))
|
||||||
|
{
|
||||||
|
// Write the header.
|
||||||
|
writer.Write(_signature);
|
||||||
|
Offset fileSizeOffset = writer.ReserveOffset();
|
||||||
|
|
||||||
|
// Write an optional string describing the image contents and the bits per pixel.
|
||||||
|
if (Description != null)
|
||||||
|
{
|
||||||
|
writer.Write(Description, BinaryStringFormat.ZeroTerminated);
|
||||||
|
}
|
||||||
|
writer.Write(BitsPerPixel);
|
||||||
|
|
||||||
|
// Write image flags describing the format and availability of the following contents.
|
||||||
|
Flags flags = Flags.None;
|
||||||
|
if (Palette != null)
|
||||||
|
{
|
||||||
|
flags |= Flags.Palettized;
|
||||||
|
}
|
||||||
|
if (compress)
|
||||||
|
{
|
||||||
|
flags |= Flags.Compressed;
|
||||||
|
}
|
||||||
|
writer.Write(flags, true);
|
||||||
|
|
||||||
|
// Write the image palette if available. The first color of the palette is implicitly black.
|
||||||
|
if (Palette != null)
|
||||||
|
{
|
||||||
|
writer.Write((short)(Palette.Length - 1));
|
||||||
|
for (int i = 1; i < Palette.Length; i++)
|
||||||
|
{
|
||||||
|
Color color = Palette[i];
|
||||||
|
writer.Write(color.R);
|
||||||
|
writer.Write(color.G);
|
||||||
|
writer.Write(color.B);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the image size.
|
||||||
|
writer.Write((short)Size.X);
|
||||||
|
writer.Write((short)Size.Y);
|
||||||
|
|
||||||
|
// Write the data byte array, which might be compressed or aligned.
|
||||||
|
if (alignData)
|
||||||
|
{
|
||||||
|
writer.Align(4);
|
||||||
|
}
|
||||||
|
byte[] data = Data;
|
||||||
|
if (compress)
|
||||||
|
{
|
||||||
|
data = Team17Compression.Compress(data);
|
||||||
|
}
|
||||||
|
writer.Write(data);
|
||||||
|
|
||||||
|
fileSizeOffset.Satisfy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Saves the optionally compressed data in the given file. The data block can be aligned to a 4-byte boundary.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileName">The name of the file to save the data in.</param>
|
||||||
|
/// <param name="compress"><c>true</c> to compress image data.</param>
|
||||||
|
/// <param name="alignData"><c>true</c> to align the data array by 4 bytes.</param>
|
||||||
|
internal void Save(string fileName, bool compress, bool alignData)
|
||||||
|
{
|
||||||
|
using (FileStream stream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
|
||||||
|
{
|
||||||
|
Save(stream, compress, alignData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ---- ENUMERATIONS -------------------------------------------------------------------------------------------
|
// ---- ENUMERATIONS -------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
private enum Flags
|
private enum Flags : byte
|
||||||
{
|
{
|
||||||
|
None = 0,
|
||||||
Compressed = 1 << 6,
|
Compressed = 1 << 6,
|
||||||
Palettized = 1 << 7
|
Palettized = 1 << 7
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Syroot.IO;
|
using Syroot.IO;
|
||||||
@ -10,7 +11,7 @@ namespace Syroot.Worms.Gen2.WorldParty
|
|||||||
/// Represents map configuration stored by the land generator in LAND.DAT files.
|
/// Represents map configuration stored by the land generator in LAND.DAT files.
|
||||||
/// Used by WWP. S. https://worms2d.info/Land_Data_file.
|
/// Used by WWP. S. https://worms2d.info/Land_Data_file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class LandData : ILoadableFile
|
public class LandData : ILoadableFile, ISaveableFile
|
||||||
{
|
{
|
||||||
// ---- CONSTANTS ----------------------------------------------------------------------------------------------
|
// ---- CONSTANTS ----------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -114,11 +115,7 @@ namespace Syroot.Worms.Gen2.WorldParty
|
|||||||
WaterHeight = reader.ReadInt32();
|
WaterHeight = reader.ReadInt32();
|
||||||
|
|
||||||
// Read the possible object coordinate array.
|
// Read the possible object coordinate array.
|
||||||
ObjectLocations = new Vector2[reader.ReadInt32()];
|
ObjectLocations = reader.ReadStructs<Vector2>(reader.ReadInt32());
|
||||||
for (int i = 0; i < ObjectLocations.Length; i++)
|
|
||||||
{
|
|
||||||
ObjectLocations[i] = reader.ReadStruct<Vector2>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read the image data.
|
// Read the image data.
|
||||||
Foreground = new Image(stream, true);
|
Foreground = new Image(stream, true);
|
||||||
@ -142,5 +139,51 @@ namespace Syroot.Worms.Gen2.WorldParty
|
|||||||
Load(stream);
|
Load(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Saves the data into the given <paramref name="stream"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The <see cref="Stream"/> to save the data to.</param>
|
||||||
|
public void Save(Stream stream)
|
||||||
|
{
|
||||||
|
using (BinaryDataWriter writer = new BinaryDataWriter(stream, Encoding.ASCII))
|
||||||
|
{
|
||||||
|
// Write the header.
|
||||||
|
writer.Write(_signature);
|
||||||
|
Offset fileSizeOffset = writer.ReserveOffset();
|
||||||
|
|
||||||
|
// Write the data.
|
||||||
|
writer.Write(Size);
|
||||||
|
writer.Write(TopBorder, BinaryBooleanFormat.NonZeroDword);
|
||||||
|
writer.Write(WaterHeight);
|
||||||
|
|
||||||
|
// Write the possible object coordinate array.
|
||||||
|
writer.Write(ObjectLocations.Length);
|
||||||
|
writer.Write(ObjectLocations);
|
||||||
|
|
||||||
|
// Write the image data.
|
||||||
|
Foreground.Save(writer.BaseStream, false, true);
|
||||||
|
CollisionMask.Save(writer.BaseStream, false, true);
|
||||||
|
Background.Save(writer.BaseStream, false, true);
|
||||||
|
|
||||||
|
// Write the file paths.
|
||||||
|
writer.Write(LandTexturePath, BinaryStringFormat.ByteLengthPrefix);
|
||||||
|
writer.Write(WaterDirPath, BinaryStringFormat.ByteLengthPrefix);
|
||||||
|
|
||||||
|
fileSizeOffset.Satisfy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Saves the data in the given file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileName">The name of the file to save the data in.</param>
|
||||||
|
public void Save(string fileName)
|
||||||
|
{
|
||||||
|
using (FileStream stream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
|
||||||
|
{
|
||||||
|
Save(stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ namespace Syroot.Worms.Gen2.Worms2
|
|||||||
/// Represents map configuration stored by the land generator in LAND.DAT files.
|
/// Represents map configuration stored by the land generator in LAND.DAT files.
|
||||||
/// Used by W2. S. https://worms2d.info/Land_Data_file.
|
/// Used by W2. S. https://worms2d.info/Land_Data_file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class LandData : ILoadableFile
|
public class LandData : ILoadableFile, ISaveableFile
|
||||||
{
|
{
|
||||||
// ---- CONSTANTS ----------------------------------------------------------------------------------------------
|
// ---- CONSTANTS ----------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -61,6 +61,11 @@ namespace Syroot.Worms.Gen2.Worms2
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public Vector2[] ObjectLocations { get; set; }
|
public Vector2[] ObjectLocations { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets an unknown value, seeming to be 0 most of the time.
|
||||||
|
/// </summary>
|
||||||
|
public int Unknown { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the visual foreground image.
|
/// Gets or sets the visual foreground image.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -113,12 +118,8 @@ namespace Syroot.Worms.Gen2.Worms2
|
|||||||
TopBorder = reader.ReadBoolean(BinaryBooleanFormat.NonZeroDword);
|
TopBorder = reader.ReadBoolean(BinaryBooleanFormat.NonZeroDword);
|
||||||
|
|
||||||
// Read the possible object coordinate array.
|
// Read the possible object coordinate array.
|
||||||
ObjectLocations = new Vector2[reader.ReadInt32()];
|
ObjectLocations = reader.ReadStructs<Vector2>(reader.ReadInt32());
|
||||||
for (int i = 0; i < ObjectLocations.Length; i++)
|
Unknown = reader.ReadInt32();
|
||||||
{
|
|
||||||
ObjectLocations[i] = reader.ReadStruct<Vector2>();
|
|
||||||
}
|
|
||||||
int unknown = reader.ReadInt32(); // Seems 0.
|
|
||||||
|
|
||||||
// Read the image data.
|
// Read the image data.
|
||||||
Foreground = new Image(stream);
|
Foreground = new Image(stream);
|
||||||
@ -143,5 +144,52 @@ namespace Syroot.Worms.Gen2.Worms2
|
|||||||
Load(stream);
|
Load(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Saves the data into the given <paramref name="stream"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The <see cref="Stream"/> to save the data to.</param>
|
||||||
|
public void Save(Stream stream)
|
||||||
|
{
|
||||||
|
using (BinaryDataWriter writer = new BinaryDataWriter(stream, Encoding.ASCII))
|
||||||
|
{
|
||||||
|
// Write the header.
|
||||||
|
writer.Write(_signature);
|
||||||
|
Offset fileSizeOffset = writer.ReserveOffset();
|
||||||
|
|
||||||
|
// Write the data.
|
||||||
|
writer.Write(Size);
|
||||||
|
writer.Write(TopBorder, BinaryBooleanFormat.NonZeroDword);
|
||||||
|
|
||||||
|
// Write the possible object coordinate array.
|
||||||
|
writer.Write(ObjectLocations.Length);
|
||||||
|
writer.Write(ObjectLocations);
|
||||||
|
writer.Write(Unknown);
|
||||||
|
|
||||||
|
// Write the image data.
|
||||||
|
Foreground.Save(writer.BaseStream);
|
||||||
|
CollisionMask.Save(writer.BaseStream);
|
||||||
|
Background.Save(writer.BaseStream);
|
||||||
|
UnknownImage.Save(writer.BaseStream);
|
||||||
|
|
||||||
|
// Write the file paths.
|
||||||
|
writer.Write(LandTexturePath, BinaryStringFormat.ByteLengthPrefix);
|
||||||
|
writer.Write(WaterDirPath, BinaryStringFormat.ByteLengthPrefix);
|
||||||
|
|
||||||
|
fileSizeOffset.Satisfy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Saves the data in the given file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileName">The name of the file to save the data in.</param>
|
||||||
|
public void Save(string fileName)
|
||||||
|
{
|
||||||
|
using (FileStream stream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
|
||||||
|
{
|
||||||
|
Save(stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Syroot.Worms.Gen2.Worms2
|
|
||||||
{
|
|
||||||
class Mission
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Syroot.Worms.Gen2.Worms2
|
|
||||||
{
|
|
||||||
class MonoMap
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user