diff --git a/SM64Lib.LIBMIO0/MIO0.cs b/SM64Lib.LIBMIO0/MIO0.cs
index 085db25..f94338d 100644
--- a/SM64Lib.LIBMIO0/MIO0.cs
+++ b/SM64Lib.LIBMIO0/MIO0.cs
@@ -1,151 +1,148 @@
-using System;
+namespace SM64Lib.LIBMIO0;
-namespace SM64Lib.LIBMIO0
+public struct MIO0_Header
{
- public struct MIO0_Header
+ public uint dest_size;
+ public uint comp_offset;
+ public uint uncomp_offset;
+ public bool big_endian;
+};
+
+public class MIO0
+{
+
+ private const int MIO0_HEADER_LENGTH = 16;
+
+ private static int GET_BIT(byte[] buf, int offset, int bit)
{
- public uint dest_size;
- public uint comp_offset;
- public uint uncomp_offset;
- public bool big_endian;
- };
+ return buf[(bit / 8) + offset] & (1 << (7 - (bit % 8)));
+ }
- public class MIO0
+ private static bool compareByteArrays(byte[] buf1, byte[] buf2, int length)
{
+ for (int i = 0; i < length; ++i)
+ if (buf1[i] != buf2[i]) return false;
+ return true;
+ }
- private const int MIO0_HEADER_LENGTH = 16;
+ private static uint read_u32_be(byte[] buf, int off)
+ {
+ return (uint)(((buf)[off + 0] << 24) + ((buf)[off + 1] << 16) +
+ ((buf)[off + 2] << 8) + ((buf)[off + 3]));
+ }
- private static int GET_BIT(byte[] buf, int offset, int bit)
+ private static uint read_u32_le(byte[] buf, int off)
+ {
+ return (uint)(((buf)[off + 1] << 24) + ((buf)[off + 0] << 16) +
+ ((buf)[off + 3] << 8) + ((buf)[off + 2]));
+ }
+
+ private static void write_u32_be(byte[] buf, uint val, int off)
+ {
+ buf[off + 0] = (byte)((val >> 24) & 0xFF);
+ buf[off + 1] = (byte)((val >> 16) & 0xFF);
+ buf[off + 2] = (byte)((val >> 8) & 0xFF);
+ buf[off + 3] = (byte)(val & 0xFF);
+ }
+
+ ///
+ /// decode MIO0 header
+ /// returns true if valid header, false otherwise
+ ///
+ public static bool decode_header(byte[] buf, ref MIO0_Header head)
+ {
+ byte[] mio0_ascii_be = new byte[] { 0x4D, 0x49, 0x4F, 0x30 };
+ byte[] mio0_ascii_le = new byte[] { 0x49, 0x4D, 0x30, 0x4F };
+
+ if (compareByteArrays(buf, mio0_ascii_be, 4))
{
- return buf[(bit / 8) + offset] & (1 << (7 - (bit % 8)));
+ head.dest_size = read_u32_be(buf, 4);
+ head.comp_offset = read_u32_be(buf, 8);
+ head.uncomp_offset = read_u32_be(buf, 12);
+ head.big_endian = true;
+ return true;
}
-
- private static bool compareByteArrays(byte[] buf1, byte[] buf2, int length)
+ else if (compareByteArrays(buf, mio0_ascii_le, 4))
{
- for (int i = 0; i < length; ++i)
- if (buf1[i] != buf2[i]) return false;
+ head.dest_size = read_u32_le(buf, 4);
+ head.comp_offset = read_u32_le(buf, 8);
+ head.uncomp_offset = read_u32_le(buf, 12);
+ head.big_endian = false;
return true;
}
- private static uint read_u32_be(byte[] buf, int off)
- {
- return (uint)(((buf)[off + 0] << 24) + ((buf)[off + 1] << 16) +
- ((buf)[off + 2] << 8) + ((buf)[off + 3]));
- }
-
- private static uint read_u32_le(byte[] buf, int off)
- {
- return (uint)(((buf)[off + 1] << 24) + ((buf)[off + 0] << 16) +
- ((buf)[off + 3] << 8) + ((buf)[off + 2]));
- }
-
- private static void write_u32_be(byte[] buf, uint val, int off)
- {
- buf[off + 0] = (byte)((val >> 24) & 0xFF);
- buf[off + 1] = (byte)((val >> 16) & 0xFF);
- buf[off + 2] = (byte)((val >> 8) & 0xFF);
- buf[off + 3] = (byte)(val & 0xFF);
- }
-
- ///
- /// decode MIO0 header
- /// returns true if valid header, false otherwise
- ///
- public static bool decode_header(byte[] buf, ref MIO0_Header head)
- {
- byte[] mio0_ascii_be = new byte[] { 0x4D, 0x49, 0x4F, 0x30 };
- byte[] mio0_ascii_le = new byte[] { 0x49, 0x4D, 0x30, 0x4F };
-
- if (compareByteArrays(buf, mio0_ascii_be, 4))
- {
- head.dest_size = read_u32_be(buf, 4);
- head.comp_offset = read_u32_be(buf, 8);
- head.uncomp_offset = read_u32_be(buf, 12);
- head.big_endian = true;
- return true;
- }
- else if (compareByteArrays(buf, mio0_ascii_le, 4))
- {
- head.dest_size = read_u32_le(buf, 4);
- head.comp_offset = read_u32_le(buf, 8);
- head.uncomp_offset = read_u32_le(buf, 12);
- head.big_endian = false;
- return true;
- }
-
- return false;
- }
-
- ///
- /// encode MIO0 header from struct
- ///
- public static void encode_header(byte[] buf, ref MIO0_Header head)
- {
- write_u32_be(buf, 0x4D494F30, 0); // write "MIO0" at start of buffer
- write_u32_be(buf, head.dest_size, 4);
- write_u32_be(buf, head.comp_offset, 8);
- write_u32_be(buf, head.uncomp_offset, 12);
- }
-
- ///
- /// decode MIO0 data
- /// mio0_buf: buffer containing MIO0 data
- /// returns the raw data as a byte array
- ///
- public static byte[] mio0_decode(byte[] mio0_buf)
- {
-
- MIO0_Header head = new MIO0_Header();
- uint bytes_written = 0;
- int bit_idx = 0;
- int comp_idx = 0;
- int uncomp_idx = 0;
- bool valid;
-
- // extract header
- valid = decode_header(mio0_buf, ref head);
- // verify MIO0 header
- if (!valid)
- {
- return null;
- }
-
- if (!head.big_endian)
- {
- return null;
- }
-
- byte[] decoded = new byte[head.dest_size];
-
- // decode data
- while (bytes_written < head.dest_size)
- {
- if (GET_BIT(mio0_buf, MIO0_HEADER_LENGTH, bit_idx) > 0)
- {
- // 1 - pull uncompressed data
- decoded[bytes_written] = mio0_buf[head.uncomp_offset + uncomp_idx];
- bytes_written++;
- uncomp_idx++;
- }
- else
- {
- // 0 - read compressed data
- byte a = mio0_buf[head.comp_offset + comp_idx + 0];
- byte b = mio0_buf[head.comp_offset + comp_idx + 1];
- comp_idx += 2;
- int length = ((a & 0xF0) >> 4) + 3;
- int idx = ((a & 0x0F) << 8) + b + 1;
- for (int i = 0; i < length; i++)
- {
- decoded[bytes_written] = decoded[bytes_written - idx];
- bytes_written++;
- }
-
- }
- bit_idx++;
- }
- return decoded;
- }
-
+ return false;
}
+
+ ///
+ /// encode MIO0 header from struct
+ ///
+ public static void encode_header(byte[] buf, ref MIO0_Header head)
+ {
+ write_u32_be(buf, 0x4D494F30, 0); // write "MIO0" at start of buffer
+ write_u32_be(buf, head.dest_size, 4);
+ write_u32_be(buf, head.comp_offset, 8);
+ write_u32_be(buf, head.uncomp_offset, 12);
+ }
+
+ ///
+ /// decode MIO0 data
+ /// mio0_buf: buffer containing MIO0 data
+ /// returns the raw data as a byte array
+ ///
+ public static byte[] mio0_decode(byte[] mio0_buf)
+ {
+
+ MIO0_Header head = new MIO0_Header();
+ uint bytes_written = 0;
+ int bit_idx = 0;
+ int comp_idx = 0;
+ int uncomp_idx = 0;
+ bool valid;
+
+ // extract header
+ valid = decode_header(mio0_buf, ref head);
+ // verify MIO0 header
+ if (!valid)
+ {
+ return null;
+ }
+
+ if (!head.big_endian)
+ {
+ return null;
+ }
+
+ byte[] decoded = new byte[head.dest_size];
+
+ // decode data
+ while (bytes_written < head.dest_size)
+ {
+ if (GET_BIT(mio0_buf, MIO0_HEADER_LENGTH, bit_idx) > 0)
+ {
+ // 1 - pull uncompressed data
+ decoded[bytes_written] = mio0_buf[head.uncomp_offset + uncomp_idx];
+ bytes_written++;
+ uncomp_idx++;
+ }
+ else
+ {
+ // 0 - read compressed data
+ byte a = mio0_buf[head.comp_offset + comp_idx + 0];
+ byte b = mio0_buf[head.comp_offset + comp_idx + 1];
+ comp_idx += 2;
+ int length = ((a & 0xF0) >> 4) + 3;
+ int idx = ((a & 0x0F) << 8) + b + 1;
+ for (int i = 0; i < length; i++)
+ {
+ decoded[bytes_written] = decoded[bytes_written - idx];
+ bytes_written++;
+ }
+
+ }
+ bit_idx++;
+ }
+ return decoded;
+ }
+
}
diff --git a/SM64Lib.LIBMIO0/Properties/AssemblyInfo.cs b/SM64Lib.LIBMIO0/Properties/AssemblyInfo.cs
index 0b48e7b..ab4224b 100644
--- a/SM64Lib.LIBMIO0/Properties/AssemblyInfo.cs
+++ b/SM64Lib.LIBMIO0/Properties/AssemblyInfo.cs
@@ -1,6 +1,4 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
+using System.Runtime.InteropServices;
// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
diff --git a/SM64Lib.N64Graphics/N64Graphics.cs b/SM64Lib.N64Graphics/N64Graphics.cs
index 342eb6b..3575997 100644
--- a/SM64Lib.N64Graphics/N64Graphics.cs
+++ b/SM64Lib.N64Graphics/N64Graphics.cs
@@ -1,524 +1,523 @@
using System.Drawing;
-namespace SM64Lib.N64Graphics
+namespace SM64Lib.N64Graphics;
+
+public enum N64Codec { RGBA16, RGBA32, IA16, IA8, IA4, I8, I4, CI8, CI4, ONEBPP };
+public enum N64IMode { AlphaCopyIntensity, AlphaBinary, AlphaOne };
+
+public class N64Graphics
{
- public enum N64Codec { RGBA16, RGBA32, IA16, IA8, IA4, I8, I4, CI8, CI4, ONEBPP };
- public enum N64IMode { AlphaCopyIntensity, AlphaBinary, AlphaOne };
-
- public class N64Graphics
+ private static int SCALE_5_8(int val)
{
- private static int SCALE_5_8(int val)
+ return (val * 0xFF) / 0x1F;
+ }
+
+ private static byte SCALE_8_5(byte val)
+ {
+ return (byte)((((val) + 4) * 0x1F) / 0xFF);
+ }
+
+ private static byte SCALE_8_4(byte val)
+ {
+ return (byte)(val / 0x11);
+ }
+
+ private static int SCALE_3_8(byte val)
+ {
+ return (val * 0xFF) / 0x7;
+ }
+
+ private static byte SCALE_8_3(byte val)
+ {
+ return (byte)(val / 0x24);
+ }
+
+ public static Color RGBA16Color(byte c0, byte c1)
+ {
+ int r = SCALE_5_8((c0 & 0xF8) >> 3);
+ int g = SCALE_5_8(((c0 & 0x07) << 2) | ((c1 & 0xC0) >> 6));
+ int b = SCALE_5_8((c1 & 0x3E) >> 1);
+ int a = ((c1 & 0x1) > 0) ? 255 : 0;
+ return Color.FromArgb(a, r, g, b);
+ }
+
+ public static void ColorRGBA16(Color col, out byte c0, out byte c1)
+ {
+ byte r, g, b;
+ r = SCALE_8_5(col.R);
+ g = SCALE_8_5(col.G);
+ b = SCALE_8_5(col.B);
+ c0 = (byte)((r << 3) | (g >> 2));
+ c1 = (byte)(((g & 0x3) << 6) | (b << 1) | ((col.A > 0) ? 1 : 0));
+ }
+
+ public static Color RGBA16Color(byte[] data, int pixOffset)
+ {
+ byte c0 = data[pixOffset];
+ byte c1 = data[pixOffset + 1];
+
+ return RGBA16Color(c0, c1);
+ }
+
+ public static Color RGBA32Color(byte[] data, int pixOffset)
+ {
+ int r, g, b, a;
+ r = data[pixOffset];
+ g = data[pixOffset + 1];
+ b = data[pixOffset + 2];
+ a = data[pixOffset + 3];
+ return Color.FromArgb(a, r, g, b);
+ }
+
+ public static Color IA16Color(byte[] data, int pixOffset)
+ {
+ int i = data[pixOffset];
+ int a = data[pixOffset + 1];
+ return Color.FromArgb(a, i, i, i);
+ }
+
+ public static Color IA8Color(byte[] data, int pixOffset)
+ {
+ int i, a;
+ byte c = data[pixOffset];
+ i = (c >> 4) * 0x11;
+ a = (c & 0xF) * 0x11;
+ return Color.FromArgb(a, i, i, i);
+ }
+
+ public static Color IA4Color(byte[] data, int pixOffset, int nibble)
+ {
+ int shift = (1 - nibble) * 4;
+ int i, a;
+ int val = (data[pixOffset] >> shift) & 0xF;
+ i = SCALE_3_8((byte)(val >> 1));
+ a = (val & 0x1) > 0 ? 0xFF : 0x00;
+ return Color.FromArgb(a, i, i, i);
+ }
+
+ public static Color I8Color(byte[] data, int pixOffset, N64IMode mode = N64IMode.AlphaCopyIntensity)
+ {
+ int i = data[pixOffset];
+ int a = i;
+ switch (mode)
{
- return (val * 0xFF) / 0x1F;
+ case N64IMode.AlphaBinary: a = (i == 0) ? 0 : 0xFF; break;
+ case N64IMode.AlphaCopyIntensity: a = i; break;
+ case N64IMode.AlphaOne: a = 0xFF; break;
}
+ return Color.FromArgb(a, i, i, i);
+ }
- private static byte SCALE_8_5(byte val)
+ public static Color I4Color(byte[] data, int pixOffset, int nibble, N64IMode mode = N64IMode.AlphaCopyIntensity)
+ {
+ int shift = (1 - nibble) * 4;
+ int i = (data[pixOffset] >> shift) & 0xF;
+ i *= 0x11;
+ int a = i;
+ switch (mode)
{
- return (byte)((((val) + 4) * 0x1F) / 0xFF);
+ case N64IMode.AlphaBinary: a = (i == 0) ? 0 : 0xFF; break;
+ case N64IMode.AlphaCopyIntensity: a = i; break;
+ case N64IMode.AlphaOne: a = 0xFF; break;
}
+ return Color.FromArgb(a, i, i, i);
+ }
- private static byte SCALE_8_4(byte val)
+ public static Color CI8Color(byte[] data, byte[] palette, int pixOffset)
+ {
+ byte c0, c1;
+ int palOffset = 2 * data[pixOffset];
+ c0 = palette[palOffset];
+ c1 = palette[palOffset + 1];
+
+ return RGBA16Color(c0, c1);
+ }
+
+ public static Color CI4Color(byte[] data, byte[] palette, int pixOffset, int nibble)
+ {
+ byte c0, c1;
+ int shift = (1 - nibble) * 4;
+ int palOffset = 2 * ((data[pixOffset] >> shift) & 0xF);
+ c0 = palette[palOffset];
+ c1 = palette[palOffset + 1];
+
+ return RGBA16Color(c0, c1);
+ }
+
+ public static Color BPPColor(byte[] data, int pixOffset, int bit)
+ {
+ int i, a;
+ int val = (data[pixOffset] >> (7 - bit)) & 0x1;
+ i = a = val == 0 ? 0x00 : 0xFF;
+ return Color.FromArgb(a, i, i, i);
+ }
+
+ // return number of bytes needed to encode numPixels using codec
+ public static int PixelsToBytes(N64Codec codec, int numPixels)
+ {
+ int numBytes = 0;
+ switch (codec)
{
- return (byte)(val / 0x11);
+ case N64Codec.RGBA16: numBytes = numPixels * 2; break;
+ case N64Codec.RGBA32: numBytes = numPixels * 4; break;
+ case N64Codec.IA16: numBytes = numPixels * 2; break;
+ case N64Codec.IA8: numBytes = numPixels; break;
+ case N64Codec.IA4: numBytes = numPixels / 2; break;
+ case N64Codec.I8: numBytes = numPixels; break;
+ case N64Codec.I4: numBytes = numPixels / 2; break;
+ case N64Codec.CI8: numBytes = numPixels; break;
+ case N64Codec.CI4: numBytes = numPixels / 2; break;
+ case N64Codec.ONEBPP: numBytes = numPixels / 8; break;
}
+ return numBytes;
+ }
- private static int SCALE_3_8(byte val)
+ public static string CodecString(N64Codec codec)
+ {
+ switch (codec)
{
- return (val * 0xFF) / 0x7;
+ case N64Codec.RGBA16: return "rgba16";
+ case N64Codec.RGBA32: return "rgba32";
+ case N64Codec.IA16: return "ia16";
+ case N64Codec.IA8: return "ia8";
+ case N64Codec.IA4: return "ia4";
+ case N64Codec.I8: return "i8";
+ case N64Codec.I4: return "i4";
+ case N64Codec.CI8: return "ci8";
+ case N64Codec.CI4: return "ci4";
+ case N64Codec.ONEBPP: return "1bpp";
}
+ return "unk";
+ }
- private static byte SCALE_8_3(byte val)
+ public static N64Codec StringCodec(string str)
+ {
+ switch (str.ToLower())
{
- return (byte)(val / 0x24);
+ default:
+ case "rgba16": return N64Codec.RGBA16;
+ case "rgba32": return N64Codec.RGBA32;
+ case "ia16": return N64Codec.IA16;
+ case "ia8": return N64Codec.IA8;
+ case "ia4": return N64Codec.IA4;
+ case "i8": return N64Codec.I8;
+ case "i4": return N64Codec.I4;
+ case "ci8": return N64Codec.CI8;
+ case "ci4": return N64Codec.CI4;
+ case "1bpp": return N64Codec.ONEBPP;
}
+ }
- public static Color RGBA16Color(byte c0, byte c1)
+ public static Color MakeColor(byte[] data, byte[] palette, int offset, int select, N64Codec codec, N64IMode mode)
+ {
+ Color color;
+ switch (codec)
{
- int r = SCALE_5_8((c0 & 0xF8) >> 3);
- int g = SCALE_5_8(((c0 & 0x07) << 2) | ((c1 & 0xC0) >> 6));
- int b = SCALE_5_8((c1 & 0x3E) >> 1);
- int a = ((c1 & 0x1) > 0) ? 255 : 0;
- return Color.FromArgb(a, r, g, b);
+ case N64Codec.RGBA16:
+ color = RGBA16Color(data, offset);
+ break;
+ case N64Codec.RGBA32:
+ color = RGBA32Color(data, offset);
+ break;
+ case N64Codec.IA16:
+ color = IA16Color(data, offset);
+ break;
+ case N64Codec.IA8:
+ color = IA8Color(data, offset);
+ break;
+ case N64Codec.IA4:
+ color = IA4Color(data, offset, select);
+ break;
+ case N64Codec.I8:
+ color = I8Color(data, offset, mode);
+ break;
+ case N64Codec.I4:
+ color = I4Color(data, offset, select, mode);
+ break;
+ case N64Codec.CI8:
+ color = CI8Color(data, palette, offset);
+ break;
+ case N64Codec.CI4:
+ color = CI4Color(data, palette, offset, select);
+ break;
+ case N64Codec.ONEBPP:
+ color = BPPColor(data, offset, select);
+ break;
+ default:
+ color = RGBA16Color(data, offset);
+ break;
}
+ return color;
+ }
- public static void ColorRGBA16(Color col, out byte c0, out byte c1)
+ public static void RenderTexture(Graphics g, byte[] data, byte[] palette, int offset, int width, int height, int scale, N64Codec codec, N64IMode mode)
+ {
+ Brush brush;
+ for (int h = 0; h < height; h++)
{
- byte r, g, b;
- r = SCALE_8_5(col.R);
- g = SCALE_8_5(col.G);
- b = SCALE_8_5(col.B);
- c0 = (byte)((r << 3) | (g >> 2));
- c1 = (byte)(((g & 0x3) << 6) | (b << 1) | ((col.A > 0) ? 1 : 0));
- }
-
- public static Color RGBA16Color(byte[] data, int pixOffset)
- {
- byte c0 = data[pixOffset];
- byte c1 = data[pixOffset + 1];
-
- return RGBA16Color(c0, c1);
- }
-
- public static Color RGBA32Color(byte[] data, int pixOffset)
- {
- int r, g, b, a;
- r = data[pixOffset];
- g = data[pixOffset + 1];
- b = data[pixOffset + 2];
- a = data[pixOffset + 3];
- return Color.FromArgb(a, r, g, b);
- }
-
- public static Color IA16Color(byte[] data, int pixOffset)
- {
- int i = data[pixOffset];
- int a = data[pixOffset + 1];
- return Color.FromArgb(a, i, i, i);
- }
-
- public static Color IA8Color(byte[] data, int pixOffset)
- {
- int i, a;
- byte c = data[pixOffset];
- i = (c >> 4) * 0x11;
- a = (c & 0xF) * 0x11;
- return Color.FromArgb(a, i, i, i);
- }
-
- public static Color IA4Color(byte[] data, int pixOffset, int nibble)
- {
- int shift = (1 - nibble) * 4;
- int i, a;
- int val = (data[pixOffset] >> shift) & 0xF;
- i = SCALE_3_8((byte)(val >> 1));
- a = (val & 0x1) > 0 ? 0xFF : 0x00;
- return Color.FromArgb(a, i, i, i);
- }
-
- public static Color I8Color(byte[] data, int pixOffset, N64IMode mode = N64IMode.AlphaCopyIntensity)
- {
- int i = data[pixOffset];
- int a = i;
- switch (mode)
+ for (int w = 0; w < width; w++)
{
- case N64IMode.AlphaBinary: a = (i == 0) ? 0 : 0xFF; break;
- case N64IMode.AlphaCopyIntensity: a = i; break;
- case N64IMode.AlphaOne: a = 0xFF; break;
- }
- return Color.FromArgb(a, i, i, i);
- }
-
- public static Color I4Color(byte[] data, int pixOffset, int nibble, N64IMode mode = N64IMode.AlphaCopyIntensity)
- {
- int shift = (1 - nibble) * 4;
- int i = (data[pixOffset] >> shift) & 0xF;
- i *= 0x11;
- int a = i;
- switch (mode)
- {
- case N64IMode.AlphaBinary: a = (i == 0) ? 0 : 0xFF; break;
- case N64IMode.AlphaCopyIntensity: a = i; break;
- case N64IMode.AlphaOne: a = 0xFF; break;
- }
- return Color.FromArgb(a, i, i, i);
- }
-
- public static Color CI8Color(byte[] data, byte[] palette, int pixOffset)
- {
- byte c0, c1;
- int palOffset = 2 * data[pixOffset];
- c0 = palette[palOffset];
- c1 = palette[palOffset + 1];
-
- return RGBA16Color(c0, c1);
- }
-
- public static Color CI4Color(byte[] data, byte[] palette, int pixOffset, int nibble)
- {
- byte c0, c1;
- int shift = (1 - nibble) * 4;
- int palOffset = 2 * ((data[pixOffset] >> shift) & 0xF);
- c0 = palette[palOffset];
- c1 = palette[palOffset + 1];
-
- return RGBA16Color(c0, c1);
- }
-
- public static Color BPPColor(byte[] data, int pixOffset, int bit)
- {
- int i, a;
- int val = (data[pixOffset] >> (7 - bit)) & 0x1;
- i = a = val == 0 ? 0x00 : 0xFF;
- return Color.FromArgb(a, i, i, i);
- }
-
- // return number of bytes needed to encode numPixels using codec
- public static int PixelsToBytes(N64Codec codec, int numPixels)
- {
- int numBytes = 0;
- switch (codec)
- {
- case N64Codec.RGBA16: numBytes = numPixels * 2; break;
- case N64Codec.RGBA32: numBytes = numPixels * 4; break;
- case N64Codec.IA16: numBytes = numPixels * 2; break;
- case N64Codec.IA8: numBytes = numPixels; break;
- case N64Codec.IA4: numBytes = numPixels / 2; break;
- case N64Codec.I8: numBytes = numPixels; break;
- case N64Codec.I4: numBytes = numPixels / 2; break;
- case N64Codec.CI8: numBytes = numPixels; break;
- case N64Codec.CI4: numBytes = numPixels / 2; break;
- case N64Codec.ONEBPP: numBytes = numPixels / 8; break;
- }
- return numBytes;
- }
-
- public static string CodecString(N64Codec codec)
- {
- switch (codec)
- {
- case N64Codec.RGBA16: return "rgba16";
- case N64Codec.RGBA32: return "rgba32";
- case N64Codec.IA16: return "ia16";
- case N64Codec.IA8: return "ia8";
- case N64Codec.IA4: return "ia4";
- case N64Codec.I8: return "i8";
- case N64Codec.I4: return "i4";
- case N64Codec.CI8: return "ci8";
- case N64Codec.CI4: return "ci4";
- case N64Codec.ONEBPP: return "1bpp";
- }
- return "unk";
- }
-
- public static N64Codec StringCodec(string str)
- {
- switch (str.ToLower())
- {
- default:
- case "rgba16": return N64Codec.RGBA16;
- case "rgba32": return N64Codec.RGBA32;
- case "ia16": return N64Codec.IA16;
- case "ia8": return N64Codec.IA8;
- case "ia4": return N64Codec.IA4;
- case "i8": return N64Codec.I8;
- case "i4": return N64Codec.I4;
- case "ci8": return N64Codec.CI8;
- case "ci4": return N64Codec.CI4;
- case "1bpp": return N64Codec.ONEBPP;
- }
- }
-
- public static Color MakeColor(byte[] data, byte[] palette, int offset, int select, N64Codec codec, N64IMode mode)
- {
- Color color;
- switch (codec)
- {
- case N64Codec.RGBA16:
- color = RGBA16Color(data, offset);
- break;
- case N64Codec.RGBA32:
- color = RGBA32Color(data, offset);
- break;
- case N64Codec.IA16:
- color = IA16Color(data, offset);
- break;
- case N64Codec.IA8:
- color = IA8Color(data, offset);
- break;
- case N64Codec.IA4:
- color = IA4Color(data, offset, select);
- break;
- case N64Codec.I8:
- color = I8Color(data, offset, mode);
- break;
- case N64Codec.I4:
- color = I4Color(data, offset, select, mode);
- break;
- case N64Codec.CI8:
- color = CI8Color(data, palette, offset);
- break;
- case N64Codec.CI4:
- color = CI4Color(data, palette, offset, select);
- break;
- case N64Codec.ONEBPP:
- color = BPPColor(data, offset, select);
- break;
- default:
- color = RGBA16Color(data, offset);
- break;
- }
- return color;
- }
-
- public static void RenderTexture(Graphics g, byte[] data, byte[] palette, int offset, int width, int height, int scale, N64Codec codec, N64IMode mode)
- {
- Brush brush;
- for (int h = 0; h < height; h++)
- {
- for (int w = 0; w < width; w++)
+ int pixOffset = (h * width + w);
+ int bytesPerPix = 1;
+ int select = 0;
+ switch (codec)
{
- int pixOffset = (h * width + w);
- int bytesPerPix = 1;
- int select = 0;
- switch (codec)
- {
- case N64Codec.RGBA16: bytesPerPix = 2; pixOffset *= bytesPerPix; break;
- case N64Codec.RGBA32: bytesPerPix = 4; pixOffset *= bytesPerPix; break;
- case N64Codec.IA16: bytesPerPix = 2; pixOffset *= bytesPerPix; break;
- case N64Codec.IA8: break;
- case N64Codec.IA4:
- select = pixOffset & 0x1;
- pixOffset /= 2;
- break;
- case N64Codec.I8: break;
- case N64Codec.I4:
- case N64Codec.CI4:
- select = pixOffset & 0x1;
- pixOffset /= 2;
- break;
- case N64Codec.CI8: break;
- case N64Codec.ONEBPP:
- select = pixOffset & 0x7;
- pixOffset /= 8;
- break;
- }
- pixOffset += offset;
- if (data.Length > pixOffset + bytesPerPix - 1)
- {
- brush = new SolidBrush(MakeColor(data, palette, pixOffset, select, codec, mode));
- g.FillRectangle(brush, w * scale, h * scale, scale, scale);
- }
+ case N64Codec.RGBA16: bytesPerPix = 2; pixOffset *= bytesPerPix; break;
+ case N64Codec.RGBA32: bytesPerPix = 4; pixOffset *= bytesPerPix; break;
+ case N64Codec.IA16: bytesPerPix = 2; pixOffset *= bytesPerPix; break;
+ case N64Codec.IA8: break;
+ case N64Codec.IA4:
+ select = pixOffset & 0x1;
+ pixOffset /= 2;
+ break;
+ case N64Codec.I8: break;
+ case N64Codec.I4:
+ case N64Codec.CI4:
+ select = pixOffset & 0x1;
+ pixOffset /= 2;
+ break;
+ case N64Codec.CI8: break;
+ case N64Codec.ONEBPP:
+ select = pixOffset & 0x7;
+ pixOffset /= 8;
+ break;
}
- }
- }
-
- // return palette index of matching c0/c1 16-bit dataset, or -1 if not found
- private static int paletteIndex(byte[] pal, int palCount, byte c0, byte c1)
- {
- for (int i = 0; i < palCount; i++)
- {
- if (pal[2 * i] == c0 && pal[2 * i + 1] == c1)
+ pixOffset += offset;
+ if (data.Length > pixOffset + bytesPerPix - 1)
{
- return i;
+ brush = new SolidBrush(MakeColor(data, palette, pixOffset, select, codec, mode));
+ g.FillRectangle(brush, w * scale, h * scale, scale, scale);
}
}
- return -1;
- }
-
- public static void Convert(ref byte[] imageData, ref byte[] paletteData, N64Codec codec, Bitmap bm)
- {
- int numPixels = bm.Width * bm.Height;
- imageData = new byte[PixelsToBytes(codec, numPixels)];
- int palCount = 0;
- switch (codec)
- {
- case N64Codec.RGBA16:
- for (int y = 0; y < bm.Height; y++)
- {
- for (int x = 0; x < bm.Width; x++)
- {
- Color col = bm.GetPixel(x, y);
- byte c0;
- byte c1;
- ColorRGBA16(col, out c0, out c1);
- int idx = 2 * (y * bm.Width + x);
- imageData[idx + 0] = c0;
- imageData[idx + 1] = c1;
- }
- }
- break;
- case N64Codec.RGBA32:
- for (int y = 0; y < bm.Height; y++)
- {
- for (int x = 0; x < bm.Width; x++)
- {
- Color col = bm.GetPixel(x, y);
- int idx = 4 * (y * bm.Width + x);
- imageData[idx + 0] = col.R;
- imageData[idx + 1] = col.G;
- imageData[idx + 2] = col.B;
- imageData[idx + 3] = col.A;
- }
- }
- break;
- case N64Codec.IA16:
- for (int y = 0; y < bm.Height; y++)
- {
- for (int x = 0; x < bm.Width; x++)
- {
- Color col = bm.GetPixel(x, y);
- int sum = col.R + col.G + col.B;
- byte intensity = (byte)(sum / 3);
- byte alpha = col.A;
- int idx = 2 * (y * bm.Width + x);
- imageData[idx + 0] = intensity;
- imageData[idx + 1] = alpha;
- }
- }
- break;
- case N64Codec.IA8:
- for (int y = 0; y < bm.Height; y++)
- {
- for (int x = 0; x < bm.Width; x++)
- {
- Color col = bm.GetPixel(x, y);
- int sum = col.R + col.G + col.B;
- byte intensity = SCALE_8_4((byte)(sum / 3));
- byte alpha = SCALE_8_4(col.A);
- int idx = y * bm.Width + x;
- imageData[idx] = (byte)((intensity << 4) | alpha);
- }
- }
- break;
- case N64Codec.IA4:
- for (int y = 0; y < bm.Height; y++)
- {
- for (int x = 0; x < bm.Width; x++)
- {
- Color col = bm.GetPixel(x, y);
- int sum = col.R + col.G + col.B;
- byte intensity = SCALE_8_3((byte)(sum / 3));
- byte alpha = (byte)(col.A > 0 ? 1 : 0);
- int idx = y * bm.Width + x;
- byte old = imageData[idx / 2];
- if ((idx % 2) > 0)
- {
- imageData[idx / 2] = (byte)((old & 0xF0) | (intensity << 1) | alpha);
- }
- else
- {
- imageData[idx / 2] = (byte)((old & 0x0F) | (((intensity << 1) | alpha) << 4));
- }
- }
- }
- break;
- case N64Codec.I8:
- for (int y = 0; y < bm.Height; y++)
- {
- for (int x = 0; x < bm.Width; x++)
- {
- Color col = bm.GetPixel(x, y);
- int sum = col.R + col.G + col.B;
- byte intensity = (byte)(sum / 3);
- int idx = y * bm.Width + x;
- imageData[idx] = intensity;
- }
- }
- break;
- case N64Codec.I4:
- for (int y = 0; y < bm.Height; y++)
- {
- for (int x = 0; x < bm.Width; x++)
- {
- Color col = bm.GetPixel(x, y);
- int sum = col.R + col.G + col.B;
- byte intensity = SCALE_8_4((byte)(sum / 3));
- int idx = y * bm.Width + x;
- byte old = imageData[idx / 2];
- if ((idx % 2) > 0)
- {
- imageData[idx / 2] = (byte)((old & 0xF0) | intensity);
- }
- else
- {
- imageData[idx / 2] = (byte)((old & 0x0F) | (intensity << 4));
- }
- }
- }
- break;
- case N64Codec.CI4:
- paletteData = new byte[16 * 2];
- for (int y = 0; y < bm.Height; y++)
- {
- for (int x = 0; x < bm.Width; x++)
- {
- Color col = bm.GetPixel(x, y);
- byte r, g, b;
- r = SCALE_8_5(col.R);
- g = SCALE_8_5(col.G);
- b = SCALE_8_5(col.B);
- byte c0 = (byte)((r << 3) | (g >> 2));
- byte c1 = (byte)(((g & 0x3) << 6) | (b << 1) | ((col.A > 0) ? 1 : 0));
- int idx = y * bm.Width + x;
- int palIdx = paletteIndex(paletteData, palCount, c0, c1);
- if (palIdx < 0)
- {
- if (palCount < paletteData.Length / 2)
- {
- palIdx = palCount;
- paletteData[2 * palCount] = c0;
- paletteData[2 * palCount + 1] = c1;
- palCount++;
- }
- else
- {
- palIdx = 0;
- // TODO: out of palette entries. error or pick closest?
- }
- }
- byte old = imageData[idx / 2];
- if ((idx % 2) > 0)
- {
- imageData[idx / 2] = (byte)((old & 0xF0) | (byte)palIdx);
- }
- else
- {
- imageData[idx / 2] = (byte)((old & 0x0F) | ((byte)palIdx << 4));
- }
- }
- }
- break;
- case N64Codec.CI8:
- paletteData = new byte[256 * 2];
- for (int y = 0; y < bm.Height; y++)
- {
- for (int x = 0; x < bm.Width; x++)
- {
- Color col = bm.GetPixel(x, y);
- byte r, g, b;
- r = SCALE_8_5(col.R);
- g = SCALE_8_5(col.G);
- b = SCALE_8_5(col.B);
- byte c0 = (byte)((r << 3) | (g >> 2));
- byte c1 = (byte)(((g & 0x3) << 6) | (b << 1) | ((col.A > 0) ? 1 : 0));
- int idx = y * bm.Width + x;
- int palIdx = paletteIndex(paletteData, palCount, c0, c1);
- if (palIdx < 0)
- {
- if (palCount < paletteData.Length / 2)
- {
- palIdx = palCount;
- paletteData[2 * palCount] = c0;
- paletteData[2 * palCount + 1] = c1;
- palCount++;
- }
- else
- {
- palIdx = 0;
- // TODO: out of palette entries. error or pick closest?
- }
- }
- imageData[idx] = (byte)palIdx;
- }
- }
- break;
- case N64Codec.ONEBPP:
- for (int y = 0; y < bm.Height; y++)
- {
- for (int x = 0; x < bm.Width; x++)
- {
- Color col = bm.GetPixel(x, y);
- int sum = col.R + col.G + col.B;
- byte intensity = (sum > 0) ? (byte)1 : (byte)0;
- int idx = y * bm.Width + x;
- byte old = imageData[idx / 8];
- int bit = idx % 8;
- int mask = ~(1 << bit);
- imageData[idx / 8] = (byte)((old & mask) | (intensity << bit));
- }
- }
- break;
- }
+ }
+ }
+
+ // return palette index of matching c0/c1 16-bit dataset, or -1 if not found
+ private static int paletteIndex(byte[] pal, int palCount, byte c0, byte c1)
+ {
+ for (int i = 0; i < palCount; i++)
+ {
+ if (pal[2 * i] == c0 && pal[2 * i + 1] == c1)
+ {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public static void Convert(ref byte[] imageData, ref byte[] paletteData, N64Codec codec, Bitmap bm)
+ {
+ int numPixels = bm.Width * bm.Height;
+ imageData = new byte[PixelsToBytes(codec, numPixels)];
+ int palCount = 0;
+ switch (codec)
+ {
+ case N64Codec.RGBA16:
+ for (int y = 0; y < bm.Height; y++)
+ {
+ for (int x = 0; x < bm.Width; x++)
+ {
+ Color col = bm.GetPixel(x, y);
+ byte c0;
+ byte c1;
+ ColorRGBA16(col, out c0, out c1);
+ int idx = 2 * (y * bm.Width + x);
+ imageData[idx + 0] = c0;
+ imageData[idx + 1] = c1;
+ }
+ }
+ break;
+ case N64Codec.RGBA32:
+ for (int y = 0; y < bm.Height; y++)
+ {
+ for (int x = 0; x < bm.Width; x++)
+ {
+ Color col = bm.GetPixel(x, y);
+ int idx = 4 * (y * bm.Width + x);
+ imageData[idx + 0] = col.R;
+ imageData[idx + 1] = col.G;
+ imageData[idx + 2] = col.B;
+ imageData[idx + 3] = col.A;
+ }
+ }
+ break;
+ case N64Codec.IA16:
+ for (int y = 0; y < bm.Height; y++)
+ {
+ for (int x = 0; x < bm.Width; x++)
+ {
+ Color col = bm.GetPixel(x, y);
+ int sum = col.R + col.G + col.B;
+ byte intensity = (byte)(sum / 3);
+ byte alpha = col.A;
+ int idx = 2 * (y * bm.Width + x);
+ imageData[idx + 0] = intensity;
+ imageData[idx + 1] = alpha;
+ }
+ }
+ break;
+ case N64Codec.IA8:
+ for (int y = 0; y < bm.Height; y++)
+ {
+ for (int x = 0; x < bm.Width; x++)
+ {
+ Color col = bm.GetPixel(x, y);
+ int sum = col.R + col.G + col.B;
+ byte intensity = SCALE_8_4((byte)(sum / 3));
+ byte alpha = SCALE_8_4(col.A);
+ int idx = y * bm.Width + x;
+ imageData[idx] = (byte)((intensity << 4) | alpha);
+ }
+ }
+ break;
+ case N64Codec.IA4:
+ for (int y = 0; y < bm.Height; y++)
+ {
+ for (int x = 0; x < bm.Width; x++)
+ {
+ Color col = bm.GetPixel(x, y);
+ int sum = col.R + col.G + col.B;
+ byte intensity = SCALE_8_3((byte)(sum / 3));
+ byte alpha = (byte)(col.A > 0 ? 1 : 0);
+ int idx = y * bm.Width + x;
+ byte old = imageData[idx / 2];
+ if ((idx % 2) > 0)
+ {
+ imageData[idx / 2] = (byte)((old & 0xF0) | (intensity << 1) | alpha);
+ }
+ else
+ {
+ imageData[idx / 2] = (byte)((old & 0x0F) | (((intensity << 1) | alpha) << 4));
+ }
+ }
+ }
+ break;
+ case N64Codec.I8:
+ for (int y = 0; y < bm.Height; y++)
+ {
+ for (int x = 0; x < bm.Width; x++)
+ {
+ Color col = bm.GetPixel(x, y);
+ int sum = col.R + col.G + col.B;
+ byte intensity = (byte)(sum / 3);
+ int idx = y * bm.Width + x;
+ imageData[idx] = intensity;
+ }
+ }
+ break;
+ case N64Codec.I4:
+ for (int y = 0; y < bm.Height; y++)
+ {
+ for (int x = 0; x < bm.Width; x++)
+ {
+ Color col = bm.GetPixel(x, y);
+ int sum = col.R + col.G + col.B;
+ byte intensity = SCALE_8_4((byte)(sum / 3));
+ int idx = y * bm.Width + x;
+ byte old = imageData[idx / 2];
+ if ((idx % 2) > 0)
+ {
+ imageData[idx / 2] = (byte)((old & 0xF0) | intensity);
+ }
+ else
+ {
+ imageData[idx / 2] = (byte)((old & 0x0F) | (intensity << 4));
+ }
+ }
+ }
+ break;
+ case N64Codec.CI4:
+ paletteData = new byte[16 * 2];
+ for (int y = 0; y < bm.Height; y++)
+ {
+ for (int x = 0; x < bm.Width; x++)
+ {
+ Color col = bm.GetPixel(x, y);
+ byte r, g, b;
+ r = SCALE_8_5(col.R);
+ g = SCALE_8_5(col.G);
+ b = SCALE_8_5(col.B);
+ byte c0 = (byte)((r << 3) | (g >> 2));
+ byte c1 = (byte)(((g & 0x3) << 6) | (b << 1) | ((col.A > 0) ? 1 : 0));
+ int idx = y * bm.Width + x;
+ int palIdx = paletteIndex(paletteData, palCount, c0, c1);
+ if (palIdx < 0)
+ {
+ if (palCount < paletteData.Length / 2)
+ {
+ palIdx = palCount;
+ paletteData[2 * palCount] = c0;
+ paletteData[2 * palCount + 1] = c1;
+ palCount++;
+ }
+ else
+ {
+ palIdx = 0;
+ // TODO: out of palette entries. error or pick closest?
+ }
+ }
+ byte old = imageData[idx / 2];
+ if ((idx % 2) > 0)
+ {
+ imageData[idx / 2] = (byte)((old & 0xF0) | (byte)palIdx);
+ }
+ else
+ {
+ imageData[idx / 2] = (byte)((old & 0x0F) | ((byte)palIdx << 4));
+ }
+ }
+ }
+ break;
+ case N64Codec.CI8:
+ paletteData = new byte[256 * 2];
+ for (int y = 0; y < bm.Height; y++)
+ {
+ for (int x = 0; x < bm.Width; x++)
+ {
+ Color col = bm.GetPixel(x, y);
+ byte r, g, b;
+ r = SCALE_8_5(col.R);
+ g = SCALE_8_5(col.G);
+ b = SCALE_8_5(col.B);
+ byte c0 = (byte)((r << 3) | (g >> 2));
+ byte c1 = (byte)(((g & 0x3) << 6) | (b << 1) | ((col.A > 0) ? 1 : 0));
+ int idx = y * bm.Width + x;
+ int palIdx = paletteIndex(paletteData, palCount, c0, c1);
+ if (palIdx < 0)
+ {
+ if (palCount < paletteData.Length / 2)
+ {
+ palIdx = palCount;
+ paletteData[2 * palCount] = c0;
+ paletteData[2 * palCount + 1] = c1;
+ palCount++;
+ }
+ else
+ {
+ palIdx = 0;
+ // TODO: out of palette entries. error or pick closest?
+ }
+ }
+ imageData[idx] = (byte)palIdx;
+ }
+ }
+ break;
+ case N64Codec.ONEBPP:
+ for (int y = 0; y < bm.Height; y++)
+ {
+ for (int x = 0; x < bm.Width; x++)
+ {
+ Color col = bm.GetPixel(x, y);
+ int sum = col.R + col.G + col.B;
+ byte intensity = (sum > 0) ? (byte)1 : (byte)0;
+ int idx = y * bm.Width + x;
+ byte old = imageData[idx / 8];
+ int bit = idx % 8;
+ int mask = ~(1 << bit);
+ imageData[idx / 8] = (byte)((old & mask) | (intensity << bit));
+ }
+ }
+ break;
}
}
}
diff --git a/SM64Lib.N64Graphics/Properties/AssemblyInfo.cs b/SM64Lib.N64Graphics/Properties/AssemblyInfo.cs
index 8903d48..4796be6 100644
--- a/SM64Lib.N64Graphics/Properties/AssemblyInfo.cs
+++ b/SM64Lib.N64Graphics/Properties/AssemblyInfo.cs
@@ -1,6 +1,4 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
+using System.Runtime.InteropServices;
// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar
// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von
diff --git a/SM64Lib.N64Graphics/TextureFormat.cs b/SM64Lib.N64Graphics/TextureFormat.cs
index d067855..7e447fb 100644
--- a/SM64Lib.N64Graphics/TextureFormat.cs
+++ b/SM64Lib.N64Graphics/TextureFormat.cs
@@ -1,598 +1,593 @@
using System;
-using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
-using System.Linq;
using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
-namespace SM64Lib.N64Graphics
+namespace SM64Lib.N64Graphics;
+
+public class TextureFormats
{
- public class TextureFormats
+ public static Bitmap createColorTexture(Color color)
{
- public static Bitmap createColorTexture(Color color)
+ Bitmap tex = new Bitmap(1, 1);
+ Graphics.FromImage(tex).Clear(color);
+ return tex;
+ }
+
+ public static string ConvertFormatToString(byte formatColorType, byte formatByteSize)
+ {
+ string formatStr = "";
+ switch (formatColorType & 7)
{
- Bitmap tex = new Bitmap(1, 1);
- Graphics.FromImage(tex).Clear(color);
- return tex;
+ case 0: formatStr = "RGBA"; break;
+ case 1: formatStr = "YUV"; break;
+ case 2: formatStr = "CI"; break;
+ case 3: formatStr = "IA"; break;
+ case 4: formatStr = "I"; break;
+ default: formatStr = "UNKNOWN"; break;
}
-
- public static string ConvertFormatToString(byte formatColorType, byte formatByteSize)
+ switch (formatByteSize & 3)
{
- string formatStr = "";
- switch (formatColorType & 7)
- {
- case 0: formatStr = "RGBA"; break;
- case 1: formatStr = "YUV"; break;
- case 2: formatStr = "CI"; break;
- case 3: formatStr = "IA"; break;
- case 4: formatStr = "I"; break;
- default: formatStr = "UNKNOWN"; break;
- }
- switch (formatByteSize & 3)
- {
- case 0: formatStr += "4"; break;
- case 1: formatStr += "8"; break;
- case 2: formatStr += "16"; break;
- case 3: formatStr += "32"; break;
- }
- return formatStr;
+ case 0: formatStr += "4"; break;
+ case 1: formatStr += "8"; break;
+ case 2: formatStr += "16"; break;
+ case 3: formatStr += "32"; break;
}
+ return formatStr;
+ }
- public static byte ConvertStringToFormat(string str)
- {
- str = str.ToLower();
- if (str.Equals("rgba16"))
- return 0x10;
- else if (str.Equals("rgba32"))
- return 0x18;
- else if (str.Equals("ci4"))
- return 0x40;
- else if (str.Equals("ci8"))
- return 0x48;
- else if (str.Equals("ia4"))
- return 0x60;
- else if (str.Equals("ia8"))
- return 0x68;
- else if (str.Equals("ia16"))
- return 0x70;
- else if (str.Equals("i4"))
- return 0x80;
- else if (str.Equals("i8"))
- return 0x88;
- else if (str.Equals("1bpp")) // Not a real F3D format.
- return 0x00;
-
+ public static byte ConvertStringToFormat(string str)
+ {
+ str = str.ToLower();
+ if (str.Equals("rgba16"))
return 0x10;
- }
+ else if (str.Equals("rgba32"))
+ return 0x18;
+ else if (str.Equals("ci4"))
+ return 0x40;
+ else if (str.Equals("ci8"))
+ return 0x48;
+ else if (str.Equals("ia4"))
+ return 0x60;
+ else if (str.Equals("ia8"))
+ return 0x68;
+ else if (str.Equals("ia16"))
+ return 0x70;
+ else if (str.Equals("i4"))
+ return 0x80;
+ else if (str.Equals("i8"))
+ return 0x88;
+ else if (str.Equals("1bpp")) // Not a real F3D format.
+ return 0x00;
- public static int getNumberOfBitsForFormat(byte format)
+ return 0x10;
+ }
+
+ public static int getNumberOfBitsForFormat(byte format)
+ {
+ switch (format)
{
- switch (format)
- {
- case 0x00: // Note: "1 bit per pixel" is not a Fast3D format.
- return 1;
- case 0x40:
- case 0x60:
- case 0x80:
- return 4;
- case 0x48:
- case 0x68:
- case 0x88:
- return 8;
- case 0x10:
- case 0x70:
- case 0x90:
- default:
- return 16;
- case 0x18:
- return 32;
- }
- }
-
- public static byte[] encodeTexture(N64Codec format, Bitmap texture)
- {
- switch (format)
- {
- default:
- case N64Codec.ONEBPP: // Note: "1 bit per pixel" is not a Fast3D format.
- return encode1BPP(texture);
- case N64Codec.RGBA16:
- return encodeRGBA16(texture);
- case N64Codec.RGBA32:
- return encodeRGBA32(texture);
- case N64Codec.IA4:
- return encodeIA4(texture);
- case N64Codec.IA8:
- return encodeIA8(texture);
- case N64Codec.IA16:
- return encodeIA16(texture);
- case N64Codec.I4:
- return encodeI4(texture);
- case N64Codec.I8:
- return encodeI4(texture);
- case N64Codec.CI4:
- case N64Codec.CI8:
- throw new ArgumentException("CI texture encoding is not currently supported in this version.");
- }
- }
-
- public static byte getBit(int color, int bit)
- {
- return (byte)(((color >> 24) & 0xFF) > 0 ? (1 << bit) : 0);
- }
-
- public static byte[] encode1BPP(Bitmap texture)
- {
- int data_size = (texture.Width * texture.Height) / 8;
- byte[] data = new byte[data_size];
- for (int i = 0; i < data_size; i++)
- {
- int x = (i * 8) % texture.Width;
- int y = (i * 8) / texture.Width;
-
- data[i] = (byte)(
- getBit(texture.GetPixel(x + 0, y).ToArgb(), 7) |
- getBit(texture.GetPixel(x + 1, y).ToArgb(), 6) |
- getBit(texture.GetPixel(x + 2, y).ToArgb(), 5) |
- getBit(texture.GetPixel(x + 3, y).ToArgb(), 4) |
- getBit(texture.GetPixel(x + 4, y).ToArgb(), 3) |
- getBit(texture.GetPixel(x + 5, y).ToArgb(), 2) |
- getBit(texture.GetPixel(x + 6, y).ToArgb(), 1) |
- getBit(texture.GetPixel(x + 7, y).ToArgb(), 0)
- );
- }
- return data;
- }
-
- public static byte[] encodeRGBA16(Bitmap texture)
- {
- int data_size = (texture.Width * texture.Height) * 2;
- byte[] data = new byte[data_size];
- for (int i = 0; i < data_size / 2; i++)
- {
- int x = i % texture.Width;
- int y = i / texture.Width;
- Color pix = texture.GetPixel(x, y);
- byte red = (byte)((pix.R / 256.0f) * 32.0f);
- byte green = (byte)((pix.G / 256.0f) * 32.0f);
- byte blue = (byte)((pix.B / 256.0f) * 32.0f);
- byte alpha = (byte)(pix.A >= 128.0f ? 1 : 0);
-
- data[i * 2] = (byte)((red << 3) | (green >> 2));
- data[(i * 2) + 1] = (byte)(((green & 3) << 6) | (blue << 1) | alpha);
- }
- return data;
- }
-
- public static byte[] encodeRGBA32(Bitmap texture)
- {
- int data_size = (texture.Width * texture.Height) * 4;
- byte[] data = new byte[data_size];
- for (int i = 0; i < data_size / 4; i++)
- {
- int x = i % texture.Width;
- int y = i / texture.Width;
- Color pix = texture.GetPixel(x, y);
-
- data[(i * 4) + 0] = pix.R;
- data[(i * 4) + 1] = pix.G;
- data[(i * 4) + 2] = pix.B;
- data[(i * 4) + 3] = pix.A;
- }
- return data;
- }
-
- public static byte[] encodeIA4(Bitmap texture)
- {
- int data_size = (texture.Width * texture.Height) / 2;
- byte[] data = new byte[data_size];
- for (int i = 0; i < data_size; i++)
- {
- int x = (i * 2) % texture.Width;
- int y = (i * 2) / texture.Width;
-
- Color pix1 = texture.GetPixel(x, y);
- byte pix1_avg = (byte)((((pix1.R + pix1.G + pix1.B) / 3) / 255.0f) * 8.0f);
- byte upper = (byte)((pix1_avg << 1) | (pix1.A < 255 ? 0 : 1));
-
- Color pix2 = texture.GetPixel(x + 1, y);
- byte pix2_avg = (byte)((((pix2.R + pix2.G + pix2.B) / 3) / 255.0f) * 8.0f);
- byte lower = (byte)((pix2_avg << 1) | (pix2.A < 255 ? 0 : 1));
-
- data[i] = (byte)(((upper & 0xF) << 4) | (lower & 0xF));
- }
- return data;
- }
-
- public static byte[] encodeIA8(Bitmap texture)
- {
- int data_size = texture.Width * texture.Height;
- byte[] data = new byte[data_size];
- for (int i = 0; i < data_size; i++)
- {
- int x = i % texture.Width;
- int y = i / texture.Width;
-
- Color pix = texture.GetPixel(x, y);
- byte pix_avg = (byte)((((pix.R + pix.G + pix.B) / 3) / 255.0f) * 16.0f);
- byte pix_alpha = (byte)((pix.A / 255.0f) * 16.0f);
-
- data[i] = (byte)(((pix_avg & 0xF) << 4) | (pix_alpha & 0xF));
- }
- return data;
- }
-
- public static byte[] encodeIA16(Bitmap texture)
- {
- int data_size = texture.Width * texture.Height * 2;
- byte[] data = new byte[data_size];
- for (int i = 0; i < data_size / 2; i++)
- {
- int x = i % texture.Width;
- int y = i / texture.Width;
-
- Color pix = texture.GetPixel(x, y);
- byte pix_avg = (byte)((pix.R + pix.G + pix.B) / 3);
-
- data[i * 2] = pix_avg;
- data[(i * 2) + 1] = pix.A;
- }
- return data;
- }
-
- public static byte[] encodeI4(Bitmap texture)
- {
- int data_size = (texture.Width * texture.Height) / 2;
- byte[] data = new byte[data_size];
- for (int i = 0; i < data_size; i++)
- {
- int x = (i * 2) % texture.Width;
- int y = (i * 2) / texture.Width;
-
- Color pix1 = texture.GetPixel(x, y);
- byte upper = (byte)((((pix1.R + pix1.G + pix1.B) / 3) / 255.0f) * 16.0f);
-
- Color pix2 = texture.GetPixel(x + 1, y);
- byte lower = (byte)((((pix2.R + pix2.G + pix2.B) / 3) / 255.0f) * 16.0f);
-
- data[i] = (byte)(((upper & 0xF) << 4) | (lower & 0xF));
- }
- return data;
- }
-
-
- public static byte[] encodeI8(Bitmap texture)
- {
- int data_size = texture.Width * texture.Height;
- byte[] data = new byte[data_size];
- for (int i = 0; i < data_size; i++)
- {
- int x = i % texture.Width;
- int y = i / texture.Width;
-
- Color pix = texture.GetPixel(x, y);
-
- data[i] = (byte)((pix.R + pix.G + pix.B) / 3);
- }
- return data;
- }
-
- public static Bitmap decodeTexture(N64Codec format, byte[] data, int width, int height, ushort[] palette)
- {
- switch (format)
- {
- default:
- case N64Codec.ONEBPP: // Note: "1 bit per pixel" is not a Fast3D format.
- return decode1BPP(data, width, height);
- case N64Codec.RGBA16:
- return decodeRGBA16(data, width, height);
- case N64Codec.RGBA32:
- return decodeRGBA32(data, width, height);
- case N64Codec.CI4:
- return decodeCI4(data, width, height, palette);
- case N64Codec.CI8:
- return decodeCI8(data, width, height, palette);
- case N64Codec.IA4:
- return decodeIA4(data, width, height);
- case N64Codec.IA8:
- return decodeIA8(data, width, height);
- case N64Codec.IA16:
- return decodeIA16(data, width, height);
- case N64Codec.I4:
- return decodeI4(data, width, height);
- case N64Codec.I8:
- return decodeI8(data, width, height);
- }
- }
-
-
- public static Bitmap decode1BPP(byte[] data, int width, int height)
- {
- Bitmap tex = new Bitmap(width, height);
- if (data.Length >= (width * height) / 8) // Sanity Check
- {
- int len = (width * height) / 8;
- for (int i = 0; i < len; ++i)
- {
- for (int x = 0; x < 8; x++)
- {
- byte intensity = (byte)((data[i] >> (7 - x)) & 1);
- if (intensity > 0)
- intensity = 0xFF;
- int alpha = intensity;
- int pos = (i * 8) + x;
- tex.SetPixel(pos % width, pos / width, Color.FromArgb(alpha, intensity, intensity, intensity));
- }
- }
- }
- tex.Tag = new string[] { "Format: 1BPP", "Width: " + width,
- "Height: " + height };
- return tex;
- }
-
- public static Bitmap decodeRGBA32(byte[] data, int width, int height)
- {
- Console.WriteLine("Texture size = (" + width + "x" + height + ")");
- Console.WriteLine("data.Length = (" + data.Length + ")");
- Bitmap tex = new Bitmap(width, height);
-
- if (data.Length >= width * height * 4) // Sanity Check
- {
- BitmapData bitmapData = tex.LockBits(new Rectangle(0, 0, width, height),
- ImageLockMode.ReadWrite, tex.PixelFormat);
-
- int len = width * height;
- for (int i = 0; i < len; i++)
- {
- // Swap red and blue values
- byte temp_red = data[(i * 4) + 0];
- data[(i * 4) + 0] = data[(i * 4) + 2];
- data[(i * 4) + 2] = temp_red;
- }
- Marshal.Copy(data, 0, bitmapData.Scan0, data.Length);
- tex.UnlockBits(bitmapData);
-
- }
- tex.Tag = new string[] { "Format: RGBA32", "Width: " + width,
- "Height: " + height };
- return tex;
- }
-
- public static Bitmap decodeRGBA16(byte[] data, int width, int height)
- {
- Bitmap tex = new Bitmap(width, height);
- if (data.Length >= width * height * 2) // Sanity Check
- {
- BitmapData bitmapData = tex.LockBits(new Rectangle(0, 0, width, height),
- ImageLockMode.ReadWrite, tex.PixelFormat);
- byte[] pixels = new byte[width * height * 4];
-
- int len = width * height;
- for (int i = 0; i < len; i++)
- {
- ushort pixel = (ushort)((data[i * 2] << 8) | data[i * 2 + 1]);
- pixels[(i * 4) + 2] = (byte)(((pixel >> 11) & 0x1F) * 8); // Red
- pixels[(i * 4) + 1] = (byte)(((pixel >> 6) & 0x1F) * 8); // Green
- pixels[(i * 4) + 0] = (byte)(((pixel >> 1) & 0x1F) * 8); // Blue
- pixels[(i * 4) + 3] = (pixel & 1) > 0 ? (byte)0xFF : (byte)0x00; // (Transparency)
- }
- Marshal.Copy(pixels, 0, bitmapData.Scan0, pixels.Length);
- tex.UnlockBits(bitmapData);
- }
-
- tex.Tag = new string[] { "Format: RGBA16", "Width: " + width,
- "Height: " + height };
- return tex;
- }
-
- public static Bitmap decodeIA16(byte[] data, int width, int height)
- {
- Bitmap tex = new Bitmap(width, height);
- if (data.Length >= width * height * 2) // Sanity Check
- {
- BitmapData bitmapData = tex.LockBits(new Rectangle(0, 0, width, height),
- ImageLockMode.ReadWrite, tex.PixelFormat);
- byte[] pixels = new byte[width * height * 4];
-
- int len = width * height;
- for (int i = 0; i < len; i++)
- {
- pixels[(i * 4) + 2] = data[i * 2]; // Red
- pixels[(i * 4) + 1] = data[i * 2]; // Green
- pixels[(i * 4) + 0] = data[i * 2]; // Blue
- pixels[(i * 4) + 3] = data[(i * 2) + 1]; // Alpha
- }
- Marshal.Copy(pixels, 0, bitmapData.Scan0, pixels.Length);
- tex.UnlockBits(bitmapData);
- }
- tex.Tag = new string[] { "Format: IA16", "Width: " + width,
- "Height: " + height};
- return tex;
- }
-
- public static Bitmap decodeIA8(byte[] data, int width, int height)
- {
- Bitmap tex = new Bitmap(width, height);
- if (data.Length >= width * height) // Sanity Check
- {
- BitmapData bitmapData = tex.LockBits(new Rectangle(0, 0, width, height),
- ImageLockMode.ReadWrite, tex.PixelFormat);
- byte[] pixels = new byte[width * height * 4];
-
- int len = width * height;
- for (int i = 0; i < len; i++)
- {
- byte intensity = (byte)(((data[i] >> 4) & 0xF) * 16);
- pixels[(i * 4) + 2] = intensity; // Red
- pixels[(i * 4) + 1] = intensity; // Green
- pixels[(i * 4) + 0] = intensity; // Blue
- pixels[(i * 4) + 3] = (byte)((data[i] & 0xF) * 16); // Alpha
- }
- Marshal.Copy(pixels, 0, bitmapData.Scan0, pixels.Length);
- tex.UnlockBits(bitmapData);
- }
- tex.Tag = new string[] { "Format: IA8", "Width: " + width,
- "Height: " + height };
- return tex;
- }
- public static Bitmap decodeIA4(byte[] data, int width, int height)
- {
- Bitmap tex = new Bitmap(width, height);
-
- if (data.Length >= (width * height) / 2) // Sanity Check
- {
- BitmapData bitmapData = tex.LockBits(new Rectangle(0, 0, width, height),
- ImageLockMode.ReadWrite, tex.PixelFormat);
- byte[] pixels = new byte[width * height * 4];
-
- int len = (width * height) / 2;
- for (int i = 0; i < len; i++)
- {
- byte twoPixels = data[i];
-
- byte intensity = (byte)((twoPixels >> 5) * 32);
- pixels[(i * 8) + 2] = intensity; // Red
- pixels[(i * 8) + 1] = intensity; // Green
- pixels[(i * 8) + 0] = intensity; // Blue
- pixels[(i * 8) + 3] = (byte)(((twoPixels >> 4) & 0x1) * 255); // Alpha
-
- intensity = (byte)(((twoPixels >> 1) & 0x7) * 32);
- pixels[(i * 8) + 6] = intensity; // Red
- pixels[(i * 8) + 5] = intensity; // Green
- pixels[(i * 8) + 4] = intensity; // Blue
- pixels[(i * 8) + 7] = (byte)((twoPixels & 0x1) * 255); // Alpha
- }
- Marshal.Copy(pixels, 0, bitmapData.Scan0, pixels.Length);
- tex.UnlockBits(bitmapData);
- tex.Tag = new string[] { "Format: IA4", "Width: " + width,
- "Height: " + height };
- }
- return tex;
- }
- public static Bitmap decodeI8(byte[] data, int width, int height)
- {
- Bitmap tex = new Bitmap(width, height);
-
- if (data.Length >= width * height) // Sanity Check
- {
- BitmapData bitmapData = tex.LockBits(new Rectangle(0, 0, width, height),
- ImageLockMode.ReadWrite, tex.PixelFormat);
- byte[] pixels = new byte[width * height * 4];
-
- int len = width * height;
- for (int i = 0; i < len; i++)
- {
- byte intensity = data[i];
- pixels[(i * 4) + 2] = intensity; // Red
- pixels[(i * 4) + 1] = intensity; // Green
- pixels[(i * 4) + 0] = intensity; // Blue
- pixels[(i * 4) + 3] = 0xFF; // Alpha
- }
- Marshal.Copy(pixels, 0, bitmapData.Scan0, pixels.Length);
- tex.UnlockBits(bitmapData);
-
- tex.Tag = new string[] { "Format: I8", "Width: " + width,
- "Height: " + height };
- }
- return tex;
- }
- public static Bitmap decodeI4(byte[] data, int width, int height)
- {
- Bitmap tex = new Bitmap(width, height);
-
- if (data.Length >= (width * height) / 2) // Sanity Check
- {
- BitmapData bitmapData = tex.LockBits(new Rectangle(0, 0, width, height),
- ImageLockMode.ReadWrite, tex.PixelFormat);
- byte[] pixels = new byte[width * height * 4];
-
- int len = (width * height) / 2;
- for (int i = 0; i < len; i++)
- {
- byte twoPixels = data[i];
-
- byte intensity = (byte)((twoPixels >> 4) * 16);
- pixels[(i * 8) + 2] = intensity; // Red
- pixels[(i * 8) + 1] = intensity; // Green
- pixels[(i * 8) + 0] = intensity; // Blue
- pixels[(i * 8) + 3] = 0xFF; // Alpha
-
- intensity = (byte)((twoPixels & 0xF) * 16);
- pixels[(i * 8) + 6] = intensity; // Red
- pixels[(i * 8) + 5] = intensity; // Green
- pixels[(i * 8) + 4] = intensity; // Blue
- pixels[(i * 8) + 7] = 0xFF; // Alpha
- }
- Marshal.Copy(pixels, 0, bitmapData.Scan0, pixels.Length);
- tex.UnlockBits(bitmapData);
- }
- tex.Tag = new string[] { "Format: I4", "Width: " + width,
- "Height: " + height };
- return tex;
- }
-
- public static Bitmap decodeCI4(byte[] data, int width, int height, ushort[] palette)
- {
- Bitmap tex = new Bitmap(width, height);
-
- if (data.Length >= (width * height) / 2) // Sanity Check
- {
- BitmapData bitmapData = tex.LockBits(new Rectangle(0, 0, width, height),
- ImageLockMode.ReadWrite, tex.PixelFormat);
- byte[] pixels = new byte[width * height * 4];
-
- int len = (width * height) / 2;
- for (int i = 0; i < len; i++)
- {
- ushort pixel = palette[(data[i] >> 4) & 0xF];
- pixels[(i * 8) + 2] = (byte)(((pixel >> 11) & 0x1F) * 8); // Red
- pixels[(i * 8) + 1] = (byte)(((pixel >> 6) & 0x1F) * 8); // Green
- pixels[(i * 8) + 0] = (byte)(((pixel >> 1) & 0x1F) * 8); // Blue
- pixels[(i * 8) + 3] = (pixel & 1) > 0 ? (byte)0xFF : (byte)0x00; // Alpha
-
- pixel = palette[(data[i]) & 0xF];
- pixels[(i * 8) + 6] = (byte)(((pixel >> 11) & 0x1F) * 8); // Red
- pixels[(i * 8) + 5] = (byte)(((pixel >> 6) & 0x1F) * 8); // Green
- pixels[(i * 8) + 4] = (byte)(((pixel >> 1) & 0x1F) * 8); // Blue
- pixels[(i * 8) + 7] = (pixel & 1) > 0 ? (byte)0xFF : (byte)0x00; // Alpha
-
- }
- Marshal.Copy(pixels, 0, bitmapData.Scan0, pixels.Length);
- tex.UnlockBits(bitmapData);
- }
- tex.Tag = new string[] { "Format: CI4", "Width: " + width,
- "Height: " + height };
- return tex;
- }
-
- public static Bitmap decodeCI8(byte[] data, int width, int height, ushort[] palette)
- {
- Bitmap tex = new Bitmap(width, height);
-
- if (data.Length >= width * height) // Sanity Check
- {
- BitmapData bitmapData = tex.LockBits(new Rectangle(0, 0, width, height),
- ImageLockMode.ReadWrite, tex.PixelFormat);
- byte[] pixels = new byte[width * height * 4];
-
- int len = width * height;
- for (int i = 0; i < len; i++)
- {
- ushort pixel = palette[data[i]];
- pixels[(i * 4) + 2] = (byte)(((pixel >> 11) & 0x1F) * 8); // Red
- pixels[(i * 4) + 1] = (byte)(((pixel >> 6) & 0x1F) * 8); // Green
- pixels[(i * 4) + 0] = (byte)(((pixel >> 1) & 0x1F) * 8); // Blue
- pixels[(i * 4) + 3] = (pixel & 1) > 0 ? (byte)0xFF : (byte)0x00; // (Transparency)
- //tex.SetPixel(i % width, i / width, Color.FromArgb(alpha, red, green, blue));
- }
- Marshal.Copy(pixels, 0, bitmapData.Scan0, pixels.Length);
- tex.UnlockBits(bitmapData);
- }
- tex.Tag = new string[] { "Format: CI8", "Width: " + width,
- "Height: " + height };
- return tex;
+ case 0x00: // Note: "1 bit per pixel" is not a Fast3D format.
+ return 1;
+ case 0x40:
+ case 0x60:
+ case 0x80:
+ return 4;
+ case 0x48:
+ case 0x68:
+ case 0x88:
+ return 8;
+ case 0x10:
+ case 0x70:
+ case 0x90:
+ default:
+ return 16;
+ case 0x18:
+ return 32;
}
}
+
+ public static byte[] encodeTexture(N64Codec format, Bitmap texture)
+ {
+ switch (format)
+ {
+ default:
+ case N64Codec.ONEBPP: // Note: "1 bit per pixel" is not a Fast3D format.
+ return encode1BPP(texture);
+ case N64Codec.RGBA16:
+ return encodeRGBA16(texture);
+ case N64Codec.RGBA32:
+ return encodeRGBA32(texture);
+ case N64Codec.IA4:
+ return encodeIA4(texture);
+ case N64Codec.IA8:
+ return encodeIA8(texture);
+ case N64Codec.IA16:
+ return encodeIA16(texture);
+ case N64Codec.I4:
+ return encodeI4(texture);
+ case N64Codec.I8:
+ return encodeI4(texture);
+ case N64Codec.CI4:
+ case N64Codec.CI8:
+ throw new ArgumentException("CI texture encoding is not currently supported in this version.");
+ }
+ }
+
+ public static byte getBit(int color, int bit)
+ {
+ return (byte)(((color >> 24) & 0xFF) > 0 ? (1 << bit) : 0);
+ }
+
+ public static byte[] encode1BPP(Bitmap texture)
+ {
+ int data_size = (texture.Width * texture.Height) / 8;
+ byte[] data = new byte[data_size];
+ for (int i = 0; i < data_size; i++)
+ {
+ int x = (i * 8) % texture.Width;
+ int y = (i * 8) / texture.Width;
+
+ data[i] = (byte)(
+ getBit(texture.GetPixel(x + 0, y).ToArgb(), 7) |
+ getBit(texture.GetPixel(x + 1, y).ToArgb(), 6) |
+ getBit(texture.GetPixel(x + 2, y).ToArgb(), 5) |
+ getBit(texture.GetPixel(x + 3, y).ToArgb(), 4) |
+ getBit(texture.GetPixel(x + 4, y).ToArgb(), 3) |
+ getBit(texture.GetPixel(x + 5, y).ToArgb(), 2) |
+ getBit(texture.GetPixel(x + 6, y).ToArgb(), 1) |
+ getBit(texture.GetPixel(x + 7, y).ToArgb(), 0)
+ );
+ }
+ return data;
+ }
+
+ public static byte[] encodeRGBA16(Bitmap texture)
+ {
+ int data_size = (texture.Width * texture.Height) * 2;
+ byte[] data = new byte[data_size];
+ for (int i = 0; i < data_size / 2; i++)
+ {
+ int x = i % texture.Width;
+ int y = i / texture.Width;
+ Color pix = texture.GetPixel(x, y);
+ byte red = (byte)((pix.R / 256.0f) * 32.0f);
+ byte green = (byte)((pix.G / 256.0f) * 32.0f);
+ byte blue = (byte)((pix.B / 256.0f) * 32.0f);
+ byte alpha = (byte)(pix.A >= 128.0f ? 1 : 0);
+
+ data[i * 2] = (byte)((red << 3) | (green >> 2));
+ data[(i * 2) + 1] = (byte)(((green & 3) << 6) | (blue << 1) | alpha);
+ }
+ return data;
+ }
+
+ public static byte[] encodeRGBA32(Bitmap texture)
+ {
+ int data_size = (texture.Width * texture.Height) * 4;
+ byte[] data = new byte[data_size];
+ for (int i = 0; i < data_size / 4; i++)
+ {
+ int x = i % texture.Width;
+ int y = i / texture.Width;
+ Color pix = texture.GetPixel(x, y);
+
+ data[(i * 4) + 0] = pix.R;
+ data[(i * 4) + 1] = pix.G;
+ data[(i * 4) + 2] = pix.B;
+ data[(i * 4) + 3] = pix.A;
+ }
+ return data;
+ }
+
+ public static byte[] encodeIA4(Bitmap texture)
+ {
+ int data_size = (texture.Width * texture.Height) / 2;
+ byte[] data = new byte[data_size];
+ for (int i = 0; i < data_size; i++)
+ {
+ int x = (i * 2) % texture.Width;
+ int y = (i * 2) / texture.Width;
+
+ Color pix1 = texture.GetPixel(x, y);
+ byte pix1_avg = (byte)((((pix1.R + pix1.G + pix1.B) / 3) / 255.0f) * 8.0f);
+ byte upper = (byte)((pix1_avg << 1) | (pix1.A < 255 ? 0 : 1));
+
+ Color pix2 = texture.GetPixel(x + 1, y);
+ byte pix2_avg = (byte)((((pix2.R + pix2.G + pix2.B) / 3) / 255.0f) * 8.0f);
+ byte lower = (byte)((pix2_avg << 1) | (pix2.A < 255 ? 0 : 1));
+
+ data[i] = (byte)(((upper & 0xF) << 4) | (lower & 0xF));
+ }
+ return data;
+ }
+
+ public static byte[] encodeIA8(Bitmap texture)
+ {
+ int data_size = texture.Width * texture.Height;
+ byte[] data = new byte[data_size];
+ for (int i = 0; i < data_size; i++)
+ {
+ int x = i % texture.Width;
+ int y = i / texture.Width;
+
+ Color pix = texture.GetPixel(x, y);
+ byte pix_avg = (byte)((((pix.R + pix.G + pix.B) / 3) / 255.0f) * 16.0f);
+ byte pix_alpha = (byte)((pix.A / 255.0f) * 16.0f);
+
+ data[i] = (byte)(((pix_avg & 0xF) << 4) | (pix_alpha & 0xF));
+ }
+ return data;
+ }
+
+ public static byte[] encodeIA16(Bitmap texture)
+ {
+ int data_size = texture.Width * texture.Height * 2;
+ byte[] data = new byte[data_size];
+ for (int i = 0; i < data_size / 2; i++)
+ {
+ int x = i % texture.Width;
+ int y = i / texture.Width;
+
+ Color pix = texture.GetPixel(x, y);
+ byte pix_avg = (byte)((pix.R + pix.G + pix.B) / 3);
+
+ data[i * 2] = pix_avg;
+ data[(i * 2) + 1] = pix.A;
+ }
+ return data;
+ }
+
+ public static byte[] encodeI4(Bitmap texture)
+ {
+ int data_size = (texture.Width * texture.Height) / 2;
+ byte[] data = new byte[data_size];
+ for (int i = 0; i < data_size; i++)
+ {
+ int x = (i * 2) % texture.Width;
+ int y = (i * 2) / texture.Width;
+
+ Color pix1 = texture.GetPixel(x, y);
+ byte upper = (byte)((((pix1.R + pix1.G + pix1.B) / 3) / 255.0f) * 16.0f);
+
+ Color pix2 = texture.GetPixel(x + 1, y);
+ byte lower = (byte)((((pix2.R + pix2.G + pix2.B) / 3) / 255.0f) * 16.0f);
+
+ data[i] = (byte)(((upper & 0xF) << 4) | (lower & 0xF));
+ }
+ return data;
+ }
+
+
+ public static byte[] encodeI8(Bitmap texture)
+ {
+ int data_size = texture.Width * texture.Height;
+ byte[] data = new byte[data_size];
+ for (int i = 0; i < data_size; i++)
+ {
+ int x = i % texture.Width;
+ int y = i / texture.Width;
+
+ Color pix = texture.GetPixel(x, y);
+
+ data[i] = (byte)((pix.R + pix.G + pix.B) / 3);
+ }
+ return data;
+ }
+
+ public static Bitmap decodeTexture(N64Codec format, byte[] data, int width, int height, ushort[] palette)
+ {
+ switch (format)
+ {
+ default:
+ case N64Codec.ONEBPP: // Note: "1 bit per pixel" is not a Fast3D format.
+ return decode1BPP(data, width, height);
+ case N64Codec.RGBA16:
+ return decodeRGBA16(data, width, height);
+ case N64Codec.RGBA32:
+ return decodeRGBA32(data, width, height);
+ case N64Codec.CI4:
+ return decodeCI4(data, width, height, palette);
+ case N64Codec.CI8:
+ return decodeCI8(data, width, height, palette);
+ case N64Codec.IA4:
+ return decodeIA4(data, width, height);
+ case N64Codec.IA8:
+ return decodeIA8(data, width, height);
+ case N64Codec.IA16:
+ return decodeIA16(data, width, height);
+ case N64Codec.I4:
+ return decodeI4(data, width, height);
+ case N64Codec.I8:
+ return decodeI8(data, width, height);
+ }
+ }
+
+
+ public static Bitmap decode1BPP(byte[] data, int width, int height)
+ {
+ Bitmap tex = new Bitmap(width, height);
+ if (data.Length >= (width * height) / 8) // Sanity Check
+ {
+ int len = (width * height) / 8;
+ for (int i = 0; i < len; ++i)
+ {
+ for (int x = 0; x < 8; x++)
+ {
+ byte intensity = (byte)((data[i] >> (7 - x)) & 1);
+ if (intensity > 0)
+ intensity = 0xFF;
+ int alpha = intensity;
+ int pos = (i * 8) + x;
+ tex.SetPixel(pos % width, pos / width, Color.FromArgb(alpha, intensity, intensity, intensity));
+ }
+ }
+ }
+ tex.Tag = new string[] { "Format: 1BPP", "Width: " + width,
+ "Height: " + height };
+ return tex;
+ }
+
+ public static Bitmap decodeRGBA32(byte[] data, int width, int height)
+ {
+ Console.WriteLine("Texture size = (" + width + "x" + height + ")");
+ Console.WriteLine("data.Length = (" + data.Length + ")");
+ Bitmap tex = new Bitmap(width, height);
+
+ if (data.Length >= width * height * 4) // Sanity Check
+ {
+ BitmapData bitmapData = tex.LockBits(new Rectangle(0, 0, width, height),
+ ImageLockMode.ReadWrite, tex.PixelFormat);
+
+ int len = width * height;
+ for (int i = 0; i < len; i++)
+ {
+ // Swap red and blue values
+ byte temp_red = data[(i * 4) + 0];
+ data[(i * 4) + 0] = data[(i * 4) + 2];
+ data[(i * 4) + 2] = temp_red;
+ }
+ Marshal.Copy(data, 0, bitmapData.Scan0, data.Length);
+ tex.UnlockBits(bitmapData);
+
+ }
+ tex.Tag = new string[] { "Format: RGBA32", "Width: " + width,
+ "Height: " + height };
+ return tex;
+ }
+
+ public static Bitmap decodeRGBA16(byte[] data, int width, int height)
+ {
+ Bitmap tex = new Bitmap(width, height);
+ if (data.Length >= width * height * 2) // Sanity Check
+ {
+ BitmapData bitmapData = tex.LockBits(new Rectangle(0, 0, width, height),
+ ImageLockMode.ReadWrite, tex.PixelFormat);
+ byte[] pixels = new byte[width * height * 4];
+
+ int len = width * height;
+ for (int i = 0; i < len; i++)
+ {
+ ushort pixel = (ushort)((data[i * 2] << 8) | data[i * 2 + 1]);
+ pixels[(i * 4) + 2] = (byte)(((pixel >> 11) & 0x1F) * 8); // Red
+ pixels[(i * 4) + 1] = (byte)(((pixel >> 6) & 0x1F) * 8); // Green
+ pixels[(i * 4) + 0] = (byte)(((pixel >> 1) & 0x1F) * 8); // Blue
+ pixels[(i * 4) + 3] = (pixel & 1) > 0 ? (byte)0xFF : (byte)0x00; // (Transparency)
+ }
+ Marshal.Copy(pixels, 0, bitmapData.Scan0, pixels.Length);
+ tex.UnlockBits(bitmapData);
+ }
+
+ tex.Tag = new string[] { "Format: RGBA16", "Width: " + width,
+ "Height: " + height };
+ return tex;
+ }
+
+ public static Bitmap decodeIA16(byte[] data, int width, int height)
+ {
+ Bitmap tex = new Bitmap(width, height);
+ if (data.Length >= width * height * 2) // Sanity Check
+ {
+ BitmapData bitmapData = tex.LockBits(new Rectangle(0, 0, width, height),
+ ImageLockMode.ReadWrite, tex.PixelFormat);
+ byte[] pixels = new byte[width * height * 4];
+
+ int len = width * height;
+ for (int i = 0; i < len; i++)
+ {
+ pixels[(i * 4) + 2] = data[i * 2]; // Red
+ pixels[(i * 4) + 1] = data[i * 2]; // Green
+ pixels[(i * 4) + 0] = data[i * 2]; // Blue
+ pixels[(i * 4) + 3] = data[(i * 2) + 1]; // Alpha
+ }
+ Marshal.Copy(pixels, 0, bitmapData.Scan0, pixels.Length);
+ tex.UnlockBits(bitmapData);
+ }
+ tex.Tag = new string[] { "Format: IA16", "Width: " + width,
+ "Height: " + height};
+ return tex;
+ }
+
+ public static Bitmap decodeIA8(byte[] data, int width, int height)
+ {
+ Bitmap tex = new Bitmap(width, height);
+ if (data.Length >= width * height) // Sanity Check
+ {
+ BitmapData bitmapData = tex.LockBits(new Rectangle(0, 0, width, height),
+ ImageLockMode.ReadWrite, tex.PixelFormat);
+ byte[] pixels = new byte[width * height * 4];
+
+ int len = width * height;
+ for (int i = 0; i < len; i++)
+ {
+ byte intensity = (byte)(((data[i] >> 4) & 0xF) * 16);
+ pixels[(i * 4) + 2] = intensity; // Red
+ pixels[(i * 4) + 1] = intensity; // Green
+ pixels[(i * 4) + 0] = intensity; // Blue
+ pixels[(i * 4) + 3] = (byte)((data[i] & 0xF) * 16); // Alpha
+ }
+ Marshal.Copy(pixels, 0, bitmapData.Scan0, pixels.Length);
+ tex.UnlockBits(bitmapData);
+ }
+ tex.Tag = new string[] { "Format: IA8", "Width: " + width,
+ "Height: " + height };
+ return tex;
+ }
+ public static Bitmap decodeIA4(byte[] data, int width, int height)
+ {
+ Bitmap tex = new Bitmap(width, height);
+
+ if (data.Length >= (width * height) / 2) // Sanity Check
+ {
+ BitmapData bitmapData = tex.LockBits(new Rectangle(0, 0, width, height),
+ ImageLockMode.ReadWrite, tex.PixelFormat);
+ byte[] pixels = new byte[width * height * 4];
+
+ int len = (width * height) / 2;
+ for (int i = 0; i < len; i++)
+ {
+ byte twoPixels = data[i];
+
+ byte intensity = (byte)((twoPixels >> 5) * 32);
+ pixels[(i * 8) + 2] = intensity; // Red
+ pixels[(i * 8) + 1] = intensity; // Green
+ pixels[(i * 8) + 0] = intensity; // Blue
+ pixels[(i * 8) + 3] = (byte)(((twoPixels >> 4) & 0x1) * 255); // Alpha
+
+ intensity = (byte)(((twoPixels >> 1) & 0x7) * 32);
+ pixels[(i * 8) + 6] = intensity; // Red
+ pixels[(i * 8) + 5] = intensity; // Green
+ pixels[(i * 8) + 4] = intensity; // Blue
+ pixels[(i * 8) + 7] = (byte)((twoPixels & 0x1) * 255); // Alpha
+ }
+ Marshal.Copy(pixels, 0, bitmapData.Scan0, pixels.Length);
+ tex.UnlockBits(bitmapData);
+ tex.Tag = new string[] { "Format: IA4", "Width: " + width,
+ "Height: " + height };
+ }
+ return tex;
+ }
+ public static Bitmap decodeI8(byte[] data, int width, int height)
+ {
+ Bitmap tex = new Bitmap(width, height);
+
+ if (data.Length >= width * height) // Sanity Check
+ {
+ BitmapData bitmapData = tex.LockBits(new Rectangle(0, 0, width, height),
+ ImageLockMode.ReadWrite, tex.PixelFormat);
+ byte[] pixels = new byte[width * height * 4];
+
+ int len = width * height;
+ for (int i = 0; i < len; i++)
+ {
+ byte intensity = data[i];
+ pixels[(i * 4) + 2] = intensity; // Red
+ pixels[(i * 4) + 1] = intensity; // Green
+ pixels[(i * 4) + 0] = intensity; // Blue
+ pixels[(i * 4) + 3] = 0xFF; // Alpha
+ }
+ Marshal.Copy(pixels, 0, bitmapData.Scan0, pixels.Length);
+ tex.UnlockBits(bitmapData);
+
+ tex.Tag = new string[] { "Format: I8", "Width: " + width,
+ "Height: " + height };
+ }
+ return tex;
+ }
+ public static Bitmap decodeI4(byte[] data, int width, int height)
+ {
+ Bitmap tex = new Bitmap(width, height);
+
+ if (data.Length >= (width * height) / 2) // Sanity Check
+ {
+ BitmapData bitmapData = tex.LockBits(new Rectangle(0, 0, width, height),
+ ImageLockMode.ReadWrite, tex.PixelFormat);
+ byte[] pixels = new byte[width * height * 4];
+
+ int len = (width * height) / 2;
+ for (int i = 0; i < len; i++)
+ {
+ byte twoPixels = data[i];
+
+ byte intensity = (byte)((twoPixels >> 4) * 16);
+ pixels[(i * 8) + 2] = intensity; // Red
+ pixels[(i * 8) + 1] = intensity; // Green
+ pixels[(i * 8) + 0] = intensity; // Blue
+ pixels[(i * 8) + 3] = 0xFF; // Alpha
+
+ intensity = (byte)((twoPixels & 0xF) * 16);
+ pixels[(i * 8) + 6] = intensity; // Red
+ pixels[(i * 8) + 5] = intensity; // Green
+ pixels[(i * 8) + 4] = intensity; // Blue
+ pixels[(i * 8) + 7] = 0xFF; // Alpha
+ }
+ Marshal.Copy(pixels, 0, bitmapData.Scan0, pixels.Length);
+ tex.UnlockBits(bitmapData);
+ }
+ tex.Tag = new string[] { "Format: I4", "Width: " + width,
+ "Height: " + height };
+ return tex;
+ }
+
+ public static Bitmap decodeCI4(byte[] data, int width, int height, ushort[] palette)
+ {
+ Bitmap tex = new Bitmap(width, height);
+
+ if (data.Length >= (width * height) / 2) // Sanity Check
+ {
+ BitmapData bitmapData = tex.LockBits(new Rectangle(0, 0, width, height),
+ ImageLockMode.ReadWrite, tex.PixelFormat);
+ byte[] pixels = new byte[width * height * 4];
+
+ int len = (width * height) / 2;
+ for (int i = 0; i < len; i++)
+ {
+ ushort pixel = palette[(data[i] >> 4) & 0xF];
+ pixels[(i * 8) + 2] = (byte)(((pixel >> 11) & 0x1F) * 8); // Red
+ pixels[(i * 8) + 1] = (byte)(((pixel >> 6) & 0x1F) * 8); // Green
+ pixels[(i * 8) + 0] = (byte)(((pixel >> 1) & 0x1F) * 8); // Blue
+ pixels[(i * 8) + 3] = (pixel & 1) > 0 ? (byte)0xFF : (byte)0x00; // Alpha
+
+ pixel = palette[(data[i]) & 0xF];
+ pixels[(i * 8) + 6] = (byte)(((pixel >> 11) & 0x1F) * 8); // Red
+ pixels[(i * 8) + 5] = (byte)(((pixel >> 6) & 0x1F) * 8); // Green
+ pixels[(i * 8) + 4] = (byte)(((pixel >> 1) & 0x1F) * 8); // Blue
+ pixels[(i * 8) + 7] = (pixel & 1) > 0 ? (byte)0xFF : (byte)0x00; // Alpha
+
+ }
+ Marshal.Copy(pixels, 0, bitmapData.Scan0, pixels.Length);
+ tex.UnlockBits(bitmapData);
+ }
+ tex.Tag = new string[] { "Format: CI4", "Width: " + width,
+ "Height: " + height };
+ return tex;
+ }
+
+ public static Bitmap decodeCI8(byte[] data, int width, int height, ushort[] palette)
+ {
+ Bitmap tex = new Bitmap(width, height);
+
+ if (data.Length >= width * height) // Sanity Check
+ {
+ BitmapData bitmapData = tex.LockBits(new Rectangle(0, 0, width, height),
+ ImageLockMode.ReadWrite, tex.PixelFormat);
+ byte[] pixels = new byte[width * height * 4];
+
+ int len = width * height;
+ for (int i = 0; i < len; i++)
+ {
+ ushort pixel = palette[data[i]];
+ pixels[(i * 4) + 2] = (byte)(((pixel >> 11) & 0x1F) * 8); // Red
+ pixels[(i * 4) + 1] = (byte)(((pixel >> 6) & 0x1F) * 8); // Green
+ pixels[(i * 4) + 0] = (byte)(((pixel >> 1) & 0x1F) * 8); // Blue
+ pixels[(i * 4) + 3] = (pixel & 1) > 0 ? (byte)0xFF : (byte)0x00; // (Transparency)
+ //tex.SetPixel(i % width, i / width, Color.FromArgb(alpha, red, green, blue));
+ }
+ Marshal.Copy(pixels, 0, bitmapData.Scan0, pixels.Length);
+ tex.UnlockBits(bitmapData);
+ }
+ tex.Tag = new string[] { "Format: CI8", "Width: " + width,
+ "Height: " + height };
+ return tex;
+ }
}
diff --git a/SM64Lib.Text.Exporters/ExcelExporter.cs b/SM64Lib.Text.Exporters/ExcelExporter.cs
index bd71057..935b53f 100644
--- a/SM64Lib.Text.Exporters/ExcelExporter.cs
+++ b/SM64Lib.Text.Exporters/ExcelExporter.cs
@@ -1,102 +1,98 @@
using OfficeOpenXml;
using System;
-using System.Collections.Generic;
using System.IO;
-using System.Linq;
-using System.Text;
using System.Threading.Tasks;
-namespace SM64Lib.Text.Exporters
+namespace SM64Lib.Text.Exporters;
+
+public class ExcelExporter
{
- public class ExcelExporter
+ public ExcelExporter()
{
- public ExcelExporter()
+ ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
+ }
+
+ public async Task Export(string destFilePath, TextGroup[] groups)
+ {
+ var pkg = new ExcelPackage();
+
+ foreach (var tg in groups)
{
- ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
+ var ws = pkg.Workbook.Worksheets.Add(tg.TextGroupInfo.Name);
+ var hasDialogCells = false;
+
+ ws.Cells.Style.VerticalAlignment = OfficeOpenXml.Style.ExcelVerticalAlignment.Top;
+ ws.Cells.Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Left;
+ ws.Row(1).Style.Font.Bold = true;
+ ws.Cells[1, 1].Value = "#";
+ ws.Cells[1, 2].Value = "Text";
+
+ for (int i = 0; i < tg.Count; i++)
+ {
+ var ti = tg[i];
+ var ri = i + 2;
+
+ ws.Cells[ri, 1].Value = i;
+ ws.Cells[ri, 2].Value = ti.Text;
+
+ if (ti is TextTableDialogItem)
+ hasDialogCells = true;
+ }
+
+
+ for (int ri = 1; ri <= ws.Cells.Rows; ri++)
+ {
+ var r = ws.Row(ri);
+ r.CustomHeight = false;
+ }
+
+ if (hasDialogCells)
+ {
+ var c = ws.Column(2);
+ c.Style.WrapText = true;
+ c.Width = 30;
+ }
+
+ for (int ci = 1; ci <= 2; ci++)
+ {
+ var c = ws.Column(ci);
+ if (!c.Style.WrapText)
+ c.AutoFit();
+ }
}
- public async Task Export(string destFilePath, TextGroup[] groups)
+ await pkg.SaveAsAsync(new FileInfo(destFilePath));
+ pkg.Dispose();
+ }
+
+ public async Task Import(string filePath, TextGroup[] groups)
+ {
+ try
{
var pkg = new ExcelPackage();
+ await pkg.LoadAsync(new FileInfo(filePath));
foreach (var tg in groups)
{
- var ws = pkg.Workbook.Worksheets.Add(tg.TextGroupInfo.Name);
- var hasDialogCells = false;
-
- ws.Cells.Style.VerticalAlignment = OfficeOpenXml.Style.ExcelVerticalAlignment.Top;
- ws.Cells.Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Left;
- ws.Row(1).Style.Font.Bold = true;
- ws.Cells[1, 1].Value = "#";
- ws.Cells[1, 2].Value = "Text";
-
- for (int i = 0; i < tg.Count; i++)
+ var ws = pkg.Workbook.Worksheets[tg.TextGroupInfo.Name];
+ if (ws is not null)
{
- var ti = tg[i];
- var ri = i + 2;
-
- ws.Cells[ri, 1].Value = i;
- ws.Cells[ri, 2].Value = ti.Text;
-
- if (ti is TextTableDialogItem)
- hasDialogCells = true;
- }
-
-
- for (int ri = 1; ri <= ws.Cells.Rows; ri++)
- {
- var r = ws.Row(ri);
- r.CustomHeight = false;
- }
-
- if (hasDialogCells)
- {
- var c = ws.Column(2);
- c.Style.WrapText = true;
- c.Width = 30;
- }
-
- for (int ci = 1; ci <= 2; ci++)
- {
- var c = ws.Column(ci);
- if (!c.Style.WrapText)
- c.AutoFit();
- }
- }
-
- await pkg.SaveAsAsync(new FileInfo(destFilePath));
- pkg.Dispose();
- }
-
- public async Task Import(string filePath, TextGroup[] groups)
- {
- try
- {
- var pkg = new ExcelPackage();
- await pkg.LoadAsync(new FileInfo(filePath));
-
- foreach (var tg in groups)
- {
- var ws = pkg.Workbook.Worksheets[tg.TextGroupInfo.Name];
- if (ws is not null)
+ for (int iti = 0; iti < tg.Count; iti++)
{
- for (int iti = 0; iti < tg.Count; iti++)
- {
- var ti = tg[iti];
- var ri = iti + 2;
- var c = ws.Cells[ri, 2];
+ var ti = tg[iti];
+ var ri = iti + 2;
+ var c = ws.Cells[ri, 2];
- ti.Text = ((string)c.Value).Replace("\r\n", "\n").Replace("\n", "\r\n");
- tg.NeedToSave = true;
- }
+ ti.Text = ((string)c.Value).Replace("\r\n", "\n").Replace("\n", "\r\n");
+ tg.NeedToSave = true;
}
}
+ }
- pkg.Dispose();
- }
- catch (Exception)
- {
- }
+ pkg.Dispose();
+ }
+ catch (Exception)
+ {
}
}
}
diff --git a/SM64Lib.Text.Exporters/Properties/AssemblyInfo.cs b/SM64Lib.Text.Exporters/Properties/AssemblyInfo.cs
index 0a38d8c..09226f9 100644
--- a/SM64Lib.Text.Exporters/Properties/AssemblyInfo.cs
+++ b/SM64Lib.Text.Exporters/Properties/AssemblyInfo.cs
@@ -1,6 +1,4 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
+using System.Runtime.InteropServices;
// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
diff --git a/SM64Lib.Text.Exporters/TxtExporter.cs b/SM64Lib.Text.Exporters/TxtExporter.cs
index da66691..8e9cfe0 100644
--- a/SM64Lib.Text.Exporters/TxtExporter.cs
+++ b/SM64Lib.Text.Exporters/TxtExporter.cs
@@ -1,48 +1,43 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
+using System.IO;
using System.Threading.Tasks;
-namespace SM64Lib.Text.Exporters
+namespace SM64Lib.Text.Exporters;
+
+public class TxtExporter
{
- public class TxtExporter
+ public async Task Export(string destFilePath, TextGroup[] groups)
{
- public async Task Export(string destFilePath, TextGroup[] groups)
+ var sw = new StreamWriter(destFilePath);
+
+ for (int itg = 0; itg < groups.Length; itg++)
{
- var sw = new StreamWriter(destFilePath);
+ var tg = groups[itg];
- for (int itg = 0; itg < groups.Length; itg++)
- {
- var tg = groups[itg];
-
- if (itg != 0)
- await sw.WriteLineAsync("------------------------------\n");
- await sw.WriteLineAsync($"Text Group - {tg.TextGroupInfo.Name}\n");
+ if (itg != 0)
await sw.WriteLineAsync("------------------------------\n");
+ await sw.WriteLineAsync($"Text Group - {tg.TextGroupInfo.Name}\n");
+ await sw.WriteLineAsync("------------------------------\n");
- for (int iti = 0; iti < tg.Count; iti++)
+ for (int iti = 0; iti < tg.Count; iti++)
+ {
+ var ti = tg[iti];
+
+ if (ti is TextTableDialogItem)
{
- var ti = tg[iti];
-
- if (ti is TextTableDialogItem)
- {
- await sw.WriteLineAsync($"Dialog #{iti}\n");
- await sw.WriteLineAsync(ti.Text);
- await sw.WriteLineAsync("\n\n");
- }
- else
- {
- await sw.WriteLineAsync($"Text Item #{iti}");
- await sw.WriteLineAsync(ti.Text);
- await sw.WriteLineAsync();
- }
+ await sw.WriteLineAsync($"Dialog #{iti}\n");
+ await sw.WriteLineAsync(ti.Text);
+ await sw.WriteLineAsync("\n\n");
+ }
+ else
+ {
+ await sw.WriteLineAsync($"Text Item #{iti}");
+ await sw.WriteLineAsync(ti.Text);
+ await sw.WriteLineAsync();
}
}
-
- await sw.FlushAsync();
- sw.Close();
}
+
+ await sw.FlushAsync();
+ sw.Close();
}
}
diff --git a/SM64Lib.TextValueConverter/Properties/AssemblyInfo.cs b/SM64Lib.TextValueConverter/Properties/AssemblyInfo.cs
index 021c7af..3c546af 100644
--- a/SM64Lib.TextValueConverter/Properties/AssemblyInfo.cs
+++ b/SM64Lib.TextValueConverter/Properties/AssemblyInfo.cs
@@ -1,5 +1,4 @@
using global::System;
-using global::System.Reflection;
using global::System.Runtime.InteropServices;
[assembly: ComVisible(false)]
diff --git a/SM64Lib.TextValueConverter/TextValueConverter.cs b/SM64Lib.TextValueConverter/TextValueConverter.cs
index 170a6f1..f54df49 100644
--- a/SM64Lib.TextValueConverter/TextValueConverter.cs
+++ b/SM64Lib.TextValueConverter/TextValueConverter.cs
@@ -1,89 +1,87 @@
using System;
-using Microsoft.VisualBasic.CompilerServices;
-namespace SM64Lib.TextValueConverter
+namespace SM64Lib.TextValueConverter;
+
+public static class TextValueConverter
{
- public static class TextValueConverter
+ public static event WantIntegerValueModeEventHandler WantIntegerValueMode;
+ public delegate void WantIntegerValueModeEventHandler(WantIntegerValueModeEventArgs e);
+
+ public static int ValueFromText(string Text, int DefaultValue = 0, int useIVM = -1)
{
- public static event WantIntegerValueModeEventHandler WantIntegerValueMode;
- public delegate void WantIntegerValueModeEventHandler(WantIntegerValueModeEventArgs e);
+ return Convert.ToInt32(LongFromText(Text, DefaultValue, useIVM));
+ }
- public static int ValueFromText(string Text, int DefaultValue = 0, int useIVM = -1)
+ public static long LongFromText(string Text, long DefaultValue = 0, int useIVM = -1)
+ {
+ try
{
- return Convert.ToInt32(LongFromText(Text, DefaultValue, useIVM));
- }
+ int IVM = useIVM > -1 ? useIVM : GetIntegerValueMode();
+ Text = Text?.ToLower()?.Trim();
- public static long LongFromText(string Text, long DefaultValue = 0, int useIVM = -1)
- {
- try
+ if (string.IsNullOrWhiteSpace(Text))
+ return 0;
+
+ switch (true)
{
- int IVM = useIVM > -1 ? useIVM : GetIntegerValueMode();
- Text = Text?.ToLower()?.Trim();
-
- if (string.IsNullOrWhiteSpace(Text))
- return 0;
-
- switch (true)
- {
- case object _ when Text.StartsWith("0x"):
- case object _ when Text.StartsWith("&h"):
- return Convert.ToInt32(Text.Substring(2), 16);
- case object _ when Text.StartsWith("$"):
- return Convert.ToInt32(Text.Substring(1), 16);
- case object _ when Text.StartsWith("0b"):
- case object _ when Text.StartsWith("&b"):
- return Convert.ToInt32(Text.Substring(2), 2);
- default:
- return Convert.ToInt32(Text);
- }
- }
- catch (Exception)
- {
- return DefaultValue;
- }
- }
-
- public static string TextFromValue(long Value, int IVM = -1, int charCount = 0)
- {
- if (IVM == -1)
- {
- IVM = GetIntegerValueMode();
- }
-
- switch (IVM)
- {
- case 0:
- return Value.ToString(GetCharCountAsZeroString(charCount));
- case 1:
- return "0x" + Value.ToString("X" + (charCount > 0 ? charCount.ToString() : ""));
- case 2:
- return "&H" + Value.ToString("X" + (charCount > 0 ? charCount.ToString() : ""));
- case 3:
- return "$" + Value.ToString("X" + (charCount > 0 ? charCount.ToString() : ""));
+ case object _ when Text.StartsWith("0x"):
+ case object _ when Text.StartsWith("&h"):
+ return Convert.ToInt32(Text.Substring(2), 16);
+ case object _ when Text.StartsWith("$"):
+ return Convert.ToInt32(Text.Substring(1), 16);
+ case object _ when Text.StartsWith("0b"):
+ case object _ when Text.StartsWith("&b"):
+ return Convert.ToInt32(Text.Substring(2), 2);
default:
- return string.Empty;
+ return Convert.ToInt32(Text);
}
}
-
- private static string GetCharCountAsZeroString(int charCount)
+ catch (Exception)
{
- string GetCharCountAsZeroStringRet = default;
- GetCharCountAsZeroStringRet = "";
- while (GetCharCountAsZeroStringRet.Length < charCount)
- GetCharCountAsZeroStringRet += "0";
- return GetCharCountAsZeroStringRet;
- }
-
- private static int GetIntegerValueMode()
- {
- var e = new WantIntegerValueModeEventArgs();
- WantIntegerValueMode?.Invoke(e);
- return e.IntegerValueMode;
+ return DefaultValue;
}
}
- public class WantIntegerValueModeEventArgs : EventArgs
+ public static string TextFromValue(long Value, int IVM = -1, int charCount = 0)
{
- public int IntegerValueMode { get; set; }
+ if (IVM == -1)
+ {
+ IVM = GetIntegerValueMode();
+ }
+
+ switch (IVM)
+ {
+ case 0:
+ return Value.ToString(GetCharCountAsZeroString(charCount));
+ case 1:
+ return "0x" + Value.ToString("X" + (charCount > 0 ? charCount.ToString() : ""));
+ case 2:
+ return "&H" + Value.ToString("X" + (charCount > 0 ? charCount.ToString() : ""));
+ case 3:
+ return "$" + Value.ToString("X" + (charCount > 0 ? charCount.ToString() : ""));
+ default:
+ return string.Empty;
+ }
}
+
+ private static string GetCharCountAsZeroString(int charCount)
+ {
+ string GetCharCountAsZeroStringRet = default;
+ GetCharCountAsZeroStringRet = "";
+ while (GetCharCountAsZeroStringRet.Length < charCount)
+ GetCharCountAsZeroStringRet += "0";
+ return GetCharCountAsZeroStringRet;
+ }
+
+ private static int GetIntegerValueMode()
+ {
+ var e = new WantIntegerValueModeEventArgs();
+ WantIntegerValueMode?.Invoke(e);
+ return e.IntegerValueMode;
+ }
+}
+
+public class WantIntegerValueModeEventArgs : EventArgs
+{
+ public int IntegerValueMode { get; set; }
}
\ No newline at end of file
diff --git a/SM64Lib/ASM/CustomAsmArea.cs b/SM64Lib/ASM/CustomAsmArea.cs
index e34272b..dbff10b 100644
--- a/SM64Lib/ASM/CustomAsmArea.cs
+++ b/SM64Lib/ASM/CustomAsmArea.cs
@@ -1,83 +1,77 @@
using Newtonsoft.Json;
using SM64Lib.Data;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-namespace SM64Lib.ASM
+namespace SM64Lib.ASM;
+
+public class CustomAsmArea
{
- public class CustomAsmArea
+ public byte[] AreaBytes { get; set; }
+
+ [JsonProperty(nameof(Config))]
+ private CustomAsmAreaConfig config;
+
+ [JsonIgnore]
+ public CustomAsmAreaConfig Config
{
- public byte[] AreaBytes { get; set; }
-
- [JsonProperty(nameof(Config))]
- private CustomAsmAreaConfig config;
-
- [JsonIgnore]
- public CustomAsmAreaConfig Config
+ get
{
- get
- {
- if (config == null)
- config = new CustomAsmAreaConfig();
- return config;
- }
- }
-
- [JsonConstructor]
- private CustomAsmArea(JsonConstructorAttribute emptyObject)
- {
- }
-
- public CustomAsmArea()
- : this(true)
- {
- }
-
- private CustomAsmArea(bool createEmptyAreaBytesArray)
- : this(null, createEmptyAreaBytesArray)
- {
- }
-
- public CustomAsmArea(CustomAsmAreaConfig config)
- : this(config, false)
- {
- }
-
- private CustomAsmArea(CustomAsmAreaConfig config, bool createEmptyAreaBytesArray)
- {
- this.config = config;
-
- if (createEmptyAreaBytesArray)
- AreaBytes = new byte[] { };
- }
-
- public void Load(BinaryData data, CustomAsmBankConfig bankConfig)
- {
- if (Config.RomAddress != -1 && Config.Length > 0)
- {
- data.Position = Config.RomAddress;
- AreaBytes = data.Read(Config.Length);
- }
- else
- AreaBytes = new byte[] { };
- }
-
- public int Save(BinaryData data, int address, CustomAsmBankConfig bankConfig)
- {
- data.Position = address;
- data.Write(AreaBytes);
- return UpdateAddresses(address, bankConfig);
- }
-
- internal int UpdateAddresses(int address, CustomAsmBankConfig bankConfig)
- {
- Config.RomAddress = address;
- Config.Length = AreaBytes.Length;
- Config.RamAddress = address - bankConfig.GetRomStartAddress() + bankConfig.GetRamStartAddress();
- return Config.Length;
+ if (config == null)
+ config = new CustomAsmAreaConfig();
+ return config;
}
}
+
+ [JsonConstructor]
+ private CustomAsmArea(JsonConstructorAttribute emptyObject)
+ {
+ }
+
+ public CustomAsmArea()
+ : this(true)
+ {
+ }
+
+ private CustomAsmArea(bool createEmptyAreaBytesArray)
+ : this(null, createEmptyAreaBytesArray)
+ {
+ }
+
+ public CustomAsmArea(CustomAsmAreaConfig config)
+ : this(config, false)
+ {
+ }
+
+ private CustomAsmArea(CustomAsmAreaConfig config, bool createEmptyAreaBytesArray)
+ {
+ this.config = config;
+
+ if (createEmptyAreaBytesArray)
+ AreaBytes = new byte[] { };
+ }
+
+ public void Load(BinaryData data, CustomAsmBankConfig bankConfig)
+ {
+ if (Config.RomAddress != -1 && Config.Length > 0)
+ {
+ data.Position = Config.RomAddress;
+ AreaBytes = data.Read(Config.Length);
+ }
+ else
+ AreaBytes = new byte[] { };
+ }
+
+ public int Save(BinaryData data, int address, CustomAsmBankConfig bankConfig)
+ {
+ data.Position = address;
+ data.Write(AreaBytes);
+ return UpdateAddresses(address, bankConfig);
+ }
+
+ internal int UpdateAddresses(int address, CustomAsmBankConfig bankConfig)
+ {
+ Config.RomAddress = address;
+ Config.Length = AreaBytes.Length;
+ Config.RamAddress = address - bankConfig.GetRomStartAddress() + bankConfig.GetRamStartAddress();
+ return Config.Length;
+ }
}
diff --git a/SM64Lib/ASM/CustomAsmAreaConfig.cs b/SM64Lib/ASM/CustomAsmAreaConfig.cs
index dff55ca..c7f61bc 100644
--- a/SM64Lib/ASM/CustomAsmAreaConfig.cs
+++ b/SM64Lib/ASM/CustomAsmAreaConfig.cs
@@ -1,39 +1,33 @@
using Newtonsoft.Json;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using Pilz.Cryptography;
using Pilz.Json.Converters;
-namespace SM64Lib.ASM
+namespace SM64Lib.ASM;
+
+public class CustomAsmAreaConfig
{
- public class CustomAsmAreaConfig
+ internal delegate void RequestCustomAsmAreaEventHandler(CustomAsmAreaConfig config, RequestCustomAsmAreaEventArgs request);
+ internal static event RequestCustomAsmAreaEventHandler RequestCustomAsmArea;
+
+ [JsonConverter(typeof(UniquieIDStringJsonConverter))]
+ public UniquieID ID { get; set; } = new();
+ public string Name { get; set; }
+ [JsonProperty]
+ public int RamAddress { get; internal set; } = -1;
+ [JsonProperty]
+ public int RomAddress { get; internal set; } = -1;
+ [JsonProperty]
+ public int Length { get; internal set; } = 0;
+
+ public CustomAsmArea FindCustomAsmArea()
{
- internal delegate void RequestCustomAsmAreaEventHandler(CustomAsmAreaConfig config, RequestCustomAsmAreaEventArgs request);
- internal static event RequestCustomAsmAreaEventHandler RequestCustomAsmArea;
+ var args = new RequestCustomAsmAreaEventArgs();
+ RequestCustomAsmArea?.Invoke(this, args);
+ return args.CustomAsmArea;
+ }
- [JsonConverter(typeof(UniquieIDStringJsonConverter))]
- public UniquieID ID { get; set; } = new();
- public string Name { get; set; }
- [JsonProperty]
- public int RamAddress { get; internal set; } = -1;
- [JsonProperty]
- public int RomAddress { get; internal set; } = -1;
- [JsonProperty]
- public int Length { get; internal set; } = 0;
-
- public CustomAsmArea FindCustomAsmArea()
- {
- var args = new RequestCustomAsmAreaEventArgs();
- RequestCustomAsmArea?.Invoke(this, args);
- return args.CustomAsmArea;
- }
-
- internal class RequestCustomAsmAreaEventArgs
- {
- public CustomAsmArea CustomAsmArea { get; set; }
- }
+ internal class RequestCustomAsmAreaEventArgs
+ {
+ public CustomAsmArea CustomAsmArea { get; set; }
}
}
diff --git a/SM64Lib/ASM/CustomAsmBank.cs b/SM64Lib/ASM/CustomAsmBank.cs
index 0013409..33450a5 100644
--- a/SM64Lib/ASM/CustomAsmBank.cs
+++ b/SM64Lib/ASM/CustomAsmBank.cs
@@ -1,85 +1,81 @@
using Newtonsoft.Json;
-using System;
using System.Collections.Generic;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-namespace SM64Lib.ASM
+namespace SM64Lib.ASM;
+
+public class CustomAsmBank
{
- public class CustomAsmBank
+ public CustomAsmBankConfig Config { get; }
+ [JsonIgnore]
+ public List Areas { get; } = new List();
+
+ public CustomAsmBank() : this(new CustomAsmBankConfig())
{
- public CustomAsmBankConfig Config { get; }
- [JsonIgnore]
- public List Areas { get; } = new List();
+ }
- public CustomAsmBank() : this(new CustomAsmBankConfig())
+ public CustomAsmBank(CustomAsmBankConfig config)
+ {
+ Config = config;
+ }
+
+ public void Load(RomManager romManager)
+ {
+ Areas.Clear();
+
+ bool canLoadArea(CustomAsmAreaConfig areaConfig) =>
+ areaConfig.RomAddress != -1;
+
+ if (Config.Areas.Where(n => canLoadArea(n)).Any())
{
- }
+ var data = romManager.GetBinaryRom(System.IO.FileAccess.Read);
- public CustomAsmBank(CustomAsmBankConfig config)
- {
- Config = config;
- }
-
- public void Load(RomManager romManager)
- {
- Areas.Clear();
-
- bool canLoadArea(CustomAsmAreaConfig areaConfig) =>
- areaConfig.RomAddress != -1;
-
- if (Config.Areas.Where(n => canLoadArea(n)).Any())
+ foreach (var areaConfig in Config.Areas)
{
- var data = romManager.GetBinaryRom(System.IO.FileAccess.Read);
-
- foreach (var areaConfig in Config.Areas)
- {
- var area = new CustomAsmArea(areaConfig);
- area.Config.ID.GenerateIfNull();
- area.Load(data, Config);
- Areas.Add(area);
- }
-
- data.Close();
+ var area = new CustomAsmArea(areaConfig);
+ area.Config.ID.GenerateIfNull();
+ area.Load(data, Config);
+ Areas.Add(area);
}
+
+ data.Close();
+ }
+ }
+
+ public void Save(RomManager romManager)
+ {
+ var startAddr = Config.GetRomStartAddress();
+ var curRomAddr = startAddr;
+
+ if (Areas.Any())
+ {
+ var data = romManager.GetBinaryRom(System.IO.FileAccess.ReadWrite);
+
+ foreach (var area in Areas)
+ curRomAddr += area.Save(data, curRomAddr, Config);
+
+ data.Close();
}
- public void Save(RomManager romManager)
+ UpdateAreaConfigCollection();
+ Config.Length = curRomAddr - startAddr;
+ }
+
+ public void UpdateAddresses()
+ {
+ if (Areas.Any())
{
var startAddr = Config.GetRomStartAddress();
var curRomAddr = startAddr;
-
- if (Areas.Any())
- {
- var data = romManager.GetBinaryRom(System.IO.FileAccess.ReadWrite);
-
- foreach (var area in Areas)
- curRomAddr += area.Save(data, curRomAddr, Config);
-
- data.Close();
- }
-
- UpdateAreaConfigCollection();
+ foreach (var area in Areas)
+ curRomAddr += area.UpdateAddresses(curRomAddr, Config);
Config.Length = curRomAddr - startAddr;
}
+ }
- public void UpdateAddresses()
- {
- if (Areas.Any())
- {
- var startAddr = Config.GetRomStartAddress();
- var curRomAddr = startAddr;
- foreach (var area in Areas)
- curRomAddr += area.UpdateAddresses(curRomAddr, Config);
- Config.Length = curRomAddr - startAddr;
- }
- }
-
- public void UpdateAreaConfigCollection()
- {
- Config.Areas.Clear();
- Config.Areas.AddRange(Areas.Select(n => n.Config));
- }
+ public void UpdateAreaConfigCollection()
+ {
+ Config.Areas.Clear();
+ Config.Areas.AddRange(Areas.Select(n => n.Config));
}
}
diff --git a/SM64Lib/ASM/CustomAsmBankConfig.cs b/SM64Lib/ASM/CustomAsmBankConfig.cs
index 14646bb..63df9ef 100644
--- a/SM64Lib/ASM/CustomAsmBankConfig.cs
+++ b/SM64Lib/ASM/CustomAsmBankConfig.cs
@@ -1,50 +1,45 @@
using Newtonsoft.Json;
-using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-namespace SM64Lib.ASM
+namespace SM64Lib.ASM;
+
+public class CustomAsmBankConfig
{
- public class CustomAsmBankConfig
+ public static int DefaultMaxLength { get; set; } = 0xA000;
+ public static int DefaultRomStartAddress { get; internal set; } = 0x1206000;
+ public static int DefaultRamStartAddress { get; internal set; } = 0x406000;
+
+ public List Areas { get; } = new List();
+ public int MaxLength { get; set; } = -1;
+ [JsonProperty]
+ public int Length { get; internal set; } = -1;
+ public int RomStartAddress { get; set; } = -1;
+ public int RamStartAddress { get; set; } = -1;
+
+ public int GetRomStartAddress()
+ => GetRomStartAddressAdv().address;
+
+ public (int address, bool isDefault) GetRomStartAddressAdv()
{
- public static int DefaultMaxLength { get; set; } = 0xA000;
- public static int DefaultRomStartAddress { get; internal set; } = 0x1206000;
- public static int DefaultRamStartAddress { get; internal set; } = 0x406000;
+ bool isDefault = RomStartAddress == -1;
+ return (isDefault ? DefaultRomStartAddress : RomStartAddress, isDefault);
+ }
- public List Areas { get; } = new List();
- public int MaxLength { get; set; } = -1;
- [JsonProperty]
- public int Length { get; internal set; } = -1;
- public int RomStartAddress { get; set; } = -1;
- public int RamStartAddress { get; set; } = -1;
+ public int GetRamStartAddress()
+ => GetRamStartAddressAdv().address;
- public int GetRomStartAddress()
- => GetRomStartAddressAdv().address;
+ public (int address, bool isDefault) GetRamStartAddressAdv()
+ {
+ bool isDefault = RamStartAddress == -1;
+ return (isDefault ? DefaultRamStartAddress : RamStartAddress, isDefault);
+ }
- public (int address, bool isDefault) GetRomStartAddressAdv()
- {
- bool isDefault = RomStartAddress == -1;
- return (isDefault ? DefaultRomStartAddress : RomStartAddress, isDefault);
- }
+ public int GetMaxLength()
+ => GetMaxLengthAdv().length;
- public int GetRamStartAddress()
- => GetRamStartAddressAdv().address;
-
- public (int address, bool isDefault) GetRamStartAddressAdv()
- {
- bool isDefault = RamStartAddress == -1;
- return (isDefault ? DefaultRamStartAddress : RamStartAddress, isDefault);
- }
-
- public int GetMaxLength()
- => GetMaxLengthAdv().length;
-
- public (int length, bool isDefault) GetMaxLengthAdv()
- {
- bool isDefault = RamStartAddress == -1;
- return (isDefault ? DefaultMaxLength : MaxLength, isDefault);
- }
+ public (int length, bool isDefault) GetMaxLengthAdv()
+ {
+ bool isDefault = RamStartAddress == -1;
+ return (isDefault ? DefaultMaxLength : MaxLength, isDefault);
}
}
diff --git a/SM64Lib/BaseTweakScriptInfo.cs b/SM64Lib/BaseTweakScriptInfo.cs
index 55a1b66..92a507e 100644
--- a/SM64Lib/BaseTweakScriptInfo.cs
+++ b/SM64Lib/BaseTweakScriptInfo.cs
@@ -1,30 +1,25 @@
using SM64Lib.Patching;
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-namespace SM64Lib
+namespace SM64Lib;
+
+public class BaseTweakScriptInfo
{
- public class BaseTweakScriptInfo
- {
- public PatchScript Script { get; private set; }
- public int Priority { get; private set; }
- public bool IsReadOnly { get; private set; }
- public string Name { get; private set; }
- public bool EnabledByDefault { get; private set; }
- public bool Enabled { get; set; }
+ public PatchScript Script { get; private set; }
+ public int Priority { get; private set; }
+ public bool IsReadOnly { get; private set; }
+ public string Name { get; private set; }
+ public bool EnabledByDefault { get; private set; }
+ public bool Enabled { get; set; }
- public BaseTweakScriptInfo(PatchScript script)
- {
- var infos = script.Name.Split('#');
- Priority = Convert.ToInt32(infos[0]);
- IsReadOnly = infos[1] == "w" ? true : false;
- EnabledByDefault = infos[2] == "y" ? true : false;
- Enabled = EnabledByDefault;
- Name = infos[3];
- Script = script;
- }
+ public BaseTweakScriptInfo(PatchScript script)
+ {
+ var infos = script.Name.Split('#');
+ Priority = Convert.ToInt32(infos[0]);
+ IsReadOnly = infos[1] == "w" ? true : false;
+ EnabledByDefault = infos[2] == "y" ? true : false;
+ Enabled = EnabledByDefault;
+ Name = infos[3];
+ Script = script;
}
}
diff --git a/SM64Lib/Behaviors/Behavior.cs b/SM64Lib/Behaviors/Behavior.cs
index a2dd0f1..5af431b 100644
--- a/SM64Lib/Behaviors/Behavior.cs
+++ b/SM64Lib/Behaviors/Behavior.cs
@@ -5,237 +5,234 @@ using SM64Lib.Data;
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using Z.Collections.Extensions;
using static SM64Lib.Extensions.ObjectExtensions;
-namespace SM64Lib.Behaviors
+namespace SM64Lib.Behaviors;
+
+public class Behavior
{
- public class Behavior
+ private readonly Dictionary knownCustomAsmCommands = new Dictionary();
+
+ [JsonProperty]
+ public BehaviorConfig Config { get; private set; }
+ [JsonProperty]
+ public Behaviorscript Script { get; private set; }
+ public int CollisionPointer { get; set; }
+ public bool EnableCollisionPointer { get; set; }
+ public List BehaviorAddressDestinations { get; set; } = new List();
+
+ [JsonIgnore]
+ public long Length
{
- private readonly Dictionary knownCustomAsmCommands = new Dictionary();
-
- [JsonProperty]
- public BehaviorConfig Config { get; private set; }
- [JsonProperty]
- public Behaviorscript Script { get; private set; }
- public int CollisionPointer { get; set; }
- public bool EnableCollisionPointer { get; set; }
- public List BehaviorAddressDestinations { get; set; } = new List();
-
- [JsonIgnore]
- public long Length
+ get
{
- get
+ if (Config.FixedLength == -1)
+ return Script.Length;
+ else
+ return Config.FixedLength;
+ }
+ }
+
+ public Behavior() : this(new BehaviorConfig())
+ {
+ }
+
+ public Behavior(BehaviorConfig config)
+ {
+ CreateNewBehaviorscript();
+ Config = config;
+ }
+
+ public Behavior(BehaviorCreationTypes behaviorCreationType) : this()
+ {
+ Create(behaviorCreationType);
+ }
+
+ public void Create(BehaviorCreationTypes type)
+ {
+ CreateNewBehaviorscript();
+
+ switch (type)
+ {
+ case BehaviorCreationTypes.SolidObject:
+ Script.Add(new BehaviorscriptCommand("00 09 00 00"));
+ Script.Add(new BehaviorscriptCommand("11 01 00 01"));
+ Script.Add(new BehaviorscriptCommand("2a 00 00 00 00 00 00 00"));
+ Script.Add(new BehaviorscriptCommand("08 00 00 00"));
+ Script.Add(new BehaviorscriptCommand("0c 00 00 00 80 38 39 cc"));
+ Script.Add(new BehaviorscriptCommand("09 00 00 00"));
+ break;
+ }
+
+ ParseScript();
+ }
+
+ private void CreateNewBehaviorscript()
+ {
+ if (Script != null)
+ Script.Close();
+ Script = new Behaviorscript();
+ }
+
+ public bool Read(BinaryData data, int address)
+ {
+ CreateNewBehaviorscript();
+ var success = Script.Read(data, address, Config.IsVanilla, Config.ExpectedLength != -1, Config.ExpectedLength);
+ if (Config.IsVanilla)
+ Config.FixedLength = (int)Script.Length;
+ Config.ExpectedLength = (int)Script.Length;
+ ParseScript();
+ return success;
+ }
+
+ public void Write(BinaryData data, int address)
+ {
+ //if (!Config.IsVanilla)
+ TakeoverSettingsToScript();
+
+ var length = Script.Write(data, address);
+
+ if (Config.FixedLength != -1 && length != Config.FixedLength)
+ data.Position -= length - Config.FixedLength;
+ Config.ExpectedLength = length;
+ }
+
+ public void ParseScript()
+ {
+ var dicCustomAsmFuncs = new Dictionary();
+ EnableCollisionPointer = false;
+ knownCustomAsmCommands.Clear();
+
+ foreach (var link in Config.CustomAsmLinks)
+ dicCustomAsmFuncs.AddOrUpdate(link.CustomAsmAreaConfig.RamAddress | unchecked((int)0x80000000), link);
+
+ foreach (BehaviorscriptCommand cmd in Script)
+ {
+ switch (cmd.CommandType)
{
- if (Config.FixedLength == -1)
- return Script.Length;
- else
- return Config.FixedLength;
- }
- }
-
- public Behavior() : this(new BehaviorConfig())
- {
- }
-
- public Behavior(BehaviorConfig config)
- {
- CreateNewBehaviorscript();
- Config = config;
- }
-
- public Behavior(BehaviorCreationTypes behaviorCreationType) : this()
- {
- Create(behaviorCreationType);
- }
-
- public void Create(BehaviorCreationTypes type)
- {
- CreateNewBehaviorscript();
-
- switch (type)
- {
- case BehaviorCreationTypes.SolidObject:
- Script.Add(new BehaviorscriptCommand("00 09 00 00"));
- Script.Add(new BehaviorscriptCommand("11 01 00 01"));
- Script.Add(new BehaviorscriptCommand("2a 00 00 00 00 00 00 00"));
- Script.Add(new BehaviorscriptCommand("08 00 00 00"));
- Script.Add(new BehaviorscriptCommand("0c 00 00 00 80 38 39 cc"));
- Script.Add(new BehaviorscriptCommand("09 00 00 00"));
+ case BehaviorscriptCommandTypes.x2A_SetCollision:
+ CollisionPointer = BehaviorscriptCommandFunctions.X2A.GetCollisionPointer(cmd);
+ EnableCollisionPointer = true;
+ break;
+ case BehaviorscriptCommandTypes.x0C_CallFunction:
+ var ptr = BehaviorscriptCommandFunctions.X0C.GetAsmPointer(cmd);
+ if (dicCustomAsmFuncs.ContainsKey(ptr))
+ knownCustomAsmCommands.AddOrUpdate(dicCustomAsmFuncs[ptr].CustomAsmAreaConfig, cmd);
break;
}
-
- ParseScript();
}
+ }
- private void CreateNewBehaviorscript()
+ public void TakeoverSettingsToScript()
+ {
+ // Update collision pointer
+ AddUpdateRemoveCmd(
+ BehaviorscriptCommandTypes.x2A_SetCollision,
+ EnableCollisionPointer,
+ () => BehaviorscriptCommandFactory.Build_x2A(CollisionPointer),
+ (cmd) => BehaviorscriptCommandFunctions.X2A.SetCollisionPointer(cmd, CollisionPointer));
+
+ // Insert Custom Asm Links
{
- if (Script != null)
- Script.Close();
- Script = new Behaviorscript();
- }
-
- public bool Read(BinaryData data, int address)
- {
- CreateNewBehaviorscript();
- var success = Script.Read(data, address, Config.IsVanilla, Config.ExpectedLength != -1, Config.ExpectedLength);
- if (Config.IsVanilla)
- Config.FixedLength = (int)Script.Length;
- Config.ExpectedLength = (int)Script.Length;
- ParseScript();
- return success;
- }
-
- public void Write(BinaryData data, int address)
- {
- //if (!Config.IsVanilla)
- TakeoverSettingsToScript();
-
- var length = Script.Write(data, address);
-
- if (Config.FixedLength != -1 && length != Config.FixedLength)
- data.Position -= length - Config.FixedLength;
- Config.ExpectedLength = length;
- }
-
- public void ParseScript()
- {
- var dicCustomAsmFuncs = new Dictionary();
- EnableCollisionPointer = false;
- knownCustomAsmCommands.Clear();
-
foreach (var link in Config.CustomAsmLinks)
- dicCustomAsmFuncs.AddOrUpdate(link.CustomAsmAreaConfig.RamAddress | unchecked((int)0x80000000), link);
-
- foreach (BehaviorscriptCommand cmd in Script)
{
- switch (cmd.CommandType)
+ var asmPointer = link.CustomAsmAreaConfig.RamAddress | unchecked((int)0x80000000);
+ var cmdStartLoop = Script.FirstOfType(BehaviorscriptCommandTypes.x08_LoopStart);
+ var cmdStartLoopIndex = Script.IndexOf(cmdStartLoop);
+ int iInsert;
+
+ if (link.Loop)
{
- case BehaviorscriptCommandTypes.x2A_SetCollision:
- CollisionPointer = BehaviorscriptCommandFunctions.X2A.GetCollisionPointer(cmd);
- EnableCollisionPointer = true;
- break;
- case BehaviorscriptCommandTypes.x0C_CallFunction:
- var ptr = BehaviorscriptCommandFunctions.X0C.GetAsmPointer(cmd);
- if (dicCustomAsmFuncs.ContainsKey(ptr))
- knownCustomAsmCommands.AddOrUpdate(dicCustomAsmFuncs[ptr].CustomAsmAreaConfig, cmd);
- break;
- }
- }
- }
-
- public void TakeoverSettingsToScript()
- {
- // Update collision pointer
- AddUpdateRemoveCmd(
- BehaviorscriptCommandTypes.x2A_SetCollision,
- EnableCollisionPointer,
- () => BehaviorscriptCommandFactory.Build_x2A(CollisionPointer),
- (cmd) => BehaviorscriptCommandFunctions.X2A.SetCollisionPointer(cmd, CollisionPointer));
-
- // Insert Custom Asm Links
- {
- foreach (var link in Config.CustomAsmLinks)
- {
- var asmPointer = link.CustomAsmAreaConfig.RamAddress | unchecked((int)0x80000000);
- var cmdStartLoop = Script.FirstOfType(BehaviorscriptCommandTypes.x08_LoopStart);
- var cmdStartLoopIndex = Script.IndexOf(cmdStartLoop);
- int iInsert;
-
- if (link.Loop)
- {
- if (cmdStartLoop is not null)
- iInsert = cmdStartLoopIndex + 1;
- else
- iInsert = -1;
- }
+ if (cmdStartLoop is not null)
+ iInsert = cmdStartLoopIndex + 1;
else
- {
- if (cmdStartLoop is not null)
- iInsert = cmdStartLoopIndex;
- else
- iInsert = (int)Script.Count - 2;
- }
-
- if (knownCustomAsmCommands.ContainsKey(link.CustomAsmAreaConfig))
- {
- var cmd = knownCustomAsmCommands[link.CustomAsmAreaConfig];
- var cmdIndex = Script.IndexOf(cmd);
- BehaviorscriptCommandFunctions.X0C.SetAsmPointer(cmd, asmPointer);
-
- if (cmdIndex != -1)
- {
- var reinsert = false;
-
- if (link.Loop && cmdIndex < cmdStartLoopIndex)
- {
- reinsert = true;
- iInsert -= 1;
- }
- else if (!link.Loop && cmdIndex > cmdStartLoopIndex)
- reinsert = true;
-
- if (reinsert)
- {
- Script.Remove(cmd);
- Script.Insert(iInsert, cmd);
- }
- }
- }
- else if (iInsert != -1)
- {
- var cmd = BehaviorscriptCommandFactory.Build_x0C(asmPointer);
- Script.Insert(iInsert, cmd);
- knownCustomAsmCommands.Add(link.CustomAsmAreaConfig, cmd);
- }
+ iInsert = -1;
}
-
- foreach (var kvp in knownCustomAsmCommands.ToArray())
- {
- if (!Config.CustomAsmLinks.Where(n => n.CustomAsmAreaConfig == kvp.Key).Any())
- {
- knownCustomAsmCommands.Remove(kvp.Key);
- Script.RemoveIfContains(kvp.Value);
- kvp.Value.Close();
- }
- }
- }
- }
-
- private void AddUpdateRemoveCmd(BehaviorscriptCommandTypes cmdType, bool conditionAddUpdate, Func createCmd, Action updateCmd)
- {
- var cmd = Script.FirstOfType(cmdType);
- if (cmd is not null)
- {
- if (conditionAddUpdate)
- updateCmd(cmd);
else
{
- Script.Remove(cmd);
- cmd.Close();
+ if (cmdStartLoop is not null)
+ iInsert = cmdStartLoopIndex;
+ else
+ iInsert = (int)Script.Count - 2;
+ }
+
+ if (knownCustomAsmCommands.ContainsKey(link.CustomAsmAreaConfig))
+ {
+ var cmd = knownCustomAsmCommands[link.CustomAsmAreaConfig];
+ var cmdIndex = Script.IndexOf(cmd);
+ BehaviorscriptCommandFunctions.X0C.SetAsmPointer(cmd, asmPointer);
+
+ if (cmdIndex != -1)
+ {
+ var reinsert = false;
+
+ if (link.Loop && cmdIndex < cmdStartLoopIndex)
+ {
+ reinsert = true;
+ iInsert -= 1;
+ }
+ else if (!link.Loop && cmdIndex > cmdStartLoopIndex)
+ reinsert = true;
+
+ if (reinsert)
+ {
+ Script.Remove(cmd);
+ Script.Insert(iInsert, cmd);
+ }
+ }
+ }
+ else if (iInsert != -1)
+ {
+ var cmd = BehaviorscriptCommandFactory.Build_x0C(asmPointer);
+ Script.Insert(iInsert, cmd);
+ knownCustomAsmCommands.Add(link.CustomAsmAreaConfig, cmd);
}
}
- else if (conditionAddUpdate)
+
+ foreach (var kvp in knownCustomAsmCommands.ToArray())
{
- cmd = createCmd();
- Script.Insert(1, cmd);
+ if (!Config.CustomAsmLinks.Where(n => n.CustomAsmAreaConfig == kvp.Key).Any())
+ {
+ knownCustomAsmCommands.Remove(kvp.Key);
+ Script.RemoveIfContains(kvp.Value);
+ kvp.Value.Close();
+ }
}
}
-
- public void CopyPropertiesTo(Behavior dest)
- {
- // Copy Script
- TakeoverSettingsToScript();
- dest.Script.Close();
- dest.Script.AddRange(Script);
- dest.ParseScript();
-
- // Copy Configs
- dest.Config.Name = Config.Name;
- Config.ParamsInfo.CloneTo(dest.Config.ParamsInfo);
- }
-
}
+
+ private void AddUpdateRemoveCmd(BehaviorscriptCommandTypes cmdType, bool conditionAddUpdate, Func createCmd, Action updateCmd)
+ {
+ var cmd = Script.FirstOfType(cmdType);
+ if (cmd is not null)
+ {
+ if (conditionAddUpdate)
+ updateCmd(cmd);
+ else
+ {
+ Script.Remove(cmd);
+ cmd.Close();
+ }
+ }
+ else if (conditionAddUpdate)
+ {
+ cmd = createCmd();
+ Script.Insert(1, cmd);
+ }
+ }
+
+ public void CopyPropertiesTo(Behavior dest)
+ {
+ // Copy Script
+ TakeoverSettingsToScript();
+ dest.Script.Close();
+ dest.Script.AddRange(Script);
+ dest.ParseScript();
+
+ // Copy Configs
+ dest.Config.Name = Config.Name;
+ Config.ParamsInfo.CloneTo(dest.Config.ParamsInfo);
+ }
+
}
diff --git a/SM64Lib/Behaviors/BehaviorBank.cs b/SM64Lib/Behaviors/BehaviorBank.cs
index c0ab209..1abfb8d 100644
--- a/SM64Lib/Behaviors/BehaviorBank.cs
+++ b/SM64Lib/Behaviors/BehaviorBank.cs
@@ -1,220 +1,216 @@
using Newtonsoft.Json;
using SM64Lib.Data;
using SM64Lib.SegmentedBanking;
-using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using Z.Collections.Extensions;
-namespace SM64Lib.Behaviors
+namespace SM64Lib.Behaviors;
+
+public class BehaviorBank
{
- public class BehaviorBank
+ public BehaviorBankConfig Config { get; private set; }
+ public List Behaviors { get; } = new List();
+
+ [JsonIgnore]
+ public long Length
{
- public BehaviorBankConfig Config { get; private set; }
- public List Behaviors { get; } = new List();
+ get => Behaviors.Sum(n => n.Length);
+ }
- [JsonIgnore]
- public long Length
+ public BehaviorBank(BehaviorBankConfig config)
+ {
+ Config = config;
+ }
+
+ public void ReadBank(SegmentedBank seg, int offset)
+ {
+ ReadBank(seg, offset, false);
+ }
+
+ public void ReadVanillaBank(SegmentedBank seg)
+ {
+ ReadBank(seg, 0, true);
+ }
+
+ private void ReadBank(SegmentedBank seg, int offset, bool isVanilla)
+ {
+ var data = new BinaryStreamData(seg.Data);
+ data.Position = offset;
+ ReadBank(data, isVanilla, seg.Length, (sbyte)seg.BankID);
+ }
+
+ public void ReadBank(BinaryData data)
+ {
+ ReadBank(data, false, -1, -1);
+ }
+
+ private void ReadBank(BinaryData data, bool isVanilla, int endAddress, sbyte bankID)
+ {
+ // Clear current list
+ Behaviors.Clear();
+
+ if (isVanilla)
{
- get => Behaviors.Sum(n => n.Length);
+ while (data.Position <= endAddress - 0x10)
+ {
+ var conf = new BehaviorConfig();
+ Config.BehaviorConfigs.Add(conf);
+ readBehavior(conf);
+ }
+ }
+ else
+ {
+ foreach (var config in Config.BehaviorConfigs.OrderBy(n => n.BankAddress))
+ readBehavior(config);
}
- public BehaviorBank(BehaviorBankConfig config)
+ void readBehavior(BehaviorConfig config)
{
- Config = config;
- }
-
- public void ReadBank(SegmentedBank seg, int offset)
- {
- ReadBank(seg, offset, false);
- }
-
- public void ReadVanillaBank(SegmentedBank seg)
- {
- ReadBank(seg, 0, true);
- }
-
- private void ReadBank(SegmentedBank seg, int offset, bool isVanilla)
- {
- var data = new BinaryStreamData(seg.Data);
- data.Position = offset;
- ReadBank(data, isVanilla, seg.Length, (sbyte)seg.BankID);
- }
-
- public void ReadBank(BinaryData data)
- {
- ReadBank(data, false, -1, -1);
- }
-
- private void ReadBank(BinaryData data, bool isVanilla, int endAddress, sbyte bankID)
- {
- // Clear current list
- Behaviors.Clear();
+ int bankOffset;
+ Behavior behav = new Behavior(config);
if (isVanilla)
{
- while (data.Position <= endAddress - 0x10)
- {
- var conf = new BehaviorConfig();
- Config.BehaviorConfigs.Add(conf);
- readBehavior(conf);
- }
+ bankOffset = (int)data.Position;
+ config.BankAddress = (bankID << 24) | bankOffset;
+ behav.Config.IsVanilla = true;
}
else
{
- foreach (var config in Config.BehaviorConfigs.OrderBy(n => n.BankAddress))
- readBehavior(config);
+ bankOffset = config.BankAddress & 0xffffff;
+ if (!behav.Config.IsVanilla && !config.ID.HasID) config.ID.Generate();
}
- void readBehavior(BehaviorConfig config)
+ var lastBehav = Behaviors.LastOrDefault();
+
+ if (behav.Read(data, bankOffset))
{
- int bankOffset;
- Behavior behav = new Behavior(config);
+ if (isVanilla && lastBehav is not null && lastBehav.Config.IsVanilla && lastBehav.Config.FixedLength != -1)
+ lastBehav.Config.FixedLength = bankOffset - (lastBehav.Config.BankAddress & 0xffffff);
- if (isVanilla)
+ Behaviors.Add(behav);
+ }
+ }
+ }
+
+ public SegmentedBank WriteToSeg(byte bankID, int offset, RomManager rommgr)
+ {
+ var segStream = new MemoryStream();
+ var seg = new SegmentedBank(bankID, segStream);
+ int lastPos = WriteToSeg(seg, offset, rommgr);
+ seg.Length = General.HexRoundUp1(lastPos);
+ return seg;
+ }
+
+ public int WriteToSeg(SegmentedBank seg, int offset, RomManager rommgr)
+ {
+ var addressUpdates = new Dictionary();
+ var segStartAddress = seg.BankAddress | offset;
+ var data = new BinaryStreamData(seg.Data);
+ data.Position = offset;
+
+ if (Behaviors.Any())
+ {
+ // Save Behaviors to ROM
+ foreach (var behav in Behaviors)
+ {
+ var address = (int)data.Position;
+ var newBankAddress = (int)data.Position - offset + segStartAddress;
+ if (newBankAddress != behav.Config.BankAddress)
{
- bankOffset = (int)data.Position;
- config.BankAddress = (bankID << 24) | bankOffset;
- behav.Config.IsVanilla = true;
- }
- else
- {
- bankOffset = config.BankAddress & 0xffffff;
- if (!behav.Config.IsVanilla && !config.ID.HasID) config.ID.Generate();
- }
-
- var lastBehav = Behaviors.LastOrDefault();
-
- if (behav.Read(data, bankOffset))
- {
- if (isVanilla && lastBehav is not null && lastBehav.Config.IsVanilla && lastBehav.Config.FixedLength != -1)
- lastBehav.Config.FixedLength = bankOffset - (lastBehav.Config.BankAddress & 0xffffff);
-
- Behaviors.Add(behav);
+ if (behav.Config.BankAddress != -1)
+ addressUpdates.AddOrUpdate(behav.Config.BankAddress, newBankAddress);
+ behav.Config.BankAddress = newBankAddress;
}
+ behav.Write(data, (int)data.Position);
}
}
- public SegmentedBank WriteToSeg(byte bankID, int offset, RomManager rommgr)
- {
- var segStream = new MemoryStream();
- var seg = new SegmentedBank(bankID, segStream);
- int lastPos = WriteToSeg(seg, offset, rommgr);
- seg.Length = General.HexRoundUp1(lastPos);
- return seg;
- }
+ // Delete unused configs / Add new configs
+ Config.BehaviorConfigs.Clear();
+ Config.BehaviorConfigs.AddRange(Behaviors.Select(n => n.Config));
- public int WriteToSeg(SegmentedBank seg, int offset, RomManager rommgr)
- {
- var addressUpdates = new Dictionary();
- var segStartAddress = seg.BankAddress | offset;
- var data = new BinaryStreamData(seg.Data);
- data.Position = offset;
+ // Update addresses
+ UpdateBehaviorAddresses(rommgr, addressUpdates);
- if (Behaviors.Any())
+ return (int)data.Position;
+ }
+
+ private void UpdateBehaviorAddresses(RomManager rommgr, Dictionary addressUpdates)
+ {
+ if (Behaviors.Any() && rommgr is not null)
+ {
+ foreach (var lvl in rommgr.Levels)
{
- // Save Behaviors to ROM
- foreach (var behav in Behaviors)
+ foreach (var area in lvl.Areas)
{
- var address = (int)data.Position;
- var newBankAddress = (int)data.Position - offset + segStartAddress;
- if (newBankAddress != behav.Config.BankAddress)
+ foreach (var obj in area.Objects)
{
- if (behav.Config.BankAddress != -1)
- addressUpdates.AddOrUpdate(behav.Config.BankAddress, newBankAddress);
- behav.Config.BankAddress = newBankAddress;
- }
- behav.Write(data, (int)data.Position);
- }
- }
-
- // Delete unused configs / Add new configs
- Config.BehaviorConfigs.Clear();
- Config.BehaviorConfigs.AddRange(Behaviors.Select(n => n.Config));
-
- // Update addresses
- UpdateBehaviorAddresses(rommgr, addressUpdates);
-
- return (int)data.Position;
- }
-
- private void UpdateBehaviorAddresses(RomManager rommgr, Dictionary addressUpdates)
- {
- if (Behaviors.Any() && rommgr is not null)
- {
- foreach (var lvl in rommgr.Levels)
- {
- foreach (var area in lvl.Areas)
- {
- foreach (var obj in area.Objects)
+ var behavAddr = Levels.Script.Commands.clNormal3DObject.GetSegBehaviorAddr(obj);
+ foreach (var kvp in addressUpdates)
{
- var behavAddr = Levels.Script.Commands.clNormal3DObject.GetSegBehaviorAddr(obj);
- foreach (var kvp in addressUpdates)
- {
- if (behavAddr == kvp.Key)
- Levels.Script.Commands.clNormal3DObject.SetSegBehaviorAddr(obj, (uint)kvp.Value);
- }
+ if (behavAddr == kvp.Key)
+ Levels.Script.Commands.clNormal3DObject.SetSegBehaviorAddr(obj, (uint)kvp.Value);
}
}
}
}
}
+ }
- public void WriteBehaviorAddresss(RomManager rommgr)
+ public void WriteBehaviorAddresss(RomManager rommgr)
+ {
+ var data = rommgr.GetBinaryRom(FileAccess.ReadWrite);
+ WriteBehaviorAddresss(data);
+ data.Close();
+ }
+
+ public void WriteBehaviorAddresss(BinaryData data)
+ {
+ if (Behaviors.Any())
{
- var data = rommgr.GetBinaryRom(FileAccess.ReadWrite);
- WriteBehaviorAddresss(data);
- data.Close();
- }
-
- public void WriteBehaviorAddresss(BinaryData data)
- {
- if (Behaviors.Any())
- {
- foreach (var behav in Behaviors)
- {
- foreach (var dest in behav.BehaviorAddressDestinations)
- {
- data.Position = dest;
- data.Write(behav.Config.BankAddress);
- }
- }
- }
- }
-
- public Behavior GetBehaviorByID(string id)
- {
- return Behaviors.FirstOrDefault(n => n.Config.ID == id);
- }
-
- public Behavior GetBehaviorByBankAddress(int bankAddress)
- {
- return Behaviors.FirstOrDefault(n => n.Config.BankAddress == bankAddress);
- }
-
- public void CalculateBehaviorBankAddresses(int bankStartAddress, RomManager rommgr)
- {
- var length = 0;
- var addressUpdates = new Dictionary();
-
foreach (var behav in Behaviors)
{
- if (behav.Config.IsVanilla)
- length += behav.Config.FixedLength;
- else
+ foreach (var dest in behav.BehaviorAddressDestinations)
{
- var newBankAddress = bankStartAddress + length;
- addressUpdates.AddIfNotContainsKey(behav.Config.BankAddress, newBankAddress);
- behav.Config.BankAddress = newBankAddress;
- length += (int)behav.Script.Length;
+ data.Position = dest;
+ data.Write(behav.Config.BankAddress);
}
}
-
- // Update addresses
- UpdateBehaviorAddresses(rommgr, addressUpdates);
}
}
+
+ public Behavior GetBehaviorByID(string id)
+ {
+ return Behaviors.FirstOrDefault(n => n.Config.ID == id);
+ }
+
+ public Behavior GetBehaviorByBankAddress(int bankAddress)
+ {
+ return Behaviors.FirstOrDefault(n => n.Config.BankAddress == bankAddress);
+ }
+
+ public void CalculateBehaviorBankAddresses(int bankStartAddress, RomManager rommgr)
+ {
+ var length = 0;
+ var addressUpdates = new Dictionary();
+
+ foreach (var behav in Behaviors)
+ {
+ if (behav.Config.IsVanilla)
+ length += behav.Config.FixedLength;
+ else
+ {
+ var newBankAddress = bankStartAddress + length;
+ addressUpdates.AddIfNotContainsKey(behav.Config.BankAddress, newBankAddress);
+ behav.Config.BankAddress = newBankAddress;
+ length += (int)behav.Script.Length;
+ }
+ }
+
+ // Update addresses
+ UpdateBehaviorAddresses(rommgr, addressUpdates);
+ }
}
diff --git a/SM64Lib/Behaviors/BehaviorBankConfig.cs b/SM64Lib/Behaviors/BehaviorBankConfig.cs
index 48fef6f..218f4b9 100644
--- a/SM64Lib/Behaviors/BehaviorBankConfig.cs
+++ b/SM64Lib/Behaviors/BehaviorBankConfig.cs
@@ -1,36 +1,31 @@
using Newtonsoft.Json;
-using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-namespace SM64Lib.Behaviors
+namespace SM64Lib.Behaviors;
+
+public class BehaviorBankConfig
{
- public class BehaviorBankConfig
+ public bool IsVanilla { get; set; } = true;
+ public List BehaviorConfigs { get; } = new List();
+
+ [JsonProperty(nameof(Enabled))]
+ private bool enabled = false;
+ public void Enable() => enabled = true;
+ internal void Disable()
{
- public bool IsVanilla { get; set; } = true;
- public List BehaviorConfigs { get; } = new List();
+ enabled = false;
+ IsVanilla = true;
+ BehaviorConfigs.Clear();
+ }
- [JsonProperty(nameof(Enabled))]
- private bool enabled = false;
- public void Enable() => enabled = true;
- internal void Disable()
+ [JsonIgnore]
+ public bool Enabled
+ {
+ get
{
- enabled = false;
- IsVanilla = true;
- BehaviorConfigs.Clear();
- }
-
- [JsonIgnore]
- public bool Enabled
- {
- get
- {
- if (!enabled && !IsVanilla)
- enabled = true;
- return enabled;
- }
+ if (!enabled && !IsVanilla)
+ enabled = true;
+ return enabled;
}
}
}
diff --git a/SM64Lib/Behaviors/BehaviorConfig.cs b/SM64Lib/Behaviors/BehaviorConfig.cs
index 53e2cc2..944d915 100644
--- a/SM64Lib/Behaviors/BehaviorConfig.cs
+++ b/SM64Lib/Behaviors/BehaviorConfig.cs
@@ -1,39 +1,34 @@
using Newtonsoft.Json;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using Pilz.Cryptography;
using Pilz.Json.Converters;
+using System.Collections.Generic;
-namespace SM64Lib.Behaviors
+namespace SM64Lib.Behaviors;
+
+public class BehaviorConfig
{
- public class BehaviorConfig
+ internal delegate void RequestModelEventHandler(BehaviorConfig config, RequestBehaviorEventArgs request);
+ internal static event RequestModelEventHandler RequestBehavior;
+
+ [JsonConverter(typeof(UniquieIDStringJsonConverter))]
+ public UniquieID ID { get; set; } = new();
+ public int BankAddress { get; set; } = -1;
+ public bool IsVanilla { get; set; } = false;
+ public string Name { get; set; } = string.Empty;
+ public int FixedLength { get; set; } = -1;
+ public int ExpectedLength { get; set; } = -1;
+ public List CustomAsmLinks { get; } = new List();
+ public BehaviorParamsInfo ParamsInfo { get; } = new BehaviorParamsInfo();
+
+ public Behavior FindBehavior()
{
- internal delegate void RequestModelEventHandler(BehaviorConfig config, RequestBehaviorEventArgs request);
- internal static event RequestModelEventHandler RequestBehavior;
+ var args = new RequestBehaviorEventArgs();
+ RequestBehavior?.Invoke(this, args);
+ return args.Behavior;
+ }
- [JsonConverter(typeof(UniquieIDStringJsonConverter))]
- public UniquieID ID { get; set; } = new();
- public int BankAddress { get; set; } = -1;
- public bool IsVanilla { get; set; } = false;
- public string Name { get; set; } = string.Empty;
- public int FixedLength { get; set; } = -1;
- public int ExpectedLength { get; set; } = -1;
- public List CustomAsmLinks { get; } = new List();
- public BehaviorParamsInfo ParamsInfo { get; } = new BehaviorParamsInfo();
-
- public Behavior FindBehavior()
- {
- var args = new RequestBehaviorEventArgs();
- RequestBehavior?.Invoke(this, args);
- return args.Behavior;
- }
-
- internal class RequestBehaviorEventArgs
- {
- public Behavior Behavior { get; set; }
- }
+ internal class RequestBehaviorEventArgs
+ {
+ public Behavior Behavior { get; set; }
}
}
diff --git a/SM64Lib/Behaviors/BehaviorCreationTypes.cs b/SM64Lib/Behaviors/BehaviorCreationTypes.cs
index a626d09..cce8350 100644
--- a/SM64Lib/Behaviors/BehaviorCreationTypes.cs
+++ b/SM64Lib/Behaviors/BehaviorCreationTypes.cs
@@ -1,13 +1,6 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+namespace SM64Lib.Behaviors;
-namespace SM64Lib.Behaviors
+public enum BehaviorCreationTypes
{
- public enum BehaviorCreationTypes
- {
- SolidObject
- }
+ SolidObject
}
diff --git a/SM64Lib/Behaviors/BehaviorParamInfo.cs b/SM64Lib/Behaviors/BehaviorParamInfo.cs
index 8bd9927..30fb7eb 100644
--- a/SM64Lib/Behaviors/BehaviorParamInfo.cs
+++ b/SM64Lib/Behaviors/BehaviorParamInfo.cs
@@ -1,15 +1,10 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using System.Collections.Generic;
-namespace SM64Lib.Behaviors
+namespace SM64Lib.Behaviors;
+
+public class BehaviorParamInfo
{
- public class BehaviorParamInfo
- {
- public string Name { get; set; } = string.Empty;
- public string Description { get; set; } = string.Empty;
- public List Values { get; } = new List();
- }
+ public string Name { get; set; } = string.Empty;
+ public string Description { get; set; } = string.Empty;
+ public List Values { get; } = new List();
}
diff --git a/SM64Lib/Behaviors/BehaviorParamValue.cs b/SM64Lib/Behaviors/BehaviorParamValue.cs
index e76106b..0adad8b 100644
--- a/SM64Lib/Behaviors/BehaviorParamValue.cs
+++ b/SM64Lib/Behaviors/BehaviorParamValue.cs
@@ -1,14 +1,7 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+namespace SM64Lib.Behaviors;
-namespace SM64Lib.Behaviors
+public class BehaviorParamValue
{
- public class BehaviorParamValue
- {
- public string Name { get; set; } = "";
- public byte Value { get; set; } = 0;
- }
+ public string Name { get; set; } = "";
+ public byte Value { get; set; } = 0;
}
diff --git a/SM64Lib/Behaviors/BehaviorParamsInfo.cs b/SM64Lib/Behaviors/BehaviorParamsInfo.cs
index fe682f3..83e361e 100644
--- a/SM64Lib/Behaviors/BehaviorParamsInfo.cs
+++ b/SM64Lib/Behaviors/BehaviorParamsInfo.cs
@@ -1,16 +1,9 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+namespace SM64Lib.Behaviors;
-namespace SM64Lib.Behaviors
+public class BehaviorParamsInfo
{
- public class BehaviorParamsInfo
- {
- public BehaviorParamInfo Param1 { get; } = new();
- public BehaviorParamInfo Param2 { get; } = new();
- public BehaviorParamInfo Param3 { get; } = new();
- public BehaviorParamInfo Param4 { get; } = new();
- }
+ public BehaviorParamInfo Param1 { get; } = new();
+ public BehaviorParamInfo Param2 { get; } = new();
+ public BehaviorParamInfo Param3 { get; } = new();
+ public BehaviorParamInfo Param4 { get; } = new();
}
diff --git a/SM64Lib/Behaviors/CustomAsmAreaLinkOptions.cs b/SM64Lib/Behaviors/CustomAsmAreaLinkOptions.cs
index 1720f61..e34fe51 100644
--- a/SM64Lib/Behaviors/CustomAsmAreaLinkOptions.cs
+++ b/SM64Lib/Behaviors/CustomAsmAreaLinkOptions.cs
@@ -1,25 +1,19 @@
using Newtonsoft.Json;
using SM64Lib.ASM;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-namespace SM64Lib.Behaviors
+namespace SM64Lib.Behaviors;
+
+public class CustomAsmAreaLinkOptions
{
- public class CustomAsmAreaLinkOptions
+ // Temporary fix - Remove custom property code and make it auto property in v1.?
+ private CustomAsmAreaConfig customAsmAreaConfig;
+ public CustomAsmAreaConfig CustomAsmAreaConfig
{
- // Temporary fix - Remove custom property code and make it auto property in v1.?
- private CustomAsmAreaConfig customAsmAreaConfig;
- public CustomAsmAreaConfig CustomAsmAreaConfig
- {
- get => customAsmAreaConfig ?? CustomAsm?.Config;
- set => customAsmAreaConfig = value;
- }
- // Temporary fix for old files - Remove property in v1.?
- [JsonProperty]
- public CustomAsmArea CustomAsm { get; private set; }
- public bool Loop { get; set; }
+ get => customAsmAreaConfig ?? CustomAsm?.Config;
+ set => customAsmAreaConfig = value;
}
+ // Temporary fix for old files - Remove property in v1.?
+ [JsonProperty]
+ public CustomAsmArea CustomAsm { get; private set; }
+ public bool Loop { get; set; }
}
diff --git a/SM64Lib/Behaviors/Script/Behaviorscript.cs b/SM64Lib/Behaviors/Script/Behaviorscript.cs
index 57216a4..d016b68 100644
--- a/SM64Lib/Behaviors/Script/Behaviorscript.cs
+++ b/SM64Lib/Behaviors/Script/Behaviorscript.cs
@@ -1,106 +1,104 @@
using SM64Lib.Data;
using System;
-using System.Collections;
using System.Collections.Generic;
using System.Linq;
-namespace SM64Lib.Behaviors.Script
+namespace SM64Lib.Behaviors.Script;
+
+public class Behaviorscript : BehaviorscriptCommandCollection
{
- public class Behaviorscript : BehaviorscriptCommandCollection
+ public bool Read(BinaryData data, int address, bool detectJumpsAsEnd = false, bool ignoreEndCmds = false, int expectedLength = -1)
{
- public bool Read(BinaryData data, int address, bool detectJumpsAsEnd = false, bool ignoreEndCmds = false, int expectedLength = -1)
+ bool ende = false;
+ bool success = true;
+ var newCmds = new List();
+
+ data.Position = address;
+
+ if (expectedLength < 0)
+ expectedLength = (int)data.Length;
+ else
+ expectedLength += address;
+
+ while (!ende)
{
- bool ende = false;
- bool success = true;
- var newCmds = new List();
-
- data.Position = address;
-
- if (expectedLength < 0)
- expectedLength = (int)data.Length;
- else
- expectedLength += address;
-
- while (!ende)
+ if (expectedLength - data.Position >= 4)
{
- if (expectedLength - data.Position >= 4)
+ // Get command infos
+ var cmdType = (BehaviorscriptCommandTypes)data.ReadByte();
+ int cmdLength = BehaviorscriptCommand.GetCommandLength(cmdType);
+ var unknownCmd = cmdLength == -1;
+ bool isEndCmd = ignoreEndCmds ? false : (unknownCmd || BehaviorscriptCommand.IsEndCommand(cmdType, detectJumpsAsEnd));
+
+ if (!unknownCmd)
{
- // Get command infos
- var cmdType = (BehaviorscriptCommandTypes)data.ReadByte();
- int cmdLength = BehaviorscriptCommand.GetCommandLength(cmdType);
- var unknownCmd = cmdLength == -1;
- bool isEndCmd = ignoreEndCmds ? false : (unknownCmd || BehaviorscriptCommand.IsEndCommand(cmdType, detectJumpsAsEnd));
+ // Reset position
+ data.Position -= 1;
- if (!unknownCmd)
+ if (data.Position + cmdLength <= expectedLength)
{
- // Reset position
- data.Position -= 1;
+ // Read full command
+ byte[] buf = new byte[cmdLength];
+ data.Read(buf);
- if (data.Position + cmdLength <= expectedLength)
+ // Create & add command
+ try
{
- // Read full command
- byte[] buf = new byte[cmdLength];
- data.Read(buf);
-
- // Create & add command
- try
- {
- newCmds.Add(new BehaviorscriptCommand(buf));
- }
- catch (Exception)
- {
- success = false;
- }
-
- ende = isEndCmd;
+ newCmds.Add(new BehaviorscriptCommand(buf));
}
- else
- ende = true;
- }
- else
- {
- data.Position += 3;
+ catch (Exception)
+ {
+ success = false;
+ }
+
ende = isEndCmd;
}
+ else
+ ende = true;
}
else
- ende = true;
+ {
+ data.Position += 3;
+ ende = isEndCmd;
+ }
}
-
- // Add new Cmds
- if (success && newCmds.Any())
- {
- Close();
- AddRange(newCmds.ToArray());
- }
-
- return success;
+ else
+ ende = true;
}
- public int Write(BinaryData data, int address)
+ // Add new Cmds
+ if (success && newCmds.Any())
{
- data.Position = address;
-
- foreach (BehaviorscriptCommand command in this)
- {
- var cmdLength = BehaviorscriptCommand.GetCommandLength(command.CommandType);
- if (command.Length != cmdLength)
- command.SetLength(cmdLength);
- data.Write(command.ToArray());
- }
-
- return (int)data.Position - address;
- }
-
- public int IndexOfType(BehaviorscriptCommandTypes cmdType)
- {
- return IndexOf(this.FirstOrDefault(n => n.CommandType == cmdType));
- }
-
- public BehaviorscriptCommand FirstOfType(BehaviorscriptCommandTypes cmdType)
- {
- return (BehaviorscriptCommand)this.FirstOrDefault(n => n.CommandType == cmdType);
+ Close();
+ AddRange(newCmds.ToArray());
}
+ return success;
}
+
+ public int Write(BinaryData data, int address)
+ {
+ data.Position = address;
+
+ foreach (BehaviorscriptCommand command in this)
+ {
+ var cmdLength = BehaviorscriptCommand.GetCommandLength(command.CommandType);
+ if (command.Length != cmdLength)
+ command.SetLength(cmdLength);
+ data.Write(command.ToArray());
+ }
+
+ return (int)data.Position - address;
+ }
+
+ public int IndexOfType(BehaviorscriptCommandTypes cmdType)
+ {
+ return IndexOf(this.FirstOrDefault(n => n.CommandType == cmdType));
+ }
+
+ public BehaviorscriptCommand FirstOfType(BehaviorscriptCommandTypes cmdType)
+ {
+ return (BehaviorscriptCommand)this.FirstOrDefault(n => n.CommandType == cmdType);
+ }
+
}
\ No newline at end of file
diff --git a/SM64Lib/Behaviors/Script/BehaviorscriptCommand.cs b/SM64Lib/Behaviors/Script/BehaviorscriptCommand.cs
index 9e42486..094dc61 100644
--- a/SM64Lib/Behaviors/Script/BehaviorscriptCommand.cs
+++ b/SM64Lib/Behaviors/Script/BehaviorscriptCommand.cs
@@ -2,119 +2,118 @@
using Newtonsoft.Json;
using SM64Lib.Json;
-namespace SM64Lib.Behaviors.Script
+namespace SM64Lib.Behaviors.Script;
+
+[JsonConverter(typeof(BehaviorscriptCommandJsonConverter))]
+public class BehaviorscriptCommand : SM64Lib.Script.BaseCommand
{
- [JsonConverter(typeof(BehaviorscriptCommandJsonConverter))]
- public class BehaviorscriptCommand : SM64Lib.Script.BaseCommand
+
+ public override BehaviorscriptCommandTypes CommandType
{
-
- public override BehaviorscriptCommandTypes CommandType
+ get
{
- get
- {
- Position = 0;
- return (BehaviorscriptCommandTypes)ReadByte();
- }
-
- set
- {
- Position = 0;
- WriteByte((byte)value);
- }
+ Position = 0;
+ return (BehaviorscriptCommandTypes)ReadByte();
}
- public BehaviorscriptCommand() : base()
+ set
{
+ Position = 0;
+ WriteByte((byte)value);
}
-
- public BehaviorscriptCommand(byte[] cmd) : base(cmd)
- {
- }
-
- public BehaviorscriptCommand(string cmd) : base(cmd, true)
- {
- }
-
- public static int GetCommandLength(BehaviorscriptCommandTypes type)
- {
- switch (type)
- {
- case BehaviorscriptCommandTypes.x00_Start: return 4;
- case BehaviorscriptCommandTypes.x01_StateLoop: return 4;
- case BehaviorscriptCommandTypes.x02_JumpandLink: return 8;
- case BehaviorscriptCommandTypes.x03_Return: return 4;
- case BehaviorscriptCommandTypes.x04_Jump: return 8;
- case BehaviorscriptCommandTypes.x05_LoopN: return 4;
- case BehaviorscriptCommandTypes.x06_EndLoopN: return 4;
- case BehaviorscriptCommandTypes.x07_InfiniteLoop: return 4;
- case BehaviorscriptCommandTypes.x08_LoopStart: return 4;
- case BehaviorscriptCommandTypes.x09_LoopEnd: return 4;
- case BehaviorscriptCommandTypes.x0A_EndBehaviorscript: return 4;
- case BehaviorscriptCommandTypes.x0B_EndBehaviorscript_Unused: return 4;
- case BehaviorscriptCommandTypes.x0C_CallFunction: return 8;
- case BehaviorscriptCommandTypes.x0D_OffsetbyFloat: return 4;
- case BehaviorscriptCommandTypes.x0E_SettoFloat: return 4;
- case BehaviorscriptCommandTypes.x0F_OffsetbyInteger: return 4;
- case BehaviorscriptCommandTypes.x10_SettoInteger: return 4;
- case BehaviorscriptCommandTypes.x11_BitSet: return 4;
- case BehaviorscriptCommandTypes.x12_BitClear: return 4;
- case BehaviorscriptCommandTypes.x13_AddRNG: return 8;
- case BehaviorscriptCommandTypes.x14_ObjectType: return 8;
- case BehaviorscriptCommandTypes.x15_FloatMultiply: return 8;
- case BehaviorscriptCommandTypes.x16_FloatAdd: return 8;
- case BehaviorscriptCommandTypes.x17_AddRNG2: return 8;
- case BehaviorscriptCommandTypes.x18_NoOperation: return 4;
- case BehaviorscriptCommandTypes.x19_NoOperation: return 4;
- case BehaviorscriptCommandTypes.x1A_NoOperation: return 4;
- case BehaviorscriptCommandTypes.x1B_ChangeModelID: return 4;
- case BehaviorscriptCommandTypes.x1C_LoadChildObject: return 0xC;
- case BehaviorscriptCommandTypes.x1D_Deactivate: return 4;
- case BehaviorscriptCommandTypes.x1E_DroptoGround: return 4;
- case BehaviorscriptCommandTypes.x1F_UsedforWaves: return 4;
- case BehaviorscriptCommandTypes.x20_Unused: return 4;
- case BehaviorscriptCommandTypes.x21_SetBillboarding: return 4;
- case BehaviorscriptCommandTypes.x22_SetRenderInvisibleflag: return 4;
- case BehaviorscriptCommandTypes.x23_Collisioncylindersize: return 8;
- case BehaviorscriptCommandTypes.x24_Nothing: return 4;
- case BehaviorscriptCommandTypes.x25_StateCycle: return 4;
- case BehaviorscriptCommandTypes.x26_Loop: return 4;
- case BehaviorscriptCommandTypes.x27_SetWord: return 8;
- case BehaviorscriptCommandTypes.x28_Animates: return 4;
- case BehaviorscriptCommandTypes.x29_LoadChildObject: return 0xC;
- case BehaviorscriptCommandTypes.x2A_SetCollision: return 8;
- case BehaviorscriptCommandTypes.x2B_SetCollisionSphere: return 0xC;
- case BehaviorscriptCommandTypes.x2C_SpawnObject: return 0xC;
- case BehaviorscriptCommandTypes.x2D_SetInitPosition: return 4;
- case BehaviorscriptCommandTypes.x2E_SetHurtbox: return 8;
- case BehaviorscriptCommandTypes.x2F_SetInteraction: return 8;
- case BehaviorscriptCommandTypes.x30_SetGravity: return 0x14;
- case BehaviorscriptCommandTypes.x31_SetInteractionSubType: return 8;
- case BehaviorscriptCommandTypes.x32_ScaleObject: return 4;
- case BehaviorscriptCommandTypes.x33_ChildObjectChange: return 8;
- case BehaviorscriptCommandTypes.x34_TextureAnimateRate: return 4;
- case BehaviorscriptCommandTypes.x35_ClearGraphFlag: return 4;
- case BehaviorscriptCommandTypes.x36_SetValue: return 8;
- case BehaviorscriptCommandTypes.x37_SpawnSomething: return 8;
- default: return -1; //throw new System.Exception("Command type not found!");
- }
- }
-
- public static bool IsEndCommand(BehaviorscriptCommandTypes type, bool detectJumpsAsEnd = true)
- {
- switch (type)
- {
- case BehaviorscriptCommandTypes.x02_JumpandLink:
- case BehaviorscriptCommandTypes.x04_Jump:
- return detectJumpsAsEnd;
- case BehaviorscriptCommandTypes.x06_EndLoopN:
- case BehaviorscriptCommandTypes.x0A_EndBehaviorscript:
- case BehaviorscriptCommandTypes.x0B_EndBehaviorscript_Unused:
- case BehaviorscriptCommandTypes.x09_LoopEnd:
- return true;
- default:
- return false;
- }
- }
-
}
+
+ public BehaviorscriptCommand() : base()
+ {
+ }
+
+ public BehaviorscriptCommand(byte[] cmd) : base(cmd)
+ {
+ }
+
+ public BehaviorscriptCommand(string cmd) : base(cmd, true)
+ {
+ }
+
+ public static int GetCommandLength(BehaviorscriptCommandTypes type)
+ {
+ switch (type)
+ {
+ case BehaviorscriptCommandTypes.x00_Start: return 4;
+ case BehaviorscriptCommandTypes.x01_StateLoop: return 4;
+ case BehaviorscriptCommandTypes.x02_JumpandLink: return 8;
+ case BehaviorscriptCommandTypes.x03_Return: return 4;
+ case BehaviorscriptCommandTypes.x04_Jump: return 8;
+ case BehaviorscriptCommandTypes.x05_LoopN: return 4;
+ case BehaviorscriptCommandTypes.x06_EndLoopN: return 4;
+ case BehaviorscriptCommandTypes.x07_InfiniteLoop: return 4;
+ case BehaviorscriptCommandTypes.x08_LoopStart: return 4;
+ case BehaviorscriptCommandTypes.x09_LoopEnd: return 4;
+ case BehaviorscriptCommandTypes.x0A_EndBehaviorscript: return 4;
+ case BehaviorscriptCommandTypes.x0B_EndBehaviorscript_Unused: return 4;
+ case BehaviorscriptCommandTypes.x0C_CallFunction: return 8;
+ case BehaviorscriptCommandTypes.x0D_OffsetbyFloat: return 4;
+ case BehaviorscriptCommandTypes.x0E_SettoFloat: return 4;
+ case BehaviorscriptCommandTypes.x0F_OffsetbyInteger: return 4;
+ case BehaviorscriptCommandTypes.x10_SettoInteger: return 4;
+ case BehaviorscriptCommandTypes.x11_BitSet: return 4;
+ case BehaviorscriptCommandTypes.x12_BitClear: return 4;
+ case BehaviorscriptCommandTypes.x13_AddRNG: return 8;
+ case BehaviorscriptCommandTypes.x14_ObjectType: return 8;
+ case BehaviorscriptCommandTypes.x15_FloatMultiply: return 8;
+ case BehaviorscriptCommandTypes.x16_FloatAdd: return 8;
+ case BehaviorscriptCommandTypes.x17_AddRNG2: return 8;
+ case BehaviorscriptCommandTypes.x18_NoOperation: return 4;
+ case BehaviorscriptCommandTypes.x19_NoOperation: return 4;
+ case BehaviorscriptCommandTypes.x1A_NoOperation: return 4;
+ case BehaviorscriptCommandTypes.x1B_ChangeModelID: return 4;
+ case BehaviorscriptCommandTypes.x1C_LoadChildObject: return 0xC;
+ case BehaviorscriptCommandTypes.x1D_Deactivate: return 4;
+ case BehaviorscriptCommandTypes.x1E_DroptoGround: return 4;
+ case BehaviorscriptCommandTypes.x1F_UsedforWaves: return 4;
+ case BehaviorscriptCommandTypes.x20_Unused: return 4;
+ case BehaviorscriptCommandTypes.x21_SetBillboarding: return 4;
+ case BehaviorscriptCommandTypes.x22_SetRenderInvisibleflag: return 4;
+ case BehaviorscriptCommandTypes.x23_Collisioncylindersize: return 8;
+ case BehaviorscriptCommandTypes.x24_Nothing: return 4;
+ case BehaviorscriptCommandTypes.x25_StateCycle: return 4;
+ case BehaviorscriptCommandTypes.x26_Loop: return 4;
+ case BehaviorscriptCommandTypes.x27_SetWord: return 8;
+ case BehaviorscriptCommandTypes.x28_Animates: return 4;
+ case BehaviorscriptCommandTypes.x29_LoadChildObject: return 0xC;
+ case BehaviorscriptCommandTypes.x2A_SetCollision: return 8;
+ case BehaviorscriptCommandTypes.x2B_SetCollisionSphere: return 0xC;
+ case BehaviorscriptCommandTypes.x2C_SpawnObject: return 0xC;
+ case BehaviorscriptCommandTypes.x2D_SetInitPosition: return 4;
+ case BehaviorscriptCommandTypes.x2E_SetHurtbox: return 8;
+ case BehaviorscriptCommandTypes.x2F_SetInteraction: return 8;
+ case BehaviorscriptCommandTypes.x30_SetGravity: return 0x14;
+ case BehaviorscriptCommandTypes.x31_SetInteractionSubType: return 8;
+ case BehaviorscriptCommandTypes.x32_ScaleObject: return 4;
+ case BehaviorscriptCommandTypes.x33_ChildObjectChange: return 8;
+ case BehaviorscriptCommandTypes.x34_TextureAnimateRate: return 4;
+ case BehaviorscriptCommandTypes.x35_ClearGraphFlag: return 4;
+ case BehaviorscriptCommandTypes.x36_SetValue: return 8;
+ case BehaviorscriptCommandTypes.x37_SpawnSomething: return 8;
+ default: return -1; //throw new System.Exception("Command type not found!");
+ }
+ }
+
+ public static bool IsEndCommand(BehaviorscriptCommandTypes type, bool detectJumpsAsEnd = true)
+ {
+ switch (type)
+ {
+ case BehaviorscriptCommandTypes.x02_JumpandLink:
+ case BehaviorscriptCommandTypes.x04_Jump:
+ return detectJumpsAsEnd;
+ case BehaviorscriptCommandTypes.x06_EndLoopN:
+ case BehaviorscriptCommandTypes.x0A_EndBehaviorscript:
+ case BehaviorscriptCommandTypes.x0B_EndBehaviorscript_Unused:
+ case BehaviorscriptCommandTypes.x09_LoopEnd:
+ return true;
+ default:
+ return false;
+ }
+ }
+
}
\ No newline at end of file
diff --git a/SM64Lib/Behaviors/Script/BehaviorscriptCommandCollection.cs b/SM64Lib/Behaviors/Script/BehaviorscriptCommandCollection.cs
index f2a4c84..9f80c27 100644
--- a/SM64Lib/Behaviors/Script/BehaviorscriptCommandCollection.cs
+++ b/SM64Lib/Behaviors/Script/BehaviorscriptCommandCollection.cs
@@ -1,7 +1,6 @@
-namespace SM64Lib.Behaviors.Script
+namespace SM64Lib.Behaviors.Script;
+
+public class BehaviorscriptCommandCollection : SM64Lib.Script.BaseCommandCollection
{
- public class BehaviorscriptCommandCollection : SM64Lib.Script.BaseCommandCollection
- {
- }
}
\ No newline at end of file
diff --git a/SM64Lib/Behaviors/Script/BehaviorscriptCommandFactory.cs b/SM64Lib/Behaviors/Script/BehaviorscriptCommandFactory.cs
index 6383b0a..755a79b 100644
--- a/SM64Lib/Behaviors/Script/BehaviorscriptCommandFactory.cs
+++ b/SM64Lib/Behaviors/Script/BehaviorscriptCommandFactory.cs
@@ -1,32 +1,25 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+namespace SM64Lib.Behaviors.Script;
-namespace SM64Lib.Behaviors.Script
+public static class BehaviorscriptCommandFactory
{
- public static class BehaviorscriptCommandFactory
+ public static BehaviorscriptCommand Build_x2A(int collisionPointer = -1)
{
- public static BehaviorscriptCommand Build_x2A(int collisionPointer = -1)
- {
- var cmd = new BehaviorscriptCommand("2a 00 00 00 00 00 00 00");
- if (collisionPointer != -1)
- BehaviorscriptCommandFunctions.X2A.SetCollisionPointer(cmd, collisionPointer);
- return cmd;
- }
+ var cmd = new BehaviorscriptCommand("2a 00 00 00 00 00 00 00");
+ if (collisionPointer != -1)
+ BehaviorscriptCommandFunctions.X2A.SetCollisionPointer(cmd, collisionPointer);
+ return cmd;
+ }
- public static BehaviorscriptCommand Build_x08()
- {
- return new BehaviorscriptCommand("08 00 00 00");
- }
+ public static BehaviorscriptCommand Build_x08()
+ {
+ return new BehaviorscriptCommand("08 00 00 00");
+ }
- public static BehaviorscriptCommand Build_x0C(int asmPointer = -1)
- {
- var cmd = new BehaviorscriptCommand("0C 00 00 00 00 00 00 00");
- if (asmPointer != -1)
- BehaviorscriptCommandFunctions.X2A.SetCollisionPointer(cmd, asmPointer);
- return cmd;
- }
+ public static BehaviorscriptCommand Build_x0C(int asmPointer = -1)
+ {
+ var cmd = new BehaviorscriptCommand("0C 00 00 00 00 00 00 00");
+ if (asmPointer != -1)
+ BehaviorscriptCommandFunctions.X2A.SetCollisionPointer(cmd, asmPointer);
+ return cmd;
}
}
diff --git a/SM64Lib/Behaviors/Script/BehaviorscriptCommandFunctions.cs b/SM64Lib/Behaviors/Script/BehaviorscriptCommandFunctions.cs
index 5265762..4130a40 100644
--- a/SM64Lib/Behaviors/Script/BehaviorscriptCommandFunctions.cs
+++ b/SM64Lib/Behaviors/Script/BehaviorscriptCommandFunctions.cs
@@ -1,39 +1,31 @@
-using SM64Lib.Data;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+namespace SM64Lib.Behaviors.Script;
-namespace SM64Lib.Behaviors.Script
+public class BehaviorscriptCommandFunctions
{
- public class BehaviorscriptCommandFunctions
+ public class X2A
{
- public class X2A
+ public static int GetCollisionPointer(BehaviorscriptCommand cmd)
{
- public static int GetCollisionPointer(BehaviorscriptCommand cmd)
- {
- cmd.Position = 4;
- return cmd.ReadInt32();
- }
- public static void SetCollisionPointer(BehaviorscriptCommand cmd, int pointer)
- {
- cmd.Position = 4;
- cmd.Write(pointer);
- }
+ cmd.Position = 4;
+ return cmd.ReadInt32();
}
- public class X0C
+ public static void SetCollisionPointer(BehaviorscriptCommand cmd, int pointer)
{
- public static int GetAsmPointer(BehaviorscriptCommand cmd)
- {
- cmd.Position = 4;
- return cmd.ReadInt32();
- }
- public static void SetAsmPointer(BehaviorscriptCommand cmd, int pointer)
- {
- cmd.Position = 4;
- cmd.Write(pointer);
- }
+ cmd.Position = 4;
+ cmd.Write(pointer);
+ }
+ }
+ public class X0C
+ {
+ public static int GetAsmPointer(BehaviorscriptCommand cmd)
+ {
+ cmd.Position = 4;
+ return cmd.ReadInt32();
+ }
+ public static void SetAsmPointer(BehaviorscriptCommand cmd, int pointer)
+ {
+ cmd.Position = 4;
+ cmd.Write(pointer);
}
}
}
diff --git a/SM64Lib/Behaviors/Script/BehaviorscriptCommandTypes.cs b/SM64Lib/Behaviors/Script/BehaviorscriptCommandTypes.cs
index 9bcb9fd..ffd6f23 100644
--- a/SM64Lib/Behaviors/Script/BehaviorscriptCommandTypes.cs
+++ b/SM64Lib/Behaviors/Script/BehaviorscriptCommandTypes.cs
@@ -1,62 +1,61 @@
-namespace SM64Lib.Behaviors.Script
+namespace SM64Lib.Behaviors.Script;
+
+public enum BehaviorscriptCommandTypes
{
- public enum BehaviorscriptCommandTypes
- {
- x00_Start,
- x01_StateLoop,
- x02_JumpandLink,
- x03_Return,
- x04_Jump,
- x05_LoopN,
- x06_EndLoopN,
- x07_InfiniteLoop,
- x08_LoopStart,
- x09_LoopEnd,
- x0A_EndBehaviorscript,
- x0B_EndBehaviorscript_Unused,
- x0C_CallFunction,
- x0D_OffsetbyFloat,
- x0E_SettoFloat,
- x0F_OffsetbyInteger,
- x10_SettoInteger,
- x11_BitSet,
- x12_BitClear,
- x13_AddRNG,
- x14_ObjectType,
- x15_FloatMultiply,
- x16_FloatAdd,
- x17_AddRNG2,
- x18_NoOperation,
- x19_NoOperation,
- x1A_NoOperation,
- x1B_ChangeModelID,
- x1C_LoadChildObject,
- x1D_Deactivate,
- x1E_DroptoGround,
- x1F_UsedforWaves,
- x20_Unused,
- x21_SetBillboarding,
- x22_SetRenderInvisibleflag,
- x23_Collisioncylindersize,
- x24_Nothing,
- x25_StateCycle,
- x26_Loop,
- x27_SetWord,
- x28_Animates,
- x29_LoadChildObject,
- x2A_SetCollision,
- x2B_SetCollisionSphere,
- x2C_SpawnObject,
- x2D_SetInitPosition,
- x2E_SetHurtbox,
- x2F_SetInteraction,
- x30_SetGravity,
- x31_SetInteractionSubType,
- x32_ScaleObject,
- x33_ChildObjectChange,
- x34_TextureAnimateRate,
- x35_ClearGraphFlag,
- x36_SetValue,
- x37_SpawnSomething
- }
+ x00_Start,
+ x01_StateLoop,
+ x02_JumpandLink,
+ x03_Return,
+ x04_Jump,
+ x05_LoopN,
+ x06_EndLoopN,
+ x07_InfiniteLoop,
+ x08_LoopStart,
+ x09_LoopEnd,
+ x0A_EndBehaviorscript,
+ x0B_EndBehaviorscript_Unused,
+ x0C_CallFunction,
+ x0D_OffsetbyFloat,
+ x0E_SettoFloat,
+ x0F_OffsetbyInteger,
+ x10_SettoInteger,
+ x11_BitSet,
+ x12_BitClear,
+ x13_AddRNG,
+ x14_ObjectType,
+ x15_FloatMultiply,
+ x16_FloatAdd,
+ x17_AddRNG2,
+ x18_NoOperation,
+ x19_NoOperation,
+ x1A_NoOperation,
+ x1B_ChangeModelID,
+ x1C_LoadChildObject,
+ x1D_Deactivate,
+ x1E_DroptoGround,
+ x1F_UsedforWaves,
+ x20_Unused,
+ x21_SetBillboarding,
+ x22_SetRenderInvisibleflag,
+ x23_Collisioncylindersize,
+ x24_Nothing,
+ x25_StateCycle,
+ x26_Loop,
+ x27_SetWord,
+ x28_Animates,
+ x29_LoadChildObject,
+ x2A_SetCollision,
+ x2B_SetCollisionSphere,
+ x2C_SpawnObject,
+ x2D_SetInitPosition,
+ x2E_SetHurtbox,
+ x2F_SetInteraction,
+ x30_SetGravity,
+ x31_SetInteractionSubType,
+ x32_ScaleObject,
+ x33_ChildObjectChange,
+ x34_TextureAnimateRate,
+ x35_ClearGraphFlag,
+ x36_SetValue,
+ x37_SpawnSomething
}
\ No newline at end of file
diff --git a/SM64Lib/Configuration/CollisionBasicConfig.cs b/SM64Lib/Configuration/CollisionBasicConfig.cs
index b21fded..38ee63c 100644
--- a/SM64Lib/Configuration/CollisionBasicConfig.cs
+++ b/SM64Lib/Configuration/CollisionBasicConfig.cs
@@ -1,22 +1,18 @@
using Newtonsoft.Json;
-using System;
using System.Collections.Generic;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-namespace SM64Lib.Configuration
+namespace SM64Lib.Configuration;
+
+public class CollisionBasicConfig
{
- public class CollisionBasicConfig
- {
- private List collisionTypesWithParams = new List()
- { 4, 14, 44, 36, 37, 39, 45 };
+ private List collisionTypesWithParams = new List()
+ { 4, 14, 44, 36, 37, 39, 45 };
- [JsonProperty("CollisionTypesWithParamsV2", ObjectCreationHandling = ObjectCreationHandling.Replace)]
- public List CollisionTypesWithParams
- {
- get => collisionTypesWithParams;
- private set => collisionTypesWithParams = value.Distinct().ToList();
- }
+ [JsonProperty("CollisionTypesWithParamsV2", ObjectCreationHandling = ObjectCreationHandling.Replace)]
+ public List CollisionTypesWithParams
+ {
+ get => collisionTypesWithParams;
+ private set => collisionTypesWithParams = value.Distinct().ToList();
}
}
diff --git a/SM64Lib/Configuration/CustomModelConfig.cs b/SM64Lib/Configuration/CustomModelConfig.cs
index 38067a7..89b3842 100644
--- a/SM64Lib/Configuration/CustomModelConfig.cs
+++ b/SM64Lib/Configuration/CustomModelConfig.cs
@@ -1,31 +1,30 @@
using Newtonsoft.Json;
-using SM64Lib.Objects.ModelBanks;
-using System.Collections.Generic;
using Pilz.Cryptography;
using Pilz.Json.Converters;
+using SM64Lib.Objects.ModelBanks;
+using System.Collections.Generic;
-namespace SM64Lib.Configuration
+namespace SM64Lib.Configuration;
+
+public class CustomModelConfig
{
- public class CustomModelConfig
+ internal delegate void RequestModelEventHandler(CustomModelConfig config, RequestModelEventArgs request);
+ internal static event RequestModelEventHandler RequestModel;
+
+ [JsonConverter(typeof(UniquieIDStringJsonConverter))]
+ public UniquieID ID { get; set; } = new();
+ public string Name { get; set; } = string.Empty;
+ public List CollisionPointerDestinations { get; private set; } = new List();
+
+ public CustomModel FindModel()
{
- internal delegate void RequestModelEventHandler(CustomModelConfig config, RequestModelEventArgs request);
- internal static event RequestModelEventHandler RequestModel;
+ var args = new RequestModelEventArgs();
+ RequestModel?.Invoke(this, args);
+ return args.Model;
+ }
- [JsonConverter(typeof(UniquieIDStringJsonConverter))]
- public UniquieID ID { get; set; } = new();
- public string Name { get; set; } = string.Empty;
- public List CollisionPointerDestinations { get; private set; } = new List();
-
- public CustomModel FindModel()
- {
- var args = new RequestModelEventArgs();
- RequestModel?.Invoke(this, args);
- return args.Model;
- }
-
- internal class RequestModelEventArgs
- {
- public CustomModel Model { get; set; }
- }
+ internal class RequestModelEventArgs
+ {
+ public CustomModel Model { get; set; }
}
}
\ No newline at end of file
diff --git a/SM64Lib/Configuration/LevelAreaConfig.cs b/SM64Lib/Configuration/LevelAreaConfig.cs
index ac99b0f..338c0a6 100644
--- a/SM64Lib/Configuration/LevelAreaConfig.cs
+++ b/SM64Lib/Configuration/LevelAreaConfig.cs
@@ -1,10 +1,9 @@
using System.Collections.Generic;
-namespace SM64Lib.Configuration
+namespace SM64Lib.Configuration;
+
+public class LevelAreaConfig
{
- public class LevelAreaConfig
- {
- public string AreaName { get; set; }
- public Dictionary ScrollingNames { get; set; } = new Dictionary();
- }
+ public string AreaName { get; set; }
+ public Dictionary ScrollingNames { get; set; } = new Dictionary();
}
\ No newline at end of file
diff --git a/SM64Lib/Configuration/LevelConfig.cs b/SM64Lib/Configuration/LevelConfig.cs
index d761a2b..8743b88 100644
--- a/SM64Lib/Configuration/LevelConfig.cs
+++ b/SM64Lib/Configuration/LevelConfig.cs
@@ -1,26 +1,25 @@
using System.Collections.Generic;
-namespace SM64Lib.Configuration
-{
- public class LevelConfig
- {
- public string LevelName { get; set; }
- public bool EnableLocalObjectBank { get; set; } = false;
- public ObjectModelConfig LocalObjectBank { get; set; } = new ObjectModelConfig();
- public Dictionary AreaConfigs { get; private set; } = new Dictionary();
+namespace SM64Lib.Configuration;
- public LevelAreaConfig GetLevelAreaConfig(byte areaID)
+public class LevelConfig
+{
+ public string LevelName { get; set; }
+ public bool EnableLocalObjectBank { get; set; } = false;
+ public ObjectModelConfig LocalObjectBank { get; set; } = new ObjectModelConfig();
+ public Dictionary AreaConfigs { get; private set; } = new Dictionary();
+
+ public LevelAreaConfig GetLevelAreaConfig(byte areaID)
+ {
+ if (AreaConfigs.ContainsKey(areaID))
{
- if (AreaConfigs.ContainsKey(areaID))
- {
- return AreaConfigs[areaID];
- }
- else
- {
- var conf = new LevelAreaConfig();
- AreaConfigs.Add(areaID, conf);
- return conf;
- }
+ return AreaConfigs[areaID];
+ }
+ else
+ {
+ var conf = new LevelAreaConfig();
+ AreaConfigs.Add(areaID, conf);
+ return conf;
}
}
}
\ No newline at end of file
diff --git a/SM64Lib/Configuration/MusicConfiguration.cs b/SM64Lib/Configuration/MusicConfiguration.cs
index be25ccd..03ac8b2 100644
--- a/SM64Lib/Configuration/MusicConfiguration.cs
+++ b/SM64Lib/Configuration/MusicConfiguration.cs
@@ -1,9 +1,8 @@
using System.Collections.Generic;
-namespace SM64Lib.Configuration
+namespace SM64Lib.Configuration;
+
+public class MusicConfiguration
{
- public class MusicConfiguration
- {
- public List SqeuenceNames { get; private set; } = new List();
- }
+ public List SqeuenceNames { get; private set; } = new List();
}
\ No newline at end of file
diff --git a/SM64Lib/Configuration/NPCConfig.cs b/SM64Lib/Configuration/NPCConfig.cs
index d14d6d6..863dfa9 100644
--- a/SM64Lib/Configuration/NPCConfig.cs
+++ b/SM64Lib/Configuration/NPCConfig.cs
@@ -1,13 +1,6 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+namespace SM64Lib.Configuration;
-namespace SM64Lib.Configuration
+public class NPCConfig
{
- public class NPCConfig
- {
- public bool Enabled3DCoins { get; set; } = false;
- }
+ public bool Enabled3DCoins { get; set; } = false;
}
diff --git a/SM64Lib/Configuration/ObjectModelConfig.cs b/SM64Lib/Configuration/ObjectModelConfig.cs
index d28d25e..f2bb2ad 100644
--- a/SM64Lib/Configuration/ObjectModelConfig.cs
+++ b/SM64Lib/Configuration/ObjectModelConfig.cs
@@ -1,20 +1,19 @@
using System.Collections.Generic;
-namespace SM64Lib.Configuration
+namespace SM64Lib.Configuration;
+
+public class ObjectModelConfig
{
- public class ObjectModelConfig
+ public Dictionary CustomObjectConfigs { get; private set; } = new Dictionary();
+
+ public CustomModelConfig GetCustomObjectConfig(int id)
{
- public Dictionary CustomObjectConfigs { get; private set; } = new Dictionary();
-
- public CustomModelConfig GetCustomObjectConfig(int id)
+ CustomModelConfig conf = null;
+ if (!CustomObjectConfigs.TryGetValue(id, out conf))
{
- CustomModelConfig conf = null;
- if (!CustomObjectConfigs.TryGetValue(id, out conf))
- {
- conf = new CustomModelConfig();
- }
-
- return conf;
+ conf = new CustomModelConfig();
}
+
+ return conf;
}
}
\ No newline at end of file
diff --git a/SM64Lib/Configuration/PatchingConfig.cs b/SM64Lib/Configuration/PatchingConfig.cs
index 78b30b4..82874a5 100644
--- a/SM64Lib/Configuration/PatchingConfig.cs
+++ b/SM64Lib/Configuration/PatchingConfig.cs
@@ -1,15 +1,9 @@
using Pilz.IO;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-namespace SM64Lib.Configuration
+namespace SM64Lib.Configuration;
+
+public class PatchingConfig
{
- public class PatchingConfig
- {
- public EmbeddedFilesContainer TweakBackups { get; } = new EmbeddedFilesContainer();
- public bool Patched2DCamera { get; set; } = false;
- }
+ public EmbeddedFilesContainer TweakBackups { get; } = new EmbeddedFilesContainer();
+ public bool Patched2DCamera { get; set; } = false;
}
diff --git a/SM64Lib/Configuration/RomConfig.cs b/SM64Lib/Configuration/RomConfig.cs
index 6fc300e..c590005 100644
--- a/SM64Lib/Configuration/RomConfig.cs
+++ b/SM64Lib/Configuration/RomConfig.cs
@@ -1,78 +1,76 @@
-using System.Collections.Generic;
+using global::Newtonsoft.Json.Linq;
using global::System.IO;
-using Microsoft.VisualBasic.CompilerServices;
-using global::Newtonsoft.Json.Linq;
using Newtonsoft.Json;
+using SM64Lib.ASM;
using SM64Lib.Behaviors;
using SM64Lib.Objects.ObjectBanks;
-using SM64Lib.ASM;
using SM64Lib.Objects.ObjectBanks.Data;
using System;
+using System.Collections.Generic;
-namespace SM64Lib.Configuration
+namespace SM64Lib.Configuration;
+
+public class RomConfig
{
- public class RomConfig
+ // Levels
+ public Dictionary LevelConfigs { get; } = new Dictionary();
+
+ // Global Banks
+ [JsonProperty("GlobalObjectBankConfig")]
+ public ObjectModelConfig GlobalModelBank { get; } = new ObjectModelConfig();
+ public CustomAsmBankConfig GlobalCustomAsmBank { get; } = new CustomAsmBankConfig();
+ public BehaviorBankConfig GlobalBehaviorBank { get; } = new BehaviorBankConfig();
+ public CustomObjectCollection GlobalObjectBank { get; } = new CustomObjectCollection();
+
+ // Music
+ public MusicConfiguration MusicConfig { get; } = new MusicConfiguration();
+
+ // Texts
+ public Text.Profiles.TextProfileInfo TextProfileInfo { get; set; } = null;
+
+ // Patching
+ public PatchingConfig PatchingConfig { get; set; } = new PatchingConfig();
+
+ // Other
+ public ScrollTexConfig ScrollTexConfig { get; set; } = new ScrollTexConfig();
+ public ObjectBankDataListCollection ObjectBankInfoData { get; } = new ObjectBankDataListCollection();
+ public NPCConfig NPCConfig { get; } = new NPCConfig();
+ public CollisionBasicConfig CollisionBaseConfig { get; } = new CollisionBasicConfig();
+
+ ///
+ /// Contains custom configuration that isn't used by SM64Lib. E.g. Extra Object Combos.
+ ///
+ public Dictionary CustomConfigs { get; } = new Dictionary();
+
+ // F e a t u r e s
+
+ public LevelConfig GetLevelConfig(ushort levelID)
{
- // Levels
- public Dictionary LevelConfigs { get; } = new Dictionary();
-
- // Global Banks
- [JsonProperty("GlobalObjectBankConfig")]
- public ObjectModelConfig GlobalModelBank { get; } = new ObjectModelConfig();
- public CustomAsmBankConfig GlobalCustomAsmBank { get; } = new CustomAsmBankConfig();
- public BehaviorBankConfig GlobalBehaviorBank { get; } = new BehaviorBankConfig();
- public CustomObjectCollection GlobalObjectBank { get; } = new CustomObjectCollection();
-
- // Music
- public MusicConfiguration MusicConfig { get; } = new MusicConfiguration();
-
- // Texts
- public Text.Profiles.TextProfileInfo TextProfileInfo { get; set; } = null;
-
- // Patching
- public PatchingConfig PatchingConfig { get; set; } = new PatchingConfig();
-
- // Other
- public ScrollTexConfig ScrollTexConfig { get; set; } = new ScrollTexConfig();
- public ObjectBankDataListCollection ObjectBankInfoData { get; } = new ObjectBankDataListCollection();
- public NPCConfig NPCConfig { get; } = new NPCConfig();
- public CollisionBasicConfig CollisionBaseConfig { get; } = new CollisionBasicConfig();
-
- ///
- /// Contains custom configuration that isn't used by SM64Lib. E.g. Extra Object Combos.
- ///
- public Dictionary CustomConfigs { get; } = new Dictionary();
-
- // F e a t u r e s
-
- public LevelConfig GetLevelConfig(ushort levelID)
+ if (LevelConfigs.ContainsKey(Convert.ToByte(levelID)))
{
- if (LevelConfigs.ContainsKey(Convert.ToByte(levelID)))
- {
- return LevelConfigs[Convert.ToByte(levelID)];
- }
- else
- {
- var conf = new LevelConfig();
- LevelConfigs.Add(Convert.ToByte(levelID), conf);
- return conf;
- }
+ return LevelConfigs[Convert.ToByte(levelID)];
}
-
- // L o a d / S a v e
-
- public static RomConfig Load(string filePath)
+ else
{
- var serializer = JsonSerializer.CreateDefault();
- serializer.PreserveReferencesHandling = PreserveReferencesHandling.All;
- return JObject.Parse(File.ReadAllText(filePath)).ToObject(serializer);
- }
-
- public void Save(string filePath)
- {
- var serializer = JsonSerializer.CreateDefault();
- serializer.PreserveReferencesHandling = PreserveReferencesHandling.All;
- File.WriteAllText(filePath, JObject.FromObject(this, serializer).ToString());
+ var conf = new LevelConfig();
+ LevelConfigs.Add(Convert.ToByte(levelID), conf);
+ return conf;
}
}
+
+ // L o a d / S a v e
+
+ public static RomConfig Load(string filePath)
+ {
+ var serializer = JsonSerializer.CreateDefault();
+ serializer.PreserveReferencesHandling = PreserveReferencesHandling.All;
+ return JObject.Parse(File.ReadAllText(filePath)).ToObject(serializer);
+ }
+
+ public void Save(string filePath)
+ {
+ var serializer = JsonSerializer.CreateDefault();
+ serializer.PreserveReferencesHandling = PreserveReferencesHandling.All;
+ File.WriteAllText(filePath, JObject.FromObject(this, serializer).ToString());
+ }
}
\ No newline at end of file
diff --git a/SM64Lib/Configuration/ScrollTexConfig.cs b/SM64Lib/Configuration/ScrollTexConfig.cs
index 898d160..e800c69 100644
--- a/SM64Lib/Configuration/ScrollTexConfig.cs
+++ b/SM64Lib/Configuration/ScrollTexConfig.cs
@@ -1,14 +1,7 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+namespace SM64Lib.Configuration;
-namespace SM64Lib.Configuration
+public class ScrollTexConfig
{
- public class ScrollTexConfig
- {
- public bool UseCustomBehavior { get; set; } = false;
- public int CustomBehaviorAddress { get; set; } = -1;
- }
+ public bool UseCustomBehavior { get; set; } = false;
+ public int CustomBehaviorAddress { get; set; } = -1;
}
diff --git a/SM64Lib/Data/BinaryArrayData.cs b/SM64Lib/Data/BinaryArrayData.cs
index 8cfd2d8..1032e31 100644
--- a/SM64Lib/Data/BinaryArrayData.cs
+++ b/SM64Lib/Data/BinaryArrayData.cs
@@ -1,28 +1,27 @@
using global::System.IO;
-namespace SM64Lib.Data
+namespace SM64Lib.Data;
+
+public class BinaryArrayData : BinaryStreamData
{
- public class BinaryArrayData : BinaryStreamData
+ public FileAccess RomAccess { get; private set; } = FileAccess.Read;
+
+ public BinaryArrayData(byte[] buffer) : base(new MemoryStream(buffer))
{
- public FileAccess RomAccess { get; private set; } = FileAccess.Read;
-
- public BinaryArrayData(byte[] buffer) : base(new MemoryStream(buffer))
- {
- }
-
- // Inherits BinaryData
-
- // Private ReadOnly myBaseStream As Stream
-
- // Public ReadOnly Property RomAccess As FileAccess = FileAccess.Read
-
- // Public Sub New(buffer As Byte())
- // myBaseStream = New MemoryStream(buffer)
- // End Sub
-
- // Protected Overrides Function GetBaseStream() As Stream
- // Return myBaseStream
- // End Function
-
}
+
+ // Inherits BinaryData
+
+ // Private ReadOnly myBaseStream As Stream
+
+ // Public ReadOnly Property RomAccess As FileAccess = FileAccess.Read
+
+ // Public Sub New(buffer As Byte())
+ // myBaseStream = New MemoryStream(buffer)
+ // End Sub
+
+ // Protected Overrides Function GetBaseStream() As Stream
+ // Return myBaseStream
+ // End Function
+
}
\ No newline at end of file
diff --git a/SM64Lib/Data/BinaryData.cs b/SM64Lib/Data/BinaryData.cs
index 6fd8ff1..6523a04 100644
--- a/SM64Lib/Data/BinaryData.cs
+++ b/SM64Lib/Data/BinaryData.cs
@@ -2,279 +2,278 @@
using SM64Lib.Data.System;
using System;
-namespace SM64Lib.Data
+namespace SM64Lib.Data;
+
+public abstract class BinaryData : IDisposable
{
- public abstract class BinaryData : IDisposable
+ public delegate void AnyBinaryDataEventHandler(BinaryData data);
+
+ public static event AnyBinaryDataEventHandler AnyBinaryDataOpened;
+ public static event AnyBinaryDataEventHandler AnyBinaryDataClosing;
+ public static event AnyBinaryDataEventHandler AnyBinaryDataClosed;
+ public static event AnyBinaryDataDisposedEventHandler AnyBinaryDataDisposed;
+
+ public delegate void AnyBinaryDataDisposedEventHandler();
+
+ private Stream _BaseStream = null;
+ private BinaryWriter _writer = null;
+ private BinaryReader _reader = null;
+
+ public RomManager RomManager { get; private set; }
+
+ protected abstract Stream GetBaseStream();
+
+ protected BinaryWriter Writer
{
- public delegate void AnyBinaryDataEventHandler(BinaryData data);
-
- public static event AnyBinaryDataEventHandler AnyBinaryDataOpened;
- public static event AnyBinaryDataEventHandler AnyBinaryDataClosing;
- public static event AnyBinaryDataEventHandler AnyBinaryDataClosed;
- public static event AnyBinaryDataDisposedEventHandler AnyBinaryDataDisposed;
-
- public delegate void AnyBinaryDataDisposedEventHandler();
-
- private Stream _BaseStream = null;
- private BinaryWriter _writer = null;
- private BinaryReader _reader = null;
-
- public RomManager RomManager { get; private set; }
-
- protected abstract Stream GetBaseStream();
-
- protected BinaryWriter Writer
+ get
{
- get
+ if (_writer is null)
{
- if (_writer is null)
- {
- _writer = new BinaryWriter(BaseStream);
- }
-
- return _writer;
- }
- }
-
- protected BinaryReader Reader
- {
- get
- {
- if (_reader is null)
- {
- _reader = new BinaryReader(BaseStream);
- }
-
- return _reader;
- }
- }
-
- public long Position
- {
- get
- {
- return BaseStream.Position;
+ _writer = new BinaryWriter(BaseStream);
}
- set
- {
- BaseStream.Position = value;
- }
- }
-
- public long Length
- {
- get
- {
- return BaseStream.Length;
- }
- }
-
- public Stream BaseStream
- {
- get
- {
- if (_BaseStream is null)
- {
- _BaseStream = GetBaseStream();
- RaiseAnyBinaryDataOpened(this);
- }
-
- return _BaseStream;
- }
- }
-
- ~BinaryData()
- {
- AnyBinaryDataDisposed?.Invoke();
- }
-
- public void RoundUpPosition()
- {
- Position = General.HexRoundUp1(Position);
- }
-
- public void RoundUpPosition(int add)
- {
- Position = General.HexRoundUp1(Position + add);
- }
-
- protected void SetRomManager(RomManager rommgr)
- {
- RomManager = rommgr;
- }
-
- public void Write(sbyte value)
- {
- Writer.Write(value);
- }
-
- public void Write(byte value)
- {
- Writer.Write(value);
- }
-
- public void WriteByte(byte value)
- {
- Write(value);
- }
-
- public void Write(short value)
- {
- Writer.Write(SwapInts.SwapInt16(value));
- }
-
- public void Write(ushort value)
- {
- Writer.Write(SwapInts.SwapUInt16(value));
- }
-
- public void Write(int value)
- {
- Writer.Write(SwapInts.SwapInt32(value));
- }
-
- public void Write(uint value)
- {
- Writer.Write(SwapInts.SwapUInt32(value));
- }
-
- public void Write(long value)
- {
- Writer.Write(SwapInts.SwapInt64(value));
- }
-
- public void Write(ulong value)
- {
- Writer.Write(SwapInts.SwapUInt64(value));
- }
-
- public void Write(float value, bool isHalf = false)
- {
- if (isHalf)
- Writer.Write(SwapInts.SwapHalf(value));
- else
- Writer.Write(SwapInts.SwapFloat32(value));
- }
-
- public void Write(string value)
- {
- Writer.Write(value);
- }
-
- public void Write(byte[] buffer)
- {
- Write(buffer, 0, buffer.Length);
- }
-
- public void Write(byte[] buffer, int index, int count)
- {
- Writer.Write(buffer, index, count);
- }
-
- public byte ReadByte()
- {
- return Reader.ReadByte();
- }
-
- public sbyte ReadSByte()
- {
- return Reader.ReadSByte();
- }
-
- public short ReadInt16()
- {
- return SwapInts.SwapInt16(Reader.ReadInt16());
- }
-
- public ushort ReadUInt16()
- {
- return SwapInts.SwapUInt16(Reader.ReadUInt16());
- }
-
- public int ReadInt32()
- {
- return SwapInts.SwapInt32(Reader.ReadInt32());
- }
-
- public uint ReadUInt32()
- {
- return SwapInts.SwapUInt32(Reader.ReadUInt32());
- }
-
- public long ReadInt64()
- {
- return SwapInts.SwapInt64(Reader.ReadInt64());
- }
-
- public ulong ReadUInt64()
- {
- return SwapInts.SwapUInt64(Reader.ReadUInt64());
- }
-
- public float ReadSingle()
- {
- return SwapInts.SwapFloat32(Reader.ReadSingle());
- }
-
- public string ReadString()
- {
- return Reader.ReadString();
- }
-
- public void Read(byte[] buffer)
- {
- Read(buffer, 0, buffer.Length);
- }
-
- public void Read(byte[] buffer, int index, int count)
- {
- Reader.Read(buffer, index, count);
- }
-
- public byte[] Read(int count)
- {
- var buf = new byte[count];
- Read(buf, 0, count);
- return buf;
- }
-
- public void Close()
- {
- AnyBinaryDataClosing?.Invoke(this);
- BaseStream.Close();
- AnyBinaryDataClosed?.Invoke(this);
- }
-
- public bool CanRead
- {
- get
- {
- return BaseStream.CanRead;
- }
- }
-
- public bool CanWrite
- {
- get
- {
- return BaseStream.CanWrite;
- }
- }
-
- public void SetLength(long length)
- {
- BaseStream.SetLength(length);
- }
-
- internal static void RaiseAnyBinaryDataOpened(BinaryData data)
- {
- AnyBinaryDataOpened?.Invoke(data);
- }
-
- public void Dispose()
- {
- Close();
+ return _writer;
}
}
+
+ protected BinaryReader Reader
+ {
+ get
+ {
+ if (_reader is null)
+ {
+ _reader = new BinaryReader(BaseStream);
+ }
+
+ return _reader;
+ }
+ }
+
+ public long Position
+ {
+ get
+ {
+ return BaseStream.Position;
+ }
+
+ set
+ {
+ BaseStream.Position = value;
+ }
+ }
+
+ public long Length
+ {
+ get
+ {
+ return BaseStream.Length;
+ }
+ }
+
+ public Stream BaseStream
+ {
+ get
+ {
+ if (_BaseStream is null)
+ {
+ _BaseStream = GetBaseStream();
+ RaiseAnyBinaryDataOpened(this);
+ }
+
+ return _BaseStream;
+ }
+ }
+
+ ~BinaryData()
+ {
+ AnyBinaryDataDisposed?.Invoke();
+ }
+
+ public void RoundUpPosition()
+ {
+ Position = General.HexRoundUp1(Position);
+ }
+
+ public void RoundUpPosition(int add)
+ {
+ Position = General.HexRoundUp1(Position + add);
+ }
+
+ protected void SetRomManager(RomManager rommgr)
+ {
+ RomManager = rommgr;
+ }
+
+ public void Write(sbyte value)
+ {
+ Writer.Write(value);
+ }
+
+ public void Write(byte value)
+ {
+ Writer.Write(value);
+ }
+
+ public void WriteByte(byte value)
+ {
+ Write(value);
+ }
+
+ public void Write(short value)
+ {
+ Writer.Write(SwapInts.SwapInt16(value));
+ }
+
+ public void Write(ushort value)
+ {
+ Writer.Write(SwapInts.SwapUInt16(value));
+ }
+
+ public void Write(int value)
+ {
+ Writer.Write(SwapInts.SwapInt32(value));
+ }
+
+ public void Write(uint value)
+ {
+ Writer.Write(SwapInts.SwapUInt32(value));
+ }
+
+ public void Write(long value)
+ {
+ Writer.Write(SwapInts.SwapInt64(value));
+ }
+
+ public void Write(ulong value)
+ {
+ Writer.Write(SwapInts.SwapUInt64(value));
+ }
+
+ public void Write(float value, bool isHalf = false)
+ {
+ if (isHalf)
+ Writer.Write(SwapInts.SwapHalf(value));
+ else
+ Writer.Write(SwapInts.SwapFloat32(value));
+ }
+
+ public void Write(string value)
+ {
+ Writer.Write(value);
+ }
+
+ public void Write(byte[] buffer)
+ {
+ Write(buffer, 0, buffer.Length);
+ }
+
+ public void Write(byte[] buffer, int index, int count)
+ {
+ Writer.Write(buffer, index, count);
+ }
+
+ public byte ReadByte()
+ {
+ return Reader.ReadByte();
+ }
+
+ public sbyte ReadSByte()
+ {
+ return Reader.ReadSByte();
+ }
+
+ public short ReadInt16()
+ {
+ return SwapInts.SwapInt16(Reader.ReadInt16());
+ }
+
+ public ushort ReadUInt16()
+ {
+ return SwapInts.SwapUInt16(Reader.ReadUInt16());
+ }
+
+ public int ReadInt32()
+ {
+ return SwapInts.SwapInt32(Reader.ReadInt32());
+ }
+
+ public uint ReadUInt32()
+ {
+ return SwapInts.SwapUInt32(Reader.ReadUInt32());
+ }
+
+ public long ReadInt64()
+ {
+ return SwapInts.SwapInt64(Reader.ReadInt64());
+ }
+
+ public ulong ReadUInt64()
+ {
+ return SwapInts.SwapUInt64(Reader.ReadUInt64());
+ }
+
+ public float ReadSingle()
+ {
+ return SwapInts.SwapFloat32(Reader.ReadSingle());
+ }
+
+ public string ReadString()
+ {
+ return Reader.ReadString();
+ }
+
+ public void Read(byte[] buffer)
+ {
+ Read(buffer, 0, buffer.Length);
+ }
+
+ public void Read(byte[] buffer, int index, int count)
+ {
+ Reader.Read(buffer, index, count);
+ }
+
+ public byte[] Read(int count)
+ {
+ var buf = new byte[count];
+ Read(buf, 0, count);
+ return buf;
+ }
+
+ public void Close()
+ {
+ AnyBinaryDataClosing?.Invoke(this);
+ BaseStream.Close();
+ AnyBinaryDataClosed?.Invoke(this);
+ }
+
+ public bool CanRead
+ {
+ get
+ {
+ return BaseStream.CanRead;
+ }
+ }
+
+ public bool CanWrite
+ {
+ get
+ {
+ return BaseStream.CanWrite;
+ }
+ }
+
+ public void SetLength(long length)
+ {
+ BaseStream.SetLength(length);
+ }
+
+ internal static void RaiseAnyBinaryDataOpened(BinaryData data)
+ {
+ AnyBinaryDataOpened?.Invoke(data);
+ }
+
+ public void Dispose()
+ {
+ Close();
+ }
}
\ No newline at end of file
diff --git a/SM64Lib/Data/BinaryFile.cs b/SM64Lib/Data/BinaryFile.cs
index 3e2c31a..019376a 100644
--- a/SM64Lib/Data/BinaryFile.cs
+++ b/SM64Lib/Data/BinaryFile.cs
@@ -1,11 +1,10 @@
using global::System.IO;
-namespace SM64Lib.Data
+namespace SM64Lib.Data;
+
+public class BinaryFile : BinaryStreamData
{
- public class BinaryFile : BinaryStreamData
+ public BinaryFile(string filePath, FileMode fileMode, FileAccess fileAccess) : base(new FileStream(filePath, fileMode, fileAccess))
{
- public BinaryFile(string filePath, FileMode fileMode, FileAccess fileAccess) : base(new FileStream(filePath, fileMode, fileAccess))
- {
- }
}
}
\ No newline at end of file
diff --git a/SM64Lib/Data/BinaryRom.cs b/SM64Lib/Data/BinaryRom.cs
index 9784dec..43810de 100644
--- a/SM64Lib/Data/BinaryRom.cs
+++ b/SM64Lib/Data/BinaryRom.cs
@@ -1,26 +1,25 @@
using global::System.IO;
-namespace SM64Lib.Data
+namespace SM64Lib.Data;
+
+public class BinaryRom : BinaryFile
{
- public class BinaryRom : BinaryFile
+ public BinaryRom(RomManager rommgr, FileAccess romAccess) : base(rommgr.RomFile, FileMode.Open, romAccess)
{
- public BinaryRom(RomManager rommgr, FileAccess romAccess) : base(rommgr.RomFile, FileMode.Open, romAccess)
- {
- SetRomManager(rommgr);
- }
-
- // Inherits BinaryData
-
- // Public ReadOnly Property RomAccess As FileAccess = FileAccess.Read
-
- // Public Sub New(rommgr As RomManager, romAccess As FileAccess)
- // SetRomManager(rommgr)
- // Me.RomAccess = romAccess
- // End Sub
-
- // Protected Overrides Function GetBaseStream() As Stream
- // Return RomManager.GetStream(RomAccess)
- // End Function
-
+ SetRomManager(rommgr);
}
+
+ // Inherits BinaryData
+
+ // Public ReadOnly Property RomAccess As FileAccess = FileAccess.Read
+
+ // Public Sub New(rommgr As RomManager, romAccess As FileAccess)
+ // SetRomManager(rommgr)
+ // Me.RomAccess = romAccess
+ // End Sub
+
+ // Protected Overrides Function GetBaseStream() As Stream
+ // Return RomManager.GetStream(RomAccess)
+ // End Function
+
}
\ No newline at end of file
diff --git a/SM64Lib/Data/BinarySegBank.cs b/SM64Lib/Data/BinarySegBank.cs
index 8ca6d83..c93275d 100644
--- a/SM64Lib/Data/BinarySegBank.cs
+++ b/SM64Lib/Data/BinarySegBank.cs
@@ -1,33 +1,32 @@
-using global::System.IO;
-using global::SM64Lib.SegmentedBanking;
+using global::SM64Lib.SegmentedBanking;
+using global::System.IO;
-namespace SM64Lib.Data
+namespace SM64Lib.Data;
+
+public class BinarySegBank : BinaryData
{
- public class BinarySegBank : BinaryData
+ public SegmentedBank SegBank { get; private set; }
+
+ public BinarySegBank(SegmentedBank segBank, RomManager rommgr)
{
- public SegmentedBank SegBank { get; private set; }
+ SegBank = segBank;
+ SetRomManager(rommgr);
+ }
- public BinarySegBank(SegmentedBank segBank, RomManager rommgr)
+ public BinarySegBank(SegmentedBank segBank)
+ {
+ SegBank = segBank;
+ }
+
+ protected override Stream GetBaseStream()
+ {
+ if (RomManager is not null)
{
- SegBank = segBank;
- SetRomManager(rommgr);
+ var s = RomManager.GetBinaryRom(FileAccess.Read);
+ SegBank.ReadDataIfNull(s.BaseStream);
+ s.Close();
}
- public BinarySegBank(SegmentedBank segBank)
- {
- SegBank = segBank;
- }
-
- protected override Stream GetBaseStream()
- {
- if (RomManager is not null)
- {
- var s = RomManager.GetBinaryRom(FileAccess.Read);
- SegBank.ReadDataIfNull(s.BaseStream);
- s.Close();
- }
-
- return SegBank.Data;
- }
+ return SegBank.Data;
}
}
\ No newline at end of file
diff --git a/SM64Lib/Data/BinaryStreamData.cs b/SM64Lib/Data/BinaryStreamData.cs
index dd9c568..4c38b10 100644
--- a/SM64Lib/Data/BinaryStreamData.cs
+++ b/SM64Lib/Data/BinaryStreamData.cs
@@ -1,20 +1,19 @@
using global::System.IO;
-namespace SM64Lib.Data
+namespace SM64Lib.Data;
+
+public class BinaryStreamData : BinaryData
{
- public class BinaryStreamData : BinaryData
+ protected readonly Stream myBaseStream;
+
+ public BinaryStreamData(Stream stream)
{
- protected readonly Stream myBaseStream;
+ myBaseStream = stream;
+ //RaiseAnyBinaryDataOpened(this);
+ }
- public BinaryStreamData(Stream stream)
- {
- myBaseStream = stream;
- //RaiseAnyBinaryDataOpened(this);
- }
-
- protected override Stream GetBaseStream()
- {
- return myBaseStream;
- }
+ protected override Stream GetBaseStream()
+ {
+ return myBaseStream;
}
}
\ No newline at end of file
diff --git a/SM64Lib/Data/System/Bits.cs b/SM64Lib/Data/System/Bits.cs
index 33b9727..5e67349 100644
--- a/SM64Lib/Data/System/Bits.cs
+++ b/SM64Lib/Data/System/Bits.cs
@@ -1,98 +1,96 @@
using System;
using System.Collections;
using System.Linq;
-using Microsoft.VisualBasic.CompilerServices;
-namespace SM64Lib.Data.System
+namespace SM64Lib.Data.System;
+
+public class Bits
{
- public class Bits
+ public static byte[] ByteToBitArray(byte b)
{
- public static byte[] ByteToBitArray(byte b)
+ var bitarray = new BitArray(new[] { b });
+ var temp = new byte[bitarray.Length];
+ for (int i = 0, loopTo = bitarray.Length - 1; i <= loopTo; i++)
+ temp[i] = Convert.ToByte(bitarray[i]);
+ int tindex = 0;
+ var temp2 = new byte[(temp.Count())];
+ for (int i = temp.Length - 1; i >= 0; i += -1)
{
- var bitarray = new BitArray(new[] { b });
- var temp = new byte[bitarray.Length];
- for (int i = 0, loopTo = bitarray.Length - 1; i <= loopTo; i++)
- temp[i] = Convert.ToByte(bitarray[i]);
- int tindex = 0;
- var temp2 = new byte[(temp.Count())];
- for (int i = temp.Length - 1; i >= 0; i += -1)
- {
- temp2[tindex] = temp[i];
- tindex += 1;
- }
-
- return temp2;
+ temp2[tindex] = temp[i];
+ tindex += 1;
}
- public static bool[] ByteToBoolArray(byte b)
- {
- var bitarray = new BitArray(new[] { b });
- var temp = new bool[bitarray.Length];
- for (int i = 0, loopTo = bitarray.Length - 1; i <= loopTo; i++)
- temp[i] = Convert.ToBoolean(bitarray[i]);
- int tindex = 0;
- var temp2 = new bool[(temp.Count())];
- for (int i = temp.Length - 1; i >= 0; i += -1)
- {
- temp2[tindex] = temp[i];
- tindex += 1;
- }
+ return temp2;
+ }
- return temp2;
+ public static bool[] ByteToBoolArray(byte b)
+ {
+ var bitarray = new BitArray(new[] { b });
+ var temp = new bool[bitarray.Length];
+ for (int i = 0, loopTo = bitarray.Length - 1; i <= loopTo; i++)
+ temp[i] = Convert.ToBoolean(bitarray[i]);
+ int tindex = 0;
+ var temp2 = new bool[(temp.Count())];
+ for (int i = temp.Length - 1; i >= 0; i += -1)
+ {
+ temp2[tindex] = temp[i];
+ tindex += 1;
}
- public static byte ArrayToByte(byte[] ba)
+ return temp2;
+ }
+
+ public static byte ArrayToByte(byte[] ba)
+ {
+ // ODER: BitArray.ToByte()
+
+ byte endval = 0;
+ int index = ba.Count() - 1;
+ foreach (var bit in ba)
{
- // ODER: BitArray.ToByte()
-
- byte endval = 0;
- int index = ba.Count() - 1;
- foreach (var bit in ba)
- {
- endval += (byte)(bit * Math.Pow(2, index));
- index -= 1;
- }
-
- return endval;
+ endval += (byte)(bit * Math.Pow(2, index));
+ index -= 1;
}
- public static byte ArrayToByte(bool[] ba)
+ return endval;
+ }
+
+ public static byte ArrayToByte(bool[] ba)
+ {
+ // ODER: BitArray.ToByte()
+
+ byte endval = 0;
+ int index = ba.Count() - 1;
+ foreach (var bit in ba)
{
- // ODER: BitArray.ToByte()
-
- byte endval = 0;
- int index = ba.Count() - 1;
- foreach (var bit in ba)
- {
- endval += (byte)((bit ? 1 : 0) * Math.Pow(2, index));
- index -= 1;
- }
-
- return endval;
+ endval += (byte)((bit ? 1 : 0) * Math.Pow(2, index));
+ index -= 1;
}
- public static byte SetInByte(byte b, int index, byte value)
- {
- var temp = ByteToBitArray(b);
- temp[index] = value;
- return ArrayToByte(temp);
- }
+ return endval;
+ }
- public static byte SetInByte(byte b, int index, bool value)
- {
- var temp = ByteToBoolArray(b);
- temp[index] = value;
- return ArrayToByte(temp);
- }
+ public static byte SetInByte(byte b, int index, byte value)
+ {
+ var temp = ByteToBitArray(b);
+ temp[index] = value;
+ return ArrayToByte(temp);
+ }
- public static byte GetBitOfByte(byte b, int index)
- {
- return ByteToBitArray(b)[index];
- }
+ public static byte SetInByte(byte b, int index, bool value)
+ {
+ var temp = ByteToBoolArray(b);
+ temp[index] = value;
+ return ArrayToByte(temp);
+ }
- public static bool GetBoolOfByte(byte b, int index)
- {
- return ByteToBoolArray(b)[index];
- }
+ public static byte GetBitOfByte(byte b, int index)
+ {
+ return ByteToBitArray(b)[index];
+ }
+
+ public static bool GetBoolOfByte(byte b, int index)
+ {
+ return ByteToBoolArray(b)[index];
}
}
\ No newline at end of file
diff --git a/SM64Lib/Data/System/SwapInts.cs b/SM64Lib/Data/System/SwapInts.cs
index ac0d32a..6fb0e11 100644
--- a/SM64Lib/Data/System/SwapInts.cs
+++ b/SM64Lib/Data/System/SwapInts.cs
@@ -1,62 +1,61 @@
using System;
-namespace SM64Lib.Data.System
+namespace SM64Lib.Data.System;
+
+internal static class SwapInts
{
- internal static class SwapInts
+ public static short SwapInt16(short value)
{
- public static short SwapInt16(short value)
- {
- var bytes = BitConverter.GetBytes(value);
- Array.Reverse(bytes);
- return BitConverter.ToInt16(bytes, 0);
- }
+ var bytes = BitConverter.GetBytes(value);
+ Array.Reverse(bytes);
+ return BitConverter.ToInt16(bytes, 0);
+ }
- public static ushort SwapUInt16(ushort value)
- {
- var bytes = BitConverter.GetBytes(value);
- Array.Reverse(bytes);
- return BitConverter.ToUInt16(bytes, 0);
- }
+ public static ushort SwapUInt16(ushort value)
+ {
+ var bytes = BitConverter.GetBytes(value);
+ Array.Reverse(bytes);
+ return BitConverter.ToUInt16(bytes, 0);
+ }
- public static int SwapInt32(int value)
- {
- var bytes = BitConverter.GetBytes(value);
- Array.Reverse(bytes);
- return BitConverter.ToInt32(bytes, 0);
- }
+ public static int SwapInt32(int value)
+ {
+ var bytes = BitConverter.GetBytes(value);
+ Array.Reverse(bytes);
+ return BitConverter.ToInt32(bytes, 0);
+ }
- public static uint SwapUInt32(uint value)
- {
- var bytes = BitConverter.GetBytes(value);
- Array.Reverse(bytes);
- return BitConverter.ToUInt32(bytes, 0);
- }
+ public static uint SwapUInt32(uint value)
+ {
+ var bytes = BitConverter.GetBytes(value);
+ Array.Reverse(bytes);
+ return BitConverter.ToUInt32(bytes, 0);
+ }
- public static long SwapInt64(long value)
- {
- var bytes = BitConverter.GetBytes(value);
- Array.Reverse(bytes);
- return BitConverter.ToInt64(bytes, 0);
- }
+ public static long SwapInt64(long value)
+ {
+ var bytes = BitConverter.GetBytes(value);
+ Array.Reverse(bytes);
+ return BitConverter.ToInt64(bytes, 0);
+ }
- public static ulong SwapUInt64(ulong value)
- {
- var bytes = BitConverter.GetBytes(value);
- Array.Reverse(bytes);
- return BitConverter.ToUInt64(bytes, 0);
- }
+ public static ulong SwapUInt64(ulong value)
+ {
+ var bytes = BitConverter.GetBytes(value);
+ Array.Reverse(bytes);
+ return BitConverter.ToUInt64(bytes, 0);
+ }
- public static short SwapHalf(float value)
- {
- byte[] bytes = BitConverter.GetBytes(value);
- return (short)(BitConverter.ToInt32(bytes, 0) >> 16);
- }
+ public static short SwapHalf(float value)
+ {
+ byte[] bytes = BitConverter.GetBytes(value);
+ return (short)(BitConverter.ToInt32(bytes, 0) >> 16);
+ }
- public static float SwapFloat32(float value)
- {
- byte[] bytes = BitConverter.GetBytes(value);
- Array.Reverse(bytes);
- return BitConverter.ToSingle(bytes, 0);
- }
+ public static float SwapFloat32(float value)
+ {
+ byte[] bytes = BitConverter.GetBytes(value);
+ Array.Reverse(bytes);
+ return BitConverter.ToSingle(bytes, 0);
}
}
\ No newline at end of file
diff --git a/SM64Lib/Datatypecastes.cs b/SM64Lib/Datatypecastes.cs
index fc61fc5..1c30b73 100644
--- a/SM64Lib/Datatypecastes.cs
+++ b/SM64Lib/Datatypecastes.cs
@@ -1,39 +1,38 @@
using global::System.Runtime.InteropServices;
-namespace SM64Lib
+namespace SM64Lib;
+
+static class Datatypecastes
{
- static class Datatypecastes
+ public static short LongToInt16(long value)
{
- public static short LongToInt16(long value)
- {
- var cast = default(CasterLongInt16);
- cast.LongValue = value;
- return cast.Int16Value;
- }
+ var cast = default(CasterLongInt16);
+ cast.LongValue = value;
+ return cast.Int16Value;
+ }
- [StructLayout(LayoutKind.Explicit)]
- private struct CasterLongInt16
- {
- [FieldOffset(0)]
- public long LongValue;
- [FieldOffset(0)]
- public short Int16Value;
- }
+ [StructLayout(LayoutKind.Explicit)]
+ private struct CasterLongInt16
+ {
+ [FieldOffset(0)]
+ public long LongValue;
+ [FieldOffset(0)]
+ public short Int16Value;
+ }
- public static byte LongToByte(long value)
- {
- var cast = default(CasterLongByte);
- cast.LongValue = value;
- return cast.ByteValue;
- }
+ public static byte LongToByte(long value)
+ {
+ var cast = default(CasterLongByte);
+ cast.LongValue = value;
+ return cast.ByteValue;
+ }
- [StructLayout(LayoutKind.Explicit)]
- private struct CasterLongByte
- {
- [FieldOffset(0)]
- public long LongValue;
- [FieldOffset(0)]
- public byte ByteValue;
- }
+ [StructLayout(LayoutKind.Explicit)]
+ private struct CasterLongByte
+ {
+ [FieldOffset(0)]
+ public long LongValue;
+ [FieldOffset(0)]
+ public byte ByteValue;
}
}
\ No newline at end of file
diff --git a/SM64Lib/EventArguments/GetTextProfileInfoEventArgs.cs b/SM64Lib/EventArguments/GetTextProfileInfoEventArgs.cs
index 0766d46..4824e9e 100644
--- a/SM64Lib/EventArguments/GetTextProfileInfoEventArgs.cs
+++ b/SM64Lib/EventArguments/GetTextProfileInfoEventArgs.cs
@@ -1,13 +1,8 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-namespace SM64Lib.EventArguments
+namespace SM64Lib.EventArguments;
+
+public class GetTextProfileInfoEventArgs : EventArgs
{
- public class GetTextProfileInfoEventArgs : EventArgs
- {
- public Text.Profiles.TextProfileInfo ProfileInfo { get; set; }
- }
+ public Text.Profiles.TextProfileInfo ProfileInfo { get; set; }
}
diff --git a/SM64Lib/EventArguments/PrepairingRomEventArgs.cs b/SM64Lib/EventArguments/PrepairingRomEventArgs.cs
index 6f519a6..9418690 100644
--- a/SM64Lib/EventArguments/PrepairingRomEventArgs.cs
+++ b/SM64Lib/EventArguments/PrepairingRomEventArgs.cs
@@ -1,13 +1,9 @@
using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-namespace SM64Lib.EventArguments
+namespace SM64Lib.EventArguments;
+
+public class PrepairingRomEventArgs : EventArgs
{
- public class PrepairingRomEventArgs : EventArgs
- {
- public IEnumerable ScriptInfos { get; set; }
- }
+ public IEnumerable ScriptInfos { get; set; }
}
diff --git a/SM64Lib/EventArguments/RomVersionEventArgs.cs b/SM64Lib/EventArguments/RomVersionEventArgs.cs
index 121f8f8..1cd20f7 100644
--- a/SM64Lib/EventArguments/RomVersionEventArgs.cs
+++ b/SM64Lib/EventArguments/RomVersionEventArgs.cs
@@ -1,14 +1,13 @@
using System;
-namespace SM64Lib.EventArguments
-{
- public class RomVersionEventArgs : EventArgs
- {
- public RomVersion RomVersion { get; set; }
+namespace SM64Lib.EventArguments;
- internal RomVersionEventArgs(RomVersion romVersion)
- {
- RomVersion = romVersion;
- }
+public class RomVersionEventArgs : EventArgs
+{
+ public RomVersion RomVersion { get; set; }
+
+ internal RomVersionEventArgs(RomVersion romVersion)
+ {
+ RomVersion = romVersion;
}
}
\ No newline at end of file
diff --git a/SM64Lib/Exceptions/InvalidMD5HashException.cs b/SM64Lib/Exceptions/InvalidMD5HashException.cs
index 2788c67..a8f1f39 100644
--- a/SM64Lib/Exceptions/InvalidMD5HashException.cs
+++ b/SM64Lib/Exceptions/InvalidMD5HashException.cs
@@ -1,8 +1,7 @@
using System;
-namespace SM64Lib.Exceptions
+namespace SM64Lib.Exceptions;
+
+public class InvalidMD5HashException : Exception
{
- public class InvalidMD5HashException : Exception
- {
- }
}
\ No newline at end of file
diff --git a/SM64Lib/Exceptions/RomCompatiblityException.cs b/SM64Lib/Exceptions/RomCompatiblityException.cs
index b41d182..5b8e92f 100644
--- a/SM64Lib/Exceptions/RomCompatiblityException.cs
+++ b/SM64Lib/Exceptions/RomCompatiblityException.cs
@@ -1,11 +1,10 @@
using System;
-namespace SM64Lib.Exceptions
+namespace SM64Lib.Exceptions;
+
+public class RomCompatiblityException : Exception
{
- public class RomCompatiblityException : Exception
+ public RomCompatiblityException(string msg) : base(msg)
{
- public RomCompatiblityException(string msg) : base(msg)
- {
- }
}
}
\ No newline at end of file
diff --git a/SM64Lib/ExtensionMethods.cs b/SM64Lib/ExtensionMethods.cs
index a2fa437..e5aa686 100644
--- a/SM64Lib/ExtensionMethods.cs
+++ b/SM64Lib/ExtensionMethods.cs
@@ -2,32 +2,31 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
-namespace SM64Lib.Extensions
+namespace SM64Lib.Extensions;
+
+public static class Int16Extensions
{
- public static class Int16Extensions
+ public static bool IsInRange(this short value, short min, short max)
{
- public static bool IsInRange(this short value, short min, short max)
- {
- return value >= min && value <= max;
- }
+ return value >= min && value <= max;
}
+}
- public static class ObjectExtensions
+public static class ObjectExtensions
+{
+ public static void CloneTo(this T source, T destination) where T : class
{
- public static void CloneTo(this T source, T destination) where T : class
- {
- var json = JsonSerializer.CreateDefault();
- var jobj = JObject.FromObject(source);
- jobj.Populate(destination);
- }
+ var json = JsonSerializer.CreateDefault();
+ var jobj = JObject.FromObject(source);
+ jobj.Populate(destination);
}
+}
- public static class JsonExtensions
+public static class JsonExtensions
+{
+ public static void Populate(this JToken value, object target)
{
- public static void Populate(this JToken value, object target)
- {
- using (var sr = value.CreateReader())
- JsonSerializer.CreateDefault().Populate(sr, target);
- }
+ using (var sr = value.CreateReader())
+ JsonSerializer.CreateDefault().Populate(sr, target);
}
}
\ No newline at end of file
diff --git a/SM64Lib/FilePathsConfiguration.cs b/SM64Lib/FilePathsConfiguration.cs
index 48386fc..92448f7 100644
--- a/SM64Lib/FilePathsConfiguration.cs
+++ b/SM64Lib/FilePathsConfiguration.cs
@@ -1,49 +1,48 @@
using System.Collections.Generic;
-namespace SM64Lib
+namespace SM64Lib;
+
+public class FilePathsConfiguration
{
- public class FilePathsConfiguration
+
+ // S T A T I C M E M B E R S
+
+ public static FilePathsConfiguration DefaultConfiguration { get; private set; } = new FilePathsConfiguration();
+
+ public static string[] AllFileKeys
{
-
- // S T A T I C M E M B E R S
-
- public static FilePathsConfiguration DefaultConfiguration { get; private set; } = new FilePathsConfiguration();
-
- public static string[] AllFileKeys
+ get
{
- get
- {
- return new[] { "rn64crc.exe","ApplyPPF3.exe", "Level Tabel.json", "Update-Patches.json", "Update Patches Folder", "Text Profiles.json", "BaseTweak", "sm64extend.exe", "Original Level Pointers.bin", "armips.exe", "Flips.exe", "nconvert.exe" };
- }
- }
-
- // F I E L D S
-
- private readonly Dictionary dic = new Dictionary();
-
- // P R O P E R T I E S
-
- public IReadOnlyDictionary Files
- {
- get
- {
- return dic;
- }
- }
-
- // C O N S T R U C T O R
-
- public FilePathsConfiguration()
- {
- foreach (string key in AllFileKeys)
- dic.Add(key, string.Empty);
- }
-
- // M E T H O D S
-
- public void SetFilePath(string key, string path)
- {
- dic[key] = path;
+ return new[] { "rn64crc.exe", "ApplyPPF3.exe", "Level Tabel.json", "Update-Patches.json", "Update Patches Folder", "Text Profiles.json", "BaseTweak", "sm64extend.exe", "Original Level Pointers.bin", "armips.exe", "Flips.exe", "nconvert.exe" };
}
}
+
+ // F I E L D S
+
+ private readonly Dictionary dic = new Dictionary();
+
+ // P R O P E R T I E S
+
+ public IReadOnlyDictionary Files
+ {
+ get
+ {
+ return dic;
+ }
+ }
+
+ // C O N S T R U C T O R
+
+ public FilePathsConfiguration()
+ {
+ foreach (string key in AllFileKeys)
+ dic.Add(key, string.Empty);
+ }
+
+ // M E T H O D S
+
+ public void SetFilePath(string key, string path)
+ {
+ dic[key] = path;
+ }
}
\ No newline at end of file
diff --git a/SM64Lib/General.cs b/SM64Lib/General.cs
index 85e1cdc..003be5e 100644
--- a/SM64Lib/General.cs
+++ b/SM64Lib/General.cs
@@ -8,596 +8,595 @@ using System.IO.Compression;
using System.Linq;
using System.Security.Cryptography;
-namespace SM64Lib
+namespace SM64Lib;
+
+public static class General
{
- public static class General
+ public static byte[] DisplayListCommandsWithPointerList { get; private set; } = new byte[] { 0x1, 0x3, 0x4, 0x6, 0xFD };
+ public static bool[] ActSelectorDefaultValues { get; private set; } = new bool[] { false, false, false, true, true, false, true, true, true, true, true, true, true, true, true, false, false, false, false, false, false, true, true, true, false, false, false, false, false, false, false, false, false, false, false };
+ public static PatchClass PatchClass { get; private set; } = new PatchClass();
+
+ public static bool IsDebugging
{
- public static byte[] DisplayListCommandsWithPointerList { get; private set; } = new byte[] { 0x1, 0x3, 0x4, 0x6, 0xFD };
- public static bool[] ActSelectorDefaultValues { get; private set; } = new bool[] { false, false, false, true, true, false, true, true, true, true, true, true, true, true, true, false, false, false, false, false, false, true, true, true, false, false, false, false, false, false, false, false, false, false, false };
- public static PatchClass PatchClass { get; private set; } = new PatchClass();
-
- public static bool IsDebugging
+ get
{
- get
- {
- return Debugger.IsAttached;
- }
+ return Debugger.IsAttached;
+ }
+ }
+
+ public static short KeepInInt16Range(double value)
+ {
+ if (value > short.MaxValue)
+ {
+ value = short.MaxValue;
+ }
+ else if (value < short.MinValue)
+ {
+ value = short.MinValue;
}
- public static short KeepInInt16Range(double value)
- {
- if (value > short.MaxValue)
- {
- value = short.MaxValue;
- }
- else if (value < short.MinValue)
- {
- value = short.MinValue;
- }
+ return Convert.ToInt16(value);
+ }
- return Convert.ToInt16(value);
+ internal static IReadOnlyDictionary MyFilePaths
+ {
+ get
+ {
+ return FilePathsConfiguration.DefaultConfiguration.Files;
+ }
+ }
+
+ public static string ComputeMD5Hash(string filePath)
+ {
+ var md5 = MD5.Create();
+ string res;
+ FileStream fs;
+
+ try
+ {
+ fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
+ res = BitConverter.ToString(md5.ComputeHash(fs)).Replace("-", string.Empty).ToLowerInvariant();
+ }
+ catch (Exception)
+ {
+ fs = null;
+ res = string.Empty;
}
- internal static IReadOnlyDictionary MyFilePaths
+ fs?.Close();
+ md5.Dispose();
+ return res;
+ }
+
+ public static void CopyBitmap(Bitmap src, Bitmap dest)
+ {
+ for (int y = 0, loopTo = src.Height - 1; y <= loopTo; y++)
{
- get
- {
- return FilePathsConfiguration.DefaultConfiguration.Files;
- }
+ for (int x = 0, loopTo1 = src.Width - 1; x <= loopTo1; x++)
+ dest.SetPixel(x, y, src.GetPixel(x, y));
+ }
+ }
+
+ public static Bitmap CopyBitmap(Bitmap src)
+ {
+ return CopyBitmap(src, src.PixelFormat);
+ }
+
+ public static Bitmap CopyBitmap(Bitmap src, System.Drawing.Imaging.PixelFormat pixelFormat)
+ {
+ var dest = new Bitmap(src.Width, src.Height, pixelFormat);
+ CopyBitmap(src, dest);
+ return dest;
+ }
+
+ public static double Round(double d)
+ {
+ return Math.Round(d, MidpointRounding.AwayFromZero);
+ }
+
+ public static bool CompareTwoByteArrays(byte[] arr1, byte[] arr2, uint size = 0)
+ {
+ if (arr2.Length != arr1.Length) return false;
+
+ int loopTo = size != 0 ? (int)size : arr1.Length;
+
+ for (int i = 0; i < loopTo; i++)
+ {
+ if (arr1[i] != arr2[i])
+ return false;
}
- public static string ComputeMD5Hash(string filePath)
+ return true;
+ }
+
+ public static byte GetLevelIndexFromID(byte LevelID)
+ {
+ switch (LevelID)
{
- var md5 = MD5.Create();
- string res;
- FileStream fs;
-
- try
- {
- fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
- res = BitConverter.ToString(md5.ComputeHash(fs)).Replace("-", string.Empty).ToLowerInvariant();
- }
- catch (Exception)
- {
- fs = null;
- res = string.Empty;
- }
-
- fs?.Close();
- md5.Dispose();
- return res;
- }
-
- public static void CopyBitmap(Bitmap src, Bitmap dest)
- {
- for (int y = 0, loopTo = src.Height - 1; y <= loopTo; y++)
- {
- for (int x = 0, loopTo1 = src.Width - 1; x <= loopTo1; x++)
- dest.SetPixel(x, y, src.GetPixel(x, y));
- }
- }
-
- public static Bitmap CopyBitmap(Bitmap src)
- {
- return CopyBitmap(src, src.PixelFormat);
- }
-
- public static Bitmap CopyBitmap(Bitmap src, System.Drawing.Imaging.PixelFormat pixelFormat)
- {
- var dest = new Bitmap(src.Width, src.Height, pixelFormat);
- CopyBitmap(src, dest);
- return dest;
- }
-
- public static double Round(double d)
- {
- return Math.Round(d, MidpointRounding.AwayFromZero);
- }
-
- public static bool CompareTwoByteArrays(byte[] arr1, byte[] arr2, uint size = 0)
- {
- if (arr2.Length != arr1.Length) return false;
-
- int loopTo = size != 0 ? (int)size : arr1.Length;
-
- for (int i = 0; i < loopTo; i++)
- {
- if (arr1[i] != arr2[i])
- return false;
- }
-
- return true;
- }
-
- public static byte GetLevelIndexFromID(byte LevelID)
- {
- switch (LevelID)
- {
- case 0x4:
- {
- return 0;
- }
-
- case 0x5:
- {
- return 1;
- }
-
- case 0x6:
- {
- return 2;
- }
-
- case 0x7:
- {
- return 3;
- }
-
- case 0x8:
- {
- return 4;
- }
-
- case 0x9:
- {
- return 5;
- }
-
- case 0xA:
- {
- return 6;
- }
-
- case 0xB:
- {
- return 7;
- }
-
- case 0xC:
- {
- return 8;
- }
-
- case 0xD:
- {
- return 9;
- }
-
- case 0xE:
- {
- return 10;
- }
-
- case 0xF:
- {
- return 11;
- }
-
- case 0x10:
- {
- return 12;
- }
-
- case 0x11:
- {
- return 13;
- }
-
- case 0x12:
- {
- return 14;
- }
-
- case 0x13:
- {
- return 15;
- }
-
- case 0x14:
- {
- return 16;
- }
-
- case 0x15:
- {
- return 17;
- }
-
- case 0x16:
- {
- return 18;
- }
-
- case 0x17:
- {
- return 19;
- }
-
- case 0x18:
- {
- return 20;
- }
-
- case 0x19:
- {
- return 21;
- }
-
- case 0x1A:
- {
- return 22;
- }
-
- case 0x1B:
- {
- return 23;
- }
-
- case 0x1C:
- {
- return 24;
- }
-
- case 0x1D:
- {
- return 25;
- }
-
- case 0x1E:
- {
- return 26;
- }
-
- case 0x1F:
- {
- return 27;
- }
-
- case 0x21:
- {
- return 28;
- }
-
- case 0x22:
- {
- return 29;
- }
-
- case 0x24:
- {
- return 30;
- }
-
- default:
- {
- return 5;
- }
- }
- }
-
- public static byte GetLevelIDFromIndex(byte LevelID)
- {
- switch (LevelID)
- {
- case 0:
- {
- return 0x4;
- }
-
- case 1:
- {
- return 0x5;
- }
-
- case 2:
- {
- return 0x6;
- }
-
- case 3:
- {
- return 0x7;
- }
-
- case 4:
- {
- return 0x8;
- }
-
- case 5:
- {
- return 0x9;
- }
-
- case 6:
- {
- return 0xA;
- }
-
- case 7:
- {
- return 0xB;
- }
-
- case 8:
- {
- return 0xC;
- }
-
- case 9:
- {
- return 0xD;
- }
-
- case 10:
- {
- return 0xE;
- }
-
- case 11:
- {
- return 0xF;
- }
-
- case 12:
- {
- return 0x10;
- }
-
- case 13:
- {
- return 0x11;
- }
-
- case 14:
- {
- return 0x12;
- }
-
- case 15:
- {
- return 0x13;
- }
-
- case 16:
- {
- return 0x14;
- }
-
- case 17:
- {
- return 0x15;
- }
-
- case 18:
- {
- return 0x16;
- }
-
- case 19:
- {
- return 0x17;
- }
-
- case 20:
- {
- return 0x18;
- }
-
- case 21:
- {
- return 0x19;
- }
-
- case 22:
- {
- return 0x1A;
- }
-
- case 23:
- {
- return 0x1B;
- }
-
- case 24:
- {
- return 0x1C;
- }
-
- case 25:
- {
- return 0x1D;
- }
-
- case 26:
- {
- return 0x1E;
- }
-
- case 27:
- {
- return 0x1F;
- }
-
- case 28:
- {
- return 0x21;
- }
-
- case 29:
- {
- return 0x22;
- }
-
- case 30:
- {
- return 0x24;
- }
-
- default:
- {
- return 5;
- }
- }
- }
-
- public static int HexRoundUp1(int value)
- {
- while (value % 0x10 != 0)
- value += 1;
- return value;
- }
-
- public static long HexRoundUp1(long value)
- {
- while (value % 0x10 != 0)
- value += 1;
- return value;
- }
-
- public static void HexRoundUp2(ref long value)
- {
- while (value % 0x10 != 0)
- value += 1;
- }
-
- public static void HexRoundUp2(ref uint value)
- {
- while (value % 0x10 != 0)
- value += 1;
- }
-
- public static void HexRoundUp2(ref int value)
- {
- while (value % 0x10 != 0)
- value += 1;
- }
-
- public static string FillStrToCharCount(string str, int charCount, string fillVal = "0")
- {
- if (fillVal.Count() == 0)
- return str;
- if (charCount == 0)
- return str;
- while (str.Count() < charCount)
- str = fillVal + str;
- return str;
- }
-
- public static Geolayout.BackgroundPointers GetBackgroundAddressOfID(Geolayout.BackgroundIDs ID, bool EndAddr)
- {
- switch (ID)
- {
- case Geolayout.BackgroundIDs.AboveClouds:
- {
- if (EndAddr)
- return Geolayout.BackgroundPointers.AboveCloudsEnd;
- return Geolayout.BackgroundPointers.AboveCloudsStart;
- }
-
- case Geolayout.BackgroundIDs.BelowClouds:
- {
- if (EndAddr)
- return Geolayout.BackgroundPointers.BelowCloudsEnd;
- return Geolayout.BackgroundPointers.BelowCloudsStart;
- }
-
- case Geolayout.BackgroundIDs.Cavern:
- {
- if (EndAddr)
- return Geolayout.BackgroundPointers.CavernEnd;
- return Geolayout.BackgroundPointers.CavernStart;
- }
-
- case Geolayout.BackgroundIDs.Desert:
- {
- if (EndAddr)
- return Geolayout.BackgroundPointers.DesertEnd;
- return Geolayout.BackgroundPointers.DesertStart;
- }
-
- case Geolayout.BackgroundIDs.FlamingSky:
- {
- if (EndAddr)
- return Geolayout.BackgroundPointers.FlamingSkyEnd;
- return Geolayout.BackgroundPointers.FlamingSkyStart;
- }
-
- case Geolayout.BackgroundIDs.HauntedForest:
- {
- if (EndAddr)
- return Geolayout.BackgroundPointers.HauntedForestEnd;
- return Geolayout.BackgroundPointers.HauntedForestStart;
- }
-
- case Geolayout.BackgroundIDs.Ocean:
- {
- if (EndAddr)
- return Geolayout.BackgroundPointers.OceanEnd;
- return Geolayout.BackgroundPointers.OceanStart;
- }
-
- case Geolayout.BackgroundIDs.PurpleClouds:
- {
- if (EndAddr)
- return Geolayout.BackgroundPointers.PurpleCloudsEnd;
- return Geolayout.BackgroundPointers.PurpleCloudsStart;
- }
-
- case Geolayout.BackgroundIDs.SnowyMountains:
- {
- if (EndAddr)
- return Geolayout.BackgroundPointers.SnowyMountainsEnd;
- return Geolayout.BackgroundPointers.SnowyMountainsStart;
- }
-
- case Geolayout.BackgroundIDs.UnderwaterCity:
- {
- if (EndAddr)
- return Geolayout.BackgroundPointers.UnderwaterCityEnd;
- return Geolayout.BackgroundPointers.UnderwaterCityStart;
- }
- }
-
- return EndAddr ? Geolayout.BackgroundPointers.OceanEnd : Geolayout.BackgroundPointers.OceanStart;
- }
-
- public static string CommandByteArrayToString(byte[] bytes)
- {
- string res = string.Empty;
- foreach (byte b in bytes)
- {
- if (!string.IsNullOrEmpty(res))
+ case 0x4:
{
- res += " ";
+ return 0;
}
- res += b.ToString("X2");
- }
+ case 0x5:
+ {
+ return 1;
+ }
- return res;
+ case 0x6:
+ {
+ return 2;
+ }
+
+ case 0x7:
+ {
+ return 3;
+ }
+
+ case 0x8:
+ {
+ return 4;
+ }
+
+ case 0x9:
+ {
+ return 5;
+ }
+
+ case 0xA:
+ {
+ return 6;
+ }
+
+ case 0xB:
+ {
+ return 7;
+ }
+
+ case 0xC:
+ {
+ return 8;
+ }
+
+ case 0xD:
+ {
+ return 9;
+ }
+
+ case 0xE:
+ {
+ return 10;
+ }
+
+ case 0xF:
+ {
+ return 11;
+ }
+
+ case 0x10:
+ {
+ return 12;
+ }
+
+ case 0x11:
+ {
+ return 13;
+ }
+
+ case 0x12:
+ {
+ return 14;
+ }
+
+ case 0x13:
+ {
+ return 15;
+ }
+
+ case 0x14:
+ {
+ return 16;
+ }
+
+ case 0x15:
+ {
+ return 17;
+ }
+
+ case 0x16:
+ {
+ return 18;
+ }
+
+ case 0x17:
+ {
+ return 19;
+ }
+
+ case 0x18:
+ {
+ return 20;
+ }
+
+ case 0x19:
+ {
+ return 21;
+ }
+
+ case 0x1A:
+ {
+ return 22;
+ }
+
+ case 0x1B:
+ {
+ return 23;
+ }
+
+ case 0x1C:
+ {
+ return 24;
+ }
+
+ case 0x1D:
+ {
+ return 25;
+ }
+
+ case 0x1E:
+ {
+ return 26;
+ }
+
+ case 0x1F:
+ {
+ return 27;
+ }
+
+ case 0x21:
+ {
+ return 28;
+ }
+
+ case 0x22:
+ {
+ return 29;
+ }
+
+ case 0x24:
+ {
+ return 30;
+ }
+
+ default:
+ {
+ return 5;
+ }
+ }
+ }
+
+ public static byte GetLevelIDFromIndex(byte LevelID)
+ {
+ switch (LevelID)
+ {
+ case 0:
+ {
+ return 0x4;
+ }
+
+ case 1:
+ {
+ return 0x5;
+ }
+
+ case 2:
+ {
+ return 0x6;
+ }
+
+ case 3:
+ {
+ return 0x7;
+ }
+
+ case 4:
+ {
+ return 0x8;
+ }
+
+ case 5:
+ {
+ return 0x9;
+ }
+
+ case 6:
+ {
+ return 0xA;
+ }
+
+ case 7:
+ {
+ return 0xB;
+ }
+
+ case 8:
+ {
+ return 0xC;
+ }
+
+ case 9:
+ {
+ return 0xD;
+ }
+
+ case 10:
+ {
+ return 0xE;
+ }
+
+ case 11:
+ {
+ return 0xF;
+ }
+
+ case 12:
+ {
+ return 0x10;
+ }
+
+ case 13:
+ {
+ return 0x11;
+ }
+
+ case 14:
+ {
+ return 0x12;
+ }
+
+ case 15:
+ {
+ return 0x13;
+ }
+
+ case 16:
+ {
+ return 0x14;
+ }
+
+ case 17:
+ {
+ return 0x15;
+ }
+
+ case 18:
+ {
+ return 0x16;
+ }
+
+ case 19:
+ {
+ return 0x17;
+ }
+
+ case 20:
+ {
+ return 0x18;
+ }
+
+ case 21:
+ {
+ return 0x19;
+ }
+
+ case 22:
+ {
+ return 0x1A;
+ }
+
+ case 23:
+ {
+ return 0x1B;
+ }
+
+ case 24:
+ {
+ return 0x1C;
+ }
+
+ case 25:
+ {
+ return 0x1D;
+ }
+
+ case 26:
+ {
+ return 0x1E;
+ }
+
+ case 27:
+ {
+ return 0x1F;
+ }
+
+ case 28:
+ {
+ return 0x21;
+ }
+
+ case 29:
+ {
+ return 0x22;
+ }
+
+ case 30:
+ {
+ return 0x24;
+ }
+
+ default:
+ {
+ return 5;
+ }
+ }
+ }
+
+ public static int HexRoundUp1(int value)
+ {
+ while (value % 0x10 != 0)
+ value += 1;
+ return value;
+ }
+
+ public static long HexRoundUp1(long value)
+ {
+ while (value % 0x10 != 0)
+ value += 1;
+ return value;
+ }
+
+ public static void HexRoundUp2(ref long value)
+ {
+ while (value % 0x10 != 0)
+ value += 1;
+ }
+
+ public static void HexRoundUp2(ref uint value)
+ {
+ while (value % 0x10 != 0)
+ value += 1;
+ }
+
+ public static void HexRoundUp2(ref int value)
+ {
+ while (value % 0x10 != 0)
+ value += 1;
+ }
+
+ public static string FillStrToCharCount(string str, int charCount, string fillVal = "0")
+ {
+ if (fillVal.Count() == 0)
+ return str;
+ if (charCount == 0)
+ return str;
+ while (str.Count() < charCount)
+ str = fillVal + str;
+ return str;
+ }
+
+ public static Geolayout.BackgroundPointers GetBackgroundAddressOfID(Geolayout.BackgroundIDs ID, bool EndAddr)
+ {
+ switch (ID)
+ {
+ case Geolayout.BackgroundIDs.AboveClouds:
+ {
+ if (EndAddr)
+ return Geolayout.BackgroundPointers.AboveCloudsEnd;
+ return Geolayout.BackgroundPointers.AboveCloudsStart;
+ }
+
+ case Geolayout.BackgroundIDs.BelowClouds:
+ {
+ if (EndAddr)
+ return Geolayout.BackgroundPointers.BelowCloudsEnd;
+ return Geolayout.BackgroundPointers.BelowCloudsStart;
+ }
+
+ case Geolayout.BackgroundIDs.Cavern:
+ {
+ if (EndAddr)
+ return Geolayout.BackgroundPointers.CavernEnd;
+ return Geolayout.BackgroundPointers.CavernStart;
+ }
+
+ case Geolayout.BackgroundIDs.Desert:
+ {
+ if (EndAddr)
+ return Geolayout.BackgroundPointers.DesertEnd;
+ return Geolayout.BackgroundPointers.DesertStart;
+ }
+
+ case Geolayout.BackgroundIDs.FlamingSky:
+ {
+ if (EndAddr)
+ return Geolayout.BackgroundPointers.FlamingSkyEnd;
+ return Geolayout.BackgroundPointers.FlamingSkyStart;
+ }
+
+ case Geolayout.BackgroundIDs.HauntedForest:
+ {
+ if (EndAddr)
+ return Geolayout.BackgroundPointers.HauntedForestEnd;
+ return Geolayout.BackgroundPointers.HauntedForestStart;
+ }
+
+ case Geolayout.BackgroundIDs.Ocean:
+ {
+ if (EndAddr)
+ return Geolayout.BackgroundPointers.OceanEnd;
+ return Geolayout.BackgroundPointers.OceanStart;
+ }
+
+ case Geolayout.BackgroundIDs.PurpleClouds:
+ {
+ if (EndAddr)
+ return Geolayout.BackgroundPointers.PurpleCloudsEnd;
+ return Geolayout.BackgroundPointers.PurpleCloudsStart;
+ }
+
+ case Geolayout.BackgroundIDs.SnowyMountains:
+ {
+ if (EndAddr)
+ return Geolayout.BackgroundPointers.SnowyMountainsEnd;
+ return Geolayout.BackgroundPointers.SnowyMountainsStart;
+ }
+
+ case Geolayout.BackgroundIDs.UnderwaterCity:
+ {
+ if (EndAddr)
+ return Geolayout.BackgroundPointers.UnderwaterCityEnd;
+ return Geolayout.BackgroundPointers.UnderwaterCityStart;
+ }
}
- internal static byte[] CompressData(Stream input, CompressionLevel compressionLevel)
+ return EndAddr ? Geolayout.BackgroundPointers.OceanEnd : Geolayout.BackgroundPointers.OceanStart;
+ }
+
+ public static string CommandByteArrayToString(byte[] bytes)
+ {
+ string res = string.Empty;
+ foreach (byte b in bytes)
{
- var output = new MemoryStream();
- input.Position = 0;
-
- using (var compressor = new DeflateStream(output, compressionLevel, true))
- input.CopyTo(compressor);
-
- var res = output.ToArray();
- output.Close();
- return res;
- }
-
- internal static void DecompressData(byte[] input, Stream output)
- {
- using (var sInput = new MemoryStream(input))
+ if (!string.IsNullOrEmpty(res))
{
- using (var decompressor = new DeflateStream(sInput, CompressionMode.Decompress, true))
- decompressor.CopyTo(output);
+ res += " ";
}
+
+ res += b.ToString("X2");
+ }
+
+ return res;
+ }
+
+ internal static byte[] CompressData(Stream input, CompressionLevel compressionLevel)
+ {
+ var output = new MemoryStream();
+ input.Position = 0;
+
+ using (var compressor = new DeflateStream(output, compressionLevel, true))
+ input.CopyTo(compressor);
+
+ var res = output.ToArray();
+ output.Close();
+ return res;
+ }
+
+ internal static void DecompressData(byte[] input, Stream output)
+ {
+ using (var sInput = new MemoryStream(input))
+ {
+ using (var decompressor = new DeflateStream(sInput, CompressionMode.Decompress, true))
+ decompressor.CopyTo(output);
}
}
}
\ No newline at end of file
diff --git a/SM64Lib/Geolayout/BackgroundIDs.cs b/SM64Lib/Geolayout/BackgroundIDs.cs
index f4560ce..67accd6 100644
--- a/SM64Lib/Geolayout/BackgroundIDs.cs
+++ b/SM64Lib/Geolayout/BackgroundIDs.cs
@@ -1,18 +1,17 @@
-namespace SM64Lib.Geolayout
+namespace SM64Lib.Geolayout;
+
+public enum BackgroundIDs : byte
{
- public enum BackgroundIDs : byte
- {
- HauntedForest = 0x6,
- SnowyMountains = 0x4,
- Desert = 0x5,
- Ocean = 0x0,
- UnderwaterCity = 0x2,
- BelowClouds = 0x8,
- AboveClouds = 0x3,
- Cavern = 0x7,
- FlamingSky = 0x1,
- PurpleClouds = 0x9,
- Custom = 0xA
- }
+ HauntedForest = 0x6,
+ SnowyMountains = 0x4,
+ Desert = 0x5,
+ Ocean = 0x0,
+ UnderwaterCity = 0x2,
+ BelowClouds = 0x8,
+ AboveClouds = 0x3,
+ Cavern = 0x7,
+ FlamingSky = 0x1,
+ PurpleClouds = 0x9,
+ Custom = 0xA
}
\ No newline at end of file
diff --git a/SM64Lib/Geolayout/BackgroundPointers.cs b/SM64Lib/Geolayout/BackgroundPointers.cs
index 3dd546c..139fa8e 100644
--- a/SM64Lib/Geolayout/BackgroundPointers.cs
+++ b/SM64Lib/Geolayout/BackgroundPointers.cs
@@ -1,27 +1,26 @@
-namespace SM64Lib.Geolayout
+namespace SM64Lib.Geolayout;
+
+public enum BackgroundPointers
{
- public enum BackgroundPointers
- {
- HauntedForestStart = 0xC3B030, // &HC3AFD5
- HauntedForestEnd = 0xC4F970, // &HC4F915
- SnowyMountainsStart = 0xB5D8B0, // &HB5D855
- SnowyMountainsEnd = 0xB7D9F0, // &HB7D995
- DesertStart = 0xC12EF0, // &HC12E95
- DesertEnd = 0xC33030, // &HC32FD5
- OceanStart = 0xB35770, // &HB35715
- OceanEnd = 0xB558B0, // &HB55855
- UnderwaterCityStart = 0xBC2C70, // &HBC2C15
- UnderwaterCityEnd = 0xBE2DB0, // &HBE2D55
- BelowCloudsStart = 0xB859F0, // &HB85995
- BelowCloudsEnd = 0xB9A330, // &HB9A2D5
- AboveCloudsStart = 0xBEADB0, // &HBEAD55
- AboveCloudsEnd = 0xC0AEF0, // &HC0AE95
- CavernStart = 0xC57970, // &HC57915
- CavernEnd = 0xC77AB0, // &HC77A55
- FlamingSkyStart = 0xBA2330, // &HBA22D5
- FlamingSkyEnd = 0xBBAC70, // &HBBAC15
- PurpleCloudsStart = 0xC7FAB0, // &HC7FA55
- PurpleCloudsEnd = 0xC9FBF0 // &HC9FB95
- }
+ HauntedForestStart = 0xC3B030, // &HC3AFD5
+ HauntedForestEnd = 0xC4F970, // &HC4F915
+ SnowyMountainsStart = 0xB5D8B0, // &HB5D855
+ SnowyMountainsEnd = 0xB7D9F0, // &HB7D995
+ DesertStart = 0xC12EF0, // &HC12E95
+ DesertEnd = 0xC33030, // &HC32FD5
+ OceanStart = 0xB35770, // &HB35715
+ OceanEnd = 0xB558B0, // &HB55855
+ UnderwaterCityStart = 0xBC2C70, // &HBC2C15
+ UnderwaterCityEnd = 0xBE2DB0, // &HBE2D55
+ BelowCloudsStart = 0xB859F0, // &HB85995
+ BelowCloudsEnd = 0xB9A330, // &HB9A2D5
+ AboveCloudsStart = 0xBEADB0, // &HBEAD55
+ AboveCloudsEnd = 0xC0AEF0, // &HC0AE95
+ CavernStart = 0xC57970, // &HC57915
+ CavernEnd = 0xC77AB0, // &HC77A55
+ FlamingSkyStart = 0xBA2330, // &HBA22D5
+ FlamingSkyEnd = 0xBBAC70, // &HBBAC15
+ PurpleCloudsStart = 0xC7FAB0, // &HC7FA55
+ PurpleCloudsEnd = 0xC9FBF0 // &HC9FB95
}
\ No newline at end of file
diff --git a/SM64Lib/Geolayout/CameraFrustrum.cs b/SM64Lib/Geolayout/CameraFrustrum.cs
index 78738d5..81d6a8f 100644
--- a/SM64Lib/Geolayout/CameraFrustrum.cs
+++ b/SM64Lib/Geolayout/CameraFrustrum.cs
@@ -1,20 +1,13 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+namespace SM64Lib.Geolayout;
-namespace SM64Lib.Geolayout
+public class CameraFrustrum
{
- public class CameraFrustrum
- {
- ///
- /// This is essentially render distance of geometry.
- ///
- public short CameraFar { get; set; } = 0x7530;
- ///
- /// Defines how close to the camera geometry will render.
- ///
- public short CameraNear { get; set; } = 0x64;
- }
+ ///
+ /// This is essentially render distance of geometry.
+ ///
+ public short CameraFar { get; set; } = 0x7530;
+ ///
+ /// Defines how close to the camera geometry will render.
+ ///
+ public short CameraNear { get; set; } = 0x64;
}
diff --git a/SM64Lib/Geolayout/CameraPresets.cs b/SM64Lib/Geolayout/CameraPresets.cs
index 3ffd72d..c1e1148 100644
--- a/SM64Lib/Geolayout/CameraPresets.cs
+++ b/SM64Lib/Geolayout/CameraPresets.cs
@@ -1,23 +1,22 @@
-namespace SM64Lib.Geolayout
+namespace SM64Lib.Geolayout;
+
+public enum CameraPresets
{
- public enum CameraPresets
- {
- OpenCamera = 0x1,
- TickTockClock,
- SecretAquarium,
- InsideCastle,
- Unmoving,
- MarioFacingObject,
- Unmoving1,
- UnderwaterCamera,
- PeachSlideCamera,
- InsideCannon,
- BowserFightsDistant,
- CloseCameraCrashes,
- FixedReferencePoint,
- PlattfromLevels,
- Unmoving2,
- FreeRoamCamera
- }
+ OpenCamera = 0x1,
+ TickTockClock,
+ SecretAquarium,
+ InsideCastle,
+ Unmoving,
+ MarioFacingObject,
+ Unmoving1,
+ UnderwaterCamera,
+ PeachSlideCamera,
+ InsideCannon,
+ BowserFightsDistant,
+ CloseCameraCrashes,
+ FixedReferencePoint,
+ PlattfromLevels,
+ Unmoving2,
+ FreeRoamCamera
}
\ No newline at end of file
diff --git a/SM64Lib/Geolayout/DefaultGeolayers.cs b/SM64Lib/Geolayout/DefaultGeolayers.cs
index f6c6797..3c48fa0 100644
--- a/SM64Lib/Geolayout/DefaultGeolayers.cs
+++ b/SM64Lib/Geolayout/DefaultGeolayers.cs
@@ -1,15 +1,14 @@
-namespace SM64Lib.Geolayout
+namespace SM64Lib.Geolayout;
+
+public enum DefaultGeolayers
{
- public enum DefaultGeolayers
- {
- SolidNoAntiAlias,
- Solid,
- SolidDecal,
- TranslucentDecal,
- Alpha,
- Translucent,
- TranslucentDecal2,
- TranslucentDecal3
- }
+ SolidNoAntiAlias,
+ Solid,
+ SolidDecal,
+ TranslucentDecal,
+ Alpha,
+ Translucent,
+ TranslucentDecal2,
+ TranslucentDecal3
}
\ No newline at end of file
diff --git a/SM64Lib/Geolayout/EnvironmentEffects.cs b/SM64Lib/Geolayout/EnvironmentEffects.cs
index 9504db9..334c2d2 100644
--- a/SM64Lib/Geolayout/EnvironmentEffects.cs
+++ b/SM64Lib/Geolayout/EnvironmentEffects.cs
@@ -1,14 +1,13 @@
-namespace SM64Lib.Geolayout
+namespace SM64Lib.Geolayout;
+
+public enum EnvironmentEffects
{
- public enum EnvironmentEffects
- {
- NoEffect = 0x0,
- Snow = 0x1,
- Bllizard = 0x3,
- BetaFlower = 0xB,
- Lava = 0xC,
- WaterRelated1 = 0xD,
- WaterRelated2 = 0x2
- }
+ NoEffect = 0x0,
+ Snow = 0x1,
+ Bllizard = 0x3,
+ BetaFlower = 0xB,
+ Lava = 0xC,
+ WaterRelated1 = 0xD,
+ WaterRelated2 = 0x2
}
\ No newline at end of file
diff --git a/SM64Lib/Geolayout/GeoAsmPointer.cs b/SM64Lib/Geolayout/GeoAsmPointer.cs
index 8ae265c..726fd32 100644
--- a/SM64Lib/Geolayout/GeoAsmPointer.cs
+++ b/SM64Lib/Geolayout/GeoAsmPointer.cs
@@ -1,10 +1,9 @@
-namespace SM64Lib.Geolayout
+namespace SM64Lib.Geolayout;
+
+public enum GeoAsmPointer : uint
{
- public enum GeoAsmPointer : uint
- {
- EnvironmentEffect = 0x802761D0,
- Water = 0x802D104C,
- Unknown = 0x802CD1E8
- }
+ EnvironmentEffect = 0x802761D0,
+ Water = 0x802D104C,
+ Unknown = 0x802CD1E8
}
\ No newline at end of file
diff --git a/SM64Lib/Geolayout/Geolayout.cs b/SM64Lib/Geolayout/Geolayout.cs
index d2751da..bd5c2ca 100644
--- a/SM64Lib/Geolayout/Geolayout.cs
+++ b/SM64Lib/Geolayout/Geolayout.cs
@@ -1,380 +1,378 @@
-using System.Collections.Generic;
+using global::SM64Lib.Geolayout.Script;
+using global::SM64Lib.Geolayout.Script.Commands;
using global::System.IO;
using Microsoft.VisualBasic;
-using Microsoft.VisualBasic.CompilerServices;
-using global::SM64Lib.Geolayout.Script;
-using global::SM64Lib.Geolayout.Script.Commands;
using Newtonsoft.Json;
using System;
+using System.Collections.Generic;
-namespace SM64Lib.Geolayout
+namespace SM64Lib.Geolayout;
+
+public class Geolayout
{
- public class Geolayout
+ [JsonProperty]
+ private int IndexForGeopointers = -1;
+
+ public Geolayoutscript Geolayoutscript { get; set; } = new Geolayoutscript();
+ public CameraPresets CameraPreset { get; set; } = CameraPresets.OpenCamera;
+ public EnvironmentEffects EnvironmentEffect { get; set; } = default;
+ public List GeopointerOffsets { get; set; } = new List();
+ public List Geopointers { get; set; } = new List();
+ public int NewGeoOffset { get; set; } = 0;
+ public bool Closed { get; set; } = false;
+ public ObjectShadow ObjectShadow { get; set; } = new ObjectShadow();
+ public CameraFrustrum CameraFrustrum { get; set; } = new CameraFrustrum();
+
+ public int Length
{
- [JsonProperty]
- private int IndexForGeopointers = -1;
-
- public Geolayoutscript Geolayoutscript { get; set; } = new Geolayoutscript();
- public CameraPresets CameraPreset { get; set; } = CameraPresets.OpenCamera;
- public EnvironmentEffects EnvironmentEffect { get; set; } = default;
- public List GeopointerOffsets { get; set; } = new List();
- public List Geopointers { get; set; } = new List();
- public int NewGeoOffset { get; set; } = 0;
- public bool Closed { get; set; } = false;
- public ObjectShadow ObjectShadow { get; set; } = new ObjectShadow();
- public CameraFrustrum CameraFrustrum { get; set; } = new CameraFrustrum();
-
- public int Length
- {
- get
- {
- int tLength = Geopointers.Count * 8;
- foreach (var c in Geolayoutscript)
- tLength += (int)c.Length;
- return tLength;
- }
- }
-
- private void RemoveOldGeopointerCommands()
- {
- var ToRemove = new List();
- foreach (GeolayoutCommand c in Geolayoutscript)
- {
- if (c.CommandType == GeolayoutCommandTypes.LoadDisplaylist)
- {
- ToRemove.Add(c);
- }
- }
-
- foreach (GeolayoutCommand cmd in ToRemove)
- {
- Geolayoutscript.Remove(cmd);
- cmd.Close();
- }
- }
-
- private List GetGeopointersFromGeolayoutScript(Geolayoutscript script)
- {
- List geopointers = new List();
- int geolayoutCommandIndex = 0;
- var curMdlScale = System.Numerics.Vector3.One;
- var curMdlOffset = System.Numerics.Vector3.Zero;
- foreach (GeolayoutCommand geolayoutCommand in script)
- {
- var referenceCommand = geolayoutCommand;
- if (geolayoutCommand.CommandType == GeolayoutCommandTypes.LoadDisplaylist)
- {
- geopointers.Add(new Geopointer(
- cgLoadDisplayList.GetDrawingLayer(ref referenceCommand),
- cgLoadDisplayList.GetSegGeopointer(ref referenceCommand),
- curMdlScale,
- curMdlOffset,
- geolayoutCommandIndex
- ));
- }
- geolayoutCommandIndex += 1;
- }
- return geopointers;
- }
-
- public Geolayout(NewScriptCreationMode mode)
- {
- switch (mode)
- {
- case NewScriptCreationMode.Level:
- {
- {
- var withBlock = Geolayoutscript;
- withBlock.Add(new GeolayoutCommand(new byte[] { 0x8, 0x0, 0x0, 0xA, 0x0, 0xA0, 0x0, 0x78, 0x0, 0xA0, 0x0, 0x78 }));
- withBlock.Add(new GeolayoutCommand(new byte[] { 0x4, 0x0, 0x0, 0x0 }));
- withBlock.Add(new GeolayoutCommand(new byte[] { 0xC, 0x0, 0x0, 0x0 }));
- withBlock.Add(new GeolayoutCommand(new byte[] { 0x4, 0x0, 0x0, 0x0 }));
- withBlock.Add(new GeolayoutCommand(new byte[] { 0x9, 0x0, 0x0, 0x64 }));
- withBlock.Add(new GeolayoutCommand(new byte[] { 0x4, 0x0, 0x0, 0x0 }));
- withBlock.Add(new GeolayoutCommand(new byte[] { 0x19, 0x0, 0x0, 0x0, 0x80, 0x27, 0x63, 0xD4 }));
- withBlock.Add(new GeolayoutCommand(new byte[] { 0x5, 0x0, 0x0, 0x0 }));
- withBlock.Add(new GeolayoutCommand(new byte[] { 0x5, 0x0, 0x0, 0x0 }));
- withBlock.Add(new GeolayoutCommand(new byte[] { 0xC, 0x1, 0x0, 0x0 }));
- withBlock.Add(new GeolayoutCommand(new byte[] { 0x4, 0x0, 0x0, 0x0 }));
- withBlock.Add(new GeolayoutCommand(new byte[] { 0xA, 0x1, 0x0, 0x2D, 0x0, 0x64, 0x75, 0x30, 0x80, 0x29, 0xAA, 0x3C }));
- withBlock.Add(new GeolayoutCommand(new byte[] { 0x4, 0x0, 0x0, 0x0 }));
- withBlock.Add(new GeolayoutCommand("0F 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 80 28 7D 30"));
- withBlock.Add(new GeolayoutCommand(new byte[] { 0x4, 0x0, 0x0, 0x0 }));
- IndexForGeopointers = 15;
- // .Add(New GeolayoutCommand({&H15, &H1, &H0, &H0, &H0, &H0, &H0, &H0}))
- withBlock.Add(new GeolayoutCommand(new byte[] { 0x17, 0x0, 0x0, 0x0 }));
- withBlock.Add(new GeolayoutCommand(new byte[] { 0x18, 0x0, 0x0, 0x0, 0x80, 0x27, 0x61, 0xD0 }));
- withBlock.Add(new GeolayoutCommand(new byte[] { 0x18, 0x0, 0x50, 0x0, 0x80, 0x2D, 0x10, 0x4C })); // Water
- withBlock.Add(new GeolayoutCommand(new byte[] { 0x18, 0x0, 0x50, 0x1, 0x80, 0x2D, 0x10, 0x4C })); // Toxic Haze
- withBlock.Add(new GeolayoutCommand(new byte[] { 0x18, 0x0, 0x50, 0x2, 0x80, 0x2D, 0x10, 0x4C })); // Mist
- withBlock.Add(new GeolayoutCommand(new byte[] { 0x5, 0x0, 0x0, 0x0 }));
- withBlock.Add(new GeolayoutCommand(new byte[] { 0x5, 0x0, 0x0, 0x0 }));
- withBlock.Add(new GeolayoutCommand(new byte[] { 0x5, 0x0, 0x0, 0x0 }));
- withBlock.Add(new GeolayoutCommand(new byte[] { 0xC, 0x0, 0x0, 0x0 }));
- withBlock.Add(new GeolayoutCommand(new byte[] { 0x4, 0x0, 0x0, 0x0 }));
- withBlock.Add(new GeolayoutCommand(new byte[] { 0x18, 0x0, 0x0, 0x0, 0x80, 0x2C, 0xD1, 0xE8 }));
- withBlock.Add(new GeolayoutCommand(new byte[] { 0x5, 0x0, 0x0, 0x0 }));
- withBlock.Add(new GeolayoutCommand(new byte[] { 0x5, 0x0, 0x0, 0x0 }));
- withBlock.Add(new GeolayoutCommand(new byte[] { 0x1, 0x0, 0x0, 0x0 }));
- }
-
- break;
- }
-
- case NewScriptCreationMode.Object:
- {
- {
- var withBlock1 = Geolayoutscript;
- withBlock1.Add(new GeolayoutCommand("20 00 0F A0"));
- withBlock1.Add(new GeolayoutCommand("04 00 00 00"));
- IndexForGeopointers = 2;
- withBlock1.Add(new GeolayoutCommand("05 00 00 00"));
- withBlock1.Add(new GeolayoutCommand("01 00 00 00"));
- }
-
- break;
- }
- }
- }
-
- public void Read(byte[] data, byte bankID)
- {
- RenewGeolayout();
- Geolayoutscript.Read(data, bankID);
- ParseGeolayout();
- }
-
- public void Read(RomManager rommgr, int segAddress)
- {
- RenewGeolayout();
- Geolayoutscript.Read(rommgr, segAddress);
- ParseGeolayout();
- }
-
- private void RenewGeolayout()
- {
- if (!Closed) Close();
- Closed = false;
- Geolayoutscript.Clear();
- Geopointers.Clear();
- GeopointerOffsets.Clear();
- Geolayoutscript = new Geolayoutscript();
- ObjectShadow = new ObjectShadow();
- CameraFrustrum = new CameraFrustrum();
- }
-
- public void ParseGeolayout()
- {
- var ToRemove = new List();
- int cIndex = 0;
- var curMdlScale = System.Numerics.Vector3.One;
- var curMdlOffset = System.Numerics.Vector3.Zero;
-
- foreach (GeolayoutCommand fec in Geolayoutscript)
- {
- var c = fec;
- var switchExpr = c.CommandType;
-
- switch (switchExpr)
- {
- case GeolayoutCommandTypes.CameraPreset:
- CameraPreset = (CameraPresets)cgCameraPreset.GetCameraPreset(ref c);
- break;
- case GeolayoutCommandTypes.x18:
- var switchExpr1 = (uint)cgx18.GetAsmPointer(ref c);
- switch (switchExpr1)
- {
- case 0x802761D0:
- EnvironmentEffect = (EnvironmentEffects)cgx18.GetParam1(ref c);
- break;
- }
- break;
- case GeolayoutCommandTypes.LoadDisplaylist:
- if (Geopointers.Count == 0)
- IndexForGeopointers = cIndex;
- Geopointers.Add(new Geopointer(cgLoadDisplayList.GetDrawingLayer(ref c), cgLoadDisplayList.GetSegGeopointer(ref c), curMdlScale, curMdlOffset, cIndex));
- break;
- case GeolayoutCommandTypes.ObjectShadown:
- cgObjectShadow.GetShadow(c, ObjectShadow);
- ObjectShadow.Enabled = true;
- break;
- case GeolayoutCommandTypes.DrawingDistance:
- ObjectShadow.Enabled = false;
- break;
- case GeolayoutCommandTypes.CameraFrustrum:
- cgCameraFrustrum.GetCameraFrustrum(c, CameraFrustrum);
- break;
- }
-
- cIndex += 1;
- }
-
- // Remove Geopointercommands
- RemoveOldGeopointerCommands();
- }
-
- public void Write(Stream s, int StartOffset)
- {
- NewGeoOffset = StartOffset;
- var commandsToRemove = new List();
- GeolayoutCommand cmdObjectShadow = null;
- GeolayoutCommand cmdDrawingDistance = null;
- int tIndexForGeoPointer = IndexForGeopointers;
- var isForLevel = false;
-
- // Einstellungen übernehmen
- int currentPosition = 0;
- foreach (GeolayoutCommand fec in Geolayoutscript)
- {
- var c = fec;
- var switchExpr = c.CommandType;
-
- switch (switchExpr)
- {
- case GeolayoutCommandTypes.CameraPreset:
- cgCameraPreset.SetCameraPreset(ref c, Convert.ToByte(CameraPreset));
- break;
- case GeolayoutCommandTypes.x18:
- var switchExpr1 = cgx18.GetAsmPointer(ref c);
- switch ((GeoAsmPointer)switchExpr1)
- {
- case GeoAsmPointer.EnvironmentEffect:
- cgx18.SetParam1(ref c, (ushort)EnvironmentEffect);
- break;
- }
- break;
- case GeolayoutCommandTypes.ObjectShadown:
- if (ObjectShadow.Enabled)
- cmdObjectShadow = c;
- else
- commandsToRemove.Add(c);
- break;
- case GeolayoutCommandTypes.DrawingDistance:
- if (ObjectShadow.Enabled)
- commandsToRemove.Add(c);
- else
- cmdDrawingDistance = c;
- break;
- case GeolayoutCommandTypes.CameraFrustrum:
- cgCameraFrustrum.SetCameraFrustrum(c, CameraFrustrum);
- isForLevel = true;
- break;
- case GeolayoutCommandTypes.SetScreenRenderArea:
- isForLevel = true;
- break;
- }
-
- currentPosition += (int)c.Length;
- }
-
- // Insert Geopointers
- foreach (Geopointer g in Geopointers)
- {
- var tcommand = new GeolayoutCommand(new byte[] { 0x15, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 });
- cgLoadDisplayList.SetDrawingLayer(ref tcommand, g.Layer);
- cgLoadDisplayList.SetSegGeopointer(ref tcommand, g.SegPointer);
- if (g.Index == -1)
- {
- Geolayoutscript.Insert(tIndexForGeoPointer, tcommand);
- }
- else
- {
- Geolayoutscript.Insert(g.Index, tcommand);
- }
-
- tIndexForGeoPointer += 1;
- }
-
- // Remove all other commands to remove
- foreach (var cmd in commandsToRemove)
- {
- Geolayoutscript.Remove(cmd);
- cmd.Close();
- }
-
- // Add Geolayout Start command for non-level geolayouts
- if (!isForLevel)
- {
- if (ObjectShadow.Enabled)
- {
- // Add Object Shadow
- if (cmdObjectShadow is null)
- {
- cmdObjectShadow = new GeolayoutCommand("16 00 00 00 00 00 00 00");
- Geolayoutscript.Insert(0, cmdObjectShadow);
- }
- cgObjectShadow.SetShadow(cmdObjectShadow, ObjectShadow);
- }
- else
- {
- if (cmdDrawingDistance == null)
- Geolayoutscript.Insert(0, new GeolayoutCommand("20 00 0F A0"));
- }
- }
-
- // Update Geopointer indexes after adding and removing other commands
- Geopointers = GetGeopointersFromGeolayoutScript(Geolayoutscript);
-
- // Write Geolayout to ROM
- Geolayoutscript.Write(s, StartOffset);
-
- // Remove Geopointercommands again
- RemoveOldGeopointerCommands();
- }
-
- public void Close()
+ get
{
+ int tLength = Geopointers.Count * 8;
foreach (var c in Geolayoutscript)
- c.Close();
- }
-
- public override string ToString()
- {
- string output = "";
- foreach (var cmd in Geolayoutscript)
- {
- string tbytelist = "";
- foreach (byte b in cmd.ToArray())
- {
- if (tbytelist != string.Empty)
- tbytelist += " ";
- tbytelist += Conversion.Hex(b);
- }
-
- if (output != string.Empty)
- output += Environment.NewLine;
- output += tbytelist;
- }
-
- return output;
- }
-
- public string ToString(GeolayoutCommandCollection Geolayoutscript)
- {
- string output = "";
- foreach (var cmd in Geolayoutscript)
- {
- string tbytelist = "";
- foreach (byte b in cmd.ToArray())
- {
- if (tbytelist != string.Empty)
- tbytelist += " ";
- tbytelist += Conversion.Hex(b);
- }
-
- if (output != string.Empty)
- output += Environment.NewLine;
- output += tbytelist;
- }
-
- return output;
- }
-
- public enum NewScriptCreationMode
- {
- None,
- Level,
- Object
+ tLength += (int)c.Length;
+ return tLength;
}
}
+
+ private void RemoveOldGeopointerCommands()
+ {
+ var ToRemove = new List();
+ foreach (GeolayoutCommand c in Geolayoutscript)
+ {
+ if (c.CommandType == GeolayoutCommandTypes.LoadDisplaylist)
+ {
+ ToRemove.Add(c);
+ }
+ }
+
+ foreach (GeolayoutCommand cmd in ToRemove)
+ {
+ Geolayoutscript.Remove(cmd);
+ cmd.Close();
+ }
+ }
+
+ private List GetGeopointersFromGeolayoutScript(Geolayoutscript script)
+ {
+ List geopointers = new List();
+ int geolayoutCommandIndex = 0;
+ var curMdlScale = System.Numerics.Vector3.One;
+ var curMdlOffset = System.Numerics.Vector3.Zero;
+ foreach (GeolayoutCommand geolayoutCommand in script)
+ {
+ var referenceCommand = geolayoutCommand;
+ if (geolayoutCommand.CommandType == GeolayoutCommandTypes.LoadDisplaylist)
+ {
+ geopointers.Add(new Geopointer(
+ cgLoadDisplayList.GetDrawingLayer(ref referenceCommand),
+ cgLoadDisplayList.GetSegGeopointer(ref referenceCommand),
+ curMdlScale,
+ curMdlOffset,
+ geolayoutCommandIndex
+ ));
+ }
+ geolayoutCommandIndex += 1;
+ }
+ return geopointers;
+ }
+
+ public Geolayout(NewScriptCreationMode mode)
+ {
+ switch (mode)
+ {
+ case NewScriptCreationMode.Level:
+ {
+ {
+ var withBlock = Geolayoutscript;
+ withBlock.Add(new GeolayoutCommand(new byte[] { 0x8, 0x0, 0x0, 0xA, 0x0, 0xA0, 0x0, 0x78, 0x0, 0xA0, 0x0, 0x78 }));
+ withBlock.Add(new GeolayoutCommand(new byte[] { 0x4, 0x0, 0x0, 0x0 }));
+ withBlock.Add(new GeolayoutCommand(new byte[] { 0xC, 0x0, 0x0, 0x0 }));
+ withBlock.Add(new GeolayoutCommand(new byte[] { 0x4, 0x0, 0x0, 0x0 }));
+ withBlock.Add(new GeolayoutCommand(new byte[] { 0x9, 0x0, 0x0, 0x64 }));
+ withBlock.Add(new GeolayoutCommand(new byte[] { 0x4, 0x0, 0x0, 0x0 }));
+ withBlock.Add(new GeolayoutCommand(new byte[] { 0x19, 0x0, 0x0, 0x0, 0x80, 0x27, 0x63, 0xD4 }));
+ withBlock.Add(new GeolayoutCommand(new byte[] { 0x5, 0x0, 0x0, 0x0 }));
+ withBlock.Add(new GeolayoutCommand(new byte[] { 0x5, 0x0, 0x0, 0x0 }));
+ withBlock.Add(new GeolayoutCommand(new byte[] { 0xC, 0x1, 0x0, 0x0 }));
+ withBlock.Add(new GeolayoutCommand(new byte[] { 0x4, 0x0, 0x0, 0x0 }));
+ withBlock.Add(new GeolayoutCommand(new byte[] { 0xA, 0x1, 0x0, 0x2D, 0x0, 0x64, 0x75, 0x30, 0x80, 0x29, 0xAA, 0x3C }));
+ withBlock.Add(new GeolayoutCommand(new byte[] { 0x4, 0x0, 0x0, 0x0 }));
+ withBlock.Add(new GeolayoutCommand("0F 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 80 28 7D 30"));
+ withBlock.Add(new GeolayoutCommand(new byte[] { 0x4, 0x0, 0x0, 0x0 }));
+ IndexForGeopointers = 15;
+ // .Add(New GeolayoutCommand({&H15, &H1, &H0, &H0, &H0, &H0, &H0, &H0}))
+ withBlock.Add(new GeolayoutCommand(new byte[] { 0x17, 0x0, 0x0, 0x0 }));
+ withBlock.Add(new GeolayoutCommand(new byte[] { 0x18, 0x0, 0x0, 0x0, 0x80, 0x27, 0x61, 0xD0 }));
+ withBlock.Add(new GeolayoutCommand(new byte[] { 0x18, 0x0, 0x50, 0x0, 0x80, 0x2D, 0x10, 0x4C })); // Water
+ withBlock.Add(new GeolayoutCommand(new byte[] { 0x18, 0x0, 0x50, 0x1, 0x80, 0x2D, 0x10, 0x4C })); // Toxic Haze
+ withBlock.Add(new GeolayoutCommand(new byte[] { 0x18, 0x0, 0x50, 0x2, 0x80, 0x2D, 0x10, 0x4C })); // Mist
+ withBlock.Add(new GeolayoutCommand(new byte[] { 0x5, 0x0, 0x0, 0x0 }));
+ withBlock.Add(new GeolayoutCommand(new byte[] { 0x5, 0x0, 0x0, 0x0 }));
+ withBlock.Add(new GeolayoutCommand(new byte[] { 0x5, 0x0, 0x0, 0x0 }));
+ withBlock.Add(new GeolayoutCommand(new byte[] { 0xC, 0x0, 0x0, 0x0 }));
+ withBlock.Add(new GeolayoutCommand(new byte[] { 0x4, 0x0, 0x0, 0x0 }));
+ withBlock.Add(new GeolayoutCommand(new byte[] { 0x18, 0x0, 0x0, 0x0, 0x80, 0x2C, 0xD1, 0xE8 }));
+ withBlock.Add(new GeolayoutCommand(new byte[] { 0x5, 0x0, 0x0, 0x0 }));
+ withBlock.Add(new GeolayoutCommand(new byte[] { 0x5, 0x0, 0x0, 0x0 }));
+ withBlock.Add(new GeolayoutCommand(new byte[] { 0x1, 0x0, 0x0, 0x0 }));
+ }
+
+ break;
+ }
+
+ case NewScriptCreationMode.Object:
+ {
+ {
+ var withBlock1 = Geolayoutscript;
+ withBlock1.Add(new GeolayoutCommand("20 00 0F A0"));
+ withBlock1.Add(new GeolayoutCommand("04 00 00 00"));
+ IndexForGeopointers = 2;
+ withBlock1.Add(new GeolayoutCommand("05 00 00 00"));
+ withBlock1.Add(new GeolayoutCommand("01 00 00 00"));
+ }
+
+ break;
+ }
+ }
+ }
+
+ public void Read(byte[] data, byte bankID)
+ {
+ RenewGeolayout();
+ Geolayoutscript.Read(data, bankID);
+ ParseGeolayout();
+ }
+
+ public void Read(RomManager rommgr, int segAddress)
+ {
+ RenewGeolayout();
+ Geolayoutscript.Read(rommgr, segAddress);
+ ParseGeolayout();
+ }
+
+ private void RenewGeolayout()
+ {
+ if (!Closed) Close();
+ Closed = false;
+ Geolayoutscript.Clear();
+ Geopointers.Clear();
+ GeopointerOffsets.Clear();
+ Geolayoutscript = new Geolayoutscript();
+ ObjectShadow = new ObjectShadow();
+ CameraFrustrum = new CameraFrustrum();
+ }
+
+ public void ParseGeolayout()
+ {
+ var ToRemove = new List();
+ int cIndex = 0;
+ var curMdlScale = System.Numerics.Vector3.One;
+ var curMdlOffset = System.Numerics.Vector3.Zero;
+
+ foreach (GeolayoutCommand fec in Geolayoutscript)
+ {
+ var c = fec;
+ var switchExpr = c.CommandType;
+
+ switch (switchExpr)
+ {
+ case GeolayoutCommandTypes.CameraPreset:
+ CameraPreset = (CameraPresets)cgCameraPreset.GetCameraPreset(ref c);
+ break;
+ case GeolayoutCommandTypes.x18:
+ var switchExpr1 = (uint)cgx18.GetAsmPointer(ref c);
+ switch (switchExpr1)
+ {
+ case 0x802761D0:
+ EnvironmentEffect = (EnvironmentEffects)cgx18.GetParam1(ref c);
+ break;
+ }
+ break;
+ case GeolayoutCommandTypes.LoadDisplaylist:
+ if (Geopointers.Count == 0)
+ IndexForGeopointers = cIndex;
+ Geopointers.Add(new Geopointer(cgLoadDisplayList.GetDrawingLayer(ref c), cgLoadDisplayList.GetSegGeopointer(ref c), curMdlScale, curMdlOffset, cIndex));
+ break;
+ case GeolayoutCommandTypes.ObjectShadown:
+ cgObjectShadow.GetShadow(c, ObjectShadow);
+ ObjectShadow.Enabled = true;
+ break;
+ case GeolayoutCommandTypes.DrawingDistance:
+ ObjectShadow.Enabled = false;
+ break;
+ case GeolayoutCommandTypes.CameraFrustrum:
+ cgCameraFrustrum.GetCameraFrustrum(c, CameraFrustrum);
+ break;
+ }
+
+ cIndex += 1;
+ }
+
+ // Remove Geopointercommands
+ RemoveOldGeopointerCommands();
+ }
+
+ public void Write(Stream s, int StartOffset)
+ {
+ NewGeoOffset = StartOffset;
+ var commandsToRemove = new List();
+ GeolayoutCommand cmdObjectShadow = null;
+ GeolayoutCommand cmdDrawingDistance = null;
+ int tIndexForGeoPointer = IndexForGeopointers;
+ var isForLevel = false;
+
+ // Einstellungen übernehmen
+ int currentPosition = 0;
+ foreach (GeolayoutCommand fec in Geolayoutscript)
+ {
+ var c = fec;
+ var switchExpr = c.CommandType;
+
+ switch (switchExpr)
+ {
+ case GeolayoutCommandTypes.CameraPreset:
+ cgCameraPreset.SetCameraPreset(ref c, Convert.ToByte(CameraPreset));
+ break;
+ case GeolayoutCommandTypes.x18:
+ var switchExpr1 = cgx18.GetAsmPointer(ref c);
+ switch ((GeoAsmPointer)switchExpr1)
+ {
+ case GeoAsmPointer.EnvironmentEffect:
+ cgx18.SetParam1(ref c, (ushort)EnvironmentEffect);
+ break;
+ }
+ break;
+ case GeolayoutCommandTypes.ObjectShadown:
+ if (ObjectShadow.Enabled)
+ cmdObjectShadow = c;
+ else
+ commandsToRemove.Add(c);
+ break;
+ case GeolayoutCommandTypes.DrawingDistance:
+ if (ObjectShadow.Enabled)
+ commandsToRemove.Add(c);
+ else
+ cmdDrawingDistance = c;
+ break;
+ case GeolayoutCommandTypes.CameraFrustrum:
+ cgCameraFrustrum.SetCameraFrustrum(c, CameraFrustrum);
+ isForLevel = true;
+ break;
+ case GeolayoutCommandTypes.SetScreenRenderArea:
+ isForLevel = true;
+ break;
+ }
+
+ currentPosition += (int)c.Length;
+ }
+
+ // Insert Geopointers
+ foreach (Geopointer g in Geopointers)
+ {
+ var tcommand = new GeolayoutCommand(new byte[] { 0x15, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 });
+ cgLoadDisplayList.SetDrawingLayer(ref tcommand, g.Layer);
+ cgLoadDisplayList.SetSegGeopointer(ref tcommand, g.SegPointer);
+ if (g.Index == -1)
+ {
+ Geolayoutscript.Insert(tIndexForGeoPointer, tcommand);
+ }
+ else
+ {
+ Geolayoutscript.Insert(g.Index, tcommand);
+ }
+
+ tIndexForGeoPointer += 1;
+ }
+
+ // Remove all other commands to remove
+ foreach (var cmd in commandsToRemove)
+ {
+ Geolayoutscript.Remove(cmd);
+ cmd.Close();
+ }
+
+ // Add Geolayout Start command for non-level geolayouts
+ if (!isForLevel)
+ {
+ if (ObjectShadow.Enabled)
+ {
+ // Add Object Shadow
+ if (cmdObjectShadow is null)
+ {
+ cmdObjectShadow = new GeolayoutCommand("16 00 00 00 00 00 00 00");
+ Geolayoutscript.Insert(0, cmdObjectShadow);
+ }
+ cgObjectShadow.SetShadow(cmdObjectShadow, ObjectShadow);
+ }
+ else
+ {
+ if (cmdDrawingDistance == null)
+ Geolayoutscript.Insert(0, new GeolayoutCommand("20 00 0F A0"));
+ }
+ }
+
+ // Update Geopointer indexes after adding and removing other commands
+ Geopointers = GetGeopointersFromGeolayoutScript(Geolayoutscript);
+
+ // Write Geolayout to ROM
+ Geolayoutscript.Write(s, StartOffset);
+
+ // Remove Geopointercommands again
+ RemoveOldGeopointerCommands();
+ }
+
+ public void Close()
+ {
+ foreach (var c in Geolayoutscript)
+ c.Close();
+ }
+
+ public override string ToString()
+ {
+ string output = "";
+ foreach (var cmd in Geolayoutscript)
+ {
+ string tbytelist = "";
+ foreach (byte b in cmd.ToArray())
+ {
+ if (tbytelist != string.Empty)
+ tbytelist += " ";
+ tbytelist += Conversion.Hex(b);
+ }
+
+ if (output != string.Empty)
+ output += Environment.NewLine;
+ output += tbytelist;
+ }
+
+ return output;
+ }
+
+ public string ToString(GeolayoutCommandCollection Geolayoutscript)
+ {
+ string output = "";
+ foreach (var cmd in Geolayoutscript)
+ {
+ string tbytelist = "";
+ foreach (byte b in cmd.ToArray())
+ {
+ if (tbytelist != string.Empty)
+ tbytelist += " ";
+ tbytelist += Conversion.Hex(b);
+ }
+
+ if (output != string.Empty)
+ output += Environment.NewLine;
+ output += tbytelist;
+ }
+
+ return output;
+ }
+
+ public enum NewScriptCreationMode
+ {
+ None,
+ Level,
+ Object
+ }
}
\ No newline at end of file
diff --git a/SM64Lib/Geolayout/Geopointer.cs b/SM64Lib/Geolayout/Geopointer.cs
index 22e2a7e..ee432d3 100644
--- a/SM64Lib/Geolayout/Geopointer.cs
+++ b/SM64Lib/Geolayout/Geopointer.cs
@@ -1,42 +1,41 @@
using Newtonsoft.Json;
-namespace SM64Lib.Geolayout
+namespace SM64Lib.Geolayout;
+
+public class Geopointer
{
- public class Geopointer
+ public byte Layer { get; set; } = default;
+ public int SegPointer { get; set; } = 0;
+ public int Index { get; set; } = -1;
+ public System.Numerics.Vector3 ModelScale { get; set; } = System.Numerics.Vector3.One;
+ public System.Numerics.Vector3 ModelOffset { get; set; } = System.Numerics.Vector3.Zero;
+
+ [JsonConstructor]
+ private Geopointer()
{
- public byte Layer { get; set; } = default;
- public int SegPointer { get; set; } = 0;
- public int Index { get; set; } = -1;
- public System.Numerics.Vector3 ModelScale { get; set; } = System.Numerics.Vector3.One;
- public System.Numerics.Vector3 ModelOffset { get; set; } = System.Numerics.Vector3.Zero;
+ }
- [JsonConstructor]
- private Geopointer()
- {
- }
+ public Geopointer(byte Layer) : this()
+ {
+ this.Layer = Layer;
+ }
- public Geopointer(byte Layer) : this()
- {
- this.Layer = Layer;
- }
+ public Geopointer(byte Layer, int SegPointer) : this(Layer)
+ {
+ this.SegPointer = SegPointer;
+ }
- public Geopointer(byte Layer, int SegPointer) : this(Layer)
- {
- this.SegPointer = SegPointer;
- }
+ public Geopointer(byte Layer, int SegPointer, System.Numerics.Vector3 mdlscale, System.Numerics.Vector3 mdloffset) : this(Layer, SegPointer)
+ {
+ ModelScale = mdlscale;
+ ModelOffset = mdloffset;
+ }
- public Geopointer(byte Layer, int SegPointer, System.Numerics.Vector3 mdlscale, System.Numerics.Vector3 mdloffset) : this(Layer, SegPointer)
- {
- ModelScale = mdlscale;
- ModelOffset = mdloffset;
- }
-
- public Geopointer(byte Layer, int SegPointer, System.Numerics.Vector3 mdlscale, System.Numerics.Vector3 mdloffset, int index) : this(Layer, SegPointer)
- {
- ModelScale = mdlscale;
- ModelOffset = mdloffset;
- Index = index;
- }
+ public Geopointer(byte Layer, int SegPointer, System.Numerics.Vector3 mdlscale, System.Numerics.Vector3 mdloffset, int index) : this(Layer, SegPointer)
+ {
+ ModelScale = mdlscale;
+ ModelOffset = mdloffset;
+ Index = index;
}
}
\ No newline at end of file
diff --git a/SM64Lib/Geolayout/ObjectShadow.cs b/SM64Lib/Geolayout/ObjectShadow.cs
index 1ac5dce..8cb61b2 100644
--- a/SM64Lib/Geolayout/ObjectShadow.cs
+++ b/SM64Lib/Geolayout/ObjectShadow.cs
@@ -1,16 +1,9 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+namespace SM64Lib.Geolayout;
-namespace SM64Lib.Geolayout
+public class ObjectShadow
{
- public class ObjectShadow
- {
- public bool Enabled { get; set; } = false;
- public ObjectShadowType Type { get; set; } = ObjectShadowType.Circle_9Verts;
- public short Scale { get; set; }
- public byte Solidity { get; set; } = 0xFF;
- }
+ public bool Enabled { get; set; } = false;
+ public ObjectShadowType Type { get; set; } = ObjectShadowType.Circle_9Verts;
+ public short Scale { get; set; }
+ public byte Solidity { get; set; } = 0xFF;
}
diff --git a/SM64Lib/Geolayout/ObjectShadowType.cs b/SM64Lib/Geolayout/ObjectShadowType.cs
index 000e4c6..9058fa7 100644
--- a/SM64Lib/Geolayout/ObjectShadowType.cs
+++ b/SM64Lib/Geolayout/ObjectShadowType.cs
@@ -1,24 +1,17 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+namespace SM64Lib.Geolayout;
-namespace SM64Lib.Geolayout
+public enum ObjectShadowType
{
- public enum ObjectShadowType
- {
- Circle_9Verts = 0,
- Circle_4Verts = 1,
- Circle_4Verts_Flat_Unused = 2,
- SquarePermanent = 10,
- SquareScaleable = 11,
- SquareTooglable = 12,
- /**
- * This defines an offset after which rectangular shadows with custom
- * widths and heights can be defined.
- */
- RectangleHardcodedOffset = 50,
- CirclePlayer = 99
- }
+ Circle_9Verts = 0,
+ Circle_4Verts = 1,
+ Circle_4Verts_Flat_Unused = 2,
+ SquarePermanent = 10,
+ SquareScaleable = 11,
+ SquareTooglable = 12,
+ /**
+ * This defines an offset after which rectangular shadows with custom
+ * widths and heights can be defined.
+ */
+ RectangleHardcodedOffset = 50,
+ CirclePlayer = 99
}
diff --git a/SM64Lib/Geolayout/Script/GeolayoutCommand.cs b/SM64Lib/Geolayout/Script/GeolayoutCommand.cs
index 038b8b9..30d1109 100644
--- a/SM64Lib/Geolayout/Script/GeolayoutCommand.cs
+++ b/SM64Lib/Geolayout/Script/GeolayoutCommand.cs
@@ -2,39 +2,38 @@
using Newtonsoft.Json;
using SM64Lib.Json;
-namespace SM64Lib.Geolayout.Script
+namespace SM64Lib.Geolayout.Script;
+
+[JsonConverter(typeof(GeolayoutscriptCommandJsonConverter))]
+public class GeolayoutCommand : BaseCommand
{
- [JsonConverter(typeof(GeolayoutscriptCommandJsonConverter))]
- public class GeolayoutCommand : BaseCommand
+ public GeolayoutCommand(byte[] bytes) : base(bytes)
{
- public GeolayoutCommand(byte[] bytes) : base(bytes)
+ }
+
+ public GeolayoutCommand() : base()
+ {
+ }
+
+ public GeolayoutCommand(string bytes, bool enabledHex = true) : base(bytes, enabledHex)
+ {
+ }
+
+ public override GeolayoutCommandTypes CommandType
+ {
+ get
{
+ Position = 0;
+ GeolayoutCommandTypes t = (GeolayoutCommandTypes)ReadByte();
+ Position = 0;
+ return t;
}
- public GeolayoutCommand() : base()
+ set
{
- }
-
- public GeolayoutCommand(string bytes, bool enabledHex = true) : base(bytes, enabledHex)
- {
- }
-
- public override GeolayoutCommandTypes CommandType
- {
- get
- {
- Position = 0;
- GeolayoutCommandTypes t = (GeolayoutCommandTypes)ReadByte();
- Position = 0;
- return t;
- }
-
- set
- {
- Position = 0;
- WriteByte((byte)value);
- Position = 0;
- }
+ Position = 0;
+ WriteByte((byte)value);
+ Position = 0;
}
}
}
\ No newline at end of file
diff --git a/SM64Lib/Geolayout/Script/GeolayoutCommandCollection.cs b/SM64Lib/Geolayout/Script/GeolayoutCommandCollection.cs
index 962f77f..da20439 100644
--- a/SM64Lib/Geolayout/Script/GeolayoutCommandCollection.cs
+++ b/SM64Lib/Geolayout/Script/GeolayoutCommandCollection.cs
@@ -1,18 +1,17 @@
using global::SM64Lib.Script;
-namespace SM64Lib.Geolayout.Script
-{
- public class GeolayoutCommandCollection : BaseCommandCollection
- {
- public int IndexOfFirst(GeolayoutCommandTypes cmdType)
- {
- for (int index = 0, loopTo = Count - 1; index <= loopTo; index++)
- {
- if (this[index].CommandType == cmdType)
- return index;
- }
+namespace SM64Lib.Geolayout.Script;
- return -1;
+public class GeolayoutCommandCollection : BaseCommandCollection
+{
+ public int IndexOfFirst(GeolayoutCommandTypes cmdType)
+ {
+ for (int index = 0, loopTo = Count - 1; index <= loopTo; index++)
+ {
+ if (this[index].CommandType == cmdType)
+ return index;
}
+
+ return -1;
}
}
\ No newline at end of file
diff --git a/SM64Lib/Geolayout/Script/GeolayoutCommandFunctions.cs b/SM64Lib/Geolayout/Script/GeolayoutCommandFunctions.cs
index 08bb254..f33ef06 100644
--- a/SM64Lib/Geolayout/Script/GeolayoutCommandFunctions.cs
+++ b/SM64Lib/Geolayout/Script/GeolayoutCommandFunctions.cs
@@ -1,5 +1,4 @@
using global::System.Numerics;
-using Microsoft.VisualBasic.CompilerServices;
using System;
namespace SM64Lib.Geolayout.Script
diff --git a/SM64Lib/Geolayout/Script/GeolayoutCommandTypes.cs b/SM64Lib/Geolayout/Script/GeolayoutCommandTypes.cs
index f05aa9d..9c2890a 100644
--- a/SM64Lib/Geolayout/Script/GeolayoutCommandTypes.cs
+++ b/SM64Lib/Geolayout/Script/GeolayoutCommandTypes.cs
@@ -1,37 +1,36 @@
-namespace SM64Lib.Geolayout.Script
+namespace SM64Lib.Geolayout.Script;
+
+public enum GeolayoutCommandTypes
{
- public enum GeolayoutCommandTypes
- {
- BranchAndStore = 0x0,
- EndOfGeolayout = 0x1,
- JumpToSegAddr = 0x2,
- JumpBack = 0x3,
- StartOfNode = 0x4,
- EndOfNode = 0x5,
- SetScreenRenderArea = 0x8,
- Scale1 = 0x9,
- CameraFrustrum = 0xA,
- x0B = 0xB,
- x0C = 0xC,
- x0D = 0xD,
- x0E = 0xE,
- CameraPreset = 0xF,
- x10 = 0x10,
- x11 = 0x11,
- x12 = 0x12,
- LoadDisplaylistWithOffset = 0x13,
- BillboardModel = 0x14,
- LoadDisplaylist = 0x15,
- ObjectShadown = 0x16,
- x17 = 0x17,
- x18 = 0x18,
- Background = 0x19,
- x1A = 0x1A,
- x1C = 0x1C,
- Scale2 = 0x1D,
- x1E = 0xE,
- x1f = 0xF,
- DrawingDistance = 0x20
- }
+ BranchAndStore = 0x0,
+ EndOfGeolayout = 0x1,
+ JumpToSegAddr = 0x2,
+ JumpBack = 0x3,
+ StartOfNode = 0x4,
+ EndOfNode = 0x5,
+ SetScreenRenderArea = 0x8,
+ Scale1 = 0x9,
+ CameraFrustrum = 0xA,
+ x0B = 0xB,
+ x0C = 0xC,
+ x0D = 0xD,
+ x0E = 0xE,
+ CameraPreset = 0xF,
+ x10 = 0x10,
+ x11 = 0x11,
+ x12 = 0x12,
+ LoadDisplaylistWithOffset = 0x13,
+ BillboardModel = 0x14,
+ LoadDisplaylist = 0x15,
+ ObjectShadown = 0x16,
+ x17 = 0x17,
+ x18 = 0x18,
+ Background = 0x19,
+ x1A = 0x1A,
+ x1C = 0x1C,
+ Scale2 = 0x1D,
+ x1E = 0xE,
+ x1f = 0xF,
+ DrawingDistance = 0x20
}
\ No newline at end of file
diff --git a/SM64Lib/Geolayout/Script/Geolayoutscript.cs b/SM64Lib/Geolayout/Script/Geolayoutscript.cs
index 2ca3969..fb7da9a 100644
--- a/SM64Lib/Geolayout/Script/Geolayoutscript.cs
+++ b/SM64Lib/Geolayout/Script/Geolayoutscript.cs
@@ -1,239 +1,237 @@
-using System.Collections.Generic;
+using global::SM64Lib.Data;
using global::System.IO;
-using System.Threading.Tasks;
-using Microsoft.VisualBasic.CompilerServices;
-using global::SM64Lib.Data;
using SM64Lib.SegmentedBanking;
using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
-namespace SM64Lib.Geolayout.Script
+namespace SM64Lib.Geolayout.Script;
+
+public class Geolayoutscript : GeolayoutCommandCollection
{
- public class Geolayoutscript : GeolayoutCommandCollection
+ public List GeopointerOffsets = new List();
+
+ public Geolayoutscript()
{
- public List GeopointerOffsets = new List();
+ }
- public Geolayoutscript()
- {
- }
+ public Task ReadAsync(RomManager rommgr, int segAddress)
+ {
+ var t = new Task(() => Read(rommgr, segAddress));
+ t.Start();
+ return t;
+ }
- public Task ReadAsync(RomManager rommgr, int segAddress)
- {
- var t = new Task(() => Read(rommgr, segAddress));
- t.Start();
- return t;
- }
+ public void Read(byte[] data, byte bankID)
+ {
+ var ms = new MemoryStream(data);
+ var segBank = new SegmentedBank(bankID, ms);
+ Read(segBank, 0);
+ }
- public void Read(byte[] data, byte bankID)
- {
- var ms = new MemoryStream(data);
- var segBank = new SegmentedBank(bankID, ms);
- Read(segBank, 0);
- }
+ public void Read(RomManager rommgr, int segAddress)
+ {
+ var segBank = rommgr.GetSegBank(Convert.ToByte(segAddress >> 24));
+ segBank.ReadDataIfNull(rommgr.RomFile);
+ Read(segBank, segAddress & 0x00ffffff);
+ }
- public void Read(RomManager rommgr, int segAddress)
+ public void Read(SegmentedBank segBank, int offset)
+ {
+ Close();
+ Clear();
+ GeopointerOffsets.Clear();
+ if (segBank is null)
+ return;
+ var data = new BinaryStreamData(segBank.Data);
+ data.Position = offset;
+ var tb = new List();
+ GeolayoutCommandTypes cb = default;
+ int subNodeIndex = 0;
+ bool ende = false;
+ while (!ende)
{
- var segBank = rommgr.GetSegBank(Convert.ToByte(segAddress >> 24));
- segBank.ReadDataIfNull(rommgr.RomFile);
- Read(segBank, segAddress & 0x00ffffff);
- }
-
- public void Read(SegmentedBank segBank, int offset)
- {
- Close();
- Clear();
- GeopointerOffsets.Clear();
- if (segBank is null)
- return;
- var data = new BinaryStreamData(segBank.Data);
- data.Position = offset;
- var tb = new List();
- GeolayoutCommandTypes cb = default;
- int subNodeIndex = 0;
- bool ende = false;
- while (!ende)
+ if (data.Position >= data.Length)
+ break;
+ cb = (GeolayoutCommandTypes)data.ReadByte();
+ byte lenth = 0;
+ switch (cb)
{
- if (data.Position >= data.Length)
+ case GeolayoutCommandTypes.Background:
+ lenth = 0x8;
break;
- cb = (GeolayoutCommandTypes)data.ReadByte();
- byte lenth = 0;
- switch (cb)
- {
- case GeolayoutCommandTypes.Background:
- lenth = 0x8;
- break;
- case GeolayoutCommandTypes.CameraPreset:
- lenth = 0x14;
- break;
- case GeolayoutCommandTypes.DrawingDistance:
- lenth = 0x4;
- break;
- case GeolayoutCommandTypes.EndOfGeolayout:
- lenth = 0x4;
- break;
- case GeolayoutCommandTypes.EndOfNode:
- lenth = 0x4;
- break;
- case GeolayoutCommandTypes.JumpBack:
- lenth = 0x4;
- break;
- case GeolayoutCommandTypes.JumpToSegAddr:
- lenth = 0x8;
- break;
- case GeolayoutCommandTypes.LoadDisplaylist:
- lenth = 0x8;
- break;
- case GeolayoutCommandTypes.LoadDisplaylistWithOffset:
- lenth = 0xC;
- break;
- case GeolayoutCommandTypes.ObjectShadown:
- lenth = 0x8;
- break;
- case GeolayoutCommandTypes.Scale1:
- lenth = 0x4;
- break;
- case GeolayoutCommandTypes.Scale2:
- lenth = 0x8;
- break;
- case GeolayoutCommandTypes.StartOfNode:
- lenth = 0x4;
- break;
- case GeolayoutCommandTypes.SetScreenRenderArea:
- lenth = 0xC;
- break;
- case GeolayoutCommandTypes.BillboardModel:
- lenth = 0x8;
- break;
- case GeolayoutCommandTypes.BranchAndStore:
- lenth = 0x8;
- break;
- case GeolayoutCommandTypes.CameraFrustrum:
- {
- var switchExpr = data.ReadByte();
- switch (switchExpr)
- {
- case 0x1:
- lenth = 0xC;
- break;
- default:
- lenth = 0x8;
- break;
- }
-
- segBank.Data.Position -= 1;
- break;
- }
- case GeolayoutCommandTypes.x0B:
- lenth = 0x4;
- break;
- case GeolayoutCommandTypes.x0C:
- lenth = 0x4;
- break;
- case GeolayoutCommandTypes.x0D:
- lenth = 0x8;
- break;
- case GeolayoutCommandTypes.x0E:
- lenth = 0x8;
- break;
- case GeolayoutCommandTypes.x10:
- lenth = 0x10;
- break;
- case GeolayoutCommandTypes.x11:
- lenth = 0x8;
- break;
- case GeolayoutCommandTypes.x12:
- {
- var switchExpr = data.ReadByte() >> 4;
- switch (switchExpr)
- {
- case 0x8:
- lenth = 0xC;
- break;
- default:
- lenth = 0x8;
- break;
- }
-
- segBank.Data.Position -= 1;
- break;
- }
- case GeolayoutCommandTypes.x17:
- lenth = 0x4;
- break;
- case GeolayoutCommandTypes.x18:
- lenth = 0x8;
- break;
- case GeolayoutCommandTypes.x1A:
- lenth = 0x8;
- break;
- case GeolayoutCommandTypes.x1C:
- lenth = 0xC;
- break;
- case var @case when @case == GeolayoutCommandTypes.x1E:
- lenth = 0x8;
- break;
- case var case1 when case1 == GeolayoutCommandTypes.x1f:
- lenth = 0x10;
- break;
- default:
- break;
- }
-
- segBank.Data.Position -= 1;
- if (lenth == 0 || segBank.Data.Position + lenth > segBank.Data.Length)
+ case GeolayoutCommandTypes.CameraPreset:
+ lenth = 0x14;
break;
+ case GeolayoutCommandTypes.DrawingDistance:
+ lenth = 0x4;
+ break;
+ case GeolayoutCommandTypes.EndOfGeolayout:
+ lenth = 0x4;
+ break;
+ case GeolayoutCommandTypes.EndOfNode:
+ lenth = 0x4;
+ break;
+ case GeolayoutCommandTypes.JumpBack:
+ lenth = 0x4;
+ break;
+ case GeolayoutCommandTypes.JumpToSegAddr:
+ lenth = 0x8;
+ break;
+ case GeolayoutCommandTypes.LoadDisplaylist:
+ lenth = 0x8;
+ break;
+ case GeolayoutCommandTypes.LoadDisplaylistWithOffset:
+ lenth = 0xC;
+ break;
+ case GeolayoutCommandTypes.ObjectShadown:
+ lenth = 0x8;
+ break;
+ case GeolayoutCommandTypes.Scale1:
+ lenth = 0x4;
+ break;
+ case GeolayoutCommandTypes.Scale2:
+ lenth = 0x8;
+ break;
+ case GeolayoutCommandTypes.StartOfNode:
+ lenth = 0x4;
+ break;
+ case GeolayoutCommandTypes.SetScreenRenderArea:
+ lenth = 0xC;
+ break;
+ case GeolayoutCommandTypes.BillboardModel:
+ lenth = 0x8;
+ break;
+ case GeolayoutCommandTypes.BranchAndStore:
+ lenth = 0x8;
+ break;
+ case GeolayoutCommandTypes.CameraFrustrum:
+ {
+ var switchExpr = data.ReadByte();
+ switch (switchExpr)
+ {
+ case 0x1:
+ lenth = 0xC;
+ break;
+ default:
+ lenth = 0x8;
+ break;
+ }
- for (int i = 1, loopTo = lenth; i <= loopTo; i++)
- tb.Add(data.ReadByte());
+ segBank.Data.Position -= 1;
+ break;
+ }
+ case GeolayoutCommandTypes.x0B:
+ lenth = 0x4;
+ break;
+ case GeolayoutCommandTypes.x0C:
+ lenth = 0x4;
+ break;
+ case GeolayoutCommandTypes.x0D:
+ lenth = 0x8;
+ break;
+ case GeolayoutCommandTypes.x0E:
+ lenth = 0x8;
+ break;
+ case GeolayoutCommandTypes.x10:
+ lenth = 0x10;
+ break;
+ case GeolayoutCommandTypes.x11:
+ lenth = 0x8;
+ break;
+ case GeolayoutCommandTypes.x12:
+ {
+ var switchExpr = data.ReadByte() >> 4;
+ switch (switchExpr)
+ {
+ case 0x8:
+ lenth = 0xC;
+ break;
+ default:
+ lenth = 0x8;
+ break;
+ }
- var tCommand = new GeolayoutCommand(tb.ToArray());
- int bankOffset = (int)(segBank.Data.Position - lenth);
- tCommand.RomAddress = segBank.RomStart + bankOffset;
- tCommand.BankAddress = segBank.BankAddress + bankOffset;
- Add(tCommand);
- tb.Clear();
-
- var switchExpr1 = tCommand.CommandType;
- switch (switchExpr1)
- {
- case GeolayoutCommandTypes.EndOfGeolayout:
- ende = true;
+ segBank.Data.Position -= 1;
break;
- case GeolayoutCommandTypes.EndOfNode:
- subNodeIndex -= 1;
- break;
- case GeolayoutCommandTypes.StartOfNode:
- subNodeIndex += 1;
- break;
- }
+ }
+ case GeolayoutCommandTypes.x17:
+ lenth = 0x4;
+ break;
+ case GeolayoutCommandTypes.x18:
+ lenth = 0x8;
+ break;
+ case GeolayoutCommandTypes.x1A:
+ lenth = 0x8;
+ break;
+ case GeolayoutCommandTypes.x1C:
+ lenth = 0xC;
+ break;
+ case var @case when @case == GeolayoutCommandTypes.x1E:
+ lenth = 0x8;
+ break;
+ case var case1 when case1 == GeolayoutCommandTypes.x1f:
+ lenth = 0x10;
+ break;
+ default:
+ break;
}
- }
- public void Write(Stream s, int GeolayoutStart)
- {
- var bw = new BinaryWriter(s);
+ segBank.Data.Position -= 1;
+ if (lenth == 0 || segBank.Data.Position + lenth > segBank.Data.Length)
+ break;
- // Write new Levelscript
- s.Position = GeolayoutStart;
- foreach (GeolayoutCommand c in this)
+ for (int i = 1, loopTo = lenth; i <= loopTo; i++)
+ tb.Add(data.ReadByte());
+
+ var tCommand = new GeolayoutCommand(tb.ToArray());
+ int bankOffset = (int)(segBank.Data.Position - lenth);
+ tCommand.RomAddress = segBank.RomStart + bankOffset;
+ tCommand.BankAddress = segBank.BankAddress + bankOffset;
+ Add(tCommand);
+ tb.Clear();
+
+ var switchExpr1 = tCommand.CommandType;
+ switch (switchExpr1)
{
- if (c.CommandType == GeolayoutCommandTypes.LoadDisplaylist)
- GeopointerOffsets.Add((int)(s.Position + 0x4));
- foreach (byte b in c.ToArray())
- bw.Write(b);
+ case GeolayoutCommandTypes.EndOfGeolayout:
+ ende = true;
+ break;
+ case GeolayoutCommandTypes.EndOfNode:
+ subNodeIndex -= 1;
+ break;
+ case GeolayoutCommandTypes.StartOfNode:
+ subNodeIndex += 1;
+ break;
}
}
-
- public GeolayoutCommand GetFirst(GeolayoutCommandTypes cmdType)
- {
- foreach (GeolayoutCommand cmd in this)
- {
- if (cmd.CommandType == cmdType)
- {
- return cmd;
- }
- }
-
- return null;
- }
+ }
+
+ public void Write(Stream s, int GeolayoutStart)
+ {
+ var bw = new BinaryWriter(s);
+
+ // Write new Levelscript
+ s.Position = GeolayoutStart;
+ foreach (GeolayoutCommand c in this)
+ {
+ if (c.CommandType == GeolayoutCommandTypes.LoadDisplaylist)
+ GeopointerOffsets.Add((int)(s.Position + 0x4));
+ foreach (byte b in c.ToArray())
+ bw.Write(b);
+ }
+ }
+
+ public GeolayoutCommand GetFirst(GeolayoutCommandTypes cmdType)
+ {
+ foreach (GeolayoutCommand cmd in this)
+ {
+ if (cmd.CommandType == cmdType)
+ {
+ return cmd;
+ }
+ }
+
+ return null;
}
}
\ No newline at end of file
diff --git a/SM64Lib/Geolayout/TerrainType.cs b/SM64Lib/Geolayout/TerrainType.cs
index 47c57a0..d9389c9 100644
--- a/SM64Lib/Geolayout/TerrainType.cs
+++ b/SM64Lib/Geolayout/TerrainType.cs
@@ -1,14 +1,13 @@
-namespace SM64Lib.Geolayout
+namespace SM64Lib.Geolayout;
+
+public enum TerrainTypes
{
- public enum TerrainTypes
- {
- NoramlA = 0x0,
- NoramlB,
- SnowTerrain,
- SandTerrain,
- BigBoosHount,
- WaterLevels,
- SlipperySlide
- }
+ NoramlA = 0x0,
+ NoramlB,
+ SnowTerrain,
+ SandTerrain,
+ BigBoosHount,
+ WaterLevels,
+ SlipperySlide
}
\ No newline at end of file
diff --git a/SM64Lib/Json/ArrayReferencePreservngConverter.cs b/SM64Lib/Json/ArrayReferencePreservngConverter.cs
index 258f5a9..6486cb7 100644
--- a/SM64Lib/Json/ArrayReferencePreservngConverter.cs
+++ b/SM64Lib/Json/ArrayReferencePreservngConverter.cs
@@ -1,87 +1,83 @@
using Newtonsoft.Json;
-using System;
-using System.Collections.Generic;
-using System.Collections;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
+using System;
+using System.Collections;
+using System.Collections.Generic;
-namespace SM64Lib.Json
+namespace SM64Lib.Json;
+
+public class ArrayReferencePreservngConverter : JsonConverter
{
- public class ArrayReferencePreservngConverter : JsonConverter
+ const string refProperty = "$ref";
+ const string idProperty = "$id";
+ const string valuesProperty = "$values";
+
+ public override bool CanConvert(Type objectType)
{
- const string refProperty = "$ref";
- const string idProperty = "$id";
- const string valuesProperty = "$values";
+ return objectType.IsArray;
+ }
- public override bool CanConvert(Type objectType)
+ public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+ {
+ if (reader.TokenType == JsonToken.Null)
+ return null;
+ else if (reader.TokenType == JsonToken.StartArray)
{
- return objectType.IsArray;
- }
-
- public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
- {
- if (reader.TokenType == JsonToken.Null)
+ // No $ref. Deserialize as a List to avoid infinite recursion and return as an array.
+ var elementType = objectType.GetElementType();
+ var listType = typeof(List<>).MakeGenericType(elementType);
+ var list = (IList)serializer.Deserialize(reader, listType);
+ if (list == null)
return null;
- else if (reader.TokenType == JsonToken.StartArray)
- {
- // No $ref. Deserialize as a List to avoid infinite recursion and return as an array.
- var elementType = objectType.GetElementType();
- var listType = typeof(List<>).MakeGenericType(elementType);
- var list = (IList)serializer.Deserialize(reader, listType);
- if (list == null)
- return null;
- var array = Array.CreateInstance(elementType, list.Count);
- list.CopyTo(array, 0);
- return array;
- }
- else
- {
- var obj = JObject.Load(reader);
- var refId = (string)obj[refProperty];
- if (refId != null)
- {
- var reference = serializer.ReferenceResolver.ResolveReference(serializer, refId);
- if (reference != null)
- return reference;
- }
- var values = obj[valuesProperty];
- if (values == null || values.Type == JTokenType.Null)
- return null;
- if (!(values is JArray))
- {
- throw new JsonSerializationException(string.Format("{0} was not an array", values));
- }
- var count = ((JArray)values).Count;
-
- var elementType = objectType.GetElementType();
- var array = Array.CreateInstance(elementType, count);
-
- var objId = (string)obj[idProperty];
- if (objId != null)
- {
- // Add the empty array into the reference table BEFORE poppulating it,
- // to handle recursive references.
- serializer.ReferenceResolver.AddReference(serializer, objId, array);
- }
-
- var listType = typeof(List<>).MakeGenericType(elementType);
- using (var subReader = values.CreateReader())
- {
- var list = (IList)serializer.Deserialize(subReader, listType);
- list.CopyTo(array, 0);
- }
-
- return array;
- }
+ var array = Array.CreateInstance(elementType, list.Count);
+ list.CopyTo(array, 0);
+ return array;
}
-
- public override bool CanWrite { get { return false; } }
-
- public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ else
{
- throw new NotImplementedException();
+ var obj = JObject.Load(reader);
+ var refId = (string)obj[refProperty];
+ if (refId != null)
+ {
+ var reference = serializer.ReferenceResolver.ResolveReference(serializer, refId);
+ if (reference != null)
+ return reference;
+ }
+ var values = obj[valuesProperty];
+ if (values == null || values.Type == JTokenType.Null)
+ return null;
+ if (!(values is JArray))
+ {
+ throw new JsonSerializationException(string.Format("{0} was not an array", values));
+ }
+ var count = ((JArray)values).Count;
+
+ var elementType = objectType.GetElementType();
+ var array = Array.CreateInstance(elementType, count);
+
+ var objId = (string)obj[idProperty];
+ if (objId != null)
+ {
+ // Add the empty array into the reference table BEFORE poppulating it,
+ // to handle recursive references.
+ serializer.ReferenceResolver.AddReference(serializer, objId, array);
+ }
+
+ var listType = typeof(List<>).MakeGenericType(elementType);
+ using (var subReader = values.CreateReader())
+ {
+ var list = (IList)serializer.Deserialize(subReader, listType);
+ list.CopyTo(array, 0);
+ }
+
+ return array;
}
}
+
+ public override bool CanWrite { get { return false; } }
+
+ public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ {
+ throw new NotImplementedException();
+ }
}
diff --git a/SM64Lib/Json/BaseCommandJsonConverter.cs b/SM64Lib/Json/BaseCommandJsonConverter.cs
index 9970213..9cdaae0 100644
--- a/SM64Lib/Json/BaseCommandJsonConverter.cs
+++ b/SM64Lib/Json/BaseCommandJsonConverter.cs
@@ -1,61 +1,54 @@
using Newtonsoft.Json;
-using SM64Lib.Behaviors.Script;
using SM64Lib.Geolayout.Script;
-using SM64Lib.Model.Fast3D;
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-namespace SM64Lib.Json
+namespace SM64Lib.Json;
+
+internal class BaseCommandJsonConverter : JsonConverter
{
- internal class BaseCommandJsonConverter : JsonConverter
+ public override bool CanConvert(Type objectType)
{
- public override bool CanConvert(Type objectType)
+ return typeof(GeolayoutscriptCommandJsonConverter).IsAssignableFrom(objectType);
+ }
+
+ public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+ {
+ var export = serializer.Deserialize(reader);
+ GeolayoutCommand c;
+
+ if (existingValue is not null)
+ c = (GeolayoutCommand)existingValue;
+ else
+ c = new GeolayoutCommand();
+
+ if (export?.Buffer is not null)
{
- return typeof(GeolayoutscriptCommandJsonConverter).IsAssignableFrom(objectType);
+ c.Position = 0;
+ c.Write(export.Buffer, 0, export.Buffer.Length);
+ c.Position = 0;
}
- public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+ c.BankAddress = export.BankAddress;
+
+ return c;
+ }
+
+ public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ {
+ var cmd = (GeolayoutCommand)value;
+
+ var export = new CmdExport
{
- var export = serializer.Deserialize(reader);
- GeolayoutCommand c;
+ Buffer = cmd.ToArray(),
+ BankAddress = cmd.BankAddress
+ };
- if (existingValue is not null)
- c = (GeolayoutCommand)existingValue;
- else
- c = new GeolayoutCommand();
+ serializer.Serialize(writer, export);
+ }
- if (export?.Buffer is not null)
- {
- c.Position = 0;
- c.Write(export.Buffer, 0, export.Buffer.Length);
- c.Position = 0;
- }
-
- c.BankAddress = export.BankAddress;
-
- return c;
- }
-
- public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
- {
- var cmd = (GeolayoutCommand)value;
-
- var export = new CmdExport
- {
- Buffer = cmd.ToArray(),
- BankAddress = cmd.BankAddress
- };
-
- serializer.Serialize(writer, export);
- }
-
- private class CmdExport
- {
- public byte[] Buffer { get; set; }
- public int BankAddress { get; set; }
- }
+ private class CmdExport
+ {
+ public byte[] Buffer { get; set; }
+ public int BankAddress { get; set; }
}
}
diff --git a/SM64Lib/Json/BehaviorscriptCommandJsonConverter.cs b/SM64Lib/Json/BehaviorscriptCommandJsonConverter.cs
index 914a3d1..4e07e46 100644
--- a/SM64Lib/Json/BehaviorscriptCommandJsonConverter.cs
+++ b/SM64Lib/Json/BehaviorscriptCommandJsonConverter.cs
@@ -1,60 +1,54 @@
using Newtonsoft.Json;
using SM64Lib.Behaviors.Script;
-using SM64Lib.Model.Fast3D;
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-namespace SM64Lib.Json
+namespace SM64Lib.Json;
+
+internal class BehaviorscriptCommandJsonConverter : JsonConverter
{
- internal class BehaviorscriptCommandJsonConverter : JsonConverter
+ public override bool CanConvert(Type objectType)
{
- public override bool CanConvert(Type objectType)
+ return typeof(BehaviorscriptCommand).IsAssignableFrom(objectType);
+ }
+
+ public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+ {
+ var export = serializer.Deserialize(reader);
+ BehaviorscriptCommand c;
+
+ if (existingValue is not null)
+ c = (BehaviorscriptCommand)existingValue;
+ else
+ c = new BehaviorscriptCommand();
+
+ if (export?.Buffer is not null)
{
- return typeof(BehaviorscriptCommand).IsAssignableFrom(objectType);
+ c.Position = 0;
+ c.Write(export.Buffer, 0, export.Buffer.Length);
+ c.Position = 0;
}
- public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+ c.BankAddress = export.BankAddress;
+
+ return c;
+ }
+
+ public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ {
+ var cmd = (BehaviorscriptCommand)value;
+
+ var export = new CmdExport
{
- var export = serializer.Deserialize(reader);
- BehaviorscriptCommand c;
+ Buffer = cmd.ToArray(),
+ BankAddress = cmd.BankAddress
+ };
- if (existingValue is not null)
- c = (BehaviorscriptCommand)existingValue;
- else
- c = new BehaviorscriptCommand();
+ serializer.Serialize(writer, export);
+ }
- if (export?.Buffer is not null)
- {
- c.Position = 0;
- c.Write(export.Buffer, 0, export.Buffer.Length);
- c.Position = 0;
- }
-
- c.BankAddress = export.BankAddress;
-
- return c;
- }
-
- public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
- {
- var cmd = (BehaviorscriptCommand)value;
-
- var export = new CmdExport
- {
- Buffer = cmd.ToArray(),
- BankAddress = cmd.BankAddress
- };
-
- serializer.Serialize(writer, export);
- }
-
- private class CmdExport
- {
- public byte[] Buffer { get; set; }
- public int BankAddress { get; set; }
- }
+ private class CmdExport
+ {
+ public byte[] Buffer { get; set; }
+ public int BankAddress { get; set; }
}
}
diff --git a/SM64Lib/Json/ComplexDictionarJsonConverter.cs b/SM64Lib/Json/ComplexDictionarJsonConverter.cs
index f8f4189..1624a52 100644
--- a/SM64Lib/Json/ComplexDictionarJsonConverter.cs
+++ b/SM64Lib/Json/ComplexDictionarJsonConverter.cs
@@ -1,35 +1,30 @@
using Newtonsoft.Json;
-using SM64Lib.Model.Fast3D;
using System;
-using System.Collections;
using System.Collections.Generic;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using Z.Collections.Extensions;
-namespace SM64Lib.Json
+namespace SM64Lib.Json;
+
+internal class ComplexDictionarJsonConverter : JsonConverter
{
- internal class ComplexDictionarJsonConverter : JsonConverter
+ public override bool CanConvert(Type objectType)
{
- public override bool CanConvert(Type objectType)
- {
- return typeof(List>).IsAssignableFrom(objectType);
- }
+ return typeof(List>).IsAssignableFrom(objectType);
+ }
- public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
- {
- var list = serializer.Deserialize>>(reader);
- var dic = new Dictionary();
- dic.AddRange(list.ToArray());
+ public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+ {
+ var list = serializer.Deserialize>>(reader);
+ var dic = new Dictionary();
+ dic.AddRange(list.ToArray());
- return dic;
- }
+ return dic;
+ }
- public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
- {
- if (value is Dictionary)
- serializer.Serialize(writer, ((Dictionary)value).ToArray());
- }
+ public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ {
+ if (value is Dictionary)
+ serializer.Serialize(writer, ((Dictionary)value).ToArray());
}
}
diff --git a/SM64Lib/Json/Fast3DBufferJsonConverter.cs b/SM64Lib/Json/Fast3DBufferJsonConverter.cs
index 5fe3117..5632be3 100644
--- a/SM64Lib/Json/Fast3DBufferJsonConverter.cs
+++ b/SM64Lib/Json/Fast3DBufferJsonConverter.cs
@@ -2,70 +2,66 @@
using SM64Lib.Model.Fast3D;
using System;
using System.Collections.Generic;
-using System.IO;
using System.IO.Compression;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-namespace SM64Lib.Json
+namespace SM64Lib.Json;
+
+internal class Fast3DBufferJsonConverter : JsonConverter
{
- internal class Fast3DBufferJsonConverter : JsonConverter
+ public override bool CanConvert(Type objectType)
{
- public override bool CanConvert(Type objectType)
- {
- return typeof(Fast3DBuffer).IsAssignableFrom(objectType);
- }
+ return typeof(Fast3DBuffer).IsAssignableFrom(objectType);
+ }
- public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
- {
- var export = serializer.Deserialize(reader);
- Fast3DBuffer c;
+ public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+ {
+ var export = serializer.Deserialize(reader);
+ Fast3DBuffer c;
- if (existingValue is not null)
- c = (Fast3DBuffer)existingValue;
+ if (existingValue is not null)
+ c = (Fast3DBuffer)existingValue;
+ else
+ c = new Fast3DBuffer();
+
+ if (export?.Buffer is not null)
+ {
+ c.Position = 0;
+
+ if (export.IsDeflateStream)
+ General.DecompressData(export.Buffer, c);
else
- c = new Fast3DBuffer();
+ c.Write(export.Buffer, 0, export.Buffer.Length);
- if (export?.Buffer is not null)
- {
- c.Position = 0;
-
- if (export.IsDeflateStream)
- General.DecompressData(export.Buffer, c);
- else
- c.Write(export.Buffer, 0, export.Buffer.Length);
-
- c.Position = 0;
- }
-
- c.Fast3DBankStart = export.Fast3DBankStart;
- c.DLPointers = export.DLPointers.ToArray();
-
- return c;
+ c.Position = 0;
}
- public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ c.Fast3DBankStart = export.Fast3DBankStart;
+ c.DLPointers = export.DLPointers.ToArray();
+
+ return c;
+ }
+
+ public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ {
+ var buffer = (Fast3DBuffer)value;
+ var export = new Fast3DBufferExport
{
- var buffer = (Fast3DBuffer)value;
- var export = new Fast3DBufferExport
- {
- Buffer = General.CompressData(buffer, CompressionLevel.Fastest),
- Fast3DBankStart = buffer.Fast3DBankStart,
- DLPointers = buffer.DLPointers.ToList(),
- IsDeflateStream = true
- };
- buffer.Position = 0;
+ Buffer = General.CompressData(buffer, CompressionLevel.Fastest),
+ Fast3DBankStart = buffer.Fast3DBankStart,
+ DLPointers = buffer.DLPointers.ToList(),
+ IsDeflateStream = true
+ };
+ buffer.Position = 0;
- serializer.Serialize(writer, export);
- }
+ serializer.Serialize(writer, export);
+ }
- private class Fast3DBufferExport
- {
- public byte[] Buffer { get; set; }
- public int Fast3DBankStart { get; set; }
- public List DLPointers { get; set; }
- public bool IsDeflateStream { get; set; } = false;
- }
+ private class Fast3DBufferExport
+ {
+ public byte[] Buffer { get; set; }
+ public int Fast3DBankStart { get; set; }
+ public List DLPointers { get; set; }
+ public bool IsDeflateStream { get; set; } = false;
}
}
diff --git a/SM64Lib/Json/GeolayoutscriptCommandJsonConverter.cs b/SM64Lib/Json/GeolayoutscriptCommandJsonConverter.cs
index 1349575..c359e20 100644
--- a/SM64Lib/Json/GeolayoutscriptCommandJsonConverter.cs
+++ b/SM64Lib/Json/GeolayoutscriptCommandJsonConverter.cs
@@ -1,61 +1,54 @@
using Newtonsoft.Json;
-using SM64Lib.Behaviors.Script;
using SM64Lib.Geolayout.Script;
-using SM64Lib.Model.Fast3D;
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-namespace SM64Lib.Json
+namespace SM64Lib.Json;
+
+internal class GeolayoutscriptCommandJsonConverter : JsonConverter
{
- internal class GeolayoutscriptCommandJsonConverter : JsonConverter
+ public override bool CanConvert(Type objectType)
{
- public override bool CanConvert(Type objectType)
+ return typeof(GeolayoutCommand).IsAssignableFrom(objectType);
+ }
+
+ public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+ {
+ var export = serializer.Deserialize(reader);
+ GeolayoutCommand c;
+
+ if (existingValue is not null)
+ c = (GeolayoutCommand)existingValue;
+ else
+ c = new GeolayoutCommand();
+
+ if (export?.Buffer is not null)
{
- return typeof(GeolayoutCommand).IsAssignableFrom(objectType);
+ c.Position = 0;
+ c.Write(export.Buffer, 0, export.Buffer.Length);
+ c.Position = 0;
}
- public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+ c.BankAddress = export.BankAddress;
+
+ return c;
+ }
+
+ public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ {
+ var cmd = (GeolayoutCommand)value;
+
+ var export = new CmdExport
{
- var export = serializer.Deserialize(reader);
- GeolayoutCommand c;
+ Buffer = cmd.ToArray(),
+ BankAddress = cmd.BankAddress
+ };
- if (existingValue is not null)
- c = (GeolayoutCommand)existingValue;
- else
- c = new GeolayoutCommand();
+ serializer.Serialize(writer, export);
+ }
- if (export?.Buffer is not null)
- {
- c.Position = 0;
- c.Write(export.Buffer, 0, export.Buffer.Length);
- c.Position = 0;
- }
-
- c.BankAddress = export.BankAddress;
-
- return c;
- }
-
- public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
- {
- var cmd = (GeolayoutCommand)value;
-
- var export = new CmdExport
- {
- Buffer = cmd.ToArray(),
- BankAddress = cmd.BankAddress
- };
-
- serializer.Serialize(writer, export);
- }
-
- private class CmdExport
- {
- public byte[] Buffer { get; set; }
- public int BankAddress { get; set; }
- }
+ private class CmdExport
+ {
+ public byte[] Buffer { get; set; }
+ public int BankAddress { get; set; }
}
}
diff --git a/SM64Lib/Json/JsonHelper.cs b/SM64Lib/Json/JsonHelper.cs
index 73439ec..041afce 100644
--- a/SM64Lib/Json/JsonHelper.cs
+++ b/SM64Lib/Json/JsonHelper.cs
@@ -1,36 +1,30 @@
using Newtonsoft.Json;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-namespace SM64Lib.Json
+namespace SM64Lib.Json;
+
+internal class JsonHelper
{
- internal class JsonHelper
+ public static JsonSerializer CreateJsonSerializer(
+ bool allowReferences = false,
+ bool rememberTypeNames = false,
+ bool enableIndentedFormatting = true)
{
- public static JsonSerializer CreateJsonSerializer(
- bool allowReferences = false,
- bool rememberTypeNames = false,
- bool enableIndentedFormatting = true)
+ var serializer = JsonSerializer.CreateDefault();
+
+ if (enableIndentedFormatting)
+ serializer.Formatting = Formatting.Indented;
+
+ if (rememberTypeNames)
+ serializer.TypeNameHandling = TypeNameHandling.Auto;
+
+ if (allowReferences)
{
- var serializer = JsonSerializer.CreateDefault();
-
- if (enableIndentedFormatting)
- serializer.Formatting = Formatting.Indented;
-
- if (rememberTypeNames)
- serializer.TypeNameHandling = TypeNameHandling.Auto;
-
- if (allowReferences)
- {
- serializer.PreserveReferencesHandling = PreserveReferencesHandling.All;
- serializer.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;
- }
-
- serializer.Converters.Add(new MemoryStreamJsonConverter());
-
- return serializer;
+ serializer.PreserveReferencesHandling = PreserveReferencesHandling.All;
+ serializer.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;
}
+
+ serializer.Converters.Add(new MemoryStreamJsonConverter());
+
+ return serializer;
}
}
diff --git a/SM64Lib/Json/LevelscriptCommandJsonConverter.cs b/SM64Lib/Json/LevelscriptCommandJsonConverter.cs
index fcc71cb..4ae62b0 100644
--- a/SM64Lib/Json/LevelscriptCommandJsonConverter.cs
+++ b/SM64Lib/Json/LevelscriptCommandJsonConverter.cs
@@ -1,62 +1,54 @@
using Newtonsoft.Json;
-using SM64Lib.Behaviors.Script;
-using SM64Lib.Geolayout.Script;
using SM64Lib.Levels.Script;
-using SM64Lib.Model.Fast3D;
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-namespace SM64Lib.Json
+namespace SM64Lib.Json;
+
+internal class LevelscriptCommandJsonConverter : JsonConverter
{
- internal class LevelscriptCommandJsonConverter : JsonConverter
+ public override bool CanConvert(Type objectType)
{
- public override bool CanConvert(Type objectType)
+ return typeof(LevelscriptCommand).IsAssignableFrom(objectType);
+ }
+
+ public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+ {
+ var export = serializer.Deserialize(reader);
+ LevelscriptCommand c;
+
+ if (existingValue is not null)
+ c = (LevelscriptCommand)existingValue;
+ else
+ c = new LevelscriptCommand();
+
+ if (export?.Buffer is not null)
{
- return typeof(LevelscriptCommand).IsAssignableFrom(objectType);
+ c.Position = 0;
+ c.Write(export.Buffer, 0, export.Buffer.Length);
+ c.Position = 0;
}
- public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+ c.BankAddress = export.BankAddress;
+
+ return c;
+ }
+
+ public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ {
+ var cmd = (LevelscriptCommand)value;
+
+ var export = new CmdExport
{
- var export = serializer.Deserialize(reader);
- LevelscriptCommand c;
+ Buffer = cmd.ToArray(),
+ BankAddress = cmd.BankAddress
+ };
- if (existingValue is not null)
- c = (LevelscriptCommand)existingValue;
- else
- c = new LevelscriptCommand();
+ serializer.Serialize(writer, export);
+ }
- if (export?.Buffer is not null)
- {
- c.Position = 0;
- c.Write(export.Buffer, 0, export.Buffer.Length);
- c.Position = 0;
- }
-
- c.BankAddress = export.BankAddress;
-
- return c;
- }
-
- public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
- {
- var cmd = (LevelscriptCommand)value;
-
- var export = new CmdExport
- {
- Buffer = cmd.ToArray(),
- BankAddress = cmd.BankAddress
- };
-
- serializer.Serialize(writer, export);
- }
-
- private class CmdExport
- {
- public byte[] Buffer { get; set; }
- public int BankAddress { get; set; }
- }
+ private class CmdExport
+ {
+ public byte[] Buffer { get; set; }
+ public int BankAddress { get; set; }
}
}
diff --git a/SM64Lib/Json/MemoryStreamJsonConverter.cs b/SM64Lib/Json/MemoryStreamJsonConverter.cs
index d473ae0..841cf0c 100644
--- a/SM64Lib/Json/MemoryStreamJsonConverter.cs
+++ b/SM64Lib/Json/MemoryStreamJsonConverter.cs
@@ -1,37 +1,28 @@
using Newtonsoft.Json;
-using SM64Lib.Behaviors.Script;
-using SM64Lib.Geolayout.Script;
-using SM64Lib.Levels.Script;
-using SM64Lib.Model.Fast3D;
using System;
-using System.Collections.Generic;
using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-namespace SM64Lib.Json
+namespace SM64Lib.Json;
+
+internal class MemoryStreamJsonConverter : JsonConverter
{
- internal class MemoryStreamJsonConverter : JsonConverter
+ public override bool CanConvert(Type objectType)
{
- public override bool CanConvert(Type objectType)
- {
- return typeof(MemoryStream).IsAssignableFrom(objectType);
- }
+ return typeof(MemoryStream).IsAssignableFrom(objectType);
+ }
- public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
- {
- var msData = serializer.Deserialize(reader);
- var ms = new MemoryStream();
- ms.Write(msData, 0, msData.Length);
- ms.Position = 0;
- return ms;
- }
+ public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+ {
+ var msData = serializer.Deserialize(reader);
+ var ms = new MemoryStream();
+ ms.Write(msData, 0, msData.Length);
+ ms.Position = 0;
+ return ms;
+ }
- public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
- {
- var ms = (MemoryStream)value;
- serializer.Serialize(writer, ms.ToArray());
- }
+ public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ {
+ var ms = (MemoryStream)value;
+ serializer.Serialize(writer, ms.ToArray());
}
}
diff --git a/SM64Lib/Level/AreaBG.cs b/SM64Lib/Level/AreaBG.cs
index 548e406..81b8fc4 100644
--- a/SM64Lib/Level/AreaBG.cs
+++ b/SM64Lib/Level/AreaBG.cs
@@ -1,16 +1,15 @@
using global::System.Drawing;
-namespace SM64Lib.Levels
-{
- public class AreaBG
- {
- public AreaBGs Type { get; set; } = AreaBGs.Levelbackground;
- public Color Color { get; set; } = Color.Black;
- }
+namespace SM64Lib.Levels;
- public enum AreaBGs
- {
- Levelbackground,
- Color
- }
+public class AreaBG
+{
+ public AreaBGs Type { get; set; } = AreaBGs.Levelbackground;
+ public Color Color { get; set; } = Color.Black;
+}
+
+public enum AreaBGs
+{
+ Levelbackground,
+ Color
}
\ No newline at end of file
diff --git a/SM64Lib/Level/AreaReverbLevel.cs b/SM64Lib/Level/AreaReverbLevel.cs
index 3669380..b06c948 100644
--- a/SM64Lib/Level/AreaReverbLevel.cs
+++ b/SM64Lib/Level/AreaReverbLevel.cs
@@ -1,23 +1,16 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+namespace SM64Lib.Levels;
-namespace SM64Lib.Levels
+public enum AreaReverbLevel : byte
{
- public enum AreaReverbLevel : byte
- {
- None,
- Level01 = 0x8,
- Level02 = 0xC,
- Level03 = 0x10,
- Level04 = 0x18,
- Level05 = 0x20,
- Level06 = 0x28,
- Level07 = 0x30,
- Level08 = 0x38,
- Level09 = 0x40,
- Level10 = 0x70
- }
+ None,
+ Level01 = 0x8,
+ Level02 = 0xC,
+ Level03 = 0x10,
+ Level04 = 0x18,
+ Level05 = 0x20,
+ Level06 = 0x28,
+ Level07 = 0x30,
+ Level08 = 0x38,
+ Level09 = 0x40,
+ Level10 = 0x70
}
diff --git a/SM64Lib/Level/Enums.cs b/SM64Lib/Level/Enums.cs
index c4a809b..312852c 100644
--- a/SM64Lib/Level/Enums.cs
+++ b/SM64Lib/Level/Enums.cs
@@ -1,123 +1,122 @@
-namespace SM64Lib.Levels
+namespace SM64Lib.Levels;
+
+public enum ObjectBank0x0C
{
- public enum ObjectBank0x0C
- {
- Disabled,
- HauntedObjects,
- SnowObjects,
- AssortedEnemies1,
- DesertObjects,
- BigBobOmbBoss,
- AssortedEnemies2,
- WaterObjects,
- AssortedEnemies3,
- PeachYoshi,
- Switches,
- LavaObjects
- }
+ Disabled,
+ HauntedObjects,
+ SnowObjects,
+ AssortedEnemies1,
+ DesertObjects,
+ BigBobOmbBoss,
+ AssortedEnemies2,
+ WaterObjects,
+ AssortedEnemies3,
+ PeachYoshi,
+ Switches,
+ LavaObjects
+}
- public enum ObjectBank0x0D
- {
- Disabled,
- AssortedEnemies4,
- Moneybags,
- CastleObjects,
- GroundEnemies,
- WaterObjects2,
- Bowser
- }
+public enum ObjectBank0x0D
+{
+ Disabled,
+ AssortedEnemies4,
+ Moneybags,
+ CastleObjects,
+ GroundEnemies,
+ WaterObjects2,
+ Bowser
+}
- public enum ObjectBank0x0E
- {
- Disabled,
- HaundetHouse,
- CoolCoolMountain,
- InsideCastle,
- HazyMazeCave,
- ShiftingSandLand,
- BobOmbBattlefield,
- SnowandsLand,
- WetDryWorld,
- JollyRogerBay,
- TinyHugeIsland,
- TickTockClock,
- RainbowRide,
- CastleGrounds,
- Bowser1Course,
- VanishCap,
- Bowser2Course,
- Bowser3Course,
- LethalLavaLand,
- DireDireDocks,
- WhompsFortress,
- CastleCourtyard,
- WingCap,
- Bowser2Battle,
- Bowser3Battle,
- TallTallMountain
- }
+public enum ObjectBank0x0E
+{
+ Disabled,
+ HaundetHouse,
+ CoolCoolMountain,
+ InsideCastle,
+ HazyMazeCave,
+ ShiftingSandLand,
+ BobOmbBattlefield,
+ SnowandsLand,
+ WetDryWorld,
+ JollyRogerBay,
+ TinyHugeIsland,
+ TickTockClock,
+ RainbowRide,
+ CastleGrounds,
+ Bowser1Course,
+ VanishCap,
+ Bowser2Course,
+ Bowser3Course,
+ LethalLavaLand,
+ DireDireDocks,
+ WhompsFortress,
+ CastleCourtyard,
+ WingCap,
+ Bowser2Battle,
+ Bowser3Battle,
+ TallTallMountain
+}
- public enum ObjectBanks
- {
- Bank0x0C,
- Bank0x0D,
- Bank0x0E
- }
+public enum ObjectBanks
+{
+ Bank0x0C,
+ Bank0x0D,
+ Bank0x0E
+}
- public enum Levels : byte
- {
- HaundetHouse = 0x4,
- CoolCoolMountain,
- InsideCastle,
- HazyMazeCave,
- ShiftingSandLand,
- BobOmbsBattlefield,
- SnowManLand,
- WetDryWorld,
- JollyRogerBay,
- TinyHugeIsland,
- TickTockClock,
- RainbowRide,
- CastleGrounds,
- Bowser1Course,
- VanishCap,
- Bowser2Course,
- SecretAquarium,
- Bowser3Course,
- LethalLavaLand,
- DireDireDocks,
- WhompsFortress,
- EndCakePicture,
- CastleCourtyard,
- PeachsSecretSlide,
- MetalCap,
- WingCap,
- Bowser1Battle,
- RainbowClouds,
- Bowser2Battle = 0x21,
- Bowser3Battle,
- TallTallMountain = 0x24
- }
+public enum Levels : byte
+{
+ HaundetHouse = 0x4,
+ CoolCoolMountain,
+ InsideCastle,
+ HazyMazeCave,
+ ShiftingSandLand,
+ BobOmbsBattlefield,
+ SnowManLand,
+ WetDryWorld,
+ JollyRogerBay,
+ TinyHugeIsland,
+ TickTockClock,
+ RainbowRide,
+ CastleGrounds,
+ Bowser1Course,
+ VanishCap,
+ Bowser2Course,
+ SecretAquarium,
+ Bowser3Course,
+ LethalLavaLand,
+ DireDireDocks,
+ WhompsFortress,
+ EndCakePicture,
+ CastleCourtyard,
+ PeachsSecretSlide,
+ MetalCap,
+ WingCap,
+ Bowser1Battle,
+ RainbowClouds,
+ Bowser2Battle = 0x21,
+ Bowser3Battle,
+ TallTallMountain = 0x24
+}
- public enum ScrollingTextureAxis
- {
- X,
- Y
- }
+public enum ScrollingTextureAxis
+{
+ X,
+ Y
+}
- public enum SpecialBoxType
- {
- Water,
- ToxicHaze,
- Mist
- }
+public enum SpecialBoxType
+{
+ Water,
+ ToxicHaze,
+ Mist
+}
- public enum WaterType
- {
- Default = 0x0,
- JRBWater = 0x20000,
- GreenWater = 0x30000,
- LavaWater = 0x40000
- }
+public enum WaterType
+{
+ Default = 0x0,
+ JRBWater = 0x20000,
+ GreenWater = 0x30000,
+ LavaWater = 0x40000
}
\ No newline at end of file
diff --git a/SM64Lib/Level/ILevelManager.cs b/SM64Lib/Level/ILevelManager.cs
index 05421ba..96ec1cb 100644
--- a/SM64Lib/Level/ILevelManager.cs
+++ b/SM64Lib/Level/ILevelManager.cs
@@ -1,10 +1,9 @@
using global::SM64Lib.Data;
-namespace SM64Lib.Levels
+namespace SM64Lib.Levels;
+
+public interface ILevelManager
{
- public interface ILevelManager
- {
- void LoadLevel(Level lvl, RomManager rommgr, ushort LevelID, uint segAddress);
- LevelSaveResult SaveLevel(Level lvl, RomManager rommgr, BinaryData output, ref uint curOff);
- }
+ void LoadLevel(Level lvl, RomManager rommgr, ushort LevelID, uint segAddress);
+ LevelSaveResult SaveLevel(Level lvl, RomManager rommgr, BinaryData output, ref uint curOff);
}
\ No newline at end of file
diff --git a/SM64Lib/Level/Level.cs b/SM64Lib/Level/Level.cs
index fa8474b..bc5f105 100644
--- a/SM64Lib/Level/Level.cs
+++ b/SM64Lib/Level/Level.cs
@@ -1,329 +1,326 @@
-using System.Collections.Generic;
-using System.Data;
-using global::System.IO;
-using System.Linq;
-using Microsoft.VisualBasic;
-using Microsoft.VisualBasic.CompilerServices;
-using global::SM64Lib.Levels.Script;
+using global::SM64Lib.Levels.Script;
using global::SM64Lib.Levels.Script.Commands;
using global::SM64Lib.Objects.ObjectBanks.Data;
using global::SM64Lib.SegmentedBanking;
-using SM64Lib.Objects.ModelBanks;
+using Microsoft.VisualBasic;
using Newtonsoft.Json;
+using SM64Lib.Objects.ModelBanks;
using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Linq;
-namespace SM64Lib.Levels
+namespace SM64Lib.Levels;
+
+public abstract class Level
{
- public abstract class Level
+
+ // S h a r e d M e m b e r s
+
+ internal static readonly byte[] LevelscriptStart = new byte[] { 0x80, 0x8, 0x0, 0x0, 0x19, 0x0, 0x0, 0x1C, 0x8, 0x0, 0x0, 0xA, 0x0, 0xA0, 0x0, 0x78, 0x0, 0xA0, 0x0, 0x78, 0x4, 0x0, 0x0, 0x0, 0xC, 0x0, 0x0, 0x0 };
+
+ // F i e l d s
+
+ protected SegmentedBank _Bank0x19 = null;
+
+ // A u t o P r o p e r t i e s
+
+ internal LevelscriptCommand LastGobCmdSegLoad { get; set; } = null;
+ internal LevelscriptCommand LastLobCmdSegLoad { get; set; } = null;
+ [JsonIgnore]
+ internal Dictionary MyObjectBanks { get; private set; } = new Dictionary();
+ public Levelscript Levelscript { get; set; } = new Levelscript();
+ public List Areas { get; private set; } = new List();
+ public ushort LevelID { get; set; } = 0;
+ public LevelBG Background { get; private set; } = new LevelBG();
+ public bool ActSelector { get; set; } = false;
+ public bool HardcodedCameraSettings { get; set; } = false;
+ public bool Closed { get; set; } = false;
+ public int LastRomOffset { get; set; } = -1;
+ public bool NeedToSaveLevelscript { get; set; } = false;
+ public bool NeedToSaveBanks0E { get; set; } = false;
+ public bool OneBank0xESystemEnabled { get; set; } = true;
+ public bool EnableGlobalObjectBank { get; set; } = false;
+ public bool EnableLocalObjectBank { get; set; } = false;
+ public CustomModelBank LocalObjectBank { get; private set; } = new CustomModelBank();
+ [JsonIgnore]
+ public RomManager RomManager { get; set; }
+
+ // O t h e r P r o p e r t i e s
+
+ [JsonIgnore]
+ public IReadOnlyDictionary LoadedObjectBanks
{
-
- // S h a r e d M e m b e r s
-
- internal static readonly byte[] LevelscriptStart = new byte[] { 0x80, 0x8, 0x0, 0x0, 0x19, 0x0, 0x0, 0x1C, 0x8, 0x0, 0x0, 0xA, 0x0, 0xA0, 0x0, 0x78, 0x0, 0xA0, 0x0, 0x78, 0x4, 0x0, 0x0, 0x0, 0xC, 0x0, 0x0, 0x0 };
-
- // F i e l d s
-
- protected SegmentedBank _Bank0x19 = null;
-
- // A u t o P r o p e r t i e s
-
- internal LevelscriptCommand LastGobCmdSegLoad { get; set; } = null;
- internal LevelscriptCommand LastLobCmdSegLoad { get; set; } = null;
- [JsonIgnore]
- internal Dictionary MyObjectBanks { get; private set; } = new Dictionary();
- public Levelscript Levelscript { get; set; } = new Levelscript();
- public List Areas { get; private set; } = new List();
- public ushort LevelID { get; set; } = 0;
- public LevelBG Background { get; private set; } = new LevelBG();
- public bool ActSelector { get; set; } = false;
- public bool HardcodedCameraSettings { get; set; } = false;
- public bool Closed { get; set; } = false;
- public int LastRomOffset { get; set; } = -1;
- public bool NeedToSaveLevelscript { get; set; } = false;
- public bool NeedToSaveBanks0E { get; set; } = false;
- public bool OneBank0xESystemEnabled { get; set; } = true;
- public bool EnableGlobalObjectBank { get; set; } = false;
- public bool EnableLocalObjectBank { get; set; } = false;
- public CustomModelBank LocalObjectBank { get; private set; } = new CustomModelBank();
- [JsonIgnore]
- public RomManager RomManager { get; set; }
-
- // O t h e r P r o p e r t i e s
-
- [JsonIgnore]
- public IReadOnlyDictionary LoadedObjectBanks
+ get
{
- get
- {
- return MyObjectBanks;
- }
- }
-
- [JsonIgnore]
- public SegmentedBank Bank0x19
- {
- get
- {
- return _Bank0x19;
- }
-
- internal set
- {
- _Bank0x19 = value;
- }
- }
-
- [JsonIgnore]
- public int ObjectsCount
- {
- get
- {
- int tcount = 0;
- foreach (var a in Areas)
- tcount += a.Objects.Count;
- return tcount;
- }
- }
-
- [JsonIgnore]
- public int WarpsCount
- {
- get
- {
- int tcount = 0;
- foreach (var a in Areas)
- tcount += a.Warps.Count;
- return tcount;
- }
- }
-
- [JsonIgnore]
- public long Length
- {
- get
- {
- long length = 0;
-
- if (Bank0x19 is not null)
- length += Bank0x19.Length;
- else
- length += RomManagerSettings.DefaultLevelscriptSize;
-
- if (LocalObjectBank is not null)
- length += LocalObjectBank.Length;
-
- foreach (var area in Areas)
- {
- length += area.AreaModel.Length;
- if (OneBank0xESystemEnabled)
- length += area.Levelscript.Length;
- }
-
- return length;
- }
- }
-
- // C o n s t r u c t o r s
-
- [JsonConstructor]
- protected Level(JsonConstructorAttribute attr)
- {
- }
-
- protected Level(ushort LevelID, int LevelIndex, RomManager rommgr) : this(rommgr)
- {
- this.LevelID = LevelID;
- CreateNewLevelscript();
- HardcodedCameraSettings = false;
- ActSelector = General.ActSelectorDefaultValues[LevelIndex];
- }
-
- protected Level(RomManager rommgr)
- {
- RomManager = rommgr;
- }
-
- // M e t h o d s
-
- public void CreateNewLevelscript()
- {
- {
- var withBlock = Levelscript;
- withBlock.Close();
- withBlock.Clear();
-
- // Start Loading Commands
- withBlock.Add(new LevelscriptCommand(new byte[] { 0x1B, 0x4, 0x0, 0x0 }));
-
- // Loading Commands
- withBlock.Add(new LevelscriptCommand(new byte[] { 0x17, 0xC, 0x1, 0xE, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }));
-
- // Start Model Commands
- withBlock.Add(new LevelscriptCommand(new byte[] { 0x1D, 0x4, 0x0, 0x0 }));
-
- // Load Marios Model
- withBlock.Add(new LevelscriptCommand(new byte[] { 0x25, 0xC, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x13, 0x0, 0x2E, 0xC0 }));
-
- // Start End-Of-Level Commands
- withBlock.Add(new LevelscriptCommand(new byte[] { 0x1E, 0x4, 0x0, 0x0 }));
-
- // End-Of-Level Commands
- withBlock.Add(new LevelscriptCommand(new byte[] { 0x2B, 0xC, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }));
- withBlock.Add(new LevelscriptCommand(new byte[] { 0x11, 0x8, 0x0, 0x0, 0x80, 0x24, 0xBC, 0xD8 }));
- withBlock.Add(new LevelscriptCommand(new byte[] { 0x12, 0x8, 0x0, 0x1, 0x80, 0x24, 0xBC, 0xD8 }));
- withBlock.Add(new LevelscriptCommand(new byte[] { 0x1C, 0x4, 0x0, 0x0 }));
- withBlock.Add(new LevelscriptCommand(new byte[] { 0x4, 0x4, 0x0, 0x1 }));
- withBlock.Add(new LevelscriptCommand(new byte[] { 0x2, 0x4, 0x0, 0x0 }));
-
- // Add the general object bank
- ChangeObjectBank(null, RomManager.RomConfig.ObjectBankInfoData[Convert.ToByte(0xB)]?.FirstOrDefault());
- }
-
- foreach (LevelscriptCommand c in Levelscript)
- {
- if (c.CommandType != LevelscriptCommandTypes.LoadRomToRam)
- continue;
- if (clLoadRomToRam.GetSegmentedID(c) != 0xE)
- continue;
- }
- }
-
- public void SetSegmentedBanks(RomManager rommgr)
- {
- foreach (LevelscriptCommand cmd in Levelscript)
- {
- var switchExpr = cmd.CommandType;
- switch (switchExpr)
- {
- case LevelscriptCommandTypes.LoadRomToRam:
- case LevelscriptCommandTypes.x1A:
- case LevelscriptCommandTypes.x18:
- {
- cmd.Position = 0;
- byte bankID = clLoadRomToRam.GetSegmentedID(cmd);
- int startAddr = clLoadRomToRam.GetRomStart(cmd);
- int endAddr = clLoadRomToRam.GetRomEnd(cmd);
- var seg = rommgr.SetSegBank(bankID, startAddr, endAddr);
- if (cmd.CommandType == LevelscriptCommandTypes.x1A)
- seg.MakeAsMIO0();
- break;
- }
- }
- }
-
- if (Bank0x19 is not null)
- {
- rommgr.SetSegBank(Bank0x19);
- }
- }
-
- public LevelscriptCommand GetDefaultPositionCmd()
- {
- return (LevelscriptCommand)Levelscript.FirstOrDefault(n => n.CommandType == LevelscriptCommandTypes.DefaultPosition);
- }
-
- public void ChangeObjectBankData(byte bankID, ObjectBankData newObd)
- {
- ChangeObjectBank(GetObjectBankData(bankID), newObd);
- MyObjectBanks[bankID] = newObd;
- }
-
- public ObjectBankData GetObjectBankData(byte bankID)
- {
- if (MyObjectBanks.ContainsKey(bankID))
- {
- return MyObjectBanks[bankID];
- }
- else
- {
- var obd = FindObjectBankData(bankID);
- MyObjectBanks.Add(bankID, obd);
- return obd;
- }
- }
-
- protected void ChangeObjectBank(ObjectBankData oldObd, ObjectBankData newObd)
- {
- // Remove old commands
- if (oldObd is not null)
- {
- foreach (ObjectBankDataCommand obdCmd in oldObd.Commands)
- {
- foreach (var cmd in Levelscript.Where(n => General.CompareTwoByteArrays(n.ToArray(), obdCmd.Command)).ToArray())
- {
- cmd.Close();
- Levelscript.Remove(cmd);
- }
- }
- }
-
- // Add new commands
- if (newObd is not null)
- {
- foreach (ObjectBankDataCommand obdCmd in newObd.Commands)
- {
- int startIndex = Levelscript.IndexOfFirst(LevelscriptCommandTypes.x1D);
- if (!(obdCmd.CommandType == 0x1A || obdCmd.CommandType == 0x17))
- {
- startIndex += 1;
- }
-
- var cmd = new LevelscriptCommand(obdCmd.Command);
- Levelscript.Insert(startIndex, cmd);
- startIndex += 1;
- }
- }
- }
-
- protected ObjectBankData FindObjectBankData(byte bankID)
- {
- var list = RomManager.RomConfig.ObjectBankInfoData[bankID];
- var Found = new List();
- foreach (ObjectBankData obd in list)
- {
- foreach (ObjectBankDataCommand obdCmd in obd.Commands)
- Found.Add(Levelscript.Where(n => General.CompareTwoByteArrays(n.ToArray(), obdCmd.Command)).Any());
- if (!Found.Contains(false))
- {
- return obd;
- }
-
- Found.Clear();
- }
-
- return null;
- }
-
- public void Close()
- {
- foreach (var c in Levelscript)
- c.Close();
- Levelscript.Clear();
- foreach (var a in Areas)
- a.Close();
- Areas.Clear();
- Closed = true;
- }
-
- public override string ToString()
- {
- string output = "";
- foreach (var cmd in Levelscript)
- {
- string tbytelist = "";
- foreach (byte b in cmd.ToArray())
- {
- if (tbytelist != string.Empty)
- tbytelist += " ";
- tbytelist += Conversion.Hex(b);
- }
-
- if (output != string.Empty)
- output += Environment.NewLine;
- output += tbytelist;
- }
-
- return output;
+ return MyObjectBanks;
}
}
+
+ [JsonIgnore]
+ public SegmentedBank Bank0x19
+ {
+ get
+ {
+ return _Bank0x19;
+ }
+
+ internal set
+ {
+ _Bank0x19 = value;
+ }
+ }
+
+ [JsonIgnore]
+ public int ObjectsCount
+ {
+ get
+ {
+ int tcount = 0;
+ foreach (var a in Areas)
+ tcount += a.Objects.Count;
+ return tcount;
+ }
+ }
+
+ [JsonIgnore]
+ public int WarpsCount
+ {
+ get
+ {
+ int tcount = 0;
+ foreach (var a in Areas)
+ tcount += a.Warps.Count;
+ return tcount;
+ }
+ }
+
+ [JsonIgnore]
+ public long Length
+ {
+ get
+ {
+ long length = 0;
+
+ if (Bank0x19 is not null)
+ length += Bank0x19.Length;
+ else
+ length += RomManagerSettings.DefaultLevelscriptSize;
+
+ if (LocalObjectBank is not null)
+ length += LocalObjectBank.Length;
+
+ foreach (var area in Areas)
+ {
+ length += area.AreaModel.Length;
+ if (OneBank0xESystemEnabled)
+ length += area.Levelscript.Length;
+ }
+
+ return length;
+ }
+ }
+
+ // C o n s t r u c t o r s
+
+ [JsonConstructor]
+ protected Level(JsonConstructorAttribute attr)
+ {
+ }
+
+ protected Level(ushort LevelID, int LevelIndex, RomManager rommgr) : this(rommgr)
+ {
+ this.LevelID = LevelID;
+ CreateNewLevelscript();
+ HardcodedCameraSettings = false;
+ ActSelector = General.ActSelectorDefaultValues[LevelIndex];
+ }
+
+ protected Level(RomManager rommgr)
+ {
+ RomManager = rommgr;
+ }
+
+ // M e t h o d s
+
+ public void CreateNewLevelscript()
+ {
+ {
+ var withBlock = Levelscript;
+ withBlock.Close();
+ withBlock.Clear();
+
+ // Start Loading Commands
+ withBlock.Add(new LevelscriptCommand(new byte[] { 0x1B, 0x4, 0x0, 0x0 }));
+
+ // Loading Commands
+ withBlock.Add(new LevelscriptCommand(new byte[] { 0x17, 0xC, 0x1, 0xE, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }));
+
+ // Start Model Commands
+ withBlock.Add(new LevelscriptCommand(new byte[] { 0x1D, 0x4, 0x0, 0x0 }));
+
+ // Load Marios Model
+ withBlock.Add(new LevelscriptCommand(new byte[] { 0x25, 0xC, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x13, 0x0, 0x2E, 0xC0 }));
+
+ // Start End-Of-Level Commands
+ withBlock.Add(new LevelscriptCommand(new byte[] { 0x1E, 0x4, 0x0, 0x0 }));
+
+ // End-Of-Level Commands
+ withBlock.Add(new LevelscriptCommand(new byte[] { 0x2B, 0xC, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }));
+ withBlock.Add(new LevelscriptCommand(new byte[] { 0x11, 0x8, 0x0, 0x0, 0x80, 0x24, 0xBC, 0xD8 }));
+ withBlock.Add(new LevelscriptCommand(new byte[] { 0x12, 0x8, 0x0, 0x1, 0x80, 0x24, 0xBC, 0xD8 }));
+ withBlock.Add(new LevelscriptCommand(new byte[] { 0x1C, 0x4, 0x0, 0x0 }));
+ withBlock.Add(new LevelscriptCommand(new byte[] { 0x4, 0x4, 0x0, 0x1 }));
+ withBlock.Add(new LevelscriptCommand(new byte[] { 0x2, 0x4, 0x0, 0x0 }));
+
+ // Add the general object bank
+ ChangeObjectBank(null, RomManager.RomConfig.ObjectBankInfoData[Convert.ToByte(0xB)]?.FirstOrDefault());
+ }
+
+ foreach (LevelscriptCommand c in Levelscript)
+ {
+ if (c.CommandType != LevelscriptCommandTypes.LoadRomToRam)
+ continue;
+ if (clLoadRomToRam.GetSegmentedID(c) != 0xE)
+ continue;
+ }
+ }
+
+ public void SetSegmentedBanks(RomManager rommgr)
+ {
+ foreach (LevelscriptCommand cmd in Levelscript)
+ {
+ var switchExpr = cmd.CommandType;
+ switch (switchExpr)
+ {
+ case LevelscriptCommandTypes.LoadRomToRam:
+ case LevelscriptCommandTypes.x1A:
+ case LevelscriptCommandTypes.x18:
+ {
+ cmd.Position = 0;
+ byte bankID = clLoadRomToRam.GetSegmentedID(cmd);
+ int startAddr = clLoadRomToRam.GetRomStart(cmd);
+ int endAddr = clLoadRomToRam.GetRomEnd(cmd);
+ var seg = rommgr.SetSegBank(bankID, startAddr, endAddr);
+ if (cmd.CommandType == LevelscriptCommandTypes.x1A)
+ seg.MakeAsMIO0();
+ break;
+ }
+ }
+ }
+
+ if (Bank0x19 is not null)
+ {
+ rommgr.SetSegBank(Bank0x19);
+ }
+ }
+
+ public LevelscriptCommand GetDefaultPositionCmd()
+ {
+ return (LevelscriptCommand)Levelscript.FirstOrDefault(n => n.CommandType == LevelscriptCommandTypes.DefaultPosition);
+ }
+
+ public void ChangeObjectBankData(byte bankID, ObjectBankData newObd)
+ {
+ ChangeObjectBank(GetObjectBankData(bankID), newObd);
+ MyObjectBanks[bankID] = newObd;
+ }
+
+ public ObjectBankData GetObjectBankData(byte bankID)
+ {
+ if (MyObjectBanks.ContainsKey(bankID))
+ {
+ return MyObjectBanks[bankID];
+ }
+ else
+ {
+ var obd = FindObjectBankData(bankID);
+ MyObjectBanks.Add(bankID, obd);
+ return obd;
+ }
+ }
+
+ protected void ChangeObjectBank(ObjectBankData oldObd, ObjectBankData newObd)
+ {
+ // Remove old commands
+ if (oldObd is not null)
+ {
+ foreach (ObjectBankDataCommand obdCmd in oldObd.Commands)
+ {
+ foreach (var cmd in Levelscript.Where(n => General.CompareTwoByteArrays(n.ToArray(), obdCmd.Command)).ToArray())
+ {
+ cmd.Close();
+ Levelscript.Remove(cmd);
+ }
+ }
+ }
+
+ // Add new commands
+ if (newObd is not null)
+ {
+ foreach (ObjectBankDataCommand obdCmd in newObd.Commands)
+ {
+ int startIndex = Levelscript.IndexOfFirst(LevelscriptCommandTypes.x1D);
+ if (!(obdCmd.CommandType == 0x1A || obdCmd.CommandType == 0x17))
+ {
+ startIndex += 1;
+ }
+
+ var cmd = new LevelscriptCommand(obdCmd.Command);
+ Levelscript.Insert(startIndex, cmd);
+ startIndex += 1;
+ }
+ }
+ }
+
+ protected ObjectBankData FindObjectBankData(byte bankID)
+ {
+ var list = RomManager.RomConfig.ObjectBankInfoData[bankID];
+ var Found = new List();
+ foreach (ObjectBankData obd in list)
+ {
+ foreach (ObjectBankDataCommand obdCmd in obd.Commands)
+ Found.Add(Levelscript.Where(n => General.CompareTwoByteArrays(n.ToArray(), obdCmd.Command)).Any());
+ if (!Found.Contains(false))
+ {
+ return obd;
+ }
+
+ Found.Clear();
+ }
+
+ return null;
+ }
+
+ public void Close()
+ {
+ foreach (var c in Levelscript)
+ c.Close();
+ Levelscript.Clear();
+ foreach (var a in Areas)
+ a.Close();
+ Areas.Clear();
+ Closed = true;
+ }
+
+ public override string ToString()
+ {
+ string output = "";
+ foreach (var cmd in Levelscript)
+ {
+ string tbytelist = "";
+ foreach (byte b in cmd.ToArray())
+ {
+ if (tbytelist != string.Empty)
+ tbytelist += " ";
+ tbytelist += Conversion.Hex(b);
+ }
+
+ if (output != string.Empty)
+ output += Environment.NewLine;
+ output += tbytelist;
+ }
+
+ return output;
+ }
}
\ No newline at end of file
diff --git a/SM64Lib/Level/LevelArea.cs b/SM64Lib/Level/LevelArea.cs
index 8a29a2b..eb491c9 100644
--- a/SM64Lib/Level/LevelArea.cs
+++ b/SM64Lib/Level/LevelArea.cs
@@ -1,178 +1,175 @@
-using System.Collections.Generic;
-using System.Linq;
-using Microsoft.VisualBasic.CompilerServices;
-using global::SM64Lib.Levels.Script;
+using global::SM64Lib.Levels.Script;
using global::SM64Lib.Levels.Script.Commands;
using global::SM64Lib.Levels.ScrolTex;
using global::SM64Lib.Model;
using Newtonsoft.Json;
using System;
+using System.Collections.Generic;
-namespace SM64Lib.Levels
+namespace SM64Lib.Levels;
+
+public abstract class LevelArea
{
- public abstract class LevelArea
+
+ // S h a r e d M e m b e r s
+
+ public static readonly byte[] DefaultNormal3DObject = new byte[] { 0x24, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x13, 0x0, 0x0, 0x0 };
+
+ // F i e l d s
+
+ protected bool _GettingAreaCollision = false;
+
+ // A u t o P r o p e r t i e s
+
+ public SpecialBoxList SpecialBoxes { get; private set; } = new SpecialBoxList();
+ public List ScrollingTextures { get; private set; } = new List();
+ public List Objects { get; private set; } = new List();
+ public List MacroObjects { get; private set; } = new List();
+ public List Warps { get; private set; } = new List();
+ public List WarpsForGame { get; private set; } = new List();
+ public ShowMessage ShowMessage { get; private set; } = new ShowMessage();
+ public AreaBG Background { get; private set; } = new AreaBG();
+ public LevelscriptCommandCollection Levelscript { get; set; } = new LevelscriptCommandCollection();
+ public Geolayout.Geolayout Geolayout { get; set; } = new Geolayout.Geolayout(SM64Lib.Geolayout.Geolayout.NewScriptCreationMode.None);
+ public Geolayout.TerrainTypes TerrainType { get; set; } = SM64Lib.Geolayout.TerrainTypes.NoramlA;
+ public byte BGMusic { get; set; } = 0;
+ public byte AreaID { get; set; } = 0;
+ public uint GeolayoutOffset { get; set; } = 0;
+ public ObjectModel AreaModel { get; set; } = new ObjectModel();
+ public bool Enable2DCamera { get; set; } = false;
+ public uint Bank0x0EOffset { get; set; } = 0;
+ public int Bank0xELength { get; set; }
+
+ // O t h e r P r o p e r t i e s
+
+ [JsonIgnore]
+ public int Fast3DBankRomStart
{
-
- // S h a r e d M e m b e r s
-
- public static readonly byte[] DefaultNormal3DObject = new byte[] { 0x24, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x13, 0x0, 0x0, 0x0 };
-
- // F i e l d s
-
- protected bool _GettingAreaCollision = false;
-
- // A u t o P r o p e r t i e s
-
- public SpecialBoxList SpecialBoxes { get; private set; } = new SpecialBoxList();
- public List ScrollingTextures { get; private set; } = new List();
- public List Objects { get; private set; } = new List();
- public List MacroObjects { get; private set; } = new List();
- public List Warps { get; private set; } = new List();
- public List WarpsForGame { get; private set; } = new List();
- public ShowMessage ShowMessage { get; private set; } = new ShowMessage();
- public AreaBG Background { get; private set; } = new AreaBG();
- public LevelscriptCommandCollection Levelscript { get; set; } = new LevelscriptCommandCollection();
- public Geolayout.Geolayout Geolayout { get; set; } = new Geolayout.Geolayout(SM64Lib.Geolayout.Geolayout.NewScriptCreationMode.None);
- public Geolayout.TerrainTypes TerrainType { get; set; } = SM64Lib.Geolayout.TerrainTypes.NoramlA;
- public byte BGMusic { get; set; } = 0;
- public byte AreaID { get; set; } = 0;
- public uint GeolayoutOffset { get; set; } = 0;
- public ObjectModel AreaModel { get; set; } = new ObjectModel();
- public bool Enable2DCamera { get; set; } = false;
- public uint Bank0x0EOffset { get; set; } = 0;
- public int Bank0xELength { get; set; }
-
- // O t h e r P r o p e r t i e s
-
- [JsonIgnore]
- public int Fast3DBankRomStart
- {
- get
- {
- return Convert.ToInt32(Bank0x0EOffset);
- }
- }
-
- [JsonIgnore]
- public int Fast3DLength
- {
- get
- {
- return CollisionPointer - 0xE000000;
- }
- }
-
- [JsonIgnore]
- public bool IsCamera2D
- {
- get
- {
- return Enable2DCamera && Geolayout.CameraPreset == SM64Lib.Geolayout.CameraPresets.PlattfromLevels;
- }
- }
-
- [JsonIgnore]
- public int CollisionPointer
- {
- get
- {
- int CollisionPointerRet = default;
- _GettingAreaCollision = true;
- foreach (var cmd in Levelscript)
- {
- if (cmd.CommandType == LevelscriptCommandTypes.AreaCollision)
- {
- CollisionPointerRet = Convert.ToInt32(clAreaCollision.GetAreaCollision((LevelscriptCommand)cmd));
- }
- }
-
- _GettingAreaCollision = false;
- return CollisionPointerRet;
- }
-
- set
- {
- if (_GettingAreaCollision)
- return;
- foreach (var cmd in Levelscript)
- {
- if (cmd.CommandType == LevelscriptCommandTypes.AreaCollision)
- {
- clAreaCollision.SetAreaCollision((LevelscriptCommand)cmd, Convert.ToUInt32(value));
- }
- }
- }
- }
-
- // M e t h o d s
-
- public void SetSegmentedBanks(RomManager rommgr)
- {
- var bank0xE = rommgr.SetSegBank(0xE, Convert.ToInt32(Bank0x0EOffset), (int)(Bank0x0EOffset + Bank0xELength), AreaID);
- bank0xE.Data = AreaModel.Fast3DBuffer;
- }
-
- internal void UpdateScrollingTextureVertexPointer(int offset)
- {
- foreach (ManagedScrollingTexture scrollText in ScrollingTextures)
- scrollText.VertexPointer += offset;
- }
-
- public void Close()
- {
- Levelscript.Close();
- Geolayout.Close();
- }
-
- // C o n s t r u c t o r s
-
- protected LevelArea(byte AreaID) : this(AreaID, 9)
- {
- }
-
- protected LevelArea(byte AreaID, byte LevelID) : this(AreaID, LevelID, true, true)
- {
- }
-
- protected LevelArea(byte AreaID, byte LevelID, bool AddWarps, bool AddObjects)
- {
- Geolayout = new Geolayout.Geolayout(SM64Lib.Geolayout.Geolayout.NewScriptCreationMode.Level);
- this.AreaID = AreaID;
- {
- var withBlock = Levelscript;
- withBlock.Add(new LevelscriptCommand(new byte[] { 0x1F, 0x8, AreaID, 0x0, 0x0, 0x0, 0x0, 0x0 }));
- withBlock.Add(new LevelscriptCommand(new byte[] { 0x2E, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }));
- withBlock.Add(new LevelscriptCommand(new byte[] { 0x36, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }));
- withBlock.Add(new LevelscriptCommand(new byte[] { 0x31, 0x4, 0x0, 0x2 }));
- withBlock.Add(new LevelscriptCommand(new byte[] { 0x20, 0x4, 0x0, 0x0 }));
- }
-
- if (AddWarps)
- {
- Objects.Add(new LevelscriptCommand(new byte[] { 0x24, 0x18, 0x1F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xA, 0x0, 0x0, 0x13, 0x0, 0x2F, 0x74 }));
- Warps.Add(new LevelscriptCommand(new byte[] { 0x26, 0x8, 0xA, LevelID, AreaID, 0x0, 0x0, 0x0 }));
- WarpsForGame.Add(new LevelscriptCommand(new byte[] { 0x26, 0x8, 0xF0, 0x6, 0x1, 0x32, 0x0, 0x0 }));
- WarpsForGame.Add(new LevelscriptCommand(new byte[] { 0x26, 0x8, 0xF1, 0x6, 0x1, 0x64, 0x0, 0x0 }));
- }
-
- if (AddObjects)
- {
- //for (int i = 1; i <= 15; i++)
- //{
- // var newObj = new LevelscriptCommand(DefaultNormal3DObject);
- // Objects.Add(newObj);
- //}
- }
- }
-
- protected LevelArea()
- {
- Geolayout = new Geolayout.Geolayout(SM64Lib.Geolayout.Geolayout.NewScriptCreationMode.Level);
- }
-
- [JsonConstructor]
- protected LevelArea(JsonConstructorAttribute attr)
+ get
{
+ return Convert.ToInt32(Bank0x0EOffset);
}
}
+
+ [JsonIgnore]
+ public int Fast3DLength
+ {
+ get
+ {
+ return CollisionPointer - 0xE000000;
+ }
+ }
+
+ [JsonIgnore]
+ public bool IsCamera2D
+ {
+ get
+ {
+ return Enable2DCamera && Geolayout.CameraPreset == SM64Lib.Geolayout.CameraPresets.PlattfromLevels;
+ }
+ }
+
+ [JsonIgnore]
+ public int CollisionPointer
+ {
+ get
+ {
+ int CollisionPointerRet = default;
+ _GettingAreaCollision = true;
+ foreach (var cmd in Levelscript)
+ {
+ if (cmd.CommandType == LevelscriptCommandTypes.AreaCollision)
+ {
+ CollisionPointerRet = Convert.ToInt32(clAreaCollision.GetAreaCollision((LevelscriptCommand)cmd));
+ }
+ }
+
+ _GettingAreaCollision = false;
+ return CollisionPointerRet;
+ }
+
+ set
+ {
+ if (_GettingAreaCollision)
+ return;
+ foreach (var cmd in Levelscript)
+ {
+ if (cmd.CommandType == LevelscriptCommandTypes.AreaCollision)
+ {
+ clAreaCollision.SetAreaCollision((LevelscriptCommand)cmd, Convert.ToUInt32(value));
+ }
+ }
+ }
+ }
+
+ // M e t h o d s
+
+ public void SetSegmentedBanks(RomManager rommgr)
+ {
+ var bank0xE = rommgr.SetSegBank(0xE, Convert.ToInt32(Bank0x0EOffset), (int)(Bank0x0EOffset + Bank0xELength), AreaID);
+ bank0xE.Data = AreaModel.Fast3DBuffer;
+ }
+
+ internal void UpdateScrollingTextureVertexPointer(int offset)
+ {
+ foreach (ManagedScrollingTexture scrollText in ScrollingTextures)
+ scrollText.VertexPointer += offset;
+ }
+
+ public void Close()
+ {
+ Levelscript.Close();
+ Geolayout.Close();
+ }
+
+ // C o n s t r u c t o r s
+
+ protected LevelArea(byte AreaID) : this(AreaID, 9)
+ {
+ }
+
+ protected LevelArea(byte AreaID, byte LevelID) : this(AreaID, LevelID, true, true)
+ {
+ }
+
+ protected LevelArea(byte AreaID, byte LevelID, bool AddWarps, bool AddObjects)
+ {
+ Geolayout = new Geolayout.Geolayout(SM64Lib.Geolayout.Geolayout.NewScriptCreationMode.Level);
+ this.AreaID = AreaID;
+ {
+ var withBlock = Levelscript;
+ withBlock.Add(new LevelscriptCommand(new byte[] { 0x1F, 0x8, AreaID, 0x0, 0x0, 0x0, 0x0, 0x0 }));
+ withBlock.Add(new LevelscriptCommand(new byte[] { 0x2E, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }));
+ withBlock.Add(new LevelscriptCommand(new byte[] { 0x36, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }));
+ withBlock.Add(new LevelscriptCommand(new byte[] { 0x31, 0x4, 0x0, 0x2 }));
+ withBlock.Add(new LevelscriptCommand(new byte[] { 0x20, 0x4, 0x0, 0x0 }));
+ }
+
+ if (AddWarps)
+ {
+ Objects.Add(new LevelscriptCommand(new byte[] { 0x24, 0x18, 0x1F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xA, 0x0, 0x0, 0x13, 0x0, 0x2F, 0x74 }));
+ Warps.Add(new LevelscriptCommand(new byte[] { 0x26, 0x8, 0xA, LevelID, AreaID, 0x0, 0x0, 0x0 }));
+ WarpsForGame.Add(new LevelscriptCommand(new byte[] { 0x26, 0x8, 0xF0, 0x6, 0x1, 0x32, 0x0, 0x0 }));
+ WarpsForGame.Add(new LevelscriptCommand(new byte[] { 0x26, 0x8, 0xF1, 0x6, 0x1, 0x64, 0x0, 0x0 }));
+ }
+
+ if (AddObjects)
+ {
+ //for (int i = 1; i <= 15; i++)
+ //{
+ // var newObj = new LevelscriptCommand(DefaultNormal3DObject);
+ // Objects.Add(newObj);
+ //}
+ }
+ }
+
+ protected LevelArea()
+ {
+ Geolayout = new Geolayout.Geolayout(SM64Lib.Geolayout.Geolayout.NewScriptCreationMode.Level);
+ }
+
+ [JsonConstructor]
+ protected LevelArea(JsonConstructorAttribute attr)
+ {
+ }
}
\ No newline at end of file
diff --git a/SM64Lib/Level/LevelBG.cs b/SM64Lib/Level/LevelBG.cs
index 80b501f..25f05f1 100644
--- a/SM64Lib/Level/LevelBG.cs
+++ b/SM64Lib/Level/LevelBG.cs
@@ -1,234 +1,232 @@
-using global::System.Drawing;
+using global::SM64Lib.Model.Fast3D;
+using global::System.Drawing;
using global::System.IO;
-using Microsoft.VisualBasic.CompilerServices;
-using SM64Lib.Data.System;
-using global::SM64Lib.Model.Fast3D;
using Newtonsoft.Json;
+using SM64Lib.Data.System;
using System;
-namespace SM64Lib.Levels
+namespace SM64Lib.Levels;
+
+public class LevelBG
{
- public class LevelBG
+ private Bitmap _Image = null;
+
+ // A u t o P r o p e r t i e s
+
+ public byte[] ImageData { get; set; } = null;
+ public bool Enabled { get; set; } = true;
+ public bool IsCustom { get; set; } = false;
+ public Geolayout.BackgroundIDs ID { get; set; } = Geolayout.BackgroundIDs.Ocean;
+
+ // A u t o P r o p e r t i e s
+
+ [JsonIgnore]
+ public Bitmap Image
{
- private Bitmap _Image = null;
-
- // A u t o P r o p e r t i e s
-
- public byte[] ImageData { get; set; } = null;
- public bool Enabled { get; set; } = true;
- public bool IsCustom { get; set; } = false;
- public Geolayout.BackgroundIDs ID { get; set; } = Geolayout.BackgroundIDs.Ocean;
-
- // A u t o P r o p e r t i e s
-
- [JsonIgnore]
- public Bitmap Image
+ get
{
- get
+ if (_Image is not null)
{
- if (_Image is not null)
- {
- return _Image;
- }
- else
- {
- var img = GetImage();
- _Image = (Bitmap)img;
- return (Bitmap)img;
- }
- }
- }
-
- [JsonIgnore]
- public int ImageLength
- {
- get
- {
- return ImageData?.Length ?? 0;
- }
- }
-
- [JsonIgnore]
- public bool HasImage
- {
- get
- {
- return ImageData is object;
- }
- }
-
- // C o n s t r c u t o r s
-
- public LevelBG()
- {
- }
-
- public LevelBG(Geolayout.BackgroundIDs ID)
- {
- this.ID = ID;
- }
-
- public LevelBG(Image Image)
- {
- ID = Geolayout.BackgroundIDs.Custom;
- SetImage(Image);
- }
-
- // M e t h o d s
-
- public void WriteImage(Stream s, int offset)
- {
- // Write Image Data
- s.Position = offset;
- if (ImageData is not null)
- {
- s.Write(ImageData, 0, ImageData.Length);
- }
- }
-
- public void ReadImage(Stream s, int offset)
- {
- // Read Image Data
- ImageData = new byte[131072];
- s.Position = offset;
- s.Read(ImageData, 0, ImageData.Length);
- _Image = null;
- }
-
- public void SetImage(Image image)
- {
- SetImage(new Bitmap(image));
- }
-
- public void SetImage(Bitmap bmp)
- {
- var s = new Size(248, 248); // ((&H20140 - &H140) / 256 / 2 / 32) * 31)
- if (bmp.Size != s)
- {
- bmp = (Bitmap)TextureManager.ResizeImage(bmp, s, false);
- }
-
- ImageData = BackgroundImageConverter.GetBytes(bmp);
- _Image = null;
- }
-
- public Image GetImage()
- {
- if (ImageData is not null)
- {
- var s = new Size(248, 248); // ((_ImageByts.Length - &H140) / 256 / 2 / 32) * 31)
- var img = BackgroundImageConverter.GetImage(ImageData, s);
- _Image = img;
- return img;
+ return _Image;
}
else
{
- return null;
+ var img = GetImage();
+ _Image = (Bitmap)img;
+ return (Bitmap)img;
+ }
+ }
+ }
+
+ [JsonIgnore]
+ public int ImageLength
+ {
+ get
+ {
+ return ImageData?.Length ?? 0;
+ }
+ }
+
+ [JsonIgnore]
+ public bool HasImage
+ {
+ get
+ {
+ return ImageData is object;
+ }
+ }
+
+ // C o n s t r c u t o r s
+
+ public LevelBG()
+ {
+ }
+
+ public LevelBG(Geolayout.BackgroundIDs ID)
+ {
+ this.ID = ID;
+ }
+
+ public LevelBG(Image Image)
+ {
+ ID = Geolayout.BackgroundIDs.Custom;
+ SetImage(Image);
+ }
+
+ // M e t h o d s
+
+ public void WriteImage(Stream s, int offset)
+ {
+ // Write Image Data
+ s.Position = offset;
+ if (ImageData is not null)
+ {
+ s.Write(ImageData, 0, ImageData.Length);
+ }
+ }
+
+ public void ReadImage(Stream s, int offset)
+ {
+ // Read Image Data
+ ImageData = new byte[131072];
+ s.Position = offset;
+ s.Read(ImageData, 0, ImageData.Length);
+ _Image = null;
+ }
+
+ public void SetImage(Image image)
+ {
+ SetImage(new Bitmap(image));
+ }
+
+ public void SetImage(Bitmap bmp)
+ {
+ var s = new Size(248, 248); // ((&H20140 - &H140) / 256 / 2 / 32) * 31)
+ if (bmp.Size != s)
+ {
+ bmp = (Bitmap)TextureManager.ResizeImage(bmp, s, false);
+ }
+
+ ImageData = BackgroundImageConverter.GetBytes(bmp);
+ _Image = null;
+ }
+
+ public Image GetImage()
+ {
+ if (ImageData is not null)
+ {
+ var s = new Size(248, 248); // ((_ImageByts.Length - &H140) / 256 / 2 / 32) * 31)
+ var img = BackgroundImageConverter.GetImage(ImageData, s);
+ _Image = img;
+ return img;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public static byte[] GetBackgroundPointerTable()
+ {
+ return new byte[] { 0xA, 0x0, 0x0, 0x0, 0xA, 0x0, 0x8, 0x0, 0xA, 0x0, 0x10, 0x0, 0xA, 0x0, 0x18, 0x0, 0xA, 0x0, 0x20, 0x0, 0xA, 0x0, 0x28, 0x0, 0xA, 0x0, 0x30, 0x0, 0xA, 0x0, 0x38, 0x0, 0xA, 0x0, 0x0, 0x0, 0xA, 0x0, 0x8, 0x0, 0xA, 0x0, 0x40, 0x0, 0xA, 0x0, 0x48, 0x0, 0xA, 0x0, 0x50, 0x0, 0xA, 0x0, 0x58, 0x0, 0xA, 0x0, 0x60, 0x0, 0xA, 0x0, 0x68, 0x0, 0xA, 0x0, 0x70, 0x0, 0xA, 0x0, 0x78, 0x0, 0xA, 0x0, 0x40, 0x0, 0xA, 0x0, 0x48, 0x0, 0xA, 0x0, 0x80, 0x0, 0xA, 0x0, 0x88, 0x0, 0xA, 0x0, 0x90, 0x0, 0xA, 0x0, 0x98, 0x0, 0xA, 0x0, 0xA0, 0x0, 0xA, 0x0, 0xA8, 0x0, 0xA, 0x0, 0xB0, 0x0, 0xA, 0x0, 0xB8, 0x0, 0xA, 0x0, 0x80, 0x0, 0xA, 0x0, 0x88, 0x0, 0xA, 0x0, 0xC0, 0x0, 0xA, 0x0, 0xC8, 0x0, 0xA, 0x0, 0xD0, 0x0, 0xA, 0x0, 0xD8, 0x0, 0xA, 0x0, 0xE0, 0x0, 0xA, 0x0, 0xE8, 0x0, 0xA, 0x0, 0xF0, 0x0, 0xA, 0x0, 0xF8, 0x0, 0xA, 0x0, 0xC0, 0x0, 0xA, 0x0, 0xC8, 0x0, 0xA, 0x1, 0x0, 0x0, 0xA, 0x1, 0x8, 0x0, 0xA, 0x1, 0x10, 0x0, 0xA, 0x1, 0x18, 0x0, 0xA, 0x1, 0x20, 0x0, 0xA, 0x1, 0x28, 0x0, 0xA, 0x1, 0x30, 0x0, 0xA, 0x1, 0x38, 0x0, 0xA, 0x1, 0x0, 0x0, 0xA, 0x1, 0x8, 0x0, 0xA, 0x1, 0x40, 0x0, 0xA, 0x1, 0x48, 0x0, 0xA, 0x1, 0x50, 0x0, 0xA, 0x1, 0x58, 0x0, 0xA, 0x1, 0x60, 0x0, 0xA, 0x1, 0x68, 0x0, 0xA, 0x1, 0x70, 0x0, 0xA, 0x1, 0x78, 0x0, 0xA, 0x1, 0x40, 0x0, 0xA, 0x1, 0x48, 0x0, 0xA, 0x1, 0x80, 0x0, 0xA, 0x1, 0x88, 0x0, 0xA, 0x1, 0x90, 0x0, 0xA, 0x1, 0x98, 0x0, 0xA, 0x1, 0xA0, 0x0, 0xA, 0x1, 0xA8, 0x0, 0xA, 0x1, 0xB0, 0x0, 0xA, 0x1, 0xB8, 0x0, 0xA, 0x1, 0x80, 0x0, 0xA, 0x1, 0x88, 0x0, 0xA, 0x1, 0xC0, 0x0, 0xA, 0x1, 0xC8, 0x0, 0xA, 0x1, 0xD0, 0x0, 0xA, 0x1, 0xD8, 0x0, 0xA, 0x1, 0xE0, 0x0, 0xA, 0x1, 0xE8, 0x0, 0xA, 0x1, 0xF0, 0x0, 0xA, 0x1, 0xF8, 0x0, 0xA, 0x1, 0xC0, 0x0, 0xA, 0x1, 0xC8, 0x0 };
+ }
+
+ // C l a s s e s
+
+ private class BackgroundImageConverter
+ {
+ public static Bitmap GetImage(byte[] data, Size size)
+ {
+ var ms = new MemoryStream(data);
+ var br = new BinaryReader(ms);
+ var img = new Bitmap(size.Width, size.Height);
+ uint current_address = 0;
+ for (int y = 0, loopTo = (int)(size.Height / (double)31 - 1); y <= loopTo; y++)
+ {
+ for (int x = 0, loopTo1 = (int)(size.Width / (double)31 - 1); x <= loopTo1; x++)
+ {
+ ParseBlock(br, img, current_address, new Rectangle(x * 31, y * 31, 31, 31));
+ current_address += 2048;
+ }
+ }
+
+ ms.Close();
+ return img;
+ }
+
+ private static void ParseBlock(BinaryReader br, Bitmap map, uint address, Rectangle rect)
+ {
+ for (int yy = 0, loopTo = rect.Height - 1; yy <= loopTo; yy++)
+ {
+ for (int xx = 0, loopTo1 = rect.Width - 1; xx <= loopTo1; xx++)
+ {
+ int offset = (int)(address + (yy * (rect.Width + 1) + xx) * 2);
+ br.BaseStream.Position = offset;
+ ushort pixel = SwapInts.SwapUInt16(br.ReadUInt16());
+ byte red = Convert.ToByte((pixel >> 11 & 0x1F) * 8);
+ byte green = Convert.ToByte((pixel >> 6 & 0x1F) * 8);
+ byte blue = Convert.ToByte((pixel >> 1 & 0x1F) * 8);
+ byte alpha = Convert.ToByte((pixel & 1) > 0 ? 0xFF : 0);
+ var pixcol = Color.FromArgb(alpha, red, green, blue);
+ map.SetPixel(rect.X + xx, rect.Y + yy, pixcol);
+ }
}
}
- public static byte[] GetBackgroundPointerTable()
+ public static byte[] GetBytes(Bitmap img)
{
- return new byte[] { 0xA, 0x0, 0x0, 0x0, 0xA, 0x0, 0x8, 0x0, 0xA, 0x0, 0x10, 0x0, 0xA, 0x0, 0x18, 0x0, 0xA, 0x0, 0x20, 0x0, 0xA, 0x0, 0x28, 0x0, 0xA, 0x0, 0x30, 0x0, 0xA, 0x0, 0x38, 0x0, 0xA, 0x0, 0x0, 0x0, 0xA, 0x0, 0x8, 0x0, 0xA, 0x0, 0x40, 0x0, 0xA, 0x0, 0x48, 0x0, 0xA, 0x0, 0x50, 0x0, 0xA, 0x0, 0x58, 0x0, 0xA, 0x0, 0x60, 0x0, 0xA, 0x0, 0x68, 0x0, 0xA, 0x0, 0x70, 0x0, 0xA, 0x0, 0x78, 0x0, 0xA, 0x0, 0x40, 0x0, 0xA, 0x0, 0x48, 0x0, 0xA, 0x0, 0x80, 0x0, 0xA, 0x0, 0x88, 0x0, 0xA, 0x0, 0x90, 0x0, 0xA, 0x0, 0x98, 0x0, 0xA, 0x0, 0xA0, 0x0, 0xA, 0x0, 0xA8, 0x0, 0xA, 0x0, 0xB0, 0x0, 0xA, 0x0, 0xB8, 0x0, 0xA, 0x0, 0x80, 0x0, 0xA, 0x0, 0x88, 0x0, 0xA, 0x0, 0xC0, 0x0, 0xA, 0x0, 0xC8, 0x0, 0xA, 0x0, 0xD0, 0x0, 0xA, 0x0, 0xD8, 0x0, 0xA, 0x0, 0xE0, 0x0, 0xA, 0x0, 0xE8, 0x0, 0xA, 0x0, 0xF0, 0x0, 0xA, 0x0, 0xF8, 0x0, 0xA, 0x0, 0xC0, 0x0, 0xA, 0x0, 0xC8, 0x0, 0xA, 0x1, 0x0, 0x0, 0xA, 0x1, 0x8, 0x0, 0xA, 0x1, 0x10, 0x0, 0xA, 0x1, 0x18, 0x0, 0xA, 0x1, 0x20, 0x0, 0xA, 0x1, 0x28, 0x0, 0xA, 0x1, 0x30, 0x0, 0xA, 0x1, 0x38, 0x0, 0xA, 0x1, 0x0, 0x0, 0xA, 0x1, 0x8, 0x0, 0xA, 0x1, 0x40, 0x0, 0xA, 0x1, 0x48, 0x0, 0xA, 0x1, 0x50, 0x0, 0xA, 0x1, 0x58, 0x0, 0xA, 0x1, 0x60, 0x0, 0xA, 0x1, 0x68, 0x0, 0xA, 0x1, 0x70, 0x0, 0xA, 0x1, 0x78, 0x0, 0xA, 0x1, 0x40, 0x0, 0xA, 0x1, 0x48, 0x0, 0xA, 0x1, 0x80, 0x0, 0xA, 0x1, 0x88, 0x0, 0xA, 0x1, 0x90, 0x0, 0xA, 0x1, 0x98, 0x0, 0xA, 0x1, 0xA0, 0x0, 0xA, 0x1, 0xA8, 0x0, 0xA, 0x1, 0xB0, 0x0, 0xA, 0x1, 0xB8, 0x0, 0xA, 0x1, 0x80, 0x0, 0xA, 0x1, 0x88, 0x0, 0xA, 0x1, 0xC0, 0x0, 0xA, 0x1, 0xC8, 0x0, 0xA, 0x1, 0xD0, 0x0, 0xA, 0x1, 0xD8, 0x0, 0xA, 0x1, 0xE0, 0x0, 0xA, 0x1, 0xE8, 0x0, 0xA, 0x1, 0xF0, 0x0, 0xA, 0x1, 0xF8, 0x0, 0xA, 0x1, 0xC0, 0x0, 0xA, 0x1, 0xC8, 0x0 };
+ var ms = new MemoryStream();
+ var bw = new BinaryWriter(ms);
+ int wTiles = (int)(img.Width / (double)31);
+ int hTiles = (int)(img.Height / (double)31);
+ int current_address = 0;
+ for (int y = 0, loopTo = hTiles - 1; y <= loopTo; y++)
+ {
+ for (int x = 0, loopTo1 = wTiles - 1; x <= loopTo1; x++)
+ {
+ ConvertBlock(bw, img, Convert.ToUInt32(current_address), x * 31, y * 31, 0, 0, 0, 0, 31, 31, 32);
+ if (x < wTiles - 1)
+ {
+ ConvertBlock(bw, img, Convert.ToUInt32(current_address), (x + 1) * 31 - 30, y * 31, 30, 0, 1, 0, 31, 31, 32);
+ ConvertBlock(bw, img, Convert.ToUInt32(current_address), (x + 1) * 31 - 30, y * 31, 30, 30, 1, 1, 31, 31, 32);
+ }
+ else
+ {
+ ConvertBlock(bw, img, Convert.ToUInt32(current_address), -30, y * 31, 30, 0, 1, 0, 31, 31, 32);
+ ConvertBlock(bw, img, Convert.ToUInt32(current_address), -30, y * 31, 30, 30, 1, 1, 31, 31, 32);
+ }
+
+ if (y < hTiles - 1)
+ {
+ ConvertBlock(bw, img, Convert.ToUInt32(current_address), x * 31, (y + 1) * 31 - 30, 0, 30, 0, 1, 31, 31, 32);
+ }
+ else
+ {
+ ConvertBlock(bw, img, Convert.ToUInt32(current_address), x * 31, -30, 0, 30, 0, 1, 31, 31, 32);
+ }
+
+ current_address += 2048;
+ }
+ }
+
+ var temp = ms.ToArray();
+ ms.Close();
+ return temp;
}
- // C l a s s e s
-
- private class BackgroundImageConverter
+ private static void ConvertBlock(BinaryWriter bw, Bitmap map, uint address, int src_x, int src_y, int start_x, int start_y, int offset_x, int offset_y, int w, int h, int lineWidth)
{
- public static Bitmap GetImage(byte[] data, Size size)
+ for (int yy = start_y, loopTo = h - 1; yy <= loopTo; yy++)
{
- var ms = new MemoryStream(data);
- var br = new BinaryReader(ms);
- var img = new Bitmap(size.Width, size.Height);
- uint current_address = 0;
- for (int y = 0, loopTo = (int)(size.Height / (double)31 - 1); y <= loopTo; y++)
+ for (int xx = start_x, loopTo1 = w - 1; xx <= loopTo1; xx++)
{
- for (int x = 0, loopTo1 = (int)(size.Width / (double)31 - 1); x <= loopTo1; x++)
- {
- ParseBlock(br, img, current_address, new Rectangle(x * 31, y * 31, 31, 31));
- current_address += 2048;
- }
- }
-
- ms.Close();
- return img;
- }
-
- private static void ParseBlock(BinaryReader br, Bitmap map, uint address, Rectangle rect)
- {
- for (int yy = 0, loopTo = rect.Height - 1; yy <= loopTo; yy++)
- {
- for (int xx = 0, loopTo1 = rect.Width - 1; xx <= loopTo1; xx++)
- {
- int offset = (int)(address + (yy * (rect.Width + 1) + xx) * 2);
- br.BaseStream.Position = offset;
- ushort pixel = SwapInts.SwapUInt16(br.ReadUInt16());
- byte red = Convert.ToByte((pixel >> 11 & 0x1F) * 8);
- byte green = Convert.ToByte((pixel >> 6 & 0x1F) * 8);
- byte blue = Convert.ToByte((pixel >> 1 & 0x1F) * 8);
- byte alpha = Convert.ToByte((pixel & 1) > 0 ? 0xFF : 0);
- var pixcol = Color.FromArgb(alpha, red, green, blue);
- map.SetPixel(rect.X + xx, rect.Y + yy, pixcol);
- }
- }
- }
-
- public static byte[] GetBytes(Bitmap img)
- {
- var ms = new MemoryStream();
- var bw = new BinaryWriter(ms);
- int wTiles = (int)(img.Width / (double)31);
- int hTiles = (int)(img.Height / (double)31);
- int current_address = 0;
- for (int y = 0, loopTo = hTiles - 1; y <= loopTo; y++)
- {
- for (int x = 0, loopTo1 = wTiles - 1; x <= loopTo1; x++)
- {
- ConvertBlock(bw, img, Convert.ToUInt32(current_address), x * 31, y * 31, 0, 0, 0, 0, 31, 31, 32);
- if (x < wTiles - 1)
- {
- ConvertBlock(bw, img, Convert.ToUInt32(current_address), (x + 1) * 31 - 30, y * 31, 30, 0, 1, 0, 31, 31, 32);
- ConvertBlock(bw, img, Convert.ToUInt32(current_address), (x + 1) * 31 - 30, y * 31, 30, 30, 1, 1, 31, 31, 32);
- }
- else
- {
- ConvertBlock(bw, img, Convert.ToUInt32(current_address), -30, y * 31, 30, 0, 1, 0, 31, 31, 32);
- ConvertBlock(bw, img, Convert.ToUInt32(current_address), -30, y * 31, 30, 30, 1, 1, 31, 31, 32);
- }
-
- if (y < hTiles - 1)
- {
- ConvertBlock(bw, img, Convert.ToUInt32(current_address), x * 31, (y + 1) * 31 - 30, 0, 30, 0, 1, 31, 31, 32);
- }
- else
- {
- ConvertBlock(bw, img, Convert.ToUInt32(current_address), x * 31, -30, 0, 30, 0, 1, 31, 31, 32);
- }
-
- current_address += 2048;
- }
- }
-
- var temp = ms.ToArray();
- ms.Close();
- return temp;
- }
-
- private static void ConvertBlock(BinaryWriter bw, Bitmap map, uint address, int src_x, int src_y, int start_x, int start_y, int offset_x, int offset_y, int w, int h, int lineWidth)
- {
- for (int yy = start_y, loopTo = h - 1; yy <= loopTo; yy++)
- {
- for (int xx = start_x, loopTo1 = w - 1; xx <= loopTo1; xx++)
- {
- var pixel = map.GetPixel(src_x + xx, src_y + yy);
- int r = pixel.R / 8;
- int g = pixel.G / 8;
- int b = pixel.B / 8;
- int a = pixel.A == 0xFF ? 1 : 0;
- bw.BaseStream.Position = address + ((yy + offset_y) * lineWidth + xx + offset_x) * 2;
- bw.Write(SwapInts.SwapUInt16(Convert.ToUInt16(r << 11 | g << 6 | b << 1 | a)));
- }
+ var pixel = map.GetPixel(src_x + xx, src_y + yy);
+ int r = pixel.R / 8;
+ int g = pixel.G / 8;
+ int b = pixel.B / 8;
+ int a = pixel.A == 0xFF ? 1 : 0;
+ bw.BaseStream.Position = address + ((yy + offset_y) * lineWidth + xx + offset_x) * 2;
+ bw.Write(SwapInts.SwapUInt16(Convert.ToUInt16(r << 11 | g << 6 | b << 1 | a)));
}
}
}
diff --git a/SM64Lib/Level/LevelExport.cs b/SM64Lib/Level/LevelExport.cs
index 0497a39..4c3cf32 100644
--- a/SM64Lib/Level/LevelExport.cs
+++ b/SM64Lib/Level/LevelExport.cs
@@ -1,79 +1,74 @@
using Newtonsoft.Json;
using SM64Lib.Levels.Script;
-using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-namespace SM64Lib.Levels
+namespace SM64Lib.Levels;
+
+public class LevelExport
{
- public class LevelExport
+ // P r o p e r t i e s
+
+ [JsonProperty]
+ public object Content { get; protected set; }
+ [JsonProperty]
+ public LevelExportContentType ContentType { get; set; }
+
+ // C o n s t r u c t o r s
+
+ private LevelExport(object content, LevelExportContentType type) : this()
{
- // P r o p e r t i e s
+ Content = content;
+ ContentType = type;
+ }
- [JsonProperty]
- public object Content { get; protected set; }
- [JsonProperty]
- public LevelExportContentType ContentType { get; set; }
+ public LevelExport(Level level) : this(new List { level }) { }
+ public LevelExport(List levels) : this(levels, LevelExportContentType.Level) { }
+ public LevelExport(LevelArea area) : this(new List { area }) { }
+ public LevelExport(List areas) : this(areas, LevelExportContentType.Area) { }
+ public LevelExport(List cmds, LevelExportContentType contentType) : this((object)cmds, contentType) { }
- // C o n s t r u c t o r s
+ [JsonConstructor]
+ private LevelExport() { }
- private LevelExport(object content, LevelExportContentType type) : this()
- {
- Content = content;
- ContentType = type;
- }
+ // F e a t u r e s
- public LevelExport(Level level) : this(new List { level }) { }
- public LevelExport(List levels) : this(levels, LevelExportContentType.Level) { }
- public LevelExport(LevelArea area) : this(new List { area }) { }
- public LevelExport(List areas) : this(areas, LevelExportContentType.Area) { }
- public LevelExport(List cmds, LevelExportContentType contentType) : this((object)cmds, contentType) { }
+ public void WriteToFile(string filePath, CompressionLevel compressionLevel)
+ {
+ var plainText = compressionLevel == CompressionLevel.NoCompression;
- [JsonConstructor]
- private LevelExport() { }
+ // Open streams
+ var fs = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite);
+ var output = new DeflateStream(fs, compressionLevel, true);
+ var sw = new StreamWriter(output);
- // F e a t u r e s
+ // Create serializer
+ var serializer = Json.JsonHelper.CreateJsonSerializer(true, true, plainText);
- public void WriteToFile(string filePath, CompressionLevel compressionLevel)
- {
- var plainText = compressionLevel == CompressionLevel.NoCompression;
+ // Serialize
+ serializer.Serialize(sw, this);
- // Open streams
- var fs = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite);
- var output = new DeflateStream(fs, compressionLevel, true);
- var sw = new StreamWriter(output);
+ sw.Flush();
+ output.Close();
+ fs.Close();
+ }
- // Create serializer
- var serializer = Json.JsonHelper.CreateJsonSerializer(true, true, plainText);
+ public static LevelExport ReadFromFile(string filePath)
+ {
+ // Open streams
+ var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
+ var input = new DeflateStream(fs, CompressionMode.Decompress);
+ var sr = new StreamReader(input);
- // Serialize
- serializer.Serialize(sw, this);
+ // Create serializer
+ var serializer = Json.JsonHelper.CreateJsonSerializer(true, true);
- sw.Flush();
- output.Close();
- fs.Close();
- }
+ // Deserialize
+ var export = (LevelExport)serializer.Deserialize(sr, typeof(LevelExport));
- public static LevelExport ReadFromFile(string filePath)
- {
- // Open streams
- var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
- var input = new DeflateStream(fs, CompressionMode.Decompress);
- var sr = new StreamReader(input);
-
- // Create serializer
- var serializer = Json.JsonHelper.CreateJsonSerializer(true, true);
+ fs.Close();
- // Deserialize
- var export = (LevelExport)serializer.Deserialize(sr, typeof(LevelExport));
-
- fs.Close();
-
- return export;
- }
+ return export;
}
}
diff --git a/SM64Lib/Level/LevelExportContentType.cs b/SM64Lib/Level/LevelExportContentType.cs
index 95c2c17..caf3a95 100644
--- a/SM64Lib/Level/LevelExportContentType.cs
+++ b/SM64Lib/Level/LevelExportContentType.cs
@@ -1,17 +1,10 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+namespace SM64Lib.Levels;
-namespace SM64Lib.Levels
+public enum LevelExportContentType
{
- public enum LevelExportContentType
- {
- Unknown,
- Level,
- Area,
- Objects,
- Warps
- }
+ Unknown,
+ Level,
+ Area,
+ Objects,
+ Warps
}
diff --git a/SM64Lib/Level/LevelExportFileFormat.cs b/SM64Lib/Level/LevelExportFileFormat.cs
index 90452d0..9b90c75 100644
--- a/SM64Lib/Level/LevelExportFileFormat.cs
+++ b/SM64Lib/Level/LevelExportFileFormat.cs
@@ -1,14 +1,7 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+namespace SM64Lib.Levels;
-namespace SM64Lib.Levels
+public enum LevelExportFileFormat
{
- public enum LevelExportFileFormat
- {
- JSON,
- PlainText
- }
+ JSON,
+ PlainText
}
diff --git a/SM64Lib/Level/LevelExportImporter.cs b/SM64Lib/Level/LevelExportImporter.cs
index a269533..2f1da83 100644
--- a/SM64Lib/Level/LevelExportImporter.cs
+++ b/SM64Lib/Level/LevelExportImporter.cs
@@ -2,74 +2,71 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-namespace SM64Lib.Levels
+namespace SM64Lib.Levels;
+
+public static class LevelExportImporter
{
- public static class LevelExportImporter
+ public static void ImportLevel(LevelExport export, RomManager destRomManager, KeyValuePair[] levelIDs)
{
- public static void ImportLevel(LevelExport export, RomManager destRomManager, KeyValuePair[] levelIDs)
+ var levels = export.Content as Level[];
+ if (levels != null)
{
- var levels = export.Content as Level[];
- if (levels != null)
+ foreach (var level in levels)
{
- foreach (var level in levels)
+ var id = (ushort?)levelIDs.FirstOrDefault(n => n.Key == level).Value;
+ if (id is not null)
{
- var id = (ushort?)levelIDs.FirstOrDefault(n => n.Key == level).Value;
- if (id is not null)
- {
- level.LevelID = (ushort)id;
- destRomManager.Levels.Add(level);
- }
+ level.LevelID = (ushort)id;
+ destRomManager.Levels.Add(level);
}
}
- else
- throw new NotSupportedException();
}
+ else
+ throw new NotSupportedException();
+ }
- public static void ImportArea(LevelExport export, Level destLevel, KeyValuePair[] areaIDs)
+ public static void ImportArea(LevelExport export, Level destLevel, KeyValuePair[] areaIDs)
+ {
+ var areas = export.Content as LevelArea[];
+ if (areas != null)
{
- var areas = export.Content as LevelArea[];
- if (areas != null)
+ foreach (var area in areas)
{
- foreach (var area in areas)
+ var id = (byte?)areaIDs.FirstOrDefault(n => n.Key == area).Value;
+ if (id is not null)
{
- var id = (byte?)areaIDs.FirstOrDefault(n => n.Key == area).Value;
- if (id is not null)
- {
- area.AreaID = (byte)id;
- destLevel.Areas.Add(area);
- }
+ area.AreaID = (byte)id;
+ destLevel.Areas.Add(area);
}
}
- else
- throw new NotSupportedException();
}
+ else
+ throw new NotSupportedException();
+ }
- public static void ImportScript(LevelExport export, LevelArea destArea, List allowedCommands)
+ public static void ImportScript(LevelExport export, LevelArea destArea, List allowedCommands)
+ {
+ var cmds = export.Content as List;
+ if (cmds is not null)
{
- var cmds = export.Content as List;
- if (cmds is not null)
+ foreach (var cmd in cmds)
{
- foreach (var cmd in cmds)
+ if (allowedCommands.Contains(cmd))
{
- if (allowedCommands.Contains(cmd))
+ switch (export.ContentType)
{
- switch (export.ContentType)
- {
- case LevelExportContentType.Objects:
- destArea.Objects.Add(cmd);
- break;
- case LevelExportContentType.Warps:
- destArea.Warps.Add(cmd);
- break;
- }
+ case LevelExportContentType.Objects:
+ destArea.Objects.Add(cmd);
+ break;
+ case LevelExportContentType.Warps:
+ destArea.Warps.Add(cmd);
+ break;
}
}
}
- else
- throw new NotSupportedException();
}
+ else
+ throw new NotSupportedException();
}
}
diff --git a/SM64Lib/Level/LevelInfoDataTabel.cs b/SM64Lib/Level/LevelInfoDataTabel.cs
index 074f749..39a489e 100644
--- a/SM64Lib/Level/LevelInfoDataTabel.cs
+++ b/SM64Lib/Level/LevelInfoDataTabel.cs
@@ -1,143 +1,142 @@
-using System.Collections.Generic;
+using global::Newtonsoft.Json.Linq;
using global::System.IO;
+using System.Collections.Generic;
using System.Linq;
-using global::Newtonsoft.Json.Linq;
using static SM64Lib.TextValueConverter.TextValueConverter;
-namespace SM64Lib.Levels
+namespace SM64Lib.Levels;
+
+public class LevelInfoDataTabelList : List
{
- public class LevelInfoDataTabelList : List
+ public void ReadFromFile(string FileName)
{
- public void ReadFromFile(string FileName)
+ var jobj = JObject.Parse(File.ReadAllText(FileName));
+ if (jobj["Levels"] is not null)
{
- var jobj = JObject.Parse(File.ReadAllText(FileName));
- if (jobj["Levels"] is not null)
+ foreach (JObject entry in (JArray)jobj["Levels"])
{
- foreach (JObject entry in (JArray)jobj["Levels"])
+ Add(new Level
{
- Add(new Level
- {
- Name = entry?["Name"].ToString(),
- Number = entry?["Number"].ToString(),
- TypeString = entry?["Type"].ToString(),
- ID = (ushort)ValueFromText(entry?["ID"].ToString()),
- Pointer = (uint)ValueFromText(entry?["Pointer"].ToString()),
- Index = entry["Index"].Value()
- });
- }
+ Name = entry?["Name"].ToString(),
+ Number = entry?["Number"].ToString(),
+ TypeString = entry?["Type"].ToString(),
+ ID = (ushort)ValueFromText(entry?["ID"].ToString()),
+ Pointer = (uint)ValueFromText(entry?["Pointer"].ToString()),
+ Index = entry["Index"].Value()
+ });
}
}
-
- public Level GetByLevelID(ushort ID)
- {
- return this.FirstOrDefault(n => n.ID == ID);
- }
-
- public class Level
- {
- public ushort ID { get; set; } = 0;
- public uint Pointer { get; set; } = 0;
- public string Name { get; set; } = "";
- public string Number { get; set; } = "";
- public LevelTypes Type { get; set; } = LevelTypes.Level;
- public int Index { get; set; } = -1;
-
- public string TypeString
- {
- get
- {
- var switchExpr = Type;
- switch (switchExpr)
- {
- case LevelTypes.Level:
- {
- return "Level";
- }
-
- case LevelTypes.Sidelevel:
- {
- return "Side";
- }
-
- case LevelTypes.Overworld:
- {
- return "OW";
- }
-
- case LevelTypes.Bowsercourse:
- {
- return "BC";
- }
-
- case LevelTypes.Bowserbattle:
- {
- return "BB";
- }
-
- case LevelTypes.Switchpalace:
- {
- return "Switch";
- }
-
- default:
- {
- return "";
- }
- }
- }
-
- set
- {
- switch (value)
- {
- case "Level":
- {
- Type = LevelTypes.Level;
- break;
- }
-
- case "Side":
- {
- Type = LevelTypes.Sidelevel;
- break;
- }
-
- case "OW":
- {
- Type = LevelTypes.Overworld;
- break;
- }
-
- case "BC":
- {
- Type = LevelTypes.Bowsercourse;
- break;
- }
-
- case "BB":
- {
- Type = LevelTypes.Bowserbattle;
- break;
- }
-
- case "Switch":
- {
- Type = LevelTypes.Switchpalace;
- break;
- }
- }
- }
- }
- }
-
- public enum LevelTypes
- {
- Level,
- Sidelevel,
- Overworld,
- Switchpalace,
- Bowsercourse,
- Bowserbattle
- }
+ }
+
+ public Level GetByLevelID(ushort ID)
+ {
+ return this.FirstOrDefault(n => n.ID == ID);
+ }
+
+ public class Level
+ {
+ public ushort ID { get; set; } = 0;
+ public uint Pointer { get; set; } = 0;
+ public string Name { get; set; } = "";
+ public string Number { get; set; } = "";
+ public LevelTypes Type { get; set; } = LevelTypes.Level;
+ public int Index { get; set; } = -1;
+
+ public string TypeString
+ {
+ get
+ {
+ var switchExpr = Type;
+ switch (switchExpr)
+ {
+ case LevelTypes.Level:
+ {
+ return "Level";
+ }
+
+ case LevelTypes.Sidelevel:
+ {
+ return "Side";
+ }
+
+ case LevelTypes.Overworld:
+ {
+ return "OW";
+ }
+
+ case LevelTypes.Bowsercourse:
+ {
+ return "BC";
+ }
+
+ case LevelTypes.Bowserbattle:
+ {
+ return "BB";
+ }
+
+ case LevelTypes.Switchpalace:
+ {
+ return "Switch";
+ }
+
+ default:
+ {
+ return "";
+ }
+ }
+ }
+
+ set
+ {
+ switch (value)
+ {
+ case "Level":
+ {
+ Type = LevelTypes.Level;
+ break;
+ }
+
+ case "Side":
+ {
+ Type = LevelTypes.Sidelevel;
+ break;
+ }
+
+ case "OW":
+ {
+ Type = LevelTypes.Overworld;
+ break;
+ }
+
+ case "BC":
+ {
+ Type = LevelTypes.Bowsercourse;
+ break;
+ }
+
+ case "BB":
+ {
+ Type = LevelTypes.Bowserbattle;
+ break;
+ }
+
+ case "Switch":
+ {
+ Type = LevelTypes.Switchpalace;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ public enum LevelTypes
+ {
+ Level,
+ Sidelevel,
+ Overworld,
+ Switchpalace,
+ Bowsercourse,
+ Bowserbattle
}
}
\ No newline at end of file
diff --git a/SM64Lib/Level/LevelList.cs b/SM64Lib/Level/LevelList.cs
index 778b681..895bc0a 100644
--- a/SM64Lib/Level/LevelList.cs
+++ b/SM64Lib/Level/LevelList.cs
@@ -2,21 +2,20 @@
using System.Data;
using System.Linq;
-namespace SM64Lib.Levels
-{
- public class LevelList : List
- {
- public bool NeedToSave
- {
- get
- {
- return this.Where(n => n.NeedToSaveLevelscript || n.NeedToSaveBanks0E).Count() > 0;
- }
- }
+namespace SM64Lib.Levels;
- public long Length
+public class LevelList : List
+{
+ public bool NeedToSave
+ {
+ get
{
- get => this.Sum(n => n.Length);
+ return this.Where(n => n.NeedToSaveLevelscript || n.NeedToSaveBanks0E).Count() > 0;
}
}
+
+ public long Length
+ {
+ get => this.Sum(n => n.Length);
+ }
}
\ No newline at end of file
diff --git a/SM64Lib/Level/LevelManager.cs b/SM64Lib/Level/LevelManager.cs
index a51b088..bda2a30 100644
--- a/SM64Lib/Level/LevelManager.cs
+++ b/SM64Lib/Level/LevelManager.cs
@@ -1,10 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Data;
-using global::System.IO;
-using System.Linq;
-using Microsoft.VisualBasic.CompilerServices;
-using global::SM64Lib.Data;
+using global::SM64Lib.Data;
using global::SM64Lib.Data.System;
using global::SM64Lib.Geolayout.Script;
using global::SM64Lib.Geolayout.Script.Commands;
@@ -13,882 +7,886 @@ using global::SM64Lib.Levels.Script.Commands;
using global::SM64Lib.Levels.ScrolTex;
using global::SM64Lib.Model;
using global::SM64Lib.SegmentedBanking;
+using global::System.IO;
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Linq;
-namespace SM64Lib.Levels
+namespace SM64Lib.Levels;
+
+public class LevelManager : ILevelManager
{
- public class LevelManager : ILevelManager
+ public bool EnableLoadingAreaReverb { get; set; } = true;
+ public bool SortSpecialBoxesByHeight { get; set; } = true;
+
+ ///
+ /// Loads a ROM Manager Level from ROM.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public virtual void LoadLevel(Level lvl, RomManager rommgr, ushort LevelID, uint segAddress)
{
- public bool EnableLoadingAreaReverb { get; set; } = true;
- public bool SortSpecialBoxesByHeight { get; set; } = true;
+ int customBGStart = 0;
+ int customBGEnd = 0;
+ lvl.LevelID = LevelID;
- ///
- /// Loads a ROM Manager Level from ROM.
- ///
- ///
- ///
- ///
- ///
- public virtual void LoadLevel(Level lvl, RomManager rommgr, ushort LevelID, uint segAddress)
+ // Load Bank 0x19
+ lvl.Bank0x19 = rommgr.GetSegBank(0x19);
+ lvl.Bank0x19.ReadDataIfNull(rommgr.RomFile);
+
+ // Close if not closed & re-open
+ if (!lvl.Closed) lvl.Close();
+ lvl.Closed = false;
+
+ // Lade Levelscript
+ lvl.Levelscript = new Levelscript();
+ lvl.Levelscript.Read(rommgr, Convert.ToInt32(segAddress));
+
+ // Erstelle Areas / Lade Einstellungen
+ bool AreaOnFly = false;
+ LevelArea tArea = null;
+ var CurrentLevelScriptCommands = lvl.Levelscript.ToArray();
+ var cmdsToRemove = new List();
+ foreach (LevelscriptCommand c in CurrentLevelScriptCommands)
{
- int customBGStart = 0;
- int customBGEnd = 0;
- lvl.LevelID = LevelID;
-
- // Load Bank 0x19
- lvl.Bank0x19 = rommgr.GetSegBank(0x19);
- lvl.Bank0x19.ReadDataIfNull(rommgr.RomFile);
-
- // Close if not closed & re-open
- if (!lvl.Closed) lvl.Close();
- lvl.Closed = false;
-
- // Lade Levelscript
- lvl.Levelscript = new Levelscript();
- lvl.Levelscript.Read(rommgr, Convert.ToInt32(segAddress));
-
- // Erstelle Areas / Lade Einstellungen
- bool AreaOnFly = false;
- LevelArea tArea = null;
- var CurrentLevelScriptCommands = lvl.Levelscript.ToArray();
- var cmdsToRemove = new List();
- foreach (LevelscriptCommand c in CurrentLevelScriptCommands)
+ var switchExpr = c.CommandType;
+ switch (switchExpr)
{
- var switchExpr = c.CommandType;
- switch (switchExpr)
- {
- case LevelscriptCommandTypes.StartArea:
- AreaOnFly = true;
- tArea = new RMLevelArea();
- tArea.AreaID = clStartArea.GetAreaID(c);
- tArea.GeolayoutOffset = clStartArea.GetSegGeolayoutAddr(c); // - bank0x19.BankAddress + bank0x19.RomStart
- tArea.Geolayout.Read(rommgr, Convert.ToInt32(tArea.GeolayoutOffset));
- break;
- case LevelscriptCommandTypes.EndOfArea:
- tArea.Levelscript.Add(c);
- lvl.Levelscript.Remove(c);
- lvl.Areas.Add(tArea);
- AreaOnFly = false;
- break;
- case LevelscriptCommandTypes.AreaMusic:
- tArea.BGMusic = clAreaMusic.GetMusicID(c);
- break;
- case LevelscriptCommandTypes.AreaMusicSimple:
- tArea.BGMusic = clAreaMusicSimple.GetMusicID(c);
- break;
- case LevelscriptCommandTypes.Tarrain:
- tArea.TerrainType = (Geolayout.TerrainTypes)clTerrian.GetTerrainType(c);
- break;
- case LevelscriptCommandTypes.Normal3DObject:
- var scrollTexAddrs = new List(new[] { 0x400000, 0x401700 });
- if (rommgr.RomConfig.ScrollTexConfig.UseCustomBehavior)
- scrollTexAddrs.Add(rommgr.RomConfig.ScrollTexConfig.CustomBehaviorAddress);
- if (scrollTexAddrs.Contains((int)clNormal3DObject.GetSegBehaviorAddr(c)))
- tArea.ScrollingTextures.Add(new ManagedScrollingTexture(c));
- else
- tArea.Objects.Add(c);
- break;
- case LevelscriptCommandTypes.ConnectedWarp:
- if ((new[] { 0xF0, 0xF1 }).Contains(clWarp.GetWarpID(c)))
- tArea.WarpsForGame.Add(c);
- else
- tArea.Warps.Add(c);
- break;
- case LevelscriptCommandTypes.PaintingWarp:
- case LevelscriptCommandTypes.InstantWarp:
+ case LevelscriptCommandTypes.StartArea:
+ AreaOnFly = true;
+ tArea = new RMLevelArea();
+ tArea.AreaID = clStartArea.GetAreaID(c);
+ tArea.GeolayoutOffset = clStartArea.GetSegGeolayoutAddr(c); // - bank0x19.BankAddress + bank0x19.RomStart
+ tArea.Geolayout.Read(rommgr, Convert.ToInt32(tArea.GeolayoutOffset));
+ break;
+ case LevelscriptCommandTypes.EndOfArea:
+ tArea.Levelscript.Add(c);
+ lvl.Levelscript.Remove(c);
+ lvl.Areas.Add(tArea);
+ AreaOnFly = false;
+ break;
+ case LevelscriptCommandTypes.AreaMusic:
+ tArea.BGMusic = clAreaMusic.GetMusicID(c);
+ break;
+ case LevelscriptCommandTypes.AreaMusicSimple:
+ tArea.BGMusic = clAreaMusicSimple.GetMusicID(c);
+ break;
+ case LevelscriptCommandTypes.Tarrain:
+ tArea.TerrainType = (Geolayout.TerrainTypes)clTerrian.GetTerrainType(c);
+ break;
+ case LevelscriptCommandTypes.Normal3DObject:
+ var scrollTexAddrs = new List(new[] { 0x400000, 0x401700 });
+ if (rommgr.RomConfig.ScrollTexConfig.UseCustomBehavior)
+ scrollTexAddrs.Add(rommgr.RomConfig.ScrollTexConfig.CustomBehaviorAddress);
+ if (scrollTexAddrs.Contains((int)clNormal3DObject.GetSegBehaviorAddr(c)))
+ tArea.ScrollingTextures.Add(new ManagedScrollingTexture(c));
+ else
+ tArea.Objects.Add(c);
+ break;
+ case LevelscriptCommandTypes.ConnectedWarp:
+ if ((new[] { 0xF0, 0xF1 }).Contains(clWarp.GetWarpID(c)))
+ tArea.WarpsForGame.Add(c);
+ else
tArea.Warps.Add(c);
+ break;
+ case LevelscriptCommandTypes.PaintingWarp:
+ case LevelscriptCommandTypes.InstantWarp:
+ tArea.Warps.Add(c);
+ break;
+ case LevelscriptCommandTypes.LoadRomToRam:
+ byte bankID = clLoadRomToRam.GetSegmentedID(c);
+ int startAddr = clLoadRomToRam.GetRomStart(c);
+ int endAddr = clLoadRomToRam.GetRomEnd(c);
+ switch (bankID)
+ {
+ case 0xA: // Background-Image
+ customBGStart = startAddr;
+ customBGEnd = endAddr - 0x140;
+ break;
+ case 0x7: // Global Object Bank
+ if (rommgr.GlobalModelBank?.CurSeg is not null && startAddr == rommgr.GlobalModelBank.CurSeg.RomStart && endAddr == rommgr.GlobalModelBank.CurSeg.RomEnd)
+ {
+ lvl.EnableGlobalObjectBank = true;
+ lvl.LastGobCmdSegLoad = c;
+ }
+ break;
+ case 0x9:
+ if (((RMLevel)lvl).Config.EnableLocalObjectBank)
+ {
+ lvl.EnableLocalObjectBank = true;
+ }
+ lvl.LastLobCmdSegLoad = c;
+ break;
+ }
+ break;
+ case LevelscriptCommandTypes.ShowDialog:
+ if (AreaOnFly)
+ {
+ tArea.ShowMessage.Enabled = true;
+ tArea.ShowMessage.DialogID = clShowDialog.GetDialogID(c);
+ }
+ break;
+ case LevelscriptCommandTypes.JumpBack:
+ case LevelscriptCommandTypes.JumpToSegAddr:
+ if (tArea is not null)
+ cmdsToRemove.Add(c);
+ break;
+ }
+
+ if (AreaOnFly && !cmdsToRemove.Contains(c))
+ {
+ lvl.Levelscript.Remove(c);
+ tArea.Levelscript.Add(c);
+ }
+ }
+
+ // Lösche alle Jump-Commands aus dem Levelscript
+ foreach (LevelscriptCommand cmd in cmdsToRemove)
+ {
+ lvl.Levelscript.Remove(cmd);
+ cmd.Close();
+ }
+
+ // Lösche alle Objekte und Warps aus dem Levelscript
+ var lvlscrptidstoremove = new[] { LevelscriptCommandTypes.Normal3DObject, LevelscriptCommandTypes.ConnectedWarp, LevelscriptCommandTypes.PaintingWarp, LevelscriptCommandTypes.InstantWarp };
+ foreach (var a in lvl.Areas)
+ {
+ foreach (var c in a.Levelscript.Where(n => lvlscrptidstoremove.Contains(n.CommandType)).ToArray())
+ a.Levelscript.Remove(c);
+ }
+
+ // Load Local Object Bank
+ if (lvl.LastLobCmdSegLoad is not null)
+ {
+ var seg = new SegmentedBank()
+ {
+ BankID = clLoadRomToRam.GetSegmentedID(lvl.LastLobCmdSegLoad),
+ RomStart = clLoadRomToRam.GetRomStart(lvl.LastLobCmdSegLoad),
+ RomEnd = clLoadRomToRam.GetRomEnd(lvl.LastLobCmdSegLoad)
+ };
+ lvl.LocalObjectBank.ReadFromSeg(rommgr, seg, ((RMLevel)lvl).Config.LocalObjectBank);
+ }
+
+ // Lese Custom Background Image
+ var fs = new FileStream(rommgr.RomFile, FileMode.Open, FileAccess.Read);
+ var br2 = new BinaryReader(fs);
+ lvl.Background.Enabled = false;
+ foreach (LevelArea a in lvl.Areas)
+ {
+ var bgglcmd = a.Geolayout.Geolayoutscript.GetFirst(GeolayoutCommandTypes.Background);
+ if (cgBackground.GetBackgroundPointer(bgglcmd) == 0)
+ {
+ a.Background.Type = AreaBGs.Color;
+ a.Background.Color = cgBackground.GetRrgbaColor(bgglcmd);
+ }
+ else
+ {
+ a.Background.Type = AreaBGs.Levelbackground;
+ lvl.Background.ID = (Geolayout.BackgroundIDs)cgBackground.GetBackgroundID(bgglcmd);
+ lvl.Background.Enabled = true;
+ }
+ }
+
+ if (customBGStart != 0)
+ {
+ lvl.Background.IsCustom = true;
+ }
+
+ foreach (int val in Enum.GetValues(typeof(Geolayout.BackgroundPointers)))
+ {
+ if (val != 0 && customBGStart == val)
+ {
+ lvl.Background.IsCustom = false;
+ }
+ }
+
+ if (lvl.Background.Enabled && lvl.Background.IsCustom) // .ID = Geolayout.BackgroundIDs.Custom Then
+ {
+ fs.Position = customBGStart;
+ lvl.Background.ReadImage(fs, customBGStart);
+ }
+
+ int bank0x19RomStart;
+ int bank0x19RomEnd;
+ BinaryReader brToUse;
+ bank0x19RomStart = 0;
+ bank0x19RomEnd = lvl.Bank0x19.Length;
+ brToUse = new BinaryReader(lvl.Bank0x19.Data);
+
+ // Lese Area-Table
+ foreach (LevelArea a in lvl.Areas)
+ {
+ // Fast3D-Daten
+ brToUse.BaseStream.Position = bank0x19RomStart + 0x5F00 + a.AreaID * 0x10;
+ a.Bank0x0EOffset = Convert.ToUInt32(SwapInts.SwapInt32(brToUse.ReadInt32()));
+ int romEnd0xE = SwapInts.SwapInt32(brToUse.ReadInt32());
+ rommgr.SetSegBank(0xE, Convert.ToInt32(a.Bank0x0EOffset), romEnd0xE, a.AreaID);
+
+ // 2D-Kamera
+ brToUse.BaseStream.Position = bank0x19RomStart + 0x5F0F + a.AreaID * 0x10;
+ a.Enable2DCamera = Bits.GetBoolOfByte(brToUse.ReadByte(), 7);
+ }
+
+ // Lese Area-Modelle
+ foreach (LevelArea a in lvl.Areas)
+ {
+ a.AreaModel.FromStream(fs, Convert.ToInt32(a.Bank0x0EOffset), 0xE000000, a.Fast3DBankRomStart, a.Fast3DLength, a.Geolayout.Geopointers.ToArray(), a.CollisionPointer, rommgr.RomConfig.CollisionBaseConfig);
+ }
+
+ // Lese alle Box-Daten
+ int CurrentBoxOffset = bank0x19RomStart + 0x6A00;
+ foreach (LevelArea a in lvl.Areas.Where(n => n.AreaID < 8))
+ {
+ // Clear special boxes
+ a.SpecialBoxes.Clear();
+
+ // Load special boxes
+ a.SpecialBoxes.AddRange(SpecialBoxList.ReadTable(brToUse.BaseStream, SpecialBoxType.Water, bank0x19RomStart, bank0x19RomStart + 0x6000 + 0x50 * a.AreaID));
+ a.SpecialBoxes.AddRange(SpecialBoxList.ReadTable(brToUse.BaseStream, SpecialBoxType.ToxicHaze, bank0x19RomStart, bank0x19RomStart + 0x6280 + 0x50 * a.AreaID));
+ a.SpecialBoxes.AddRange(SpecialBoxList.ReadTable(brToUse.BaseStream, SpecialBoxType.Mist, bank0x19RomStart, bank0x19RomStart + 0x6500 + 0x50 * a.AreaID));
+
+ for (int i = 0; i < a.SpecialBoxes.Count; i++)
+ {
+ var boxdata = a.AreaModel.Collision.SpecialBoxes.ElementAtOrDefault(i);
+ if (boxdata is not null)
+ {
+ a.SpecialBoxes[i].Y = boxdata.Y;
+ }
+ }
+ }
+
+ // One-Bank-0xE-System
+ lvl.OneBank0xESystemEnabled = true;
+
+ // Act Selector
+ General.PatchClass.Open(fs);
+ lvl.ActSelector = General.PatchClass.get_ActSelector_Enabled(LevelID);
+
+ // Hardcoded Camera
+ lvl.HardcodedCameraSettings = General.PatchClass.get_HardcodedCamera_Enabled(LevelID);
+
+ // Area Reverb
+ if (EnableLoadingAreaReverb)
+ {
+ foreach (var area in lvl.Areas)
+ {
+ if (area is RMLevelArea && area.AreaID >= 1 && area.AreaID <= 3)
+ {
+ fs.Position = 0xEE0C0 + lvl.LevelID * 3 + area.AreaID - 1;
+ ((RMLevelArea)area).ReverbLevel = (AreaReverbLevel)fs.ReadByte();
+ }
+ }
+ }
+
+ fs.Close();
+ }
+
+ ///
+ /// Saves a ROM Manager Level to ROM.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public virtual LevelSaveResult SaveLevel(Level lvl, RomManager rommgr, BinaryData output, ref uint curOff)
+ {
+ var saveres = new LevelSaveResult();
+ BinaryData data0x19;
+ var lid = rommgr.LevelInfoData.GetByLevelID(lvl.LevelID);
+
+ // Write Area Model & Update Scrolling Texture Vertex Pointers & Write Custom Object Bank
+ foreach (LevelArea a in lvl.Areas)
+ {
+ var CollisionBoxTableIndex = new[] { 0, 0x32, 0x33 };
+ a.Bank0x0EOffset = curOff;
+
+ if (SortSpecialBoxesByHeight)
+ a.SpecialBoxes.SortByHeight();
+
+ int oldModelStart = a.AreaModel.Fast3DBuffer.Fast3DBankStart;
+ int newModelStart;
+ int modelOffset;
+
+ // Add the new water boxes
+ a.AreaModel.Collision.SpecialBoxes.Clear();
+ foreach (SpecialBox sp in a.SpecialBoxes)
+ {
+ var boxdata = new Model.Collision.BoxData
+ {
+ X1 = sp.X1,
+ X2 = sp.X2,
+ Z1 = sp.Z1,
+ Z2 = sp.Z2,
+ Y = sp.Y,
+ Index = (short)CollisionBoxTableIndex[(int)sp.Type]
+ };
+
+ switch (sp.Type)
+ {
+ case SpecialBoxType.Water:
+ boxdata.Type = Model.Collision.BoxDataType.Water;
+ CollisionBoxTableIndex[(int)sp.Type] += 1;
break;
- case LevelscriptCommandTypes.LoadRomToRam:
- byte bankID = clLoadRomToRam.GetSegmentedID(c);
- int startAddr = clLoadRomToRam.GetRomStart(c);
- int endAddr = clLoadRomToRam.GetRomEnd(c);
- switch (bankID)
+ case SpecialBoxType.Mist:
+ boxdata.Type = Model.Collision.BoxDataType.Mist;
+ CollisionBoxTableIndex[(int)sp.Type] += 1;
+ break;
+ case SpecialBoxType.ToxicHaze:
+ boxdata.Type = Model.Collision.BoxDataType.ToxicHaze;
+ CollisionBoxTableIndex[(int)sp.Type] += 10;
+ break;
+ }
+
+ a.AreaModel.Collision.SpecialBoxes.Add(boxdata);
+ }
+
+ // Write Area Model
+ ObjectModel.SaveResult res;
+ res = a.AreaModel.ToBinaryData(output, (int)curOff, (int)curOff, 0xE000000, rommgr.RomConfig.CollisionBaseConfig);
+
+ // Calculate Model Offset & Update Scrolling Texture Vertex Pointers
+ newModelStart = a.AreaModel.Fast3DBuffer.Fast3DBankStart;
+ modelOffset = newModelStart - oldModelStart;
+ if (modelOffset != 0)
+ {
+ a.UpdateScrollingTextureVertexPointer(modelOffset);
+ }
+
+ a.CollisionPointer = res.CollisionPointer;
+ a.Geolayout.Geopointers.Clear();
+ a.Geolayout.Geopointers.AddRange(res.GeoPointers.ToArray());
+ curOff += (uint)(res.Length + 0x20);
+ General.HexRoundUp2(ref curOff);
+
+ a.Bank0xELength = (int)(curOff - a.Bank0x0EOffset);
+ }
+
+ // Write Background Image
+ output.RoundUpPosition();
+ int customBGStart = Convert.ToInt32(curOff);
+ int customBGEnd = 0;
+ if (lvl.Background.IsCustom) // .ID = Geolayout.BackgroundIDs.Custom Then
+ {
+ // Write Custom Background
+ lvl.Background.WriteImage(output.BaseStream, customBGStart);
+
+ // Write Pointer Table
+ var bgPtrTable = LevelBG.GetBackgroundPointerTable();
+ output.Write(bgPtrTable, 0, bgPtrTable.Length);
+ customBGEnd = customBGStart + lvl.Background.ImageLength + bgPtrTable.Length;
+ curOff += (uint)lvl.Background.ImageLength + (uint)bgPtrTable.Length;
+ General.HexRoundUp2(ref curOff);
+ }
+
+ // Generate & Write Local Object Bank
+ uint localObjectBankRomStart = 0;
+ uint localObjectBankRomEnd = 0;
+ bool writeLocalObjectBank = lvl.LocalObjectBank.Models.Count > 0 && lvl.EnableLocalObjectBank;
+ if (writeLocalObjectBank)
+ {
+ localObjectBankRomStart = curOff;
+ curOff += (uint)lvl.LocalObjectBank.WriteToSeg(output, (int)curOff, 0x9, rommgr.RomConfig.CollisionBaseConfig);
+ localObjectBankRomEnd = curOff;
+ ((RMLevel)lvl).Config.LocalObjectBank = lvl.LocalObjectBank.Config;
+ lvl.LocalObjectBank.WriteCollisionPointers(output);
+ }
+ ((RMLevel)lvl).Config.EnableLocalObjectBank = writeLocalObjectBank;
+
+ // Get Bank 0x19
+ if (lvl.Bank0x19 is null)
+ {
+ lvl.Bank0x19 = rommgr.SetSegBank(0x19, Convert.ToInt32(curOff), (int)RomManagerSettings.DefaultLevelscriptSize);
+ lvl.Bank0x19.Data = new MemoryStream();
+ lvl.Bank0x19.Length = (int)RomManagerSettings.DefaultLevelscriptSize;
+ }
+ else
+ {
+ var oldData = lvl.Bank0x19.Data;
+ lvl.Bank0x19 = rommgr.SetSegBank(0x19, Convert.ToInt32(curOff), (int)(curOff + lvl.Bank0x19.Length));
+ lvl.Bank0x19.Data = oldData;
+ }
+
+ data0x19 = new BinaryStreamData(lvl.Bank0x19.Data);
+ saveres.Bank0x19 = lvl.Bank0x19;
+ curOff += (uint)lvl.Bank0x19.Data.Length;
+ General.HexRoundUp2(ref curOff);
+
+ // Update Geolayouts
+ foreach (LevelArea a in lvl.Areas)
+ {
+ // Update Backcolor Command
+ var cmd = a.Geolayout.Geolayoutscript.GetFirst(GeolayoutCommandTypes.Background);
+ if (a.Background.Type == AreaBGs.Levelbackground && lvl.Background.Enabled)
+ {
+ cgBackground.SetBackgroundPointer(cmd, unchecked((int)0x802763D4));
+ cgBackground.SetBackgroundID(cmd, (short)lvl.Background.ID);
+ }
+ else
+ {
+ cgBackground.SetBackgroundPointer(cmd, 0);
+ cgBackground.SetRgbaColor(cmd, a.Background.Color);
+ }
+ }
+
+ // Write Geolayouts
+ int geoOffset = 0x5F00;
+ foreach (LevelArea a in lvl.Areas)
+ {
+ geoOffset -= General.HexRoundUp1(a.Geolayout.Length) + 0x50;
+ a.GeolayoutOffset = (uint)(lvl.Bank0x19.BankAddress + geoOffset);
+ a.Geolayout.Write(lvl.Bank0x19.Data, geoOffset);
+ a.Geolayout.NewGeoOffset = lvl.Bank0x19.RomStart + geoOffset;
+ }
+
+ // Füge Show-Dialog-Command & 2D-Camera-Object ein
+ foreach (LevelArea a in lvl.Areas)
+ {
+ // Show-Dialog-Command
+ if (a.ShowMessage.Enabled)
+ {
+ var cmdShowMsg = new LevelscriptCommand($"30 04 00 {a.ShowMessage.DialogID.ToString("X2")}");
+ int indexOf1E = a.Levelscript.IndexOfFirst(LevelscriptCommandTypes.EndOfArea);
+ a.Levelscript.Insert(indexOf1E, cmdShowMsg);
+ }
+
+ // 2D-Camera-Object
+ if (rommgr.RomConfig.PatchingConfig.Patched2DCamera)
+ {
+ var cmds2d = new List();
+ foreach (LevelscriptCommand obj in a.Objects)
+ {
+ if (obj.CommandType == LevelscriptCommandTypes.Normal3DObject)
+ {
+ if (clNormal3DObject.GetSegBehaviorAddr(obj) == (long)0x130053C4) // Behav-ID: '0x130053C4
{
- case 0xA: // Background-Image
- customBGStart = startAddr;
- customBGEnd = endAddr - 0x140;
+ cmds2d.Add(obj);
+ }
+ }
+ }
+
+ if (a.Enable2DCamera)
+ {
+ if (cmds2d.Count == 0)
+ {
+ var cmd = new LevelscriptCommand("24 18 1F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 13 00 53 C4");
+ a.Objects.Add(cmd);
+ }
+ }
+ else if (cmds2d.Count > 0)
+ {
+ foreach (LevelscriptCommand cmd in cmds2d)
+ a.Objects.Remove(cmd);
+ }
+ }
+ }
+
+ Levelscript lvlScript0E = null;
+ Dictionary areaobjwarpoffsetdic = null;
+ SegmentedBank firstBank0xE = null;
+ uint curFirstBank0xEOffset = 0;
+
+ // Add Objects and Warps to new Levelscript
+ lvlScript0E = new Levelscript();
+ firstBank0xE = rommgr.SetSegBank(0xE, Convert.ToInt32(curOff), 0);
+ areaobjwarpoffsetdic = new Dictionary();
+ foreach (LevelArea a in lvl.Areas)
+ {
+ areaobjwarpoffsetdic.Add(a.AreaID, (uint)(firstBank0xE.BankAddress + curFirstBank0xEOffset));
+ foreach (LevelscriptCommand c in a.Objects)
+ {
+ lvlScript0E.Add(c);
+ curFirstBank0xEOffset += (uint)c.Length;
+ }
+
+ foreach (ManagedScrollingTexture c in a.ScrollingTextures)
+ {
+ c.SaveProperties(rommgr.RomConfig.ScrollTexConfig);
+ lvlScript0E.Add(c.Command);
+ curFirstBank0xEOffset += (uint)c.Command.Length;
+ }
+
+ foreach (LevelscriptCommand c in a.Warps)
+ {
+ lvlScript0E.Add(c);
+ curFirstBank0xEOffset += (uint)c.Length;
+ }
+
+ foreach (LevelscriptCommand c in a.WarpsForGame)
+ {
+ lvlScript0E.Add(c);
+ curFirstBank0xEOffset += (uint)c.Length;
+ }
+
+ lvlScript0E.Add(new LevelscriptCommand("07 04 00 00"));
+ curFirstBank0xEOffset += 4;
+ }
+
+ firstBank0xE.Length = (int)General.HexRoundUp1(curFirstBank0xEOffset);
+ lvlScript0E.Write(output, firstBank0xE.RomStart);
+ curOff += (uint)firstBank0xE.Length;
+
+ // Füge Area dem Levelscript hinzu
+ int cIndex2 = lvl.Levelscript.IndexOfFirst(LevelscriptCommandTypes.x1E);
+ foreach (var a in lvl.Areas)
+ {
+ foreach (var c in a.Levelscript)
+ {
+ lvl.Levelscript.Insert(cIndex2, c);
+ cIndex2 += 1;
+ }
+ }
+
+ // Übernehme Level- und Areaeinstellungen
+ int CurrentAreaIndex = 0;
+ var areaobjwarpindextoinsertdic = new Dictionary();
+ var areaidindex = new Dictionary();
+ LevelArea tArea = null;
+ bool foundCmdShowMsg = false;
+ LevelscriptCommand cmdBgSegLoad = null;
+ LevelscriptCommand cmdGobSegLoad = null;
+ LevelscriptCommand cmdGobJump = null;
+ LevelscriptCommand cmdLobSegLoad = null;
+ LevelscriptCommand cmdLobJump = null;
+ var cmdsToInsertAt = new Dictionary();
+ var cmdsToRemove = new List();
+ foreach (var c in lvl.Levelscript)
+ {
+ var switchExpr1 = c.CommandType;
+ switch (switchExpr1)
+ {
+ case LevelscriptCommandTypes.StartArea:
+ {
+ tArea = lvl.Areas[CurrentAreaIndex];
+ byte areaid = tArea.AreaID;
+ areaidindex.Add(areaid, Convert.ToByte(areaidindex.Count));
+ clStartArea.SetSegGeolayoutAddr(c, (uint)(lvl.Areas[CurrentAreaIndex].Geolayout.NewGeoOffset - lvl.Bank0x19.RomStart + lvl.Bank0x19.BankAddress));
+ clStartArea.SetAreaID(c, areaid);
+ areaobjwarpindextoinsertdic.Add(areaid, lvl.Levelscript.IndexOf(c) + 1);
+ break;
+ }
+
+ case LevelscriptCommandTypes.EndOfArea:
+ {
+ if (!foundCmdShowMsg && tArea.ShowMessage.Enabled)
+ {
+ var cmdShowMsg = new LevelscriptCommand($"30 04 00 {tArea.ShowMessage.DialogID.ToString("X2")}");
+ cmdsToInsertAt.Add((LevelscriptCommand)c, cmdShowMsg);
+ }
+
+ foundCmdShowMsg = false;
+ CurrentAreaIndex += 1;
+ tArea = null;
+ break;
+ }
+
+ case LevelscriptCommandTypes.AreaMusic:
+ {
+ clAreaMusic.SetMusicID((LevelscriptCommand)c, lvl.Areas[CurrentAreaIndex].BGMusic);
+ break;
+ }
+
+ case LevelscriptCommandTypes.AreaMusicSimple:
+ {
+ clAreaMusicSimple.SetMusicID((LevelscriptCommand)c, lvl.Areas[CurrentAreaIndex].BGMusic);
+ break;
+ }
+
+ case LevelscriptCommandTypes.Tarrain:
+ {
+ clTerrian.SetTerrainType((LevelscriptCommand)c, (byte)lvl.Areas[CurrentAreaIndex].TerrainType);
+ break;
+ }
+
+ case LevelscriptCommandTypes.LoadRomToRam:
+ {
+ var switchExpr2 = clLoadRomToRam.GetSegmentedID((LevelscriptCommand)c);
+ switch (switchExpr2)
+ {
+ case 0xE: // Bank 0xE
+ clLoadRomToRam.SetRomStart((LevelscriptCommand)c, firstBank0xE.RomStart);
+ clLoadRomToRam.SetRomEnd((LevelscriptCommand)c, firstBank0xE.RomEnd);
break;
- case 0x7: // Global Object Bank
- if (rommgr.GlobalModelBank?.CurSeg is not null && startAddr == rommgr.GlobalModelBank.CurSeg.RomStart && endAddr == rommgr.GlobalModelBank.CurSeg.RomEnd)
+ case 0xA:
+ cmdBgSegLoad = (LevelscriptCommand)c;
+ break;
+ case 0x7:
+ if (lvl.LastGobCmdSegLoad == c)
{
- lvl.EnableGlobalObjectBank = true;
- lvl.LastGobCmdSegLoad = c;
+ cmdGobSegLoad = (LevelscriptCommand)c;
}
break;
case 0x9:
- if (((RMLevel)lvl).Config.EnableLocalObjectBank)
+ if (lvl.LastLobCmdSegLoad == c)
{
- lvl.EnableLocalObjectBank = true;
+ cmdLobSegLoad = (LevelscriptCommand)c;
}
- lvl.LastLobCmdSegLoad = c;
+ break;
+ }
+
+ break;
+ }
+
+ case LevelscriptCommandTypes.ShowDialog:
+ {
+ if ((bool)tArea?.ShowMessage.Enabled && !foundCmdShowMsg)
+ {
+ clShowDialog.SetDialogID((LevelscriptCommand)c, tArea.ShowMessage.DialogID);
+ foundCmdShowMsg = true;
+ }
+ else
+ {
+ cmdsToRemove.Add((LevelscriptCommand)c);
+ }
+
+ break;
+ }
+
+ case LevelscriptCommandTypes.JumpToSegAddr:
+ {
+ int bankID = clJumpToSegAddr.GetSegJumpAddr((LevelscriptCommand)c) >> 24;
+ switch (bankID)
+ {
+ case 0x7:
+ cmdGobJump = (LevelscriptCommand)c;
+ break;
+ case 0x9:
+ cmdLobJump = (LevelscriptCommand)c;
break;
}
break;
- case LevelscriptCommandTypes.ShowDialog:
- if (AreaOnFly)
- {
- tArea.ShowMessage.Enabled = true;
- tArea.ShowMessage.DialogID = clShowDialog.GetDialogID(c);
- }
- break;
- case LevelscriptCommandTypes.JumpBack:
- case LevelscriptCommandTypes.JumpToSegAddr:
- if (tArea is not null)
- cmdsToRemove.Add(c);
- break;
- }
-
- if (AreaOnFly && !cmdsToRemove.Contains(c))
- {
- lvl.Levelscript.Remove(c);
- tArea.Levelscript.Add(c);
- }
- }
-
- // Lösche alle Jump-Commands aus dem Levelscript
- foreach (LevelscriptCommand cmd in cmdsToRemove)
- {
- lvl.Levelscript.Remove(cmd);
- cmd.Close();
- }
-
- // Lösche alle Objekte und Warps aus dem Levelscript
- var lvlscrptidstoremove = new[] { LevelscriptCommandTypes.Normal3DObject, LevelscriptCommandTypes.ConnectedWarp, LevelscriptCommandTypes.PaintingWarp, LevelscriptCommandTypes.InstantWarp };
- foreach (var a in lvl.Areas)
- {
- foreach (var c in a.Levelscript.Where(n => lvlscrptidstoremove.Contains(n.CommandType)).ToArray())
- a.Levelscript.Remove(c);
- }
-
- // Load Local Object Bank
- if (lvl.LastLobCmdSegLoad is not null)
- {
- var seg = new SegmentedBank()
- {
- BankID = clLoadRomToRam.GetSegmentedID(lvl.LastLobCmdSegLoad),
- RomStart = clLoadRomToRam.GetRomStart(lvl.LastLobCmdSegLoad),
- RomEnd = clLoadRomToRam.GetRomEnd(lvl.LastLobCmdSegLoad)
- };
- lvl.LocalObjectBank.ReadFromSeg(rommgr, seg, ((RMLevel)lvl).Config.LocalObjectBank);
- }
-
- // Lese Custom Background Image
- var fs = new FileStream(rommgr.RomFile, FileMode.Open, FileAccess.Read);
- var br2 = new BinaryReader(fs);
- lvl.Background.Enabled = false;
- foreach (LevelArea a in lvl.Areas)
- {
- var bgglcmd = a.Geolayout.Geolayoutscript.GetFirst(GeolayoutCommandTypes.Background);
- if (cgBackground.GetBackgroundPointer(bgglcmd) == 0)
- {
- a.Background.Type = AreaBGs.Color;
- a.Background.Color = cgBackground.GetRrgbaColor(bgglcmd);
- }
- else
- {
- a.Background.Type = AreaBGs.Levelbackground;
- lvl.Background.ID = (Geolayout.BackgroundIDs)cgBackground.GetBackgroundID(bgglcmd);
- lvl.Background.Enabled = true;
- }
- }
-
- if (customBGStart != 0)
- {
- lvl.Background.IsCustom = true;
- }
-
- foreach (int val in Enum.GetValues(typeof(Geolayout.BackgroundPointers)))
- {
- if (val != 0 && customBGStart == val)
- {
- lvl.Background.IsCustom = false;
- }
- }
-
- if (lvl.Background.Enabled && lvl.Background.IsCustom) // .ID = Geolayout.BackgroundIDs.Custom Then
- {
- fs.Position = customBGStart;
- lvl.Background.ReadImage(fs, customBGStart);
- }
-
- int bank0x19RomStart;
- int bank0x19RomEnd;
- BinaryReader brToUse;
- bank0x19RomStart = 0;
- bank0x19RomEnd = lvl.Bank0x19.Length;
- brToUse = new BinaryReader(lvl.Bank0x19.Data);
-
- // Lese Area-Table
- foreach (LevelArea a in lvl.Areas)
- {
- // Fast3D-Daten
- brToUse.BaseStream.Position = bank0x19RomStart + 0x5F00 + a.AreaID * 0x10;
- a.Bank0x0EOffset = Convert.ToUInt32(SwapInts.SwapInt32(brToUse.ReadInt32()));
- int romEnd0xE = SwapInts.SwapInt32(brToUse.ReadInt32());
- rommgr.SetSegBank(0xE, Convert.ToInt32(a.Bank0x0EOffset), romEnd0xE, a.AreaID);
-
- // 2D-Kamera
- brToUse.BaseStream.Position = bank0x19RomStart + 0x5F0F + a.AreaID * 0x10;
- a.Enable2DCamera = Bits.GetBoolOfByte(brToUse.ReadByte(), 7);
- }
-
- // Lese Area-Modelle
- foreach (LevelArea a in lvl.Areas)
- {
- a.AreaModel.FromStream(fs, Convert.ToInt32(a.Bank0x0EOffset), 0xE000000, a.Fast3DBankRomStart, a.Fast3DLength, a.Geolayout.Geopointers.ToArray(), a.CollisionPointer, rommgr.RomConfig.CollisionBaseConfig);
- }
-
- // Lese alle Box-Daten
- int CurrentBoxOffset = bank0x19RomStart + 0x6A00;
- foreach (LevelArea a in lvl.Areas.Where(n => n.AreaID < 8))
- {
- // Clear special boxes
- a.SpecialBoxes.Clear();
-
- // Load special boxes
- a.SpecialBoxes.AddRange(SpecialBoxList.ReadTable(brToUse.BaseStream, SpecialBoxType.Water, bank0x19RomStart, bank0x19RomStart + 0x6000 + 0x50 * a.AreaID));
- a.SpecialBoxes.AddRange(SpecialBoxList.ReadTable(brToUse.BaseStream, SpecialBoxType.ToxicHaze, bank0x19RomStart, bank0x19RomStart + 0x6280 + 0x50 * a.AreaID));
- a.SpecialBoxes.AddRange(SpecialBoxList.ReadTable(brToUse.BaseStream, SpecialBoxType.Mist, bank0x19RomStart, bank0x19RomStart + 0x6500 + 0x50 * a.AreaID));
-
- for (int i = 0; i < a.SpecialBoxes.Count; i++)
- {
- var boxdata = a.AreaModel.Collision.SpecialBoxes.ElementAtOrDefault(i);
- if (boxdata is not null)
- {
- a.SpecialBoxes[i].Y = boxdata.Y;
}
- }
}
-
- // One-Bank-0xE-System
- lvl.OneBank0xESystemEnabled = true;
-
- // Act Selector
- General.PatchClass.Open(fs);
- lvl.ActSelector = General.PatchClass.get_ActSelector_Enabled(LevelID);
-
- // Hardcoded Camera
- lvl.HardcodedCameraSettings = General.PatchClass.get_HardcodedCamera_Enabled(LevelID);
-
- // Area Reverb
- if (EnableLoadingAreaReverb)
- {
- foreach (var area in lvl.Areas)
- {
- if (area is RMLevelArea && area.AreaID >= 1 && area.AreaID <= 3)
- {
- fs.Position = 0xEE0C0 + lvl.LevelID * 3 + area.AreaID - 1;
- ((RMLevelArea)area).ReverbLevel = (AreaReverbLevel)fs.ReadByte();
- }
- }
- }
-
- fs.Close();
}
- ///
- /// Saves a ROM Manager Level to ROM.
- ///
- ///
- ///
- ///
- ///
- ///
- public virtual LevelSaveResult SaveLevel(Level lvl, RomManager rommgr, BinaryData output, ref uint curOff)
+ // Füge Jump Commands zur ersten 0xE-Bank hinzu
+ foreach (var e in areaobjwarpindextoinsertdic.OrderByDescending(n => n.Value))
{
- var saveres = new LevelSaveResult();
- BinaryData data0x19;
- var lid = rommgr.LevelInfoData.GetByLevelID(lvl.LevelID);
-
- // Write Area Model & Update Scrolling Texture Vertex Pointers & Write Custom Object Bank
- foreach (LevelArea a in lvl.Areas)
- {
- var CollisionBoxTableIndex = new[] { 0, 0x32, 0x33 };
- a.Bank0x0EOffset = curOff;
-
- if (SortSpecialBoxesByHeight)
- a.SpecialBoxes.SortByHeight();
-
- int oldModelStart = a.AreaModel.Fast3DBuffer.Fast3DBankStart;
- int newModelStart;
- int modelOffset;
-
- // Add the new water boxes
- a.AreaModel.Collision.SpecialBoxes.Clear();
- foreach (SpecialBox sp in a.SpecialBoxes)
- {
- var boxdata = new Model.Collision.BoxData
- {
- X1 = sp.X1,
- X2 = sp.X2,
- Z1 = sp.Z1,
- Z2 = sp.Z2,
- Y = sp.Y,
- Index = (short)CollisionBoxTableIndex[(int)sp.Type]
- };
-
- switch (sp.Type)
- {
- case SpecialBoxType.Water:
- boxdata.Type = Model.Collision.BoxDataType.Water;
- CollisionBoxTableIndex[(int)sp.Type] += 1;
- break;
- case SpecialBoxType.Mist:
- boxdata.Type = Model.Collision.BoxDataType.Mist;
- CollisionBoxTableIndex[(int)sp.Type] += 1;
- break;
- case SpecialBoxType.ToxicHaze:
- boxdata.Type = Model.Collision.BoxDataType.ToxicHaze;
- CollisionBoxTableIndex[(int)sp.Type] += 10;
- break;
- }
-
- a.AreaModel.Collision.SpecialBoxes.Add(boxdata);
- }
-
- // Write Area Model
- ObjectModel.SaveResult res;
- res = a.AreaModel.ToBinaryData(output, (int)curOff, (int)curOff, 0xE000000, rommgr.RomConfig.CollisionBaseConfig);
-
- // Calculate Model Offset & Update Scrolling Texture Vertex Pointers
- newModelStart = a.AreaModel.Fast3DBuffer.Fast3DBankStart;
- modelOffset = newModelStart - oldModelStart;
- if (modelOffset != 0)
- {
- a.UpdateScrollingTextureVertexPointer(modelOffset);
- }
-
- a.CollisionPointer = res.CollisionPointer;
- a.Geolayout.Geopointers.Clear();
- a.Geolayout.Geopointers.AddRange(res.GeoPointers.ToArray());
- curOff += (uint)(res.Length + 0x20);
- General.HexRoundUp2(ref curOff);
-
- a.Bank0xELength = (int)(curOff - a.Bank0x0EOffset);
- }
-
- // Write Background Image
- output.RoundUpPosition();
- int customBGStart = Convert.ToInt32(curOff);
- int customBGEnd = 0;
- if (lvl.Background.IsCustom) // .ID = Geolayout.BackgroundIDs.Custom Then
- {
- // Write Custom Background
- lvl.Background.WriteImage(output.BaseStream, customBGStart);
-
- // Write Pointer Table
- var bgPtrTable = LevelBG.GetBackgroundPointerTable();
- output.Write(bgPtrTable, 0, bgPtrTable.Length);
- customBGEnd = customBGStart + lvl.Background.ImageLength + bgPtrTable.Length;
- curOff += (uint)lvl.Background.ImageLength + (uint)bgPtrTable.Length;
- General.HexRoundUp2(ref curOff);
- }
-
- // Generate & Write Local Object Bank
- uint localObjectBankRomStart = 0;
- uint localObjectBankRomEnd = 0;
- bool writeLocalObjectBank = lvl.LocalObjectBank.Models.Count > 0 && lvl.EnableLocalObjectBank;
- if (writeLocalObjectBank)
- {
- localObjectBankRomStart = curOff;
- curOff += (uint)lvl.LocalObjectBank.WriteToSeg(output, (int)curOff, 0x9, rommgr.RomConfig.CollisionBaseConfig);
- localObjectBankRomEnd = curOff;
- ((RMLevel)lvl).Config.LocalObjectBank = lvl.LocalObjectBank.Config;
- lvl.LocalObjectBank.WriteCollisionPointers(output);
- }
- ((RMLevel)lvl).Config.EnableLocalObjectBank = writeLocalObjectBank;
-
- // Get Bank 0x19
- if (lvl.Bank0x19 is null)
- {
- lvl.Bank0x19 = rommgr.SetSegBank(0x19, Convert.ToInt32(curOff), (int)RomManagerSettings.DefaultLevelscriptSize);
- lvl.Bank0x19.Data = new MemoryStream();
- lvl.Bank0x19.Length = (int)RomManagerSettings.DefaultLevelscriptSize;
- }
- else
- {
- var oldData = lvl.Bank0x19.Data;
- lvl.Bank0x19 = rommgr.SetSegBank(0x19, Convert.ToInt32(curOff), (int)(curOff + lvl.Bank0x19.Length));
- lvl.Bank0x19.Data = oldData;
- }
-
- data0x19 = new BinaryStreamData(lvl.Bank0x19.Data);
- saveres.Bank0x19 = lvl.Bank0x19;
- curOff += (uint)lvl.Bank0x19.Data.Length;
- General.HexRoundUp2(ref curOff);
-
- // Update Geolayouts
- foreach (LevelArea a in lvl.Areas)
- {
- // Update Backcolor Command
- var cmd = a.Geolayout.Geolayoutscript.GetFirst(GeolayoutCommandTypes.Background);
- if (a.Background.Type == AreaBGs.Levelbackground && lvl.Background.Enabled)
- {
- cgBackground.SetBackgroundPointer(cmd, unchecked((int)0x802763D4));
- cgBackground.SetBackgroundID(cmd, (short)lvl.Background.ID);
- }
- else
- {
- cgBackground.SetBackgroundPointer(cmd, 0);
- cgBackground.SetRgbaColor(cmd, a.Background.Color);
- }
- }
-
- // Write Geolayouts
- int geoOffset = 0x5F00;
- foreach (LevelArea a in lvl.Areas)
- {
- geoOffset -= General.HexRoundUp1(a.Geolayout.Length) + 0x50;
- a.GeolayoutOffset = (uint)(lvl.Bank0x19.BankAddress + geoOffset);
- a.Geolayout.Write(lvl.Bank0x19.Data, geoOffset);
- a.Geolayout.NewGeoOffset = lvl.Bank0x19.RomStart + geoOffset;
- }
-
- // Füge Show-Dialog-Command & 2D-Camera-Object ein
- foreach (LevelArea a in lvl.Areas)
- {
- // Show-Dialog-Command
- if (a.ShowMessage.Enabled)
- {
- var cmdShowMsg = new LevelscriptCommand($"30 04 00 {a.ShowMessage.DialogID.ToString("X2")}");
- int indexOf1E = a.Levelscript.IndexOfFirst(LevelscriptCommandTypes.EndOfArea);
- a.Levelscript.Insert(indexOf1E, cmdShowMsg);
- }
-
- // 2D-Camera-Object
- if (rommgr.RomConfig.PatchingConfig.Patched2DCamera)
- {
- var cmds2d = new List();
- foreach (LevelscriptCommand obj in a.Objects)
- {
- if (obj.CommandType == LevelscriptCommandTypes.Normal3DObject)
- {
- if (clNormal3DObject.GetSegBehaviorAddr(obj) == (long)0x130053C4) // Behav-ID: '0x130053C4
- {
- cmds2d.Add(obj);
- }
- }
- }
-
- if (a.Enable2DCamera)
- {
- if (cmds2d.Count == 0)
- {
- var cmd = new LevelscriptCommand("24 18 1F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 13 00 53 C4");
- a.Objects.Add(cmd);
- }
- }
- else if (cmds2d.Count > 0)
- {
- foreach (LevelscriptCommand cmd in cmds2d)
- a.Objects.Remove(cmd);
- }
- }
- }
-
- Levelscript lvlScript0E = null;
- Dictionary areaobjwarpoffsetdic = null;
- SegmentedBank firstBank0xE = null;
- uint curFirstBank0xEOffset = 0;
-
- // Add Objects and Warps to new Levelscript
- lvlScript0E = new Levelscript();
- firstBank0xE = rommgr.SetSegBank(0xE, Convert.ToInt32(curOff), 0);
- areaobjwarpoffsetdic = new Dictionary();
- foreach (LevelArea a in lvl.Areas)
- {
- areaobjwarpoffsetdic.Add(a.AreaID, (uint)(firstBank0xE.BankAddress + curFirstBank0xEOffset));
- foreach (LevelscriptCommand c in a.Objects)
- {
- lvlScript0E.Add(c);
- curFirstBank0xEOffset += (uint)c.Length;
- }
-
- foreach (ManagedScrollingTexture c in a.ScrollingTextures)
- {
- c.SaveProperties(rommgr.RomConfig.ScrollTexConfig);
- lvlScript0E.Add(c.Command);
- curFirstBank0xEOffset += (uint)c.Command.Length;
- }
-
- foreach (LevelscriptCommand c in a.Warps)
- {
- lvlScript0E.Add(c);
- curFirstBank0xEOffset += (uint)c.Length;
- }
-
- foreach (LevelscriptCommand c in a.WarpsForGame)
- {
- lvlScript0E.Add(c);
- curFirstBank0xEOffset += (uint)c.Length;
- }
-
- lvlScript0E.Add(new LevelscriptCommand("07 04 00 00"));
- curFirstBank0xEOffset += 4;
- }
-
- firstBank0xE.Length = (int)General.HexRoundUp1(curFirstBank0xEOffset);
- lvlScript0E.Write(output, firstBank0xE.RomStart);
- curOff += (uint)firstBank0xE.Length;
-
- // Füge Area dem Levelscript hinzu
- int cIndex2 = lvl.Levelscript.IndexOfFirst(LevelscriptCommandTypes.x1E);
- foreach (var a in lvl.Areas)
- {
- foreach (var c in a.Levelscript)
- {
- lvl.Levelscript.Insert(cIndex2, c);
- cIndex2 += 1;
- }
- }
-
- // Übernehme Level- und Areaeinstellungen
- int CurrentAreaIndex = 0;
- var areaobjwarpindextoinsertdic = new Dictionary();
- var areaidindex = new Dictionary();
- LevelArea tArea = null;
- bool foundCmdShowMsg = false;
- LevelscriptCommand cmdBgSegLoad = null;
- LevelscriptCommand cmdGobSegLoad = null;
- LevelscriptCommand cmdGobJump = null;
- LevelscriptCommand cmdLobSegLoad = null;
- LevelscriptCommand cmdLobJump = null;
- var cmdsToInsertAt = new Dictionary();
- var cmdsToRemove = new List();
- foreach (var c in lvl.Levelscript)
- {
- var switchExpr1 = c.CommandType;
- switch (switchExpr1)
- {
- case LevelscriptCommandTypes.StartArea:
- {
- tArea = lvl.Areas[CurrentAreaIndex];
- byte areaid = tArea.AreaID;
- areaidindex.Add(areaid, Convert.ToByte(areaidindex.Count));
- clStartArea.SetSegGeolayoutAddr(c, (uint)(lvl.Areas[CurrentAreaIndex].Geolayout.NewGeoOffset - lvl.Bank0x19.RomStart + lvl.Bank0x19.BankAddress));
- clStartArea.SetAreaID(c, areaid);
- areaobjwarpindextoinsertdic.Add(areaid, lvl.Levelscript.IndexOf(c) + 1);
- break;
- }
-
- case LevelscriptCommandTypes.EndOfArea:
- {
- if (!foundCmdShowMsg && tArea.ShowMessage.Enabled)
- {
- var cmdShowMsg = new LevelscriptCommand($"30 04 00 {tArea.ShowMessage.DialogID.ToString("X2")}");
- cmdsToInsertAt.Add((LevelscriptCommand)c, cmdShowMsg);
- }
-
- foundCmdShowMsg = false;
- CurrentAreaIndex += 1;
- tArea = null;
- break;
- }
-
- case LevelscriptCommandTypes.AreaMusic:
- {
- clAreaMusic.SetMusicID((LevelscriptCommand)c, lvl.Areas[CurrentAreaIndex].BGMusic);
- break;
- }
-
- case LevelscriptCommandTypes.AreaMusicSimple:
- {
- clAreaMusicSimple.SetMusicID((LevelscriptCommand)c, lvl.Areas[CurrentAreaIndex].BGMusic);
- break;
- }
-
- case LevelscriptCommandTypes.Tarrain:
- {
- clTerrian.SetTerrainType((LevelscriptCommand)c, (byte)lvl.Areas[CurrentAreaIndex].TerrainType);
- break;
- }
-
- case LevelscriptCommandTypes.LoadRomToRam:
- {
- var switchExpr2 = clLoadRomToRam.GetSegmentedID((LevelscriptCommand)c);
- switch (switchExpr2)
- {
- case 0xE: // Bank 0xE
- clLoadRomToRam.SetRomStart((LevelscriptCommand)c, firstBank0xE.RomStart);
- clLoadRomToRam.SetRomEnd((LevelscriptCommand)c, firstBank0xE.RomEnd);
- break;
- case 0xA:
- cmdBgSegLoad = (LevelscriptCommand)c;
- break;
- case 0x7:
- if (lvl.LastGobCmdSegLoad == c)
- {
- cmdGobSegLoad = (LevelscriptCommand)c;
- }
- break;
- case 0x9:
- if (lvl.LastLobCmdSegLoad == c)
- {
- cmdLobSegLoad = (LevelscriptCommand)c;
- }
- break;
- }
-
- break;
- }
-
- case LevelscriptCommandTypes.ShowDialog:
- {
- if ((bool)tArea?.ShowMessage.Enabled && !foundCmdShowMsg)
- {
- clShowDialog.SetDialogID((LevelscriptCommand)c, tArea.ShowMessage.DialogID);
- foundCmdShowMsg = true;
- }
- else
- {
- cmdsToRemove.Add((LevelscriptCommand)c);
- }
-
- break;
- }
-
- case LevelscriptCommandTypes.JumpToSegAddr:
- {
- int bankID = clJumpToSegAddr.GetSegJumpAddr((LevelscriptCommand)c) >> 24;
- switch(bankID)
- {
- case 0x7:
- cmdGobJump = (LevelscriptCommand)c;
- break;
- case 0x9:
- cmdLobJump = (LevelscriptCommand)c;
- break;
- }
- break;
- }
- }
- }
-
- // Füge Jump Commands zur ersten 0xE-Bank hinzu
- foreach (var e in areaobjwarpindextoinsertdic.OrderByDescending(n => n.Value))
- {
- uint segStartAddr = areaobjwarpoffsetdic[e.Key];
- lvl.Levelscript.Insert(e.Value, new LevelscriptCommand(new byte[] { 0x6, 8, 0, 0, Convert.ToByte((long)(segStartAddr >> 24) & (long)0xFF), Convert.ToByte((long)(segStartAddr >> 16) & (long)0xFF), Convert.ToByte((long)(segStartAddr >> 8) & (long)0xFF), Convert.ToByte((long)segStartAddr & (long)0xFF) }));
- }
-
- // Lösche Commands
- foreach (LevelscriptCommand cmd in cmdsToRemove)
- lvl.Levelscript.Remove(cmd);
-
- // Füge neue Commands ein
- foreach (KeyValuePair kvp in cmdsToInsertAt)
- {
- int index = lvl.Levelscript.IndexOf(kvp.Key);
- lvl.Levelscript.Insert(index, kvp.Value);
- }
-
- // Füge Background-Command ein
- if (lvl.Background.Enabled)
- {
- var newbgcmd = cmdBgSegLoad ?? new LevelscriptCommand(new byte[] { 0x17, 0xC, 0, 0xA, 0, 0, 0, 0, 0, 0, 0, 0 });
- if (lvl.Background.IsCustom && lvl.Background.HasImage) // .ID = Geolayout.BackgroundIDs.Custom Then
- {
- clLoadRomToRam.SetRomStart(newbgcmd, customBGStart);
- clLoadRomToRam.SetRomEnd(newbgcmd, customBGEnd);
- }
- else
- {
- clLoadRomToRam.SetRomStart(newbgcmd, (int)General.GetBackgroundAddressOfID(lvl.Background.ID, false));
- clLoadRomToRam.SetRomEnd(newbgcmd, (int)General.GetBackgroundAddressOfID(lvl.Background.ID, true));
- }
-
- if (!lvl.Levelscript.Contains(newbgcmd))
- {
- int indexoffirstx1e = lvl.Levelscript.IndexOfFirst(LevelscriptCommandTypes.x1D);
- lvl.Levelscript.Insert(indexoffirstx1e, newbgcmd);
- }
- }
- else if (cmdBgSegLoad is not null)
- {
- lvl.Levelscript.Remove(cmdBgSegLoad);
- }
-
- // Füge Global Model Bank Command ein
- if (lvl.EnableGlobalObjectBank)
- {
- var newgobjumpcmd = cmdGobJump ?? new LevelscriptCommand("06 08 00 00 07 00 00 00");
- var newgobcmd = cmdGobSegLoad ?? new LevelscriptCommand("17 0C 00 07 00 00 00 00 00 00 00 00");
- clLoadRomToRam.SetRomStart(newgobcmd, rommgr.GlobalModelBank.CurSeg.RomStart);
- clLoadRomToRam.SetRomEnd(newgobcmd, rommgr.GlobalModelBank.CurSeg.RomEnd);
-
- if (!lvl.Levelscript.Contains(newgobcmd))
- {
- int indexoffirstx1d = lvl.Levelscript.IndexOfFirst(LevelscriptCommandTypes.x1D);
- lvl.Levelscript.Insert(indexoffirstx1d, newgobcmd);
- lvl.LastGobCmdSegLoad = newgobcmd;
- }
-
- if (!lvl.Levelscript.Contains(newgobjumpcmd))
- {
- int indexoffirstx1e = lvl.Levelscript.IndexOfFirst(LevelscriptCommandTypes.x25);
- if (writeLocalObjectBank && cmdLobJump is not null && lvl.Levelscript.IndexOf(cmdLobJump) == indexoffirstx1e - 1)
- indexoffirstx1e -= 1;
- lvl.Levelscript.Insert(indexoffirstx1e, newgobjumpcmd);
- }
- }
- else
- {
- if (cmdGobJump is not null)
- lvl.Levelscript.Remove(cmdGobJump);
-
- if (cmdGobSegLoad is not null)
- lvl.Levelscript.Remove(cmdGobSegLoad);
- }
-
- // Füge Local Model Bank Command ein
- if (writeLocalObjectBank)
- {
- var newlobjumpcmd = cmdLobJump ?? new LevelscriptCommand("06 08 00 00 09 00 00 00");
- var newlobcmd = cmdLobSegLoad ?? new LevelscriptCommand("17 0C 00 09 00 00 00 00 00 00 00 00");
- clLoadRomToRam.SetRomStart(newlobcmd, (int)localObjectBankRomStart);
- clLoadRomToRam.SetRomEnd(newlobcmd, (int)localObjectBankRomEnd);
-
- if (!lvl.Levelscript.Contains(newlobcmd))
- {
- int indexoffirstx1d = lvl.Levelscript.IndexOfFirst(LevelscriptCommandTypes.x1D);
- lvl.Levelscript.Insert(indexoffirstx1d, newlobcmd);
- lvl.LastLobCmdSegLoad = newlobcmd;
- }
-
- if (!lvl.Levelscript.Contains(newlobjumpcmd))
- {
- int indexoffirstx1e = lvl.Levelscript.IndexOfFirst(LevelscriptCommandTypes.x25);
- lvl.Levelscript.Insert(indexoffirstx1e, newlobjumpcmd);
- }
- }
- else
- {
- if (cmdLobJump is not null)
- lvl.Levelscript.Remove(cmdLobJump);
-
- if (cmdLobSegLoad is not null)
- lvl.Levelscript.Remove(cmdLobSegLoad);
- }
-
- // Write Level Start (Start of Bank 0x19)
- lvl.Bank0x19.Data.Position = 0;
- foreach (byte b in Level.LevelscriptStart)
- data0x19.Write(b);
-
- // Write Levelscript
- lvl.Levelscript.Write(lvl.Bank0x19.Data, Convert.ToInt32(data0x19.Position));
-
- // Parse Levelscript again!
- bool AreaOnFly = false;
- foreach (var c in lvl.Levelscript.ToArray())
- {
- var switchExpr3 = c.CommandType;
- switch (switchExpr3)
- {
- case LevelscriptCommandTypes.StartArea:
- {
- AreaOnFly = true;
- break;
- }
-
- case LevelscriptCommandTypes.EndOfArea:
- {
- AreaOnFly = false;
- lvl.Levelscript.Remove(c);
- break;
- }
- }
-
- if (AreaOnFly)
- lvl.Levelscript.Remove(c);
- }
-
- var bwToUse = data0x19 ?? output;
-
- // Write 4 checkbytes for the One-0xE-Bank-Per-Area-Code
- lvl.Bank0x19.Data.Position = 0x5FFC;
- bwToUse.Write(Convert.ToInt32(0x4BC9189A));
-
- // Write Area Table
- foreach (LevelArea a in lvl.Areas)
- {
- uint off = (uint)(0x5F00 + a.AreaID * 0x10);
- lvl.Bank0x19.Data.Position = off;
- bwToUse.Write(Convert.ToUInt32(a.Bank0x0EOffset));
- bwToUse.Write(Convert.ToUInt32(a.Bank0x0EOffset + a.Bank0xELength));
- bwToUse.Write(Convert.ToUInt32(0));
- bwToUse.Write(Convert.ToByte(0x0));
- bwToUse.Write(Convert.ToByte(0x0));
- bwToUse.Write(Convert.ToByte(0x0));
- bwToUse.Write(Bits.ArrayToByte(new[] { false, false, false, false, false, false, false, a.Enable2DCamera }));
- }
-
- // Write SpecialBoxes
- int CurrentBoxOffset = 0x6A00;
- foreach (LevelArea a in lvl.Areas.Where(n => n.AreaID < 8))
- {
- var TableIndex = new[] { 0, 0x32, 0x33 };
- var TableOffset = new[] { 0x6000 + 0x50 * a.AreaID, 0x6280 + 0x50 * a.AreaID, 0x6500 + 0x50 * a.AreaID };
-
- foreach (SpecialBoxType t in Enum.GetValues(typeof(SpecialBoxType)))
- {
- foreach (SpecialBox w in a.SpecialBoxes.Where(n => n.Type == t))
- {
- // Write Table Entry
- bwToUse.Position = TableOffset[(int)w.Type];
- bwToUse.Write(Convert.ToInt16(TableIndex[(int)w.Type]));
- bwToUse.Write(Convert.ToInt16(0x0));
- bwToUse.Write(Convert.ToInt32(CurrentBoxOffset + lvl.Bank0x19.BankAddress));
- TableOffset[(int)w.Type] = Convert.ToInt32(bwToUse.Position);
-
- // Write Box Data
- bwToUse.Position = CurrentBoxOffset;
- w.ToBoxData(bwToUse);
- CurrentBoxOffset = (int)bwToUse.Position;
-
- if (w.Type == SpecialBoxType.ToxicHaze)
- TableIndex[(int)w.Type] += 10;
- else
- TableIndex[(int)w.Type] += 1;
- }
- }
-
- foreach (int i in TableOffset)
- {
- bwToUse.Position = i;
- bwToUse.Write((ushort)0xFFFF);
- }
- }
-
- // Write Bank0x19
- lvl.Bank0x19.WriteData(output);
-
- // Hardcoded Camera Settings & Act Selector
- General.PatchClass.Open(output);
- General.PatchClass.set_HardcodedCamera_Enabled(lvl.LevelID, lvl.HardcodedCameraSettings);
- General.PatchClass.set_ActSelector_Enabled(lvl.LevelID, lvl.ActSelector);
-
- // Write Pointer to Levelscript
- output.Position = lid.Pointer;
- output.Write(Convert.ToInt32(0x100019));
- output.Write(Convert.ToUInt32(lvl.Bank0x19.RomStart));
- output.Write(Convert.ToUInt32(lvl.Bank0x19.RomEnd));
- output.Write(Convert.ToUInt32(0x1900001C));
- output.Write(Convert.ToUInt32(0x7040000));
-
- // Write Area Reverb
- if (EnableLoadingAreaReverb)
- {
- foreach (var area in lvl.Areas)
- {
- if (area is RMLevelArea && area.AreaID >= 1 && area.AreaID <= 3)
- {
- output.Position = 0xEE0C0 + lvl.LevelID * 3 + area.AreaID - 1;
- output.Write((byte)((RMLevelArea)area).ReverbLevel);
- }
- }
- }
-
- return saveres;
+ uint segStartAddr = areaobjwarpoffsetdic[e.Key];
+ lvl.Levelscript.Insert(e.Value, new LevelscriptCommand(new byte[] { 0x6, 8, 0, 0, Convert.ToByte((long)(segStartAddr >> 24) & (long)0xFF), Convert.ToByte((long)(segStartAddr >> 16) & (long)0xFF), Convert.ToByte((long)(segStartAddr >> 8) & (long)0xFF), Convert.ToByte((long)segStartAddr & (long)0xFF) }));
}
+
+ // Lösche Commands
+ foreach (LevelscriptCommand cmd in cmdsToRemove)
+ lvl.Levelscript.Remove(cmd);
+
+ // Füge neue Commands ein
+ foreach (KeyValuePair kvp in cmdsToInsertAt)
+ {
+ int index = lvl.Levelscript.IndexOf(kvp.Key);
+ lvl.Levelscript.Insert(index, kvp.Value);
+ }
+
+ // Füge Background-Command ein
+ if (lvl.Background.Enabled)
+ {
+ var newbgcmd = cmdBgSegLoad ?? new LevelscriptCommand(new byte[] { 0x17, 0xC, 0, 0xA, 0, 0, 0, 0, 0, 0, 0, 0 });
+ if (lvl.Background.IsCustom && lvl.Background.HasImage) // .ID = Geolayout.BackgroundIDs.Custom Then
+ {
+ clLoadRomToRam.SetRomStart(newbgcmd, customBGStart);
+ clLoadRomToRam.SetRomEnd(newbgcmd, customBGEnd);
+ }
+ else
+ {
+ clLoadRomToRam.SetRomStart(newbgcmd, (int)General.GetBackgroundAddressOfID(lvl.Background.ID, false));
+ clLoadRomToRam.SetRomEnd(newbgcmd, (int)General.GetBackgroundAddressOfID(lvl.Background.ID, true));
+ }
+
+ if (!lvl.Levelscript.Contains(newbgcmd))
+ {
+ int indexoffirstx1e = lvl.Levelscript.IndexOfFirst(LevelscriptCommandTypes.x1D);
+ lvl.Levelscript.Insert(indexoffirstx1e, newbgcmd);
+ }
+ }
+ else if (cmdBgSegLoad is not null)
+ {
+ lvl.Levelscript.Remove(cmdBgSegLoad);
+ }
+
+ // Füge Global Model Bank Command ein
+ if (lvl.EnableGlobalObjectBank)
+ {
+ var newgobjumpcmd = cmdGobJump ?? new LevelscriptCommand("06 08 00 00 07 00 00 00");
+ var newgobcmd = cmdGobSegLoad ?? new LevelscriptCommand("17 0C 00 07 00 00 00 00 00 00 00 00");
+ clLoadRomToRam.SetRomStart(newgobcmd, rommgr.GlobalModelBank.CurSeg.RomStart);
+ clLoadRomToRam.SetRomEnd(newgobcmd, rommgr.GlobalModelBank.CurSeg.RomEnd);
+
+ if (!lvl.Levelscript.Contains(newgobcmd))
+ {
+ int indexoffirstx1d = lvl.Levelscript.IndexOfFirst(LevelscriptCommandTypes.x1D);
+ lvl.Levelscript.Insert(indexoffirstx1d, newgobcmd);
+ lvl.LastGobCmdSegLoad = newgobcmd;
+ }
+
+ if (!lvl.Levelscript.Contains(newgobjumpcmd))
+ {
+ int indexoffirstx1e = lvl.Levelscript.IndexOfFirst(LevelscriptCommandTypes.x25);
+ if (writeLocalObjectBank && cmdLobJump is not null && lvl.Levelscript.IndexOf(cmdLobJump) == indexoffirstx1e - 1)
+ indexoffirstx1e -= 1;
+ lvl.Levelscript.Insert(indexoffirstx1e, newgobjumpcmd);
+ }
+ }
+ else
+ {
+ if (cmdGobJump is not null)
+ lvl.Levelscript.Remove(cmdGobJump);
+
+ if (cmdGobSegLoad is not null)
+ lvl.Levelscript.Remove(cmdGobSegLoad);
+ }
+
+ // Füge Local Model Bank Command ein
+ if (writeLocalObjectBank)
+ {
+ var newlobjumpcmd = cmdLobJump ?? new LevelscriptCommand("06 08 00 00 09 00 00 00");
+ var newlobcmd = cmdLobSegLoad ?? new LevelscriptCommand("17 0C 00 09 00 00 00 00 00 00 00 00");
+ clLoadRomToRam.SetRomStart(newlobcmd, (int)localObjectBankRomStart);
+ clLoadRomToRam.SetRomEnd(newlobcmd, (int)localObjectBankRomEnd);
+
+ if (!lvl.Levelscript.Contains(newlobcmd))
+ {
+ int indexoffirstx1d = lvl.Levelscript.IndexOfFirst(LevelscriptCommandTypes.x1D);
+ lvl.Levelscript.Insert(indexoffirstx1d, newlobcmd);
+ lvl.LastLobCmdSegLoad = newlobcmd;
+ }
+
+ if (!lvl.Levelscript.Contains(newlobjumpcmd))
+ {
+ int indexoffirstx1e = lvl.Levelscript.IndexOfFirst(LevelscriptCommandTypes.x25);
+ lvl.Levelscript.Insert(indexoffirstx1e, newlobjumpcmd);
+ }
+ }
+ else
+ {
+ if (cmdLobJump is not null)
+ lvl.Levelscript.Remove(cmdLobJump);
+
+ if (cmdLobSegLoad is not null)
+ lvl.Levelscript.Remove(cmdLobSegLoad);
+ }
+
+ // Write Level Start (Start of Bank 0x19)
+ lvl.Bank0x19.Data.Position = 0;
+ foreach (byte b in Level.LevelscriptStart)
+ data0x19.Write(b);
+
+ // Write Levelscript
+ lvl.Levelscript.Write(lvl.Bank0x19.Data, Convert.ToInt32(data0x19.Position));
+
+ // Parse Levelscript again!
+ bool AreaOnFly = false;
+ foreach (var c in lvl.Levelscript.ToArray())
+ {
+ var switchExpr3 = c.CommandType;
+ switch (switchExpr3)
+ {
+ case LevelscriptCommandTypes.StartArea:
+ {
+ AreaOnFly = true;
+ break;
+ }
+
+ case LevelscriptCommandTypes.EndOfArea:
+ {
+ AreaOnFly = false;
+ lvl.Levelscript.Remove(c);
+ break;
+ }
+ }
+
+ if (AreaOnFly)
+ lvl.Levelscript.Remove(c);
+ }
+
+ var bwToUse = data0x19 ?? output;
+
+ // Write 4 checkbytes for the One-0xE-Bank-Per-Area-Code
+ lvl.Bank0x19.Data.Position = 0x5FFC;
+ bwToUse.Write(Convert.ToInt32(0x4BC9189A));
+
+ // Write Area Table
+ foreach (LevelArea a in lvl.Areas)
+ {
+ uint off = (uint)(0x5F00 + a.AreaID * 0x10);
+ lvl.Bank0x19.Data.Position = off;
+ bwToUse.Write(Convert.ToUInt32(a.Bank0x0EOffset));
+ bwToUse.Write(Convert.ToUInt32(a.Bank0x0EOffset + a.Bank0xELength));
+ bwToUse.Write(Convert.ToUInt32(0));
+ bwToUse.Write(Convert.ToByte(0x0));
+ bwToUse.Write(Convert.ToByte(0x0));
+ bwToUse.Write(Convert.ToByte(0x0));
+ bwToUse.Write(Bits.ArrayToByte(new[] { false, false, false, false, false, false, false, a.Enable2DCamera }));
+ }
+
+ // Write SpecialBoxes
+ int CurrentBoxOffset = 0x6A00;
+ foreach (LevelArea a in lvl.Areas.Where(n => n.AreaID < 8))
+ {
+ var TableIndex = new[] { 0, 0x32, 0x33 };
+ var TableOffset = new[] { 0x6000 + 0x50 * a.AreaID, 0x6280 + 0x50 * a.AreaID, 0x6500 + 0x50 * a.AreaID };
+
+ foreach (SpecialBoxType t in Enum.GetValues(typeof(SpecialBoxType)))
+ {
+ foreach (SpecialBox w in a.SpecialBoxes.Where(n => n.Type == t))
+ {
+ // Write Table Entry
+ bwToUse.Position = TableOffset[(int)w.Type];
+ bwToUse.Write(Convert.ToInt16(TableIndex[(int)w.Type]));
+ bwToUse.Write(Convert.ToInt16(0x0));
+ bwToUse.Write(Convert.ToInt32(CurrentBoxOffset + lvl.Bank0x19.BankAddress));
+ TableOffset[(int)w.Type] = Convert.ToInt32(bwToUse.Position);
+
+ // Write Box Data
+ bwToUse.Position = CurrentBoxOffset;
+ w.ToBoxData(bwToUse);
+ CurrentBoxOffset = (int)bwToUse.Position;
+
+ if (w.Type == SpecialBoxType.ToxicHaze)
+ TableIndex[(int)w.Type] += 10;
+ else
+ TableIndex[(int)w.Type] += 1;
+ }
+ }
+
+ foreach (int i in TableOffset)
+ {
+ bwToUse.Position = i;
+ bwToUse.Write((ushort)0xFFFF);
+ }
+ }
+
+ // Write Bank0x19
+ lvl.Bank0x19.WriteData(output);
+
+ // Hardcoded Camera Settings & Act Selector
+ General.PatchClass.Open(output);
+ General.PatchClass.set_HardcodedCamera_Enabled(lvl.LevelID, lvl.HardcodedCameraSettings);
+ General.PatchClass.set_ActSelector_Enabled(lvl.LevelID, lvl.ActSelector);
+
+ // Write Pointer to Levelscript
+ output.Position = lid.Pointer;
+ output.Write(Convert.ToInt32(0x100019));
+ output.Write(Convert.ToUInt32(lvl.Bank0x19.RomStart));
+ output.Write(Convert.ToUInt32(lvl.Bank0x19.RomEnd));
+ output.Write(Convert.ToUInt32(0x1900001C));
+ output.Write(Convert.ToUInt32(0x7040000));
+
+ // Write Area Reverb
+ if (EnableLoadingAreaReverb)
+ {
+ foreach (var area in lvl.Areas)
+ {
+ if (area is RMLevelArea && area.AreaID >= 1 && area.AreaID <= 3)
+ {
+ output.Position = 0xEE0C0 + lvl.LevelID * 3 + area.AreaID - 1;
+ output.Write((byte)((RMLevelArea)area).ReverbLevel);
+ }
+ }
+ }
+
+ return saveres;
}
}
\ No newline at end of file
diff --git a/SM64Lib/Level/LevelNumberTable.cs b/SM64Lib/Level/LevelNumberTable.cs
index 0860bba..1b1da38 100644
--- a/SM64Lib/Level/LevelNumberTable.cs
+++ b/SM64Lib/Level/LevelNumberTable.cs
@@ -1,27 +1,25 @@
-using System;
+using global::System.IO;
+using System;
using System.Collections.Generic;
-using global::System.IO;
-using Microsoft.VisualBasic.CompilerServices;
-namespace SM64Lib.Levels
+namespace SM64Lib.Levels;
+
+public class LevelNumberTable : List
{
- public class LevelNumberTable : List
+ public void ReadFromROM(string Romfile, int Address = 0xE8D98)
{
- public void ReadFromROM(string Romfile, int Address = 0xE8D98)
- {
- var fs = new FileStream(Romfile, FileMode.Open, FileAccess.Read);
- ReadFromROM(ref fs);
- fs.Close();
- }
+ var fs = new FileStream(Romfile, FileMode.Open, FileAccess.Read);
+ ReadFromROM(ref fs);
+ fs.Close();
+ }
- public void ReadFromROM(ref FileStream fs, int Address = 0xE8D98)
+ public void ReadFromROM(ref FileStream fs, int Address = 0xE8D98)
+ {
+ Clear();
+ for (int i = 0; i <= 30; i++)
{
- Clear();
- for (int i = 0; i <= 30; i++)
- {
- fs.Position = Address + General.GetLevelIDFromIndex(Convert.ToByte(i));
- Add(Convert.ToByte(fs.ReadByte()));
- }
+ fs.Position = Address + General.GetLevelIDFromIndex(Convert.ToByte(i));
+ Add(Convert.ToByte(fs.ReadByte()));
}
}
}
\ No newline at end of file
diff --git a/SM64Lib/Level/LevelSaveResult.cs b/SM64Lib/Level/LevelSaveResult.cs
index d4a2839..b45f5d1 100644
--- a/SM64Lib/Level/LevelSaveResult.cs
+++ b/SM64Lib/Level/LevelSaveResult.cs
@@ -1,9 +1,8 @@
using global::SM64Lib.SegmentedBanking;
-namespace SM64Lib.Levels
+namespace SM64Lib.Levels;
+
+public class LevelSaveResult
{
- public class LevelSaveResult
- {
- public SegmentedBank Bank0x19 { get; set; } = null;
- }
+ public SegmentedBank Bank0x19 { get; set; } = null;
}
\ No newline at end of file
diff --git a/SM64Lib/Level/LevelType.cs b/SM64Lib/Level/LevelType.cs
index f401fa1..74700b2 100644
--- a/SM64Lib/Level/LevelType.cs
+++ b/SM64Lib/Level/LevelType.cs
@@ -1,10 +1,9 @@
-namespace SM64Lib.Levels
+namespace SM64Lib.Levels;
+
+public enum LevelType
{
- public enum LevelType
- {
- Original,
- SM64RomManager,
- SM64Editor
- }
+ Original,
+ SM64RomManager,
+ SM64Editor
}
\ No newline at end of file
diff --git a/SM64Lib/Level/OriginalLevel.cs b/SM64Lib/Level/OriginalLevel.cs
index 7dcd7cb..ffab463 100644
--- a/SM64Lib/Level/OriginalLevel.cs
+++ b/SM64Lib/Level/OriginalLevel.cs
@@ -1,14 +1,13 @@
-namespace SM64Lib.Levels
-{
- public class OriginalLevel : Level
- {
- public OriginalLevel(ushort LevelID, int LevelIndex, RomManager rommgr) : base(LevelID, LevelIndex, rommgr)
- {
- }
+namespace SM64Lib.Levels;
- public OriginalLevel(RomManager rommgr) : base(rommgr)
- {
- }
+public class OriginalLevel : Level
+{
+ public OriginalLevel(ushort LevelID, int LevelIndex, RomManager rommgr) : base(LevelID, LevelIndex, rommgr)
+ {
+ }
+
+ public OriginalLevel(RomManager rommgr) : base(rommgr)
+ {
}
}
\ No newline at end of file
diff --git a/SM64Lib/Level/OriginalLevelArea.cs b/SM64Lib/Level/OriginalLevelArea.cs
index b87296c..0446701 100644
--- a/SM64Lib/Level/OriginalLevelArea.cs
+++ b/SM64Lib/Level/OriginalLevelArea.cs
@@ -1,22 +1,21 @@
-namespace SM64Lib.Levels
+namespace SM64Lib.Levels;
+
+public class OriginalLevelArea : LevelArea
{
- public class OriginalLevelArea : LevelArea
+ public OriginalLevelArea(byte AreaID) : base(AreaID)
{
- public OriginalLevelArea(byte AreaID) : base(AreaID)
- {
- }
+ }
- public OriginalLevelArea(byte AreaID, byte LevelID) : base(AreaID, LevelID)
- {
- }
+ public OriginalLevelArea(byte AreaID, byte LevelID) : base(AreaID, LevelID)
+ {
+ }
- public OriginalLevelArea(byte AreaID, byte LevelID, bool AddWarps, bool AddObjects) : base(AreaID, LevelID, AddWarps, AddObjects)
- {
- }
+ public OriginalLevelArea(byte AreaID, byte LevelID, bool AddWarps, bool AddObjects) : base(AreaID, LevelID, AddWarps, AddObjects)
+ {
+ }
- public OriginalLevelArea() : base()
- {
- }
+ public OriginalLevelArea() : base()
+ {
}
}
\ No newline at end of file
diff --git a/SM64Lib/Level/OriginalLevelManager.cs b/SM64Lib/Level/OriginalLevelManager.cs
index 082921e..ba8ecbe 100644
--- a/SM64Lib/Level/OriginalLevelManager.cs
+++ b/SM64Lib/Level/OriginalLevelManager.cs
@@ -1,18 +1,17 @@
-using System;
-using global::SM64Lib.Data;
+using global::SM64Lib.Data;
+using System;
-namespace SM64Lib.Levels
+namespace SM64Lib.Levels;
+
+public class OriginalLevelManager : ILevelManager
{
- public class OriginalLevelManager : ILevelManager
+ public void LoadLevel(Level lvl, RomManager rommgr, ushort LevelID, uint segAddress)
{
- public void LoadLevel(Level lvl, RomManager rommgr, ushort LevelID, uint segAddress)
- {
- throw new NotImplementedException();
- }
+ throw new NotImplementedException();
+ }
- public LevelSaveResult SaveLevel(Level lvl, RomManager rommgr, BinaryData output, ref uint curOff)
- {
- throw new NotImplementedException();
- }
+ public LevelSaveResult SaveLevel(Level lvl, RomManager rommgr, BinaryData output, ref uint curOff)
+ {
+ throw new NotImplementedException();
}
}
\ No newline at end of file
diff --git a/SM64Lib/Level/RMLevel.cs b/SM64Lib/Level/RMLevel.cs
index 8db75d6..bf064d3 100644
--- a/SM64Lib/Level/RMLevel.cs
+++ b/SM64Lib/Level/RMLevel.cs
@@ -2,33 +2,32 @@
using Newtonsoft.Json;
using SM64Lib.Configuration;
-namespace SM64Lib.Levels
+namespace SM64Lib.Levels;
+
+public class RMLevel : Level
{
- public class RMLevel : Level
+ [JsonProperty]
+ public LevelConfig Config { get; private set; }
+
+ [JsonIgnore]
+ public string Name
{
- [JsonProperty]
- public LevelConfig Config { get; private set; }
+ get => Config.LevelName;
+ set => Config.LevelName = value;
+ }
- [JsonIgnore]
- public string Name
- {
- get => Config.LevelName;
- set => Config.LevelName = value;
- }
+ public RMLevel(ushort LevelID, int LevelIndex, RomManager rommgr) : base(LevelID, LevelIndex, rommgr)
+ {
+ Config = new LevelConfig();
+ }
- public RMLevel(ushort LevelID, int LevelIndex, RomManager rommgr) : base(LevelID, LevelIndex, rommgr)
- {
- Config = new LevelConfig();
- }
+ public RMLevel(LevelConfig config, RomManager rommgr) : base(rommgr)
+ {
+ Config = config;
+ }
- public RMLevel(LevelConfig config, RomManager rommgr) : base(rommgr)
- {
- Config = config;
- }
-
- [JsonConstructor]
- private RMLevel(JsonConstructorAttribute attr) : base(attr)
- {
- }
+ [JsonConstructor]
+ private RMLevel(JsonConstructorAttribute attr) : base(attr)
+ {
}
}
\ No newline at end of file
diff --git a/SM64Lib/Level/RMLevelArea.cs b/SM64Lib/Level/RMLevelArea.cs
index 66541f2..9e15c09 100644
--- a/SM64Lib/Level/RMLevelArea.cs
+++ b/SM64Lib/Level/RMLevelArea.cs
@@ -1,35 +1,34 @@
using Newtonsoft.Json;
-namespace SM64Lib.Levels
+namespace SM64Lib.Levels;
+
+public class RMLevelArea : LevelArea
{
- public class RMLevelArea : LevelArea
+ // P r o p e r t i e s
+
+ public AreaReverbLevel ReverbLevel { get; set; } = AreaReverbLevel.None;
+
+ // C o n s t r u c t o r s
+
+ public RMLevelArea(byte AreaID) : base(AreaID)
{
- // P r o p e r t i e s
+ }
- public AreaReverbLevel ReverbLevel { get; set; } = AreaReverbLevel.None;
+ public RMLevelArea(byte AreaID, byte LevelID) : base(AreaID, LevelID)
+ {
+ }
- // C o n s t r u c t o r s
+ public RMLevelArea(byte AreaID, byte LevelID, bool AddWarps, bool AddObjects) : base(AreaID, LevelID, AddWarps, AddObjects)
+ {
+ }
- public RMLevelArea(byte AreaID) : base(AreaID)
- {
- }
+ public RMLevelArea() : base()
+ {
+ }
- public RMLevelArea(byte AreaID, byte LevelID) : base(AreaID, LevelID)
- {
- }
-
- public RMLevelArea(byte AreaID, byte LevelID, bool AddWarps, bool AddObjects) : base(AreaID, LevelID, AddWarps, AddObjects)
- {
- }
-
- public RMLevelArea() : base()
- {
- }
-
- [JsonConstructor]
- private RMLevelArea(JsonConstructorAttribute attr) : base(attr)
- {
- }
+ [JsonConstructor]
+ private RMLevelArea(JsonConstructorAttribute attr) : base(attr)
+ {
}
}
\ No newline at end of file
diff --git a/SM64Lib/Level/SM64ELevel.cs b/SM64Lib/Level/SM64ELevel.cs
index e7e437d..212e8c9 100644
--- a/SM64Lib/Level/SM64ELevel.cs
+++ b/SM64Lib/Level/SM64ELevel.cs
@@ -1,14 +1,13 @@
-namespace SM64Lib.Levels
-{
- public class SM64ELevel : Level
- {
- public SM64ELevel(ushort LevelID, int LevelIndex, RomManager rommgr) : base(LevelID, LevelIndex, rommgr)
- {
- }
+namespace SM64Lib.Levels;
- public SM64ELevel(RomManager rommgr) : base(rommgr)
- {
- }
+public class SM64ELevel : Level
+{
+ public SM64ELevel(ushort LevelID, int LevelIndex, RomManager rommgr) : base(LevelID, LevelIndex, rommgr)
+ {
+ }
+
+ public SM64ELevel(RomManager rommgr) : base(rommgr)
+ {
}
}
\ No newline at end of file
diff --git a/SM64Lib/Level/SM64ELevelArea.cs b/SM64Lib/Level/SM64ELevelArea.cs
index 9ff50ce..a64a4a2 100644
--- a/SM64Lib/Level/SM64ELevelArea.cs
+++ b/SM64Lib/Level/SM64ELevelArea.cs
@@ -1,22 +1,21 @@
-namespace SM64Lib.Levels
+namespace SM64Lib.Levels;
+
+public class SM64ELevelArea : LevelArea
{
- public class SM64ELevelArea : LevelArea
+ public SM64ELevelArea(byte AreaID) : base(AreaID)
{
- public SM64ELevelArea(byte AreaID) : base(AreaID)
- {
- }
+ }
- public SM64ELevelArea(byte AreaID, byte LevelID) : base(AreaID, LevelID)
- {
- }
+ public SM64ELevelArea(byte AreaID, byte LevelID) : base(AreaID, LevelID)
+ {
+ }
- public SM64ELevelArea(byte AreaID, byte LevelID, bool AddWarps, bool AddObjects) : base(AreaID, LevelID, AddWarps, AddObjects)
- {
- }
+ public SM64ELevelArea(byte AreaID, byte LevelID, bool AddWarps, bool AddObjects) : base(AreaID, LevelID, AddWarps, AddObjects)
+ {
+ }
- public SM64ELevelArea() : base()
- {
- }
+ public SM64ELevelArea() : base()
+ {
}
}
\ No newline at end of file
diff --git a/SM64Lib/Level/SM64EditorLevelManager.cs b/SM64Lib/Level/SM64EditorLevelManager.cs
index 70c2b2a..09a21f0 100644
--- a/SM64Lib/Level/SM64EditorLevelManager.cs
+++ b/SM64Lib/Level/SM64EditorLevelManager.cs
@@ -1,330 +1,328 @@
-using System;
-using System.Collections.Generic;
-using System.Data;
-using global::System.IO;
-using System.Linq;
-using Microsoft.VisualBasic.CompilerServices;
-using global::SM64Lib.Data;
+using global::SM64Lib.Data;
using global::SM64Lib.Geolayout.Script;
using global::SM64Lib.Geolayout.Script.Commands;
using global::SM64Lib.Levels.Script;
using global::SM64Lib.Levels.Script.Commands;
+using global::System.IO;
using SM64Lib.Configuration;
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Linq;
-namespace SM64Lib.Levels
+namespace SM64Lib.Levels;
+
+public class SM64EditorLevelManager : ILevelManager
{
- public class SM64EditorLevelManager : ILevelManager
+
+ ///
+ /// Loads a SM64 Editor Level from ROM.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void LoadLevel(Level lvl, RomManager rommgr, ushort LevelID, uint segAddress)
{
+ int customBGStart = 0;
+ int customBGEnd = 0;
+ lvl.LevelID = LevelID;
- ///
- /// Loads a SM64 Editor Level from ROM.
- ///
- ///
- ///
- ///
- ///
- public void LoadLevel(Level lvl, RomManager rommgr, ushort LevelID, uint segAddress)
+ // Load Bank 0x19
+ lvl.Bank0x19 = rommgr.GetSegBank(0x19);
+ lvl.Bank0x19.ReadDataIfNull(rommgr.RomFile);
+ if (lvl.Bank0x19.Length < 0x10000)
{
- int customBGStart = 0;
- int customBGEnd = 0;
- lvl.LevelID = LevelID;
+ lvl.Bank0x19.Length = 0x10000;
+ }
- // Load Bank 0x19
- lvl.Bank0x19 = rommgr.GetSegBank(0x19);
- lvl.Bank0x19.ReadDataIfNull(rommgr.RomFile);
- if (lvl.Bank0x19.Length < 0x10000)
+ if (!lvl.Closed)
+ lvl.Close();
+ lvl.Closed = false;
+
+ // Lade Levelscript
+ lvl.Levelscript = new Levelscript();
+ lvl.Levelscript.Read(rommgr, Convert.ToInt32(segAddress));
+
+ // Erstelle Areas / Lade Einstellungen
+ bool AreaOnFly = false;
+ LevelArea tArea = null;
+ var CurrentLevelScriptCommands = lvl.Levelscript.ToArray();
+ var cmdsToRemove = new List();
+ LevelArea firstArea = null;
+ foreach (LevelscriptCommand c in CurrentLevelScriptCommands)
+ {
+ var switchExpr = c.CommandType;
+ switch (switchExpr)
{
- lvl.Bank0x19.Length = 0x10000;
- }
+ case LevelscriptCommandTypes.StartArea:
+ {
+ AreaOnFly = true;
+ tArea = new SM64ELevelArea();
+ if (firstArea is null)
+ firstArea = tArea;
+ tArea.AreaID = clStartArea.GetAreaID(c);
+ tArea.GeolayoutOffset = clStartArea.GetSegGeolayoutAddr(c);
+ tArea.Geolayout.Read(rommgr, Convert.ToInt32(tArea.GeolayoutOffset));
+ break;
+ }
- if (!lvl.Closed)
- lvl.Close();
- lvl.Closed = false;
+ case LevelscriptCommandTypes.EndOfArea:
+ {
+ tArea.Levelscript.Add(c);
+ lvl.Levelscript.Remove(c);
+ lvl.Areas.Add(tArea);
+ AreaOnFly = false;
+ break;
+ }
- // Lade Levelscript
- lvl.Levelscript = new Levelscript();
- lvl.Levelscript.Read(rommgr, Convert.ToInt32(segAddress));
+ case LevelscriptCommandTypes.AreaMusic:
+ {
+ tArea.BGMusic = clAreaMusic.GetMusicID(c);
+ break;
+ }
- // Erstelle Areas / Lade Einstellungen
- bool AreaOnFly = false;
- LevelArea tArea = null;
- var CurrentLevelScriptCommands = lvl.Levelscript.ToArray();
- var cmdsToRemove = new List();
- LevelArea firstArea = null;
- foreach (LevelscriptCommand c in CurrentLevelScriptCommands)
- {
- var switchExpr = c.CommandType;
- switch (switchExpr)
- {
- case LevelscriptCommandTypes.StartArea:
+ case LevelscriptCommandTypes.AreaMusicSimple:
+ {
+ tArea.BGMusic = clAreaMusicSimple.GetMusicID(c);
+ break;
+ }
+
+ case LevelscriptCommandTypes.Tarrain:
+ {
+ tArea.TerrainType = (Geolayout.TerrainTypes)clTerrian.GetTerrainType(c);
+ break;
+ }
+
+ case LevelscriptCommandTypes.Normal3DObject:
+ {
+ if (clNormal3DObject.GetSegBehaviorAddr(c) == (long)0x13003420)
{
- AreaOnFly = true;
- tArea = new SM64ELevelArea();
- if (firstArea is null)
- firstArea = tArea;
- tArea.AreaID = clStartArea.GetAreaID(c);
- tArea.GeolayoutOffset = clStartArea.GetSegGeolayoutAddr(c);
- tArea.Geolayout.Read(rommgr, Convert.ToInt32(tArea.GeolayoutOffset));
- break;
+ tArea.ScrollingTextures.Add(new ScrolTex.ManagedScrollingTexture(c));
+ }
+ else
+ {
+ tArea.Objects.Add(c);
}
- case LevelscriptCommandTypes.EndOfArea:
+ break;
+ }
+
+ case LevelscriptCommandTypes.ConnectedWarp:
+ {
+ if ((new[] { 0xF0, 0xF1 }).Contains(clWarp.GetWarpID(c)))
{
- tArea.Levelscript.Add(c);
- lvl.Levelscript.Remove(c);
- lvl.Areas.Add(tArea);
- AreaOnFly = false;
- break;
+ tArea.WarpsForGame.Add(c);
}
-
- case LevelscriptCommandTypes.AreaMusic:
- {
- tArea.BGMusic = clAreaMusic.GetMusicID(c);
- break;
- }
-
- case LevelscriptCommandTypes.AreaMusicSimple:
- {
- tArea.BGMusic = clAreaMusicSimple.GetMusicID(c);
- break;
- }
-
- case LevelscriptCommandTypes.Tarrain:
- {
- tArea.TerrainType = (Geolayout.TerrainTypes)clTerrian.GetTerrainType(c);
- break;
- }
-
- case LevelscriptCommandTypes.Normal3DObject:
- {
- if (clNormal3DObject.GetSegBehaviorAddr(c) == (long)0x13003420)
- {
- tArea.ScrollingTextures.Add(new ScrolTex.ManagedScrollingTexture(c));
- }
- else
- {
- tArea.Objects.Add(c);
- }
-
- break;
- }
-
- case LevelscriptCommandTypes.ConnectedWarp:
- {
- if ((new[] { 0xF0, 0xF1 }).Contains(clWarp.GetWarpID(c)))
- {
- tArea.WarpsForGame.Add(c);
- }
- else
- {
- tArea.Warps.Add(c);
- }
-
- break;
- }
-
- case LevelscriptCommandTypes.PaintingWarp:
- case LevelscriptCommandTypes.InstantWarp:
+ else
{
tArea.Warps.Add(c);
- break;
}
- case LevelscriptCommandTypes.LoadRomToRam:
- {
- byte bankID = clLoadRomToRam.GetSegmentedID(c);
- int startAddr = clLoadRomToRam.GetRomStart(c);
- int endAddr = clLoadRomToRam.GetRomEnd(c);
- switch (bankID)
- {
- case 0xA: // Background-Image
- {
- customBGStart = startAddr;
- customBGEnd = endAddr - 0x140;
- break;
- }
-
- case 0xE:
- {
- rommgr.SetSegBank(bankID, startAddr, endAddr);
- break;
- }
- }
-
- break;
- }
-
- case LevelscriptCommandTypes.ShowDialog:
- {
- if (AreaOnFly)
- {
- tArea.ShowMessage.Enabled = true;
- tArea.ShowMessage.DialogID = clShowDialog.GetDialogID(c);
- }
-
- break;
- }
-
- case LevelscriptCommandTypes.JumpBack:
- case LevelscriptCommandTypes.JumpToSegAddr:
- {
- if (tArea is not null)
- cmdsToRemove.Add(c);
- break;
- }
- }
-
- if (AreaOnFly && !cmdsToRemove.Contains(c))
- {
- lvl.Levelscript.Remove(c);
- tArea.Levelscript.Add(c);
- }
- }
-
- // Lösche alle Jump-Commands aus dem Levelscript
- foreach (LevelscriptCommand cmd in cmdsToRemove)
- {
- lvl.Levelscript.Remove(cmd);
- cmd.Close();
- }
-
- // Stelle frisches Levelscript wieder her
- lvl.CreateNewLevelscript();
-
- // Lösche alle Objekte und Warps aus dem Levelscript
- var lvlscrptidstoremove = new[] { LevelscriptCommandTypes.Normal3DObject, LevelscriptCommandTypes.ConnectedWarp, LevelscriptCommandTypes.PaintingWarp, LevelscriptCommandTypes.InstantWarp };
- foreach (var a in lvl.Areas)
- {
- foreach (var c in a.Levelscript.Where(n => lvlscrptidstoremove.Contains(n.CommandType)).ToArray())
- a.Levelscript.Remove(c);
- }
-
- // Lese Custom Background Image
- var fs = new FileStream(rommgr.RomFile, FileMode.Open, FileAccess.Read);
- var br2 = new BinaryReader(fs);
- lvl.Background.Enabled = false;
- foreach (LevelArea a in lvl.Areas)
- {
- var bgglcmd = a.Geolayout.Geolayoutscript.GetFirst(GeolayoutCommandTypes.Background);
- if (cgBackground.GetBackgroundPointer(bgglcmd) == 0)
- {
- a.Background.Type = AreaBGs.Color;
- a.Background.Color = cgBackground.GetRrgbaColor(bgglcmd);
- }
- else
- {
- a.Background.Type = AreaBGs.Levelbackground;
- lvl.Background.ID = (Geolayout.BackgroundIDs)cgBackground.GetBackgroundID(bgglcmd);
- lvl.Background.Enabled = true;
- }
- }
-
- if (lvl.Background.Enabled && lvl.Background.ID == Geolayout.BackgroundIDs.Custom)
- {
- fs.Position = customBGStart;
- lvl.Background.ReadImage(fs, customBGStart);
- }
-
- int bank0x19RomStart;
- int bank0x19RomEnd;
- BinaryReader brToUse;
- bank0x19RomStart = 0;
- bank0x19RomEnd = lvl.Bank0x19.Length;
- brToUse = new BinaryReader(lvl.Bank0x19.Data);
-
- // Lese Area-Modelle
- var modelBank = rommgr.GetSegBank(0xE);
- int curMdlStartOffset = modelBank.RomStart;
- for (int i = 0, loopTo = lvl.Areas.Count - 1; i <= loopTo; i++)
- {
- var a = lvl.Areas[i];
- int newEndOffset = GetModelEnd(fs, modelBank.RomStart, Convert.ToByte(i));
- a.Bank0x0EOffset = Convert.ToUInt32(curMdlStartOffset);
- rommgr.SetSegBank(0xE, Convert.ToInt32(a.Bank0x0EOffset), newEndOffset, a.AreaID);
- a.AreaModel.Collision = new Model.Collision.CollisionMap();
- a.AreaModel.Collision.FromStream(fs, modelBank.SegToRomAddr(a.CollisionPointer), new CollisionBasicConfig());
- a.AreaModel.Fast3DBuffer = new Model.Fast3D.Fast3DBuffer();
- a.AreaModel.FromStream(fs, modelBank.RomStart, 0xE000000, curMdlStartOffset, newEndOffset - curMdlStartOffset, a.Geolayout.Geopointers.ToArray(), a.CollisionPointer, rommgr.RomConfig.CollisionBaseConfig);
- a.AreaModel.Collision.SpecialBoxes.Clear();
- curMdlStartOffset = newEndOffset;
- }
-
- // Lese alle Box-Daten
- firstArea.SpecialBoxes.Clear();
- firstArea.SpecialBoxes.AddRange(SpecialBoxList.ReadTable(brToUse.BaseStream, SpecialBoxType.Water, bank0x19RomStart, bank0x19RomStart + 0x1810));
- firstArea.SpecialBoxes.AddRange(SpecialBoxList.ReadTable(brToUse.BaseStream, SpecialBoxType.ToxicHaze, bank0x19RomStart, bank0x19RomStart + 0x1850));
- firstArea.SpecialBoxes.AddRange(SpecialBoxList.ReadTable(brToUse.BaseStream, SpecialBoxType.Mist, bank0x19RomStart, bank0x19RomStart + 0x18A0));
- var areaWithBoxData = lvl.Areas.FirstOrDefault(n => n.AreaModel.Collision.SpecialBoxes.Any());
- if (areaWithBoxData is not null)
- {
- for (int i = 0, loopTo1 = firstArea.SpecialBoxes.Count - 1; i <= loopTo1; i++)
- {
- var boxdata = firstArea.AreaModel.Collision.SpecialBoxes.ElementAtOrDefault(i);
- if (boxdata is not null)
- {
- firstArea.SpecialBoxes[i].Y = boxdata.Y;
+ break;
+ }
+
+ case LevelscriptCommandTypes.PaintingWarp:
+ case LevelscriptCommandTypes.InstantWarp:
+ {
+ tArea.Warps.Add(c);
+ break;
+ }
+
+ case LevelscriptCommandTypes.LoadRomToRam:
+ {
+ byte bankID = clLoadRomToRam.GetSegmentedID(c);
+ int startAddr = clLoadRomToRam.GetRomStart(c);
+ int endAddr = clLoadRomToRam.GetRomEnd(c);
+ switch (bankID)
+ {
+ case 0xA: // Background-Image
+ {
+ customBGStart = startAddr;
+ customBGEnd = endAddr - 0x140;
+ break;
+ }
+
+ case 0xE:
+ {
+ rommgr.SetSegBank(bankID, startAddr, endAddr);
+ break;
+ }
+ }
+
+ break;
+ }
+
+ case LevelscriptCommandTypes.ShowDialog:
+ {
+ if (AreaOnFly)
+ {
+ tArea.ShowMessage.Enabled = true;
+ tArea.ShowMessage.DialogID = clShowDialog.GetDialogID(c);
+ }
+
+ break;
+ }
+
+ case LevelscriptCommandTypes.JumpBack:
+ case LevelscriptCommandTypes.JumpToSegAddr:
+ {
+ if (tArea is not null)
+ cmdsToRemove.Add(c);
+ break;
}
- }
}
- // One-Bank-0xE-System
- lvl.OneBank0xESystemEnabled = true;
-
- // Act Selector
- General.PatchClass.Open(fs);
- lvl.ActSelector = General.PatchClass.get_ActSelector_Enabled(LevelID);
-
- // Hardcoded Camera
- lvl.HardcodedCameraSettings = General.PatchClass.get_HardcodedCamera_Enabled(LevelID);
- fs.Close();
-
- // Object-Banks
- lvl.MyObjectBanks.Clear();
- lvl.MyObjectBanks.Add(0xC, null);
- lvl.MyObjectBanks.Add(0xD, null);
- lvl.MyObjectBanks.Add(0x9, null);
+ if (AreaOnFly && !cmdsToRemove.Contains(c))
+ {
+ lvl.Levelscript.Remove(c);
+ tArea.Levelscript.Add(c);
+ }
}
- public LevelSaveResult SaveLevel(Level lvl, RomManager rommgr, BinaryData output, ref uint curOff)
+ // Lösche alle Jump-Commands aus dem Levelscript
+ foreach (LevelscriptCommand cmd in cmdsToRemove)
{
- throw new NotImplementedException();
+ lvl.Levelscript.Remove(cmd);
+ cmd.Close();
}
- private static int GetModelEnd(Stream s, int startPos, byte areaIndex)
+ // Stelle frisches Levelscript wieder her
+ lvl.CreateNewLevelscript();
+
+ // Lösche alle Objekte und Warps aus dem Levelscript
+ var lvlscrptidstoremove = new[] { LevelscriptCommandTypes.Normal3DObject, LevelscriptCommandTypes.ConnectedWarp, LevelscriptCommandTypes.PaintingWarp, LevelscriptCommandTypes.InstantWarp };
+ foreach (var a in lvl.Areas)
{
- byte cb = 0;
- int Ausnahmen = 0;
- s.Position = startPos;
- bool ende = false;
+ foreach (var c in a.Levelscript.Where(n => lvlscrptidstoremove.Contains(n.CommandType)).ToArray())
+ a.Levelscript.Remove(c);
+ }
- do
+ // Lese Custom Background Image
+ var fs = new FileStream(rommgr.RomFile, FileMode.Open, FileAccess.Read);
+ var br2 = new BinaryReader(fs);
+ lvl.Background.Enabled = false;
+ foreach (LevelArea a in lvl.Areas)
+ {
+ var bgglcmd = a.Geolayout.Geolayoutscript.GetFirst(GeolayoutCommandTypes.Background);
+ if (cgBackground.GetBackgroundPointer(bgglcmd) == 0)
{
- cb = Convert.ToByte(s.ReadByte());
- if (s.Position >= s.Length - 1)
- return Convert.ToInt32(s.Length);
- else if (cb == 0x1)
+ a.Background.Type = AreaBGs.Color;
+ a.Background.Color = cgBackground.GetRrgbaColor(bgglcmd);
+ }
+ else
+ {
+ a.Background.Type = AreaBGs.Levelbackground;
+ lvl.Background.ID = (Geolayout.BackgroundIDs)cgBackground.GetBackgroundID(bgglcmd);
+ lvl.Background.Enabled = true;
+ }
+ }
+
+ if (lvl.Background.Enabled && lvl.Background.ID == Geolayout.BackgroundIDs.Custom)
+ {
+ fs.Position = customBGStart;
+ lvl.Background.ReadImage(fs, customBGStart);
+ }
+
+ int bank0x19RomStart;
+ int bank0x19RomEnd;
+ BinaryReader brToUse;
+ bank0x19RomStart = 0;
+ bank0x19RomEnd = lvl.Bank0x19.Length;
+ brToUse = new BinaryReader(lvl.Bank0x19.Data);
+
+ // Lese Area-Modelle
+ var modelBank = rommgr.GetSegBank(0xE);
+ int curMdlStartOffset = modelBank.RomStart;
+ for (int i = 0, loopTo = lvl.Areas.Count - 1; i <= loopTo; i++)
+ {
+ var a = lvl.Areas[i];
+ int newEndOffset = GetModelEnd(fs, modelBank.RomStart, Convert.ToByte(i));
+ a.Bank0x0EOffset = Convert.ToUInt32(curMdlStartOffset);
+ rommgr.SetSegBank(0xE, Convert.ToInt32(a.Bank0x0EOffset), newEndOffset, a.AreaID);
+ a.AreaModel.Collision = new Model.Collision.CollisionMap();
+ a.AreaModel.Collision.FromStream(fs, modelBank.SegToRomAddr(a.CollisionPointer), new CollisionBasicConfig());
+ a.AreaModel.Fast3DBuffer = new Model.Fast3D.Fast3DBuffer();
+ a.AreaModel.FromStream(fs, modelBank.RomStart, 0xE000000, curMdlStartOffset, newEndOffset - curMdlStartOffset, a.Geolayout.Geopointers.ToArray(), a.CollisionPointer, rommgr.RomConfig.CollisionBaseConfig);
+ a.AreaModel.Collision.SpecialBoxes.Clear();
+ curMdlStartOffset = newEndOffset;
+ }
+
+ // Lese alle Box-Daten
+ firstArea.SpecialBoxes.Clear();
+ firstArea.SpecialBoxes.AddRange(SpecialBoxList.ReadTable(brToUse.BaseStream, SpecialBoxType.Water, bank0x19RomStart, bank0x19RomStart + 0x1810));
+ firstArea.SpecialBoxes.AddRange(SpecialBoxList.ReadTable(brToUse.BaseStream, SpecialBoxType.ToxicHaze, bank0x19RomStart, bank0x19RomStart + 0x1850));
+ firstArea.SpecialBoxes.AddRange(SpecialBoxList.ReadTable(brToUse.BaseStream, SpecialBoxType.Mist, bank0x19RomStart, bank0x19RomStart + 0x18A0));
+ var areaWithBoxData = lvl.Areas.FirstOrDefault(n => n.AreaModel.Collision.SpecialBoxes.Any());
+ if (areaWithBoxData is not null)
+ {
+ for (int i = 0, loopTo1 = firstArea.SpecialBoxes.Count - 1; i <= loopTo1; i++)
+ {
+ var boxdata = firstArea.AreaModel.Collision.SpecialBoxes.ElementAtOrDefault(i);
+ if (boxdata is not null)
{
- var haveFound = true;
- s.Position -= 1;
-
- for (int i = 1; i <= 0x100; i++)
- {
- if (haveFound && s.ReadByte() != 0x1)
- haveFound = false;
- }
-
- if (haveFound)
- {
- if (Ausnahmen == areaIndex)
- ende = true;
- else
- Ausnahmen += 1;
- }
+ firstArea.SpecialBoxes[i].Y = boxdata.Y;
}
}
- while (!ende);
-
- return Convert.ToInt32(s.Position);
}
+
+ // One-Bank-0xE-System
+ lvl.OneBank0xESystemEnabled = true;
+
+ // Act Selector
+ General.PatchClass.Open(fs);
+ lvl.ActSelector = General.PatchClass.get_ActSelector_Enabled(LevelID);
+
+ // Hardcoded Camera
+ lvl.HardcodedCameraSettings = General.PatchClass.get_HardcodedCamera_Enabled(LevelID);
+ fs.Close();
+
+ // Object-Banks
+ lvl.MyObjectBanks.Clear();
+ lvl.MyObjectBanks.Add(0xC, null);
+ lvl.MyObjectBanks.Add(0xD, null);
+ lvl.MyObjectBanks.Add(0x9, null);
+ }
+
+ public LevelSaveResult SaveLevel(Level lvl, RomManager rommgr, BinaryData output, ref uint curOff)
+ {
+ throw new NotImplementedException();
+ }
+
+ private static int GetModelEnd(Stream s, int startPos, byte areaIndex)
+ {
+ byte cb = 0;
+ int Ausnahmen = 0;
+ s.Position = startPos;
+ bool ende = false;
+
+ do
+ {
+ cb = Convert.ToByte(s.ReadByte());
+ if (s.Position >= s.Length - 1)
+ return Convert.ToInt32(s.Length);
+ else if (cb == 0x1)
+ {
+ var haveFound = true;
+ s.Position -= 1;
+
+ for (int i = 1; i <= 0x100; i++)
+ {
+ if (haveFound && s.ReadByte() != 0x1)
+ haveFound = false;
+ }
+
+ if (haveFound)
+ {
+ if (Ausnahmen == areaIndex)
+ ende = true;
+ else
+ Ausnahmen += 1;
+ }
+ }
+ }
+ while (!ende);
+
+ return Convert.ToInt32(s.Position);
}
}
\ No newline at end of file
diff --git a/SM64Lib/Level/Script/Levelscript.cs b/SM64Lib/Level/Script/Levelscript.cs
index f4cf148..ad42085 100644
--- a/SM64Lib/Level/Script/Levelscript.cs
+++ b/SM64Lib/Level/Script/Levelscript.cs
@@ -1,203 +1,201 @@
-using System;
-using System.Collections.Generic;
-using global::System.IO;
-using System.Linq;
-using Microsoft.VisualBasic.CompilerServices;
-using global::SM64Lib.Data;
+using global::SM64Lib.Data;
using global::SM64Lib.Levels.Script.Commands;
using global::SM64Lib.SegmentedBanking;
+using global::System.IO;
+using System;
+using System.Collections.Generic;
+using System.Linq;
-namespace SM64Lib.Levels.Script
+namespace SM64Lib.Levels.Script;
+
+public class Levelscript : LevelscriptCommandCollection
{
- public class Levelscript : LevelscriptCommandCollection
+ public new void Close()
{
- public new void Close()
- {
- for (int i = 0, loopTo = Count - 1; i <= loopTo; i++)
- this[i].Close();
- Clear();
- }
+ for (int i = 0, loopTo = Count - 1; i <= loopTo; i++)
+ this[i].Close();
+ Clear();
+ }
- public Levelscript()
- {
- }
+ public Levelscript()
+ {
+ }
- public void Read(RomManager rommgr, int scriptStartInBank, LevelscriptCommandTypes EndAtCommands = LevelscriptCommandTypes.EndOfLevel, Dictionary segDic = null, bool storeToRommgr = true)
+ public void Read(RomManager rommgr, int scriptStartInBank, LevelscriptCommandTypes EndAtCommands = LevelscriptCommandTypes.EndOfLevel, Dictionary segDic = null, bool storeToRommgr = true)
+ {
+ Stream s = null;
+ BinaryReader br = null;
+ FileStream fs = null;
+ BinaryReader brfs = null;
+ var tb = new List();
+ LevelscriptCommandTypes cb = default;
+ bool enableDo = true;
+ SegmentedBank curSegBank = null;
+ var dicBankBinaryReaders = new Dictionary();
+ var brStack = new Stack();
+ var sStack = new Stack();
+ var jumpStack = new Stack();
+ var segStack = new Stack();
+ Close();
+ Read_GetStream(ref curSegBank, ref s, ref br, ref fs, ref brfs, rommgr, scriptStartInBank, dicBankBinaryReaders, segDic);
+ while (enableDo)
{
- Stream s = null;
- BinaryReader br = null;
- FileStream fs = null;
- BinaryReader brfs = null;
- var tb = new List();
- LevelscriptCommandTypes cb = default;
- bool enableDo = true;
- SegmentedBank curSegBank = null;
- var dicBankBinaryReaders = new Dictionary();
- var brStack = new Stack();
- var sStack = new Stack();
- var jumpStack = new Stack();
- var segStack = new Stack();
- Close();
- Read_GetStream(ref curSegBank, ref s, ref br, ref fs, ref brfs, rommgr, scriptStartInBank, dicBankBinaryReaders, segDic);
- while (enableDo)
+ try
{
- try
+ cb = (LevelscriptCommandTypes)br.ReadByte();
+ byte lenth = 0;
+ lenth = br.ReadByte();
+ if (lenth == 0)
+ lenth = 4;
+ tb.Add((byte)cb);
+ tb.Add(lenth);
+ for (int i = 3, loopTo = lenth; i <= loopTo; i++)
+ tb.Add(br.ReadByte());
+ var curLvlCmd = new LevelscriptCommand(tb.ToArray());
+ int bankOffset = (int)(br.BaseStream.Position - lenth);
+ curLvlCmd.RomAddress = (int)(curSegBank?.RomStart + bankOffset);
+ curLvlCmd.BankAddress = (int)(curSegBank?.BankAddress + bankOffset);
+ Add(curLvlCmd);
+ tb.Clear();
+ var switchExpr = curLvlCmd.CommandType;
+ switch (switchExpr)
{
- cb = (LevelscriptCommandTypes)br.ReadByte();
- byte lenth = 0;
- lenth = br.ReadByte();
- if (lenth == 0)
- lenth = 4;
- tb.Add((byte)cb);
- tb.Add(lenth);
- for (int i = 3, loopTo = lenth; i <= loopTo; i++)
- tb.Add(br.ReadByte());
- var curLvlCmd = new LevelscriptCommand(tb.ToArray());
- int bankOffset = (int)(br.BaseStream.Position - lenth);
- curLvlCmd.RomAddress = (int)(curSegBank?.RomStart + bankOffset);
- curLvlCmd.BankAddress = (int)(curSegBank?.BankAddress + bankOffset);
- Add(curLvlCmd);
- tb.Clear();
- var switchExpr = curLvlCmd.CommandType;
- switch (switchExpr)
- {
- case LevelscriptCommandTypes.LoadRomToRam:
- case LevelscriptCommandTypes.x1A:
- case LevelscriptCommandTypes.x18:
- case LevelscriptCommandTypes.x00:
- case LevelscriptCommandTypes.x01:
+ case LevelscriptCommandTypes.LoadRomToRam:
+ case LevelscriptCommandTypes.x1A:
+ case LevelscriptCommandTypes.x18:
+ case LevelscriptCommandTypes.x00:
+ case LevelscriptCommandTypes.x01:
+ {
+ var bank = new SegmentedBank()
{
- var bank = new SegmentedBank()
+ BankID = clLoadRomToRam.GetSegmentedID(curLvlCmd),
+ RomStart = clLoadRomToRam.GetRomStart(curLvlCmd),
+ RomEnd = clLoadRomToRam.GetRomEnd(curLvlCmd)
+ };
+ if (curLvlCmd.CommandType == LevelscriptCommandTypes.x1A)
+ bank.MakeAsMIO0();
+ if (storeToRommgr)
+ rommgr?.SetSegBank(bank);
+ if (segDic is not null)
+ {
+ if (segDic.ContainsKey(bank.BankID))
{
- BankID = clLoadRomToRam.GetSegmentedID(curLvlCmd),
- RomStart = clLoadRomToRam.GetRomStart(curLvlCmd),
- RomEnd = clLoadRomToRam.GetRomEnd(curLvlCmd)
- };
- if (curLvlCmd.CommandType == LevelscriptCommandTypes.x1A)
- bank.MakeAsMIO0();
- if (storeToRommgr)
- rommgr?.SetSegBank(bank);
- if (segDic is not null)
- {
- if (segDic.ContainsKey(bank.BankID))
- {
- segDic[bank.BankID] = bank;
- }
- else
- {
- segDic.Add(bank.BankID, bank);
- }
+ segDic[bank.BankID] = bank;
}
-
- if (new[] { LevelscriptCommandTypes.x00, LevelscriptCommandTypes.x01 }.Contains(curLvlCmd.CommandType))
+ else
{
- int SegAddr = clLoadRomToRam.GetSegmentedAddressToJump(curLvlCmd);
- JumpTo(jumpStack, sStack, brStack, segStack, ref curSegBank, ref s, ref br, ref fs, ref brfs, rommgr, SegAddr, dicBankBinaryReaders, segDic);
+ segDic.Add(bank.BankID, bank);
}
-
- break;
}
- case LevelscriptCommandTypes.JumpToSegAddr:
+ if (new[] { LevelscriptCommandTypes.x00, LevelscriptCommandTypes.x01 }.Contains(curLvlCmd.CommandType))
{
- int SegAddr = clJumpToSegAddr.GetSegJumpAddr(curLvlCmd);
- if (new[] { 0x19, 0xE }.Contains(SegAddr >> 24))
- {
- JumpTo(jumpStack, sStack, brStack, segStack, ref curSegBank, ref s, ref br, ref fs, ref brfs, rommgr, SegAddr, dicBankBinaryReaders, segDic);
- }
-
- break;
+ int SegAddr = clLoadRomToRam.GetSegmentedAddressToJump(curLvlCmd);
+ JumpTo(jumpStack, sStack, brStack, segStack, ref curSegBank, ref s, ref br, ref fs, ref brfs, rommgr, SegAddr, dicBankBinaryReaders, segDic);
}
- case LevelscriptCommandTypes.JumpBack:
- case (LevelscriptCommandTypes)0xA: // Jump back
- {
- curSegBank = segStack.Pop();
- s = sStack.Pop();
- br = brStack.Pop();
- s.Position = jumpStack.Pop();
- break;
- }
- }
+ break;
+ }
- if (curLvlCmd.CommandType == LevelscriptCommandTypes.EndOfLevel || curLvlCmd.CommandType == EndAtCommands)
- {
- enableDo = false;
- }
+ case LevelscriptCommandTypes.JumpToSegAddr:
+ {
+ int SegAddr = clJumpToSegAddr.GetSegJumpAddr(curLvlCmd);
+ if (new[] { 0x19, 0xE }.Contains(SegAddr >> 24))
+ {
+ JumpTo(jumpStack, sStack, brStack, segStack, ref curSegBank, ref s, ref br, ref fs, ref brfs, rommgr, SegAddr, dicBankBinaryReaders, segDic);
+ }
+
+ break;
+ }
+
+ case LevelscriptCommandTypes.JumpBack:
+ case (LevelscriptCommandTypes)0xA: // Jump back
+ {
+ curSegBank = segStack.Pop();
+ s = sStack.Pop();
+ br = brStack.Pop();
+ s.Position = jumpStack.Pop();
+ break;
+ }
}
- catch (Exception)
+
+ if (curLvlCmd.CommandType == LevelscriptCommandTypes.EndOfLevel || curLvlCmd.CommandType == EndAtCommands)
{
enableDo = false;
}
}
-
- // If s Is fs Then s?.Close()
- fs?.Close();
- }
-
- private void JumpTo(Stack jumpStack, Stack sStack, Stack brStack, Stack segStack, ref SegmentedBank curSegBank, ref Stream s, ref BinaryReader br, ref FileStream fs, ref BinaryReader brfs, RomManager rommgr, int scriptStartInBank, Dictionary