Add bulletin board logic

This commit is contained in:
Kurt 2020-04-30 23:12:58 -07:00
parent 493124d74a
commit ca0545809c
2 changed files with 140 additions and 0 deletions

View File

@ -0,0 +1,113 @@
using System.Runtime.InteropServices;
// ReSharper disable FieldCanBeMadeReadOnly.Global
// ReSharper disable MemberCanBePrivate.Global
#pragma warning disable CS8618, CA1815
namespace NHSE.Core
{
[StructLayout(LayoutKind.Sequential, Pack = 1, Size = SIZE, CharSet = CharSet.Unicode)]
public struct GSaveBulletinBoard
{
public const int SIZE = 0xe0ae8;
public GSaveDate BuiltDate; // @0x0 size 0x4, align 2
public bool _3347e149; // @0x4 size 0x1, align 1
public BulletinBoardStock Stock; // @0x8 size 0xe0ad8, align 8
public uint LatestUniqueId; // @0xe0ae0 size 0x4, align 4
};
public struct BulletinBoardStock
{
public const int SIZE = 0xe0ad8;
public const int MaxCount = 30;
[field: MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxCount)]
public GSaveBBS[] Buffer; // @0x0 size 0x77d0, align 8
[field: MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxCount)]
public int[] IndexTable; // @0xe0a60 size 0x4, align 4
}
[StructLayout(LayoutKind.Sequential, Pack = 1, Size = SIZE, CharSet = CharSet.Unicode)]
public struct GSaveBBS
{
public const int SIZE = 0x77d0;
public GSaveDate Date; // @0x0 size 0x4, align 2
[field: MarshalAs(UnmanagedType.ByValTStr, SizeConst = 240/2)]
public string Body; // @0x4 size 0x1e0, align 2
[field: MarshalAs(UnmanagedType.ByValTStr, SizeConst = 48/2)]
public string Footer; // @0x1e4 size 0x60, align 2
public Handwriting HandWrite; // @0x244 size 0x7538, align 4
public GSavePlayerId PlayerId; // @0x777c size 0x38, align 4
public ushort _5d1fcb04; // @0x77b4 size 0x2, align 2
public ushort DesignId; // @0x77b6 size 0x2, align 2
public ulong PopId; // @0x77b8 size 0x8, align 8
public ulong NsaId; // @0x77c0 size 0x8, align 8
public uint UniqueId; // @0x77c8 size 0x4, align 4
}
[StructLayout(LayoutKind.Sequential, Pack = 1, Size = SIZE)]
public struct GSaveDate
{
public const int SIZE = 4;
public ushort Year;
public byte Month;
public byte Day;
}
[StructLayout(LayoutKind.Sequential, Pack = 1, Size = SIZE)]
public struct Handwriting
{
public const int SIZE = 0x7538;
public const int InkCount = 30_000;
[field: MarshalAs(UnmanagedType.ByValArray, SizeConst = InkCount)]
public byte[] Image;
[field: MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] Palette;
public uint VerticesNum;
}
[StructLayout(LayoutKind.Sequential, Pack = 1, Size = SIZE)]
public struct GSavePlayerId
{
public const int SIZE = 0x38;
public GSaveLandId LandId;
public GSavePlayerBaseId BaseId;
}
[StructLayout(LayoutKind.Sequential, Pack = 4, Size = SIZE, CharSet = CharSet.Unicode)]
public struct GSaveLandId
{
public const int SIZE = 0x1C;
public uint Id;
[field: MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x14 / 2)]
public string Name;
public byte IslandRubyType;
}
[StructLayout(LayoutKind.Sequential, Pack = 4, Size = SIZE, CharSet = CharSet.Unicode)]
public struct GSavePlayerBaseId
{
public const int SIZE = 0x1C;
public uint Id;
[field: MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x14 / 2)]
public string Name;
public int Gender; // enum
}
}
#pragma warning restore CS8618, CA1815

View File

@ -0,0 +1,27 @@
using FluentAssertions;
using NHSE.Core;
using Xunit;
namespace NHSE.Tests
{
public class FancyMarshalTests
{
[Fact] public void MarshalGSaveBulletinBoard() => MarshalBytesTestS<GSaveBulletinBoard>(GSaveBulletinBoard.SIZE);
[Fact] public void MarshalBulletinBoard() => MarshalBytesTestS<BulletinBoardStock>(BulletinBoardStock.SIZE);
[Fact] public void MarshalGSaveBBS() => MarshalBytesTestS<GSaveBBS>(GSaveBBS.SIZE);
[Fact] public void MarshalGSaveDate() => MarshalBytesTestS<GSaveDate>(GSaveDate.SIZE);
[Fact] public void MarshalGSavePlayerId() => MarshalBytesTestS<GSavePlayerId>(GSavePlayerId.SIZE);
[Fact] public void MarshalGSaveLandId() => MarshalBytesTestS<GSaveLandId>(GSaveLandId.SIZE);
[Fact] public void MarshalGSavePlayerBaseId() => MarshalBytesTestS<GSavePlayerBaseId>(GSavePlayerBaseId.SIZE);
[Fact] public void MarshalHandwriting() => MarshalBytesTestS<Handwriting>(Handwriting.SIZE);
private static void MarshalBytesTestS<T>(int size) where T : struct
{
var bytes = new byte[size];
var obj = bytes.ToStructure<T>();
var decomputed = obj.ToBytes();
decomputed.Length.Should().Be(size);
}
}
}