From ec5f8c803e58fdf312f7b2fcd7c4ea9cc38f1795 Mon Sep 17 00:00:00 2001 From: korenkonder Date: Thu, 10 Mar 2022 21:29:09 +0300 Subject: [PATCH] Release v0.4.10.11 A3DA, DIVAFILE, MotHead --- KKdBaseLib/DCC.cs | 99 ------------ KKdBaseLib/KKdBaseLib.csproj | 6 +- KKdMainLib/A3DA.cs | 6 +- KKdMainLib/DIVAFILE.cs | 66 +++++++- KKdMainLib/DataBank.cs | 6 +- KKdMainLib/Extensions.cs | 67 +++++++- KKdMainLib/KKdMainLib.csproj | 4 +- KKdMainLib/MotHead.cs | 243 ++++++++++++++++++----------- PD_Tool/Program.cs | 2 + PD_Tool/Properties/AssemblyInfo.cs | 4 +- PD_Tool/classes/A3D.cs | 27 ++-- PD_Tool/classes/DB.cs | 4 +- PD_Tool/classes/DIVAFILE.cs | 4 +- PD_Tool/classes/MHD.cs | 6 +- 14 files changed, 315 insertions(+), 229 deletions(-) delete mode 100644 KKdBaseLib/DCC.cs diff --git a/KKdBaseLib/DCC.cs b/KKdBaseLib/DCC.cs deleted file mode 100644 index e988778..0000000 --- a/KKdBaseLib/DCC.cs +++ /dev/null @@ -1,99 +0,0 @@ -//Original research by Samyuu - -namespace KKdBaseLib -{ - public static class DCC //Databank Checksum Calculator - { - private static readonly ushort[] ChecksumLookupTable = { - 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, - 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, - 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, - 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, - 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, - 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, - 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, - 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, - 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, - 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, - 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, - 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, - 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, - 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, - 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, - 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, - 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, - 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, - 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, - 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, - 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, - 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, - 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, - 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, - 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, - 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, - 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, - 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, - 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, - 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, - 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, - 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0, - }; - - public static ushort CalculateChecksum(byte[] data, - int offset = 0, ushort seed = 0xFFFF) - { - int length = data.Length; - ushort result = seed; - for (int i = offset; i < length; i++) - result = (ushort)(ChecksumLookupTable[(result >> 8) ^ data[i]] ^ (result << 8)); - return result; - } - - public static uint CalculateChecksumU32(byte[] data, - int offset = 0, uint seed = 0xFFFFFFFF) - { - int length = data.Length; - uint result = seed; - for (int i = offset; i < length; i++) - result = ChecksumLookupTable[(byte)(result >> 8) ^ data[i]] ^ (result << 8); - return result; - } - - public static ulong CalculateChecksumU64(byte[] data, - int offset = 0, ulong seed = 0xFFFFFFFFFFFFFFFF) - { - int length = data.Length; - ulong result = seed; - for (int i = offset; i < length; i++) - result = ChecksumLookupTable[(byte)(result >> 8) ^ data[i]] ^ (result << 8); - return result; - } - - public static unsafe ushort CalculateChecksum(byte* data, - int length, int offset = 0, ushort seed = 0xFFFF) - { - ushort result = seed; - for (int i = offset; i < length; i++) - result = (ushort)(ChecksumLookupTable[(result >> 8) ^ data[i]] ^ (result << 8)); - return result; - } - - public static unsafe uint CalculateChecksumU32(byte* data, - int length, int offset = 0, uint seed = 0xFFFFFFFF) - { - uint result = seed; - for (int i = offset; i < length; i++) - result = ChecksumLookupTable[(byte)(result >> 8) ^ data[i]] ^ (result << 8); - return result; - } - - public static unsafe ulong CalculateChecksumU64(byte* data, - int length, int offset = 0, ulong seed = 0xFFFFFFFFFFFFFFFF) - { - ulong result = seed; - for (int i = offset; i < length; i++) - result = ChecksumLookupTable[(byte)(result >> 8) ^ data[i]] ^ (result << 8); - return result; - } - } -} diff --git a/KKdBaseLib/KKdBaseLib.csproj b/KKdBaseLib/KKdBaseLib.csproj index 1ce0590..6dbe141 100644 --- a/KKdBaseLib/KKdBaseLib.csproj +++ b/KKdBaseLib/KKdBaseLib.csproj @@ -4,14 +4,14 @@ korenkonder - korenkonder (C) 2019-2021 + korenkonder (C) 2019-2022 A base library - 0.4.10.8 + 0.4.10.11 KKdBaseLib KKdBaseLib net461 KKdBaseLib - 0.4.10.8 + 0.4.10.11 AnyCPU diff --git a/KKdMainLib/A3DA.cs b/KKdMainLib/A3DA.cs index 74d18bd..e37734b 100644 --- a/KKdMainLib/A3DA.cs +++ b/KKdMainLib/A3DA.cs @@ -14,6 +14,8 @@ namespace KKdMainLib public Data Data; public A3DAHeader Head; + public static int Rounding = 9; + private Stream s; private bool a3dc; private int i, i0, i1; @@ -1253,9 +1255,9 @@ namespace KKdMainLib private void W(string Data, ulong val) => W(Data, val.ToS()); private void W(string Data, float val) => - W(Data, val.ToS(9)); + W(Data, val.ToS(Rounding)); private void W(string Data, double val) => - W(Data, val.ToS(9)); + W(Data, val.ToS(Rounding)); private void W(string Data, string val) { if (val != null) s.W(Data + "=" + val + "\n"); } diff --git a/KKdMainLib/DIVAFILE.cs b/KKdMainLib/DIVAFILE.cs index f31ab5e..434e6ad 100644 --- a/KKdMainLib/DIVAFILE.cs +++ b/KKdMainLib/DIVAFILE.cs @@ -10,13 +10,13 @@ namespace KKdMainLib { private static readonly byte[] Key = "file access deny".ToASCII(); - public static void Decrypt(this string file) + public static void Decrypt(string file) { int streamLength, fileLength; byte[] encrypted, decrypted; using (Stream _IO = File.OpenReader(file)) { - if (_IO.RI64() != 0x454C494641564944) return; + if (_IO.RU64() != 0x454C494641564944u) return; streamLength = _IO.RI32(); fileLength = _IO.RI32(); @@ -36,8 +36,8 @@ namespace KKdMainLib using (Stream _IO = File.OpenWriter(file, fileLength)) _IO.W(decrypted, fileLength < streamLength ? fileLength : streamLength); } - - public static void Encrypt(this string file) + + public static void Encrypt(string file) { byte[] data; using (Stream _IO = File.OpenReader(file)) @@ -60,11 +60,67 @@ namespace KKdMainLib using (Stream _IO = File.OpenWriter(file, dataAlign.Length)) { - _IO.W(0x454C494641564944); + _IO.W(0x454C494641564944u); _IO.W(fileLength); _IO.W(fileLengthOrigin); _IO.W(encrypted); } } + + public static byte[] Decrypt(byte[] data) + { + int streamLength, fileLength; + byte[] encrypted, decrypted; + using (Stream _IO = File.OpenReader(data)) + { + if (_IO.RU64() != 0x454C494641564944u) return data; + + streamLength = _IO.RI32(); + fileLength = _IO.RI32(); + encrypted = _IO.RBy(streamLength); + decrypted = new byte[streamLength]; + } + + using (AesManaged crypto = new AesManaged()) + { + crypto.Key = Key; crypto.IV = new byte[16]; + crypto.Mode = CipherMode.ECB; crypto.Padding = PaddingMode.Zeros; + using CryptoStream cryptoData = new CryptoStream(new MSIO.MemoryStream(encrypted), + crypto.CreateDecryptor(crypto.Key, crypto.IV), CryptoStreamMode.Read); + cryptoData.Read(decrypted, 0, streamLength); + } + + data = new byte[fileLength]; + Array.Copy(decrypted, data, fileLength < streamLength ? fileLength : streamLength); + return data; + } + + public static byte[] Encrypt(byte[] data) + { + int fileLengthOrigin = data.Length; + int fileLength = fileLengthOrigin.A(16); + byte[] dataAlign = new byte[fileLength]; + Array.Copy(data, dataAlign, data.Length); + data = null; + byte[] encrypted = new byte[fileLength]; + using (AesManaged crypto = new AesManaged()) + { + crypto.Key = Key; crypto.IV = new byte[16]; + crypto.Mode = CipherMode.ECB; crypto.Padding = PaddingMode.Zeros; + using CryptoStream cryptoData = new CryptoStream(new MSIO.MemoryStream(dataAlign), + crypto.CreateEncryptor(crypto.Key, crypto.IV), CryptoStreamMode.Read); + cryptoData.Read(encrypted, 0, fileLength); + } + + using (Stream _IO = File.OpenWriter()) + { + _IO.W(0x454C494641564944u); + _IO.W(fileLength); + _IO.W(fileLengthOrigin); + _IO.W(encrypted); + data = _IO.ToArray(); + } + return data; + } } } diff --git a/KKdMainLib/DataBank.cs b/KKdMainLib/DataBank.cs index 562d342..aeb7081 100644 --- a/KKdMainLib/DataBank.cs +++ b/KKdMainLib/DataBank.cs @@ -83,15 +83,15 @@ namespace KKdMainLib return s.ToArray(true); } - public void DBWriter(string file, uint num2) + public void DBWriter(string file, uint timestamp) { if (!Success) return; byte[] data = DBWriter(file); if (data == null) return; - ushort num = DCC.CalculateChecksum(data); - File.WriteAllBytes(file + "_" + num + "_" + num2 + ".dat", data); + ushort hash = data.HashCRC16_CCITT(); + File.WriteAllBytes(file + "_" + hash + "_" + timestamp + ".dat", data); } public void MsgPackReader(string file, bool json) diff --git a/KKdMainLib/Extensions.cs b/KKdMainLib/Extensions.cs index 8ff696d..8bf7560 100644 --- a/KKdMainLib/Extensions.cs +++ b/KKdMainLib/Extensions.cs @@ -100,13 +100,14 @@ namespace KKdMainLib public static Struct RSt(this byte[] data) { if (data == null || data.Length < 1) return default; + data = DIVAFILE.Decrypt(data); Struct @struct; using (Stream stream = File.OpenReader(data)) @struct = stream.RSt(stream.ReadHeader(false)); return @struct; } - public static Struct RSt(this Stream stream, Header header) + private static Struct RSt(this Stream stream, Header header) { uint l = header.UseSectionSize ? header.SectionSize : header.DataSize; Struct @struct = new Struct { Header = header, DataOffset = @@ -248,25 +249,31 @@ namespace KKdMainLib } public static class HashExt - { + { public static uint HashFNV1a64(this byte[] array) => array.HashMurmurHash(array.Length); - public static ulong HashFNV1a64(this byte[] array, int length) // 0x1403B04D0 in SBZV_7.10; FNV 1a 64-bit + // FNV 1a 64-bit Modified + // 0x1403B04D0 in SBZV_7.10 + public static ulong HashFNV1a64m(this byte[] array, int length) { int i = 0; ulong hash = 0xCBF29CE484222325; while (i < length) { hash = 0x100000001B3 * (hash ^ (ulong)array[i]); i++; } - return (hash >> 32) ^ hash; - } - + return (hash >> 32) ^ hash; // Actual Modification + } + public static uint HashMurmurHash(this byte[] array, uint salt = 0, bool alreadyUpper = false, bool bigEndian = false) => array.HashMurmurHash(array.Length, salt, alreadyUpper, bigEndian); + // MurmurHash + // 0x814D7A9C in PCSB00554 + // 0x8134C304 in PCSB01007 + // 0x0069CEA4 in NPEB02013 public static uint HashMurmurHash(this byte[] array, int length, uint salt = 0, - bool alreadyUpper = false, bool bigEndian = false) // 0x814D7A9C in PCSB00554; MurmurHash + bool alreadyUpper = false, bool bigEndian = false) { uint a, b, hash; int i; @@ -360,5 +367,51 @@ namespace KKdMainLib hash ^= hash >> 17; return hash; } + + private static readonly ushort[] CRC16_CCITT_Table = { + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, + 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, + 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, + 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, + 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, + 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, + 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, + 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, + 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, + 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, + 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, + 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, + 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, + 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, + 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, + 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, + 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, + 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, + 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, + 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, + 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, + 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, + 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0, + }; + + // CRC16-CCITT + // 0x140011A90 in SBZV_7.10 + public static ushort HashCRC16_CCITT(this byte[] data, int offset = 0, ushort seed = 0xFFFF) + { + int length = data.Length; + ushort hash = seed; + for (int i = offset; i < length; i++) + hash = (ushort)(CRC16_CCITT_Table[(hash >> 8) ^ data[i]] ^ (hash << 8)); + return hash; + } } } diff --git a/KKdMainLib/KKdMainLib.csproj b/KKdMainLib/KKdMainLib.csproj index 6a3ffad..8a42b26 100644 --- a/KKdMainLib/KKdMainLib.csproj +++ b/KKdMainLib/KKdMainLib.csproj @@ -6,12 +6,12 @@ korenkonder (C) 2018-2022 A simple library for working with Project Diva AC/DT/F/AFT/F2/X/XHD/FT/VRFL/M39 files - 0.4.10.10 + 0.4.10.11 KKdMainLib KKdMainLib net461 KKdMainLib - 0.4.10.10 + 0.4.10.11 AnyCPU diff --git a/KKdMainLib/MotHead.cs b/KKdMainLib/MotHead.cs index 2f03b2a..de392a5 100644 --- a/KKdMainLib/MotHead.cs +++ b/KKdMainLib/MotHead.cs @@ -1,4 +1,5 @@ using KKdBaseLib; +using KKdBaseLib.F2; using KKdMainLib.IO; namespace KKdMainLib @@ -10,49 +11,96 @@ namespace KKdMainLib public HeaderData Header; - public void MotHeadReader(string file) + public void MotHeadReader(string file, string ext) { - s = File.OpenReader(file + ".bin"); - s.RI32(); + bool f2; + bool x = false; + int x_offset = 0; + s = File.OpenReader(file + ext); Header = new HeaderData(); + int signature = s.RI32(); + if (signature == 0x484D4D4D) + { + x_offset = (int)s.ReadHeader(true).Length; + Header.MotionSetID = s.RU32(); + int mot_count = s.RI32(); + int mot_hashes_offset = s.RI32(); + Header.SubHeaderOffset = s.RI32(); + if (Header.SubHeaderOffset == 0) + { + if (mot_hashes_offset != 0) mot_hashes_offset += x_offset; + s.IsX = true; + x = true; + Header.SubHeaderOffset = (int)s.RIX(); + if (Header.SubHeaderOffset != 0) Header.SubHeaderOffset += x_offset; + } - int offset = s.RI32(); - if (offset < 0x10) goto RETURN; - s.O = offset; - s.P = 0; + if (Header.SubHeaderOffset < 0x20) goto RETURN; - Header. MotionSetID = s.RI32(); - Header.FirstMotionID = s.RI32(); - Header. LastMotionID = s.RI32(); - Header.SubHeaderOffset = s.RI32(); + s.P = mot_hashes_offset; + Header.Data = new HeaderData.Sub[mot_count]; + for (i = 0; i < Header.Data.Length; i++) Header.Data[i].MotionID = s.RU32(); - if (Header.SubHeaderOffset < 0x10) goto RETURN; - i0 = Header.LastMotionID - Header.FirstMotionID; - if (i0 < 0) goto RETURN; + s.P = Header.SubHeaderOffset; + f2 = true; + } + else + { + int offset = s.RI32(); + if (offset < 0x10) goto RETURN; + s.O = offset; + s.P = 0; + + Header.MotionSetID = s.RU32(); + Header.FirstMotionID = s.RU32(); + Header.LastMotionID = s.RU32(); + Header.SubHeaderOffset = (int)s.RIX(); + + if (Header.SubHeaderOffset < 0x10) goto RETURN; + i0 = (int)(Header.LastMotionID - Header.FirstMotionID); + if (i0 < 0) goto RETURN; + + s.P = Header.SubHeaderOffset; + Header.Data = new HeaderData.Sub[++i0]; + f2 = false; + } + + for (i = 0; i < Header.Data.Length; i++) + { + if (x) s.A(0x08); + Header.Data[i].Offset = (int)s.RIX(); + if (x && Header.Data[i].Offset != 0) Header.Data[i].Offset += x_offset; + } - s.P = Header.SubHeaderOffset; - Header.Data = new HeaderData.Sub[++i0]; - for (i = 0; i < Header.Data.Length; i++) Header.Data[i].Offset = s.RI32(); for (i = 0; i < Header.Data.Length; i++) { if (Header.Data[i].Offset < 0x10) continue; s.P = Header.Data[i].Offset; - Header.Data[i].MotionID = Header.FirstMotionID + i; + if (!f2) + Header.Data[i].MotionID = Header.FirstMotionID + (uint)i; Header.Data[i].Field00 = s.RI32(); - Header.Data[i].Field04 = s.RI32(); - Header.Data[i].Field08 = s.RI32(); - Header.Data[i].Field0C = s.RI32(); + if (!x) + { + Header.Data[i].Field04 = s.RI32(); + Header.Data[i].Field08 = s.RI32(); + Header.Data[i].Field0C = s.RI32(); + } Header.Data[i].Field10 = s.RU16(); Header.Data[i].Field12 = s.RU16(); - Header.Data[i].Offset2 = s.RI32(); - Header.Data[i].DataHeaderOffset = s.RI32(); + if (x) s.A(0x08); + Header.Data[i].Offset2 = (int)s.RIX(); + if (x && Header.Data[i].Offset2 != 0) Header.Data[i].Offset2 += x_offset; + if (x) s.A(0x08); + Header.Data[i].DataHeaderOffset = (int)s.RIX(); + if (x && Header.Data[i].DataHeaderOffset != 0) + Header.Data[i].DataHeaderOffset += x_offset; if (Header.Data[i].DataHeaderOffset < 0x10) goto RETURN; s.P = Header.Data[i].DataHeaderOffset; i0 = 0; - while (s.RI32() != -1) { s.RI32(); s.RI32(); i0++; } + while (s.RI32() != -1) { s.RI32(); if (x) s.A(0x08); s.RIX(); i0++; } s.P = Header.Data[i].DataHeaderOffset; Header.Data[i].Array = new HeaderData.Sub.Data[i0]; @@ -60,7 +108,10 @@ namespace KKdMainLib { Header.Data[i].Array[i0].Type = (Type)s.RI32(); Header.Data[i].Array[i0].Frame = s.RI32(); - Header.Data[i].Array[i0].Offset = s.RI32(); + if (x) s.A(0x08); + Header.Data[i].Array[i0].Offset = (int)s.RIX(); + if (x && Header.Data[i].Array[i0].Offset != 0) + Header.Data[i].Array[i0].Offset += x_offset; } } @@ -77,7 +128,10 @@ namespace KKdMainLib for (i0 = 0; i0 < Header.Data[i].Array2.Length; i0++) { Header.Data[i].Array2[i0].Type = s.RI32(); - Header.Data[i].Array2[i0].Offset = s.RI32(); + if (x) s.A(0x08); + Header.Data[i].Array2[i0].Offset = (int)s.RIX(); + if (x && Header.Data[i].Array2[i0].Offset != 0) + Header.Data[i].Array2[i0].Offset += x_offset; } for (i0 = 0; i0 < Header.Data[i].Array2.Length; i0++) @@ -131,7 +185,7 @@ RETURN: s.O = 0x20; s.P = 0; s.W(0); - for (int I = Header.LastMotionID - Header.FirstMotionID; I > -1; I--) + for (int I = (int)(Header.LastMotionID - Header.FirstMotionID); I > -1; I--) for (i = 0; i < Header.Data.Length; i++) if (Header.FirstMotionID + I == Header.Data[i].MotionID) { @@ -168,15 +222,15 @@ RETURN: s.A(0x20, true); } - if (Header.Data[i].Array2 != null && Header.Data[i].Array2.Length > 0) - { - Header.Data[i].Offset2 = s.P; - - for (i0 = 0; i0 < Header.Data[i].Array2.Length; i0++) - { s.W( 0); s.W(0); } - s.W(-1); s.W(0); - - for (i0 = Header.Data[i].Array2.Length - 1; i0 > -1; i0--) + if (Header.Data[i].Array2 != null && Header.Data[i].Array2.Length > 0) + { + Header.Data[i].Offset2 = s.P; + + for (i0 = 0; i0 < Header.Data[i].Array2.Length; i0++) + { s.W( 0); s.W(0); } + s.W(-1); s.W(0); + + for (i0 = Header.Data[i].Array2.Length - 1; i0 > -1; i0--) { ref HeaderData.Sub.Data2 data = ref Header.Data[i].Array2[i0]; int Size = GetSize2(data.Type); @@ -188,15 +242,15 @@ RETURN: s.A(0x02, true); data.Offset = s.P; - s.W(data.Array); - } - break; - } + s.W(data.Array); + } + break; + } } s.A(0x10, true); Header.SubHeaderOffset = s.P; - i1 = Header.LastMotionID - Header.FirstMotionID; + i1 = (int)(Header.LastMotionID - Header.FirstMotionID); int offset = 0; for (i = 0, i1++; i < i1; i++) @@ -254,14 +308,14 @@ RETURN: MsgPack motHead; MsgPack msgPack = file.ReadMPAllAtOnce(json); if ((motHead = msgPack["MotHead"]).IsNull) return; - Header.MotionSetID = motHead.RI32("MotionSetID"); + Header.MotionSetID = motHead.RU32("MotionSetID"); MsgPack motions, array; if ((motions = motHead["Motions", true]).IsNull) return; Header.Data = new HeaderData.Sub[motions.Array.Length]; for (i = 0; i < Header.Data.Length; i++) { - Header.Data[i].MotionID = motions[i].RI32("MotionID"); + Header.Data[i].MotionID = motions[i].RU32("MotionID"); Header.Data[i].Field00 = motions[i].RI32("Field00"); Header.Data[i].Field04 = motions[i].RI32("Field04"); Header.Data[i].Field08 = motions[i].RI32("Field08"); @@ -370,7 +424,7 @@ RETURN: break; case 0x20: data.Array.GBy(temp.RI16("i00_16"), 0x00); - data.Array.GBy(temp.RI32("i04"), 0x04); + data.Array.GBy(temp.RF32("trans_time"), 0x04); data.Array.GBy(temp.RI32("i08"), 0x08); data.Array.GBy(temp.RI32("i0C"), 0x0C); break; @@ -462,6 +516,9 @@ RETURN: data.Array.GBy(temp.RF32("f34"), 0x34); data.Array.GBy(temp.RF32("f38"), 0x38); break; + case 0x41: + data.Array.GBy(temp.RI32("Iterations"), 0x00); + break; case 0x42: data.Array.GBy(temp.RF32("Value"), 0x00); break; @@ -480,8 +537,8 @@ RETURN: data.Array.GBy(temp.RI32("i00"), 0x00); break; case 0x47: - data.Array.GBy(temp.RU8("i00_8"), 0x00); - data.Array.GBy(temp.RF32("f04"), 0x04); + data.Array.GBy(temp.RU8("ID"), 0x00); // 0 - All, 1 - Kami, 2 - Outer + data.Array.GBy(temp.RF32("Value"), 0x04); break; case 0x48: data.Array.GBy(temp.RF32("f00"), 0x00); @@ -495,21 +552,21 @@ RETURN: data.Array.GBy(temp.RU8("i1A_8"), 0x1A); break; case 0x49: - data.Array.GBy(temp.RI16("i00_16"), 0x00); - data.Array.GBy(temp.RI16("i02_16"), 0x02); - data.Array.GBy(temp.RF32("f04"), 0x04); - data.Array.GBy(temp.RI16("i08_16"), 0x08); - data.Array.GBy(temp.RF32("f0C"), 0x0C); - data.Array.GBy(temp.RI32("i10"), 0x10); - data.Array.GBy(temp.RI32("i14"), 0x14); - data.Array.GBy(temp.RI32("i18"), 0x18); - data.Array.GBy(temp.RI32("i1C"), 0x1C); - data.Array.GBy(temp.RU8("i20"), 0x20); - data.Array.GBy(temp.RU8("i21"), 0x21); - data.Array.GBy(temp.RU8("i22"), 0x22); - data.Array.GBy(temp.RU8("i23"), 0x23); - data.Array.GBy(temp.RF32("f24"), 0x24); - data.Array.GBy(temp.RI32("i28"), 0x28); + data.Array.GBy(temp.RI16("hand"), 0x00); + data.Array.GBy(temp.RI16("scale_select"), 0x02); + data.Array.GBy(temp.RF32("trans_time"), 0x04); + data.Array.GBy(temp.RI16("type"), 0x08); + data.Array.GBy(temp.RF32("scale"), 0x0C); + data.Array.GBy(temp.RF32("rot_blend"), 0x10); + data.Array.GBy(temp.RF32("offset_x"), 0x14); + data.Array.GBy(temp.RF32("offset_y"), 0x18); + data.Array.GBy(temp.RF32("offset_z"), 0x1C); + data.Array.GBy(temp.RU8("enable_scale"), 0x20); + data.Array.GBy(temp.RU8("disable_x"), 0x21); + data.Array.GBy(temp.RU8("disable_y"), 0x22); + data.Array.GBy(temp.RU8("disable_z"), 0x23); + data.Array.GBy(temp.RF32("offset_blend"), 0x24); + data.Array.GBy(temp.RF32("f28"), 0x28); data.Array.GBy(temp.RI32("i2C"), 0x2C); break; case 0x4A: @@ -533,8 +590,8 @@ RETURN: data.Array.GBy(temp.RF32("f30"), 0x30); break; case 0x4C: - data.Array.GBy(temp.RI16("i00_16"), 0x00); - data.Array.GBy(temp.RF32("f04"), 0x04); + data.Array.GBy(temp.RI16("hand"), 0x00); + data.Array.GBy(temp.RF32("trans_time"), 0x04); data.Array.GBy(temp.RF32("f08"), 0x08); break; case 0x4D: @@ -657,7 +714,7 @@ RETURN: case 0x20: arrayEntry.Add(new MsgPack("Data") .Add("i00_16", data.Array.TI16(0x00)) - .Add("i04", data.Array.TI32(0x04)) + .Add("trans_time", data.Array.TF32(0x04)) .Add("i08", data.Array.TI32(0x08)) .Add("i0C", data.Array.TI32(0x0C))); break; @@ -761,6 +818,10 @@ RETURN: .Add("f34", data.Array.TF32(0x34)) .Add("f38", data.Array.TF32(0x38))); break; + case 0x41: + arrayEntry.Add(new MsgPack("Data") + .Add("Iterations", data.Array.TI32(0x00))); + break; case 0x42: arrayEntry.Add(new MsgPack("Data") .Add("Value", data.Array.TF32(0x00))); @@ -785,8 +846,8 @@ RETURN: break; case 0x47: arrayEntry.Add(new MsgPack("Data") - .Add("i00_8", data.Array[0x00]) - .Add("f04", data.Array.TF32(0x04))); + .Add("ID", data.Array[0x00]) // 0 - All, 1 - Kami, 2 - Outer + .Add("Value", data.Array.TF32(0x04))); break; case 0x48: arrayEntry.Add(new MsgPack("Data") @@ -802,21 +863,21 @@ RETURN: break; case 0x49: arrayEntry.Add(new MsgPack("Data") - .Add("i00_16", data.Array.TI16(0x00)) - .Add("i02_16", data.Array.TI16(0x02)) - .Add("f04", data.Array.TF32(0x04)) - .Add("i08_16", data.Array.TI16(0x08)) - .Add("f0C", data.Array.TF32(0x0C)) - .Add("i10", data.Array.TI32(0x10)) - .Add("i14", data.Array.TI32(0x14)) - .Add("i18", data.Array.TI32(0x18)) - .Add("i1C", data.Array.TI32(0x1C)) - .Add("i20_8", data.Array[0x20]) - .Add("i21_8", data.Array[0x21]) - .Add("i22_8", data.Array[0x22]) - .Add("i23_8", data.Array[0x23]) - .Add("f24", data.Array.TI32(0x24)) - .Add("i28", data.Array.TI32(0x28)) + .Add("hand", data.Array.TI16(0x00)) + .Add("scale_select", data.Array.TI16(0x02)) + .Add("trans_time", data.Array.TF32(0x04)) + .Add("type", data.Array.TI16(0x08)) + .Add("scale", data.Array.TF32(0x0C)) + .Add("rot_blend", data.Array.TF32(0x10)) + .Add("offset_x", data.Array.TF32(0x14)) + .Add("offset_y", data.Array.TF32(0x18)) + .Add("offset_z", data.Array.TF32(0x1C)) + .Add("enable_scale", data.Array[0x20]) + .Add("disable_x", data.Array[0x21]) + .Add("disable_y", data.Array[0x22]) + .Add("disable_z", data.Array[0x23]) + .Add("offset_blend", data.Array.TF32(0x24)) + .Add("f28", data.Array.TF32(0x28)) .Add("i2C", data.Array.TI32(0x2C))); break; case 0x4A: @@ -843,8 +904,8 @@ RETURN: break; case 0x4C: arrayEntry.Add(new MsgPack("Data") - .Add("i00_16", data.Array.TI16(0x00)) - .Add("f04", data.Array.TF32(0x04)) + .Add("hand", data.Array.TI16(0x00)) + .Add("trans_time", data.Array.TF32(0x04)) .Add("f08", data.Array.TF32(0x08))); break; case 0x4D: @@ -936,6 +997,7 @@ RETURN: 0x3C => 0x10, 0x3D => 0x08, 0x3E => 0x40, + 0x41 => 0x04, 0x42 => 0x04, 0x43 => 0x08, 0x44 => 0x08, @@ -968,9 +1030,9 @@ RETURN: public struct HeaderData { - public int MotionSetID; - public int FirstMotionID; - public int LastMotionID; + public uint MotionSetID; + public uint FirstMotionID; + public uint LastMotionID; public int SubHeaderOffset; public Sub[] Data; @@ -978,7 +1040,7 @@ RETURN: public struct Sub { public int Offset; - public int MotionID; + public uint MotionID; public int Field00; public int Field04; @@ -1013,9 +1075,10 @@ RETURN: public enum Type { - WindReset = 0x40, - OsageReset = 0x41, - OsageStep = 0x42, + WindReset = 0x40, + RobReset = 0x41, + RobStep = 0x42, + RobMoveCancel = 0x47, } } } diff --git a/PD_Tool/Program.cs b/PD_Tool/Program.cs index 456da9a..cd5fd1b 100644 --- a/PD_Tool/Program.cs +++ b/PD_Tool/Program.cs @@ -334,6 +334,8 @@ namespace PD_Tool else if (filetype == "json") Filter = GetArgs("JSON", "json"); else if (filetype == "igb" ) Filter = GetArgs("IGB", "igb"); else if (filetype == "mgftxt") Filter = GetArgs("MGF2AFT txt", "txt"); + else if (filetype == "mhd" ) Filter = GetArgs("MotHead", "mhd", "bin", "json", "mp") + + GetArgs("MotHead", true, "mhd") + bin + json + mp; else if (filetype == "mp" ) Filter = GetArgs("MessagePack", "mp"); else if (filetype == "lit") Filter = GetArgs("LIT" , "lit", "json", "mp") + GetArgs("LIT", true, "lit") + json + mp; diff --git a/PD_Tool/Properties/AssemblyInfo.cs b/PD_Tool/Properties/AssemblyInfo.cs index 1efd0a2..d52e643 100644 --- a/PD_Tool/Properties/AssemblyInfo.cs +++ b/PD_Tool/Properties/AssemblyInfo.cs @@ -11,5 +11,5 @@ using System.Runtime.InteropServices; [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] [assembly: Guid("7B5D5A3A-A6F8-4813-C97D-ACFC98F7397E")] -[assembly: AssemblyVersion("0.4.10.10")] -[assembly: AssemblyFileVersion("0.4.10.10")] +[assembly: AssemblyVersion("0.4.10.11")] +[assembly: AssemblyFileVersion("0.4.10.11")] diff --git a/PD_Tool/classes/A3D.cs b/PD_Tool/classes/A3D.cs index 6214710..557013e 100644 --- a/PD_Tool/classes/A3D.cs +++ b/PD_Tool/classes/A3D.cs @@ -37,20 +37,29 @@ namespace PD_Tool Program.ConsoleDesign("8. A3DC [XHD/VRFL]"); if (!mp) Program.ConsoleDesign($"9. {(json ? "JSON" : "MsgPack")}"); Program.ConsoleDesign(false); + Program.ConsoleDesign("X[Y] - X: option; Y: rounding in text (def. 9)"); + Program.ConsoleDesign(false); Program.ConsoleDesign(true); Console.WriteLine(); choose = Console.ReadLine().ToUpper(); - if (choose == "1") format = Format.DT ; - else if (choose == "2") format = Format.F ; - else if (choose == "3") format = Format.AFT; - else if (choose == "4") format = Format.AFT; - else if (choose == "5") format = Format.F2 ; - else if (choose == "6") format = Format.MGF; - else if (choose == "7") format = Format.X ; - else if (choose == "8") format = Format.XHD; - else if (choose == "9") format = Format.NULL; + if (choose == null || choose.Length < 1) + return; + else if (choose[0] == '1') format = Format.DT ; + else if (choose[0] == '2') format = Format.F ; + else if (choose[0] == '3') format = Format.AFT; + else if (choose[0] == '4') format = Format.AFT; + else if (choose[0] == '5') format = Format.F2 ; + else if (choose[0] == '6') format = Format.MGF; + else if (choose[0] == '7') format = Format.X ; + else if (choose[0] == '8') format = Format.XHD; + else if (choose[0] == '9') format = Format.NULL; else return; + if (int.TryParse(choose.Substring(1), out int rounding)) + KKdA3DA.Rounding = rounding; + else + KKdA3DA.Rounding = 9; + int state; string filepath, ext; KKdA3DA a3da; diff --git a/PD_Tool/classes/DB.cs b/PD_Tool/classes/DB.cs index 5c7867f..a002648 100644 --- a/PD_Tool/classes/DB.cs +++ b/PD_Tool/classes/DB.cs @@ -16,7 +16,7 @@ namespace PD_Tool if (file.EndsWith(".mp" )) { mp = false; break; } else if (file.EndsWith(".json")) { mp = false; break; } - uint num2 = (uint)((DateTime.Now.Ticks - 621355968000000000) / 10000000); + uint timestamp = (uint)((DateTime.Now.Ticks - 621355968000000000) / 10000000); string[] file_split; string filepath, ext; KKdMainLib.DataBank db; @@ -48,7 +48,7 @@ namespace PD_Tool { Console.Title = "DataBank Converter: " + filename; db.MsgPackReader(filepath, json); - db. DBWriter(filepath, num2); + db. DBWriter(filepath, timestamp); } } } diff --git a/PD_Tool/classes/DIVAFILE.cs b/PD_Tool/classes/DIVAFILE.cs index 18b8d55..8660e1c 100644 --- a/PD_Tool/classes/DIVAFILE.cs +++ b/PD_Tool/classes/DIVAFILE.cs @@ -13,7 +13,7 @@ namespace PD_Tool if (head != 0x454C494641564944) return; System.Console.Title = "DIVAFILE Decrypt: " + Path.GetFileName(file); - file.Decrypt(); + KKdMainLib.DIVAFILE.Decrypt(file); } public static void Encrypt(string file) @@ -24,7 +24,7 @@ namespace PD_Tool if (head == 0x454C494641564944) return; System.Console.Title = "DIVAFILE Encrypt: " + Path.GetFileName(file); - file.Encrypt(); + KKdMainLib.DIVAFILE.Encrypt(file); } } } diff --git a/PD_Tool/classes/MHD.cs b/PD_Tool/classes/MHD.cs index b46fb06..6eb43ed 100644 --- a/PD_Tool/classes/MHD.cs +++ b/PD_Tool/classes/MHD.cs @@ -9,7 +9,7 @@ namespace PD_Tool public static void Processor(bool json) { Console.Title = "MotHead Converter"; - Program.Choose(1, "bin", out string[] fileNames); + Program.Choose(1, "mhd", out string[] fileNames); if (fileNames.Length < 1) return; string filepath, ext; @@ -21,9 +21,9 @@ namespace PD_Tool ext = Path.GetExtension(file).ToLower(); Console.Title = "MotHead Converter: " + Path.GetFileNameWithoutExtension(file); - if (ext == ".bin") + if (ext == ".bin" || ext == ".mhd") { - mhd.MotHeadReader(filepath); + mhd.MotHeadReader(filepath, ext); mhd.MsgPackWriter(filepath, json); } else if (ext == ".mp" || ext == ".json")