diff --git a/ArcFormats/ArcFormats.csproj b/ArcFormats/ArcFormats.csproj index 8061dfd8..80581176 100644 --- a/ArcFormats/ArcFormats.csproj +++ b/ArcFormats/ArcFormats.csproj @@ -48,6 +48,9 @@ prompt MinimumRecommendedRules.ruleset + + false + ..\packages\SharpZipLib.1.3.3\lib\net45\ICSharpCode.SharpZipLib.dll @@ -55,6 +58,7 @@ ..\packages\NAudio.1.7.3\lib\net35\NAudio.dll + ..\packages\NVorbis.0.10.4\lib\net45\NVorbis.dll @@ -69,6 +73,7 @@ + ..\packages\System.Memory.4.5.4\lib\netstandard1.1\System.Memory.dll @@ -1234,12 +1239,6 @@ exit 0 xcopy "$(ProjectDir)\Resources\Formats.dat" "$(TargetDir)\GameData\" /D /Y >NUL - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - 0) - output[dst++] = v; + case 0x80: + { + byte v = input.ReadUInt8(); + while (count-- > 0) + output[dst++] = v; + break; + } + + case 0xE0: + { + count = count << 8 | input.ReadUInt8(); + byte v = input.ReadUInt8(); + while (count-- > 0) + output[dst++] = v; + break; + } + + case 0x00: + dst += count; break; - } - case 0xE0: - { + case 0xC0: count = count << 8 | input.ReadUInt8(); - byte v = input.ReadUInt8(); - while (count --> 0) - output[dst++] = v; + dst += count; break; + } + } + return dst; + } + + int UnpackH(byte[] buf_packed, byte[] output, uint unpacked_size) + { + var buf = new Byte[0x10000]; + Array.Clear(buf, 0, buf.Length); + const uint off2 = 0x2004; + const uint off3 = 0x2804; + const uint off4 = 0x3004; //0x811C9784 + + uint cur_addr = 2, pre_pos, next_pos = 2, cur_output_addr = 0; + byte outchar, i1 = 0, i2, v29, first_char = buf_packed[0]; + int idx1 = 0, v28=0; + do + { + pre_pos = next_pos; + var cur_char1 = buf_packed[cur_addr]; + var next_addr = cur_addr + 1; + next_pos++; + if (cur_char1 != 0) + { + byte l1 = buf_packed[cur_addr + 1]; + byte h1 = buf_packed[cur_addr + 2]; + uint t1 = (ushort)(l1 + (h1 << 8)); + if (cur_char1 >= 8) + { + if (cur_char1 >= 0xD) + { + uint d; + if (cur_char1 < 0x10) // 2 byte + { + d = t1; + next_addr = cur_addr + 3; + next_pos = pre_pos + 3; + } + else //3 byte + { + d = (uint)(t1 + (buf_packed[cur_addr + 3] << 16)); + next_addr = cur_addr + 4; + next_pos = pre_pos + 4; + } + buf[off3 + 4 + 8 * i1] = cur_char1; + BitConverter.GetBytes((uint)(d)).CopyTo(buf, off3 + 8 * i1); + buf[off3 + 5 + 8 * i1] = (byte)idx1; + i1++; + } + else //2byte + { + buf[2 * t1] = (byte)idx1; + buf[2 * t1 + 1] = cur_char1; + next_addr = cur_addr + 3; + next_pos = pre_pos + 3; + } } + else // 1byte + { + buf[2 * l1] = (byte)idx1; + buf[2 * l1 + 1] = cur_char1; + next_addr = cur_addr + 2; + next_pos = pre_pos + 2; + } + } + cur_addr = next_addr; + ++idx1; + } while (idx1 != 0x100); - case 0x00: - dst += count; - break; + byte idx2 = 0; + byte v19 = 0xD; + do + { + i2 = 0; + buf[off4 + v19] = (byte)idx2; + if (i1 != 0) + { + int buf3_addr = 0x2804; //buf3_addr = (_BYTE *)&dword_811C8F84; + do + { + if (buf[buf3_addr + 4] == v19) + { + Array.Copy(buf, buf3_addr, buf, off2 + 8 * idx2, 4); + Array.Copy(buf, buf3_addr+4, buf, off2 + 4 + 8 * idx2, 4); + idx2++; + } + ++i2; + buf3_addr += 8; + } + while (i2 != i1); + } + v19++; + } while (v19 != 0x18); - case 0xC0: - count = count << 8 | input.ReadUInt8(); - dst += count; + buf[0x301c] = (byte)idx2; //unk_811C979C = idx2; + Array.Clear(buf, 0x3028, 8);//qword_811C97A8 = 0i64; + int v23 = (int)unpacked_size, v33=0, size_done = 0; + while (true) + { + int v24 = (int)(next_pos + ((uint)(v33 & 0x1F) >> 3) + ((v33 >> 3) & 0xFFFFFFFC)); //this place, out of range + ulong v25 = BitConverter.ToUInt32(buf_packed, v24); + byte cur_char2 = first_char; + uint v27 = sub_8105E56C((uint)v25, (uint)(v25 >> 32), (uint)((v33 & 0x1F) - (v33 & 0x18))); + if (first_char != 0xD) + { + while (true) + { + v28 = (int)(v27 & dword_8107F828[2 * cur_char2]); + BitConverter.GetBytes((int)(2 * v28 + 0x811C6780)).CopyTo(buf, off2 - 4); //must pay attention to the type convert and length + if (cur_char2 == buf[2 * v28 + 1])// buf1+1 + break; + cur_char2++; + if (cur_char2 == 0xD) + goto LABEL_22; + } + outchar = buf[2 * v28]; + goto LABEL_29; + } + LABEL_22: + if (cur_char2 == 0x18) break; + LABEL_26_2: + while (true) + { + v29 = buf[off4 + cur_char2]; + if (v29 != buf[off4 + 1 + cur_char2]) + break; + LABEL_26: //goto can not jump here + if (++cur_char2 == 0x18) + { + return 0; + //outchar = buf[off2 + 5 + 8 * v29]; //this seems a hack... + //goto LABEL_29; + } + } + while (BitConverter.ToUInt32(buf, (int)off2 + 8 * v29) != + (v27 & dword_8107F828[2 * cur_char2])) + { + v29++; + if (v29 == buf[off4 + 1 + cur_char2 ]) + { + if (++cur_char2 == 0x18) + { + return 0; + } + goto LABEL_26_2; + } } + outchar = buf[off2 + 5 + 8 * v29]; + LABEL_29: + output[cur_output_addr] = (byte)outchar; + BitConverter.GetBytes((Int64)v33 + (ushort)cur_char2).CopyTo(buf, 0x3028); + v23 = size_done + 1; + ++cur_output_addr; + v33 += cur_char2 ; + size_done = v23; + if (v23 >= unpacked_size) + return size_done; } + return 0; } - - void UnpackH (IBinaryStream input, byte[] output) + uint sub_8105E56C(uint result, uint a2, uint a3) { - throw new NotImplementedException(); + if (a3 > 63) + { + result = 0; + } + else if (a3 != 0) + { + if (a3 > 31) + result = a2 >> (int)(a3 - 32); + else + result = (a2 << (int)(32 - a3)) | (result >> (int)a3); + //insert the low a3 bit of the result into a2, then asign to result + } + return result; } - void UnpackW (IBinaryStream input, byte[] output) + int UnpackW(byte[] buf_packed, byte[] output, uint unpacked_size) { throw new NotImplementedException(); + //not appear in my test game /* int header_length = input.ReadUInt8(); int shift = input.ReadUInt8(); @@ -194,42 +428,42 @@ void UnpackW (IBinaryStream input, byte[] output) { int bit = v7 & 0x1F; int v9 = (v7 >> 3) & 0x1FFFFFFC; - int v10; + int pre_addr; if (bit < 0x1C) { - v10 = input.ReadInt32(); //MemInt32(&src[v9]); + pre_addr = input.ReadInt32(); //MemInt32(&src[v9]); } else { - v10 = input.ReadInt32(); //MemInt32(&src[v9 + 1]); + pre_addr = input.ReadInt32(); //MemInt32(&src[v9 + 1]); bit -= 8; } v7 += 5; - int v13 = (v10 >> bit) & 0x1F; + int l1 = (pre_addr >> bit) & 0x1F; bit = v7 & 0x1F; int v14 = (v7 >> 3) & 0x1FFFFFFC; if (bit < 8) { - v10 = MemInt32(&src[v14]); + pre_addr = MemInt32(&src[v14]); } else if (bit < 0x10) { - v10 = MemInt32(&src[v14 + 1]); + pre_addr = MemInt32(&src[v14 + 1]); bit -= 8; } else if (bit < 0x18) { - v10 = MemInt32(&src[v14 + 2]); + pre_addr = MemInt32(&src[v14 + 2]); bit -= 16; } else { - v10 = MemInt32(&src[v14 + 3]); + pre_addr = MemInt32(&src[v14 + 3]); bit -= 24; } - v17 = v13 & 0xF; - int sample = dword_455580[v17] + (((v10 >> bit) & (dword_4554E8[v17] >> shift)) << shift); - if ((v13 & 0x10) != 0) + v17 = l1 & 0xF; + int sample = dword_455580[v17] + (((pre_addr >> bit) & (dword_4554E8[v17] >> shift)) << shift); + if ((l1 & 0x10) != 0) sample = -sample; LittleEndian.Pack ((short)sample, output, dst); dst += 2; @@ -242,6 +476,75 @@ void UnpackW (IBinaryStream input, byte[] output) */ } + int decrypt(byte[] input, byte[] output, int len, char enc_method, int start_input=0, int start_output=0) + { + int len_decrypt = len, i; + int cur_output_addr = start_output; + int cur_addr = start_input; + switch (enc_method) + { + case 'N': + input.CopyTo(output, 0); + break; + case 'B': //byte + i = 0; + if (len_decrypt!=0) + { + do + { + var d = input[cur_addr]; + var tmp = -d; + if (i != 0) + tmp = input[cur_addr - 1] - d; + i++; + output[cur_output_addr++] = (byte)tmp; + ++cur_addr; + } + while (i != len_decrypt); + } + break; + case 'W': //word + len_decrypt = (int)((len + 1) & 0xFFFFFFFE); + i = 0; + if (len_decrypt!=0) + { + do + { + var d = input[cur_addr] | (input[cur_addr+1] << 8); + var tmp = -d; + if (i!=0) + tmp = (input[cur_addr-2] | input[cur_addr-1] << 8) - d; + output[cur_output_addr++] = (byte)(tmp & 0xff); + output[cur_output_addr++] = (byte)(tmp >> 8); + i += 2; + cur_addr += 2; + } + while (i != len_decrypt); + } + break; + case 'S': // big endian word + len_decrypt = (int)((len + 1) & 0xFFFFFFFE); + i = 0; + if (len_decrypt!=0) + { + do + { + var d = input[cur_addr+1] | (input[cur_addr] << 8); + var tmp = -d; + if (i!=0) + tmp = (input[cur_addr - 1] | input[cur_addr - 2] << 8) - d; + output[cur_output_addr++] = (byte)(tmp >> 8); + output[cur_output_addr++] = (byte)(tmp & 0xff); + i += 2; + cur_addr += 2; + } + while (i != len_decrypt); + } + break; + } + return len_decrypt; + } + static readonly int[] dword_455540 = { 0x0, 0x0, 0x0, 0x0, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE @@ -250,9 +553,44 @@ void UnpackW (IBinaryStream input, byte[] output) 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 }; - static readonly int[] dword_4554E8 = { + static readonly int[] dword_4554E8 = { //8107F748 0x00, 0x00, 0x00, 0x00, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF }; + static readonly uint[] dword_8107F828 = { + 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000003, 0x00000000, 0x00000007, 0x00000000, + 0x0000000F, 0x00000000, 0x0000001F, 0x00000000, 0x0000003F, 0x00000000, 0x0000007F, 0x00000000, + 0x000000FF, 0x00000000, 0x000001FF, 0x00000000, 0x000003FF, 0x00000000, 0x000007FF, 0x00000000, + 0x00000FFF, 0x00000000, 0x00001FFF, 0x00000000, 0x00003FFF, 0x00000000, 0x00007FFF, 0x00000000, + 0x0000FFFF, 0x00000000, 0x0001FFFF, 0x00000000, 0x0003FFFF, 0x00000000, 0x0007FFFF, 0x00000000, + 0x000FFFFF, 0x00000000, 0x001FFFFF, 0x00000000, 0x003FFFFF, 0x00000000, 0x007FFFFF, 0x00000000, + 0x00FFFFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000007, 0x0000000F, + 0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF, + 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF, 0x0001FFFF, 0x0003FFFF, 0x000FFFFF, 0x00000000, + 0x06050403, 0x0A090807, 0x0E0D0C0B, 0x00000000, 0x00000001, 0x00000002, 0x00000004, 0x00000008, + 0x00000010, 0x00000020, 0x00000040, 0x00000080, 0x00000100, 0x00000200, 0x00000400, 0x00000800, + 0x00001000, 0x00002000, 0x00004000, 0x00000000, 0xFFFF0001, 0x00000000, 0x00000000, 0x00000001, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001, 0x00000001, + }; + static readonly uint[] dword_8107F750 ={ + 0x00000000, 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000F, 0x0000001F, 0x0000003F, + 0x0000007F, 0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF, 0x00001FFF, 0x00003FFF, + 0x00007FFF, 0x0000FFFF, 0x0001FFFF, 0x0003FFFF, 0x000FFFFF, 0x00000000, 0x00000000, 0x00000001, + }; + static readonly uint[] dword_8107F7A4 = { + 0x00000000, 0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, + 0x00000007, 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E, + 0x00000000, 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010, 0x00000020, 0x00000040, + 0x00000080, 0x00000100, 0x00000200, 0x00000400, 0x00000800, 0x00001000, 0x00002000, 0x00004000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000003, 0x00000000, 0x00000007, + 0x00000000, 0x0000000F, 0x00000000, 0x0000001F, 0x00000000, 0x0000003F, 0x00000000, 0x0000007F, + 0x00000000, 0x000000FF, 0x00000000, 0x000001FF, 0x00000000, 0x000003FF, 0x00000000, 0x000007FF, + 0x00000000, 0x00000FFF, 0x00000000, 0x00001FFF, 0x00000000, 0x00003FFF, 0x00000000, 0x00007FFF, + 0x00000000, 0x0000FFFF, 0x00000000, 0x0001FFFF, 0x00000000, 0x0003FFFF, 0x00000000, 0x0007FFFF, + 0x00000000, 0x000FFFFF, 0x00000000, 0x001FFFFF, 0x00000000, 0x003FFFFF, 0x00000000, 0x007FFFFF, + 0x00000000, 0x00FFFFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000007, + 0x0000000F, 0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF, + 0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF, 0x0001FFFF, 0x0003FFFF, 0x000FFFFF, + }; } } diff --git a/Console/ConsoleBrowser.cs b/Console/ConsoleBrowser.cs index c4b11043..44a74418 100644 --- a/Console/ConsoleBrowser.cs +++ b/Console/ConsoleBrowser.cs @@ -3,14 +3,12 @@ //! \brief game resources browser. // +using GameRes; using System; +using System.Diagnostics; using System.IO; -using System.IO.MemoryMappedFiles; -using System.Text; using System.Linq; -using System.Collections.Generic; -using System.Diagnostics; -using GameRes; +using System.Text; namespace GARbro { @@ -91,6 +89,7 @@ void Run (string[] args) } var tag = args[argn+1]; m_image_format = ImageFormat.FindByTag (tag); + if (null == m_image_format) { Console.Error.WriteLine ("{0}: unknown format specified", tag); @@ -151,6 +150,12 @@ void Run (string[] args) } } + private ImageFormat FindFormat(string tag) + { + var range = FormatCatalog.Instance.LookupExtension(tag); + return range.FirstOrDefault(); + } + void DeserializeGameData () { string scheme_file = Path.Combine (FormatCatalog.Instance.DataDirectory, "Formats.dat"); diff --git a/Console/GARbro.Console.csproj b/Console/GARbro.Console.csproj index d645b9c8..677e895c 100644 --- a/Console/GARbro.Console.csproj +++ b/Console/GARbro.Console.csproj @@ -61,6 +61,7 @@ + diff --git a/Console/GARbro.Console.csproj.user b/Console/GARbro.Console.csproj.user index 210701f0..08d7eca7 100644 --- a/Console/GARbro.Console.csproj.user +++ b/Console/GARbro.Console.csproj.user @@ -11,6 +11,6 @@ false - -l + -x "D:\MAKE\Reverse\Getsuei_psvpsp\intermediate\psv\SCRDATA.ARC" \ No newline at end of file diff --git a/GARbro.sln b/GARbro.sln index 1fb08ac8..a74209f6 100644 --- a/GARbro.sln +++ b/GARbro.sln @@ -1,12 +1,13 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.21005.1 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30225.117 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GARbro.Console", "Console\GARbro.Console.csproj", "{B966F292-431A-4D8A-A1D3-1EB45048A1D2}" ProjectSection(ProjectDependencies) = postProject {453C087F-E416-4AE9-8C03-D8760DA0574B} = {453C087F-E416-4AE9-8C03-D8760DA0574B} {A8865685-27CC-427B-AC38-E48D2AD05DF4} = {A8865685-27CC-427B-AC38-E48D2AD05DF4} + {757EB8B1-F62C-4690-AC3D-DAE4A5576B3E} = {757EB8B1-F62C-4690-AC3D-DAE4A5576B3E} EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ArcFormats", "ArcFormats\ArcFormats.csproj", "{A8865685-27CC-427B-AC38-E48D2AD05DF4}" @@ -86,4 +87,7 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {4BAF3CDB-672B-4342-8D33-43A9715BE02B} + EndGlobalSection EndGlobal diff --git a/GUI/GARbro.GUI.csproj b/GUI/GARbro.GUI.csproj index d1430a33..6cbbf234 100644 --- a/GUI/GARbro.GUI.csproj +++ b/GUI/GARbro.GUI.csproj @@ -72,7 +72,7 @@ - true + false Properties\app.manifest @@ -345,12 +345,6 @@ exit 0 - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - -