mirror of
https://gitlab.com/Syroot/Worms.git
synced 2025-01-27 22:27:58 +03:00
Add IGD and LPD support. Remove Syroot.Maths reference.
This commit is contained in:
parent
83024baaf3
commit
8a616939de
51
src/010_editor/IGD.bt
Normal file
51
src/010_editor/IGD.bt
Normal file
@ -0,0 +1,51 @@
|
||||
//------------------------------------------------
|
||||
//--- 010 Editor v9.0.1 Binary Template
|
||||
//
|
||||
// File: IGD.bt
|
||||
// Authors: Syroot
|
||||
// Version: 0.1.0
|
||||
// Purpose: Parse Worms World Party Aqua IGD graphics containers.
|
||||
// Category: Worms World Party Aqua
|
||||
// File Mask: *.igd
|
||||
// ID Bytes:
|
||||
// History:
|
||||
// 0.1.0 2019-01-05 Initial version.
|
||||
//------------------------------------------------
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
} Vec2 <read=Vec2Read>;
|
||||
string Vec2Read(Vec2& v)
|
||||
{
|
||||
string s;
|
||||
SPrintf(s, "(%d, %d)", v.x, v.y);
|
||||
return s;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint unkA;
|
||||
uint index;
|
||||
uint unkB;
|
||||
uint unkC;
|
||||
Vec2 size;
|
||||
Vec2 center;
|
||||
uint lenData;
|
||||
uint lenDataComp;
|
||||
ubyte dataComp[lenDataComp];
|
||||
} Image;
|
||||
|
||||
LittleEndian();
|
||||
|
||||
uint unkA;
|
||||
uint unkB;
|
||||
Vec2 negativeSize;
|
||||
Vec2 center;
|
||||
Vec2 size;
|
||||
uint numColors;
|
||||
uint palette[numColors] <format=hex>;
|
||||
uint numImages;
|
||||
if (numImages <= 512)
|
||||
Image images[numImages] <optimize=false>;
|
35
src/010_editor/LPD.bt
Normal file
35
src/010_editor/LPD.bt
Normal file
@ -0,0 +1,35 @@
|
||||
//------------------------------------------------
|
||||
//--- 010 Editor v9.0.1 Binary Template
|
||||
//
|
||||
// File: LPD.bt
|
||||
// Authors: Syroot
|
||||
// Version: 0.1.0
|
||||
// Purpose: Parse Worms World Party Aqua LPD layout files.
|
||||
// Category: Worms World Party Aqua
|
||||
// File Mask: *.lpd
|
||||
// ID Bytes:
|
||||
// History:
|
||||
// 0.1.0 2019-01-05 Initial version.
|
||||
//------------------------------------------------
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint lenFileName;
|
||||
char fileName[lenFileName];
|
||||
uint left;
|
||||
uint top;
|
||||
uint right;
|
||||
uint bottom;
|
||||
uint param5;
|
||||
uint version;
|
||||
} Element <read=ElementRead>;
|
||||
wstring ElementRead(Element &var)
|
||||
{
|
||||
return StringToWString(var.fileName, CHARSET_KOREAN_J);
|
||||
}
|
||||
|
||||
LittleEndian();
|
||||
|
||||
uint numElements;
|
||||
if (numElements <= 512)
|
||||
Element elements[numElements] <optimize=false>;
|
@ -24,4 +24,9 @@
|
||||
<ItemGroup>
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Update="OWLauncherConfig.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@ -1,4 +1,4 @@
|
||||
using System.Drawing;
|
||||
using System;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using Syroot.Worms.OnlineWorms;
|
||||
@ -11,6 +11,31 @@ namespace Syroot.Worms.Scratchpad
|
||||
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
ConvertIgdImages();
|
||||
Console.ReadLine();
|
||||
}
|
||||
|
||||
private static void ConvertIgdImages()
|
||||
{
|
||||
string igdFolder = @"C:\Games\WWP Aqua\Images";
|
||||
string pngFolder = @"D:\Pictures\LPD";
|
||||
Directory.CreateDirectory(pngFolder);
|
||||
|
||||
foreach (string igdFilePath in Directory.GetFiles(igdFolder, "*.igd", SearchOption.AllDirectories))
|
||||
{
|
||||
// Load the IGD and let it convert the images.
|
||||
Igd igd = new Igd(igdFilePath);
|
||||
|
||||
// Save the images in the output folder.
|
||||
string pngIgdFolder = Path.Combine(pngFolder, Path.GetFileName(igdFilePath));
|
||||
Directory.CreateDirectory(pngIgdFolder);
|
||||
for (int i = 0; i < igd.Images.Count; i++)
|
||||
{
|
||||
string pngFileName = Path.ChangeExtension(i.ToString(), "png");
|
||||
IgdImage image = igd.Images[i];
|
||||
image.Bitmap.Save(Path.Combine(pngIgdFolder, pngFileName), ImageFormat.Png);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void ConvertKsfImages()
|
||||
@ -37,20 +62,9 @@ namespace Syroot.Worms.Scratchpad
|
||||
for (int i = 0; i < ksf.Images.Count; i++)
|
||||
{
|
||||
string pngFileName = Path.ChangeExtension(i.ToString(), "png");
|
||||
Image image = ksf.Images[i];
|
||||
if (image != null)
|
||||
image.Save(Path.Combine(pngKsfFolder, pngFileName), ImageFormat.Png);
|
||||
ksf.Images[i].Bitmap?.Save(Path.Combine(pngKsfFolder, pngFileName), ImageFormat.Png);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteMemoryManagerBlocks()
|
||||
{
|
||||
// Memory manager block allocation simulation.
|
||||
byte[] buffer = new byte[0x600000];
|
||||
for (int idx = 0; idx < buffer.Length; idx += 2)
|
||||
buffer[idx] = (byte)((0x41 * idx - 0x78) | 0x55);
|
||||
File.WriteAllBytes(@"D:\Pictures\memory.bin", buffer);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Syroot.BinaryData;
|
||||
using Syroot.Maths;
|
||||
using Syroot.Worms.Core;
|
||||
|
||||
namespace Syroot.Worms.Armageddon
|
||||
@ -21,9 +21,7 @@ namespace Syroot.Worms.Armageddon
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LandData"/> class.
|
||||
/// </summary>
|
||||
public LandData()
|
||||
{
|
||||
}
|
||||
public LandData() { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LandData"/> class, loading the data from the given
|
||||
@ -49,7 +47,7 @@ namespace Syroot.Worms.Armageddon
|
||||
/// <summary>
|
||||
/// Gets or sets the size of the landscape in pixels.
|
||||
/// </summary>
|
||||
public Vector2 Size { get; set; }
|
||||
public Size Size { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether an indestructible top border will be enabled.
|
||||
@ -69,7 +67,7 @@ namespace Syroot.Worms.Armageddon
|
||||
/// <summary>
|
||||
/// Gets or sets an array of coordinates at which objects can be placed.
|
||||
/// </summary>
|
||||
public Vector2[] ObjectLocations { get; set; }
|
||||
public Point[] ObjectLocations { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the visual foreground image.
|
||||
@ -95,7 +93,7 @@ namespace Syroot.Worms.Armageddon
|
||||
/// Gets or sets the path to the Water.dir file.
|
||||
/// </summary>
|
||||
public string WaterDirPath { get; set; }
|
||||
|
||||
|
||||
// ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
@ -108,19 +106,17 @@ namespace Syroot.Worms.Armageddon
|
||||
{
|
||||
// Read the header.
|
||||
if (reader.ReadInt32() != _signature)
|
||||
{
|
||||
throw new InvalidDataException("Invalid LND file signature.");
|
||||
}
|
||||
int fileSize = reader.ReadInt32();
|
||||
|
||||
// Read the data.
|
||||
Size = reader.ReadStruct<Vector2>();
|
||||
Size = reader.ReadStruct<Size>();
|
||||
TopBorder = reader.ReadBoolean(BooleanCoding.Dword);
|
||||
WaterHeight = reader.ReadInt32();
|
||||
Unknown = reader.ReadInt32();
|
||||
|
||||
// Read the possible object coordinate array.
|
||||
ObjectLocations = reader.ReadStructs<Vector2>(reader.ReadInt32());
|
||||
ObjectLocations = reader.ReadStructs<Point>(reader.ReadInt32());
|
||||
|
||||
// Read the image data.
|
||||
Foreground = reader.Load<Img>();
|
||||
@ -140,9 +136,7 @@ namespace Syroot.Worms.Armageddon
|
||||
public void Load(string fileName)
|
||||
{
|
||||
using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
Load(stream);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -187,9 +181,7 @@ namespace Syroot.Worms.Armageddon
|
||||
public void Save(string fileName)
|
||||
{
|
||||
using (FileStream stream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
|
||||
{
|
||||
Save(stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Syroot.BinaryData;
|
||||
using Syroot.Maths;
|
||||
using Syroot.Worms.Core;
|
||||
|
||||
namespace Syroot.Worms.Armageddon
|
||||
@ -81,7 +81,7 @@ namespace Syroot.Worms.Armageddon
|
||||
/// <summary>
|
||||
/// Gets or sets the team grave bitmap if it uses a custom one.
|
||||
/// </summary>
|
||||
public BitmapData Grave { get; set; }
|
||||
public RawBitmapData Grave { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the team's special weapon.
|
||||
@ -151,7 +151,7 @@ namespace Syroot.Worms.Armageddon
|
||||
/// <summary>
|
||||
/// Gets or sets the bitmap of the team flag.
|
||||
/// </summary>
|
||||
public BitmapData Flag { get; set; }
|
||||
public RawBitmapData Flag { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the deathmatch rank this team reached.
|
||||
@ -210,10 +210,10 @@ namespace Syroot.Worms.Armageddon
|
||||
if (GraveSprite < 0)
|
||||
{
|
||||
GraveFileName = reader.ReadFixedString(0x20);
|
||||
Grave = new BitmapData()
|
||||
Grave = new RawBitmapData()
|
||||
{
|
||||
BitsPerPixel = 8,
|
||||
Size = new Vector2(24, 32),
|
||||
Size = new Size(24, 32),
|
||||
Palette = reader.ReadStructs<Color>(256),
|
||||
Data = reader.ReadBytes(24 * 32)
|
||||
};
|
||||
@ -233,10 +233,10 @@ namespace Syroot.Worms.Armageddon
|
||||
MissionStatuses = reader.ReadStructs<TeamMissionStatus>(_missionCount);
|
||||
|
||||
FlagFileName = reader.ReadFixedString(0x20);
|
||||
Flag = new BitmapData()
|
||||
Flag = new RawBitmapData()
|
||||
{
|
||||
BitsPerPixel = 8,
|
||||
Size = new Vector2(20, 17),
|
||||
Size = new Size(20, 17),
|
||||
Palette = reader.ReadStructs<Color>(256),
|
||||
Data = reader.ReadBytes(20 * 17)
|
||||
};
|
||||
|
@ -1,11 +1,13 @@
|
||||
using Syroot.Maths;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
|
||||
namespace Syroot.Worms
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a pixel-based 2D image in different color formats.
|
||||
/// </summary>
|
||||
public class BitmapData
|
||||
[Obsolete("Use System.Drawing instead as it is now available in .NET Core.")]
|
||||
public class RawBitmapData
|
||||
{
|
||||
// ---- PROPERTIES ---------------------------------------------------------------------------------------------
|
||||
|
||||
@ -22,7 +24,7 @@ namespace Syroot.Worms
|
||||
/// <summary>
|
||||
/// Gets or sets the size of the image in pixels.
|
||||
/// </summary>
|
||||
public Vector2 Size { get; set; }
|
||||
public Size Size { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the data of the image pixels.
|
||||
|
@ -47,23 +47,17 @@ namespace Syroot.Worms.Core
|
||||
int arg1 = (cmd >> 3) & 0xF;
|
||||
int arg2 = stream.ReadByte();
|
||||
if (arg2 == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Arg2 = bits 6-16
|
||||
arg2 = ((cmd << 8) | arg2) & 0x7FF;
|
||||
if (arg1 == 0)
|
||||
{
|
||||
// Command: 0x80 0x00
|
||||
if (arg2 == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int arg3 = stream.ReadByte();
|
||||
if (arg3 == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Command: 3 bytes
|
||||
output = CopyData(output, arg2, arg3 + 18, buffer);
|
||||
}
|
||||
@ -81,9 +75,7 @@ namespace Syroot.Worms.Core
|
||||
private static int CopyData(int offset, int compressedOffset, int count, byte[] buffer)
|
||||
{
|
||||
for (; count > 0; count--)
|
||||
{
|
||||
buffer[offset] = buffer[offset++ - compressedOffset];
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
|
45
src/Syroot.Worms/Graphics/BitmapTools.cs
Normal file
45
src/Syroot.Worms/Graphics/BitmapTools.cs
Normal file
@ -0,0 +1,45 @@
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Runtime.InteropServices;
|
||||
using Syroot.Worms.Core;
|
||||
|
||||
namespace Syroot.Worms.Graphics
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a collection of methods helping with palettized images.
|
||||
/// </summary>
|
||||
internal static class BitmapTools
|
||||
{
|
||||
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Creates an indexed <see cref="Bitmap"/> with the given <paramref name="size"/> and
|
||||
/// <paramref name="palette"/> from the provided raw <paramref name="data"/> array.
|
||||
/// </summary>
|
||||
/// <param name="data">The data array storing bytes indexing the palette color array.</param>
|
||||
/// <param name="size">The dimensions of the image.</param>
|
||||
/// <param name="palette">The palette as a <see cref="Color"/> array.</param>
|
||||
/// <returns>The <see cref="Bitmap"/> instance.</returns>
|
||||
internal static Bitmap CreateIndexed(byte[] data, Size size, Color[] palette)
|
||||
{
|
||||
using (DisposableGCHandle dataPin = new DisposableGCHandle(data, GCHandleType.Pinned))
|
||||
{
|
||||
// Transfer the pixel data, respecting power-of-2 strides.
|
||||
Bitmap bitmap = new Bitmap(size.Width, size.Height, PixelFormat.Format8bppIndexed);
|
||||
BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, size.Width, size.Height),
|
||||
ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
|
||||
for (int y = 0; y < size.Height; y++)
|
||||
Marshal.Copy(data, y * size.Width, bitmapData.Scan0 + y * bitmapData.Stride, size.Width);
|
||||
bitmap.UnlockBits(bitmapData);
|
||||
|
||||
// Transfer the palette.
|
||||
ColorPalette bitmapPalette = bitmap.Palette;
|
||||
for (int i = 0; i < palette.Length; i++)
|
||||
bitmapPalette.Entries[i] = palette[i];
|
||||
bitmap.Palette = bitmapPalette;
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
17
src/Syroot.Worms/Graphics/IPalette.cs
Normal file
17
src/Syroot.Worms/Graphics/IPalette.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using System.Drawing;
|
||||
|
||||
namespace Syroot.Worms.Graphics
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an interface for any class storing indexed image palette colors.
|
||||
/// </summary>
|
||||
public interface IPalette
|
||||
{
|
||||
// ---- PROPERTIES ---------------------------------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="Color"/> values stored by this palette.
|
||||
/// </summary>
|
||||
Color[] Colors { get; set; }
|
||||
}
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Syroot.BinaryData;
|
||||
using Syroot.Maths;
|
||||
using Syroot.Worms.Core;
|
||||
|
||||
namespace Syroot.Worms
|
||||
@ -11,7 +11,7 @@ namespace Syroot.Worms
|
||||
/// Represents a (palettized) graphical image stored in an IMG file, possibly compressed.
|
||||
/// Used by W2, WA and WWP. S. https://worms2d.info/Image_file.
|
||||
/// </summary>
|
||||
public class Img : BitmapData, ILoadableFile, ISaveableFile
|
||||
public class Img : RawBitmapData, ILoadableFile, ISaveableFile
|
||||
{
|
||||
// ---- CONSTANTS ----------------------------------------------------------------------------------------------
|
||||
|
||||
@ -139,7 +139,7 @@ namespace Syroot.Worms
|
||||
Palette = new Color[colorCount + 1];
|
||||
Palette[0] = Color.Black;
|
||||
for (int i = 1; i <= colorCount; i++)
|
||||
Palette[i] = new Color(reader.Read1Byte(), reader.Read1Byte(), reader.Read1Byte());
|
||||
Palette[i] = Color.FromArgb(reader.Read1Byte(), reader.Read1Byte(), reader.Read1Byte());
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -147,12 +147,12 @@ namespace Syroot.Worms
|
||||
}
|
||||
|
||||
// Read the image size.
|
||||
Size = new Vector2(reader.ReadInt16(), reader.ReadInt16());
|
||||
Size = new Size(reader.ReadInt16(), reader.ReadInt16());
|
||||
|
||||
// Read the data byte array, which might be compressed or aligned.
|
||||
if (alignData)
|
||||
reader.Align(4);
|
||||
byte[] data = new byte[Size.X * Size.Y * BitsPerPixel / 8];
|
||||
byte[] data = new byte[Size.Width * Size.Height * BitsPerPixel / 8];
|
||||
if (flags.HasFlag(Flags.Compressed))
|
||||
Team17Compression.Decompress(reader.BaseStream, data);
|
||||
else
|
||||
@ -215,8 +215,8 @@ namespace Syroot.Worms
|
||||
}
|
||||
|
||||
// Write the image size.
|
||||
writer.Write((short)Size.X);
|
||||
writer.Write((short)Size.Y);
|
||||
writer.Write((short)Size.Width);
|
||||
writer.Write((short)Size.Height);
|
||||
|
||||
// Write the data byte array, which might be compressed or aligned.
|
||||
if (alignData)
|
||||
|
146
src/Syroot.Worms/OnlineWorms/Igd.cs
Normal file
146
src/Syroot.Worms/OnlineWorms/Igd.cs
Normal file
@ -0,0 +1,146 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using Syroot.BinaryData;
|
||||
using Syroot.Worms.Graphics;
|
||||
|
||||
namespace Syroot.Worms.OnlineWorms
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an IGD image container.
|
||||
/// </summary>
|
||||
public class Igd
|
||||
{
|
||||
// ---- CONSTRUCTORS & DESTRUCTOR ------------------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Igd"/> class, loading data from the file with the given
|
||||
/// <paramref name="fileName"/>.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The name of the file to load the data from.</param>
|
||||
public Igd(string fileName)
|
||||
{
|
||||
Load(fileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Igd"/> class, loading data from the given
|
||||
/// <paramref name="stream"/>.
|
||||
/// </summary>
|
||||
/// <param name="stream">The <see cref="Stream"/> to load the data from.</param>
|
||||
public Igd(Stream stream)
|
||||
{
|
||||
Load(stream);
|
||||
}
|
||||
|
||||
// ---- PROPERTIES ---------------------------------------------------------------------------------------------
|
||||
|
||||
public int UnknownA { get; set; }
|
||||
public int UnknownB { get; set; }
|
||||
public byte[] UnknownC { get; set; }
|
||||
public Point Center { get; set; }
|
||||
public Size Size { get; set; }
|
||||
public IList<IgdImage> Images { get; set; }
|
||||
|
||||
// ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Loads the data from the file with the given <paramref name="fileName"/>.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The name of the file to load the data from.</param>
|
||||
public void Load(string fileName)
|
||||
{
|
||||
using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
Load(stream);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads the data from the given <paramref name="stream"/>.
|
||||
/// </summary>
|
||||
/// <param name="stream">The <see cref="Stream"/> to load the data from.</param>
|
||||
public void Load(Stream stream)
|
||||
{
|
||||
UnknownA = stream.ReadInt32();
|
||||
UnknownB = stream.ReadInt32();
|
||||
UnknownC = stream.ReadBytes(8);
|
||||
Center = new Point(stream.ReadInt32(), stream.ReadInt32());
|
||||
Size = new Size(stream.ReadInt32(), stream.ReadInt32());
|
||||
|
||||
// Load the palette.
|
||||
int colorCount = stream.ReadInt32();
|
||||
Color[] palette = new Color[colorCount];
|
||||
for (int i = 0; i < colorCount; i++)
|
||||
{
|
||||
palette[i] = Color.FromArgb(stream.Read1Byte(), stream.Read1Byte(), stream.Read1Byte());
|
||||
stream.Seek(1); // Ignore empty alpha.
|
||||
}
|
||||
|
||||
// Load the images.
|
||||
int imageCount = stream.ReadInt32();
|
||||
Console.WriteLine(((FileStream)stream).Name);
|
||||
Console.WriteLine(imageCount);
|
||||
Images = new List<IgdImage>(imageCount);
|
||||
for (int i = 0; i < imageCount; i++)
|
||||
{
|
||||
IgdImage image = new IgdImage();
|
||||
image.UnknownA = stream.ReadInt32();
|
||||
int index = stream.ReadInt32();
|
||||
if (index != i)
|
||||
throw new InvalidDataException("Read index does not match image index.");
|
||||
image.UnknownB = stream.ReadInt32();
|
||||
image.UnknownC = stream.ReadInt32();
|
||||
Size size = new Size(stream.ReadInt32(), stream.ReadInt32());
|
||||
image.Center = new Point(stream.ReadInt32(), stream.ReadInt32());
|
||||
|
||||
// Decompress the data.
|
||||
int dataSize = stream.ReadInt32();
|
||||
int dataSizeCompressed = stream.ReadInt32();
|
||||
byte[] data = Decompress(stream, dataSizeCompressed, dataSize);
|
||||
image.Bitmap = BitmapTools.CreateIndexed(data, size, palette);
|
||||
|
||||
Images.Add(image);
|
||||
}
|
||||
}
|
||||
|
||||
// ---- METHODS (PRIVATE) --------------------------------------------------------------------------------------
|
||||
|
||||
private static byte[] Decompress(Stream stream, int compressedSize, int decompressedSize)
|
||||
{
|
||||
// Each input byte is either a byte of decompressed data or a marker for a following command (0xFF).
|
||||
// A command consists of 4 bytes which specify the range of bytes to copy from already decompressed data.
|
||||
byte[] decompressed = new byte[decompressedSize];
|
||||
int i = 0;
|
||||
|
||||
long endPosition = stream.Position + compressedSize - 2;
|
||||
while (stream.Position < endPosition)
|
||||
{
|
||||
byte b = stream.Read1Byte();
|
||||
if (b == 0xFF)
|
||||
{
|
||||
// Copy existing data.
|
||||
byte mask1 = stream.Read1Byte();
|
||||
byte mask2 = stream.Read1Byte();
|
||||
int offset = mask2 & 0x0FFF | ((mask1 & 0x000F) << 8);
|
||||
int bytesToCopy = stream.Read1Byte();
|
||||
for (int j = 0; j < bytesToCopy; j++)
|
||||
{
|
||||
int outIndex = i + j;
|
||||
decompressed[outIndex] = decompressed[outIndex - offset];
|
||||
}
|
||||
i += bytesToCopy;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Raw transfer next byte.
|
||||
decompressed[i++] = b;
|
||||
}
|
||||
}
|
||||
|
||||
// Validate remaining 2 check bytes and return the decompressed data if valid.
|
||||
if (stream.ReadUInt16() != 0x0080)
|
||||
throw new InvalidDataException("Invalid check bytes at end of compressed image data.");
|
||||
return decompressed;
|
||||
}
|
||||
}
|
||||
}
|
18
src/Syroot.Worms/OnlineWorms/IgdImage.cs
Normal file
18
src/Syroot.Worms/OnlineWorms/IgdImage.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using System.Drawing;
|
||||
|
||||
namespace Syroot.Worms.OnlineWorms
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an image and its metadata as stored in an <see cref="Igd"/> image container.
|
||||
/// </summary>
|
||||
public class IgdImage
|
||||
{
|
||||
// ---- PROPERTIES ---------------------------------------------------------------------------------------------
|
||||
|
||||
public int UnknownA { get; set; }
|
||||
public int UnknownB { get; set; }
|
||||
public int UnknownC { get; set; }
|
||||
public Point Center { get; set; }
|
||||
public Bitmap Bitmap { get; set; }
|
||||
}
|
||||
}
|
@ -1,26 +1,23 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using Syroot.BinaryData;
|
||||
using Syroot.Worms.Core;
|
||||
using Syroot.Worms.Graphics;
|
||||
|
||||
namespace Syroot.Worms.OnlineWorms
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a KSF image container.
|
||||
/// </summary>
|
||||
public class Ksf : IDisposable
|
||||
public class Ksf // TODO: Implement ILoadableFile
|
||||
{
|
||||
// ---- FIELDS -------------------------------------------------------------------------------------------------
|
||||
|
||||
private bool _disposed;
|
||||
|
||||
// ---- CONSTRUCTORS & DESTRUCTOR ------------------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Ksf"/> class.
|
||||
/// </summary>
|
||||
public Ksf() { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Ksf"/> class, loading data from the file with the given
|
||||
/// <paramref name="fileName"/> and the colors in the provided <paramref name="palette"/>.
|
||||
@ -46,9 +43,9 @@ namespace Syroot.Worms.OnlineWorms
|
||||
// ---- PROPERTIES ---------------------------------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the list of converted <see cref="Image"/> instances stored in this KSF.
|
||||
/// Gets or sets the list of converted <see cref="Bitmap"/> instances stored in this KSF.
|
||||
/// </summary>
|
||||
public KsfImageList Images { get; } = new KsfImageList();
|
||||
public IList<KsfImage> Images { get; set; } = new List<KsfImage>();
|
||||
|
||||
// ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
|
||||
|
||||
@ -76,154 +73,32 @@ namespace Syroot.Worms.OnlineWorms
|
||||
int dataSize = stream.ReadInt32();
|
||||
|
||||
// Read image headers. Terminating image is of 0 size and data offset at end of data block.
|
||||
ImageHeader[] headers = new ImageHeader[imageCount];
|
||||
KsfImage[] images = new KsfImage[imageCount];
|
||||
int[] offsets = new int[imageCount];
|
||||
Size[] sizes = new Size[imageCount];
|
||||
for (int i = 0; i < imageCount; i++)
|
||||
{
|
||||
headers[i] = new ImageHeader
|
||||
{
|
||||
Offset = stream.ReadInt32(),
|
||||
HalfWidth = stream.ReadInt32(),
|
||||
HalfHeight = stream.ReadInt32(),
|
||||
Width = stream.ReadInt16(),
|
||||
Height = stream.ReadInt16()
|
||||
};
|
||||
KsfImage image = new KsfImage();
|
||||
offsets[i] = stream.ReadInt32();
|
||||
image.Center = new Point(stream.ReadInt32(), stream.ReadInt32());
|
||||
sizes[i] = new Size(stream.ReadInt16(), stream.ReadInt16());
|
||||
images[i] = image;
|
||||
}
|
||||
|
||||
// Convert images.
|
||||
Images = new List<KsfImage>(imageCount);
|
||||
long dataStart = stream.Position;
|
||||
for (int i = 0; i < imageCount - 1; i++)
|
||||
{
|
||||
ImageHeader header = headers[i];
|
||||
stream.Position = dataStart + header.Offset;
|
||||
int imageDataLength = headers[i + 1].Offset - header.Offset;
|
||||
Images.AddWithoutClone(ConvertImage(header, stream.ReadBytes(imageDataLength), palette));
|
||||
int offset = offsets[i];
|
||||
stream.Position = dataStart + offset;
|
||||
int dataLength = offsets[i + 1] - offset;
|
||||
Size size = sizes[i];
|
||||
if (!size.IsEmpty)
|
||||
images[i].Bitmap = BitmapTools.CreateIndexed(stream.ReadBytes(dataLength), size, palette.Colors);
|
||||
|
||||
Images.Add(images[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Releases all resources used by this instance.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
// Do not change this code. Put cleanup code in Dispose(bool disposing).
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
// ---- METHODS (PROTECTED) ------------------------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Releases all resources used by this instance.
|
||||
/// </summary>
|
||||
/// <param name="disposing"><see langword="true"/> to release managed resources.</param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!_disposed)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
foreach (Image image in Images)
|
||||
image.Dispose();
|
||||
}
|
||||
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
// ---- METHODS (PRIVATE) --------------------------------------------------------------------------------------
|
||||
|
||||
private Image ConvertImage(ImageHeader header, byte[] data, Palette palette)
|
||||
{
|
||||
if (header.Width == 0)
|
||||
return null;
|
||||
|
||||
using (DisposableGCHandle dataPin = new DisposableGCHandle(data, GCHandleType.Pinned))
|
||||
{
|
||||
// Transfer the pixel data, respecting power-of-2 strides.
|
||||
Bitmap bitmap = new Bitmap(header.Width, header.Height, PixelFormat.Format8bppIndexed);
|
||||
System.Drawing.Imaging.BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, header.Width, header.Height),
|
||||
ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
|
||||
for (int y = 0; y < header.Height; y++)
|
||||
Marshal.Copy(data, y * header.Width, bitmapData.Scan0 + y * bitmapData.Stride, header.Width);
|
||||
bitmap.UnlockBits(bitmapData);
|
||||
|
||||
// Transfer the palette.
|
||||
ColorPalette bitmapPalette = bitmap.Palette;
|
||||
for (int i = 0; i < Palette.ColorCount; i++)
|
||||
bitmapPalette.Entries[i] = palette.Colors[i];
|
||||
bitmap.Palette = bitmapPalette;
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
}
|
||||
|
||||
// ---- CLASSES, STRUCTS & ENUMS -------------------------------------------------------------------------------
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct ImageHeader
|
||||
{
|
||||
internal int Offset;
|
||||
internal int HalfWidth;
|
||||
internal int HalfHeight;
|
||||
internal short Width;
|
||||
internal short Height;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a list of <see cref="Image"/> instances which are cloned before being added to the list.
|
||||
/// </summary>
|
||||
public class KsfImageList : IList<Image>
|
||||
{
|
||||
private List<Image> _list;
|
||||
|
||||
internal KsfImageList()
|
||||
{
|
||||
_list = new List<Image>();
|
||||
}
|
||||
|
||||
public int Count => _list.Count;
|
||||
public bool IsReadOnly => false;
|
||||
|
||||
public Image this[int index]
|
||||
{
|
||||
get => _list[index];
|
||||
set
|
||||
{
|
||||
_list[index].Dispose();
|
||||
_list[index] = (Image)value?.Clone();
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(Image item) => _list.Add((Image)item?.Clone());
|
||||
internal void AddWithoutClone(Image item) => _list.Add(item);
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
foreach (Image image in _list)
|
||||
image.Dispose();
|
||||
_list.Clear();
|
||||
}
|
||||
|
||||
public bool Contains(Image item) => _list.Contains(item);
|
||||
public void CopyTo(Image[] array, int arrayIndex) => _list.CopyTo(array, arrayIndex);
|
||||
public IEnumerator<Image> GetEnumerator() => _list.GetEnumerator();
|
||||
public int IndexOf(Image item) => _list.IndexOf(item);
|
||||
public void Insert(int index, Image item) => _list.Insert(index, (Image)item?.Clone());
|
||||
public bool Remove(Image item)
|
||||
{
|
||||
bool result = _list.Remove(item);
|
||||
if (result)
|
||||
item.Dispose();
|
||||
return result;
|
||||
}
|
||||
|
||||
public void RemoveAt(int index)
|
||||
{
|
||||
Image image = _list[index];
|
||||
_list.RemoveAt(index);
|
||||
image.Dispose();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => _list.GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
15
src/Syroot.Worms/OnlineWorms/KsfImage.cs
Normal file
15
src/Syroot.Worms/OnlineWorms/KsfImage.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using System.Drawing;
|
||||
|
||||
namespace Syroot.Worms.OnlineWorms
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an image and its metadata as stored in a <see cref="Ksf"/> image container.
|
||||
/// </summary>
|
||||
public class KsfImage
|
||||
{
|
||||
// ---- PROPERTIES ---------------------------------------------------------------------------------------------
|
||||
|
||||
public Point Center { get; set; }
|
||||
public Bitmap Bitmap { get; set; }
|
||||
}
|
||||
}
|
@ -58,11 +58,8 @@ namespace Syroot.Worms.OnlineWorms
|
||||
{
|
||||
stream.Write("Online Worms Config File");
|
||||
|
||||
if (_passwordString != null)
|
||||
{
|
||||
stream.Position = 36;
|
||||
stream.Write(_passwordString);
|
||||
}
|
||||
stream.Position = 36;
|
||||
stream.Write(_passwordString);
|
||||
|
||||
stream.Position = 66;
|
||||
stream.Write("UID=", StringCoding.Raw);
|
||||
@ -76,14 +73,6 @@ namespace Syroot.Worms.OnlineWorms
|
||||
return mappedFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes any previously set password in the configuration.
|
||||
/// </summary>
|
||||
public void ClearPassword()
|
||||
{
|
||||
_passwordString = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decrypts the password stored in the configuration as previously set through
|
||||
/// <see cref="SetPassword(String, Int32)"/>.
|
||||
|
74
src/Syroot.Worms/OnlineWorms/Lpd.cs
Normal file
74
src/Syroot.Worms/OnlineWorms/Lpd.cs
Normal file
@ -0,0 +1,74 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using Syroot.BinaryData;
|
||||
|
||||
namespace Syroot.Worms.OnlineWorms
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an LPD layout description file used in Worms World Party Aqua.
|
||||
/// </summary>
|
||||
public class Lpd
|
||||
{
|
||||
// ---- CONSTRUCTORS & DESTRUCTOR ------------------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Lpd"/> class, loading data from the file with the given
|
||||
/// <paramref name="fileName"/>.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The name of the file to load the data from.</param>
|
||||
public Lpd(string fileName)
|
||||
{
|
||||
Load(fileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Lpd"/> class, loading data from the given
|
||||
/// <paramref name="stream"/>.
|
||||
/// </summary>
|
||||
/// <param name="stream">The <see cref="Stream"/> to load the data from.</param>
|
||||
public Lpd(Stream stream)
|
||||
{
|
||||
Load(stream);
|
||||
}
|
||||
|
||||
// ---- PROPERTIES ---------------------------------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the list of <see cref="LpdElement"/> instances stored by this class.
|
||||
/// </summary>
|
||||
public IList<LpdElement> Elements { get; set; }
|
||||
|
||||
// ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Loads the data from the file with the given <paramref name="fileName"/>.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The name of the file to load the data from.</param>
|
||||
public void Load(string fileName)
|
||||
{
|
||||
using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
Load(stream);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads the data from the given <paramref name="stream"/>.
|
||||
/// </summary>
|
||||
/// <param name="stream">The <see cref="Stream"/> to load the data from.</param>
|
||||
public void Load(Stream stream)
|
||||
{
|
||||
int elementCount = stream.ReadInt32();
|
||||
Elements = new List<LpdElement>(elementCount);
|
||||
while (elementCount-- > 0)
|
||||
{
|
||||
Elements.Add(new LpdElement
|
||||
{
|
||||
FileName = stream.ReadString(StringCoding.Int32CharCount, Encodings.Win949),
|
||||
Rectangle = new Rectangle(stream.ReadInt32(), stream.ReadInt32(), stream.ReadInt32(), stream.ReadInt32()),
|
||||
Properties = stream.ReadInt32(),
|
||||
Version = stream.ReadInt32()
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
32
src/Syroot.Worms/OnlineWorms/LpdElement.cs
Normal file
32
src/Syroot.Worms/OnlineWorms/LpdElement.cs
Normal file
@ -0,0 +1,32 @@
|
||||
using System.Drawing;
|
||||
|
||||
namespace Syroot.Worms.OnlineWorms
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a single UI element described in an <see cref="Lpd"/> file.
|
||||
/// </summary>
|
||||
public class LpdElement
|
||||
{
|
||||
// ---- PROPERTIES ---------------------------------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a the relative path to the IGD storing the image of this element.
|
||||
/// </summary>
|
||||
public string FileName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a the area at which the UI element appears.
|
||||
/// </summary>
|
||||
public Rectangle Rectangle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an unknown value.
|
||||
/// </summary>
|
||||
public int Properties { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value which must lie between 0-4 (inclusive) for the game to accept the element.
|
||||
/// </summary>
|
||||
public int Version { get; set; }
|
||||
}
|
||||
}
|
@ -1,49 +1,50 @@
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using Syroot.BinaryData;
|
||||
using Syroot.Worms.Core;
|
||||
using Syroot.Worms.Graphics;
|
||||
|
||||
namespace Syroot.Worms.OnlineWorms
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a PAL color palette.
|
||||
/// </summary>
|
||||
public class Palette
|
||||
public class Palette : ILoadableFile, IPalette
|
||||
{
|
||||
// ---- CONSTANTS ----------------------------------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// The number of colors stored in a palette.
|
||||
/// </summary>
|
||||
public const int ColorCount = 256;
|
||||
internal const int ColorCount = 256;
|
||||
|
||||
// ---- CONSTRUCTORS & DESTRUCTOR ------------------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Palette"/> class.
|
||||
/// </summary>
|
||||
public Palette() { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Palette"/> class, loading data from the file with the given
|
||||
/// <paramref name="fileName"/>.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The name of the file to load the data from.</param>
|
||||
public Palette(string fileName)
|
||||
{
|
||||
Load(fileName);
|
||||
}
|
||||
public Palette(string fileName) => Load(fileName);
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Palette"/> class, loading data from the given
|
||||
/// <paramref name="stream"/>.
|
||||
/// </summary>
|
||||
/// <param name="stream">The <see cref="Stream"/> to load the data from.</param>
|
||||
public Palette(Stream stream)
|
||||
{
|
||||
Load(stream);
|
||||
}
|
||||
public Palette(Stream stream) => Load(stream);
|
||||
|
||||
// ---- PROPERTIES ---------------------------------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Gets the array of 256 colors stored in this palette.
|
||||
/// </summary>
|
||||
public Color[] Colors { get; } = new Color[ColorCount];
|
||||
public Color[] Colors { get; set; } = new Color[ColorCount];
|
||||
|
||||
// ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using Syroot.BinaryData;
|
||||
using Syroot.Maths;
|
||||
using Syroot.Worms.Core;
|
||||
using Syroot.Worms.Graphics;
|
||||
|
||||
namespace Syroot.Worms
|
||||
{
|
||||
@ -10,7 +11,7 @@ namespace Syroot.Worms
|
||||
/// Used by WA and WWP. S. http://worms2d.info/Palette_file.
|
||||
/// </summary>
|
||||
[RiffFile("PAL ")]
|
||||
public class RiffPalette : RiffFile, ILoadableFile, ISaveableFile
|
||||
public class RiffPalette : RiffFile, ILoadableFile, ISaveableFile, IPalette
|
||||
{
|
||||
// ---- CONSTANTS ----------------------------------------------------------------------------------------------
|
||||
|
||||
@ -132,7 +133,7 @@ namespace Syroot.Worms
|
||||
Colors = new Color[reader.ReadInt16()];
|
||||
for (int i = 0; i < Colors.Length; i++)
|
||||
{
|
||||
Colors[i] = new Color(reader.Read1Byte(), reader.Read1Byte(), reader.Read1Byte());
|
||||
Colors[i] = Color.FromArgb(reader.Read1Byte(), reader.Read1Byte(), reader.Read1Byte());
|
||||
int alpha = reader.ReadByte(); // Dismiss alpha, as it is not used in WA.
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,6 @@
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Syroot.BinaryData.Serialization" Version="5.0.0" />
|
||||
<PackageReference Include="Syroot.Maths" Version="1.5.3" />
|
||||
<PackageReference Include="Syroot.BinaryData" Version="5.0.0" />
|
||||
<PackageReference Include="System.Drawing.Common" Version="4.5.1" />
|
||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.5.0" />
|
||||
|
@ -1,7 +1,7 @@
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Syroot.BinaryData;
|
||||
using Syroot.Maths;
|
||||
using Syroot.Worms.Core;
|
||||
|
||||
namespace Syroot.Worms.WorldParty
|
||||
@ -21,35 +21,27 @@ namespace Syroot.Worms.WorldParty
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LandData"/> class.
|
||||
/// </summary>
|
||||
public LandData()
|
||||
{
|
||||
}
|
||||
public LandData() { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LandData"/> class, loading the data from the given
|
||||
/// <see cref="Stream"/>.
|
||||
/// </summary>
|
||||
/// <param name="stream">The <see cref="Stream"/> to load the data from.</param>
|
||||
public LandData(Stream stream)
|
||||
{
|
||||
Load(stream);
|
||||
}
|
||||
public LandData(Stream stream) => Load(stream);
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LandData"/> class, loading the data from the given file.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The name of the file to load the data from.</param>
|
||||
public LandData(string fileName)
|
||||
{
|
||||
Load(fileName);
|
||||
}
|
||||
public LandData(string fileName) => Load(fileName);
|
||||
|
||||
// ---- PROPERTIES ---------------------------------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the size of the landscape in pixels.
|
||||
/// </summary>
|
||||
public Vector2 Size { get; set; }
|
||||
public Size Size { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether an indestructible top border will be enabled.
|
||||
@ -64,7 +56,7 @@ namespace Syroot.Worms.WorldParty
|
||||
/// <summary>
|
||||
/// Gets or sets an array of coordinates at which objects can be placed.
|
||||
/// </summary>
|
||||
public Vector2[] ObjectLocations { get; set; }
|
||||
public Point[] ObjectLocations { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the visual foreground image.
|
||||
@ -90,7 +82,7 @@ namespace Syroot.Worms.WorldParty
|
||||
/// Gets or sets the path to the Water.dir file.
|
||||
/// </summary>
|
||||
public string WaterDirPath { get; set; }
|
||||
|
||||
|
||||
// ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
@ -103,18 +95,16 @@ namespace Syroot.Worms.WorldParty
|
||||
{
|
||||
// Read the header.
|
||||
if (reader.ReadInt32() != _signature)
|
||||
{
|
||||
throw new InvalidDataException("Invalid LND file signature.");
|
||||
}
|
||||
int fileSize = reader.ReadInt32();
|
||||
|
||||
// Read the data.
|
||||
Size = reader.ReadStruct<Vector2>();
|
||||
Size = reader.ReadStruct<Size>();
|
||||
TopBorder = reader.ReadBoolean(BooleanCoding.Dword);
|
||||
WaterHeight = reader.ReadInt32();
|
||||
|
||||
// Read the possible object coordinate array.
|
||||
ObjectLocations = reader.ReadStructs<Vector2>(reader.ReadInt32());
|
||||
ObjectLocations = reader.ReadStructs<Point>(reader.ReadInt32());
|
||||
|
||||
// Read the image data.
|
||||
Foreground = new Img(stream, true);
|
||||
@ -134,9 +124,7 @@ namespace Syroot.Worms.WorldParty
|
||||
public void Load(string fileName)
|
||||
{
|
||||
using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
Load(stream);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -180,9 +168,7 @@ namespace Syroot.Worms.WorldParty
|
||||
public void Save(string fileName)
|
||||
{
|
||||
using (FileStream stream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
|
||||
{
|
||||
Save(stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Syroot.BinaryData;
|
||||
using Syroot.Maths;
|
||||
using Syroot.Worms.Core;
|
||||
|
||||
namespace Syroot.Worms.WorldParty
|
||||
@ -79,7 +79,7 @@ namespace Syroot.Worms.WorldParty
|
||||
/// <summary>
|
||||
/// Gets or sets the team grave bitmap if it uses a custom one.
|
||||
/// </summary>
|
||||
public BitmapData Grave { get; set; }
|
||||
public RawBitmapData Grave { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the team's special weapon.
|
||||
@ -149,7 +149,7 @@ namespace Syroot.Worms.WorldParty
|
||||
/// <summary>
|
||||
/// Gets or sets the bitmap of the team flag.
|
||||
/// </summary>
|
||||
public BitmapData Flag { get; set; }
|
||||
public RawBitmapData Flag { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an unknown value.
|
||||
@ -209,10 +209,10 @@ namespace Syroot.Worms.WorldParty
|
||||
if (GraveSprite < 0)
|
||||
{
|
||||
GraveFileName = reader.ReadFixedString(0x20);
|
||||
Grave = new BitmapData()
|
||||
Grave = new RawBitmapData()
|
||||
{
|
||||
BitsPerPixel = 8,
|
||||
Size = new Vector2(24, 32),
|
||||
Size = new Size(24, 32),
|
||||
Palette = reader.ReadStructs<Color>(256),
|
||||
Data = reader.ReadBytes(24 * 32)
|
||||
};
|
||||
@ -232,10 +232,10 @@ namespace Syroot.Worms.WorldParty
|
||||
MissionStatuses = reader.ReadStructs<TeamMissionStatus>(_missionCount);
|
||||
|
||||
FlagFileName = reader.ReadFixedString(0x20);
|
||||
Flag = new BitmapData()
|
||||
Flag = new RawBitmapData()
|
||||
{
|
||||
BitsPerPixel = 8,
|
||||
Size = new Vector2(20, 17),
|
||||
Size = new Size(20, 17),
|
||||
Palette = reader.ReadStructs<Color>(256),
|
||||
Data = reader.ReadBytes(20 * 17)
|
||||
};
|
||||
|
@ -1,7 +1,7 @@
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Syroot.BinaryData;
|
||||
using Syroot.Maths;
|
||||
using Syroot.Worms.Core;
|
||||
|
||||
namespace Syroot.Worms.Worms2
|
||||
@ -21,45 +21,37 @@ namespace Syroot.Worms.Worms2
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LandData"/> class.
|
||||
/// </summary>
|
||||
public LandData()
|
||||
{
|
||||
}
|
||||
public LandData() { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LandData"/> class, loading the data from the given
|
||||
/// <see cref="Stream"/>.
|
||||
/// </summary>
|
||||
/// <param name="stream">The <see cref="Stream"/> to load the data from.</param>
|
||||
public LandData(Stream stream)
|
||||
{
|
||||
Load(stream);
|
||||
}
|
||||
public LandData(Stream stream) => Load(stream);
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LandData"/> class, loading the data from the given file.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The name of the file to load the data from.</param>
|
||||
public LandData(string fileName)
|
||||
{
|
||||
Load(fileName);
|
||||
}
|
||||
public LandData(string fileName) => Load(fileName);
|
||||
|
||||
// ---- PROPERTIES ---------------------------------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the size of the landscape in pixels.
|
||||
/// </summary>
|
||||
public Vector2 Size { get; set; }
|
||||
public Size Size { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether an indestructible top border will be enabled.
|
||||
/// </summary>
|
||||
public bool TopBorder { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an array of coordinates at which objects can be placed.
|
||||
/// </summary>
|
||||
public Vector2[] ObjectLocations { get; set; }
|
||||
public Point[] ObjectLocations { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an unknown value, seeming to be 0 most of the time.
|
||||
@ -95,7 +87,7 @@ namespace Syroot.Worms.Worms2
|
||||
/// Gets or sets the path to the Water.dir file.
|
||||
/// </summary>
|
||||
public string WaterDirPath { get; set; }
|
||||
|
||||
|
||||
// ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
@ -108,17 +100,15 @@ namespace Syroot.Worms.Worms2
|
||||
{
|
||||
// Read the header.
|
||||
if (reader.ReadInt32() != _signature)
|
||||
{
|
||||
throw new InvalidDataException("Invalid LND file signature.");
|
||||
}
|
||||
int fileSize = reader.ReadInt32();
|
||||
|
||||
// Read the data.
|
||||
Size = reader.ReadStruct<Vector2>();
|
||||
Size = reader.ReadStruct<Size>();
|
||||
TopBorder = reader.ReadBoolean(BooleanCoding.Dword);
|
||||
|
||||
// Read the possible object coordinate array.
|
||||
ObjectLocations = reader.ReadStructs<Vector2>(reader.ReadInt32());
|
||||
ObjectLocations = reader.ReadStructs<Point>(reader.ReadInt32());
|
||||
Unknown = reader.ReadInt32();
|
||||
|
||||
// Read the image data.
|
||||
@ -140,9 +130,7 @@ namespace Syroot.Worms.Worms2
|
||||
public void Load(string fileName)
|
||||
{
|
||||
using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
Load(stream);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -187,9 +175,7 @@ namespace Syroot.Worms.Worms2
|
||||
public void Save(string fileName)
|
||||
{
|
||||
using (FileStream stream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
|
||||
{
|
||||
Save(stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user