├── Tools ├── PSBExternal.exe └── Bitmap Resolution Finder.exe ├── ScnEditorGUI ├── Properties │ ├── Settings.settings │ ├── Settings.Designer.cs │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ └── Resources.resx ├── app.config ├── Program.cs ├── Find.cs ├── Find.Designer.cs ├── ScnEditorGUI.csproj ├── Find.resx ├── Form1.resx ├── Form1.Designer.cs └── Form1.cs ├── .gitattributes ├── KrKrSceneManager ├── KrKrSceneManager.csproj ├── Zlib │ ├── license.txt │ ├── readme.txt │ ├── ZStreamException.cs │ ├── Adler32.cs │ ├── SupportClass.cs │ ├── StaticTree.cs │ ├── Tree.cs │ ├── ZOutputStream.cs │ ├── ZInputStream.cs │ └── Inflate.cs ├── Algorithms.cs ├── PSBAnalyzer.cs ├── TJS2Manager.cs ├── PSBResourceManager.cs └── PSBStringManager.cs ├── README.md ├── ScnEditorGUI.sln └── .gitignore /Tools/PSBExternal.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcussacana/KrKrZSceneManager/HEAD/Tools/PSBExternal.exe -------------------------------------------------------------------------------- /Tools/Bitmap Resolution Finder.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marcussacana/KrKrZSceneManager/HEAD/Tools/Bitmap Resolution Finder.exe -------------------------------------------------------------------------------- /ScnEditorGUI/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /ScnEditorGUI/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /ScnEditorGUI/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Windows.Forms; 5 | 6 | namespace ScnEditorGUI 7 | { 8 | static class Program 9 | { 10 | /// 11 | /// The main entry point for the application. 12 | /// 13 | [STAThread] 14 | static void Main() 15 | { 16 | Application.EnableVisualStyles(); 17 | Application.SetCompatibleTextRenderingDefault(false); 18 | Application.Run(new Form1()); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /KrKrSceneManager/KrKrSceneManager.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net46 4 | AnyCPU 5 | 1.0.0.0 6 | 1.0.0.0 7 | true 8 | true 9 | true 10 | preview 11 | PackageReference 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /ScnEditorGUI/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // O código foi gerado por uma ferramenta. 4 | // Versão de Tempo de Execução:4.0.30319.42000 5 | // 6 | // As alterações ao arquivo poderão causar comportamento incorreto e serão perdidas se 7 | // o código for gerado novamente. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace ScnEditorGUI.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.6.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## My Ko-Fi 2 | Buy Me a Coffee at ko-fi.com 3 | 4 | ### KiriKiriZSM ~5.6 (Final?) 5 | [![Build Status](https://travis-ci.org/ForumHulp/pageaddon.svg?branch=master)](http://vnx.uvnworks.com) 6 | 7 | A DLL Library tool to allow you write your own string editor or resouce manager in C# 8 | Tested with: Nekopara Vol.0 & Vol.1, Dracu+Riot, Wagamama [Steam ver] (.scn, .pimg and .psb), TJS2100 9 | 10 | ### Added new experimental features (by hiroshiyuri) 11 | 🆕 Added maximized window 12 | 🆕 Added font size config 🎉 13 | 🆕 Added dark mode config 🎉 14 | 🆕 Added config to select all in textbox when click 15 | 🆕 Added config to update text when CTRL + V 16 | 🆕 Added a simple find box when CTRL + F 🎉 17 | 18 | Enable and disable this features in file `ScnEditorGUI.exe.config` 19 | 20 | ### Any problem with my shit? 21 | Try use this: https://github.com/UlyssesWu/FreeMote/tree/master/FreeMote.Tools.PsbDecompile 22 | 23 | This tool is a proper PSB Editor, can help you with the .pimg, .psb, .scn too. 24 | 25 | 26 | [Embedded Bitmap Tutorial](https://youtu.be/2OlgmNdK5UU) 27 | 28 | [ZLIB LICENSE](https://raw.githubusercontent.com/marcussacana/KrKrZSceneManager/master/KrKrSceneManager/Zlib/license.txt) 29 | -------------------------------------------------------------------------------- /KrKrSceneManager/Zlib/license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2006-2007, ComponentAce 2 | http://www.componentace.com 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 6 | 7 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 9 | Neither the name of ComponentAce nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 10 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 11 | -------------------------------------------------------------------------------- /ScnEditorGUI/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ScnEditorGUI")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ScnEditorGUI")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("838b7676-aeb7-4509-b1d0-e439d6599d0d")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /ScnEditorGUI.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.23107.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ScnEditorGUI", "ScnEditorGUI\ScnEditorGUI.csproj", "{838B7676-AEB7-4509-B1D0-E439D6599D0D}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KrKrSceneManager", "KrKrSceneManager\KrKrSceneManager.csproj", "{77B183F4-656E-4FEC-A424-891382B64FA9}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {838B7676-AEB7-4509-B1D0-E439D6599D0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {838B7676-AEB7-4509-B1D0-E439D6599D0D}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {838B7676-AEB7-4509-B1D0-E439D6599D0D}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {838B7676-AEB7-4509-B1D0-E439D6599D0D}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {77B183F4-656E-4FEC-A424-891382B64FA9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {77B183F4-656E-4FEC-A424-891382B64FA9}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {77B183F4-656E-4FEC-A424-891382B64FA9}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {77B183F4-656E-4FEC-A424-891382B64FA9}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /ScnEditorGUI/Find.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Configuration; 3 | using System.Drawing; 4 | using System.Runtime.InteropServices; 5 | using System.Windows.Forms; 6 | 7 | namespace ScnEditorGUI 8 | { 9 | public partial class Find : Form 10 | { 11 | private Form1 _parentForm = null; 12 | 13 | [DllImport("dwmapi.dll")] 14 | private static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize); 15 | 16 | private static bool UseImmersiveDarkMode(IntPtr handle, bool enabled) 17 | { 18 | if (Environment.OSVersion.Version.Build >= 9200) 19 | { 20 | var attribute = 20; // DWMWA_USE_IMMERSIVE_DARK_MODE 21 | 22 | int useImmersiveDarkMode = enabled ? 1 : 0; 23 | return DwmSetWindowAttribute(handle, (int)attribute, ref useImmersiveDarkMode, sizeof(int)) == 0; 24 | } 25 | 26 | return false; 27 | } 28 | 29 | public Find(Form1 form1) 30 | { 31 | InitializeComponent(); 32 | 33 | this._parentForm = form1; 34 | 35 | string fontSize = ConfigurationSettings.AppSettings["font_size"]; 36 | string darkMode = ConfigurationSettings.AppSettings["dark_mode"]; 37 | 38 | this.textBox1.Font = new Font( 39 | "Microsoft Sans Serif", 40 | float.Parse(fontSize), 41 | FontStyle.Regular, 42 | GraphicsUnit.Point, 43 | ((byte)(0)) 44 | ); 45 | 46 | if (darkMode == "true") { 47 | UseImmersiveDarkMode(this.Handle, true); 48 | this.BackColor = Color.Gray; 49 | this.textBox1.BackColor = Color.Black; 50 | this.textBox1.ForeColor = Color.White; 51 | } 52 | } 53 | 54 | private void button1_Click(object sender, EventArgs e) { 55 | this._parentForm.FindMyString(textBox1.Text); 56 | this.Close(); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /KrKrSceneManager/Zlib/readme.txt: -------------------------------------------------------------------------------- 1 | ZLIB.NET: README 2 | ================================================== 3 | 4 | Contents 5 | -------- 6 | 7 | Program information 8 | Company information 9 | Description 10 | Specification 11 | Other ComponentAce compression products 12 | 13 | 14 | 15 | Program information 16 | ------------------- 17 | 18 | Program Name: 19 | ZLIB.NET 20 | License Type: freeware 21 | 22 | Program Version: 23 | 1.04 24 | Program Release Date: 25 | 03/28/2007 26 | Program Purpose: 27 | version of ZLIB compression library for .NET framework 28 | Target Environment: 29 | Visual Studio 2003, Visual Studio 2005, Borland Developer Studio 2005, Borland Developer Studio 2006 and other 30 | 31 | 32 | Company information 33 | ------------------- 34 | 35 | Company Name: 36 | ComponentAce 37 | Contact E-mail Address: 38 | support@componentace.com 39 | Contact WWW URL: 40 | http://www.componentace.com 41 | 42 | 43 | Description 44 | ----------- 45 | 46 | 100% managed version of ZLIB compression library. 47 | Based on JZlib library (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. 48 | 49 | The zlib compression library was written by Jean-loup Gailly gzip@prep.ai.mit.edu and Mark Adler madler@alumni.caltech.edu. 50 | 51 | The primary site for the zlib compression library is http://www.zlib.org. 52 | 53 | Copyright and license 54 | --------------------- 55 | 56 | See "license.txt" file. 57 | 58 | 59 | Warranty and guarantee 60 | ---------------------- 61 | 62 | See "license.txt" file. 63 | 64 | 65 | Other ComponentAce compression products 66 | --------------------------------------- 67 | 68 | ZipForge.NET 69 | ------------ 70 | 71 | ZipForge.NET is an advanced ZIP compression library for .NET framework. 72 | ZipForge.NET features include streaming support, transaction system, ZIP encryption, repair, 73 | progress indication, Zip64 support, SFX (self-extracting) archives, unicode filenames, spanning support and much more. 74 | 75 | FlexCompress.NET 76 | ---------------- 77 | 78 | FlexCompress.NET is an advanced compression and encryption .NET component designed to provide archive 79 | functionality for your applications. This solution provides flexible compression and strong encryption algorithms that 80 | allows you to integrate archiving or backup features into your programs in a fast and easy way. 81 | FlexCompres.NET uses its own file format which allows to achieve high compression rate. 82 | 83 | For more info visit 84 | http://www.componentace.com/.NET_components -------------------------------------------------------------------------------- /ScnEditorGUI/Find.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ScnEditorGUI 2 | { 3 | partial class Find 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.textBox1 = new System.Windows.Forms.TextBox(); 32 | this.button1 = new System.Windows.Forms.Button(); 33 | this.SuspendLayout(); 34 | // 35 | // textBox1 36 | // 37 | this.textBox1.Location = new System.Drawing.Point(12, 12); 38 | this.textBox1.Name = "textBox1"; 39 | this.textBox1.Size = new System.Drawing.Size(493, 20); 40 | this.textBox1.TabIndex = 0; 41 | // 42 | // button1 43 | // 44 | this.button1.Location = new System.Drawing.Point(219, 53); 45 | this.button1.Name = "button1"; 46 | this.button1.Size = new System.Drawing.Size(75, 23); 47 | this.button1.TabIndex = 1; 48 | this.button1.Text = "Search"; 49 | this.button1.UseVisualStyleBackColor = true; 50 | this.button1.Click += new System.EventHandler(this.button1_Click); 51 | // 52 | // Find 53 | // 54 | this.AcceptButton = this.button1; 55 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 56 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 57 | this.ClientSize = new System.Drawing.Size(517, 88); 58 | this.Controls.Add(this.button1); 59 | this.Controls.Add(this.textBox1); 60 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; 61 | this.MaximizeBox = false; 62 | this.MinimizeBox = false; 63 | this.Name = "Find"; 64 | this.Text = "Find"; 65 | this.ResumeLayout(false); 66 | this.PerformLayout(); 67 | 68 | } 69 | 70 | #endregion 71 | 72 | private System.Windows.Forms.TextBox textBox1; 73 | private System.Windows.Forms.Button button1; 74 | } 75 | } -------------------------------------------------------------------------------- /ScnEditorGUI/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // O código foi gerado por uma ferramenta. 4 | // Versão de Tempo de Execução:4.0.30319.42000 5 | // 6 | // As alterações ao arquivo poderão causar comportamento incorreto e serão perdidas se 7 | // o código for gerado novamente. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace ScnEditorGUI.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// Uma classe de recurso de tipo de alta segurança, para pesquisar cadeias de caracteres localizadas etc. 17 | /// 18 | // Essa classe foi gerada automaticamente pela classe StronglyTypedResourceBuilder 19 | // através de uma ferramenta como ResGen ou Visual Studio. 20 | // Para adicionar ou remover um associado, edite o arquivo .ResX e execute ResGen novamente 21 | // com a opção /str, ou recrie o projeto do VS. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Retorna a instância de ResourceManager armazenada em cache usada por essa classe. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ScnEditorGUI.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Substitui a propriedade CurrentUICulture do thread atual para todas as 51 | /// pesquisas de recursos que usam essa classe de recurso de tipo de alta segurança. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /KrKrSceneManager/Zlib/ZStreamException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2006, ComponentAce 2 | // http://www.componentace.componentAce.com 3 | // All rights reserved. 4 | 5 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 6 | 7 | // Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | // Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 9 | // Neither the name of ComponentAce nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 10 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 11 | 12 | /* 13 | Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. 14 | 15 | Redistribution and use in source and binary forms, with or without 16 | modification, are permitted provided that the following conditions are met: 17 | 18 | 1. Redistributions of source code must retain the above copyright notice, 19 | this list of conditions and the following disclaimer. 20 | 21 | 2. Redistributions in binary form must reproduce the above copyright 22 | notice, this list of conditions and the following disclaimer in 23 | the documentation and/or other materials provided with the distribution. 24 | 25 | 3. The names of the authors may not be used to endorse or promote products 26 | derived from this software without specific prior written permission. 27 | 28 | THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, 29 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 30 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, 31 | INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, 32 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 33 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 34 | OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 35 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 36 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 37 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 | */ 39 | /* 40 | * This program is based on zlib-1.1.3, so all credit should go authors 41 | * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) 42 | * and contributors of zlib. 43 | */ 44 | using System; 45 | using System.IO; 46 | 47 | namespace KrKrSceneManager 48 | { 49 | 50 | /// 51 | /// Exceptions that occur in ZStream 52 | /// 53 | internal class ZStreamException : System.IO.IOException 54 | { 55 | /// 56 | /// Default constructor. 57 | /// 58 | internal ZStreamException() 59 | :base() 60 | { 61 | } 62 | 63 | /// 64 | /// Constructor which takes one parameter - an error message 65 | /// 66 | internal ZStreamException(System.String s) 67 | :base(s) 68 | { 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # Build results 11 | [Dd]ebug/ 12 | [Dd]ebugPublic/ 13 | [Rr]elease/ 14 | [Rr]eleases/ 15 | x64/ 16 | x86/ 17 | build/ 18 | bld/ 19 | [Bb]in/ 20 | [Oo]bj/ 21 | 22 | # Roslyn cache directories 23 | *.ide/ 24 | 25 | # MSTest test Results 26 | [Tt]est[Rr]esult*/ 27 | [Bb]uild[Ll]og.* 28 | 29 | #NUNIT 30 | *.VisualState.xml 31 | TestResult.xml 32 | 33 | # Build Results of an ATL Project 34 | [Dd]ebugPS/ 35 | [Rr]eleasePS/ 36 | dlldata.c 37 | 38 | *_i.c 39 | *_p.c 40 | *_i.h 41 | *.ilk 42 | *.meta 43 | *.obj 44 | *.pch 45 | *.pdb 46 | *.pgc 47 | *.pgd 48 | *.rsp 49 | *.sbr 50 | *.tlb 51 | *.tli 52 | *.tlh 53 | *.tmp 54 | *.tmp_proj 55 | *.log 56 | *.vspscc 57 | *.vssscc 58 | .builds 59 | *.pidb 60 | *.svclog 61 | *.scc 62 | 63 | # Chutzpah Test files 64 | _Chutzpah* 65 | 66 | # Visual C++ cache files 67 | ipch/ 68 | *.aps 69 | *.ncb 70 | *.opensdf 71 | *.sdf 72 | *.cachefile 73 | 74 | # Visual Studio profiler 75 | *.psess 76 | *.vsp 77 | *.vspx 78 | 79 | # TFS 2012 Local Workspace 80 | $tf/ 81 | 82 | # Guidance Automation Toolkit 83 | *.gpState 84 | 85 | # ReSharper is a .NET coding add-in 86 | _ReSharper*/ 87 | *.[Rr]e[Ss]harper 88 | *.DotSettings.user 89 | 90 | # JustCode is a .NET coding addin-in 91 | .JustCode 92 | 93 | # TeamCity is a build add-in 94 | _TeamCity* 95 | 96 | # DotCover is a Code Coverage Tool 97 | *.dotCover 98 | 99 | # NCrunch 100 | _NCrunch_* 101 | .*crunch*.local.xml 102 | 103 | # MightyMoose 104 | *.mm.* 105 | AutoTest.Net/ 106 | 107 | # Web workbench (sass) 108 | .sass-cache/ 109 | 110 | # Installshield output folder 111 | [Ee]xpress/ 112 | 113 | # DocProject is a documentation generator add-in 114 | DocProject/buildhelp/ 115 | DocProject/Help/*.HxT 116 | DocProject/Help/*.HxC 117 | DocProject/Help/*.hhc 118 | DocProject/Help/*.hhk 119 | DocProject/Help/*.hhp 120 | DocProject/Help/Html2 121 | DocProject/Help/html 122 | 123 | # Click-Once directory 124 | publish/ 125 | 126 | # Publish Web Output 127 | *.[Pp]ublish.xml 128 | *.azurePubxml 129 | # TODO: Comment the next line if you want to checkin your web deploy settings 130 | # but database connection strings (with potential passwords) will be unencrypted 131 | *.pubxml 132 | *.publishproj 133 | 134 | # NuGet Packages 135 | *.nupkg 136 | # The packages folder can be ignored because of Package Restore 137 | **/packages/* 138 | # except build/, which is used as an MSBuild target. 139 | !**/packages/build/ 140 | # If using the old MSBuild-Integrated Package Restore, uncomment this: 141 | #!**/packages/repositories.config 142 | 143 | # Windows Azure Build Output 144 | csx/ 145 | *.build.csdef 146 | 147 | # Windows Store app package directory 148 | AppPackages/ 149 | 150 | # Others 151 | sql/ 152 | *.Cache 153 | ClientBin/ 154 | [Ss]tyle[Cc]op.* 155 | ~$* 156 | *~ 157 | *.dbmdl 158 | *.dbproj.schemaview 159 | *.pfx 160 | *.publishsettings 161 | node_modules/ 162 | 163 | # RIA/Silverlight projects 164 | Generated_Code/ 165 | 166 | # Backup & report files from converting an old project file 167 | # to a newer Visual Studio version. Backup files are not needed, 168 | # because we have git ;-) 169 | _UpgradeReport_Files/ 170 | Backup*/ 171 | .vs/ 172 | UpgradeLog*.XML 173 | UpgradeLog*.htm 174 | 175 | # SQL Server files 176 | *.mdf 177 | *.ldf 178 | 179 | # Business Intelligence projects 180 | *.rdl.data 181 | *.bim.layout 182 | *.bim_*.settings 183 | 184 | # Microsoft Fakes 185 | FakesAssemblies/ 186 | 187 | # ========================= 188 | # Operating System Files 189 | # ========================= 190 | 191 | # OSX 192 | # ========================= 193 | 194 | .DS_Store 195 | .AppleDouble 196 | .LSOverride 197 | 198 | # Thumbnails 199 | ._* 200 | 201 | # Files that might appear on external disk 202 | .Spotlight-V100 203 | .Trashes 204 | 205 | # Directories potentially created on remote AFP share 206 | .AppleDB 207 | .AppleDesktop 208 | Network Trash Folder 209 | Temporary Items 210 | .apdisk 211 | 212 | # Windows 213 | # ========================= 214 | 215 | # Windows image file caches 216 | Thumbs.db 217 | ehthumbs.db 218 | 219 | # Folder config file 220 | Desktop.ini 221 | 222 | # Recycle Bin used on file shares 223 | $RECYCLE.BIN/ 224 | 225 | # Windows Installer files 226 | *.cab 227 | *.msi 228 | *.msm 229 | *.msp 230 | 231 | # Windows shortcuts 232 | *.lnk 233 | -------------------------------------------------------------------------------- /ScnEditorGUI/ScnEditorGUI.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {838B7676-AEB7-4509-B1D0-E439D6599D0D} 8 | WinExe 9 | Properties 10 | ScnEditorGUI 11 | ScnEditorGUI 12 | v4.6 13 | 512 14 | 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | false 26 | 27 | 28 | AnyCPU 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | false 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | Form 52 | 53 | 54 | Find.cs 55 | 56 | 57 | Form 58 | 59 | 60 | Form1.cs 61 | 62 | 63 | 64 | 65 | Find.cs 66 | 67 | 68 | Form1.cs 69 | 70 | 71 | ResXFileCodeGenerator 72 | Resources.Designer.cs 73 | Designer 74 | 75 | 76 | True 77 | Resources.resx 78 | True 79 | 80 | 81 | 82 | SettingsSingleFileGenerator 83 | Settings.Designer.cs 84 | 85 | 86 | True 87 | Settings.settings 88 | True 89 | 90 | 91 | 92 | 93 | {77b183f4-656e-4fec-a424-891382b64fa9} 94 | KrKrSceneManager 95 | 96 | 97 | 98 | 105 | -------------------------------------------------------------------------------- /KrKrSceneManager/Algorithms.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Runtime.CompilerServices; 5 | using System.Runtime.InteropServices; 6 | using System.Text; 7 | 8 | namespace KrKrSceneManager { 9 | internal static class Tools { 10 | internal static void CompressData(byte[] inData, int compression, out byte[] outData) { 11 | using (MemoryStream outMemoryStream = new MemoryStream()) 12 | using (ZOutputStream outZStream = new ZOutputStream(outMemoryStream, compression)) 13 | using (Stream inMemoryStream = new MemoryStream(inData)) { 14 | CopyStream(inMemoryStream, outZStream); 15 | outZStream.Finish(); 16 | outData = outMemoryStream.ToArray(); 17 | } 18 | } 19 | internal static void CopyStream(Stream input, Stream output) { 20 | byte[] Buffer = new byte[2000]; 21 | int len; 22 | while ((len = input.Read(Buffer, 0, Buffer.Length)) > 0) { 23 | output.Write(Buffer, 0, len); 24 | } 25 | output.Flush(); 26 | } 27 | internal static void DecompressData(byte[] inData, out byte[] outData) { 28 | try { 29 | using (Stream inMemoryStream = new MemoryStream(inData)) 30 | using (ZInputStream outZStream = new ZInputStream(inMemoryStream)) { 31 | MemoryStream outMemoryStream = new MemoryStream(); 32 | CopyStream(outZStream, outMemoryStream); 33 | outData = outMemoryStream.ToArray(); 34 | } 35 | } 36 | catch { 37 | outData = new byte[0]; 38 | } 39 | } 40 | 41 | public static string ReadCString(this Stream Stream, Encoding Encoding = null) { 42 | if (Encoding == null) 43 | Encoding = Encoding.UTF8; 44 | 45 | int LastByte = 0; 46 | List Buffer = new List(); 47 | do { 48 | LastByte = Stream.ReadByte(); 49 | if (LastByte < 0) 50 | throw new InternalBufferOverflowException(); 51 | if (LastByte == 0) 52 | continue; 53 | Buffer.Add((byte)LastByte); 54 | } while (LastByte != 0); 55 | 56 | return Encoding.GetString(Buffer.ToArray()); 57 | } 58 | public static void WriteCString(this Stream Stream, string String, Encoding Encoding = null) 59 | { 60 | if (Encoding == null) 61 | Encoding = Encoding.UTF8; 62 | var Buffer = Encoding.GetBytes(String + "\x0"); 63 | Stream.WriteBytes(Buffer); 64 | } 65 | 66 | public static byte[] ReadBytes(this Stream Stream, int Count) { 67 | byte[] Buffer = new byte[Count]; 68 | if (Stream.Read(Buffer, 0, Buffer.Length) != Count) 69 | throw new Exception("Buffer Overflow Exception"); 70 | return Buffer; 71 | } 72 | public static void WriteBytes(this Stream Stream, byte[] Data) 73 | { 74 | Stream.Write(Data, 0, Data.Length); 75 | } 76 | 77 | public static T ReadStruct(this Stream Stream) where T : struct { 78 | byte[] Buffer = Stream.ReadBytes(Marshal.SizeOf(typeof(T))); 79 | return ParseStruct(Buffer); 80 | } 81 | 82 | public static void WriteStruct(this Stream Stream, T Struct) where T : struct 83 | { 84 | var Data = ParseStruct(Struct); 85 | Stream.Write(Data, 0, Data.Length); 86 | } 87 | 88 | public static T ParseStruct(this byte[] Data) where T : struct { 89 | var pStruct = Marshal.AllocHGlobal(Data.Length); 90 | Marshal.Copy(Data, 0, pStruct, Data.Length); 91 | T Struct = Marshal.PtrToStructure(pStruct); 92 | Marshal.FreeHGlobal(pStruct); 93 | return Struct; 94 | } 95 | public static byte[] ParseStruct(this T Struct) where T : struct { 96 | byte[] Buffer = new byte[Marshal.SizeOf(Struct)]; 97 | var pStruct = Marshal.AllocHGlobal(Buffer.Length); 98 | Marshal.StructureToPtr(Struct, pStruct, true); 99 | Marshal.Copy(pStruct, Buffer, 0, Buffer.Length); 100 | Marshal.FreeHGlobal(pStruct); 101 | return Buffer; 102 | } 103 | 104 | } 105 | 106 | internal struct PSBHeader { 107 | internal uint Signature; 108 | internal uint Version;//Tested: 1, 2, 3 109 | uint Unk; 110 | uint Unk2; 111 | internal uint StrOffPos; 112 | internal uint StrDataPos; 113 | internal uint ResOffPos; 114 | internal uint ResLenPos; 115 | internal uint ResDataPos; 116 | internal uint ResIndexTree; 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /KrKrSceneManager/Zlib/Adler32.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2006, ComponentAce 2 | // http://www.componentace.com 3 | // All rights reserved. 4 | 5 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 6 | 7 | // Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | // Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 9 | // Neither the name of ComponentAce nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 10 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 11 | 12 | 13 | 14 | /* 15 | Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. 16 | 17 | Redistribution and use in source and binary forms, with or without 18 | modification, are permitted provided that the following conditions are met: 19 | 20 | 1. Redistributions of source code must retain the above copyright notice, 21 | this list of conditions and the following disclaimer. 22 | 23 | 2. Redistributions in binary form must reproduce the above copyright 24 | notice, this list of conditions and the following disclaimer in 25 | the documentation and/or other materials provided with the distribution. 26 | 27 | 3. The names of the authors may not be used to endorse or promote products 28 | derived from this software without specific prior written permission. 29 | 30 | THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, 31 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 32 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, 33 | INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, 34 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 35 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 36 | OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 37 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 38 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 39 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 | */ 41 | /* 42 | * This program is based on zlib-1.1.3, so all credit should go authors 43 | * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) 44 | * and contributors of zlib. 45 | */ 46 | 47 | using System; 48 | 49 | namespace KrKrSceneManager 50 | { 51 | 52 | /// 53 | /// This class represents adler32 checksum algorithm 54 | /// 55 | internal class Adler32 56 | { 57 | 58 | // largest prime smaller than 65536 59 | private const int BASE = 65521; 60 | // NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 61 | private const int NMAX = 5552; 62 | 63 | /// 64 | /// This static method returns adler32 checksum of the buffer data 65 | /// 66 | internal static long GetAdler32Checksum(long adler, byte[] buf, int index, int len) 67 | { 68 | if (buf == null) 69 | { 70 | return 1L; 71 | } 72 | 73 | long s1 = adler & 0xffff; 74 | long s2 = (adler >> 16) & 0xffff; 75 | int k; 76 | 77 | while (len > 0) 78 | { 79 | k = len < NMAX?len:NMAX; 80 | len -= k; 81 | while (k >= 16) 82 | { 83 | s1 += (buf[index++] & 0xff); s2 += s1; 84 | s1 += (buf[index++] & 0xff); s2 += s1; 85 | s1 += (buf[index++] & 0xff); s2 += s1; 86 | s1 += (buf[index++] & 0xff); s2 += s1; 87 | s1 += (buf[index++] & 0xff); s2 += s1; 88 | s1 += (buf[index++] & 0xff); s2 += s1; 89 | s1 += (buf[index++] & 0xff); s2 += s1; 90 | s1 += (buf[index++] & 0xff); s2 += s1; 91 | s1 += (buf[index++] & 0xff); s2 += s1; 92 | s1 += (buf[index++] & 0xff); s2 += s1; 93 | s1 += (buf[index++] & 0xff); s2 += s1; 94 | s1 += (buf[index++] & 0xff); s2 += s1; 95 | s1 += (buf[index++] & 0xff); s2 += s1; 96 | s1 += (buf[index++] & 0xff); s2 += s1; 97 | s1 += (buf[index++] & 0xff); s2 += s1; 98 | s1 += (buf[index++] & 0xff); s2 += s1; 99 | k -= 16; 100 | } 101 | if (k != 0) 102 | { 103 | do 104 | { 105 | s1 += (buf[index++] & 0xff); s2 += s1; 106 | } 107 | while (--k != 0); 108 | } 109 | s1 %= BASE; 110 | s2 %= BASE; 111 | } 112 | return (s2 << 16) | s1; 113 | } 114 | 115 | } 116 | } -------------------------------------------------------------------------------- /ScnEditorGUI/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /ScnEditorGUI/Find.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /ScnEditorGUI/Form1.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | 124 | 172, 17 125 | 126 | -------------------------------------------------------------------------------- /KrKrSceneManager/Zlib/SupportClass.cs: -------------------------------------------------------------------------------- 1 | 2 | using System; 3 | 4 | 5 | namespace KrKrSceneManager 6 | { 7 | internal class SupportClass 8 | { 9 | /// 10 | /// This method returns the literal value received 11 | /// 12 | /// The literal to return 13 | /// The received value 14 | internal static long Identity(long literal) 15 | { 16 | return literal; 17 | } 18 | 19 | /// 20 | /// This method returns the literal value received 21 | /// 22 | /// The literal to return 23 | /// The received value 24 | internal static ulong Identity(ulong literal) 25 | { 26 | return literal; 27 | } 28 | 29 | /// 30 | /// This method returns the literal value received 31 | /// 32 | /// The literal to return 33 | /// The received value 34 | internal static float Identity(float literal) 35 | { 36 | return literal; 37 | } 38 | 39 | /// 40 | /// This method returns the literal value received 41 | /// 42 | /// The literal to return 43 | /// The received value 44 | internal static double Identity(double literal) 45 | { 46 | return literal; 47 | } 48 | 49 | /*******************************/ 50 | /// 51 | /// Performs an unsigned bitwise right shift with the specified number 52 | /// 53 | /// Number to operate on 54 | /// Ammount of bits to shift 55 | /// The resulting number from the shift operation 56 | internal static int URShift(int number, int bits) 57 | { 58 | if ( number >= 0) 59 | return number >> bits; 60 | else 61 | return (number >> bits) + (2 << ~bits); 62 | } 63 | 64 | /// 65 | /// Performs an unsigned bitwise right shift with the specified number 66 | /// 67 | /// Number to operate on 68 | /// Ammount of bits to shift 69 | /// The resulting number from the shift operation 70 | internal static int URShift(int number, long bits) 71 | { 72 | return URShift(number, (int)bits); 73 | } 74 | 75 | /// 76 | /// Performs an unsigned bitwise right shift with the specified number 77 | /// 78 | /// Number to operate on 79 | /// Ammount of bits to shift 80 | /// The resulting number from the shift operation 81 | internal static long URShift(long number, int bits) 82 | { 83 | if ( number >= 0) 84 | return number >> bits; 85 | else 86 | return (number >> bits) + (2L << ~bits); 87 | } 88 | 89 | /// 90 | /// Performs an unsigned bitwise right shift with the specified number 91 | /// 92 | /// Number to operate on 93 | /// Ammount of bits to shift 94 | /// The resulting number from the shift operation 95 | internal static long URShift(long number, long bits) 96 | { 97 | return URShift(number, (int)bits); 98 | } 99 | 100 | /*******************************/ 101 | /// Reads a number of characters from the current source Stream and writes the data to the target array at the specified index. 102 | /// The source Stream to read from. 103 | /// Contains the array of characteres read from the source Stream. 104 | /// The starting index of the target array. 105 | /// The maximum number of characters to read from the source Stream. 106 | /// The number of characters read. The number will be less than or equal to count depending on the data available in the source Stream. Returns -1 if the end of the stream is reached. 107 | internal static System.Int32 ReadInput(System.IO.Stream sourceStream, byte[] target, int start, int count) 108 | { 109 | // Returns 0 bytes if not enough space in target 110 | if (target.Length == 0) 111 | return 0; 112 | 113 | byte[] receiver = new byte[target.Length]; 114 | int bytesRead = sourceStream.Read(receiver, start, count); 115 | 116 | // Returns -1 if EOF 117 | if (bytesRead == 0) 118 | return -1; 119 | 120 | for(int i = start; i < start + bytesRead; i++) 121 | target[i] = (byte)receiver[i]; 122 | 123 | return bytesRead; 124 | } 125 | 126 | /// Reads a number of characters from the current source TextReader and writes the data to the target array at the specified index. 127 | /// The source TextReader to read from 128 | /// Contains the array of characteres read from the source TextReader. 129 | /// The starting index of the target array. 130 | /// The maximum number of characters to read from the source TextReader. 131 | /// The number of characters read. The number will be less than or equal to count depending on the data available in the source TextReader. Returns -1 if the end of the stream is reached. 132 | internal static System.Int32 ReadInput(System.IO.TextReader sourceTextReader, byte[] target, int start, int count) 133 | { 134 | // Returns 0 bytes if not enough space in target 135 | if (target.Length == 0) return 0; 136 | 137 | char[] charArray = new char[target.Length]; 138 | int bytesRead = sourceTextReader.Read(charArray, start, count); 139 | 140 | // Returns -1 if EOF 141 | if (bytesRead == 0) return -1; 142 | 143 | for(int index=start; index 150 | /// Converts a string to an array of bytes 151 | /// 152 | /// The string to be converted 153 | /// The new array of bytes 154 | internal static byte[] ToByteArray(System.String sourceString) 155 | { 156 | return System.Text.UTF8Encoding.UTF8.GetBytes(sourceString); 157 | } 158 | 159 | /// 160 | /// Converts an array of bytes to an array of chars 161 | /// 162 | /// The array of bytes to convert 163 | /// The new array of chars 164 | internal static char[] ToCharArray(byte[] byteArray) 165 | { 166 | return System.Text.UTF8Encoding.UTF8.GetChars(byteArray); 167 | } 168 | 169 | 170 | } 171 | } -------------------------------------------------------------------------------- /KrKrSceneManager/Zlib/StaticTree.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2006, ComponentAce 2 | // http://www.componentace.com 3 | // All rights reserved. 4 | 5 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 6 | 7 | // Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | // Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 9 | // Neither the name of ComponentAce nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 10 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 11 | 12 | /* 13 | Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. 14 | 15 | Redistribution and use in source and binary forms, with or without 16 | modification, are permitted provided that the following conditions are met: 17 | 18 | 1. Redistributions of source code must retain the above copyright notice, 19 | this list of conditions and the following disclaimer. 20 | 21 | 2. Redistributions in binary form must reproduce the above copyright 22 | notice, this list of conditions and the following disclaimer in 23 | the documentation and/or other materials provided with the distribution. 24 | 25 | 3. The names of the authors may not be used to endorse or promote products 26 | derived from this software without specific prior written permission. 27 | 28 | THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, 29 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 30 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, 31 | INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, 32 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 33 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 34 | OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 35 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 36 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 37 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 | */ 39 | /* 40 | * This program is based on zlib-1.1.3, so all credit should go authors 41 | * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) 42 | * and contributors of zlib. 43 | */ 44 | using System; 45 | 46 | 47 | namespace KrKrSceneManager 48 | { 49 | 50 | internal sealed class StaticTree 51 | { 52 | 53 | #region Fields 54 | 55 | private const int BL_CODES = 19; 56 | private const int D_CODES = 30; 57 | private const int LITERALS = 256; 58 | private const int LENGTH_CODES = 29; 59 | private const int L_CODES = (LITERALS + 1 + LENGTH_CODES); 60 | 61 | /// 62 | /// Bit length codes must not exceed MAX_BL_BITS bits 63 | /// 64 | internal const int MAX_BL_BITS = 7; 65 | 66 | internal static readonly short[] static_ltree = new short[]{12, 8, 140, 8, 76, 8, 204, 8, 44, 8, 172, 8, 108, 8, 236, 8, 28, 8, 156, 8, 92, 8, 220, 8, 60, 8, 188, 8, 124, 8, 252, 8, 2, 8, 130, 8, 66, 8, 194, 8, 34, 8, 162, 8, 98, 8, 226, 8, 18, 8, 146, 8, 82, 8, 210, 8, 50, 8, 178, 8, 114, 8, 242, 8, 10, 8, 138, 8, 74, 8, 202, 8, 42, 8, 170, 8, 106, 8, 234, 8, 26, 8, 154, 8, 90, 8, 218, 8, 58, 8, 186, 8, 122, 8, 250, 8, 6, 8, 134, 8, 70, 8, 198, 8, 38, 8, 166, 8, 102, 8, 230, 8, 22, 8, 150, 8, 86, 8, 214, 8, 54, 8, 182, 8, 118, 8, 246, 8, 14, 8, 142, 8, 78, 8, 206, 8, 46, 8, 174, 8, 110, 8, 238, 8, 30, 8, 158, 8, 94, 8, 222, 8, 62, 8, 190, 8, 126, 8, 254, 8, 1, 8, 129, 8, 65, 8, 193, 8, 33, 8, 161, 8, 97, 8, 225, 8, 17, 8, 145, 8, 81, 8, 209, 8, 49, 8, 177, 8, 113, 8, 241, 8, 9, 8, 137, 8, 73, 8, 201, 8, 41, 8, 169, 8, 105, 8, 233, 8, 25, 8, 153, 8, 89, 8, 217, 8, 57, 8, 185, 8, 121, 8, 249, 8, 5, 8, 133, 8, 69, 8, 197, 8, 37, 8, 165, 8, 101, 8, 229, 8, 21, 8, 149, 8, 85, 8, 213, 8, 53, 8, 181, 8, 117, 8, 245, 8, 13, 8, 141, 8, 77, 8, 205, 8, 45, 8, 173, 8, 109, 8, 237, 8, 29, 8, 157, 8, 93, 8, 221, 8, 61, 8, 189, 8, 125, 8, 253, 8, 19, 9, 275, 9, 147, 9, 403, 9, 83, 9, 339, 9, 211, 9, 467, 9, 51, 9, 307, 9, 179, 9, 435, 9, 115, 9, 371, 9, 243, 9, 499, 9, 11, 9, 267, 9, 139, 9, 395, 9, 75, 9, 331, 9, 203, 9, 459, 9, 43, 9, 299, 9, 171, 9, 427, 9, 107, 9, 363, 9, 235, 9, 491, 9, 27, 9, 283, 9, 155, 9, 411, 9, 91, 9, 347, 9, 219, 9, 475, 9, 59, 9, 315, 9, 187, 9, 443, 9, 123, 9, 379, 9, 251, 9, 507, 9, 7, 9, 263, 9, 135, 9, 391, 9, 71, 9, 327, 9, 199, 9, 455, 9, 39, 9, 295, 9, 167, 9, 423, 9, 103, 9, 359, 9, 231, 9, 487, 9, 23, 9, 279, 9, 151, 9, 407, 9, 87, 9, 343, 9, 215, 9, 471, 9, 55, 9, 311, 9, 183, 9, 439, 9, 119, 9, 375, 9, 247, 9, 503, 9, 15, 9, 271, 9, 143, 9, 399, 9, 79, 9, 335, 9, 207, 9, 463, 9, 47, 9, 303, 9, 175, 9, 431, 9, 111, 9, 367, 9, 239, 9, 495, 9, 31, 9, 287, 9, 159, 9, 415, 9, 95, 9, 351, 9, 223, 9, 479, 9, 63, 9, 319, 9, 191, 9, 447, 9, 127, 9, 383, 9, 255, 9, 511, 9, 0, 7, 64, 7 67 | , 32, 7, 96, 7, 16, 7, 80, 7, 48, 7, 112, 7, 8, 7, 72, 7, 40, 7, 104, 7, 24, 7, 88, 7, 56, 7, 120, 7, 4, 7, 68, 7, 36, 7, 100, 7, 20, 7, 84, 7, 52, 7, 116, 7, 3, 8, 131, 8, 67, 8, 195, 8, 35, 8, 163, 8, 99, 8, 227, 8}; 68 | 69 | internal static readonly short[] static_dtree = new short[] { 0, 5, 16, 5, 8, 5, 24, 5, 4, 5, 20, 5, 12, 5, 28, 5, 2, 5, 18, 5, 10, 5, 26, 5, 6, 5, 22, 5, 14, 5, 30, 5, 1, 5, 17, 5, 9, 5, 25, 5, 5, 5, 21, 5, 13, 5, 29, 5, 3, 5, 19, 5, 11, 5, 27, 5, 7, 5, 23, 5 }; 70 | 71 | internal static StaticTree static_l_desc; 72 | 73 | internal static StaticTree static_d_desc; 74 | 75 | internal static StaticTree static_bl_desc; 76 | 77 | internal short[] static_tree; // static tree or null 78 | internal int[] extra_bits; // extra bits for each code or null 79 | internal int extra_base; // base index for extra_bits 80 | internal int elems; // max number of elements in the tree 81 | internal int max_length; // max bit length for the codes 82 | 83 | 84 | #endregion 85 | 86 | #region Constructors 87 | 88 | internal StaticTree(short[] static_tree, int[] extra_bits, int extra_base, int elems, int max_length) 89 | { 90 | this.static_tree = static_tree; 91 | this.extra_bits = extra_bits; 92 | this.extra_base = extra_base; 93 | this.elems = elems; 94 | this.max_length = max_length; 95 | } 96 | static StaticTree() 97 | { 98 | static_l_desc = new StaticTree(static_ltree, ZLibUtil.extra_lbits, LITERALS + 1, L_CODES, ZLibUtil.MAX_WBITS); 99 | static_d_desc = new StaticTree(static_dtree, ZLibUtil.extra_dbits, 0, D_CODES, ZLibUtil.MAX_WBITS); 100 | static_bl_desc = new StaticTree(null, ZLibUtil.extra_blbits, 0, BL_CODES, MAX_BL_BITS); 101 | } 102 | #endregion 103 | } 104 | } -------------------------------------------------------------------------------- /KrKrSceneManager/PSBAnalyzer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace KrKrSceneManager { 5 | 6 | /// 7 | /// A Proxy to the StringManager that tries desort the stirng order. 8 | /// 9 | public class PSBAnalyzer { 10 | bool Warning = false; 11 | bool EmbeddedReferenced = false; 12 | 13 | /// 14 | /// Says if he analyzer found a unk opcode 15 | /// 16 | public bool UnkOpCodes { 17 | get { 18 | return Warning; 19 | } 20 | } 21 | 22 | /// 23 | /// Says if the analyzer found a Embedded content in this PSB 24 | /// 25 | public bool HaveEmbedded { 26 | get { 27 | return EmbeddedReferenced; 28 | } 29 | 30 | } 31 | 32 | public bool ExtendStringLimit = true; 33 | public bool CompressPackage = true; 34 | public int CompressionLevel = 9; 35 | 36 | uint ByteCodeStart; 37 | uint ByteCodeLen = 0; 38 | string[] Strings; 39 | byte[] Script; 40 | PSBStrMan StringManager; 41 | List Calls = new List(); 42 | public PSBAnalyzer(byte[] Script) { 43 | var Status = PSBStrMan.GetPackgetStatus(Script); 44 | if (Status == PSBStrMan.PackgetStatus.MDF) 45 | Script = PSBStrMan.ExtractMDF(Script); 46 | Status = PSBStrMan.GetPackgetStatus(Script); 47 | if (Status != PSBStrMan.PackgetStatus.PSB) 48 | throw new Exception("Bad File Format"); 49 | 50 | this.Script = new byte[Script.Length]; 51 | Script.CopyTo(this.Script, 0); 52 | 53 | StringManager = new PSBStrMan(Script) { 54 | CompressPackage = true, 55 | ForceMaxOffsetLength = ExtendStringLimit 56 | }; 57 | 58 | ByteCodeStart = ReadOffset(this.Script, 0x24, 4); 59 | ByteCodeLen = ReadOffset(this.Script, 0x10, 4) - ByteCodeStart; 60 | 61 | if (ByteCodeLen + ByteCodeStart > Script.Length) 62 | throw new Exception("Corrupted Script"); 63 | } 64 | 65 | public string[] Import() { 66 | EmbeddedReferenced = false; 67 | Warning = false; 68 | 69 | Calls = new List(); 70 | Strings = StringManager.Import(); 71 | for (uint i = ByteCodeStart; i < ByteCodeLen + ByteCodeStart; ) { 72 | try { 73 | var Result = Analyze(Script, ref i); 74 | 75 | foreach (uint ID in Result) 76 | if (ID < Strings.LongLength && !Calls.Contains(ID)) 77 | Calls.Add(ID); 78 | } catch { } 79 | } 80 | 81 | //Prevent Missmatch 82 | for (uint i = 0; i < Strings.LongLength; i++) 83 | if (!Calls.Contains(i)) 84 | Calls.Add(i); 85 | 86 | return Desort(Strings, Calls.ToArray()); 87 | } 88 | 89 | public byte[] Export(string[] Strings) { 90 | string[] Content = Sort(Strings, Calls.ToArray()); 91 | 92 | StringManager.CompressPackage = CompressPackage; 93 | PSBStrMan.CompressionLevel = CompressionLevel; 94 | 95 | return StringManager.Export(Content); 96 | } 97 | 98 | private string[] Desort(string[] Strings, uint[] Map) { 99 | if (Map.Length != Strings.Length) 100 | throw new Exception("String Calls Count Missmatch"); 101 | 102 | string[] Result = new string[Strings.LongLength]; 103 | for (uint i = 0; i < Map.LongLength; i++) { 104 | Result[i] = Strings[Map[i]]; 105 | } 106 | 107 | return Result; 108 | } 109 | 110 | private string[] Sort(string[] Strings, uint[] Map) { 111 | if (Map.Length != Strings.Length) 112 | throw new Exception("String Calls Count Mismatch"); 113 | 114 | 115 | string[] Result = new string[Strings.LongLength]; 116 | for (uint i = 0; i < Map.LongLength; i++) { 117 | Result[Map[i]] = Strings[i]; 118 | } 119 | 120 | return Result; 121 | 122 | } 123 | 124 | //Here a shit sample how to detect the string order, now plz, don't send-me more emails about this. 125 | private uint[] Analyze(byte[] Script, ref uint Index) { 126 | byte Cmd = Script[Index]; 127 | 128 | uint ID = 0; 129 | List IDs = new List(); 130 | switch (Cmd) { 131 | //Strings - Hay \o/ 132 | case 0x15: 133 | IDs.Add(ReadOffset(Script, Index + 1, 1)); 134 | Index += 2; 135 | break; 136 | case 0x16: 137 | IDs.Add(ReadOffset(Script, Index + 1, 2)); 138 | Index += 3; 139 | break; 140 | case 0x17: 141 | IDs.Add(ReadOffset(Script, Index + 1, 3)); 142 | Index += 4; 143 | break; 144 | case 0x18: 145 | IDs.Add(ReadOffset(Script, Index + 1, 4)); 146 | Index += 5; 147 | break; 148 | 149 | //Numbers 150 | case 0x4: 151 | case 0x5: 152 | case 0x6: 153 | case 0x7: 154 | case 0x8: 155 | case 0x9: 156 | case 0xA: 157 | case 0xB: 158 | case 0xC: 159 | Index++; 160 | Index += (uint)Cmd - 0x4; 161 | break; 162 | 163 | case 0x1D: 164 | Index++; 165 | break; 166 | case 0x1E: 167 | Index++; 168 | Index += 4; 169 | break; 170 | case 0x1F: 171 | Index++; 172 | Index += 8; 173 | break; 174 | 175 | //Constants 176 | case 0x0: 177 | case 0x1: 178 | case 0x2: 179 | case 0x3: 180 | Index++; 181 | break; 182 | 183 | //Arrays 184 | case 0x0D: 185 | case 0x0E: 186 | case 0x0F: 187 | case 0x10: 188 | case 0x11: 189 | case 0x12: 190 | case 0x13: 191 | case 0x14: 192 | Index++; 193 | uint CLen = (uint)Cmd - 0xC; 194 | uint Count = ReadOffset(Script, Index, CLen); 195 | Index += CLen; 196 | 197 | uint ELen = (uint)Script[Index++] - 0xC; 198 | Index += ELen * Count; 199 | 200 | break; 201 | 202 | case 0x20: 203 | Index++; 204 | IDs.AddRange(Analyze(Script, ref Index)); 205 | break; 206 | 207 | case 0x21: 208 | Index++; 209 | IDs.AddRange(Analyze(Script, ref Index)); 210 | IDs.AddRange(Analyze(Script, ref Index)); 211 | break; 212 | 213 | //References to the Embedded Content 214 | case 0x19: 215 | case 0x1A: 216 | case 0x1B: 217 | case 0x1C: 218 | EmbeddedReferenced = true; 219 | Index++; 220 | Index += (uint)Cmd - 0x18; 221 | break; 222 | 223 | //Fuck 224 | default: 225 | Warning = true; 226 | Index++; 227 | break; 228 | } 229 | 230 | return IDs.ToArray(); 231 | } 232 | 233 | internal static uint ReadOffset(byte[] Script, uint Index, uint Length) { 234 | byte[] Value = new byte[8]; 235 | Array.Copy(Script, Index, Value, 0, Length); 236 | return (uint)BitConverter.ToUInt64(Value, 0);//.Net Only works with array of Int.MaxValue of Length; 237 | } 238 | } 239 | } 240 | -------------------------------------------------------------------------------- /KrKrSceneManager/TJS2Manager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | 4 | namespace KrKrSceneManager { 5 | public partial class TJS2SManager { 6 | public static Sector[] Split(byte[] TJS2) { 7 | uint TJS2Len = Commom.GetDW(TJS2, 0x08); 8 | if (TJS2Len != TJS2.Length) 9 | throw new Exception("Corrupted File"); 10 | uint Pointer = 0x0C; 11 | //First, Data Sector 12 | Sector Data = new Sector(TJS2, Pointer); 13 | Pointer += Data.FullLength; 14 | 15 | Sector[] Unk = new Sector[Commom.GetDW(TJS2, Pointer)];//i assume is another sector... 16 | Pointer += 4; 17 | for (int i = 0; i < Unk.Length; i++) { 18 | Sector sector = new Sector(TJS2, Pointer); 19 | Pointer += sector.FullLength; 20 | Unk[i] = sector; 21 | } 22 | 23 | Sector[] TJS = new Sector[Commom.GetDW(TJS2, Pointer)]; 24 | Pointer += 4; 25 | for (int i = 0; i < TJS.Length; i++) { 26 | Sector sector = new Sector(TJS2, Pointer); 27 | Pointer += sector.FullLength; 28 | TJS[i] = sector; 29 | } 30 | 31 | //Merge Results 32 | Sector[] Sectors = new Sector[Unk.Length + TJS.Length + 1];//+1 = DATA Sector 33 | Sectors[0] = Data; 34 | Unk.CopyTo(Sectors, 1); 35 | TJS.CopyTo(Sectors, Unk.Length + 1); 36 | return Sectors; 37 | } 38 | 39 | public static byte[] Merge(Sector[] Sectors) { 40 | byte[] Header = new byte[] { 0x54, 0x4A, 0x53, 0x32, 0x31, 0x30, 0x30, 0x00 }; //Signature + Version 41 | 42 | //Diff all Sectors 43 | Sector DATA = null; 44 | Sector[] Other = new Sector[0]; 45 | Sector[] TJS = new Sector[0]; 46 | foreach (Sector sec in Sectors) 47 | switch (sec.SectorType) { 48 | case SectorType.DATA: 49 | DATA = sec; 50 | break; 51 | case SectorType.Other: 52 | Append(ref Other, sec); 53 | break; 54 | case SectorType.TJS2: 55 | Append(ref TJS, sec); 56 | break; 57 | } 58 | 59 | //Data Segment and Header 60 | byte[] OutTJS2 = new byte[Header.Length + 4]; 61 | Header.CopyTo(OutTJS2, 0); 62 | Append(ref OutTJS2, DATA.Generate()); 63 | 64 | //Others Segments 65 | Append(ref OutTJS2, Commom.GenDW((uint)Other.Length)); 66 | foreach (Sector sec in Other) 67 | Append(ref OutTJS2, sec.Generate()); 68 | 69 | //TJS2 Segments 70 | Append(ref OutTJS2, Commom.GenDW((uint)TJS.Length)); 71 | foreach (Sector sec in TJS) 72 | Append(ref OutTJS2, sec.Generate()); 73 | 74 | //Last Header Information, File Length 75 | Commom.GenDW((uint)OutTJS2.Length).CopyTo(OutTJS2, 0x08); 76 | 77 | return OutTJS2; 78 | } 79 | 80 | public static string[] GetContent(Sector sector) { 81 | if (sector.Type != "DATA") 82 | throw new Exception("Sector Type Not Supported"); 83 | byte[] Data = sector.Content; 84 | 85 | uint StrPos; 86 | FindStringPos(out StrPos, Data); 87 | 88 | string[] Strings = new string[Commom.GetDW(Data, StrPos)]; 89 | StrPos += 4; 90 | for (int i = 0; i < Strings.Length; i++) { 91 | uint StringLength = Commom.GetDW(Data, StrPos) * 2; 92 | StrPos += 4; 93 | Strings[i] = Encoding.Unicode.GetString(Data, (int)StrPos, (int)StringLength);//Fuck the uint, if you need you copy to new array 94 | StrPos += StringLength; 95 | StrPos = Round(StrPos, 4); 96 | } 97 | return Strings; 98 | } 99 | 100 | public static void SetContent(ref Sector sector, string[] Strings) { 101 | if (sector.Type != "DATA") 102 | throw new Exception("Sector Type Not Supported"); 103 | byte[] Data = sector.Content; 104 | 105 | //Load Positions 106 | uint StrPos; 107 | FindStringPos(out StrPos, Data); 108 | uint EndPos = FindStrEnd(StrPos, Data); 109 | 110 | //Copy Int Non-String Data 111 | byte[] Values = new byte[StrPos]; 112 | Array.Copy(Data, 0, Values, 0, Values.Length); 113 | 114 | byte[] StringTable = new byte[4]; 115 | Commom.GenDW((uint)Strings.Length).CopyTo(StringTable, 0);//String Count 116 | 117 | //Generate String Table 118 | foreach (string String in Strings) { 119 | uint StrLen = Round((uint)String.Length * 2, 4); 120 | byte[] StrEntry = new byte[StrLen + 4]; 121 | Commom.GenDW((uint)String.Length).CopyTo(StrEntry, 0); 122 | Encoding.Unicode.GetBytes(String).CopyTo(StrEntry, 4); 123 | Append(ref StringTable, StrEntry); 124 | } 125 | 126 | //Copy Object Values 127 | byte[] OBJS = new byte[Data.Length - EndPos]; 128 | Array.Copy(Data, EndPos, OBJS, 0, OBJS.Length); 129 | 130 | //Generate Sector Content 131 | byte[] NewContent = new byte[Values.Length + StringTable.Length + OBJS.Length]; 132 | Values.CopyTo(NewContent, 0); 133 | StringTable.CopyTo(NewContent, Values.Length); 134 | OBJS.CopyTo(NewContent, Values.Length + StringTable.Length); 135 | 136 | //Return 137 | sector.Content = NewContent; 138 | } 139 | 140 | private static void Append(ref byte[] DataTable, byte[] DataToAppend) { 141 | byte[] Out = new byte[DataTable.Length + DataToAppend.Length]; 142 | DataTable.CopyTo(Out, 0); 143 | DataToAppend.CopyTo(Out, DataTable.Length); 144 | DataTable = Out; 145 | } 146 | 147 | private static void Append(ref Sector[] DataTable, Sector SectorToAppend) { 148 | Sector[] Out = new Sector[DataTable.Length + 1]; 149 | DataTable.CopyTo(Out, 0); 150 | Out[DataTable.Length] = SectorToAppend; 151 | DataTable = Out; 152 | } 153 | private static uint FindStrEnd(uint StrPos, byte[] Data) { 154 | uint Count = Commom.GetDW(Data, StrPos); 155 | StrPos += 4; 156 | for (uint i = 0; i < Count; i++) { 157 | uint len = Commom.GetDW(Data, StrPos); 158 | StrPos += 4 + Round(len * 2, 4); 159 | } 160 | return StrPos; 161 | } 162 | private static void FindStringPos(out uint StrPos, byte[] Data) { 163 | StrPos = Commom.GetDW(Data, 0) + 4; //Skip 8 Bits Array 164 | StrPos = Round(StrPos, 4); 165 | 166 | StrPos += (Commom.GetDW(Data, StrPos) * 2) + 4; //Skip 16 Bits Array 167 | StrPos = Round(StrPos, 4); 168 | 169 | StrPos += (Commom.GetDW(Data, StrPos) * 4) + 4; //Skip 32 Bits Array 170 | StrPos = Round(StrPos, 4); 171 | 172 | StrPos += (Commom.GetDW(Data, StrPos) * 8) + 4; //Skip 64 Bits Array 173 | StrPos = Round(StrPos, 4); 174 | 175 | StrPos += (Commom.GetDW(Data, StrPos) * 8) + 4; //Skip 64 Bits wtf (IEEE Float?) 176 | StrPos = Round(StrPos, 4); 177 | } 178 | 179 | private static uint Round(uint Value, uint Multiplier) { 180 | while (Value % Multiplier != 0) 181 | Value++; 182 | return Value; 183 | } 184 | } 185 | 186 | public class Sector { 187 | internal string Type = string.Empty; 188 | public SectorType SectorType { get { 189 | switch (Type) { 190 | case "DATA": 191 | return SectorType.DATA; 192 | case "TJS2": 193 | return SectorType.TJS2; 194 | default: 195 | return SectorType.Other; 196 | } 197 | } 198 | } 199 | 200 | internal byte[] Content; 201 | 202 | internal uint FullLength { get { return (uint)(Content.Length + 8L); } } 203 | 204 | internal Sector(byte[] Data, uint SectorPos) { 205 | //Get Signature 206 | Type = Encoding.ASCII.GetString(Data, (int)SectorPos, 0x04); 207 | 208 | //Get Content 209 | Content = new byte[Commom.GetDW(Data, SectorPos + 4)]; 210 | Array.Copy(Data, SectorPos + 8, Content, 0, Content.Length); 211 | } 212 | 213 | internal byte[] Generate() { 214 | //Create new Variable 215 | byte[] sector = new byte[FullLength]; 216 | 217 | //Write Signature 218 | Encoding.ASCII.GetBytes(Type).CopyTo(sector, 0); 219 | 220 | //Write Header (Content Length) 221 | Commom.GenDW((uint)Content.Length).CopyTo(sector, 0x04); 222 | 223 | //Write Content 224 | Array.Copy(Content, 0, sector, 0x08, Content.Length); 225 | 226 | //Return 227 | return sector; 228 | } 229 | } 230 | 231 | public enum SectorType { DATA, TJS2, Other} 232 | internal static class Commom { 233 | internal static uint GetDW(byte[] data, uint pos) { 234 | byte[] DW = new byte[4]; 235 | Array.Copy(data, pos, DW, 0, DW.Length); 236 | if (!BitConverter.IsLittleEndian) 237 | Array.Reverse(DW, 0, DW.Length); 238 | uint val = BitConverter.ToUInt32(DW, 0); 239 | return val; 240 | } 241 | 242 | internal static byte[] GenDW(uint value) { 243 | byte[] DW = BitConverter.GetBytes(value); 244 | if (DW.Length != 4) 245 | throw new Exception("WTF"); 246 | if (!BitConverter.IsLittleEndian) 247 | Array.Reverse(DW, 0, DW.Length); 248 | return DW; 249 | } 250 | } 251 | 252 | public partial class TJS2SManager { 253 | Sector[] Sectors; 254 | int DataIndex; 255 | public TJS2SManager(byte[] Script) { 256 | Sectors = Split(Script); 257 | for (int i = 0; i < Sectors.Length; i++) { 258 | if (Sectors[i].SectorType == SectorType.DATA) { 259 | DataIndex = i; 260 | return; 261 | } 262 | } 263 | throw new Exception("Failed"); 264 | } 265 | 266 | public string[] Import() { 267 | return GetContent(Sectors[DataIndex]); 268 | } 269 | 270 | public byte[] Export(string[] Strings) { 271 | SetContent(ref Sectors[DataIndex], Strings); 272 | return Merge(Sectors); 273 | } 274 | } 275 | } 276 | -------------------------------------------------------------------------------- /KrKrSceneManager/PSBResourceManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace KrKrSceneManager { 7 | 8 | public class PSBResManager { 9 | 10 | private byte[] packget; 11 | public int EntryCount { get; private set; } 12 | public int ResSizePos { get; private set; } 13 | 14 | private bool Initialized; 15 | private int OffsetPos; 16 | private int OffsetSize; 17 | private int OffsetTablePos; 18 | private int StartPos; 19 | private int ResSizeOffSize; 20 | private int ResSizeOffTablePos; 21 | 22 | public bool CompressPackget = false; 23 | public int CompressionLevel = 9; 24 | public bool FixOffsets = true; 25 | public FileEntry[] Import(byte[] script) { 26 | PSBStrMan.PackgetStatus Status = PSBStrMan.GetPackgetStatus(script); 27 | if (Status == PSBStrMan.PackgetStatus.MDF) 28 | script = PSBStrMan.ExtractMDF(script); 29 | Status = PSBStrMan.GetPackgetStatus(script); 30 | if (Status != PSBStrMan.PackgetStatus.PSB) 31 | throw new Exception("Bad File Format"); 32 | 33 | packget = script; 34 | StartPos = PSBStrMan.ReadOffset(packget, 0x20, 4); 35 | OffsetPos = PSBStrMan.ReadOffset(packget, 0x18, 4); 36 | int[] tmp = GetOffsetInfo(packget, OffsetPos); 37 | OffsetSize = tmp[0]; 38 | OffsetTablePos = tmp[1]; 39 | ResSizePos = PSBStrMan.ReadOffset(packget, 0x1C, 4); 40 | tmp = GetOffsetInfo(packget, ResSizePos); 41 | ResSizeOffSize = tmp[0]; 42 | ResSizeOffTablePos = tmp[1]; 43 | int[] Offsets = GetValues(packget, OffsetPos); 44 | int[] Sizes = GetValues(packget, ResSizePos); 45 | EntryCount = Offsets.Length; 46 | FileEntry[] Files = new FileEntry[EntryCount]; 47 | for (int i = 0; i < EntryCount; i++) { 48 | int EndPos = Offsets[i] + Sizes[i]; 49 | byte[] data = new byte[Sizes[i]]; 50 | for (int ind = Offsets[i]; ind < EndPos; ind++) 51 | data[ind - Offsets[i]] = packget[ind + StartPos]; 52 | Files[i] = new FileEntry() { Data = data }; 53 | } 54 | Initialized = true; 55 | return Files; 56 | } 57 | 58 | 59 | private int[] GetOffsetInfo(byte[] file, int pos) { 60 | int OffSize = PSBStrMan.ConvertSize(file[pos]); 61 | int Count = PSBStrMan.ReadOffset(file, pos + 1, OffSize); 62 | pos += 1 + OffSize; 63 | //return[0] = OffsetSize; 64 | //return[1] = StartOffsetPos; 65 | //return[2] = EntryCount; 66 | return new int[] { PSBStrMan.ConvertSize(file[pos]), pos + 1, Count }; 67 | } 68 | 69 | private int[] GetValues(byte[] file, int pos) { 70 | int[] tmp = GetOffsetInfo(file, pos); 71 | int[] Result = new int[tmp[2]]; 72 | pos = tmp[1]; 73 | int OffSize = tmp[0]; 74 | for (int i = 0; i < Result.Length; i++) { 75 | Result[i] = PSBStrMan.ReadOffset(file, pos + (i * OffSize), OffSize); 76 | } 77 | return Result; 78 | } 79 | public byte[] Export(FileEntry[] Resources) { 80 | if (!Initialized) 81 | throw new Exception("You need to import before you can export!"); 82 | if (Resources.Length != EntryCount) 83 | throw new Exception("You can't add or delete resources!"); 84 | int TotalSize = 0; 85 | for (int i = 0; i < Resources.Length; i++) 86 | TotalSize += Resources[i].Data.Length + (FixOffsets && i + 1 != Resources.Length ? 4 - ((StartPos + TotalSize + Resources[i].Data.Length) % 4) : 0); 87 | byte[] ResTable = new byte[TotalSize]; 88 | TotalSize = 0; 89 | byte[] MainData = CutAt(packget, StartPos); 90 | for (int i = 0; i < Resources.Length; i++) { 91 | byte[] file = Resources[i].Data; 92 | file.CopyTo(ResTable, TotalSize); 93 | PSBStrMan.CreateOffset(OffsetSize, TotalSize).CopyTo(MainData, OffsetTablePos + (i * OffsetSize)); 94 | PSBStrMan.CreateOffset(ResSizeOffSize, file.Length).CopyTo(MainData, ResSizeOffTablePos + (i * ResSizeOffSize)); 95 | 96 | //If need FixOffsets and is the last loop time... 97 | TotalSize += file.Length + (FixOffsets && i + 1 != Resources.Length ? 4 - ((StartPos + TotalSize + file.Length) % 4) : 0); 98 | } 99 | byte[] ResultPackget = new byte[MainData.Length + ResTable.Length]; 100 | MainData.CopyTo(ResultPackget, 0); 101 | ResTable.CopyTo(ResultPackget, MainData.Length); 102 | return CompressPackget ? PSBStrMan.CompressMDF(ResultPackget) : ResultPackget; 103 | } 104 | private byte[] CutAt(byte[] Original, int Pos) { 105 | byte[] rst = new byte[Pos]; 106 | for (int i = 0; i < Pos; i++) 107 | rst[i] = Original[i]; 108 | return rst; 109 | } 110 | 111 | } 112 | public class FileEntry { 113 | public byte[] Data; 114 | } 115 | 116 | public class HuffmanTool { 117 | 118 | public static byte[] DecompressBitmap(byte[] data) { 119 | System.IO.MemoryStream stream = new System.IO.MemoryStream(); 120 | 121 | for (int i = 0; i < data.Length;) { 122 | byte cmd = data[i]; 123 | if (Repeat(cmd)) { 124 | int Times = GetInt(cmd) + 3; //Minimal Compression 125 | byte[] Data = GetDword(data, i + 1); 126 | i += 5; 127 | for (int count = 0; count < Times; count++) 128 | stream.Write(Data, 0, Data.Length); 129 | } 130 | else { 131 | int Length = (GetInt(cmd) + 1) * 4;//+1 because the first 4 bytes don't is counted in the offset... and *4 because 1 is equal a 4 bytes 132 | byte[] Data = SubArray(data, i + 1, Length); 133 | i += Length + 1; 134 | stream.Write(Data, 0, Data.Length); 135 | } 136 | } 137 | stream.Seek(0, System.IO.SeekOrigin.Begin); 138 | byte[] outdata = new byte[stream.Length]; 139 | stream.Read(outdata, 0, outdata.Length); 140 | return outdata; 141 | } 142 | 143 | public static byte[] CompressBitmap(byte[] data, bool JumpHeader) { 144 | if (getRange(data, 0, 2) == "BM" && JumpHeader) { 145 | byte[] cnt = new byte[data.Length - 0x36]; 146 | for (int i = 0x36; i < data.Length; i++) 147 | cnt[i - 0x36] = data[i]; 148 | data = cnt; 149 | } 150 | if (data.Length % 4 > 0) { 151 | byte[] nw = new byte[data.Length + (data.Length % 4)]; 152 | data.CopyTo(nw, 0); 153 | data = nw; 154 | } 155 | System.IO.MemoryStream stream = new System.IO.MemoryStream(); 156 | int MaxInt = 0x7F; 157 | int MinVal = 3; 158 | for (int pos = 0; pos < data.Length;) { 159 | if (HaveLoop(data, pos)) { 160 | int Loops = CountLoops(data, pos); 161 | byte[] DW = GetDword(data, pos); 162 | while (Loops > 0) { 163 | int len = (Loops - MinVal > MaxInt) ? MaxInt : Loops - MinVal; 164 | Loops -= len + MinVal; 165 | stream.Write(new byte[] { CreateInt(len) }, 0, 1); 166 | stream.Write(DW, 0, 4); 167 | pos += (len + MinVal) * 4; 168 | } 169 | } 170 | else { 171 | int len = 0; 172 | while (!HaveLoop(data, pos + (len * 4))) { 173 | len++; 174 | if (pos + (len * 4) >= data.Length) 175 | break; 176 | } 177 | while (len > 0) { 178 | int off = (len > MaxInt) ? MaxInt : len; 179 | stream.Write(new byte[] { (byte)(off - 1) }, 0, 1); 180 | stream.Write(data, pos, off * 4); 181 | len -= off; 182 | pos += off * 4; 183 | } 184 | } 185 | } 186 | stream.Seek(0, System.IO.SeekOrigin.Begin); 187 | byte[] outdata = new byte[stream.Length]; 188 | stream.Read(outdata, 0, outdata.Length); 189 | return outdata; 190 | } 191 | 192 | private static int CountLoops(byte[] data, int Pos) { 193 | byte[] Find = GetDword(data, Pos); 194 | int Loops = 0; 195 | while (true) { 196 | if (EqualsAt(data, Find, (Loops * 4) + Pos)) { 197 | Loops++; 198 | } 199 | else { 200 | break; 201 | } 202 | } 203 | return Loops; 204 | } 205 | 206 | private static bool HaveLoop(byte[] data, int pos) { 207 | byte[] dword = GetDword(data, pos); 208 | return CountLoops(data, pos) > 2; 209 | 210 | } 211 | private static byte[] GetDword(byte[] data, int pos) { 212 | return new byte[] { data[pos], data[pos + 1], data[pos + 2], data[pos + 3] }; 213 | } 214 | private static bool EqualsAt(byte[] data, byte[] CompareData, int pos) { 215 | if (CompareData.Length + pos > data.Length) 216 | return false; 217 | for (int i = 0; i < CompareData.Length; i++) 218 | if (CompareData[i] != data[i + pos]) 219 | return false; 220 | return true; 221 | } 222 | 223 | private static string getRange(byte[] file, int pos, int length) { 224 | string rst = string.Empty; 225 | for (int i = 0; i < length; i++) { 226 | string hex = file[pos + i].ToString("x").ToUpper(); 227 | if (hex.Length == 1) 228 | hex = "0" + hex; 229 | rst += hex; 230 | } 231 | return rst; 232 | } 233 | 234 | private static byte[] SubArray(byte[] data, int Pos, int length) { 235 | byte[] rst = new byte[length]; 236 | for (int i = 0; i < length && i + Pos < data.Length; i++) 237 | rst[i] = data[i + Pos]; 238 | return rst; 239 | } 240 | private static bool Repeat(byte value) { 241 | byte mask = 0x80; 242 | return ((value & mask) > 0); 243 | } 244 | private static int GetInt(byte value) { 245 | byte mask = 0x7F; 246 | return value & mask; 247 | } 248 | 249 | private static byte CreateInt(int value) { 250 | if (value > 0x7F) 251 | throw new Exception("Max Allowed value is: " + 0x7F); 252 | return (byte)(value | 0x80); 253 | } 254 | } 255 | } 256 | -------------------------------------------------------------------------------- /ScnEditorGUI/Form1.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ScnEditorGUI 2 | { 3 | partial class Form1 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.components = new System.ComponentModel.Container(); 32 | this.listBox1 = new System.Windows.Forms.ListBox(); 33 | this.textBox1 = new System.Windows.Forms.TextBox(); 34 | this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); 35 | this.openFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 36 | this.saveFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 37 | this.huffmanToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 38 | this.decompressImageToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 39 | this.compressImageToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 40 | this.tryRecoveryToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 41 | this.tJS2ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 42 | this.openToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 43 | this.saveToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 44 | this.ClipboardSeekSample = new System.Windows.Forms.ToolStripMenuItem(); 45 | this.SeekUpdate = new System.Windows.Forms.Timer(this.components); 46 | this.decompressScriptToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 47 | this.contextMenuStrip1.SuspendLayout(); 48 | this.SuspendLayout(); 49 | // 50 | // listBox1 51 | // 52 | this.listBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 53 | | System.Windows.Forms.AnchorStyles.Left) 54 | | System.Windows.Forms.AnchorStyles.Right))); 55 | this.listBox1.FormattingEnabled = true; 56 | this.listBox1.Location = new System.Drawing.Point(12, 12); 57 | this.listBox1.Name = "listBox1"; 58 | this.listBox1.Size = new System.Drawing.Size(435, 264); 59 | this.listBox1.TabIndex = 0; 60 | this.listBox1.SelectedIndexChanged += new System.EventHandler(this.listBox1_SelectedIndexChanged); 61 | this.listBox1.MouseClick += new System.Windows.Forms.MouseEventHandler(this.listBox1_MouseClick); 62 | this.listBox1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.listBox1_KeyDown); 63 | this.listBox1.KeyUp += new System.Windows.Forms.KeyEventHandler(this.listBox1_KeyUp); 64 | // 65 | // textBox1 66 | // 67 | this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 68 | | System.Windows.Forms.AnchorStyles.Right))); 69 | this.textBox1.Location = new System.Drawing.Point(12, 282); 70 | this.textBox1.Name = "textBox1"; 71 | this.textBox1.Size = new System.Drawing.Size(435, 20); 72 | this.textBox1.TabIndex = 1; 73 | this.textBox1.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.textBox1_KeyPress); 74 | // 75 | // contextMenuStrip1 76 | // 77 | this.contextMenuStrip1.ImageScalingSize = new System.Drawing.Size(20, 20); 78 | this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 79 | this.openFileToolStripMenuItem, 80 | this.saveFileToolStripMenuItem, 81 | this.huffmanToolStripMenuItem, 82 | this.tryRecoveryToolStripMenuItem, 83 | this.tJS2ToolStripMenuItem, 84 | this.ClipboardSeekSample}); 85 | this.contextMenuStrip1.Name = "contextMenuStrip1"; 86 | this.contextMenuStrip1.Size = new System.Drawing.Size(181, 158); 87 | // 88 | // openFileToolStripMenuItem 89 | // 90 | this.openFileToolStripMenuItem.Name = "openFileToolStripMenuItem"; 91 | this.openFileToolStripMenuItem.Size = new System.Drawing.Size(180, 22); 92 | this.openFileToolStripMenuItem.Text = "Open File"; 93 | this.openFileToolStripMenuItem.Click += new System.EventHandler(this.openFileToolStripMenuItem_Click); 94 | // 95 | // saveFileToolStripMenuItem 96 | // 97 | this.saveFileToolStripMenuItem.Name = "saveFileToolStripMenuItem"; 98 | this.saveFileToolStripMenuItem.Size = new System.Drawing.Size(180, 22); 99 | this.saveFileToolStripMenuItem.Text = "Save File"; 100 | this.saveFileToolStripMenuItem.Click += new System.EventHandler(this.saveFileToolStripMenuItem_Click); 101 | // 102 | // huffmanToolStripMenuItem 103 | // 104 | this.huffmanToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { 105 | this.decompressImageToolStripMenuItem, 106 | this.compressImageToolStripMenuItem, 107 | this.decompressScriptToolStripMenuItem}); 108 | this.huffmanToolStripMenuItem.Name = "huffmanToolStripMenuItem"; 109 | this.huffmanToolStripMenuItem.Size = new System.Drawing.Size(180, 22); 110 | this.huffmanToolStripMenuItem.Text = "Compress"; 111 | // 112 | // decompressImageToolStripMenuItem 113 | // 114 | this.decompressImageToolStripMenuItem.Name = "decompressImageToolStripMenuItem"; 115 | this.decompressImageToolStripMenuItem.Size = new System.Drawing.Size(180, 22); 116 | this.decompressImageToolStripMenuItem.Text = "Decompress Image"; 117 | this.decompressImageToolStripMenuItem.Click += new System.EventHandler(this.decompressImageToolStripMenuItem_Click); 118 | // 119 | // compressImageToolStripMenuItem 120 | // 121 | this.compressImageToolStripMenuItem.Name = "compressImageToolStripMenuItem"; 122 | this.compressImageToolStripMenuItem.Size = new System.Drawing.Size(180, 22); 123 | this.compressImageToolStripMenuItem.Text = "Compress Image"; 124 | this.compressImageToolStripMenuItem.Click += new System.EventHandler(this.compressImageToolStripMenuItem_Click); 125 | // 126 | // tryRecoveryToolStripMenuItem 127 | // 128 | this.tryRecoveryToolStripMenuItem.Name = "tryRecoveryToolStripMenuItem"; 129 | this.tryRecoveryToolStripMenuItem.Size = new System.Drawing.Size(180, 22); 130 | this.tryRecoveryToolStripMenuItem.Text = "Try Recovery"; 131 | this.tryRecoveryToolStripMenuItem.Click += new System.EventHandler(this.tryRecoveryToolStripMenuItem_Click); 132 | // 133 | // tJS2ToolStripMenuItem 134 | // 135 | this.tJS2ToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { 136 | this.openToolStripMenuItem, 137 | this.saveToolStripMenuItem}); 138 | this.tJS2ToolStripMenuItem.Name = "tJS2ToolStripMenuItem"; 139 | this.tJS2ToolStripMenuItem.Size = new System.Drawing.Size(180, 22); 140 | this.tJS2ToolStripMenuItem.Text = "TJS2"; 141 | // 142 | // openToolStripMenuItem 143 | // 144 | this.openToolStripMenuItem.Name = "openToolStripMenuItem"; 145 | this.openToolStripMenuItem.Size = new System.Drawing.Size(103, 22); 146 | this.openToolStripMenuItem.Text = "Open"; 147 | this.openToolStripMenuItem.Click += new System.EventHandler(this.openToolStripMenuItem_Click); 148 | // 149 | // saveToolStripMenuItem 150 | // 151 | this.saveToolStripMenuItem.Name = "saveToolStripMenuItem"; 152 | this.saveToolStripMenuItem.Size = new System.Drawing.Size(103, 22); 153 | this.saveToolStripMenuItem.Text = "Save"; 154 | this.saveToolStripMenuItem.Click += new System.EventHandler(this.saveToolStripMenuItem_Click); 155 | // 156 | // ClipboardSeekSample 157 | // 158 | this.ClipboardSeekSample.Checked = true; 159 | this.ClipboardSeekSample.CheckOnClick = true; 160 | this.ClipboardSeekSample.CheckState = System.Windows.Forms.CheckState.Checked; 161 | this.ClipboardSeekSample.Name = "ClipboardSeekSample"; 162 | this.ClipboardSeekSample.Size = new System.Drawing.Size(180, 22); 163 | this.ClipboardSeekSample.Text = "Seek Clipboard"; 164 | this.ClipboardSeekSample.Click += new System.EventHandler(this.ClipboardSeekSample_Click); 165 | // 166 | // SeekUpdate 167 | // 168 | this.SeekUpdate.Enabled = true; 169 | this.SeekUpdate.Interval = 500; 170 | this.SeekUpdate.Tick += new System.EventHandler(this.SeekUpdate_Tick); 171 | // 172 | // decompressScriptToolStripMenuItem 173 | // 174 | this.decompressScriptToolStripMenuItem.Name = "decompressScriptToolStripMenuItem"; 175 | this.decompressScriptToolStripMenuItem.Size = new System.Drawing.Size(180, 22); 176 | this.decompressScriptToolStripMenuItem.Text = "Decompress Script"; 177 | this.decompressScriptToolStripMenuItem.Click += new System.EventHandler(this.decompressScriptToolStripMenuItem_Click); 178 | // 179 | // Form1 180 | // 181 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 182 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 183 | this.ClientSize = new System.Drawing.Size(459, 322); 184 | this.ContextMenuStrip = this.contextMenuStrip1; 185 | this.Controls.Add(this.textBox1); 186 | this.Controls.Add(this.listBox1); 187 | this.Name = "Form1"; 188 | this.Text = "Scn Editor"; 189 | this.contextMenuStrip1.ResumeLayout(false); 190 | this.ResumeLayout(false); 191 | this.PerformLayout(); 192 | 193 | } 194 | 195 | #endregion 196 | 197 | private System.Windows.Forms.ListBox listBox1; 198 | private System.Windows.Forms.TextBox textBox1; 199 | private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; 200 | private System.Windows.Forms.ToolStripMenuItem openFileToolStripMenuItem; 201 | private System.Windows.Forms.ToolStripMenuItem saveFileToolStripMenuItem; 202 | private System.Windows.Forms.ToolStripMenuItem huffmanToolStripMenuItem; 203 | private System.Windows.Forms.ToolStripMenuItem decompressImageToolStripMenuItem; 204 | private System.Windows.Forms.ToolStripMenuItem compressImageToolStripMenuItem; 205 | private System.Windows.Forms.ToolStripMenuItem tryRecoveryToolStripMenuItem; 206 | private System.Windows.Forms.ToolStripMenuItem tJS2ToolStripMenuItem; 207 | private System.Windows.Forms.ToolStripMenuItem openToolStripMenuItem; 208 | private System.Windows.Forms.ToolStripMenuItem saveToolStripMenuItem; 209 | private System.Windows.Forms.ToolStripMenuItem ClipboardSeekSample; 210 | private System.Windows.Forms.Timer SeekUpdate; 211 | private System.Windows.Forms.ToolStripMenuItem decompressScriptToolStripMenuItem; 212 | } 213 | } 214 | 215 | -------------------------------------------------------------------------------- /KrKrSceneManager/PSBStringManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Text; 4 | using System.Collections.Generic; 5 | using System.Diagnostics; 6 | using AdvancedBinary; 7 | 8 | /* 9 | * KrKrSceneManager (5.6) By Marcussacana 10 | * Usage: 11 | * byte[] input = File.ReadAllBytes("C:\\sample.bin"); 12 | * PSBStringManager StrMan = new PSBStringManager(input); 13 | * string[] scncontent = StrMan.Import(); 14 | * ... 15 | * //save 16 | * byte[] output = StrMan.Export(scncontent); 17 | * File.WriteAllBytes("C:\\sample_out.bin", output); 18 | */ 19 | 20 | namespace KrKrSceneManager { 21 | public class PSBStrMan { 22 | 23 | public bool CompressPackage = true; 24 | public static int CompressionLevel = 9; 25 | public bool ForceMaxOffsetLength = false; 26 | 27 | byte[] Script; 28 | int OffLength; 29 | int StrCount; 30 | int OldOffTblLen;//Old Offset Table Length 31 | int OldStrDatLen;//Old String Data Length 32 | PSBHeader Header; 33 | public PSBStrMan(byte[] Script) { 34 | this.Script = new byte[Script.Length]; 35 | Script.CopyTo(this.Script, 0); 36 | } 37 | public string[] Import() { 38 | PackgetStatus Status = GetPackgetStatus(Script); 39 | switch (Status) { 40 | case PackgetStatus.Invalid: 41 | throw new Exception("Invalid Package"); 42 | case PackgetStatus.MDF: 43 | Script = ExtractMDF(Script); 44 | CompressPackage = true; 45 | break; 46 | } 47 | 48 | MemoryStream Reader = new MemoryStream(Script); 49 | Header = new PSBHeader(); 50 | Header = Reader.ReadStruct(); 51 | 52 | Reader.Position = Header.StrOffPos; 53 | OffLength = ConvertSize((byte)Reader.ReadByte()); 54 | StrCount = ReadOffset(Reader.ReadBytes(OffLength), 0, OffLength); 55 | OffLength = ConvertSize((byte)Reader.ReadByte()); 56 | 57 | int[] Offsets = new int[StrCount]; 58 | for (int i = 0; i < StrCount; i++) 59 | Offsets[i] = ReadOffset(Reader.ReadBytes(OffLength), 0, OffLength); 60 | 61 | OldOffTblLen = (int)(Reader.Position - Header.StrOffPos); 62 | 63 | string[] Strings = new string[StrCount]; 64 | for (int i = 0; i < StrCount; i++) { 65 | Reader.Position = Header.StrDataPos + Offsets[i]; 66 | Strings[i] = Reader.ReadCString(); 67 | } 68 | 69 | OldStrDatLen = (int)(Reader.Position - Header.StrDataPos); 70 | 71 | Reader.Close(); 72 | return Strings; 73 | } 74 | public byte[] Export(string[] Strings) { 75 | if (Strings.Length != StrCount) 76 | throw new Exception("You can't add or remove a string entry"); 77 | 78 | int[] Offsets; 79 | byte[] StringData, OffsetData; 80 | BuildStringData(Strings, out StringData, out Offsets); 81 | BuildOffsetTable(Offsets, out OffsetData); 82 | 83 | int OffTblDiff = OffsetData.Length - OldOffTblLen; 84 | int StrDatDiff = StringData.Length - OldStrDatLen; 85 | PSBHeader Header = this.Header; 86 | 87 | UpdateOffsets(ref Header, OffTblDiff, StrDatDiff); 88 | 89 | byte[] OutScript = new byte[Script.Length]; 90 | Script.CopyTo(OutScript, 0); 91 | 92 | OverwriteRange(ref OutScript, Header.StrOffPos, OldOffTblLen, OffsetData); 93 | OverwriteRange(ref OutScript, Header.StrDataPos, OldStrDatLen, StringData); 94 | 95 | Header.ParseStruct().CopyTo(OutScript, 0); 96 | 97 | return CompressPackage ? CompressMDF(OutScript) : OutScript; 98 | } 99 | 100 | private void OverwriteRange(ref byte[] OriginalData, uint Start, int Length, byte[] DataToOverwrite) { 101 | byte[] First = new byte[Start]; 102 | Array.Copy(OriginalData, First, Start); 103 | 104 | byte[] Second = new byte[OriginalData.Length - (Start + Length)]; 105 | Array.Copy(OriginalData, Start + Length, Second, 0, Second.Length); 106 | 107 | OriginalData = new byte[First.Length + DataToOverwrite.Length + Second.Length]; 108 | First.CopyTo(OriginalData, 0); 109 | DataToOverwrite.CopyTo(OriginalData, First.Length); 110 | Second.CopyTo(OriginalData, First.Length + DataToOverwrite.Length); 111 | } 112 | 113 | void UpdateOffsets(ref PSBHeader Header, int OffTblDiff, int StrDatDiff) { 114 | UpdateOffset(ref Header.ResOffPos, Header.StrOffPos, OffTblDiff); 115 | UpdateOffset(ref Header.ResDataPos, Header.StrOffPos, OffTblDiff); 116 | UpdateOffset(ref Header.ResLenPos, Header.StrOffPos, OffTblDiff); 117 | UpdateOffset(ref Header.ResIndexTree, Header.StrOffPos, OffTblDiff); 118 | UpdateOffset(ref Header.StrDataPos, Header.StrOffPos, OffTblDiff); 119 | 120 | UpdateOffset(ref Header.ResOffPos, Header.StrDataPos, StrDatDiff); 121 | UpdateOffset(ref Header.ResDataPos, Header.StrDataPos, StrDatDiff); 122 | UpdateOffset(ref Header.ResLenPos, Header.StrDataPos, StrDatDiff); 123 | UpdateOffset(ref Header.ResIndexTree, Header.StrDataPos, StrDatDiff); 124 | } 125 | 126 | void UpdateOffset(ref uint Offset, uint ChangeBaseOffset, int Diff) { 127 | if (Offset < ChangeBaseOffset) 128 | return; 129 | Offset = (uint)(Offset + Diff); 130 | } 131 | 132 | void BuildStringData(string[] Strings, out byte[] StringTable, out int[] Offsets) { 133 | Offsets = new int[StrCount]; 134 | MemoryStream Writer = new MemoryStream(); 135 | 136 | for (int i = 0; i < StrCount; i++) { 137 | Offsets[i] = (int)Writer.Length; 138 | Writer.WriteCString(Strings[i]); 139 | } 140 | StringTable = Writer.ToArray(); 141 | Writer.Close(); 142 | } 143 | 144 | void BuildOffsetTable(int[] Offsets, out byte[] OffsetData) { 145 | MemoryStream OffData = new MemoryStream(); 146 | BinaryWriter Writer = new BinaryWriter(OffData); 147 | 148 | //Offset Count 149 | int OffsetSize = ForceMaxOffsetLength ? 4 : GetMinIntLen(StrCount); 150 | Writer.Write(ConvertSize(OffsetSize)); 151 | Writer.Write(CreateOffset(OffsetSize, StrCount)); 152 | 153 | //Offset's Size 154 | OffsetSize = ForceMaxOffsetLength ? 4 : GetMinIntLen(Offsets[StrCount - 1]); 155 | Writer.Write(ConvertSize(OffsetSize)); 156 | 157 | for (int i = 0; i < StrCount; i++) 158 | Writer.Write(CreateOffset(OffsetSize, Offsets[i])); 159 | 160 | OffsetData = OffData.ToArray(); 161 | Writer.Close(); 162 | OffData?.Close(); 163 | } 164 | 165 | internal static byte[] CompressMDF(byte[] Psb) { 166 | byte[] CompressedScript; 167 | Tools.CompressData(Psb, CompressionLevel, out CompressedScript); 168 | 169 | byte[] RetData = new byte[8 + CompressedScript.Length]; 170 | (new byte[] { 0x6D, 0x64, 0x66, 0x00 }).CopyTo(RetData, 0);//Signature 171 | CreateOffset(4, Psb.Length).CopyTo(RetData, 4);//Decompressed Length 172 | CompressedScript.CopyTo(RetData, 8);//ZLIB Data 173 | 174 | return RetData; 175 | } 176 | 177 | public byte[] TryRecovery() 178 | { 179 | var Script = new byte[this.Script.Length]; 180 | this.Script.CopyTo(Script, 0); 181 | 182 | var Status = GetPackgetStatus(Script); 183 | if (Status == PackgetStatus.Invalid) 184 | throw new Exception("Invalid Package"); 185 | 186 | bool MDF = Status == PackgetStatus.MDF; 187 | if (MDF) 188 | Script = ExtractMDF(Script); 189 | 190 | int StrOff = ReadOffset(Script, 0x10, 4); 191 | int StrData = ReadOffset(Script, 0x14, 4); 192 | int CntSize = ConvertSize(Script[StrOff]); 193 | int Count = ReadOffset(Script, StrOff + 1, CntSize); 194 | int Size = ConvertSize(Script[StrOff + 1 + CntSize]); 195 | int EndStr = (StrOff + 2 + CntSize) + ((Count - 1) * Size); 196 | EndStr = ReadOffset(Script, EndStr, Size) + StrData; 197 | while (Script[EndStr] != 0x00) 198 | EndStr++; 199 | byte[] Seq = new byte[] { 0xD, 0x0, 0xD }; 200 | if (EqualsAt(Script, Seq, EndStr + 1) && EqualsAt(Script, Seq, EndStr + 1 + Seq.Length)) { 201 | OverwriteRange(ref Script, 0x18, 4, CreateOffset(4, EndStr + 1)); 202 | OverwriteRange(ref Script, 0x1C, 4, CreateOffset(4, EndStr + 4));//+3 203 | OverwriteRange(ref Script, 0x20, 4, CreateOffset(4, EndStr + 7));//+6 204 | return MDF ? CompressMDF(Script) : Script; 205 | } else { 206 | try { 207 | int tmp = ConvertSize(Script[ReadOffset(Script, 0x18, 4)]); 208 | tmp = ConvertSize(Script[ReadOffset(Script, 0x1C, 4)]); 209 | return MDF ? CompressMDF(Script) : Script; //Looks all Rigth 210 | } 211 | catch { 212 | throw new Exception("You can't attempt recovery because this package contains data."); 213 | } 214 | } 215 | } 216 | bool EqualsAt(byte[] Data, byte[] CompareData, int Pos) { 217 | if (CompareData.Length + Pos > Data.Length) 218 | return false; 219 | for (int i = 0; i < CompareData.Length; i++) 220 | if (Data[i + Pos] != CompareData[i]) 221 | return false; 222 | return true; 223 | } 224 | 225 | private static int GetMinIntLen(int Value) { 226 | int MinLen = 0; 227 | while (Value >> (MinLen * 8) > 0) 228 | MinLen++; 229 | return MinLen; 230 | } 231 | internal static byte[] CreateOffset(int Length, int Value) { 232 | byte[] Buffer = new byte[GetMinIntLen(Value)]; 233 | Array.Copy(BitConverter.GetBytes(Value), Buffer, Buffer.Length); 234 | 235 | 236 | if (Buffer.Length > Length) 237 | throw new Exception("Edited Strings are too big."); 238 | if (Buffer.Length < Length) 239 | Array.Resize(ref Buffer, Length); 240 | return Buffer; 241 | } 242 | 243 | internal static byte ConvertSize(int s) { 244 | switch (s) { 245 | case 1: 246 | return 0xD; 247 | case 2: 248 | return 0xE; 249 | case 3: 250 | return 0xF; 251 | case 4: 252 | return 0x10; 253 | } 254 | throw new Exception("Unknown Offset Size ("+s+")"); 255 | } 256 | internal static int ConvertSize(byte b) { 257 | switch (b) { 258 | case 0xD: 259 | return 1; 260 | case 0xE: 261 | return 2; 262 | case 0xF: 263 | return 3; 264 | case 0x10: 265 | return 4; 266 | } 267 | throw new Exception("Unknown Offset Size (" + b.ToString("X2") + ")"); 268 | } 269 | public static byte[] ExtractMDF(byte[] MDF) { 270 | byte[] Zlib = new byte[MDF.Length - 8]; 271 | Array.Copy(MDF, 8, Zlib, 0, MDF.Length - 8); 272 | 273 | byte[] PSB; 274 | Tools.DecompressData(Zlib, out PSB); 275 | if (ReadOffset(MDF, 4, 4) != PSB.Length) 276 | throw new Exception("Corrupted MDF Header or Zlib Data"); 277 | 278 | return PSB; 279 | } 280 | public enum PackgetStatus { 281 | MDF, PSB, Invalid 282 | } 283 | public static PackgetStatus GetPackgetStatus(byte[] Packget) { 284 | if (ReadOffset(Packget, 0, 3) == 0x66646D) 285 | return PackgetStatus.MDF; 286 | if (ReadOffset(Packget, 0, 3) == 0x425350) 287 | return PackgetStatus.PSB; 288 | return PackgetStatus.Invalid; 289 | } 290 | private static string ReadString(byte[] Script, int pos) { 291 | List Array = new List(); 292 | while (Script[pos] != 0x00) 293 | Array.Add(Script[pos++]); 294 | 295 | return Encoding.UTF8.GetString(Array.ToArray()); 296 | } 297 | 298 | internal static int ReadOffset(byte[] Script, int Index, int Length) { 299 | byte[] Value = new byte[4]; 300 | Array.Copy(Script, Index, Value, 0, Length); 301 | return BitConverter.ToInt32(Value, 0); 302 | } 303 | } 304 | } 305 | 306 | -------------------------------------------------------------------------------- /KrKrSceneManager/Zlib/Tree.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2006, ComponentAce 2 | // http://www.componentace.com 3 | // All rights reserved. 4 | 5 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 6 | 7 | // Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | // Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 9 | // Neither the name of ComponentAce nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 10 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 11 | 12 | /* 13 | Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. 14 | 15 | Redistribution and use in source and binary forms, with or without 16 | modification, are permitted provided that the following conditions are met: 17 | 18 | 1. Redistributions of source code must retain the above copyright notice, 19 | this list of conditions and the following disclaimer. 20 | 21 | 2. Redistributions in binary form must reproduce the above copyright 22 | notice, this list of conditions and the following disclaimer in 23 | the documentation and/or other materials provided with the distribution. 24 | 25 | 3. The names of the authors may not be used to endorse or promote products 26 | derived from this software without specific prior written permission. 27 | 28 | THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, 29 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 30 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, 31 | INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, 32 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 33 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 34 | OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 35 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 36 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 37 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 | */ 39 | /* 40 | * This program is based on zlib-1.1.3, so all credit should go authors 41 | * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) 42 | * and contributors of zlib. 43 | */ 44 | using System; 45 | 46 | namespace KrKrSceneManager 47 | { 48 | 49 | /// 50 | /// This class represents a tree and is used in the Deflate class 51 | /// 52 | internal sealed class Tree 53 | { 54 | 55 | #region Fields 56 | 57 | /// 58 | /// The dynamic tree 59 | /// 60 | private short[] dyn_tree; 61 | 62 | /// 63 | /// Largest code with non zero frequency 64 | /// 65 | private int max_code; 66 | 67 | /// 68 | /// the corresponding static tree 69 | /// 70 | private StaticTree stat_desc; 71 | 72 | #endregion 73 | 74 | #region Properties 75 | 76 | /// 77 | /// The dynamic tree 78 | /// 79 | internal short[] DynTree 80 | { 81 | get { return dyn_tree; } 82 | set { dyn_tree = value; } 83 | } 84 | 85 | /// 86 | /// Largest code with non zero frequency 87 | /// 88 | internal int MaxCode 89 | { 90 | get { return max_code; } 91 | set { max_code = value; } 92 | } 93 | /// 94 | /// the corresponding static tree 95 | /// 96 | internal StaticTree StatDesc 97 | { 98 | get { return stat_desc; } 99 | set { stat_desc = value; } 100 | } 101 | 102 | #endregion 103 | 104 | #region Methods 105 | 106 | /// 107 | /// Mapping from a distance to a distance code. dist is the distance - 1 and 108 | /// must not have side effects. _dist_code[256] and _dist_code[257] are never 109 | /// used. 110 | /// 111 | internal static int d_code(int dist) 112 | { 113 | return ((dist) < 256 ? ZLibUtil._dist_code[dist] : ZLibUtil._dist_code[256 + (ZLibUtil.URShift((dist), 7))]); 114 | } 115 | 116 | /// 117 | /// Compute the optimal bit lengths for a tree and update the total bit length 118 | /// for the current block. 119 | /// IN assertion: the fields freq and dad are set, heap[heap_max] and 120 | /// above are the tree nodes sorted by increasing frequency. 121 | /// OUT assertions: the field count is set to the optimal bit length, the 122 | /// array bl_count contains the frequencies for each bit length. 123 | /// The length opt_len is updated; static_len is also updated if stree is 124 | /// not null. 125 | /// 126 | private void gen_bitlen(Deflate s) 127 | { 128 | short[] tree = dyn_tree; 129 | short[] stree = stat_desc.static_tree; 130 | int[] extra = stat_desc.extra_bits; 131 | int base_Renamed = stat_desc.extra_base; 132 | int max_length = stat_desc.max_length; 133 | int h; // heap index 134 | int n, m; // iterate over the tree elements 135 | int bits; // bit length 136 | int xbits; // extra bits 137 | short f; // frequency 138 | int overflow = 0; // number of elements with bit length too large 139 | 140 | for (bits = 0; bits <= ZLibUtil.MAX_WBITS; bits++) 141 | s.bl_count[bits] = 0; 142 | 143 | // In a first pass, compute the optimal bit lengths (which may 144 | // overflow in the case of the bit length tree). 145 | tree[s.heap[s.heap_max] * 2 + 1] = 0; // root of the heap 146 | 147 | for (h = s.heap_max + 1; h < ZLibUtil.HEAP_SIZE; h++) 148 | { 149 | n = s.heap[h]; 150 | bits = tree[tree[n * 2 + 1] * 2 + 1] + 1; 151 | if (bits > max_length) 152 | { 153 | bits = max_length; overflow++; 154 | } 155 | tree[n * 2 + 1] = (short) bits; 156 | // We overwrite tree[n*2+1] which is no longer needed 157 | 158 | if (n > max_code) 159 | continue; // not a leaf node 160 | 161 | s.bl_count[bits]++; 162 | xbits = 0; 163 | if (n >= base_Renamed) 164 | xbits = extra[n - base_Renamed]; 165 | f = tree[n * 2]; 166 | s.opt_len += f * (bits + xbits); 167 | if (stree != null) 168 | s.static_len += f * (stree[n * 2 + 1] + xbits); 169 | } 170 | if (overflow == 0) 171 | return ; 172 | 173 | // This happens for example on obj2 and pic of the Calgary corpus 174 | // Find the first bit length which could increase: 175 | do 176 | { 177 | bits = max_length - 1; 178 | while (s.bl_count[bits] == 0) 179 | bits--; 180 | s.bl_count[bits]--; // move one leaf down the tree 181 | s.bl_count[bits + 1] = (short) (s.bl_count[bits + 1] + 2); // move one overflow item as its brother 182 | s.bl_count[max_length]--; 183 | // The brother of the overflow item also moves one step up, 184 | // but this does not affect bl_count[max_length] 185 | overflow -= 2; 186 | } 187 | while (overflow > 0); 188 | 189 | for (bits = max_length; bits != 0; bits--) 190 | { 191 | n = s.bl_count[bits]; 192 | while (n != 0) 193 | { 194 | m = s.heap[--h]; 195 | if (m > max_code) 196 | continue; 197 | if (tree[m * 2 + 1] != bits) 198 | { 199 | s.opt_len = (int) (s.opt_len + ((long) bits - (long) tree[m * 2 + 1]) * (long) tree[m * 2]); 200 | tree[m * 2 + 1] = (short) bits; 201 | } 202 | n--; 203 | } 204 | } 205 | } 206 | 207 | /// 208 | /// Construct one Huffman tree and assigns the code bit strings and lengths. 209 | /// Update the total bit length for the current block. 210 | /// IN assertion: the field freq is set for all tree elements. 211 | /// OUT assertions: the fields count and code are set to the optimal bit length 212 | /// and corresponding code. The length opt_len is updated; static_len is 213 | /// also updated if stree is not null. The field max_code is set. 214 | /// 215 | internal void build_tree(Deflate s) 216 | { 217 | short[] tree = dyn_tree; 218 | short[] stree = stat_desc.static_tree; 219 | int elems = stat_desc.elems; 220 | int n, m; // iterate over heap elements 221 | int max_code = - 1; // largest code with non zero frequency 222 | int node; // new node being created 223 | 224 | // Construct the initial heap, with least frequent element in 225 | // heap[1]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. 226 | // heap[0] is not used. 227 | s.heap_len = 0; 228 | s.heap_max = ZLibUtil.HEAP_SIZE; 229 | 230 | for (n = 0; n < elems; n++) 231 | { 232 | if (tree[n * 2] != 0) 233 | { 234 | s.heap[++s.heap_len] = max_code = n; 235 | s.depth[n] = 0; 236 | } 237 | else 238 | { 239 | tree[n * 2 + 1] = 0; 240 | } 241 | } 242 | 243 | // The pkzip format requires that at least one distance code exists, 244 | // and that at least one bit should be sent even if there is only one 245 | // possible code. So to avoid special checks later on we force at least 246 | // two codes of non zero frequency. 247 | while (s.heap_len < 2) 248 | { 249 | node = s.heap[++s.heap_len] = (max_code < 2?++max_code:0); 250 | tree[node * 2] = 1; 251 | s.depth[node] = 0; 252 | s.opt_len--; 253 | if (stree != null) 254 | s.static_len -= stree[node * 2 + 1]; 255 | // node is 0 or 1 so it does not have extra bits 256 | } 257 | this.max_code = max_code; 258 | 259 | // The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, 260 | // establish sub-heaps of increasing lengths: 261 | 262 | for (n = s.heap_len / 2; n >= 1; n--) 263 | s.pqdownheap(tree, n); 264 | 265 | // Construct the Huffman tree by repeatedly combining the least two 266 | // frequent nodes. 267 | 268 | node = elems; // next internal node of the tree 269 | do 270 | { 271 | // n = node of least frequency 272 | n = s.heap[1]; 273 | s.heap[1] = s.heap[s.heap_len--]; 274 | s.pqdownheap(tree, 1); 275 | m = s.heap[1]; // m = node of next least frequency 276 | 277 | s.heap[--s.heap_max] = n; // keep the nodes sorted by frequency 278 | s.heap[--s.heap_max] = m; 279 | 280 | // Create a new node father of n and m 281 | tree[node * 2] = (short) (tree[n * 2] + tree[m * 2]); 282 | s.depth[node] = (byte) (System.Math.Max((byte) s.depth[n], (byte) s.depth[m]) + 1); 283 | tree[n * 2 + 1] = tree[m * 2 + 1] = (short) node; 284 | 285 | // and insert the new node in the heap 286 | s.heap[1] = node++; 287 | s.pqdownheap(tree, 1); 288 | } 289 | while (s.heap_len >= 2); 290 | 291 | s.heap[--s.heap_max] = s.heap[1]; 292 | 293 | // At this point, the fields freq and dad are set. We can now 294 | // generate the bit lengths. 295 | 296 | gen_bitlen(s); 297 | 298 | // The field count is now set, we can generate the bit codes 299 | gen_codes(tree, max_code, s.bl_count); 300 | } 301 | 302 | /// 303 | /// Generate the codes for a given tree and bit counts (which need not be 304 | /// optimal). 305 | /// IN assertion: the array bl_count contains the bit length statistics for 306 | /// the given tree and the field count is set for all tree elements. 307 | /// OUT assertion: the field code is set for all tree elements of non 308 | /// zero code length. 309 | /// 310 | private static void gen_codes(short[] tree, int max_code, short[] bl_count) 311 | { 312 | short[] next_code = new short[ZLibUtil.MAX_WBITS + 1]; // next code value for each bit length 313 | short code = 0; // running code value 314 | int bits; // bit index 315 | int n; // code index 316 | 317 | // The distribution counts are first used to generate the code values 318 | // without bit reversal. 319 | for (bits = 1; bits <= ZLibUtil.MAX_WBITS; bits++) 320 | { 321 | next_code[bits] = code = (short) ((code + bl_count[bits - 1]) << 1); 322 | } 323 | 324 | // Check that the bit counts in bl_count are consistent. The last code 325 | // must be all ones. 326 | 327 | for (n = 0; n <= max_code; n++) 328 | { 329 | int len = tree[n * 2 + 1]; 330 | if (len == 0) 331 | continue; 332 | // Now reverse the bits 333 | tree[n * 2] = (short) (bi_reverse(next_code[len]++, len)); 334 | } 335 | } 336 | 337 | /// 338 | /// Reverse the first count bits of a code, using straightforward code (a faster 339 | /// method would use a table) 340 | /// 341 | private static int bi_reverse(int code, int len) 342 | { 343 | int res = 0; 344 | do 345 | { 346 | res |= code & 1; 347 | code = ZLibUtil.URShift(code, 1); 348 | res <<= 1; 349 | } 350 | while (--len > 0); 351 | return ZLibUtil.URShift(res, 1); 352 | } 353 | 354 | #endregion 355 | } 356 | } -------------------------------------------------------------------------------- /KrKrSceneManager/Zlib/ZOutputStream.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2006, ComponentAce 2 | // http://www.componentace.com 3 | // All rights reserved. 4 | 5 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 6 | 7 | // Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | // Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 9 | // Neither the name of ComponentAce nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 10 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 11 | 12 | /* 13 | Copyright (c) 2001 Lapo Luchini. 14 | 15 | Redistribution and use in source and binary forms, with or without 16 | modification, are permitted provided that the following conditions are met: 17 | 18 | 1. Redistributions of source code must retain the above copyright notice, 19 | this list of conditions and the following disclaimer. 20 | 21 | 2. Redistributions in binary form must reproduce the above copyright 22 | notice, this list of conditions and the following disclaimer in 23 | the documentation and/or other materials provided with the distribution. 24 | 25 | 3. The names of the authors may not be used to endorse or promote products 26 | derived from this software without specific prior written permission. 27 | 28 | THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, 29 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 30 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS 31 | OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, 32 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 33 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 34 | OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 35 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 36 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 37 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 | */ 39 | /* 40 | * This program is based on zlib-1.1.3, so all credit should go authors 41 | * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) 42 | * and contributors of zlib. 43 | */ 44 | using System; 45 | using System.IO; 46 | 47 | namespace KrKrSceneManager 48 | { 49 | 50 | /// 51 | /// This class uses the Deflate algorithm (an industry standard algorithm for lossless file compression and decompression) to compress data. When creating an instance of the class you passes a stream and an integer value indicating the compression level you want to use. The stream passed to the constructor is used to store compressed data. 52 | /// 53 | /// The following code demonstrates how to use the ZOutputStream to compress data 54 | /// 55 | /// [C#] 56 | /// private void compressFile(string inFile, string outFile) 57 | /// { 58 | /// /* Create a file to store compressed data */ 59 | /// System.IO.FileStream compressedFile = new System.IO.FileStream(@"c:\data\compressed.dat", System.IO.FileMode.Create); 60 | /// /* Open a file containing source data */ 61 | /// System.IO.FileStream sourceFile = new System.IO.FileStream(@"c:\data\source.dat", System.IO.FileMode.Open); 62 | /// /* Create ZOutputStream for compression */ 63 | /// ZOutputStream compressionStream = new ZOutputStream(compressedFile); 64 | /// 65 | /// try 66 | /// { 67 | /// byte[] buffer = new byte[2000]; 68 | /// int len; 69 | /// /* Read and compress data */ 70 | /// while ((len = sourceFile.Read(buffer, 0, 2000)) > 0) 71 | /// { 72 | /// /* Store compressed data */ 73 | /// compressionStream.Write(buffer, 0, len); 74 | /// } 75 | /// } 76 | /// finally 77 | /// { 78 | /// compressionStream.Close(); 79 | /// sourceFile.Close(); 80 | /// compressedFile.Close(); 81 | /// } 82 | /// } 83 | /// 84 | /// 85 | internal class ZOutputStream : System.IO.Stream 86 | { 87 | #region Fields 88 | 89 | /// 90 | /// A ZStream object 91 | /// 92 | protected internal ZStream z = new ZStream(); 93 | 94 | protected internal int bufsize = 4096; 95 | 96 | /// 97 | /// returns actual size of buffer, or set size of buffer between initial (4096) and maximum (2^15). Size of buffer can be only increased to prevent actual data loss 98 | /// 99 | virtual internal int BufferSize 100 | { 101 | get 102 | { 103 | return bufsize; 104 | } 105 | set 106 | { 107 | if (value >= 4096 && value <= 131072 && value > bufsize) 108 | { 109 | byte[] tmpbuf = new byte[value]; 110 | Array.Copy(buf, tmpbuf, bufsize); 111 | buf = new byte[value]; 112 | Array.Copy(tmpbuf, buf,bufsize); 113 | bufsize = value; 114 | } 115 | } 116 | } 117 | 118 | /// 119 | /// Current internalFlush strategy 120 | /// 121 | private FlushStrategy flush; 122 | 123 | /// 124 | /// Buffer byte arrays 125 | /// 126 | private byte[] buf, buf1 = new byte[1]; 127 | 128 | /// 129 | /// Out stream 130 | /// 131 | private Stream _stream; 132 | private MemoryStream outMemoryStream; 133 | 134 | #endregion 135 | 136 | #region Methods 137 | 138 | private void InitBlock() 139 | { 140 | flush = FlushStrategy.Z_NO_FLUSH; 141 | buf = new byte[ZLibUtil.zLibBufSize]; 142 | } 143 | 144 | /// 145 | /// Gets/Sets the flush strategy to use during compression. 146 | /// 147 | internal FlushStrategy FlushMode 148 | { 149 | get 150 | { 151 | return this.flush; 152 | } 153 | 154 | set 155 | { 156 | this.flush = value; 157 | } 158 | 159 | } 160 | 161 | 162 | /// 163 | /// Constructor which takes two parameters: the to store compressed data in and the desired compression level. 164 | /// 165 | /// A stream to be used to store compressed data. 166 | /// An integer value indicating the desired compression level. The compression level can take values from 0 to 9. The maximum value indicates that the maximum compression should be achieved (but this method will be the slowest one). 0 means that no compression should be used at all. If you want to use the default compression level you can pass -1. Also you can use the constants from the class. 167 | internal ZOutputStream(System.IO.Stream stream, int level) 168 | { 169 | InitBlock(); 170 | this._stream = stream; 171 | z.deflateInit(level); 172 | } 173 | 174 | internal ZOutputStream(MemoryStream outMemoryStream) 175 | { 176 | this.outMemoryStream = outMemoryStream; 177 | } 178 | 179 | /// 180 | /// Writes a byte array to the stream. This block of data is compressed and stored in the stream passed as a parameter to the class constructor. 181 | /// 182 | /// A byte array to compress. 183 | /// Offset of the first byte to compress. 184 | /// The number of bytes to compress from the buffer. 185 | /// The following code demonstrates how to use the ZOutputStream to compress data 186 | /// 187 | /// [C#] 188 | /// private void compressFile(string inFile, string outFile) 189 | /// { 190 | /// /* Create a file to store compressed data */ 191 | /// System.IO.FileStream compressedFile = new System.IO.FileStream(@"c:\data\compressed.dat", System.IO.FileMode.Create); 192 | /// /* Open a file containing source data */ 193 | /// System.IO.FileStream sourceFile = new System.IO.FileStream(@"c:\data\source.dat", System.IO.FileMode.Open); 194 | /// /* Create ZOutputStream for compression */ 195 | /// ZOutputStream compressionStream = new ZOutputStream(compressedFile); 196 | /// 197 | /// try 198 | /// { 199 | /// byte[] buffer = new byte[2000]; 200 | /// int len; 201 | /// /* Read and compress data */ 202 | /// while ((len = sourceFile.Read(buffer, 0, 2000)) > 0) 203 | /// { 204 | /// /* Store compressed data */ 205 | /// compressionStream.Write(buffer, 0, len); 206 | /// } 207 | /// } 208 | /// finally 209 | /// { 210 | /// compressionStream.Close(); 211 | /// sourceFile.Close(); 212 | /// compressedFile.Close(); 213 | /// } 214 | /// } 215 | /// 216 | /// 217 | public override void Write(byte[] buffer, int offset, int count) 218 | { 219 | 220 | if (count == 0) 221 | return ; 222 | 223 | if (buffer == null) 224 | throw new ArgumentNullException("buffer"); 225 | 226 | int err; 227 | byte[] b = new byte[buffer.Length]; 228 | System.Array.Copy(buffer, 0, b, 0, buffer.Length); 229 | z.next_in = b; 230 | z.next_in_index = offset; 231 | z.avail_in = count; 232 | do 233 | { 234 | z.next_out = buf; 235 | z.next_out_index = 0; 236 | z.avail_out = ZLibUtil.zLibBufSize; 237 | err = z.deflate(flush); 238 | if (err != (int)ZLibResultCode.Z_OK && err != (int)ZLibResultCode.Z_STREAM_END) 239 | throw new ZStreamException("deflating: " + z.msg); 240 | _stream.Write(buf, 0, ZLibUtil.zLibBufSize - z.avail_out); 241 | 242 | //fixed infinite loop where z.istate.mode == 12, but z.avail_in != 0. 243 | if (z.istate != null) 244 | if (z.istate.mode == InflateMode.DONE) 245 | if (z.avail_in > 0) { z.avail_in = 0; } 246 | } 247 | while (z.avail_in > 0 || z.avail_out == 0); 248 | } 249 | 250 | /// 251 | /// Finishes compression. 252 | /// 253 | internal void Finish() 254 | { 255 | int err; 256 | do 257 | { 258 | z.next_out = buf; 259 | z.next_out_index = 0; 260 | z.avail_out = ZLibUtil.zLibBufSize; 261 | err = z.deflate(FlushStrategy.Z_FINISH); 262 | if (err != (int)ZLibResultCode.Z_STREAM_END && err != (int)ZLibResultCode.Z_OK) 263 | throw new ZStreamException("deflating: " + z.msg); 264 | if (ZLibUtil.zLibBufSize - z.avail_out > 0) 265 | { 266 | _stream.Write(buf, 0, ZLibUtil.zLibBufSize - z.avail_out); 267 | } 268 | } 269 | while (z.avail_in > 0 || z.avail_out == 0); 270 | try 271 | { 272 | Flush(); 273 | } 274 | catch 275 | { 276 | } 277 | } 278 | 279 | /// 280 | /// Frees allocated resources. 281 | /// 282 | internal void End() 283 | { 284 | z.deflateEnd(); 285 | z.free(); 286 | z = null; 287 | } 288 | 289 | /// 290 | /// Close the current and the underying streams. 291 | /// 292 | public override void Close() 293 | { 294 | try 295 | { 296 | try 297 | { 298 | this.Finish(); 299 | } 300 | catch 301 | { 302 | } 303 | } 304 | finally 305 | { 306 | End(); 307 | _stream.Close(); 308 | _stream = null; 309 | } 310 | } 311 | 312 | /// 313 | /// Flushes the underlying stream. 314 | /// 315 | public override void Flush() 316 | { 317 | _stream.Flush(); 318 | } 319 | 320 | /// 321 | /// Read data from the stream. Please note, that this method throws the exception since doesn't support reading. 322 | /// 323 | public override int Read(byte[] buffer, int offset, int count) 324 | { 325 | throw new NotSupportedException("ZOutputStream doesn't support reading"); 326 | } 327 | 328 | /// 329 | /// Sets the length of the stream. This method throws the exception since the class doesn't support the operation. 330 | /// 331 | public override void SetLength(long value) 332 | { 333 | throw new NotSupportedException("ZOutputStream doesn't support seeking"); 334 | } 335 | 336 | /// 337 | /// Sets the current position in the stream. This method throws the exception since the class doesn't support the operation. 338 | /// 339 | public override long Seek(long offset, SeekOrigin origin) 340 | { 341 | throw new NotSupportedException("ZOutputStream doesn't support seeking"); 342 | } 343 | 344 | /// 345 | /// Gets a value indicating whether the stream supports reading. 346 | /// 347 | /// Always returns false since the doesn't support reading. 348 | public override bool CanRead 349 | { 350 | get { return false; } 351 | } 352 | 353 | /// 354 | /// Whether we can seek to a position in the stream. 355 | /// 356 | /// Always returns false since the doesn't support seeking. 357 | public override bool CanSeek 358 | { 359 | get { return false; } 360 | } 361 | 362 | /// 363 | /// Whether the stream supports the writing operation. 364 | /// 365 | /// This property always returns true. 366 | public override bool CanWrite 367 | { 368 | get { return true; } 369 | } 370 | 371 | /// 372 | /// Returns the length of the stream. Please note that this property always throws the exception since the stream doesn't support the property. 373 | /// 374 | public override long Length 375 | { 376 | get 377 | { 378 | throw new NotSupportedException("ZLibStream doesn't support the Length property"); 379 | } 380 | } 381 | 382 | /// 383 | /// Returns the current position in the compressed stream. This property throws the exception since the stream doesn't support this property. 384 | /// 385 | public override long Position 386 | { 387 | get 388 | { 389 | throw new NotSupportedException("ZOutputStream doesn't support the Position property"); 390 | } 391 | set 392 | { 393 | throw new NotSupportedException("ZOutputStream doesn't support seeking"); 394 | } 395 | } 396 | 397 | #endregion 398 | } 399 | } -------------------------------------------------------------------------------- /KrKrSceneManager/Zlib/ZInputStream.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2006, ComponentAce 2 | // http://www.componentace.com 3 | // All rights reserved. 4 | 5 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 6 | 7 | // Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | // Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 9 | // Neither the name of ComponentAce nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 10 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 11 | 12 | /* 13 | Copyright (c) 2001 Lapo Luchini. 14 | 15 | Redistribution and use in source and binary forms, with or without 16 | modification, are permitted provided that the following conditions are met: 17 | 18 | 1. Redistributions of source code must retain the above copyright notice, 19 | this list of conditions and the following disclaimer. 20 | 21 | 2. Redistributions in binary form must reproduce the above copyright 22 | notice, this list of conditions and the following disclaimer in 23 | the documentation and/or other materials provided with the distribution. 24 | 25 | 3. The names of the authors may not be used to endorse or promote products 26 | derived from this software without specific prior written permission. 27 | 28 | THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, 29 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 30 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS 31 | OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, 32 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 33 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 34 | OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 35 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 36 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 37 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 | */ 39 | /* 40 | * This program is based on zlib-1.1.3, so all credit should go authors 41 | * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) 42 | * and contributors of zlib. 43 | */ 44 | using System; 45 | using System.IO; 46 | 47 | namespace KrKrSceneManager 48 | { 49 | 50 | /// 51 | /// The ZInputStream class is used for decompression of data. For decompression the inflate algorithm is used. 52 | /// To compress data you can use either the class or the class. 53 | /// 54 | /// The following code demonstrates how to use the ZInputStream to decompresses data 55 | /// 56 | /// [C#] 57 | /// private void decompressFile(string inFile, string outFile) 58 | /// { 59 | /// /* Create a file to store decompressed data */ 60 | /// System.IO.FileStream decompressedFile = new System.IO.FileStream(@"c:\data\decompressed.dat", System.IO.FileMode.Create); 61 | /// /* Open a file containing compressed data */ 62 | /// System.IO.FileStream compressedFile = new System.IO.FileStream(@"c:\data\compressed.dat", System.IO.FileMode.Open); 63 | /// /* Create ZInputStream for decompression */ 64 | /// ZInputStream decompressionStream = new ZInputStream(compressedFile); 65 | /// 66 | /// try 67 | /// { 68 | /// byte[] buffer = new byte[2000]; 69 | /// int len; 70 | /// /* Read and decompress data */ 71 | /// while ((len = decompressionStream.Read(buffer, 0, 2000)) > 0) 72 | /// { 73 | /// /* Store decompressed data */ 74 | /// decompressedFile.Write(buffer, 0, len); 75 | /// } 76 | /// } 77 | /// finally 78 | /// { 79 | /// decompressionStream.Close(); 80 | /// decompressedFile.Close(); 81 | /// compressedFile.Close(); 82 | /// } 83 | /// } 84 | /// 85 | /// 86 | internal class ZInputStream : System.IO.Stream 87 | { 88 | #region Fields 89 | 90 | /// 91 | /// ZStream object 92 | /// 93 | private ZStream z = new ZStream(); 94 | 95 | /// 96 | /// Flush strategy 97 | /// 98 | private FlushStrategy flush; 99 | 100 | /// 101 | /// Buffers 102 | /// 103 | private byte[] buf, buf1 = new byte[1]; 104 | 105 | /// 106 | /// Stream to decompress data from 107 | /// 108 | private Stream _stream = null; 109 | 110 | /// 111 | /// True if no more input is available 112 | /// 113 | private bool nomoreinput = false; 114 | 115 | private bool needCopyArrays = false; 116 | 117 | #endregion 118 | 119 | #region Methods 120 | 121 | /// 122 | /// Initializes a block 123 | /// 124 | private void InitBlock() 125 | { 126 | flush = FlushStrategy.Z_NO_FLUSH; 127 | buf = new byte[ZLibUtil.zLibBufSize]; 128 | } 129 | 130 | /// 131 | /// Gets/Sets the current flush strategy. 132 | /// 133 | internal FlushStrategy FlushMode 134 | { 135 | get 136 | { 137 | return flush; 138 | } 139 | 140 | set 141 | { 142 | this.flush = value; 143 | } 144 | 145 | } 146 | 147 | /// 148 | /// Constructor which takes one argument - the containing data to decompress. 149 | /// 150 | /// A stream to decompress data from. 151 | internal ZInputStream(Stream stream) 152 | { 153 | InitBlock(); 154 | this._stream = stream; 155 | z.inflateInit(); 156 | z.next_in = buf; 157 | z.next_in_index = 0; 158 | z.avail_in = 0; 159 | } 160 | 161 | /// 162 | /// Reads a byte of decompressed data from the stream and advances the position within the stream by one byte, or returns -1 if at the end of the stream. 163 | /// 164 | /// The unsigned byte cast to an Int32, or -1 if at the end of the stream. 165 | public override int ReadByte() 166 | { 167 | if (Read(buf1, 0, 1) == -1) 168 | return (-1); 169 | return (buf1[0] & 0xFF); 170 | } 171 | 172 | /// 173 | /// Reads a number of decompressed bytes into the specified byte array. 174 | /// 175 | /// The array used to store decompressed bytes. 176 | /// The location in the array to begin reading. 177 | /// The number of decompressed bytes to read. 178 | /// The number of bytes that were decompressed into the byte array. 179 | /// The following code demonstrates how to use the ZInputStream to decompresses data 180 | /// 181 | /// [C#] 182 | /// private void decompressFile(string inFile, string outFile) 183 | /// { 184 | /// /* Create a file to store decompressed data */ 185 | /// System.IO.FileStream decompressedFile = new System.IO.FileStream(@"c:\data\decompressed.dat", System.IO.FileMode.Create); 186 | /// /* Open a file containing compressed data */ 187 | /// System.IO.FileStream compressedFile = new System.IO.FileStream(@"c:\data\compressed.dat", System.IO.FileMode.Open); 188 | /// /* Create ZInputStream for decompression */ 189 | /// ZInputStream decompressionStream = new ZInputStream(compressedFile); 190 | /// 191 | /// try 192 | /// { 193 | /// byte[] buffer = new byte[2000]; 194 | /// int len; 195 | /// /* Read and decompress data */ 196 | /// while ((len = decompressionStream.Read(buffer, 0, 2000)) > 0) 197 | /// { 198 | /// /* Store decompressed data */ 199 | /// decompressedFile.Write(buffer, 0, len); 200 | /// } 201 | /// } 202 | /// finally 203 | /// { 204 | /// decompressionStream.Close(); 205 | /// decompressedFile.Close(); 206 | /// compressedFile.Close(); 207 | /// } 208 | /// } 209 | /// 210 | /// 211 | public override int Read(byte[] buffer, int offset, int count) 212 | { 213 | if (count == 0) 214 | return 0; 215 | 216 | if (this.needCopyArrays && ZLibUtil.CopyLargeArrayToSmall.GetRemainingDataSize() > 0) 217 | return ZLibUtil.CopyLargeArrayToSmall.CopyData(); 218 | else 219 | this.needCopyArrays = false; 220 | 221 | bool call_finish = false; 222 | int err; 223 | z.next_out = buffer; 224 | z.next_out_index = offset; 225 | z.avail_out = count; 226 | do 227 | { 228 | if ((z.avail_in == 0) && (!nomoreinput)) 229 | { 230 | // if buffer is empty and more input is available, refill it 231 | z.next_in_index = 0; 232 | z.avail_in = ZLibUtil.ReadInput(_stream, buf, 0, ZLibUtil.zLibBufSize); //(ZLibUtil.zLibBufSize 260 | /// Writes a byte to the stream. Please note, that this method throws the since doesn't support writing. 261 | /// 262 | public override void Write(System.Byte[] buffer, int offset, int count) 263 | { 264 | throw new NotSupportedException("ZInputStream doesn't support writing"); 265 | } 266 | 267 | /// 268 | /// Skips n decompressed bytes in the stream. 269 | /// 270 | /// The number of bytes to skip. 271 | public long Skip(long n) 272 | { 273 | int len = 512; 274 | if (n < len) 275 | len = (int)n; 276 | byte[] tmp = new byte[len]; 277 | return ((long)ZLibUtil.ReadInput(this, tmp, 0, tmp.Length)); 278 | } 279 | 280 | /// 281 | /// Reads the final block of decompressed data and finishes decompression. 282 | /// 283 | /// The array used to store decompressed bytes. 284 | /// The location in the array to begin reading. 285 | /// The number of decompressed bytes to read. 286 | /// The number of bytes that were decompressed into the byte array. 287 | public virtual int Finish(byte[] buffer, int offset, int count) 288 | { 289 | 290 | int err; 291 | int nWritten = 0; 292 | do 293 | { 294 | //copy to buf, emulating File.Write() 295 | z.next_out = buf; 296 | z.next_out_index = 0; 297 | z.avail_out = ZLibUtil.zLibBufSize; 298 | err = z.inflate(FlushStrategy.Z_FINISH); 299 | if (err != (int)ZLibResultCode.Z_STREAM_END && err != (int)ZLibResultCode.Z_OK) 300 | throw new ZStreamException("inflating: " + z.msg); 301 | if (ZLibUtil.zLibBufSize - z.avail_out > 0) // 302 | { 303 | this.needCopyArrays = true; 304 | ZLibUtil.CopyLargeArrayToSmall.Initialize(buf, 0, ZLibUtil.zLibBufSize - z.avail_out, buffer, offset + nWritten, count); 305 | int nWrittenNow = ZLibUtil.CopyLargeArrayToSmall.CopyData(); 306 | if (ZLibUtil.CopyLargeArrayToSmall.GetRemainingDataSize() > 0) 307 | return nWrittenNow; 308 | nWritten += ZLibUtil.zLibBufSize - z.avail_out; //1 309 | 310 | } 311 | } 312 | while (z.avail_in > 0 || z.avail_out == 0); 313 | try 314 | { 315 | Flush(); 316 | } 317 | catch 318 | { 319 | } 320 | return nWritten; 321 | } 322 | 323 | /// 324 | /// Frees allocated resources. 325 | /// 326 | internal virtual void End() 327 | { 328 | z.inflateEnd(); 329 | z.free(); 330 | z = null; 331 | } 332 | 333 | /// 334 | /// Closes the stream and the underlying stream. 335 | /// 336 | public override void Close() 337 | { 338 | End(); 339 | _stream.Close(); 340 | _stream = null; 341 | } 342 | 343 | 344 | /// 345 | /// Flushes the stream 346 | /// 347 | public override void Flush() 348 | { 349 | _stream.Flush(); 350 | } 351 | 352 | /// 353 | /// Sets the length of the stream. Please note that the class doesn't support the SetLength operation and thus the is thrown. 354 | /// 355 | /// A new length of the stream. 356 | public override void SetLength(long value) 357 | { 358 | throw new NotSupportedException("ZInputStream doesn't support SetLength"); 359 | } 360 | 361 | /// 362 | /// Gets the length of the stream in bytes. Please note that the class doesn't support the Length property and thus the is thrown. 363 | /// 364 | public override long Length 365 | { 366 | get 367 | { 368 | throw new NotSupportedException("ZLibStream doesn't support the Length property"); 369 | } 370 | } 371 | 372 | /// 373 | /// Gets/Sets the current position in the stream. Please note that the class doesn't support the Position property and thus the is thrown. 374 | /// 375 | public override long Position 376 | { 377 | get 378 | { 379 | throw new NotSupportedException("ZInputStream doesn't support the Position property"); 380 | } 381 | set 382 | { 383 | throw new NotSupportedException("ZInputStream doesn't support seeking"); 384 | } 385 | } 386 | 387 | /// 388 | /// Seek to the offset position (from the beginning or from the current position, etc. see the available values of the parameter)in the stream. This method throws an exception since ZInpitStream doesn't support seeking operation 389 | /// 390 | public override long Seek(long offset, SeekOrigin origin) 391 | { 392 | throw new NotSupportedException("ZInputStream doesn't support seeking"); 393 | } 394 | 395 | /// 396 | /// Gets a value indicating whether the stream supports reading while decompressing a file. 397 | /// 398 | /// 399 | /// Always returns true. 400 | /// 401 | public override bool CanRead 402 | { 403 | get { return true; } 404 | } 405 | 406 | /// 407 | /// Gets a value indicating whether the stream supports writing. 408 | /// 409 | /// For the always returns false. 410 | public override bool CanWrite 411 | { 412 | get { return false; } 413 | } 414 | 415 | /// 416 | /// Gets a value indicating whether the stream supports seeking. 417 | /// 418 | /// Always returns false. 419 | public override bool CanSeek 420 | { 421 | get { return false; } 422 | } 423 | 424 | #endregion 425 | } 426 | } -------------------------------------------------------------------------------- /KrKrSceneManager/Zlib/Inflate.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2006, ComponentAce 2 | // http://www.componentace.com 3 | // All rights reserved. 4 | 5 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 6 | 7 | // Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | // Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 9 | // Neither the name of ComponentAce nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 10 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 11 | 12 | /* 13 | Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. 14 | 15 | Redistribution and use in source and binary forms, with or without 16 | modification, are permitted provided that the following conditions are met: 17 | 18 | 1. Redistributions of source code must retain the above copyright notice, 19 | this list of conditions and the following disclaimer. 20 | 21 | 2. Redistributions in binary form must reproduce the above copyright 22 | notice, this list of conditions and the following disclaimer in 23 | the documentation and/or other materials provided with the distribution. 24 | 25 | 3. The names of the authors may not be used to endorse or promote products 26 | derived from this software without specific prior written permission. 27 | 28 | THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, 29 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 30 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, 31 | INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, 32 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 33 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 34 | OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 35 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 36 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 37 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 | */ 39 | /* 40 | * This program is based on zlib-1.1.3, so all credit should go authors 41 | * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) 42 | * and contributors of zlib. 43 | */ 44 | using System; 45 | 46 | namespace KrKrSceneManager 47 | { 48 | /// 49 | /// This enumeration contains modes of inflate processing 50 | /// 51 | internal enum InflateMode 52 | { 53 | /// 54 | /// waiting for method byte 55 | /// 56 | METHOD = 0, 57 | /// 58 | /// waiting for flag byte 59 | /// 60 | FLAG = 1, 61 | /// 62 | /// four dictionary check bytes to go 63 | /// 64 | DICT4 = 2, 65 | /// 66 | /// three dictionary check bytes to go 67 | /// 68 | DICT3 = 3, 69 | /// 70 | /// two dictionary check bytes to go 71 | /// 72 | DICT2 = 4, 73 | /// 74 | /// one dictionary check byte to go 75 | /// 76 | DICT1 = 5, 77 | /// 78 | /// waiting for inflateSetDictionary 79 | /// 80 | DICT0 = 6, 81 | /// 82 | /// decompressing blocks 83 | /// 84 | BLOCKS = 7, 85 | /// 86 | /// four check bytes to go 87 | /// 88 | CHECK4 = 8, 89 | /// 90 | /// three check bytes to go 91 | /// 92 | CHECK3 = 9, 93 | /// 94 | /// two check bytes to go 95 | /// 96 | CHECK2 = 10, 97 | /// 98 | /// one check byte to go 99 | /// 100 | CHECK1 = 11, 101 | /// 102 | /// finished check, done 103 | /// 104 | DONE = 12, 105 | /// 106 | /// got an error--stay here 107 | /// 108 | BAD = 13 109 | } 110 | 111 | internal sealed class Inflate 112 | { 113 | 114 | #region Fields 115 | 116 | /// 117 | /// current inflate mode 118 | /// 119 | internal InflateMode mode; 120 | 121 | #region mode dependent information 122 | 123 | /// 124 | /// if FLAGS, method byte 125 | /// 126 | private int method; 127 | 128 | // if CHECK, check values to compare 129 | 130 | /// 131 | /// computed check value 132 | /// 133 | private long[] was = new long[1]; 134 | 135 | /// 136 | /// stream check value 137 | /// 138 | private long need; 139 | 140 | /// 141 | /// if BAD, inflateSync's marker bytes count 142 | /// 143 | private int marker; 144 | 145 | #endregion 146 | 147 | #region mode independent information 148 | /// 149 | /// flag for no wrapper 150 | /// 151 | private int nowrap; 152 | /// 153 | /// log2(Window size) (8..15, defaults to 15) 154 | /// 155 | private int wbits; 156 | 157 | #endregion 158 | 159 | /// 160 | /// current inflate_blocks state 161 | /// 162 | private InfBlocks blocks; 163 | 164 | #endregion 165 | 166 | #region Methods 167 | 168 | /// 169 | /// Resets the Inflate algorithm 170 | /// 171 | /// A ZStream object 172 | /// A result code 173 | internal int inflateReset(ZStream z) 174 | { 175 | if (z == null || z.istate == null) 176 | return (int)ZLibResultCode.Z_STREAM_ERROR; 177 | 178 | z.total_in = z.total_out = 0; 179 | z.msg = null; 180 | z.istate.mode = z.istate.nowrap != 0? InflateMode.BLOCKS: InflateMode.METHOD; 181 | z.istate.blocks.reset(z, null); 182 | return (int)ZLibResultCode.Z_OK; 183 | } 184 | 185 | /// 186 | /// Finishes the inflate algorithm processing 187 | /// 188 | /// A ZStream object 189 | /// Operation result code 190 | internal int inflateEnd(ZStream z) 191 | { 192 | if (blocks != null) 193 | blocks.free(z); 194 | blocks = null; 195 | // ZFREE(z, z->state); 196 | return (int)ZLibResultCode.Z_OK; 197 | } 198 | 199 | /// 200 | /// Initializes the inflate algorithm 201 | /// 202 | /// A ZStream object 203 | /// Window size 204 | /// Operation result code 205 | internal int inflateInit(ZStream z, int windowBits) 206 | { 207 | z.msg = null; 208 | blocks = null; 209 | 210 | // handle undocumented nowrap option (no zlib header or check) 211 | nowrap = 0; 212 | if (windowBits < 0) 213 | { 214 | windowBits = - windowBits; 215 | nowrap = 1; 216 | } 217 | 218 | // set Window size 219 | if (windowBits < 8 || windowBits > 15) 220 | { 221 | inflateEnd(z); 222 | return (int)ZLibResultCode.Z_STREAM_ERROR; 223 | } 224 | wbits = windowBits; 225 | 226 | z.istate.blocks = new InfBlocks(z, z.istate.nowrap == 0, 1 << windowBits); 227 | 228 | // reset state 229 | inflateReset(z); 230 | return (int)ZLibResultCode.Z_OK; 231 | } 232 | 233 | /// 234 | /// Runs inflate algorithm 235 | /// 236 | /// A ZStream object 237 | /// Flush strategy 238 | /// Operation result code 239 | internal int inflate(ZStream z, FlushStrategy flush) 240 | { 241 | int r; 242 | int b; 243 | 244 | int internalFlush = (int)flush; 245 | 246 | int res_temp; 247 | 248 | if (z == null || z.istate == null || z.next_in == null) 249 | return (int)ZLibResultCode.Z_STREAM_ERROR; 250 | res_temp = internalFlush == (int)FlushStrategy.Z_FINISH ? (int)ZLibResultCode.Z_BUF_ERROR : (int)ZLibResultCode.Z_OK; 251 | r = (int)ZLibResultCode.Z_BUF_ERROR; 252 | while (true) 253 | { 254 | 255 | switch (z.istate.mode) 256 | { 257 | 258 | case InflateMode.METHOD: 259 | 260 | if (z.avail_in == 0) 261 | return r; r = res_temp; 262 | 263 | z.avail_in--; z.total_in++; 264 | if (((z.istate.method = z.next_in[z.next_in_index++]) & 0xf) != ZLibUtil.Z_DEFLATED) 265 | { 266 | z.istate.mode = InflateMode.BAD; 267 | z.msg = "unknown compression method"; 268 | z.istate.marker = 5; // can't try inflateSync 269 | break; 270 | } 271 | if ((z.istate.method >> 4) + 8 > z.istate.wbits) 272 | { 273 | z.istate.mode = InflateMode.BAD; 274 | z.msg = "invalid Window size"; 275 | z.istate.marker = 5; // can't try inflateSync 276 | break; 277 | } 278 | z.istate.mode = InflateMode.FLAG; 279 | goto case InflateMode.FLAG; 280 | 281 | case InflateMode.FLAG: 282 | 283 | if (z.avail_in == 0) 284 | return r; r = res_temp; 285 | 286 | z.avail_in--; z.total_in++; 287 | b = (z.next_in[z.next_in_index++]) & 0xff; 288 | 289 | if ((((z.istate.method << 8) + b) % 31) != 0) 290 | { 291 | z.istate.mode = InflateMode.BAD; 292 | z.msg = "incorrect header check"; 293 | z.istate.marker = 5; // can't try inflateSync 294 | break; 295 | } 296 | 297 | if ((b & ZLibUtil.PRESET_DICT) == 0) 298 | { 299 | z.istate.mode = InflateMode.BLOCKS; 300 | break; 301 | } 302 | z.istate.mode = InflateMode.DICT4; 303 | goto case InflateMode.DICT4; 304 | 305 | case InflateMode.DICT4: 306 | 307 | if (z.avail_in == 0) 308 | return r; r = res_temp; 309 | 310 | z.avail_in--; z.total_in++; 311 | z.istate.need = ((long)(z.next_in[z.next_in_index++] & 0xff) << 24) & unchecked((int) 0xff000000L); 312 | z.istate.mode = InflateMode.DICT3; 313 | goto case InflateMode.DICT3; 314 | 315 | case InflateMode.DICT3: 316 | 317 | if (z.avail_in == 0) 318 | return r; r = res_temp; 319 | 320 | z.avail_in--; z.total_in++; 321 | z.istate.need += (((long)(z.next_in[z.next_in_index++] & 0xff) << 16) & 0xff0000L); 322 | z.istate.mode = InflateMode.DICT2; 323 | goto case InflateMode.DICT2; 324 | 325 | case InflateMode.DICT2: 326 | 327 | if (z.avail_in == 0) 328 | return r; r = res_temp; 329 | 330 | z.avail_in--; z.total_in++; 331 | z.istate.need += (((long)(z.next_in[z.next_in_index++] & 0xff) << 8) & 0xff00L); 332 | z.istate.mode = InflateMode.DICT1; 333 | goto case InflateMode.DICT1; 334 | 335 | case InflateMode.DICT1: 336 | 337 | if (z.avail_in == 0) 338 | return r; r = res_temp; 339 | 340 | z.avail_in--; z.total_in++; 341 | z.istate.need += (z.next_in[z.next_in_index++] & 0xffL); 342 | z.adler = z.istate.need; 343 | z.istate.mode = InflateMode.DICT0; 344 | return (int)ZLibResultCode.Z_NEED_DICT; 345 | 346 | case InflateMode.DICT0: 347 | z.istate.mode = InflateMode.BAD; 348 | z.msg = "need dictionary"; 349 | z.istate.marker = 0; // can try inflateSync 350 | return (int)ZLibResultCode.Z_STREAM_ERROR; 351 | 352 | case InflateMode.BLOCKS: 353 | 354 | r = z.istate.blocks.proc(z, r); 355 | if (r == (int)ZLibResultCode.Z_DATA_ERROR) 356 | { 357 | z.istate.mode = InflateMode.BAD; 358 | z.istate.marker = 0; // can try inflateSync 359 | break; 360 | } 361 | if (r == (int)ZLibResultCode.Z_OK) 362 | { 363 | r = res_temp; 364 | } 365 | if (r != (int)ZLibResultCode.Z_STREAM_END) 366 | { 367 | return r; 368 | } 369 | r = res_temp; 370 | z.istate.blocks.reset(z, z.istate.was); 371 | if (z.istate.nowrap != 0) 372 | { 373 | z.istate.mode = InflateMode.DONE; 374 | break; 375 | } 376 | z.istate.mode = InflateMode.CHECK4; 377 | goto case InflateMode.CHECK4; 378 | 379 | case InflateMode.CHECK4: 380 | 381 | if (z.avail_in == 0) 382 | return r; r = res_temp; 383 | 384 | z.avail_in--; z.total_in++; 385 | z.istate.need = ((z.next_in[z.next_in_index++] & 0xff) << 24) & unchecked((int) 0xff000000L); 386 | z.istate.mode = InflateMode.CHECK3; 387 | goto case InflateMode.CHECK3; 388 | 389 | case InflateMode.CHECK3: 390 | 391 | if (z.avail_in == 0) 392 | return r; r = res_temp; 393 | 394 | z.avail_in--; z.total_in++; 395 | z.istate.need += (((z.next_in[z.next_in_index++] & 0xff) << 16) & 0xff0000L); 396 | z.istate.mode = InflateMode.CHECK2; 397 | goto case InflateMode.CHECK2; 398 | 399 | case InflateMode.CHECK2: 400 | 401 | if (z.avail_in == 0) 402 | return r; r = res_temp; 403 | 404 | z.avail_in--; z.total_in++; 405 | z.istate.need += (((z.next_in[z.next_in_index++] & 0xff) << 8) & 0xff00L); 406 | z.istate.mode = InflateMode.CHECK1; 407 | goto case InflateMode.CHECK1; 408 | 409 | case InflateMode.CHECK1: 410 | 411 | if (z.avail_in == 0) 412 | return r; r = res_temp; 413 | 414 | z.avail_in--; z.total_in++; 415 | z.istate.need += (z.next_in[z.next_in_index++] & 0xffL); 416 | 417 | if (((int) (z.istate.was[0])) != ((int) (z.istate.need))) 418 | { 419 | z.istate.mode = InflateMode.BAD; 420 | z.msg = "incorrect data check"; 421 | z.istate.marker = 5; // can't try inflateSync 422 | break; 423 | } 424 | 425 | z.istate.mode = InflateMode.DONE; 426 | goto case InflateMode.DONE; 427 | 428 | case InflateMode.DONE: 429 | return (int)ZLibResultCode.Z_STREAM_END; 430 | 431 | case InflateMode.BAD: 432 | return (int)ZLibResultCode.Z_DATA_ERROR; 433 | 434 | default: 435 | return (int)ZLibResultCode.Z_STREAM_ERROR; 436 | 437 | } 438 | } 439 | } 440 | 441 | /// 442 | /// Sets dictionary for the inflate operation 443 | /// 444 | /// A ZStream object 445 | /// An array of byte - dictionary 446 | /// Dictionary length 447 | /// Operation result code 448 | internal int inflateSetDictionary(ZStream z, byte[] dictionary, int dictLength) 449 | { 450 | int index = 0; 451 | int length = dictLength; 452 | if (z == null || z.istate == null || z.istate.mode != InflateMode.DICT0) 453 | return (int)ZLibResultCode.Z_STREAM_ERROR; 454 | 455 | if (Adler32.GetAdler32Checksum(1L, dictionary, 0, dictLength) != z.adler) 456 | { 457 | return (int)ZLibResultCode.Z_DATA_ERROR; 458 | } 459 | 460 | z.adler = Adler32.GetAdler32Checksum(0, null, 0, 0); 461 | 462 | if (length >= (1 << z.istate.wbits)) 463 | { 464 | length = (1 << z.istate.wbits) - 1; 465 | index = dictLength - length; 466 | } 467 | z.istate.blocks.set_dictionary(dictionary, index, length); 468 | z.istate.mode = InflateMode.BLOCKS; 469 | return (int)ZLibResultCode.Z_OK; 470 | } 471 | 472 | 473 | /// 474 | /// Inflate synchronization 475 | /// 476 | /// A ZStream object 477 | /// Operation result code 478 | internal int inflateSync(ZStream z) 479 | { 480 | int n; // number of bytes to look at 481 | int p; // pointer to bytes 482 | int m; // number of marker bytes found in a row 483 | long r, w; // temporaries to save _total_in and _total_out 484 | 485 | // set up 486 | if (z == null || z.istate == null) 487 | return (int)ZLibResultCode.Z_STREAM_ERROR; 488 | if (z.istate.mode != InflateMode.BAD) 489 | { 490 | z.istate.mode = InflateMode.BAD; 491 | z.istate.marker = 0; 492 | } 493 | if ((n = z.avail_in) == 0) 494 | return (int)ZLibResultCode.Z_BUF_ERROR; 495 | p = z.next_in_index; 496 | m = z.istate.marker; 497 | 498 | // search 499 | while (n != 0 && m < 4) 500 | { 501 | if (z.next_in[p] == ZLibUtil.mark[m]) 502 | { 503 | m++; 504 | } 505 | else if (z.next_in[p] != 0) 506 | { 507 | m = 0; 508 | } 509 | else 510 | { 511 | m = 4 - m; 512 | } 513 | p++; n--; 514 | } 515 | 516 | // restore 517 | z.total_in += p - z.next_in_index; 518 | z.next_in_index = p; 519 | z.avail_in = n; 520 | z.istate.marker = m; 521 | 522 | // return no joy or set up to restart on a new block 523 | if (m != 4) 524 | { 525 | return (int)ZLibResultCode.Z_DATA_ERROR; 526 | } 527 | r = z.total_in; w = z.total_out; 528 | inflateReset(z); 529 | z.total_in = r; z.total_out = w; 530 | z.istate.mode = InflateMode.BLOCKS; 531 | return (int)ZLibResultCode.Z_OK; 532 | } 533 | 534 | /// 535 | /// Returns true if inflate is currently at the End of a block generated 536 | /// by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP 537 | /// implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH 538 | /// but removes the length bytes of the resulting empty stored block. When 539 | /// decompressing, PPP checks that at the End of input packet, inflate is 540 | /// waiting for these length bytes. 541 | /// 542 | internal int inflateSyncPoint(ZStream z) 543 | { 544 | if (z == null || z.istate == null || z.istate.blocks == null) 545 | return (int)ZLibResultCode.Z_STREAM_ERROR; 546 | return z.istate.blocks.sync_point(); 547 | } 548 | 549 | #endregion 550 | } 551 | } -------------------------------------------------------------------------------- /ScnEditorGUI/Form1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Configuration; 3 | using System.Drawing; 4 | using System.Runtime.InteropServices; 5 | using System.Windows.Forms; 6 | using KrKrSceneManager; 7 | 8 | namespace ScnEditorGUI { 9 | public partial class Form1 : Form { 10 | /** 11 | * https://stackoverflow.com/questions/57124243/winforms-dark-title-bar-on-windows-10#62811758 12 | */ 13 | [DllImport("dwmapi.dll")] 14 | private static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize); 15 | 16 | private static bool UseImmersiveDarkMode(IntPtr handle, bool enabled) { 17 | if (Environment.OSVersion.Version.Build >= 9200) { 18 | var attribute = 20; // DWMWA_USE_IMMERSIVE_DARK_MODE 19 | 20 | int useImmersiveDarkMode = enabled ? 1 : 0; 21 | return DwmSetWindowAttribute(handle, (int)attribute, ref useImmersiveDarkMode, sizeof(int)) == 0; 22 | } 23 | 24 | return false; 25 | } 26 | 27 | public Form1() { 28 | InitializeComponent(); 29 | MessageBox.Show("This GUI isn't a stable translation tool, this program is a demo for my DLL, \"KrKrSceneManager.dll.\" It's an open-source project to allow you to make your program for editing any .scn files (with sig PSB or MDF) or TJS2 files (with sig TJS2100)\n\nHow to use:\n*Right-click in the window to open or save a file.\n*Select the string in listbox and edit in the text box\n*Press enter to update the string\n\nThis program is unstable!"); 30 | 31 | string maximized = ConfigurationSettings.AppSettings["maximized"]; 32 | string fontSize = ConfigurationSettings.AppSettings["font_size"]; 33 | string darkMode = ConfigurationSettings.AppSettings["dark_mode"]; 34 | string textboxSelectAllWhenClick = ConfigurationSettings.AppSettings["textbox_select_all_when_click"]; 35 | string textboxEditItemWhenCtrlV = ConfigurationSettings.AppSettings["textbox_edit_item_when_ctrl_v"]; 36 | 37 | if (maximized == "true") { 38 | this.WindowState = FormWindowState.Maximized; 39 | } 40 | 41 | Font font = new Font( 42 | "Microsoft Sans Serif", 43 | float.Parse(fontSize), 44 | FontStyle.Regular, 45 | GraphicsUnit.Point, 46 | ((byte)(0)) 47 | ); 48 | this.listBox1.Font = font; 49 | this.textBox1.Font = font; 50 | 51 | if(darkMode == "true") { 52 | UseImmersiveDarkMode(this.Handle, true); 53 | this.BackColor = Color.Black; 54 | this.listBox1.BackColor = Color.Black; 55 | this.listBox1.ForeColor = Color.White; 56 | this.textBox1.BackColor = Color.Black; 57 | this.textBox1.ForeColor = Color.White; 58 | } 59 | 60 | if (textboxSelectAllWhenClick == "true") { 61 | this.textBox1.MouseClick += new MouseEventHandler(this.textBox1_MouseClick); 62 | } 63 | 64 | if (textboxEditItemWhenCtrlV == "true") { 65 | this.textBox1.KeyUp += new KeyEventHandler(this.textBox1_KeyUp); 66 | } 67 | } 68 | 69 | private void openFileToolStripMenuItem_Click(object sender, EventArgs e) { 70 | OpenFileDialog fd = new OpenFileDialog(); 71 | fd.FileName = ""; 72 | fd.Filter = "KiriKiri Compiled Files | *.scn; *.psb|Pack of Resources | *.pimg"; 73 | DialogResult dr = fd.ShowDialog(); 74 | if (dr == DialogResult.OK) 75 | OpenFile(fd.FileName); 76 | } 77 | bool ResourceMode = false; 78 | PSBResManager PRM = new PSBResManager(); 79 | public PSBAnalyzer SCN; 80 | private void OpenFile(string fname) { 81 | if (fname.EndsWith(".pimg")) { 82 | ResourceMode = true; 83 | FileEntry[] Rst = PRM.Import(System.IO.File.ReadAllBytes(fname)); 84 | for (int i = 0; i < Rst.Length; i++) 85 | System.IO.File.WriteAllBytes(AppDomain.CurrentDomain.BaseDirectory + i + ".res", Rst[i].Data); 86 | MessageBox.Show("Resources Extracted in the Program Directory...", "Resource Manager", MessageBoxButtons.OK, MessageBoxIcon.Information); 87 | } 88 | else { 89 | ResourceMode = false; 90 | listBox1.Items.Clear(); 91 | SCN = new PSBAnalyzer(System.IO.File.ReadAllBytes(fname)); 92 | foreach (string str in SCN.Import()) { 93 | listBox1.Items.Add(str); 94 | } 95 | if (SCN.UnkOpCodes) { 96 | MessageBox.Show("Maybe the reorder is wrong... try creating an issue"); 97 | } 98 | if (SCN.HaveEmbedded) { 99 | MessageBox.Show("Looks this psb contains an Embedded File, try opening it as .pimg"); 100 | } 101 | } 102 | } 103 | 104 | private void listBox1_SelectedIndexChanged(object sender, EventArgs e) { 105 | this.Text = "id: " + listBox1.SelectedIndex; 106 | 107 | if (listBox1.SelectedIndex != -1) { 108 | textBox1.Text = listBox1.Items[listBox1.SelectedIndex].ToString(); 109 | } 110 | } 111 | 112 | private void listBox1_MouseClick(object sender, MouseEventArgs e) { 113 | this.Text = "id: " + listBox1.SelectedIndex; 114 | 115 | if (listBox1.SelectedIndex != -1) { 116 | textBox1.Text = listBox1.Items[listBox1.SelectedIndex].ToString(); 117 | } 118 | } 119 | 120 | private void listBox1_KeyDown(object sender, KeyEventArgs e) { 121 | if ((e.Modifiers == Keys.Control) && (e.KeyCode == Keys.F)) { 122 | e.SuppressKeyPress = true; 123 | } 124 | } 125 | 126 | private void listBox1_KeyUp(object sender, KeyEventArgs e) { 127 | if ((e.Modifiers == Keys.Control) && (e.KeyCode == Keys.F)) { 128 | Find modalFind = new Find(this); 129 | modalFind.ShowDialog(this); 130 | } 131 | } 132 | 133 | public void FindMyString(string searchString) { 134 | bool findOk = false; 135 | 136 | // Ensure we have a proper string to search for. 137 | if (!string.IsNullOrEmpty(searchString)) { 138 | // Find the item in the list and store the index to the item. 139 | for (int index = 0; index < listBox1.Items.Count; index++) { 140 | if (listBox1.Items[index].ToString().IndexOf(searchString, StringComparison.OrdinalIgnoreCase) >= 0) { 141 | this.Text = "id: " + index; 142 | listBox1.SetSelected(index, true); 143 | textBox1.Text = listBox1.Items[index].ToString(); 144 | findOk = true; 145 | break; 146 | } 147 | } 148 | } 149 | 150 | if(!findOk) { 151 | MessageBox.Show("The search string did not match any items in the list"); 152 | } 153 | } 154 | 155 | private void saveFileToolStripMenuItem_Click(object sender, EventArgs e) { 156 | if (ResourceMode) { 157 | SaveFileDialog save = new SaveFileDialog(); 158 | save.FileName = ""; 159 | save.Filter = "Pack of Resources | *.pimg"; 160 | DialogResult dr = save.ShowDialog(); 161 | if (dr == DialogResult.OK) { 162 | FileEntry[] Images = new FileEntry[PRM.EntryCount]; 163 | for (int i = 0; i < Images.Length; i++) { 164 | Images[i] = new FileEntry(); 165 | Images[i].Data = System.IO.File.ReadAllBytes(AppDomain.CurrentDomain.BaseDirectory + i + ".res"); 166 | } 167 | byte[] result = PRM.Export(Images); 168 | System.IO.File.WriteAllBytes(save.FileName, result); 169 | } 170 | } 171 | else { 172 | SaveFileDialog save = new SaveFileDialog(); 173 | save.FileName = ""; 174 | save.Filter = "KiriKiri Compiled Files | *.scn; *.psb|Pack of Resources | *.pimg"; 175 | DialogResult dr = save.ShowDialog(); 176 | if (dr == DialogResult.OK) { 177 | string[] Strings = new string[listBox1.Items.Count]; 178 | for (int i = 0; i < Strings.Length; i++) { 179 | Strings[i] = listBox1.Items[i].ToString(); 180 | } 181 | dr = MessageBox.Show("Would you like to compress the script? (Recommended)\n\nThis does not work with old games.", "ScnEditorGUI", MessageBoxButtons.YesNo, MessageBoxIcon.Question); 182 | SCN.CompressPackage = dr == DialogResult.Yes; 183 | PSBStrMan.CompressionLevel = CompressionLevel.Z_BEST_COMPRESSION; //opitional 184 | byte[] outfile = SCN.Export(Strings); 185 | System.IO.File.WriteAllBytes(save.FileName, outfile); 186 | 187 | } 188 | } 189 | MessageBox.Show("File saved."); 190 | } 191 | private void textBox1_KeyPress(object sender, KeyPressEventArgs e) { 192 | if (e.KeyChar == '\r' || e.KeyChar == '\n') { 193 | listBox1.Items[listBox1.SelectedIndex] = textBox1.Text; 194 | } 195 | } 196 | 197 | private void textBox1_MouseClick(object sender, MouseEventArgs e) { 198 | this.textBox1.SelectAll(); 199 | } 200 | 201 | private void textBox1_KeyUp(object sender, KeyEventArgs e) { 202 | if ((e.Modifiers == Keys.Control) && (e.KeyCode == Keys.V)) { 203 | this.listBox1.Items[listBox1.SelectedIndex] = textBox1.Text; 204 | } 205 | } 206 | 207 | private void decompressImageToolStripMenuItem_Click(object sender, EventArgs e) { 208 | OpenFileDialog fd = new OpenFileDialog(); 209 | fd.FileName = ""; 210 | fd.Filter = "All Files | *.*"; 211 | DialogResult dr = fd.ShowDialog(); 212 | if (dr == DialogResult.OK) { 213 | byte[] input = System.IO.File.ReadAllBytes(fd.FileName); 214 | byte[] output = HuffmanTool.DecompressBitmap(input); 215 | string fname = System.IO.Path.GetFileNameWithoutExtension(fd.FileName); 216 | System.IO.File.WriteAllBytes(AppDomain.CurrentDomain.BaseDirectory + fname + "_decompressed.raw", output); 217 | MessageBox.Show("The resource is written as Dracu-Riot, you need to find the resolution and manually add a BMP header and the unknown resolution.\n\n(Try using RGBQuad)", "ScnEditorGUI", MessageBoxButtons.OK, MessageBoxIcon.Information); 218 | } 219 | } 220 | 221 | private void compressImageToolStripMenuItem_Click(object sender, EventArgs e) { 222 | OpenFileDialog fd = new OpenFileDialog(); 223 | fd.FileName = ""; 224 | fd.Filter = "All Files | *.*"; 225 | DialogResult dr = fd.ShowDialog(); 226 | if (dr == DialogResult.OK) { 227 | byte[] input = System.IO.File.ReadAllBytes(fd.FileName); 228 | byte[] output = HuffmanTool.CompressBitmap(input, true); 229 | string fname = System.IO.Path.GetFileNameWithoutExtension(fd.FileName); 230 | System.IO.File.WriteAllBytes(AppDomain.CurrentDomain.BaseDirectory + fname + "_compressed.res", output); 231 | MessageBox.Show("Compressed to Tool directory.", "ScnEditorGUI", MessageBoxButtons.OK, MessageBoxIcon.Information); 232 | 233 | } 234 | } 235 | 236 | void tryRecoveryToolStripMenuItem_Click(object sender, EventArgs e) { 237 | OpenFileDialog ofd = new OpenFileDialog(); 238 | ofd.Filter = "All PSB Files|*.psb;*.scn;*.pimg"; 239 | DialogResult dr = ofd.ShowDialog(); 240 | if (dr == DialogResult.OK) { 241 | try { 242 | byte[] data = System.IO.File.ReadAllBytes(ofd.FileName); 243 | var PSBManager = new PSBStrMan(data); 244 | data = PSBManager.TryRecovery(); 245 | System.IO.File.WriteAllBytes(ofd.FileName, data); 246 | MessageBox.Show("Package offsets were updated", "ScnEditorGUI", MessageBoxButtons.OK, MessageBoxIcon.Information); 247 | } 248 | catch (Exception ex) { 249 | MessageBox.Show("Failed to recover:\n" + ex.Message, "ScnEditorGUI", MessageBoxButtons.OK, MessageBoxIcon.Information); 250 | } 251 | } 252 | } 253 | 254 | 255 | 256 | TJS2SManager TJSEditor; 257 | private void openToolStripMenuItem_Click(object sender, EventArgs e) { 258 | OpenFileDialog fd = new OpenFileDialog(); 259 | fd.FileName = ""; 260 | fd.Filter = "KiriKiri TJS Compiled Files | *.tjs"; 261 | DialogResult dr = fd.ShowDialog(); 262 | if (dr == DialogResult.OK) { 263 | byte[] Data = System.IO.File.ReadAllBytes(fd.FileName); 264 | TJSEditor = new TJS2SManager(Data); 265 | string[] Strings = TJSEditor.Import(); 266 | listBox1.Items.Clear(); 267 | foreach (string str in Strings) 268 | listBox1.Items.Add(str); 269 | } 270 | } 271 | 272 | private void saveToolStripMenuItem_Click(object sender, EventArgs e) { 273 | SaveFileDialog fd = new SaveFileDialog(); 274 | fd.FileName = ""; 275 | fd.Filter = "KiriKiri TJS Compiled Files | *.tjs"; 276 | DialogResult dr = fd.ShowDialog(); 277 | if (dr == DialogResult.OK) { 278 | string[] NewString = new string[listBox1.Items.Count]; 279 | for (int i = 0; i < NewString.Length; i++) 280 | NewString[i] = listBox1.Items[i].ToString(); 281 | System.IO.File.WriteAllBytes(fd.FileName, TJSEditor.Export(NewString)); 282 | MessageBox.Show("File saved."); 283 | } 284 | } 285 | 286 | private void ClipboardSeekSample_Click(object sender, EventArgs e) { 287 | SeekUpdate.Enabled = ClipboardSeekSample.Checked; 288 | } 289 | 290 | string LastClip = string.Empty; 291 | private void SeekUpdate_Tick(object sender, EventArgs e) { 292 | string Clip = Clipboard.GetText(); 293 | if (LastClip != Clip) { 294 | LastClip = Clip; 295 | Clip = SimplfyMatch(Clip); 296 | if (!string.IsNullOrWhiteSpace(Clip)) { 297 | for (int i = 0; i < listBox1.Items.Count; i++) { 298 | string Line = SimplfyMatch(listBox1.Items[i].ToString()); 299 | if (Line == Clip) { 300 | SaveIfNeeded(); 301 | listBox1.SelectedIndex = i; 302 | return; 303 | } 304 | } 305 | for (int i = 0; i < listBox1.Items.Count; i++) { 306 | string Line = SimplfyMatch(listBox1.Items[i].ToString()); 307 | if (Line.Contains(Clip)) { 308 | SaveIfNeeded(); 309 | listBox1.SelectedIndex = i; 310 | return; 311 | } 312 | } 313 | } 314 | } 315 | } 316 | 317 | private void SaveIfNeeded() { 318 | int Sel = listBox1.SelectedIndex; 319 | if (Sel < 0) 320 | return; 321 | if (textBox1.Text != listBox1.Items[Sel].ToString()) 322 | listBox1.Items[Sel] = textBox1.Text; 323 | } 324 | 325 | /// 326 | /// Minify a String at the max. 327 | /// 328 | /// The string to Minify 329 | /// The Minified String 330 | internal static string SimplfyMatch(string Str) { 331 | string Output = TrimString(Str); 332 | for (int i = 0; i < MatchDel.Length; i++) 333 | Output = Output.Replace(MatchDel[i], ""); 334 | return Output; 335 | } 336 | 337 | /// 338 | /// Trim a String 339 | /// 340 | /// The String to Trim 341 | /// The Result 342 | internal static string TrimString(string Input) { 343 | string Result = Input; 344 | Result = TrimStart(Result); 345 | Result = TrimEnd(Result); 346 | return Result; 347 | } 348 | 349 | /// 350 | /// Trim the Begin of the String 351 | /// 352 | /// The String to Trim 353 | /// The Result 354 | internal static string TrimStart(string Txt) { 355 | string rst = Txt; 356 | foreach (string str in TrimContent) { 357 | if (string.IsNullOrEmpty(str)) 358 | continue; 359 | while (rst.StartsWith(str)) { 360 | rst = rst.Substring(str.Length, rst.Length - str.Length); 361 | } 362 | } 363 | 364 | if (rst != Txt) 365 | rst = TrimStart(rst); 366 | 367 | return rst; 368 | } 369 | 370 | /// 371 | /// Trim the End of the String 372 | /// 373 | /// The String to Trim 374 | /// The Result 375 | internal static string TrimEnd(string Txt) { 376 | string rst = Txt; 377 | foreach (string str in TrimContent) { 378 | if (string.IsNullOrEmpty(str)) 379 | continue; 380 | while (rst.EndsWith(str)) { 381 | rst = rst.Substring(0, rst.Length - str.Length); 382 | } 383 | } 384 | 385 | if (rst != Txt) 386 | rst = TrimEnd(rst); 387 | 388 | return rst; 389 | } 390 | static string[] MatchDel = new string[] { 391 | "\r", "\\r", "\n", "\\n", " ", "_r", "―", "-", "*", "♥", "①", "♪" 392 | }; 393 | 394 | static string[] TrimContent = new string[] { 395 | " ", "'", "\"", "<", "(", "[", "“", "[", "《", "«", 396 | "「", "『", "【", "]", "”", "]", "》", 397 | "»", "」", "』", "】", ")", ">", "‘", "’", "〃", "″", 398 | "~", "~", "―", "-", "%K", "%LC", "♪", "%P", "%f;", 399 | "%fSourceHanSansCN-M;", "[―]" 400 | }; 401 | 402 | private void decompressScriptToolStripMenuItem_Click(object sender, EventArgs e) { 403 | OpenFileDialog fd = new OpenFileDialog(); 404 | fd.FileName = "All PSB Files|*.psb;*.scn;*.pimg"; 405 | if (fd.ShowDialog() != DialogResult.OK) 406 | return; 407 | byte[] Content = System.IO.File.ReadAllBytes(fd.FileName); 408 | System.IO.File.WriteAllBytes(fd.FileName, PSBStrMan.ExtractMDF(Content)); 409 | MessageBox.Show("Finished"); 410 | } 411 | } 412 | } 413 | --------------------------------------------------------------------------------