├── .gitattributes ├── Be.Windows.Forms.HexBox ├── AssemblyInfo.cs ├── Be.Windows.Forms.HexBox.csproj ├── Be.Windows.Forms.HexBox.xml ├── BuiltInContextMenu.cs ├── ByteCharConverters.cs ├── ByteCollection.cs ├── BytePositionInfo.cs ├── DataBlock.cs ├── DataMap.cs ├── DynamicByteProvider.cs ├── DynamicFileByteProvider.cs ├── FileByteProvider.cs ├── FileDataBlock.cs ├── FindOptions.cs ├── HexBox.bmp ├── HexBox.cs ├── HexBox.resx ├── HexBox.snk ├── HexCasing.cs ├── IByteProvider.cs ├── MemoryDataBlock.cs ├── NativeMethods.cs ├── Properties │ ├── Resources.Designer.cs │ └── Resources.resx ├── Util.cs └── bin │ └── x86 │ └── Release │ └── Be.Windows.Forms.HexBox.dll ├── CrocExplorerWV.sln ├── CrocExplorerWV.v11.suo ├── CrocExplorerWV ├── App.config ├── CrocExplorerWV.csproj ├── Engine │ ├── Engine3D.cs │ ├── RenderObject.cs │ └── TextureManager.cs ├── FileReference.cs ├── Filesystem.cs ├── Form1.Designer.cs ├── Form1.cs ├── Form1.resx ├── Helper.cs ├── IdxFile.cs ├── Log.cs ├── MODFile.cs ├── PIXFile.cs ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── bin │ └── x86 │ │ └── Release │ │ ├── Be.Windows.Forms.HexBox.dll │ │ ├── CrocExplorerWV.exe │ │ ├── CrocExplorerWV.exe.config │ │ ├── SharpDX.D3DCompiler.dll │ │ ├── SharpDX.D3DCompiler.xml │ │ ├── SharpDX.DXGI.dll │ │ ├── SharpDX.DXGI.xml │ │ ├── SharpDX.Desktop.dll │ │ ├── SharpDX.Desktop.xml │ │ ├── SharpDX.Direct2D1.dll │ │ ├── SharpDX.Direct2D1.xml │ │ ├── SharpDX.Direct3D11.dll │ │ ├── SharpDX.Direct3D11.xml │ │ ├── SharpDX.Mathematics.dll │ │ ├── SharpDX.Mathematics.xml │ │ ├── SharpDX.dll │ │ ├── SharpDX.xml │ │ └── res │ │ └── default.png └── dll │ ├── SharpDX.D3DCompiler.dll │ ├── SharpDX.D3DCompiler.pdb │ ├── SharpDX.D3DCompiler.xml │ ├── SharpDX.DXGI.dll │ ├── SharpDX.DXGI.pdb │ ├── SharpDX.DXGI.xml │ ├── SharpDX.Desktop.dll │ ├── SharpDX.Desktop.pdb │ ├── SharpDX.Desktop.xml │ ├── SharpDX.Direct2D1.dll │ ├── SharpDX.Direct2D1.pdb │ ├── SharpDX.Direct2D1.xml │ ├── SharpDX.Direct3D11.dll │ ├── SharpDX.Direct3D11.pdb │ ├── SharpDX.Direct3D11.xml │ ├── SharpDX.Mathematics.dll │ ├── SharpDX.Mathematics.pdb │ ├── SharpDX.Mathematics.xml │ ├── SharpDX.dll │ ├── SharpDX.pdb │ └── SharpDX.xml └── README.md /.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 | -------------------------------------------------------------------------------- /Be.Windows.Forms.HexBox/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using System.Runtime.CompilerServices; 4 | using System.Security.Permissions; 5 | using System.Runtime.InteropServices; 6 | 7 | // 8 | // General Information about an assembly is controlled through the following 9 | // set of attributes. Change these attribute values to modify the information 10 | // associated with an assembly. 11 | // 12 | [assembly: AssemblyTitle("Be.Windows.Forms.HexBox")] 13 | [assembly: AssemblyDescription("hex edit control (C# DOTNET)")] 14 | [assembly: AssemblyConfiguration("")] 15 | [assembly: AssemblyCompany("Be")] 16 | [assembly: AssemblyProduct("Be.Windows.Forms.HexBox")] 17 | [assembly: AssemblyCopyright("")] 18 | [assembly: AssemblyTrademark("")] 19 | [assembly: AssemblyCulture("")] 20 | 21 | // 22 | // Version information for an assembly consists of the following four values: 23 | // 24 | // Major Version 25 | // Minor Version 26 | // Build Number 27 | // Revision 28 | // 29 | // You can specify all the values or you can default the Revision and Build Numbers 30 | // by using the '*' as shown below: 31 | 32 | [assembly: AssemblyVersion("1.6.0.*")] 33 | 34 | // 35 | // In order to sign your assembly you must specify a key to use. Refer to the 36 | // Microsoft .NET Framework documentation for more information on assembly signing. 37 | // 38 | // Use the attributes below to control which key is used for signing. 39 | // 40 | // Notes: 41 | // (*) If no key is specified, the assembly is not signed. 42 | // (*) KeyName refers to a key that has been installed in the Crypto Service 43 | // Provider (CSP) on your machine. KeyFile refers to a file which contains 44 | // a key. 45 | // (*) If the KeyFile and the KeyName values are both specified, the 46 | // following processing occurs: 47 | // (1) If the KeyName can be found in the CSP, that key is used. 48 | // (2) If the KeyName does not exist and the KeyFile does exist, the key 49 | // in the KeyFile is installed into the CSP and used. 50 | // (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. 51 | // When specifying the KeyFile, the location of the KeyFile should be 52 | // relative to the project output directory which is 53 | // %Project Directory%\obj\. For example, if your KeyFile is 54 | // located in the project directory, you would specify the AssemblyKeyFile 55 | // attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] 56 | // (*) Delay Signing is an advanced option - see the Microsoft .NET Framework 57 | // documentation for more information on this. 58 | // 59 | [assembly: AssemblyDelaySign(false)] 60 | 61 | //[assembly: AssemblyKeyFile("../../HexBox.snk")] 62 | //[assembly: AssemblyKeyName("")] 63 | 64 | //[assembly:IsolatedStorageFilePermission(SecurityAction.RequestRefuse, UserQuota=1048576)] 65 | //[assembly:SecurityPermission(SecurityAction.RequestRefuse, UnmanagedCode=true)] 66 | //[assembly:FileIOPermission(SecurityAction.RequestOptional, Unrestricted=true)] 67 | 68 | [assembly:CLSCompliant(true)] 69 | 70 | [assembly:ComVisible(false)] -------------------------------------------------------------------------------- /Be.Windows.Forms.HexBox/Be.Windows.Forms.HexBox.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Local 5 | 9.0.30729 6 | 2.0 7 | {26C5F25F-B450-4CAF-AD8B-B8D11AE73457} 8 | Debug 9 | AnyCPU 10 | 11 | 12 | 13 | 14 | Be.Windows.Forms.HexBox 15 | HexBox.snk 16 | JScript 17 | Grid 18 | IE50 19 | false 20 | Library 21 | Be.Windows.Forms 22 | OnBuildSuccess 23 | 24 | 25 | 26 | 27 | 28 | 29 | 3.5 30 | true 31 | false 32 | v4.0 33 | publish\ 34 | true 35 | Disk 36 | false 37 | Foreground 38 | 7 39 | Days 40 | false 41 | false 42 | true 43 | 0 44 | 1.0.0.%2a 45 | false 46 | true 47 | 48 | 49 | 50 | bin\Debug\ 51 | false 52 | 285212672 53 | false 54 | 55 | 56 | DEBUG;TRACE 57 | Be.Windows.Forms.HexBox.xml 58 | true 59 | 4096 60 | false 61 | 62 | 63 | false 64 | false 65 | false 66 | false 67 | 4 68 | full 69 | prompt 70 | AllRules.ruleset 71 | false 72 | 73 | 74 | bin\Release\ 75 | false 76 | 285212672 77 | false 78 | 79 | 80 | TRACE 81 | 82 | 83 | false 84 | 4096 85 | false 86 | 87 | 88 | true 89 | false 90 | false 91 | false 92 | 4 93 | none 94 | prompt 95 | BasicCorrectnessRules.ruleset 96 | false 97 | 98 | 99 | true 100 | bin\x86\Debug\ 101 | DEBUG;TRACE 102 | 285212672 103 | Be.Windows.Forms.HexBox.xml 104 | 4096 105 | full 106 | x86 107 | prompt 108 | ManagedMinimumRules.ruleset 109 | 110 | 111 | bin\x86\Release\ 112 | TRACE 113 | 285212672 114 | true 115 | 4096 116 | x86 117 | prompt 118 | ManagedMinimumRules.ruleset 119 | 120 | 121 | 122 | System 123 | 124 | 125 | System.Data 126 | 127 | 128 | False 129 | 130 | 131 | 132 | System.Windows.Forms 133 | 134 | 135 | System.XML 136 | 137 | 138 | 139 | 140 | Code 141 | 142 | 143 | Component 144 | 145 | 146 | Code 147 | 148 | 149 | 150 | Code 151 | 152 | 153 | Code 154 | 155 | 156 | Code 157 | 158 | 159 | Code 160 | 161 | 162 | Code 163 | 164 | 165 | Code 166 | 167 | 168 | 169 | Component 170 | 171 | 172 | 173 | 174 | Code 175 | 176 | 177 | Code 178 | 179 | 180 | Code 181 | 182 | 183 | True 184 | True 185 | Resources.resx 186 | 187 | 188 | 189 | 190 | HexBox.cs 191 | Designer 192 | 193 | 194 | ResXFileCodeGenerator 195 | Resources.Designer.cs 196 | 197 | 198 | 199 | 200 | 201 | False 202 | .NET Framework 3.5 SP1 Client Profile 203 | false 204 | 205 | 206 | False 207 | .NET Framework 2.0 %28x86%29 208 | true 209 | 210 | 211 | False 212 | .NET Framework 3.0 %28x86%29 213 | false 214 | 215 | 216 | False 217 | .NET Framework 3.5 218 | false 219 | 220 | 221 | False 222 | .NET Framework 3.5 SP1 223 | false 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | -------------------------------------------------------------------------------- /Be.Windows.Forms.HexBox/BuiltInContextMenu.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Drawing; 5 | using System.ComponentModel; 6 | using System.Windows.Forms; 7 | 8 | namespace Be.Windows.Forms 9 | { 10 | /// 11 | /// Defines a build-in ContextMenuStrip manager for HexBox control to show Copy, Cut, Paste menu in contextmenu of the control. 12 | /// 13 | [TypeConverterAttribute(typeof(ExpandableObjectConverter))] 14 | public sealed class BuiltInContextMenu : Component 15 | { 16 | /// 17 | /// Contains the HexBox control. 18 | /// 19 | HexBox _hexBox; 20 | /// 21 | /// Contains the ContextMenuStrip control. 22 | /// 23 | ContextMenuStrip _contextMenuStrip; 24 | /// 25 | /// Contains the "Cut"-ToolStripMenuItem object. 26 | /// 27 | ToolStripMenuItem _cutToolStripMenuItem; 28 | /// 29 | /// Contains the "Copy"-ToolStripMenuItem object. 30 | /// 31 | ToolStripMenuItem _copyToolStripMenuItem; 32 | /// 33 | /// Contains the "Paste"-ToolStripMenuItem object. 34 | /// 35 | ToolStripMenuItem _pasteToolStripMenuItem; 36 | /// 37 | /// Contains the "Select All"-ToolStripMenuItem object. 38 | /// 39 | ToolStripMenuItem _selectAllToolStripMenuItem; 40 | /// 41 | /// Initializes a new instance of BuildInContextMenu class. 42 | /// 43 | /// the HexBox control 44 | internal BuiltInContextMenu(HexBox hexBox) 45 | { 46 | _hexBox = hexBox; 47 | _hexBox.ByteProviderChanged += new EventHandler(HexBox_ByteProviderChanged); 48 | } 49 | /// 50 | /// If ByteProvider 51 | /// 52 | /// the sender object 53 | /// the event data 54 | void HexBox_ByteProviderChanged(object sender, EventArgs e) 55 | { 56 | CheckBuiltInContextMenu(); 57 | } 58 | /// 59 | /// Assigns the ContextMenuStrip control to the HexBox control. 60 | /// 61 | void CheckBuiltInContextMenu() 62 | { 63 | if (Util.DesignMode) 64 | return; 65 | 66 | if (this._contextMenuStrip == null) 67 | { 68 | ContextMenuStrip cms = new ContextMenuStrip(); 69 | _cutToolStripMenuItem = new ToolStripMenuItem(CutMenuItemTextInternal, CutMenuItemImage, new EventHandler(CutMenuItem_Click)); 70 | cms.Items.Add(_cutToolStripMenuItem); 71 | _copyToolStripMenuItem = new ToolStripMenuItem(CopyMenuItemTextInternal, CopyMenuItemImage, new EventHandler(CopyMenuItem_Click)); 72 | cms.Items.Add(_copyToolStripMenuItem); 73 | _pasteToolStripMenuItem = new ToolStripMenuItem(PasteMenuItemTextInternal, PasteMenuItemImage, new EventHandler(PasteMenuItem_Click)); 74 | cms.Items.Add(_pasteToolStripMenuItem); 75 | 76 | cms.Items.Add(new ToolStripSeparator()); 77 | 78 | _selectAllToolStripMenuItem = new ToolStripMenuItem(SelectAllMenuItemTextInternal, SelectAllMenuItemImage, new EventHandler(SelectAllMenuItem_Click)); 79 | cms.Items.Add(_selectAllToolStripMenuItem); 80 | cms.Opening += new CancelEventHandler(BuildInContextMenuStrip_Opening); 81 | 82 | _contextMenuStrip = cms; 83 | } 84 | 85 | if (this._hexBox.ByteProvider == null && this._hexBox.ContextMenuStrip == this._contextMenuStrip) 86 | this._hexBox.ContextMenuStrip = null; 87 | else if (this._hexBox.ByteProvider != null && this._hexBox.ContextMenuStrip == null) 88 | this._hexBox.ContextMenuStrip = _contextMenuStrip; 89 | } 90 | /// 91 | /// Before opening the ContextMenuStrip, we manage the availability of the items. 92 | /// 93 | /// the sender object 94 | /// the event data 95 | void BuildInContextMenuStrip_Opening(object sender, CancelEventArgs e) 96 | { 97 | _cutToolStripMenuItem.Enabled = this._hexBox.CanCut(); 98 | _copyToolStripMenuItem.Enabled = this._hexBox.CanCopy(); 99 | _pasteToolStripMenuItem.Enabled = this._hexBox.CanPaste(); 100 | _selectAllToolStripMenuItem.Enabled = this._hexBox.CanSelectAll(); 101 | } 102 | /// 103 | /// The handler for the "Cut"-Click event 104 | /// 105 | /// the sender object 106 | /// the event data 107 | void CutMenuItem_Click(object sender, EventArgs e) { this._hexBox.Cut(); } 108 | /// 109 | /// The handler for the "Copy"-Click event 110 | /// 111 | /// the sender object 112 | /// the event data 113 | void CopyMenuItem_Click(object sender, EventArgs e) { this._hexBox.Copy(); } 114 | /// 115 | /// The handler for the "Paste"-Click event 116 | /// 117 | /// the sender object 118 | /// the event data 119 | void PasteMenuItem_Click(object sender, EventArgs e) { this._hexBox.Paste(); } 120 | /// 121 | /// The handler for the "Select All"-Click event 122 | /// 123 | /// the sender object 124 | /// the event data 125 | void SelectAllMenuItem_Click(object sender, EventArgs e) { this._hexBox.SelectAll(); } 126 | /// 127 | /// Gets or sets the custom text of the "Copy" ContextMenuStrip item. 128 | /// 129 | [Category("BuiltIn-ContextMenu"), DefaultValue(null), Localizable(true)] 130 | public string CopyMenuItemText 131 | { 132 | get { return _copyMenuItemText; } 133 | set { _copyMenuItemText = value; } 134 | } string _copyMenuItemText; 135 | 136 | /// 137 | /// Gets or sets the custom text of the "Cut" ContextMenuStrip item. 138 | /// 139 | [Category("BuiltIn-ContextMenu"), DefaultValue(null), Localizable(true)] 140 | public string CutMenuItemText 141 | { 142 | get { return _cutMenuItemText; } 143 | set { _cutMenuItemText = value; } 144 | } string _cutMenuItemText; 145 | 146 | /// 147 | /// Gets or sets the custom text of the "Paste" ContextMenuStrip item. 148 | /// 149 | [Category("BuiltIn-ContextMenu"), DefaultValue(null), Localizable(true)] 150 | public string PasteMenuItemText 151 | { 152 | get { return _pasteMenuItemText; } 153 | set { _pasteMenuItemText = value; } 154 | } string _pasteMenuItemText; 155 | 156 | /// 157 | /// Gets or sets the custom text of the "Select All" ContextMenuStrip item. 158 | /// 159 | [Category("BuiltIn-ContextMenu"), DefaultValue(null), Localizable(true)] 160 | public string SelectAllMenuItemText 161 | { 162 | get { return _selectAllMenuItemText; } 163 | set { _selectAllMenuItemText = value; } 164 | } string _selectAllMenuItemText = null; 165 | 166 | /// 167 | /// Gets the text of the "Cut" ContextMenuStrip item. 168 | /// 169 | internal string CutMenuItemTextInternal { get { return !string.IsNullOrEmpty(CutMenuItemText) ? CutMenuItemText : "Cut"; } } 170 | /// 171 | /// Gets the text of the "Copy" ContextMenuStrip item. 172 | /// 173 | internal string CopyMenuItemTextInternal { get { return !string.IsNullOrEmpty(CopyMenuItemText) ? CopyMenuItemText : "Copy"; } } 174 | /// 175 | /// Gets the text of the "Paste" ContextMenuStrip item. 176 | /// 177 | internal string PasteMenuItemTextInternal { get { return !string.IsNullOrEmpty(PasteMenuItemText) ? PasteMenuItemText : "Paste"; } } 178 | /// 179 | /// Gets the text of the "Select All" ContextMenuStrip item. 180 | /// 181 | internal string SelectAllMenuItemTextInternal { get { return !string.IsNullOrEmpty(SelectAllMenuItemText) ? SelectAllMenuItemText : "SelectAll"; } } 182 | 183 | /// 184 | /// Gets or sets the image of the "Cut" ContextMenuStrip item. 185 | /// 186 | [Category("BuiltIn-ContextMenu"), DefaultValue(null)] 187 | public Image CutMenuItemImage 188 | { 189 | get { return _cutMenuItemImage; } 190 | set { _cutMenuItemImage = value; } 191 | } Image _cutMenuItemImage = null; 192 | /// 193 | /// Gets or sets the image of the "Copy" ContextMenuStrip item. 194 | /// 195 | [Category("BuiltIn-ContextMenu"), DefaultValue(null)] 196 | public Image CopyMenuItemImage 197 | { 198 | get { return _copyMenuItemImage; } 199 | set { _copyMenuItemImage = value; } 200 | } Image _copyMenuItemImage = null; 201 | /// 202 | /// Gets or sets the image of the "Paste" ContextMenuStrip item. 203 | /// 204 | [Category("BuiltIn-ContextMenu"), DefaultValue(null)] 205 | public Image PasteMenuItemImage 206 | { 207 | get { return _pasteMenuItemImage; } 208 | set { _pasteMenuItemImage = value; } 209 | } Image _pasteMenuItemImage = null; 210 | /// 211 | /// Gets or sets the image of the "Select All" ContextMenuStrip item. 212 | /// 213 | [Category("BuiltIn-ContextMenu"), DefaultValue(null)] 214 | public Image SelectAllMenuItemImage 215 | { 216 | get { return _selectAllMenuItemImage; } 217 | set { _selectAllMenuItemImage = value; } 218 | } Image _selectAllMenuItemImage = null; 219 | } 220 | } 221 | -------------------------------------------------------------------------------- /Be.Windows.Forms.HexBox/ByteCharConverters.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Be.Windows.Forms 6 | { 7 | /// 8 | /// The interface for objects that can translate between characters and bytes. 9 | /// 10 | public interface IByteCharConverter 11 | { 12 | /// 13 | /// Returns the character to display for the byte passed across. 14 | /// 15 | /// 16 | /// 17 | char ToChar(byte b); 18 | 19 | /// 20 | /// Returns the byte to use when the character passed across is entered during editing. 21 | /// 22 | /// 23 | /// 24 | byte ToByte(char c); 25 | } 26 | 27 | /// 28 | /// The default implementation. 29 | /// 30 | public class DefaultByteCharConverter : IByteCharConverter 31 | { 32 | /// 33 | /// Returns the character to display for the byte passed across. 34 | /// 35 | /// 36 | /// 37 | public virtual char ToChar(byte b) 38 | { 39 | return b > 0x1F && !(b > 0x7E && b < 0xA0) ? (char)b : '.'; 40 | } 41 | 42 | /// 43 | /// Returns the byte to use for the character passed across. 44 | /// 45 | /// 46 | /// 47 | public virtual byte ToByte(char c) 48 | { 49 | return (byte)c; 50 | } 51 | 52 | /// 53 | /// Returns a description of the byte char provider. 54 | /// 55 | /// 56 | public override string ToString() 57 | { 58 | return "ANSI (Default)"; 59 | } 60 | } 61 | 62 | /// 63 | /// A byte char provider that can translate bytes encoded in codepage 500 EBCDIC 64 | /// 65 | public class EbcdicByteCharProvider : IByteCharConverter 66 | { 67 | /// 68 | /// The IBM EBCDIC code page 500 encoding. Note that this is not always supported by .NET, 69 | /// the underlying platform has to provide support for it. 70 | /// 71 | private Encoding _ebcdicEncoding = Encoding.GetEncoding(500); 72 | 73 | /// 74 | /// Returns the EBCDIC character corresponding to the byte passed across. 75 | /// 76 | /// 77 | /// 78 | public virtual char ToChar(byte b) 79 | { 80 | string encoded = _ebcdicEncoding.GetString(new byte[] { b }); 81 | return encoded.Length > 0 ? encoded[0] : '.'; 82 | } 83 | 84 | /// 85 | /// Returns the byte corresponding to the EBCDIC character passed across. 86 | /// 87 | /// 88 | /// 89 | public virtual byte ToByte(char c) 90 | { 91 | byte[] decoded = _ebcdicEncoding.GetBytes(new char[] { c }); 92 | return decoded.Length > 0 ? decoded[0] : (byte)0; 93 | } 94 | 95 | /// 96 | /// Returns a description of the byte char provider. 97 | /// 98 | /// 99 | public override string ToString() 100 | { 101 | return "EBCDIC (Code Page 500)"; 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /Be.Windows.Forms.HexBox/ByteCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | using System.Collections; 4 | 5 | namespace Be.Windows.Forms 6 | { 7 | /// 8 | /// Represents a collection of bytes. 9 | /// 10 | public class ByteCollection : CollectionBase 11 | { 12 | /// 13 | /// Initializes a new instance of ByteCollection class. 14 | /// 15 | public ByteCollection() { } 16 | 17 | /// 18 | /// Initializes a new instance of ByteCollection class. 19 | /// 20 | /// an array of bytes to add to collection 21 | public ByteCollection(byte[] bs) 22 | { AddRange(bs); } 23 | 24 | /// 25 | /// Gets or sets the value of a byte 26 | /// 27 | public byte this[int index] 28 | { 29 | get { return (byte)List[index]; } 30 | set { List[index] = value; } 31 | } 32 | 33 | /// 34 | /// Adds a byte into the collection. 35 | /// 36 | /// the byte to add 37 | public void Add(byte b) 38 | { List.Add(b); } 39 | 40 | /// 41 | /// Adds a range of bytes to the collection. 42 | /// 43 | /// the bytes to add 44 | public void AddRange(byte[] bs) 45 | { InnerList.AddRange(bs); } 46 | 47 | /// 48 | /// Removes a byte from the collection. 49 | /// 50 | /// the byte to remove 51 | public void Remove(byte b) 52 | { List.Remove(b); } 53 | 54 | /// 55 | /// Removes a range of bytes from the collection. 56 | /// 57 | /// the index of the start byte 58 | /// the count of the bytes to remove 59 | public void RemoveRange(int index, int count) 60 | { InnerList.RemoveRange(index, count); } 61 | 62 | /// 63 | /// Inserts a range of bytes to the collection. 64 | /// 65 | /// the index of start byte 66 | /// an array of bytes to insert 67 | public void InsertRange(int index, byte[] bs) 68 | { InnerList.InsertRange(index, bs); } 69 | 70 | /// 71 | /// Gets all bytes in the array 72 | /// 73 | /// an array of bytes. 74 | public byte[] GetBytes() 75 | { 76 | byte[] bytes = new byte[Count]; 77 | InnerList.CopyTo(0, bytes, 0, bytes.Length); 78 | return bytes; 79 | } 80 | 81 | /// 82 | /// Inserts a byte to the collection. 83 | /// 84 | /// the index 85 | /// a byte to insert 86 | public void Insert(int index, byte b) 87 | { 88 | InnerList.Insert(index, b); 89 | } 90 | 91 | /// 92 | /// Returns the index of the given byte. 93 | /// 94 | public int IndexOf(byte b) 95 | { 96 | return InnerList.IndexOf(b); 97 | } 98 | 99 | /// 100 | /// Returns true, if the byte exists in the collection. 101 | /// 102 | public bool Contains(byte b) 103 | { 104 | return InnerList.Contains(b); 105 | } 106 | 107 | /// 108 | /// Copies the content of the collection into the given array. 109 | /// 110 | public void CopyTo(byte[] bs, int index) 111 | { 112 | InnerList.CopyTo(bs, index); 113 | } 114 | 115 | /// 116 | /// Copies the content of the collection into an array. 117 | /// 118 | /// the array containing all bytes. 119 | public byte[] ToArray() 120 | { 121 | byte[] data = new byte[this.Count]; 122 | this.CopyTo(data, 0); 123 | return data; 124 | } 125 | 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /Be.Windows.Forms.HexBox/BytePositionInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Be.Windows.Forms 6 | { 7 | /// 8 | /// Represents a position in the HexBox control 9 | /// 10 | struct BytePositionInfo 11 | { 12 | public BytePositionInfo(long index, int characterPosition) 13 | { 14 | _index = index; 15 | _characterPosition = characterPosition; 16 | } 17 | 18 | public int CharacterPosition 19 | { 20 | get { return _characterPosition; } 21 | } int _characterPosition; 22 | 23 | public long Index 24 | { 25 | get { return _index; } 26 | } long _index; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Be.Windows.Forms.HexBox/DataBlock.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Be.Windows.Forms 4 | { 5 | internal abstract class DataBlock 6 | { 7 | internal DataMap _map; 8 | internal DataBlock _nextBlock; 9 | internal DataBlock _previousBlock; 10 | 11 | public abstract long Length 12 | { 13 | get; 14 | } 15 | 16 | public DataMap Map 17 | { 18 | get 19 | { 20 | return _map; 21 | } 22 | } 23 | 24 | public DataBlock NextBlock 25 | { 26 | get 27 | { 28 | return _nextBlock; 29 | } 30 | } 31 | 32 | public DataBlock PreviousBlock 33 | { 34 | get 35 | { 36 | return _previousBlock; 37 | } 38 | } 39 | 40 | public abstract void RemoveBytes(long position, long count); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Be.Windows.Forms.HexBox/DataMap.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Text; 4 | 5 | namespace Be.Windows.Forms 6 | { 7 | internal class DataMap : ICollection, IEnumerable 8 | { 9 | readonly object _syncRoot = new object(); 10 | internal int _count; 11 | internal DataBlock _firstBlock; 12 | internal int _version; 13 | 14 | public DataMap() 15 | { 16 | } 17 | 18 | public DataMap(IEnumerable collection) 19 | { 20 | if (collection == null) 21 | { 22 | throw new ArgumentNullException("collection"); 23 | } 24 | 25 | foreach (DataBlock item in collection) 26 | { 27 | AddLast(item); 28 | } 29 | } 30 | 31 | public DataBlock FirstBlock 32 | { 33 | get 34 | { 35 | return _firstBlock; 36 | } 37 | } 38 | 39 | public void AddAfter(DataBlock block, DataBlock newBlock) 40 | { 41 | AddAfterInternal(block, newBlock); 42 | } 43 | 44 | public void AddBefore(DataBlock block, DataBlock newBlock) 45 | { 46 | AddBeforeInternal(block, newBlock); 47 | } 48 | 49 | public void AddFirst(DataBlock block) 50 | { 51 | if (_firstBlock == null) 52 | { 53 | AddBlockToEmptyMap(block); 54 | } 55 | else 56 | { 57 | AddBeforeInternal(_firstBlock, block); 58 | } 59 | } 60 | 61 | public void AddLast(DataBlock block) 62 | { 63 | if (_firstBlock == null) 64 | { 65 | AddBlockToEmptyMap(block); 66 | } 67 | else 68 | { 69 | AddAfterInternal(GetLastBlock(), block); 70 | } 71 | } 72 | 73 | public void Remove(DataBlock block) 74 | { 75 | RemoveInternal(block); 76 | } 77 | 78 | public void RemoveFirst() 79 | { 80 | if (_firstBlock == null) 81 | { 82 | throw new InvalidOperationException("The collection is empty."); 83 | } 84 | RemoveInternal(_firstBlock); 85 | } 86 | 87 | public void RemoveLast() 88 | { 89 | if (_firstBlock == null) 90 | { 91 | throw new InvalidOperationException("The collection is empty."); 92 | } 93 | RemoveInternal(GetLastBlock()); 94 | } 95 | 96 | public DataBlock Replace(DataBlock block, DataBlock newBlock) 97 | { 98 | AddAfterInternal(block, newBlock); 99 | RemoveInternal(block); 100 | return newBlock; 101 | } 102 | 103 | public void Clear() 104 | { 105 | DataBlock block = FirstBlock; 106 | while (block != null) 107 | { 108 | DataBlock nextBlock = block.NextBlock; 109 | InvalidateBlock(block); 110 | block = nextBlock; 111 | } 112 | _firstBlock = null; 113 | _count = 0; 114 | _version++; 115 | } 116 | 117 | void AddAfterInternal(DataBlock block, DataBlock newBlock) 118 | { 119 | newBlock._previousBlock = block; 120 | newBlock._nextBlock = block._nextBlock; 121 | newBlock._map = this; 122 | 123 | if (block._nextBlock != null) 124 | { 125 | block._nextBlock._previousBlock = newBlock; 126 | } 127 | block._nextBlock = newBlock; 128 | 129 | this._version++; 130 | this._count++; 131 | } 132 | 133 | void AddBeforeInternal(DataBlock block, DataBlock newBlock) 134 | { 135 | newBlock._nextBlock = block; 136 | newBlock._previousBlock = block._previousBlock; 137 | newBlock._map = this; 138 | 139 | if (block._previousBlock != null) 140 | { 141 | block._previousBlock._nextBlock = newBlock; 142 | } 143 | block._previousBlock = newBlock; 144 | 145 | if (_firstBlock == block) 146 | { 147 | _firstBlock = newBlock; 148 | } 149 | this._version++; 150 | this._count++; 151 | } 152 | 153 | void RemoveInternal(DataBlock block) 154 | { 155 | DataBlock previousBlock = block._previousBlock; 156 | DataBlock nextBlock = block._nextBlock; 157 | 158 | if (previousBlock != null) 159 | { 160 | previousBlock._nextBlock = nextBlock; 161 | } 162 | 163 | if (nextBlock != null) 164 | { 165 | nextBlock._previousBlock = previousBlock; 166 | } 167 | 168 | if (_firstBlock == block) 169 | { 170 | _firstBlock = nextBlock; 171 | } 172 | 173 | InvalidateBlock(block); 174 | 175 | _count--; 176 | _version++; 177 | } 178 | 179 | DataBlock GetLastBlock() 180 | { 181 | DataBlock lastBlock = null; 182 | for (DataBlock block = FirstBlock; block != null; block = block.NextBlock) 183 | { 184 | lastBlock = block; 185 | } 186 | return lastBlock; 187 | } 188 | 189 | void InvalidateBlock(DataBlock block) 190 | { 191 | block._map = null; 192 | block._nextBlock = null; 193 | block._previousBlock = null; 194 | } 195 | 196 | void AddBlockToEmptyMap(DataBlock block) 197 | { 198 | block._map = this; 199 | block._nextBlock = null; 200 | block._previousBlock = null; 201 | 202 | _firstBlock = block; 203 | _version++; 204 | _count++; 205 | } 206 | 207 | #region ICollection Members 208 | public void CopyTo(Array array, int index) 209 | { 210 | DataBlock[] blockArray = array as DataBlock[]; 211 | for (DataBlock block = FirstBlock; block != null; block = block.NextBlock) 212 | { 213 | blockArray[index++] = block; 214 | } 215 | } 216 | 217 | public int Count 218 | { 219 | get 220 | { 221 | return _count; 222 | } 223 | } 224 | 225 | public bool IsSynchronized 226 | { 227 | get 228 | { 229 | return false; 230 | } 231 | } 232 | 233 | public object SyncRoot 234 | { 235 | get 236 | { 237 | return _syncRoot; 238 | } 239 | } 240 | #endregion 241 | 242 | #region IEnumerable Members 243 | public IEnumerator GetEnumerator() 244 | { 245 | return new Enumerator(this); 246 | } 247 | #endregion 248 | 249 | #region Enumerator Nested Type 250 | internal class Enumerator : IEnumerator, IDisposable 251 | { 252 | DataMap _map; 253 | DataBlock _current; 254 | int _index; 255 | int _version; 256 | 257 | internal Enumerator(DataMap map) 258 | { 259 | _map = map; 260 | _version = map._version; 261 | _current = null; 262 | _index = -1; 263 | } 264 | 265 | object IEnumerator.Current 266 | { 267 | get 268 | { 269 | if (_index < 0 || _index > _map.Count) 270 | { 271 | throw new InvalidOperationException("Enumerator is positioned before the first element or after the last element of the collection."); 272 | } 273 | return _current; 274 | } 275 | } 276 | 277 | public bool MoveNext() 278 | { 279 | if (this._version != _map._version) 280 | { 281 | throw new InvalidOperationException("Collection was modified after the enumerator was instantiated."); 282 | } 283 | 284 | if (_index >= _map.Count) 285 | { 286 | return false; 287 | } 288 | 289 | if (++_index == 0) 290 | { 291 | _current = _map.FirstBlock; 292 | } 293 | else 294 | { 295 | _current = _current.NextBlock; 296 | } 297 | 298 | return (_index < _map.Count); 299 | } 300 | 301 | void IEnumerator.Reset() 302 | { 303 | if (this._version != this._map._version) 304 | { 305 | throw new InvalidOperationException("Collection was modified after the enumerator was instantiated."); 306 | } 307 | 308 | this._index = -1; 309 | this._current = null; 310 | } 311 | 312 | public void Dispose() 313 | { 314 | } 315 | } 316 | #endregion 317 | } 318 | } 319 | -------------------------------------------------------------------------------- /Be.Windows.Forms.HexBox/DynamicByteProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Be.Windows.Forms 5 | { 6 | /// 7 | /// Byte provider for a small amount of data. 8 | /// 9 | public class DynamicByteProvider : IByteProvider 10 | { 11 | /// 12 | /// Contains information about changes. 13 | /// 14 | bool _hasChanges; 15 | /// 16 | /// Contains a byte collection. 17 | /// 18 | List _bytes; 19 | 20 | /// 21 | /// Initializes a new instance of the DynamicByteProvider class. 22 | /// 23 | /// 24 | public DynamicByteProvider(byte[] data) : this(new List(data)) 25 | { 26 | } 27 | 28 | /// 29 | /// Initializes a new instance of the DynamicByteProvider class. 30 | /// 31 | /// 32 | public DynamicByteProvider(List bytes) 33 | { 34 | _bytes = bytes; 35 | } 36 | 37 | /// 38 | /// Raises the Changed event. 39 | /// 40 | void OnChanged(EventArgs e) 41 | { 42 | _hasChanges = true; 43 | 44 | if(Changed != null) 45 | Changed(this, e); 46 | } 47 | 48 | /// 49 | /// Raises the LengthChanged event. 50 | /// 51 | void OnLengthChanged(EventArgs e) 52 | { 53 | if(LengthChanged != null) 54 | LengthChanged(this, e); 55 | } 56 | 57 | /// 58 | /// Gets the byte collection. 59 | /// 60 | public List Bytes 61 | { 62 | get { return _bytes; } 63 | } 64 | 65 | #region IByteProvider Members 66 | /// 67 | /// True, when changes are done. 68 | /// 69 | public bool HasChanges() 70 | { 71 | return _hasChanges; 72 | } 73 | 74 | /// 75 | /// Applies changes. 76 | /// 77 | public void ApplyChanges() 78 | { 79 | _hasChanges = false; 80 | } 81 | 82 | /// 83 | /// Occurs, when the write buffer contains new changes. 84 | /// 85 | public event EventHandler Changed; 86 | 87 | /// 88 | /// Occurs, when InsertBytes or DeleteBytes method is called. 89 | /// 90 | public event EventHandler LengthChanged; 91 | 92 | 93 | /// 94 | /// Reads a byte from the byte collection. 95 | /// 96 | /// the index of the byte to read 97 | /// the byte 98 | public byte ReadByte(long index) 99 | { return _bytes[(int)index]; } 100 | 101 | /// 102 | /// Write a byte into the byte collection. 103 | /// 104 | /// the index of the byte to write. 105 | /// the byte 106 | public void WriteByte(long index, byte value) 107 | { 108 | _bytes[(int)index] = value; 109 | OnChanged(EventArgs.Empty); 110 | } 111 | 112 | /// 113 | /// Deletes bytes from the byte collection. 114 | /// 115 | /// the start index of the bytes to delete. 116 | /// the length of bytes to delete. 117 | public void DeleteBytes(long index, long length) 118 | { 119 | int internal_index = (int)Math.Max(0, index); 120 | int internal_length = (int)Math.Min((int)Length, length); 121 | _bytes.RemoveRange(internal_index, internal_length); 122 | 123 | OnLengthChanged(EventArgs.Empty); 124 | OnChanged(EventArgs.Empty); 125 | } 126 | 127 | /// 128 | /// Inserts byte into the byte collection. 129 | /// 130 | /// the start index of the bytes in the byte collection 131 | /// the byte array to insert 132 | public void InsertBytes(long index, byte[] bs) 133 | { 134 | _bytes.InsertRange((int)index, bs); 135 | 136 | OnLengthChanged(EventArgs.Empty); 137 | OnChanged(EventArgs.Empty); 138 | } 139 | 140 | /// 141 | /// Gets the length of the bytes in the byte collection. 142 | /// 143 | public long Length 144 | { 145 | get 146 | { 147 | return _bytes.Count; 148 | } 149 | } 150 | 151 | /// 152 | /// Returns true 153 | /// 154 | public bool SupportsWriteByte() 155 | { 156 | return true; 157 | } 158 | 159 | /// 160 | /// Returns true 161 | /// 162 | public bool SupportsInsertBytes() 163 | { 164 | return true; 165 | } 166 | 167 | /// 168 | /// Returns true 169 | /// 170 | public bool SupportsDeleteBytes() 171 | { 172 | return true; 173 | } 174 | #endregion 175 | 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /Be.Windows.Forms.HexBox/DynamicFileByteProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.IO; 4 | 5 | namespace Be.Windows.Forms 6 | { 7 | /// 8 | /// Implements a fully editable byte provider for file data of any size. 9 | /// 10 | /// 11 | /// Only changes to the file are stored in memory with reads from the 12 | /// original data occurring as required. 13 | /// 14 | public sealed class DynamicFileByteProvider : IByteProvider, IDisposable 15 | { 16 | const int COPY_BLOCK_SIZE = 4096; 17 | 18 | string _fileName; 19 | Stream _stream; 20 | DataMap _dataMap; 21 | long _totalLength; 22 | bool _readOnly; 23 | 24 | /// 25 | /// Constructs a new instance. 26 | /// 27 | /// The name of the file from which bytes should be provided. 28 | public DynamicFileByteProvider(string fileName) : this(fileName, false) { } 29 | 30 | /// 31 | /// Constructs a new instance. 32 | /// 33 | /// The name of the file from which bytes should be provided. 34 | /// True, opens the file in read-only mode. 35 | public DynamicFileByteProvider(string fileName, bool readOnly) 36 | { 37 | _fileName = fileName; 38 | 39 | if (!readOnly) 40 | { 41 | _stream = File.Open(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.Read); 42 | } 43 | else 44 | { 45 | _stream = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); 46 | } 47 | 48 | _readOnly = readOnly; 49 | 50 | ReInitialize(); 51 | } 52 | 53 | /// 54 | /// Constructs a new instance. 55 | /// 56 | /// the stream containing the data. 57 | /// 58 | /// The stream must supported seek operations. 59 | /// 60 | public DynamicFileByteProvider(Stream stream) 61 | { 62 | if (stream == null) 63 | throw new ArgumentNullException("stream"); 64 | if (!stream.CanSeek) 65 | throw new ArgumentException("stream must supported seek operations(CanSeek)"); 66 | 67 | _stream = stream; 68 | _readOnly = !stream.CanWrite; 69 | ReInitialize(); 70 | } 71 | 72 | #region IByteProvider Members 73 | /// 74 | /// See for more information. 75 | /// 76 | public event EventHandler LengthChanged; 77 | 78 | /// 79 | /// See for more information. 80 | /// 81 | public event EventHandler Changed; 82 | 83 | /// 84 | /// See for more information. 85 | /// 86 | public byte ReadByte(long index) 87 | { 88 | long blockOffset; 89 | DataBlock block = GetDataBlock(index, out blockOffset); 90 | FileDataBlock fileBlock = block as FileDataBlock; 91 | if (fileBlock != null) 92 | { 93 | return ReadByteFromFile(fileBlock.FileOffset + index - blockOffset); 94 | } 95 | else 96 | { 97 | MemoryDataBlock memoryBlock = (MemoryDataBlock)block; 98 | return memoryBlock.Data[index - blockOffset]; 99 | } 100 | } 101 | 102 | /// 103 | /// See for more information. 104 | /// 105 | public void WriteByte(long index, byte value) 106 | { 107 | try 108 | { 109 | // Find the block affected. 110 | long blockOffset; 111 | DataBlock block = GetDataBlock(index, out blockOffset); 112 | 113 | // If the byte is already in a memory block, modify it. 114 | MemoryDataBlock memoryBlock = block as MemoryDataBlock; 115 | if (memoryBlock != null) 116 | { 117 | memoryBlock.Data[index - blockOffset] = value; 118 | return; 119 | } 120 | 121 | FileDataBlock fileBlock = (FileDataBlock)block; 122 | 123 | // If the byte changing is the first byte in the block and the previous block is a memory block, extend that. 124 | if (blockOffset == index && block.PreviousBlock != null) 125 | { 126 | MemoryDataBlock previousMemoryBlock = block.PreviousBlock as MemoryDataBlock; 127 | if (previousMemoryBlock != null) 128 | { 129 | previousMemoryBlock.AddByteToEnd(value); 130 | fileBlock.RemoveBytesFromStart(1); 131 | if (fileBlock.Length == 0) 132 | { 133 | _dataMap.Remove(fileBlock); 134 | } 135 | return; 136 | } 137 | } 138 | 139 | // If the byte changing is the last byte in the block and the next block is a memory block, extend that. 140 | if (blockOffset + fileBlock.Length - 1 == index && block.NextBlock != null) 141 | { 142 | MemoryDataBlock nextMemoryBlock = block.NextBlock as MemoryDataBlock; 143 | if (nextMemoryBlock != null) 144 | { 145 | nextMemoryBlock.AddByteToStart(value); 146 | fileBlock.RemoveBytesFromEnd(1); 147 | if (fileBlock.Length == 0) 148 | { 149 | _dataMap.Remove(fileBlock); 150 | } 151 | return; 152 | } 153 | } 154 | 155 | // Split the block into a prefix and a suffix and place a memory block in-between. 156 | FileDataBlock prefixBlock = null; 157 | if (index > blockOffset) 158 | { 159 | prefixBlock = new FileDataBlock(fileBlock.FileOffset, index - blockOffset); 160 | } 161 | 162 | FileDataBlock suffixBlock = null; 163 | if (index < blockOffset + fileBlock.Length - 1) 164 | { 165 | suffixBlock = new FileDataBlock( 166 | fileBlock.FileOffset + index - blockOffset + 1, 167 | fileBlock.Length - (index - blockOffset + 1)); 168 | } 169 | 170 | block = _dataMap.Replace(block, new MemoryDataBlock(value)); 171 | 172 | if (prefixBlock != null) 173 | { 174 | _dataMap.AddBefore(block, prefixBlock); 175 | } 176 | 177 | if (suffixBlock != null) 178 | { 179 | _dataMap.AddAfter(block, suffixBlock); 180 | } 181 | } 182 | finally 183 | { 184 | OnChanged(EventArgs.Empty); 185 | } 186 | } 187 | 188 | /// 189 | /// See for more information. 190 | /// 191 | public void InsertBytes(long index, byte[] bs) 192 | { 193 | try 194 | { 195 | // Find the block affected. 196 | long blockOffset; 197 | DataBlock block = GetDataBlock(index, out blockOffset); 198 | 199 | // If the insertion point is in a memory block, just insert it. 200 | MemoryDataBlock memoryBlock = block as MemoryDataBlock; 201 | if (memoryBlock != null) 202 | { 203 | memoryBlock.InsertBytes(index - blockOffset, bs); 204 | return; 205 | } 206 | 207 | FileDataBlock fileBlock = (FileDataBlock)block; 208 | 209 | // If the insertion point is at the start of a file block, and the previous block is a memory block, append it to that block. 210 | if (blockOffset == index && block.PreviousBlock != null) 211 | { 212 | MemoryDataBlock previousMemoryBlock = block.PreviousBlock as MemoryDataBlock; 213 | if (previousMemoryBlock != null) 214 | { 215 | previousMemoryBlock.InsertBytes(previousMemoryBlock.Length, bs); 216 | return; 217 | } 218 | } 219 | 220 | // Split the block into a prefix and a suffix and place a memory block in-between. 221 | FileDataBlock prefixBlock = null; 222 | if (index > blockOffset) 223 | { 224 | prefixBlock = new FileDataBlock(fileBlock.FileOffset, index - blockOffset); 225 | } 226 | 227 | FileDataBlock suffixBlock = null; 228 | if (index < blockOffset + fileBlock.Length) 229 | { 230 | suffixBlock = new FileDataBlock( 231 | fileBlock.FileOffset + index - blockOffset, 232 | fileBlock.Length - (index - blockOffset)); 233 | } 234 | 235 | block = _dataMap.Replace(block, new MemoryDataBlock(bs)); 236 | 237 | if (prefixBlock != null) 238 | { 239 | _dataMap.AddBefore(block, prefixBlock); 240 | } 241 | 242 | if (suffixBlock != null) 243 | { 244 | _dataMap.AddAfter(block, suffixBlock); 245 | } 246 | } 247 | finally 248 | { 249 | _totalLength += bs.Length; 250 | OnLengthChanged(EventArgs.Empty); 251 | OnChanged(EventArgs.Empty); 252 | } 253 | } 254 | 255 | /// 256 | /// See for more information. 257 | /// 258 | public void DeleteBytes(long index, long length) 259 | { 260 | try 261 | { 262 | long bytesToDelete = length; 263 | 264 | // Find the first block affected. 265 | long blockOffset; 266 | DataBlock block = GetDataBlock(index, out blockOffset); 267 | 268 | // Truncate or remove each block as necessary. 269 | while ((bytesToDelete > 0) && (block != null)) 270 | { 271 | long blockLength = block.Length; 272 | DataBlock nextBlock = block.NextBlock; 273 | 274 | // Delete the appropriate section from the block (this may result in two blocks or a zero length block). 275 | long count = Math.Min(bytesToDelete, blockLength - (index - blockOffset)); 276 | block.RemoveBytes(index - blockOffset, count); 277 | 278 | if (block.Length == 0) 279 | { 280 | _dataMap.Remove(block); 281 | if (_dataMap.FirstBlock == null) 282 | { 283 | _dataMap.AddFirst(new MemoryDataBlock(new byte[0])); 284 | } 285 | } 286 | 287 | bytesToDelete -= count; 288 | blockOffset += block.Length; 289 | block = (bytesToDelete > 0) ? nextBlock : null; 290 | } 291 | } 292 | finally 293 | { 294 | _totalLength -= length; 295 | OnLengthChanged(EventArgs.Empty); 296 | OnChanged(EventArgs.Empty); 297 | } 298 | } 299 | 300 | /// 301 | /// See for more information. 302 | /// 303 | public long Length 304 | { 305 | get 306 | { 307 | return _totalLength; 308 | } 309 | } 310 | 311 | /// 312 | /// See for more information. 313 | /// 314 | public bool HasChanges() 315 | { 316 | if (_readOnly) 317 | return false; 318 | 319 | if (_totalLength != _stream.Length) 320 | { 321 | return true; 322 | } 323 | 324 | long offset = 0; 325 | for (DataBlock block = _dataMap.FirstBlock; block != null; block = block.NextBlock) 326 | { 327 | FileDataBlock fileBlock = block as FileDataBlock; 328 | if (fileBlock == null) 329 | { 330 | return true; 331 | } 332 | 333 | if (fileBlock.FileOffset != offset) 334 | { 335 | return true; 336 | } 337 | 338 | offset += fileBlock.Length; 339 | } 340 | return (offset != _stream.Length); 341 | } 342 | 343 | /// 344 | /// See for more information. 345 | /// 346 | public void ApplyChanges() 347 | { 348 | if (_readOnly) 349 | throw new OperationCanceledException("File is in read-only mode"); 350 | 351 | // This method is implemented to efficiently save the changes to the same file stream opened for reading. 352 | // Saving to a separate file would be a much simpler implementation. 353 | 354 | // Firstly, extend the file length (if necessary) to ensure that there is enough disk space. 355 | if (_totalLength > _stream.Length) 356 | { 357 | _stream.SetLength(_totalLength); 358 | } 359 | 360 | // Secondly, shift around any file sections that have moved. 361 | long dataOffset = 0; 362 | for (DataBlock block = _dataMap.FirstBlock; block != null; block = block.NextBlock) 363 | { 364 | FileDataBlock fileBlock = block as FileDataBlock; 365 | if (fileBlock != null && fileBlock.FileOffset != dataOffset) 366 | { 367 | MoveFileBlock(fileBlock, dataOffset); 368 | } 369 | dataOffset += block.Length; 370 | } 371 | 372 | // Next, write in-memory changes. 373 | dataOffset = 0; 374 | for (DataBlock block = _dataMap.FirstBlock; block != null; block = block.NextBlock) 375 | { 376 | MemoryDataBlock memoryBlock = block as MemoryDataBlock; 377 | if (memoryBlock != null) 378 | { 379 | _stream.Position = dataOffset; 380 | for (int memoryOffset = 0; memoryOffset < memoryBlock.Length; memoryOffset += COPY_BLOCK_SIZE) 381 | { 382 | _stream.Write(memoryBlock.Data, memoryOffset, (int)Math.Min(COPY_BLOCK_SIZE, memoryBlock.Length - memoryOffset)); 383 | } 384 | } 385 | dataOffset += block.Length; 386 | } 387 | 388 | // Finally, if the file has shortened, truncate the stream. 389 | _stream.SetLength(_totalLength); 390 | ReInitialize(); 391 | } 392 | 393 | /// 394 | /// See for more information. 395 | /// 396 | public bool SupportsWriteByte() 397 | { 398 | return !_readOnly; 399 | } 400 | 401 | /// 402 | /// See for more information. 403 | /// 404 | public bool SupportsInsertBytes() 405 | { 406 | return !_readOnly; 407 | } 408 | 409 | /// 410 | /// See for more information. 411 | /// 412 | public bool SupportsDeleteBytes() 413 | { 414 | return !_readOnly; 415 | } 416 | #endregion 417 | 418 | #region IDisposable Members 419 | /// 420 | /// See for more information. 421 | /// 422 | ~DynamicFileByteProvider() 423 | { 424 | Dispose(); 425 | } 426 | 427 | /// 428 | /// See for more information. 429 | /// 430 | public void Dispose() 431 | { 432 | if (_stream != null) 433 | { 434 | _stream.Close(); 435 | _stream = null; 436 | } 437 | _fileName = null; 438 | _dataMap = null; 439 | GC.SuppressFinalize(this); 440 | } 441 | #endregion 442 | 443 | /// 444 | /// Gets a value, if the file is opened in read-only mode. 445 | /// 446 | public bool ReadOnly 447 | { 448 | get { return _readOnly; } 449 | } 450 | 451 | void OnLengthChanged(EventArgs e) 452 | { 453 | if (LengthChanged != null) 454 | LengthChanged(this, e); 455 | } 456 | 457 | void OnChanged(EventArgs e) 458 | { 459 | if (Changed != null) 460 | { 461 | Changed(this, e); 462 | } 463 | } 464 | 465 | DataBlock GetDataBlock(long findOffset, out long blockOffset) 466 | { 467 | if (findOffset < 0 || findOffset > _totalLength) 468 | { 469 | throw new ArgumentOutOfRangeException("findOffset"); 470 | } 471 | 472 | // Iterate over the blocks until the block containing the required offset is encountered. 473 | blockOffset = 0; 474 | for (DataBlock block = _dataMap.FirstBlock; block != null; block = block.NextBlock) 475 | { 476 | if ((blockOffset <= findOffset && blockOffset + block.Length > findOffset) || block.NextBlock == null) 477 | { 478 | return block; 479 | } 480 | blockOffset += block.Length; 481 | } 482 | return null; 483 | } 484 | 485 | FileDataBlock GetNextFileDataBlock(DataBlock block, long dataOffset, out long nextDataOffset) 486 | { 487 | // Iterate over the remaining blocks until a file block is encountered. 488 | nextDataOffset = dataOffset + block.Length; 489 | block = block.NextBlock; 490 | while (block != null) 491 | { 492 | FileDataBlock fileBlock = block as FileDataBlock; 493 | if (fileBlock != null) 494 | { 495 | return fileBlock; 496 | } 497 | nextDataOffset += block.Length; 498 | block = block.NextBlock; 499 | } 500 | return null; 501 | } 502 | 503 | byte ReadByteFromFile(long fileOffset) 504 | { 505 | // Move to the correct position and read the byte. 506 | if (_stream.Position != fileOffset) 507 | { 508 | _stream.Position = fileOffset; 509 | } 510 | return (byte)_stream.ReadByte(); 511 | } 512 | 513 | void MoveFileBlock(FileDataBlock fileBlock, long dataOffset) 514 | { 515 | // First, determine whether the next file block needs to move before this one. 516 | long nextDataOffset; 517 | FileDataBlock nextFileBlock = GetNextFileDataBlock(fileBlock, dataOffset, out nextDataOffset); 518 | if (nextFileBlock != null && dataOffset + fileBlock.Length > nextFileBlock.FileOffset) 519 | { 520 | // The next block needs to move first, so do that now. 521 | MoveFileBlock(nextFileBlock, nextDataOffset); 522 | } 523 | 524 | // Now, move the block. 525 | if (fileBlock.FileOffset > dataOffset) 526 | { 527 | // Move the section to earlier in the file stream (done in chunks starting at the beginning of the section). 528 | byte[] buffer = new byte[COPY_BLOCK_SIZE]; 529 | for (long relativeOffset = 0; relativeOffset < fileBlock.Length; relativeOffset += buffer.Length) 530 | { 531 | long readOffset = fileBlock.FileOffset + relativeOffset; 532 | int bytesToRead = (int)Math.Min(buffer.Length, fileBlock.Length - relativeOffset); 533 | _stream.Position = readOffset; 534 | _stream.Read(buffer, 0, bytesToRead); 535 | 536 | long writeOffset = dataOffset + relativeOffset; 537 | _stream.Position = writeOffset; 538 | _stream.Write(buffer, 0, bytesToRead); 539 | } 540 | } 541 | else 542 | { 543 | // Move the section to later in the file stream (done in chunks starting at the end of the section). 544 | byte[] buffer = new byte[COPY_BLOCK_SIZE]; 545 | for (long relativeOffset = 0; relativeOffset < fileBlock.Length; relativeOffset += buffer.Length) 546 | { 547 | int bytesToRead = (int)Math.Min(buffer.Length, fileBlock.Length - relativeOffset); 548 | long readOffset = fileBlock.FileOffset + fileBlock.Length - relativeOffset - bytesToRead; 549 | _stream.Position = readOffset; 550 | _stream.Read(buffer, 0, bytesToRead); 551 | 552 | long writeOffset = dataOffset + fileBlock.Length - relativeOffset - bytesToRead; 553 | _stream.Position = writeOffset; 554 | _stream.Write(buffer, 0, bytesToRead); 555 | } 556 | } 557 | 558 | // This block now points to a different position in the file. 559 | fileBlock.SetFileOffset(dataOffset); 560 | } 561 | 562 | void ReInitialize() 563 | { 564 | _dataMap = new DataMap(); 565 | _dataMap.AddFirst(new FileDataBlock(0, _stream.Length)); 566 | _totalLength = _stream.Length; 567 | } 568 | } 569 | } 570 | -------------------------------------------------------------------------------- /Be.Windows.Forms.HexBox/FileByteProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Collections; 4 | 5 | namespace Be.Windows.Forms 6 | { 7 | /// 8 | /// Byte provider for (big) files. 9 | /// 10 | public class FileByteProvider : IByteProvider, IDisposable 11 | { 12 | #region WriteCollection class 13 | /// 14 | /// Represents the write buffer class 15 | /// 16 | class WriteCollection : DictionaryBase 17 | { 18 | /// 19 | /// Gets or sets a byte in the collection 20 | /// 21 | public byte this[long index] 22 | { 23 | get { return (byte)this.Dictionary[index]; } 24 | set { Dictionary[index] = value; } 25 | } 26 | 27 | /// 28 | /// Adds a byte into the collection 29 | /// 30 | /// the index of the byte 31 | /// the value of the byte 32 | public void Add(long index, byte value) 33 | { Dictionary.Add(index, value); } 34 | 35 | /// 36 | /// Determines if a byte with the given index exists. 37 | /// 38 | /// the index of the byte 39 | /// true, if the is in the collection 40 | public bool Contains(long index) 41 | { return Dictionary.Contains(index); } 42 | 43 | } 44 | #endregion 45 | 46 | /// 47 | /// Occurs, when the write buffer contains new changes. 48 | /// 49 | public event EventHandler Changed; 50 | 51 | /// 52 | /// Contains all changes 53 | /// 54 | WriteCollection _writes = new WriteCollection(); 55 | 56 | /// 57 | /// Contains the file name. 58 | /// 59 | string _fileName; 60 | /// 61 | /// Contains the file stream. 62 | /// 63 | FileStream _fileStream; 64 | /// 65 | /// Read-only access. 66 | /// 67 | bool _readOnly; 68 | 69 | /// 70 | /// Initializes a new instance of the FileByteProvider class. 71 | /// 72 | /// 73 | public FileByteProvider(string fileName) 74 | { 75 | _fileName = fileName; 76 | 77 | try 78 | { 79 | // try to open in write mode 80 | _fileStream = File.Open(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.Read); 81 | } 82 | catch 83 | { 84 | // write mode failed, try to open in read-only and fileshare friendly mode. 85 | try 86 | { 87 | _fileStream = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); 88 | _readOnly = true; 89 | } 90 | catch 91 | { 92 | throw; 93 | } 94 | } 95 | } 96 | 97 | /// 98 | /// Terminates the instance of the FileByteProvider class. 99 | /// 100 | ~FileByteProvider() 101 | { 102 | Dispose(); 103 | } 104 | 105 | /// 106 | /// Raises the Changed event. 107 | /// 108 | /// Never used. 109 | void OnChanged(EventArgs e) 110 | { 111 | if(Changed != null) 112 | Changed(this, e); 113 | } 114 | 115 | /// 116 | /// Gets the name of the file the byte provider is using. 117 | /// 118 | public string FileName 119 | { 120 | get { return _fileName; } 121 | } 122 | 123 | /// 124 | /// Returns a value if there are some changes. 125 | /// 126 | /// true, if there are some changes 127 | public bool HasChanges() 128 | { 129 | return (_writes.Count > 0); 130 | } 131 | 132 | /// 133 | /// Updates the file with all changes the write buffer contains. 134 | /// 135 | public void ApplyChanges() 136 | { 137 | if (this._readOnly) 138 | { 139 | throw new Exception("File is in read-only mode."); 140 | } 141 | 142 | if(!HasChanges()) 143 | return; 144 | 145 | IDictionaryEnumerator en = _writes.GetEnumerator(); 146 | while(en.MoveNext()) 147 | { 148 | long index = (long)en.Key; 149 | byte value = (byte)en.Value; 150 | if(_fileStream.Position != index) 151 | _fileStream.Position = index; 152 | _fileStream.Write(new byte[] { value }, 0, 1); 153 | } 154 | _writes.Clear(); 155 | } 156 | 157 | /// 158 | /// Clears the write buffer and reject all changes made. 159 | /// 160 | public void RejectChanges() 161 | { 162 | _writes.Clear(); 163 | } 164 | 165 | #region IByteProvider Members 166 | /// 167 | /// Never used. 168 | /// 169 | public event EventHandler LengthChanged; 170 | 171 | /// 172 | /// Reads a byte from the file. 173 | /// 174 | /// the index of the byte to read 175 | /// the byte 176 | public byte ReadByte(long index) 177 | { 178 | if(_writes.Contains(index)) 179 | return _writes[index]; 180 | 181 | if(_fileStream.Position != index) 182 | _fileStream.Position = index; 183 | 184 | byte res = (byte)_fileStream.ReadByte(); 185 | return res; 186 | } 187 | 188 | /// 189 | /// Gets the length of the file. 190 | /// 191 | public long Length 192 | { 193 | get 194 | { 195 | return _fileStream.Length; 196 | } 197 | } 198 | 199 | /// 200 | /// Writes a byte into write buffer 201 | /// 202 | public void WriteByte(long index, byte value) 203 | { 204 | if(_writes.Contains(index)) 205 | _writes[index] = value; 206 | else 207 | _writes.Add(index, value); 208 | 209 | OnChanged(EventArgs.Empty); 210 | } 211 | 212 | /// 213 | /// Not supported 214 | /// 215 | public void DeleteBytes(long index, long length) 216 | { 217 | throw new NotSupportedException("FileByteProvider.DeleteBytes"); 218 | } 219 | 220 | /// 221 | /// Not supported 222 | /// 223 | public void InsertBytes(long index, byte[] bs) 224 | { 225 | throw new NotSupportedException("FileByteProvider.InsertBytes"); 226 | } 227 | 228 | /// 229 | /// Returns true 230 | /// 231 | public bool SupportsWriteByte() 232 | { 233 | return !_readOnly; 234 | } 235 | 236 | /// 237 | /// Returns false 238 | /// 239 | public bool SupportsInsertBytes() 240 | { 241 | return false; 242 | } 243 | 244 | /// 245 | /// Returns false 246 | /// 247 | public bool SupportsDeleteBytes() 248 | { 249 | return false; 250 | } 251 | #endregion 252 | 253 | #region IDisposable Members 254 | /// 255 | /// Releases the file handle used by the FileByteProvider. 256 | /// 257 | public void Dispose() 258 | { 259 | if(_fileStream != null) 260 | { 261 | _fileName = null; 262 | 263 | _fileStream.Close(); 264 | _fileStream = null; 265 | } 266 | 267 | GC.SuppressFinalize(this); 268 | } 269 | #endregion 270 | } 271 | } 272 | -------------------------------------------------------------------------------- /Be.Windows.Forms.HexBox/FileDataBlock.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Be.Windows.Forms 4 | { 5 | internal sealed class FileDataBlock : DataBlock 6 | { 7 | long _length; 8 | long _fileOffset; 9 | 10 | public FileDataBlock(long fileOffset, long length) 11 | { 12 | _fileOffset = fileOffset; 13 | _length = length; 14 | } 15 | 16 | public long FileOffset 17 | { 18 | get 19 | { 20 | return _fileOffset; 21 | } 22 | } 23 | 24 | public override long Length 25 | { 26 | get 27 | { 28 | return _length; 29 | } 30 | } 31 | 32 | public void SetFileOffset(long value) 33 | { 34 | _fileOffset = value; 35 | } 36 | 37 | public void RemoveBytesFromEnd(long count) 38 | { 39 | if (count > _length) 40 | { 41 | throw new ArgumentOutOfRangeException("count"); 42 | } 43 | 44 | _length -= count; 45 | } 46 | 47 | public void RemoveBytesFromStart(long count) 48 | { 49 | if (count > _length) 50 | { 51 | throw new ArgumentOutOfRangeException("count"); 52 | } 53 | 54 | _fileOffset += count; 55 | _length -= count; 56 | } 57 | 58 | public override void RemoveBytes(long position, long count) 59 | { 60 | if (position > _length) 61 | { 62 | throw new ArgumentOutOfRangeException("position"); 63 | } 64 | 65 | if (position + count > _length) 66 | { 67 | throw new ArgumentOutOfRangeException("count"); 68 | } 69 | 70 | long prefixLength = position; 71 | long prefixFileOffset = _fileOffset; 72 | 73 | long suffixLength = _length - count - prefixLength; 74 | long suffixFileOffset = _fileOffset + position + count; 75 | 76 | if (prefixLength > 0 && suffixLength > 0) 77 | { 78 | _fileOffset = prefixFileOffset; 79 | _length = prefixLength; 80 | _map.AddAfter(this, new FileDataBlock(suffixFileOffset, suffixLength)); 81 | return; 82 | } 83 | 84 | if (prefixLength > 0) 85 | { 86 | _fileOffset = prefixFileOffset; 87 | _length = prefixLength; 88 | } 89 | else 90 | { 91 | _fileOffset = suffixFileOffset; 92 | _length = suffixLength; 93 | } 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /Be.Windows.Forms.HexBox/FindOptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Be.Windows.Forms 6 | { 7 | /// 8 | /// Defines the type of the Find operation. 9 | /// 10 | public enum FindType 11 | { 12 | /// 13 | /// Used for Text Find operations 14 | /// 15 | Text, 16 | /// 17 | /// Used for Hex Find operations 18 | /// 19 | Hex 20 | } 21 | 22 | /// 23 | /// Defines all state information nee 24 | /// 25 | public class FindOptions 26 | { 27 | /// 28 | /// Gets or sets whether the Find options are valid 29 | /// 30 | public bool IsValid { get; set; } 31 | /// 32 | /// Gets the Find buffer used for case insensitive Find operations. This is the binary representation of Text. 33 | /// 34 | internal byte[] FindBuffer { get; private set; } 35 | /// 36 | /// Gets the Find buffer used for case sensitive Find operations. This is the binary representation of Text in lower case format. 37 | /// 38 | internal byte[] FindBufferLowerCase { get; private set; } 39 | /// 40 | /// Gets the Find buffer used for case sensitive Find operations. This is the binary representation of Text in upper case format. 41 | /// 42 | internal byte[] FindBufferUpperCase { get; private set; } 43 | /// 44 | /// Contains the MatchCase value 45 | /// 46 | bool _matchCase; 47 | /// 48 | /// Gets or sets the value, whether the Find operation is case sensitive or not. 49 | /// 50 | public bool MatchCase 51 | { 52 | get { return _matchCase; } 53 | set 54 | { 55 | _matchCase = value; 56 | UpdateFindBuffer(); 57 | } 58 | } 59 | /// 60 | /// Contains the text that should be found. 61 | /// 62 | string _text; 63 | /// 64 | /// Gets or sets the text that should be found. Only used, when Type is FindType.Hex. 65 | /// 66 | public string Text 67 | { 68 | get { return _text; } 69 | set 70 | { 71 | _text = value; 72 | UpdateFindBuffer(); 73 | } 74 | } 75 | /// 76 | /// Gets or sets the hex buffer that should be found. Only used, when Type is FindType.Hex. 77 | /// 78 | public byte[] Hex { get; set; } 79 | /// 80 | /// Gets or sets the type what should be searched. 81 | /// 82 | public FindType Type { get; set; } 83 | /// 84 | /// Updates the find buffer. 85 | /// 86 | void UpdateFindBuffer() 87 | { 88 | string text = this.Text != null ? this.Text : string.Empty; 89 | FindBuffer = ASCIIEncoding.ASCII.GetBytes(text); 90 | FindBufferLowerCase = ASCIIEncoding.ASCII.GetBytes(text.ToLower()); 91 | FindBufferUpperCase = ASCIIEncoding.ASCII.GetBytes(text.ToUpper()); 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /Be.Windows.Forms.HexBox/HexBox.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroKilo/CrocExplorerWV/8b313ae1f9a634ecc1ae9aa0d6bf8d4aff27efa5/Be.Windows.Forms.HexBox/HexBox.bmp -------------------------------------------------------------------------------- /Be.Windows.Forms.HexBox/HexBox.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroKilo/CrocExplorerWV/8b313ae1f9a634ecc1ae9aa0d6bf8d4aff27efa5/Be.Windows.Forms.HexBox/HexBox.cs -------------------------------------------------------------------------------- /Be.Windows.Forms.HexBox/HexBox.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=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | 124 | False 125 | 126 | -------------------------------------------------------------------------------- /Be.Windows.Forms.HexBox/HexBox.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroKilo/CrocExplorerWV/8b313ae1f9a634ecc1ae9aa0d6bf8d4aff27efa5/Be.Windows.Forms.HexBox/HexBox.snk -------------------------------------------------------------------------------- /Be.Windows.Forms.HexBox/HexCasing.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Be.Windows.Forms 6 | { 7 | /// 8 | /// Specifies the case of hex characters in the HexBox control 9 | /// 10 | public enum HexCasing 11 | { 12 | /// 13 | /// Converts all characters to uppercase. 14 | /// 15 | Upper = 0, 16 | /// 17 | /// Converts all characters to lowercase. 18 | /// 19 | Lower = 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Be.Windows.Forms.HexBox/IByteProvider.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroKilo/CrocExplorerWV/8b313ae1f9a634ecc1ae9aa0d6bf8d4aff27efa5/Be.Windows.Forms.HexBox/IByteProvider.cs -------------------------------------------------------------------------------- /Be.Windows.Forms.HexBox/MemoryDataBlock.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Be.Windows.Forms 4 | { 5 | internal sealed class MemoryDataBlock : DataBlock 6 | { 7 | byte[] _data; 8 | 9 | public MemoryDataBlock(byte data) 10 | { 11 | _data = new byte[] { data }; 12 | } 13 | 14 | public MemoryDataBlock(byte[] data) 15 | { 16 | if (data == null) 17 | { 18 | throw new ArgumentNullException("data"); 19 | } 20 | 21 | _data = (byte[])data.Clone(); 22 | } 23 | 24 | public override long Length 25 | { 26 | get 27 | { 28 | return _data.LongLength; 29 | } 30 | } 31 | 32 | public byte[] Data 33 | { 34 | get 35 | { 36 | return _data; 37 | } 38 | } 39 | 40 | public void AddByteToEnd(byte value) 41 | { 42 | byte[] newData = new byte[_data.LongLength + 1]; 43 | _data.CopyTo(newData, 0); 44 | newData[newData.LongLength - 1] = value; 45 | _data = newData; 46 | } 47 | 48 | public void AddByteToStart(byte value) 49 | { 50 | byte[] newData = new byte[_data.LongLength + 1]; 51 | newData[0] = value; 52 | _data.CopyTo(newData, 1); 53 | _data = newData; 54 | } 55 | 56 | public void InsertBytes(long position, byte[] data) 57 | { 58 | byte[] newData = new byte[_data.LongLength + data.LongLength]; 59 | if (position > 0) 60 | { 61 | Array.Copy(_data, 0, newData, 0, position); 62 | } 63 | Array.Copy(data, 0, newData, position, data.LongLength); 64 | if (position < _data.LongLength) 65 | { 66 | Array.Copy(_data, position, newData, position + data.LongLength, _data.LongLength - position); 67 | } 68 | _data = newData; 69 | } 70 | 71 | public override void RemoveBytes(long position, long count) 72 | { 73 | byte[] newData = new byte[_data.LongLength - count]; 74 | 75 | if (position > 0) 76 | { 77 | Array.Copy(_data, 0, newData, 0, position); 78 | } 79 | if (position + count < _data.LongLength) 80 | { 81 | Array.Copy(_data, position + count, newData, position, newData.LongLength - position); 82 | } 83 | 84 | _data = newData; 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /Be.Windows.Forms.HexBox/NativeMethods.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using System.Runtime.InteropServices; 4 | 5 | namespace Be.Windows.Forms 6 | { 7 | internal static class NativeMethods 8 | { 9 | // Caret definitions 10 | [DllImport("user32.dll", SetLastError=true)] 11 | public static extern bool CreateCaret(IntPtr hWnd, IntPtr hBitmap, int nWidth, int nHeight); 12 | 13 | [DllImport("user32.dll", SetLastError=true)] 14 | public static extern bool ShowCaret(IntPtr hWnd); 15 | 16 | [DllImport("user32.dll", SetLastError=true)] 17 | public static extern bool DestroyCaret(); 18 | 19 | [DllImport("user32.dll", SetLastError=true)] 20 | public static extern bool SetCaretPos(int X, int Y); 21 | 22 | // Key definitions 23 | public const int WM_KEYDOWN = 0x100; 24 | public const int WM_KEYUP = 0x101; 25 | public const int WM_CHAR = 0x102; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Be.Windows.Forms.HexBox/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.34003 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Be.Windows.Forms.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.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 | /// Returns the cached ResourceManager instance used by this class. 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("Be.Windows.Forms.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 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 | -------------------------------------------------------------------------------- /Be.Windows.Forms.HexBox/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 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /Be.Windows.Forms.HexBox/Util.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Be.Windows.Forms 6 | { 7 | static class Util 8 | { 9 | /// 10 | /// Contains true, if we are in design mode of Visual Studio 11 | /// 12 | private static bool _designMode; 13 | 14 | /// 15 | /// Initializes an instance of Util class 16 | /// 17 | static Util() 18 | { 19 | // design mode is true if host process is: Visual Studio, Visual Studio Express Versions (C#, VB, C++) or SharpDevelop 20 | var designerHosts = new List() { "devenv", "vcsexpress", "vbexpress", "vcexpress", "sharpdevelop" }; 21 | using (var process = System.Diagnostics.Process.GetCurrentProcess()) 22 | { 23 | var processName = process.ProcessName.ToLower(); 24 | _designMode = designerHosts.Contains(processName); 25 | } 26 | } 27 | 28 | /// 29 | /// Gets true, if we are in design mode of Visual Studio 30 | /// 31 | /// 32 | /// In Visual Studio 2008 SP1 the designer is crashing sometimes on windows forms. 33 | /// The DesignMode property of Control class is buggy and cannot be used, so use our own implementation instead. 34 | /// 35 | public static bool DesignMode 36 | { 37 | get 38 | { 39 | return _designMode; 40 | } 41 | } 42 | 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Be.Windows.Forms.HexBox/bin/x86/Release/Be.Windows.Forms.HexBox.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroKilo/CrocExplorerWV/8b313ae1f9a634ecc1ae9aa0d6bf8d4aff27efa5/Be.Windows.Forms.HexBox/bin/x86/Release/Be.Windows.Forms.HexBox.dll -------------------------------------------------------------------------------- /CrocExplorerWV.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Express 2012 for Windows Desktop 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CrocExplorerWV", "CrocExplorerWV\CrocExplorerWV.csproj", "{C99CFA06-162E-42F9-8B7A-38ED5E2CFA63}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Be.Windows.Forms.HexBox", "Be.Windows.Forms.HexBox\Be.Windows.Forms.HexBox.csproj", "{26C5F25F-B450-4CAF-AD8B-B8D11AE73457}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Debug|x86 = Debug|x86 12 | Release|Any CPU = Release|Any CPU 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {C99CFA06-162E-42F9-8B7A-38ED5E2CFA63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {C99CFA06-162E-42F9-8B7A-38ED5E2CFA63}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {C99CFA06-162E-42F9-8B7A-38ED5E2CFA63}.Debug|x86.ActiveCfg = Debug|x86 19 | {C99CFA06-162E-42F9-8B7A-38ED5E2CFA63}.Debug|x86.Build.0 = Debug|x86 20 | {C99CFA06-162E-42F9-8B7A-38ED5E2CFA63}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {C99CFA06-162E-42F9-8B7A-38ED5E2CFA63}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {C99CFA06-162E-42F9-8B7A-38ED5E2CFA63}.Release|x86.ActiveCfg = Release|x86 23 | {C99CFA06-162E-42F9-8B7A-38ED5E2CFA63}.Release|x86.Build.0 = Release|x86 24 | {26C5F25F-B450-4CAF-AD8B-B8D11AE73457}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {26C5F25F-B450-4CAF-AD8B-B8D11AE73457}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {26C5F25F-B450-4CAF-AD8B-B8D11AE73457}.Debug|x86.ActiveCfg = Debug|x86 27 | {26C5F25F-B450-4CAF-AD8B-B8D11AE73457}.Debug|x86.Build.0 = Debug|x86 28 | {26C5F25F-B450-4CAF-AD8B-B8D11AE73457}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {26C5F25F-B450-4CAF-AD8B-B8D11AE73457}.Release|Any CPU.Build.0 = Release|Any CPU 30 | {26C5F25F-B450-4CAF-AD8B-B8D11AE73457}.Release|x86.ActiveCfg = Release|x86 31 | {26C5F25F-B450-4CAF-AD8B-B8D11AE73457}.Release|x86.Build.0 = Release|x86 32 | EndGlobalSection 33 | GlobalSection(SolutionProperties) = preSolution 34 | HideSolutionNode = FALSE 35 | EndGlobalSection 36 | EndGlobal 37 | -------------------------------------------------------------------------------- /CrocExplorerWV.v11.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroKilo/CrocExplorerWV/8b313ae1f9a634ecc1ae9aa0d6bf8d4aff27efa5/CrocExplorerWV.v11.suo -------------------------------------------------------------------------------- /CrocExplorerWV/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /CrocExplorerWV/CrocExplorerWV.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {C99CFA06-162E-42F9-8B7A-38ED5E2CFA63} 8 | WinExe 9 | Properties 10 | CrocExplorerWV 11 | CrocExplorerWV 12 | v4.0 13 | 512 14 | 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | false 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | true 37 | bin\x86\Debug\ 38 | DEBUG;TRACE 39 | full 40 | x86 41 | prompt 42 | ManagedMinimumRules.ruleset 43 | true 44 | 45 | 46 | bin\x86\Release\ 47 | TRACE 48 | pdbonly 49 | x86 50 | prompt 51 | ManagedMinimumRules.ruleset 52 | true 53 | true 54 | 55 | 56 | 57 | dll\SharpDX.dll 58 | 59 | 60 | dll\SharpDX.D3DCompiler.dll 61 | 62 | 63 | dll\SharpDX.Desktop.dll 64 | 65 | 66 | dll\SharpDX.Direct2D1.dll 67 | 68 | 69 | dll\SharpDX.Direct3D11.dll 70 | 71 | 72 | dll\SharpDX.DXGI.dll 73 | 74 | 75 | dll\SharpDX.Mathematics.dll 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | Form 94 | 95 | 96 | Form1.cs 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | Form1.cs 109 | 110 | 111 | ResXFileCodeGenerator 112 | Resources.Designer.cs 113 | Designer 114 | 115 | 116 | True 117 | Resources.resx 118 | True 119 | 120 | 121 | SettingsSingleFileGenerator 122 | Settings.Designer.cs 123 | 124 | 125 | True 126 | Settings.settings 127 | True 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | {26c5f25f-b450-4caf-ad8b-b8d11ae73457} 136 | Be.Windows.Forms.HexBox 137 | 138 | 139 | 140 | 147 | -------------------------------------------------------------------------------- /CrocExplorerWV/Engine/Engine3D.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Windows.Forms; 8 | using System.Runtime.InteropServices; 9 | 10 | using SharpDX; 11 | using SharpDX.Windows; 12 | using SharpDX.DXGI; 13 | using SharpDX.Direct3D; 14 | using SharpDX.Direct3D11; 15 | using SharpDX.D3DCompiler; 16 | using SharpDX.Mathematics.Interop; 17 | using SharpDX.WIC; 18 | 19 | using Device = SharpDX.Direct3D11.Device; 20 | 21 | namespace CrocExplorerWV 22 | { 23 | public class Engine3D 24 | { 25 | public bool renderLevel = false; 26 | public TextureManager textureManager = new TextureManager(); 27 | public Device device; 28 | public DeviceContext context; 29 | public SwapChain swapChain; 30 | public Texture2D backBuffer; 31 | public RenderTargetView renderTargetView; 32 | public DepthStencilView depthStencilView; 33 | public DepthStencilState depthStencilState; 34 | public float CamRot = 3.1415f / 180f, CamDis = 3f, CamHeight = 0; 35 | public Vector3 CamPos = Vector3.Zero; 36 | public List objects; 37 | public PixelShader psWired, psTextured; 38 | public InputElement[] inputElementsWired = new InputElement[] 39 | { 40 | new InputElement("SV_Position", 0, Format.R32G32B32A32_Float, 0, 0), 41 | new InputElement("COLOR", 0, Format.R32G32B32A32_Float, 16, 0) 42 | }; 43 | public InputElement[] inputElementsTextured = new InputElement[] 44 | { 45 | new InputElement("SV_Position", 0, Format.R32G32B32A32_Float, 0, 0), 46 | new InputElement("COLOR", 0, Format.R32G32B32A32_Float, 16, 0), 47 | new InputElement("TEXCOORD", 0, Format.R32G32_Float, 32, 0), 48 | }; 49 | public VertexShader vsWired, vsTextured; 50 | public ShaderSignature inputSignatureWired, inputSignatureTextured; 51 | public InputLayout inputLayoutWired, inputLayoutTextured; 52 | public SamplerState sampler; 53 | public SamplerStateDescription samplerStateDescription; 54 | public SharpDX.Direct3D11.Buffer worldViewProjectionBuffer; 55 | public Texture2D defaultTexture; 56 | public RasterizerState rasterStateWired, rasterStateTextured; 57 | private RawViewportF viewport; 58 | 59 | private RawMatrix view; 60 | private RawMatrix proj; 61 | private RawVector3 camPosRel; 62 | 63 | public Engine3D(PictureBox f) 64 | { 65 | textureManager.engine = this; 66 | InitDevice(f); 67 | InitShaders(); 68 | Resize(f); 69 | objects = new List(); 70 | RenderObject o = new RenderObject(device, RenderObject.RenderType.TriListWired, defaultTexture, this); 71 | o.InitGeometry(); 72 | objects.Add(o); 73 | } 74 | 75 | ~Engine3D() 76 | { 77 | Cleanup(); 78 | } 79 | 80 | private void InitDevice(PictureBox f) 81 | { 82 | Device.CreateWithSwapChain( 83 | DriverType.Hardware, 84 | DeviceCreationFlags.None, 85 | new[] { 86 | FeatureLevel.Level_11_1, 87 | FeatureLevel.Level_11_0, 88 | FeatureLevel.Level_10_1, 89 | FeatureLevel.Level_10_0, 90 | }, 91 | new SwapChainDescription() 92 | { 93 | ModeDescription = 94 | new ModeDescription( 95 | f.ClientSize.Width, 96 | f.ClientSize.Height, 97 | new Rational(60, 1), 98 | Format.R8G8B8A8_UNorm 99 | ), 100 | SampleDescription = new SampleDescription(1, 0), 101 | Usage = Usage.BackBuffer | Usage.RenderTargetOutput, 102 | BufferCount = 1, 103 | Flags = SwapChainFlags.AllowModeSwitch, 104 | IsWindowed = true, 105 | OutputHandle = f.Handle, 106 | SwapEffect = SwapEffect.Discard, 107 | }, 108 | out device, out swapChain 109 | ); 110 | context = device.ImmediateContext; 111 | } 112 | 113 | private void InitShaders() 114 | { 115 | defaultTexture = textureManager.CreateTexture2DFromBitmap(device, textureManager.LoadBitmap(new ImagingFactory2(), "res\\default.png")); 116 | //Wireframe shaders 117 | ShaderBytecode vertexShaderByteCodeWired = ShaderBytecode.Compile(Properties.Resources.vertexShaderWired, "main", "vs_4_0", ShaderFlags.Debug); 118 | vsWired = new VertexShader(device, vertexShaderByteCodeWired); 119 | inputSignatureWired = ShaderSignature.GetInputSignature(vertexShaderByteCodeWired); 120 | inputLayoutWired = new InputLayout(device, inputSignatureWired, inputElementsWired); 121 | psWired = new PixelShader(device, ShaderBytecode.Compile(Properties.Resources.pixelShaderWired, "main", "ps_4_0", ShaderFlags.Debug)); 122 | 123 | //Texture shaders 124 | ShaderBytecode vertexShaderByteCodeTextured = ShaderBytecode.Compile(Properties.Resources.vertexShaderTextured, "main", "vs_4_0", ShaderFlags.Debug); 125 | vsTextured = new VertexShader(device, vertexShaderByteCodeTextured); 126 | inputSignatureTextured = ShaderSignature.GetInputSignature(vertexShaderByteCodeTextured); 127 | inputLayoutTextured = new InputLayout(device, inputSignatureTextured, inputElementsTextured); 128 | psTextured = new PixelShader(device, ShaderBytecode.Compile(Properties.Resources.pixelShaderTextured, "main", "ps_4_0", ShaderFlags.Debug)); 129 | 130 | RasterizerStateDescription renderStateDescWired = RasterizerStateDescription.Default(); 131 | renderStateDescWired.FillMode = FillMode.Wireframe; 132 | renderStateDescWired.CullMode = CullMode.None; 133 | rasterStateWired = new RasterizerState(device, renderStateDescWired); 134 | RasterizerStateDescription renderStateDescTextured = RasterizerStateDescription.Default(); 135 | renderStateDescTextured.IsFrontCounterClockwise = false; 136 | renderStateDescTextured.FillMode = FillMode.Solid; 137 | renderStateDescTextured.CullMode = CullMode.None; 138 | renderStateDescTextured.IsDepthClipEnabled = true; 139 | rasterStateTextured = new RasterizerState(device, renderStateDescTextured); 140 | 141 | samplerStateDescription = new SamplerStateDescription 142 | { 143 | AddressU = TextureAddressMode.Wrap, 144 | AddressV = TextureAddressMode.Wrap, 145 | AddressW = TextureAddressMode.Wrap, 146 | Filter = Filter.MinMagMipLinear 147 | }; 148 | sampler = new SamplerState(device, samplerStateDescription); 149 | 150 | worldViewProjectionBuffer = new SharpDX.Direct3D11.Buffer(device, Utilities.SizeOf(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0); 151 | } 152 | 153 | public void Resize(PictureBox f) 154 | { 155 | if (renderTargetView != null) renderTargetView.Dispose(); 156 | if (depthStencilView != null) depthStencilView.Dispose(); 157 | if (backBuffer != null) backBuffer.Dispose(); 158 | swapChain.ResizeBuffers(1, f.ClientSize.Width, f.ClientSize.Height, Format.Unknown, SwapChainFlags.AllowModeSwitch); 159 | viewport = new RawViewportF(); 160 | viewport.X = 0; 161 | viewport.Y = 0; 162 | viewport.Width = f.ClientSize.Width; 163 | viewport.Height = f.ClientSize.Height; 164 | viewport.MinDepth = 0; 165 | viewport.MaxDepth = 1; 166 | backBuffer = Texture2D.FromSwapChain(swapChain, 0); 167 | renderTargetView = new RenderTargetView(device, backBuffer); 168 | Texture2D depthBuffer = new Texture2D(device, new Texture2DDescription() 169 | { 170 | Format = Format.D32_Float_S8X24_UInt, 171 | ArraySize = 1, 172 | MipLevels = 1, 173 | Width = f.ClientSize.Width, 174 | Height = f.ClientSize.Height, 175 | SampleDescription = new SampleDescription(1, 0), 176 | Usage = ResourceUsage.Default, 177 | BindFlags = BindFlags.DepthStencil, 178 | CpuAccessFlags = CpuAccessFlags.None, 179 | OptionFlags = ResourceOptionFlags.None 180 | }); 181 | depthStencilView = new DepthStencilView(device, depthBuffer); 182 | context.Rasterizer.SetViewport(viewport); 183 | context.OutputMerger.SetTargets(depthStencilView, renderTargetView); 184 | context.OutputMerger.SetRenderTargets(depthStencilView, renderTargetView); 185 | proj = Matrix.PerspectiveFovLH((float)Math.PI / 3f, f.ClientSize.Width / (float)f.ClientSize.Height, 0.5f, 100000f); 186 | } 187 | 188 | public void Render() 189 | { 190 | context.ClearRenderTargetView(renderTargetView, new RawColor4(0, 128, 255, 255)); 191 | context.ClearDepthStencilView(depthStencilView, DepthStencilClearFlags.Depth | DepthStencilClearFlags.Stencil, 1.0f, 0); 192 | camPosRel = new RawVector3((float)Math.Sin(CamRot) * CamDis, CamHeight, (float)Math.Cos(CamRot) * CamDis); 193 | camPosRel += CamPos; 194 | view = Matrix.LookAtLH(camPosRel, CamPos, Vector3.UnitY); 195 | foreach (RenderObject ro in objects) 196 | ro.Render(context, view, proj); 197 | swapChain.Present(0, PresentFlags.None); 198 | } 199 | 200 | public void ClearScene() 201 | { 202 | foreach (RenderObject ro in objects) 203 | ro.Dispose(); 204 | objects.Clear(); 205 | } 206 | 207 | public void ResetCameraDistance() 208 | { 209 | float dis = 0.001f; 210 | foreach (RenderObject o in objects) 211 | { 212 | foreach (RenderObject.VertexWired vw in o.verticesWired) 213 | { 214 | Vector4 v = vw.Position; 215 | float l = (float)Math.Sqrt(v.X * v.X + v.Y * v.Y + v.Z * v.Z); 216 | if (l > dis) 217 | dis = l; 218 | } 219 | foreach (RenderObject.VertexTextured v in o.verticesTextured) 220 | { 221 | Vector4 p = v.Position; 222 | float l = (float)Math.Sqrt(p.X * p.X + p.Y * p.Y + p.Z * p.Z); 223 | if (l > dis) 224 | dis = l; 225 | } 226 | } 227 | CamDis = dis * 2; 228 | } 229 | 230 | public void Cleanup() 231 | { 232 | renderTargetView.Dispose(); 233 | backBuffer.Dispose(); 234 | device.Dispose(); 235 | swapChain.Dispose(); 236 | if (objects != null) 237 | foreach (RenderObject ro in objects) 238 | ro.Dispose(); 239 | inputLayoutWired.Dispose(); 240 | inputSignatureWired.Dispose(); 241 | } 242 | } 243 | } -------------------------------------------------------------------------------- /CrocExplorerWV/Engine/RenderObject.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Runtime.InteropServices; 3 | using SharpDX; 4 | using SharpDX.Direct3D; 5 | using SharpDX.Direct3D11; 6 | using SharpDX.Mathematics.Interop; 7 | 8 | using Device = SharpDX.Direct3D11.Device; 9 | 10 | namespace CrocExplorerWV 11 | { 12 | public class RenderObject 13 | { 14 | public enum RenderType 15 | { 16 | LineList, 17 | TriListWired, 18 | TriListTextured, 19 | } 20 | 21 | [StructLayout(LayoutKind.Sequential)] 22 | public struct VertexTextured 23 | { 24 | public VertexTextured(Vector4 position, Color4 color, Vector2 textureUV) 25 | { 26 | Position = position; 27 | Color = color; 28 | TextureUV = textureUV; 29 | } 30 | 31 | public Vector4 Position; 32 | public Color4 Color; 33 | public Vector2 TextureUV; 34 | } 35 | 36 | [StructLayout(LayoutKind.Sequential)] 37 | public struct VertexWired 38 | { 39 | public VertexWired(Vector4 position, Color4 color) 40 | { 41 | Position = position; 42 | Color = color; 43 | } 44 | 45 | public VertexWired(Vector3 position, Color4 color) 46 | { 47 | Position = new Vector4(position.X, position.Y, position.Z, 1f); 48 | Color = color; 49 | } 50 | 51 | public Vector4 Position; 52 | public Color4 Color; 53 | } 54 | 55 | public Device device; 56 | public Engine3D engine; 57 | public RenderType type; 58 | public VertexWired[] verticesWired = new VertexWired[] { new VertexWired(new Vector4(-0.5f, 0.5f, 0.0f, 1.0f), Color4.Black), 59 | new VertexWired(new Vector4(0.5f, 0.5f, 0.0f, 1.0f), Color4.Black), 60 | new VertexWired(new Vector4(0.0f, -0.5f, 0.0f, 1.0f), Color4.Black) }; 61 | 62 | public VertexTextured[] verticesTextured = new VertexTextured[] { new VertexTextured(new Vector4(-0.5f, 0.5f, 0.0f, 1.0f), Color4.White, new Vector2(0, 0)), 63 | new VertexTextured(new Vector4(0.0f, -0.5f, 0.0f, 1.0f), Color4.White, new Vector2(0.5f, 1f)), 64 | new VertexTextured(new Vector4(0.5f, 0.5f, 0.0f, 1.0f), Color4.White, new Vector2(1, 0))}; 65 | public Buffer triangleVertexBufferWired; 66 | public Buffer triangleVertexBufferTextured; 67 | public Texture2D texture; 68 | public ShaderResourceView textureView; 69 | public Matrix transform = Matrix.Identity; 70 | public bool Selected = false; 71 | public BoundingSphere bsphere = new BoundingSphere(); 72 | 73 | public RenderObject(Device d, RenderType t, Texture2D tex, Engine3D e) 74 | { 75 | device = d; 76 | type = t; 77 | engine = e; 78 | texture = tex; 79 | if (tex != null) 80 | textureView = new ShaderResourceView(device, tex); 81 | } 82 | 83 | public void InitGeometry() 84 | { 85 | if (verticesWired != null) 86 | triangleVertexBufferWired = Buffer.Create(device, BindFlags.VertexBuffer, verticesWired); 87 | if (verticesTextured != null) 88 | triangleVertexBufferTextured = Buffer.Create(device, BindFlags.VertexBuffer, verticesTextured); 89 | bsphere = CalcBoundingSphere(); 90 | } 91 | 92 | public void Render(DeviceContext context, Matrix view, Matrix proj) 93 | { 94 | Matrix world = transform * view * proj; 95 | world = Matrix.Transpose(world); 96 | context.VertexShader.SetConstantBuffer(0, engine.worldViewProjectionBuffer); 97 | context.UpdateSubresource(ref world, engine.worldViewProjectionBuffer); 98 | switch (type) 99 | { 100 | case RenderType.LineList: 101 | context.Rasterizer.State = engine.rasterStateWired; 102 | context.VertexShader.Set(engine.vsWired); 103 | context.PixelShader.Set(engine.psWired); 104 | context.InputAssembler.InputLayout = engine.inputLayoutWired; 105 | context.InputAssembler.PrimitiveTopology = PrimitiveTopology.LineList; 106 | context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(triangleVertexBufferWired, Utilities.SizeOf(), 0)); 107 | context.Draw(verticesWired.Count(), 0); 108 | break; 109 | case RenderType.TriListWired: 110 | context.Rasterizer.State = engine.rasterStateWired; 111 | context.VertexShader.Set(engine.vsWired); 112 | context.PixelShader.Set(engine.psWired); 113 | context.InputAssembler.InputLayout = engine.inputLayoutWired; 114 | context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; 115 | context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(triangleVertexBufferWired, Utilities.SizeOf(), 0)); 116 | context.Draw(verticesWired.Count(), 0); 117 | break; 118 | case RenderType.TriListTextured: 119 | context.Rasterizer.State = engine.rasterStateTextured; 120 | context.VertexShader.Set(engine.vsTextured); 121 | context.InputAssembler.InputLayout = engine.inputLayoutTextured; 122 | context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; 123 | context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(triangleVertexBufferTextured, Utilities.SizeOf(), 0)); 124 | context.PixelShader.Set(engine.psTextured); 125 | context.PixelShader.SetShaderResource(0, textureView); 126 | context.PixelShader.SetSampler(0, engine.sampler); 127 | context.Draw(verticesTextured.Count(), 0); 128 | break; 129 | } 130 | } 131 | 132 | public BoundingSphere CalcBoundingSphere() 133 | { 134 | BoundingSphere s = new BoundingSphere(); 135 | float f = 0; 136 | foreach (VertexTextured v in verticesTextured) 137 | { 138 | float t = (v.Position.X * v.Position.X) + 139 | (v.Position.Y * v.Position.Y) + 140 | (v.Position.Z * v.Position.Z); 141 | if (t > f) 142 | f = t; 143 | } 144 | foreach (VertexWired v in verticesWired) 145 | { 146 | float t = (v.Position.X * v.Position.X) + 147 | (v.Position.Y * v.Position.Y) + 148 | (v.Position.Z * v.Position.Z); 149 | if (t > f) 150 | f = t; 151 | } 152 | s.Center = Vector3.Zero; 153 | s.Radius = (float)System.Math.Sqrt(f); 154 | return s; 155 | } 156 | 157 | private Vector3 DropW(Vector4 v) 158 | { 159 | return new Vector3(v.X, v.Y, v.Z); 160 | } 161 | 162 | public void Dispose() 163 | { 164 | if (triangleVertexBufferWired != null) 165 | triangleVertexBufferWired.Dispose(); 166 | if (triangleVertexBufferTextured != null) 167 | triangleVertexBufferTextured.Dispose(); 168 | } 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /CrocExplorerWV/Engine/TextureManager.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using SharpDX; 4 | using SharpDX.DXGI; 5 | using SharpDX.Direct3D11; 6 | using SharpDX.WIC; 7 | using Device = SharpDX.Direct3D11.Device; 8 | 9 | namespace CrocExplorerWV 10 | { 11 | public class TextureManager 12 | { 13 | public Engine3D engine = null; 14 | public Dictionary loadedTextures = new Dictionary(); 15 | public Texture2D FindTextureByPath(string path) 16 | { 17 | Texture2D result = null; 18 | return result; 19 | } 20 | 21 | public void ClearCache() 22 | { 23 | loadedTextures.Clear(); 24 | } 25 | 26 | public BitmapSource LoadBitmap(ImagingFactory2 factory, string filename) 27 | { 28 | var bitmapDecoder = new BitmapDecoder( 29 | factory, 30 | filename, 31 | DecodeOptions.CacheOnDemand 32 | ); 33 | 34 | var formatConverter = new FormatConverter(factory); 35 | 36 | formatConverter.Initialize( 37 | bitmapDecoder.GetFrame(0), 38 | PixelFormat.Format32bppPRGBA, 39 | BitmapDitherType.None, 40 | null, 41 | 0.0, 42 | BitmapPaletteType.Custom); 43 | 44 | return formatConverter; 45 | } 46 | public Texture2D CreateTexture2DFromBitmap(Device device, BitmapSource bitmapSource) 47 | { 48 | int stride = bitmapSource.Size.Width * 4; 49 | using (var buffer = new DataStream(bitmapSource.Size.Height * stride, true, true)) 50 | { 51 | bitmapSource.CopyPixels(stride, buffer); 52 | return new Texture2D(device, new Texture2DDescription() 53 | { 54 | Width = bitmapSource.Size.Width, 55 | Height = bitmapSource.Size.Height, 56 | ArraySize = 1, 57 | BindFlags = SharpDX.Direct3D11.BindFlags.ShaderResource, 58 | Usage = SharpDX.Direct3D11.ResourceUsage.Immutable, 59 | CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None, 60 | Format = SharpDX.DXGI.Format.R8G8B8A8_UNorm, 61 | MipLevels = 1, 62 | OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None, 63 | SampleDescription = new SampleDescription(1, 0), 64 | }, new DataRectangle(buffer.DataPointer, stride)); 65 | } 66 | } 67 | 68 | public unsafe SharpDX.WIC.Bitmap CreateWICBitmapFromGDI(System.Drawing.Bitmap gdiBitmap) 69 | { 70 | var wicFactory = new ImagingFactory(); 71 | var wicBitmap = new SharpDX.WIC.Bitmap( 72 | wicFactory, gdiBitmap.Width, gdiBitmap.Height, 73 | SharpDX.WIC.PixelFormat.Format32bppBGRA, 74 | BitmapCreateCacheOption.CacheOnLoad); 75 | System.Drawing.Rectangle rect = new System.Drawing.Rectangle( 76 | 0, 0, gdiBitmap.Width, gdiBitmap.Height); 77 | var btmpData = gdiBitmap.LockBits(rect, 78 | System.Drawing.Imaging.ImageLockMode.WriteOnly, 79 | System.Drawing.Imaging.PixelFormat.Format32bppArgb); 80 | byte* pGDIData = (byte*)btmpData.Scan0; 81 | using (BitmapLock bl = wicBitmap.Lock(BitmapLockFlags.Write)) 82 | { 83 | byte* pWICData = (byte*)bl.Data.DataPointer; 84 | for (int y = 0; y < gdiBitmap.Height; y++) 85 | { 86 | int offsetWIC = y * bl.Stride; 87 | int offsetGDI = y * btmpData.Stride; 88 | for (int x = 0; x < gdiBitmap.Width; x++) 89 | { 90 | pWICData[offsetWIC + 0] = pGDIData[offsetGDI + 0]; 91 | pWICData[offsetWIC + 1] = pGDIData[offsetGDI + 1]; 92 | pWICData[offsetWIC + 2] = pGDIData[offsetGDI + 2]; 93 | pWICData[offsetWIC + 3] = pGDIData[offsetGDI + 3]; 94 | offsetWIC += 4; 95 | offsetGDI += 4; 96 | } 97 | } 98 | } 99 | gdiBitmap.UnlockBits(btmpData); 100 | return wicBitmap; 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /CrocExplorerWV/FileReference.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace CrocExplorerWV 8 | { 9 | public class FileReference 10 | { 11 | public string name; 12 | public uint pos; 13 | public uint len; 14 | public uint ulen; 15 | public byte compression; 16 | 17 | public FileReference(string line) 18 | { 19 | string[] parts = line.Split(','); 20 | name = parts[0]; 21 | pos = Convert.ToUInt32(parts[1]); 22 | len = Convert.ToUInt32(parts[2]); 23 | ulen = Convert.ToUInt32(parts[3]); 24 | switch (parts[4]) 25 | { 26 | case "u": 27 | compression = 0; 28 | break; 29 | case "b": 30 | compression = 1; 31 | break; 32 | case "w": 33 | compression = 2; 34 | break; 35 | } 36 | } 37 | 38 | public override string ToString() 39 | { 40 | return name; 41 | } 42 | 43 | public string ToEntry() 44 | { 45 | StringBuilder sb = new StringBuilder(); 46 | sb.Append(name + ","); 47 | sb.Append(pos + ","); 48 | sb.Append(len + ","); 49 | sb.Append(ulen + ","); 50 | switch (compression) 51 | { 52 | case 1: 53 | sb.Append("b"); 54 | break; 55 | case 2: 56 | sb.Append("w"); 57 | break; 58 | default: 59 | sb.Append("u"); 60 | break; 61 | } 62 | sb.Append("\r\n"); 63 | return sb.ToString(); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /CrocExplorerWV/Filesystem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace CrocExplorerWV 9 | { 10 | public static class FileSystem 11 | { 12 | public static List idxFilenames = new List(); 13 | public static List idxFiles = new List(); 14 | public static string basePath; 15 | 16 | public static void Init(string path) 17 | { 18 | basePath = path; 19 | Log.WriteLine("Loading files from path : " + path); 20 | idxFilenames = new List(SearchIdxFiles(basePath)); 21 | idxFiles = new List(); 22 | foreach (string file in idxFilenames) 23 | { 24 | string check = Path.GetDirectoryName(file) + "\\" + Path.GetFileNameWithoutExtension(file) + ".wad"; 25 | if (!File.Exists(check)) 26 | continue; 27 | IdxFile idx = new IdxFile(file, basePath.Length + 6); 28 | Log.WriteLine("Adding " + idx.filename + " ..."); 29 | idxFiles.Add(idx); 30 | } 31 | } 32 | 33 | public static string[] SearchIdxFiles(string dir) 34 | { 35 | List result = new List(); 36 | foreach (string d in Directory.GetDirectories(dir)) 37 | { 38 | foreach (string f in Directory.GetFiles(d)) 39 | if (f.ToLower().EndsWith(".idx")) 40 | result.Add(f); 41 | result.AddRange(SearchIdxFiles(d)); 42 | } 43 | return result.ToArray(); 44 | } 45 | 46 | public static void FindFile(string s, out IdxFile idf, out FileReference r) 47 | { 48 | r = null; 49 | idf = null; 50 | string[] parts = s.Split('>'); 51 | foreach (IdxFile idx in FileSystem.idxFiles) 52 | if (idx.basepath + idx.filename == parts[0]) 53 | { 54 | idf = idx; 55 | break; 56 | } 57 | if (idf == null) 58 | { 59 | Log.WriteLine("Error: IDX File not found (" + parts[0] + ")"); 60 | return; 61 | } 62 | foreach (FileReference fr in idf.refs) 63 | if (fr.name == parts[1]) 64 | { 65 | r = fr; 66 | break; 67 | } 68 | if (r == null) 69 | { 70 | Log.WriteLine("Error: File reference not found (" + parts[1] + ")"); 71 | return; 72 | } 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /CrocExplorerWV/Form1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Collections.Generic; 4 | using System.ComponentModel; 5 | using System.Data; 6 | using System.Drawing; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Media; 10 | using System.Threading.Tasks; 11 | using System.Windows.Forms; 12 | using Be.Windows.Forms; 13 | 14 | namespace CrocExplorerWV 15 | { 16 | public partial class Form1 : Form 17 | { 18 | PIXFile currentPix; 19 | MODFile currentMod; 20 | Engine3D engine; 21 | SoundPlayer sp; 22 | public Form1() 23 | { 24 | InitializeComponent(); 25 | } 26 | 27 | private void Form1_Load(object sender, EventArgs e) 28 | { 29 | Log.box = rtb1; 30 | OpenFileDialog d = new OpenFileDialog(); 31 | d.Filter = "croc.exe|croc.exe"; 32 | if (d.ShowDialog() == System.Windows.Forms.DialogResult.OK) 33 | { 34 | FileSystem.Init(Path.GetDirectoryName(d.FileName) + "\\"); 35 | this.TopMost = true; 36 | Application.DoEvents(); 37 | this.TopMost = false; 38 | RefreshTree(); 39 | RefreshList(); 40 | engine = new Engine3D(pb2); 41 | timer1.Enabled = true; 42 | } 43 | else 44 | this.Close(); 45 | } 46 | 47 | public void RefreshTree() 48 | { 49 | tv1.Nodes.Clear(); 50 | foreach (IdxFile idx in FileSystem.idxFiles) 51 | { 52 | TreeNode nt = idx.ToTree(); 53 | bool found = false; 54 | foreach(TreeNode t in tv1.Nodes) 55 | if (t.Text == nt.Text) 56 | { 57 | t.Nodes.Add(nt.Nodes[0]); 58 | found = true; 59 | break; 60 | } 61 | if(!found) 62 | tv1.Nodes.Add(nt); 63 | } 64 | } 65 | 66 | public void RefreshList() 67 | { 68 | string[] files = Directory.GetFiles(FileSystem.basePath, "*.pix", SearchOption.AllDirectories); 69 | List fileList = new List(); 70 | foreach (string file in files) 71 | fileList.Add(file); 72 | foreach (IdxFile idx in FileSystem.idxFiles) 73 | foreach (FileReference r in idx.refs) 74 | if (r.name.ToLower().EndsWith(".pix")) 75 | fileList.Add(idx.basepath + idx.filename + ">" + r.name); 76 | listBox1.Items.Clear(); 77 | string filter = textBox1.Text.ToLower(); 78 | foreach (string s in fileList) 79 | if (s.ToLower().Contains(filter)) 80 | listBox1.Items.Add(s); 81 | 82 | 83 | files = Directory.GetFiles(FileSystem.basePath, "*.mod", SearchOption.AllDirectories); 84 | fileList = new List(); 85 | foreach (string file in files) 86 | fileList.Add(file); 87 | foreach (IdxFile idx in FileSystem.idxFiles) 88 | foreach (FileReference r in idx.refs) 89 | if (r.name.ToLower().EndsWith(".mod")) 90 | fileList.Add(idx.basepath + idx.filename + ">" + r.name); 91 | listBox2.Items.Clear(); 92 | filter = textBox2.Text.ToLower(); 93 | foreach (string s in fileList) 94 | if (s.ToLower().Contains(filter)) 95 | listBox2.Items.Add(s); 96 | 97 | 98 | fileList = new List(); 99 | foreach (IdxFile idx in FileSystem.idxFiles) 100 | foreach (FileReference r in idx.refs) 101 | if (r.name.ToLower().EndsWith(".wav")) 102 | fileList.Add(idx.basepath + idx.filename + ">" + r.name); 103 | listBox3.Items.Clear(); 104 | filter = textBox3.Text.ToLower(); 105 | foreach (string s in fileList) 106 | if (s.ToLower().Contains(filter)) 107 | listBox3.Items.Add(s); 108 | } 109 | 110 | private void tv1_AfterSelect(object sender, TreeViewEventArgs e) 111 | { 112 | TreeNode sel = e.Node; 113 | IdxFile idx = null; 114 | FileReference fr = null; 115 | GetFileReference(sel, out idx, out fr); 116 | if (fr != null) 117 | { 118 | byte[] data = idx.LoadEntry(fr); 119 | hb1.ByteProvider = new DynamicByteProvider(data); 120 | } 121 | } 122 | 123 | private void exportRAWToolStripMenuItem_Click(object sender, EventArgs e) 124 | { 125 | SaveFileDialog d = new SaveFileDialog(); 126 | d.Filter = "*.*|*.*"; 127 | if (tv1.SelectedNode != null) 128 | d.FileName = tv1.SelectedNode.Text; 129 | if (d.ShowDialog() == System.Windows.Forms.DialogResult.OK) 130 | { 131 | MemoryStream m = new MemoryStream(); 132 | for (int i = 0; i < hb1.ByteProvider.Length; i++) 133 | m.WriteByte(hb1.ByteProvider.ReadByte(i)); 134 | File.WriteAllBytes(d.FileName, m.ToArray()); 135 | Log.WriteLine("Saved to " + d.FileName); 136 | } 137 | } 138 | 139 | private void importRAWToolStripMenuItem_Click(object sender, EventArgs e) 140 | { 141 | IdxFile idx = null; 142 | FileReference fr = null; 143 | GetFileReference(tv1.SelectedNode, out idx, out fr); 144 | if (fr != null) 145 | { 146 | OpenFileDialog d = new OpenFileDialog(); 147 | d.Filter = "*.*|*.*"; 148 | if (tv1.SelectedNode != null) 149 | d.FileName = tv1.SelectedNode.Text; 150 | if (d.ShowDialog() == System.Windows.Forms.DialogResult.OK) 151 | { 152 | byte[] buff = File.ReadAllBytes(d.FileName); 153 | uint ucsize = (uint)buff.Length; 154 | if (fr.compression != 0) 155 | buff = Helper.CompressRLE(buff, fr.compression); 156 | idx.SaveEntry(fr, buff, ucsize); 157 | } 158 | } 159 | } 160 | 161 | public void GetFileReference(TreeNode sel, out IdxFile idxFile, out FileReference fileRef) 162 | { 163 | idxFile = null; 164 | fileRef = null; 165 | bool found = false; 166 | if (sel != null && sel.Parent != null && sel.Parent.Text.EndsWith(".idx")) 167 | { 168 | string idxpath = ""; 169 | if (sel.Parent.Parent == null) 170 | idxpath = sel.Parent.Text; 171 | else 172 | idxpath = sel.Parent.Parent.Text.Substring(1) + "\\" + sel.Parent.Text; 173 | foreach (IdxFile idx in FileSystem.idxFiles) 174 | { 175 | if (idx.filename == idxpath) 176 | foreach (FileReference r in idx.refs) 177 | if (r.name == sel.Text) 178 | { 179 | found = true; 180 | fileRef = r; 181 | break; 182 | } 183 | if (found) 184 | { 185 | idxFile = idx; 186 | break; 187 | } 188 | } 189 | } 190 | } 191 | 192 | private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) 193 | { 194 | try 195 | { 196 | int n = comboBox1.SelectedIndex; 197 | if (n == -1) 198 | return; 199 | PIXFile.PIXHeader h = currentPix.headers[n]; 200 | PIXFile.PIXData d = currentPix.images[n]; 201 | pb1.Image = PIXFile.MakeBitmap(h, d); 202 | } 203 | catch { } 204 | } 205 | 206 | private void textBox1_TextChanged(object sender, EventArgs e) 207 | { 208 | RefreshList(); 209 | } 210 | 211 | private void listBox1_SelectedIndexChanged_1(object sender, EventArgs e) 212 | { 213 | try 214 | { 215 | string s = listBox1.SelectedItem.ToString(); 216 | currentPix = new PIXFile(LoadFile(s)); 217 | comboBox1.Items.Clear(); 218 | int count = 1; 219 | foreach (PIXFile.PIXHeader h in currentPix.headers) 220 | comboBox1.Items.Add(count++ + "/" + currentPix.headers.Count + " " + h.name); 221 | if (comboBox1.Items.Count != 0) 222 | comboBox1.SelectedIndex = 0; 223 | } 224 | catch { } 225 | } 226 | 227 | private byte[] LoadFile(string s) 228 | { 229 | byte[] result = null; 230 | if (s.Contains(">")) 231 | { 232 | IdxFile idf; 233 | FileReference r; 234 | FileSystem.FindFile(s, out idf, out r); 235 | if (idf == null || r == null) 236 | return result; 237 | result = idf.LoadEntry(r); 238 | } 239 | else 240 | result = File.ReadAllBytes(s); 241 | return result; 242 | } 243 | 244 | private void exportBMPToolStripMenuItem_Click_1(object sender, EventArgs e) 245 | { 246 | if (pb1.Image == null) 247 | return; 248 | SaveFileDialog d = new SaveFileDialog(); 249 | d.Filter = "*.png|*.png"; 250 | if (currentPix != null && comboBox1.SelectedIndex != -1 && currentPix.headers.Count > 0 && currentPix.images.Count > 0) 251 | { 252 | d.FileName = currentPix.headers[comboBox1.SelectedIndex].name; 253 | if (!d.FileName.ToLower().EndsWith(".png")) 254 | d.FileName += ".png"; 255 | } 256 | if (d.ShowDialog() == System.Windows.Forms.DialogResult.OK) 257 | { 258 | pb1.Image.Save(d.FileName); 259 | Log.WriteLine("Saved to " + d.FileName); 260 | } 261 | } 262 | 263 | private void importPNGToolStripMenuItem_Click(object sender, EventArgs e) 264 | { 265 | if (listBox1.SelectedIndex != -1 && comboBox1.SelectedIndex != -1) 266 | { 267 | string s = listBox1.SelectedItem.ToString(); 268 | byte[] pxData = LoadFile(s); 269 | PIXFile px = new PIXFile(pxData); 270 | if (px == null) 271 | return; 272 | OpenFileDialog d = new OpenFileDialog(); 273 | d.Filter = "*.png|*.png"; 274 | if (d.ShowDialog() == System.Windows.Forms.DialogResult.OK) 275 | { 276 | Bitmap bmp = new Bitmap(d.FileName); 277 | PIXFile.PIXHeader h = px.headers[comboBox1.SelectedIndex]; 278 | if (bmp.Width != h.Width || bmp.Height != h.Height) 279 | { 280 | MessageBox.Show("Imported image size doesnt match! (" + bmp.Width + "x" + bmp.Height + " vs " + h.Width + "x" + h.Height + ")"); 281 | return; 282 | } 283 | byte[] data = PIXFile.MakePixdata(h, bmp); 284 | int start = (int)px.images[comboBox1.SelectedIndex]._fileOffset + 12; 285 | for (int i = 0; i < data.Length; i++) 286 | pxData[start + i] = data[i]; 287 | if (s.Contains(">")) 288 | { 289 | 290 | IdxFile idf; 291 | FileReference r; 292 | FileSystem.FindFile(s, out idf, out r); 293 | if (idf == null || r == null) 294 | return; 295 | uint ucsize = (uint)pxData.Length; 296 | if (r.compression != 0) 297 | pxData = Helper.CompressRLE(pxData, r.compression); 298 | idf.SaveEntry(r, pxData, ucsize); 299 | } 300 | else 301 | File.WriteAllBytes(s, pxData); 302 | Log.WriteLine("Saved to " + s); 303 | } 304 | } 305 | } 306 | 307 | private void exportAllPIXAsBMPToolStripMenuItem_Click_1(object sender, EventArgs e) 308 | { 309 | FolderBrowserDialog d = new FolderBrowserDialog(); 310 | if (d.ShowDialog() == System.Windows.Forms.DialogResult.OK) 311 | { 312 | string output = d.SelectedPath + "\\"; 313 | int count = 0; 314 | prog.Minimum = 0; 315 | prog.Maximum = listBox1.Items.Count; 316 | foreach (string entry in listBox1.Items) 317 | { 318 | if ((count % 10) == 0) 319 | { 320 | prog.Value = count; 321 | Application.DoEvents(); 322 | } 323 | if (entry.Contains(">")) 324 | ExportPNGfromPIX(LoadFile(entry), Path.GetFileName(entry.Split('>')[1]), output + Path.GetFileName(entry.Split('>')[0]) + "\\"); 325 | else 326 | ExportPNGfromPIX(File.ReadAllBytes(entry), Path.GetFileName(entry), output); 327 | count++; 328 | } 329 | prog.Value = 0; 330 | Log.WriteLine("Done."); 331 | } 332 | } 333 | 334 | private void ExportPNGfromPIX(byte[] data, string pixname, string output) 335 | { 336 | if (data == null) 337 | return; 338 | PIXFile px = new PIXFile(data); 339 | string dir = output; 340 | if (!Directory.Exists(dir)) 341 | Directory.CreateDirectory(dir); 342 | if (px.headers.Count > 1) 343 | { 344 | dir += pixname; 345 | if (!Directory.Exists(dir)) 346 | Directory.CreateDirectory(dir); 347 | dir += "\\"; 348 | } 349 | for (int i = 0; i < px.headers.Count; i++) 350 | { 351 | PIXFile.PIXHeader h = px.headers[i]; 352 | PIXFile.PIXData d = px.images[i]; 353 | Bitmap bmp = PIXFile.MakeBitmap(h, d); 354 | string name = MakeName(dir + Sanitize(h.name)); 355 | bmp.Save(name); 356 | Log.WriteLine("Saved " + name); 357 | } 358 | } 359 | 360 | private string MakeName(string name) 361 | { 362 | string result = name; 363 | if (File.Exists(result + ".png")) 364 | { 365 | int count = 0; 366 | while (File.Exists(result + "_" + count + ".png")) 367 | count++; 368 | result += "_" + count + ".png"; 369 | } 370 | else 371 | result += ".png"; 372 | return result; 373 | } 374 | 375 | private string Sanitize(string s) 376 | { 377 | return s.Replace("?", "_QUESTIONMARK_") 378 | .Replace(":", "_COLON_") 379 | .Replace(";", "_SEMICOLON_") 380 | .Replace(".", "_DOT_") 381 | .Replace(",", "_COMMA_") 382 | .Replace("<", "_LESS_") 383 | .Replace(">", "_GREATER_") 384 | .Replace("[", "_BRACKETOPEN_") 385 | .Replace("]", "_BRACKETCLOSED_") 386 | .Replace("%", "_PERCENT_") 387 | .Replace("/", "_SLASH_") 388 | .Replace("\\", "_BACKSLASH_") 389 | .Replace("'", "_QUOTE_") 390 | .Replace("\"", "_DBLQUOTE_") 391 | .Replace("*", "_STAR_"); 392 | } 393 | 394 | private void listBox2_SelectedIndexChanged(object sender, EventArgs e) 395 | { 396 | try 397 | { 398 | string s = listBox2.SelectedItem.ToString(); 399 | MODFile m = new MODFile(LoadFile(s)); 400 | engine.ClearScene(); 401 | foreach (MODFile.MODObject ob in m.obj) 402 | { 403 | RenderObject o = new RenderObject(engine.device, RenderObject.RenderType.TriListWired, engine.defaultTexture, engine); 404 | List tmp = new List(); 405 | foreach (MODFile.MODFace f in ob.faces) 406 | { 407 | tmp.Add(MakeV(ob.vertices[f.f1 - 1])); 408 | tmp.Add(MakeV(ob.vertices[f.f2 - 1])); 409 | tmp.Add(MakeV(ob.vertices[f.f3 - 1])); 410 | if ((f.flags & 0x8) != 0) 411 | { 412 | tmp.Add(MakeV(ob.vertices[f.f2 - 1])); 413 | tmp.Add(MakeV(ob.vertices[f.f3 - 1])); 414 | tmp.Add(MakeV(ob.vertices[f.f4 - 1])); 415 | } 416 | } 417 | o.verticesWired = tmp.ToArray(); 418 | o.InitGeometry(); 419 | engine.objects.Add(o); 420 | } 421 | engine.ResetCameraDistance(); 422 | 423 | } 424 | catch { } 425 | } 426 | 427 | private RenderObject.VertexWired MakeV(MODFile.MODVector3 mv) 428 | { 429 | RenderObject.VertexWired v = new RenderObject.VertexWired(); 430 | v.Position.X = mv.X; 431 | v.Position.Y = mv.Y; 432 | v.Position.Z = mv.Z; 433 | v.Position.W = 1; 434 | v.Color.Alpha = 255; 435 | return v; 436 | } 437 | 438 | private void textBox2_TextChanged(object sender, EventArgs e) 439 | { 440 | RefreshList(); 441 | } 442 | 443 | private void timer1_Tick(object sender, EventArgs e) 444 | { 445 | if (engine != null) 446 | engine.Render(); 447 | } 448 | 449 | bool mouseUp = true; 450 | Point mouseLast = new Point(0, 0); 451 | 452 | private void pb2_MouseDown(object sender, MouseEventArgs e) 453 | { 454 | mouseUp = false; 455 | mouseLast = e.Location; 456 | } 457 | 458 | private void pb2_MouseMove(object sender, MouseEventArgs e) 459 | { 460 | if (!mouseUp) 461 | { 462 | int dx = e.X - mouseLast.X; 463 | int dy = e.Y - mouseLast.Y; 464 | engine.CamDis *= 1 + (dy * 0.01f); 465 | engine.CamRot += dx * 0.01f; 466 | mouseLast = e.Location; 467 | } 468 | 469 | } 470 | 471 | private void pb2_MouseUp(object sender, MouseEventArgs e) 472 | { 473 | mouseUp = true; 474 | } 475 | 476 | private void pb2_SizeChanged(object sender, EventArgs e) 477 | { 478 | if (engine != null) 479 | engine.Resize(pb2); 480 | } 481 | 482 | private void exportAsOBJToolStripMenuItem_Click(object sender, EventArgs e) 483 | { 484 | int n = listBox2.SelectedIndex; 485 | if (n == -1) 486 | return; 487 | try 488 | { 489 | string s = listBox2.SelectedItem.ToString(); 490 | MODFile m = new MODFile(LoadFile(s)); 491 | SaveFileDialog d = new SaveFileDialog(); 492 | d.Filter = "*.obj|*.obj"; 493 | if (s.Contains(">")) 494 | d.FileName = Path.GetFileNameWithoutExtension(s.Split('>')[1]) + ".obj"; 495 | else 496 | d.FileName = Path.GetFileNameWithoutExtension(s) + ".obj"; 497 | if(d.ShowDialog() == DialogResult.OK) 498 | { 499 | m.SaveToObj(d.FileName); 500 | Log.WriteLine("Saved to " + d.FileName); 501 | } 502 | } 503 | catch { } 504 | } 505 | 506 | private void textBox3_TextChanged(object sender, EventArgs e) 507 | { 508 | RefreshList(); 509 | } 510 | 511 | private void listBox3_SelectedIndexChanged(object sender, EventArgs e) 512 | { 513 | int n = listBox3.SelectedIndex; 514 | if (n == -1) 515 | return; 516 | MemoryStream m = new MemoryStream(LoadFile(listBox3.SelectedItem.ToString())); 517 | sp = new SoundPlayer(m); 518 | } 519 | 520 | private void button1_Click(object sender, EventArgs e) 521 | { 522 | if (sp != null) 523 | sp.Play(); 524 | } 525 | 526 | private void exportAsWAVToolStripMenuItem_Click(object sender, EventArgs e) 527 | { 528 | int n = listBox3.SelectedIndex; 529 | if (n == -1) 530 | return; 531 | string s = listBox3.SelectedItem.ToString(); 532 | SaveFileDialog d = new SaveFileDialog(); 533 | d.Filter = "*.wav|*.wav"; 534 | d.FileName = Path.GetFileNameWithoutExtension(s.Split('>')[1]); 535 | if (d.ShowDialog() == System.Windows.Forms.DialogResult.OK) 536 | { 537 | File.WriteAllBytes(d.FileName, LoadFile(s)); 538 | Log.WriteLine("Saved to " + d.FileName); 539 | } 540 | } 541 | 542 | private void importWAVToolStripMenuItem_Click(object sender, EventArgs e) 543 | { 544 | int n = listBox3.SelectedIndex; 545 | if (n == -1) 546 | return; 547 | string s = listBox3.SelectedItem.ToString(); 548 | OpenFileDialog d = new OpenFileDialog(); 549 | d.Filter = "*.wav|*.wav"; 550 | if (d.ShowDialog() == System.Windows.Forms.DialogResult.OK) 551 | { 552 | byte[] data = File.ReadAllBytes(d.FileName); 553 | IdxFile idf; 554 | FileReference r; 555 | FileSystem.FindFile(s, out idf, out r); 556 | if (idf == null || r == null) 557 | return; 558 | uint ucsize = (uint)data.Length; 559 | if (r.compression != 0) 560 | data = Helper.CompressRLE(data, r.compression); 561 | idf.SaveEntry(r, data, ucsize); 562 | Log.WriteLine("Saved to " + s); 563 | } 564 | } 565 | } 566 | } 567 | -------------------------------------------------------------------------------- /CrocExplorerWV/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 | 126, 17 125 | 126 | -------------------------------------------------------------------------------- /CrocExplorerWV/Helper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Windows.Forms; 8 | using System.Drawing; 9 | 10 | namespace CrocExplorerWV 11 | { 12 | public static class Helper 13 | { 14 | public static uint ReadU32LE(Stream s) 15 | { 16 | ulong result = 0; 17 | result = (byte)s.ReadByte(); 18 | result = (result << 8) | (byte)s.ReadByte(); 19 | result = (result << 8) | (byte)s.ReadByte(); 20 | result = (result << 8) | (byte)s.ReadByte(); 21 | return (uint)result; 22 | } 23 | 24 | public static ushort ReadU16LE(Stream s) 25 | { 26 | ulong result = 0; 27 | result = (byte)s.ReadByte(); 28 | result = (result << 8) | (byte)s.ReadByte(); 29 | return (ushort)result; 30 | } 31 | public static uint ReadU32BE(Stream s) 32 | { 33 | ulong result = 0; 34 | result = (byte)s.ReadByte(); 35 | result |= (ulong)((byte)s.ReadByte() << 8); 36 | result |= (ulong)((byte)s.ReadByte() << 16); 37 | result |= (ulong)((byte)s.ReadByte() << 24); 38 | return (uint)result; 39 | } 40 | 41 | public static ushort ReadU16BE(Stream s) 42 | { 43 | ulong result = 0; 44 | result = (byte)s.ReadByte(); 45 | result |= (ulong)((byte)s.ReadByte() << 8); 46 | return (ushort)result; 47 | } 48 | 49 | public static byte[] CompressRLE(byte[] buff, byte type) 50 | { 51 | MemoryStream result = new MemoryStream(); 52 | ushort last = 0; 53 | int start = 0; 54 | int skip = 1; 55 | if (type == 1) 56 | { 57 | for (int i = 0; i < buff.Length; i++) 58 | { 59 | byte value = buff[i]; 60 | if (skip == 0 && i >= 2 && 61 | buff[i - 2] == buff[i - 1] && 62 | buff[i - 1] == buff[i]) 63 | { 64 | byte c = (byte)(-(i - start - 2)); 65 | if (c != 0) 66 | { 67 | result.WriteByte(c); 68 | result.Write(buff, start, i - start - 2); 69 | } 70 | int j = 0; 71 | while (true) 72 | { 73 | if (i + j + 1>= buff.Length || j >= 127) 74 | break; 75 | byte value2 = buff[i + j + 1]; 76 | if (value2 != value) 77 | break; 78 | j++; 79 | } 80 | result.WriteByte((byte)j); 81 | result.WriteByte((byte)last); 82 | i += j; 83 | start = i + 1; 84 | skip = 2; 85 | } 86 | else 87 | { 88 | last = value; 89 | if (skip > 0) 90 | skip--; 91 | } 92 | if (i - start == 0x80) 93 | { 94 | result.WriteByte(0x80); 95 | result.Write(buff, start, i - start); 96 | start = i; 97 | skip = 2; 98 | } 99 | } 100 | } 101 | if (type == 2) 102 | for (int i = 0; i < buff.Length; i += 2) 103 | { 104 | ushort value = (ushort)((buff[i] << 8) | buff[i + 1]); 105 | if (skip == 0 && (value == last || i - start > 130)) 106 | { 107 | byte c = (byte)(-(i - start - 2) / 2); 108 | if (c != 0) 109 | { 110 | result.WriteByte(c); 111 | result.Write(buff, start, i - start - 2); 112 | } 113 | int j = 0; 114 | while (true) 115 | { 116 | if (i + j + 2 >= buff.Length || j >= 254) 117 | break; 118 | ushort value2 = (ushort)((buff[i + j + 2] << 8) | buff[i + j + 3]); 119 | if (value2 != value) 120 | break; 121 | j += 2; 122 | } 123 | result.WriteByte((byte)(j / 2)); 124 | result.WriteByte((byte)(last >> 8)); 125 | result.WriteByte((byte)last); 126 | i += j; 127 | start = i + 2; 128 | skip = 1; 129 | } 130 | else 131 | { 132 | last = value; 133 | if (skip > 0) 134 | skip--; 135 | } 136 | } 137 | return result.ToArray(); 138 | } 139 | 140 | public static byte[] DecompressRLE(byte[] buff, byte type) 141 | { 142 | MemoryStream result = new MemoryStream(); 143 | if (type == 1) 144 | { 145 | for (int i = 0; i < buff.Length; i++) 146 | { 147 | sbyte s = (sbyte)(buff[i]); 148 | if (s < 0) 149 | { 150 | for (int j = 0; j < -s; j++) 151 | { 152 | i++; 153 | result.WriteByte(buff[i]); 154 | } 155 | } 156 | else 157 | { 158 | for (int j = 0; j < s + 3; j++) 159 | result.WriteByte(buff[i + 1]); 160 | i++; 161 | } 162 | } 163 | } 164 | if (type == 2) 165 | { 166 | for (int i = 0; i < buff.Length; i++) 167 | { 168 | sbyte s = (sbyte)(buff[i]); 169 | if (s < 0) 170 | { 171 | for (int j = 0; j < -s; j++) 172 | { 173 | i++; 174 | result.WriteByte(buff[i]); 175 | i++; 176 | result.WriteByte(buff[i]); 177 | } 178 | } 179 | else 180 | { 181 | for (int j = 0; j < s + 2; j++) 182 | { 183 | result.WriteByte(buff[i + 1]); 184 | result.WriteByte(buff[i + 2]); 185 | } 186 | i += 2; 187 | } 188 | } 189 | } 190 | return result.ToArray(); 191 | } 192 | 193 | public static Bitmap LoadBitmapUnlocked(string file_name) 194 | { 195 | using (Bitmap bm = new Bitmap(file_name)) 196 | { 197 | return new Bitmap(bm); 198 | } 199 | } 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /CrocExplorerWV/IdxFile.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Windows.Forms; 8 | 9 | namespace CrocExplorerWV 10 | { 11 | public class IdxFile 12 | { 13 | public List refs = new List(); 14 | public string basepath; 15 | public string filename; 16 | public string wadname; 17 | public IdxFile(string path, int basePathLen) 18 | { 19 | basepath = path.Substring(0, basePathLen); 20 | filename = path.Substring(basePathLen); 21 | wadname = filename.Substring(0, filename.Length - 3) + "wad"; 22 | string[] lines = File.ReadAllLines(path); 23 | foreach (string line in lines) 24 | refs.Add(new FileReference(line)); 25 | } 26 | 27 | public byte[] LoadEntry(FileReference r) 28 | { 29 | FileStream fs = new FileStream(basepath + wadname, FileMode.Open, FileAccess.Read); 30 | fs.Seek(r.pos, 0); 31 | byte[] buff = new byte[r.len]; 32 | fs.Read(buff, 0, (int)r.len); 33 | fs.Close(); 34 | if (r.compression != 0) 35 | buff = Helper.DecompressRLE(buff, r.compression); 36 | if (buff.Length > r.ulen) 37 | { 38 | MemoryStream m = new MemoryStream(); 39 | m.Write(buff, 0, (int)r.ulen); 40 | buff = m.ToArray(); 41 | } 42 | return buff; 43 | } 44 | 45 | public void SaveEntry(FileReference r, byte[] data, uint ucsize) 46 | { 47 | byte[] before = File.ReadAllBytes(basepath + wadname); 48 | MemoryStream m = new MemoryStream(); 49 | StringBuilder result = new StringBuilder(); 50 | uint pos = 0; 51 | foreach(FileReference fr in refs) 52 | if (fr.name != r.name) 53 | { 54 | m.Write(before, (int)fr.pos, (int)fr.len); 55 | fr.pos = pos; 56 | result.Append(fr.ToEntry()); 57 | pos += fr.len; 58 | } 59 | else 60 | { 61 | m.Write(data, 0, data.Length); 62 | fr.pos = pos; 63 | fr.len = (uint)data.Length; 64 | fr.ulen = ucsize; 65 | result.Append(fr.ToEntry()); 66 | pos += (uint)data.Length; 67 | } 68 | File.WriteAllText(basepath + filename, result.ToString()); 69 | File.WriteAllBytes(basepath + wadname, m.ToArray()); 70 | Log.WriteLine(filename + " updated."); 71 | } 72 | 73 | public TreeNode ToTree() 74 | { 75 | TreeNode result; 76 | TreeNode current; 77 | if (filename.Contains("\\")) 78 | { 79 | string[] parts = filename.Split('\\'); 80 | result = new TreeNode("\\" + parts[0]); 81 | current = new TreeNode(parts[1]); 82 | result.Nodes.Add(current); 83 | } 84 | else 85 | { 86 | result = new TreeNode(filename); 87 | current = result; 88 | } 89 | foreach (FileReference r in refs) 90 | current.Nodes.Add(r.name); 91 | return result; 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /CrocExplorerWV/Log.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows.Forms; 7 | 8 | namespace CrocExplorerWV 9 | { 10 | public static class Log 11 | { 12 | public static RichTextBox box = null; 13 | public static readonly object _sync = new object(); 14 | 15 | public static void WriteLine(string s) 16 | { 17 | Write(s + "\n"); 18 | } 19 | 20 | public static void Write(string s) 21 | { 22 | if (box == null) 23 | return; 24 | box.BeginInvoke((MethodInvoker)delegate() 25 | { 26 | box.AppendText(s); 27 | box.SelectionStart = box.Text.Length; 28 | box.ScrollToCaret(); 29 | }); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /CrocExplorerWV/MODFile.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace CrocExplorerWV 8 | { 9 | public class MODFile 10 | { 11 | public List obj = new List(); 12 | public MODFile(byte[] data) 13 | { 14 | MemoryStream m = new MemoryStream(data); 15 | m.Seek(0, 0); 16 | ushort count = Helper.ReadU16BE(m); 17 | ushort flags = Helper.ReadU16BE(m); 18 | for (int i = 0; i < count; i++) 19 | obj.Add(new MODObject(m)); 20 | } 21 | 22 | public void SaveToObj(string path) 23 | { 24 | StringBuilder sb = new StringBuilder(); 25 | int count = 0; 26 | int vcount = 0; 27 | foreach (MODObject o in obj) 28 | sb.Append(o.SaveToObj(count++, ref vcount)); 29 | File.WriteAllText(path, sb.ToString()); 30 | } 31 | 32 | public class MODObject 33 | { 34 | public int radius; 35 | public MODBBox[] bbox = new MODBBox[9]; 36 | public uint countVerts; 37 | public MODVector3[] vertices; 38 | public MODVector3[] normals; 39 | public uint countFaces; 40 | public MODFace[] faces; 41 | 42 | public MODObject(Stream s) 43 | { 44 | radius = (int)Helper.ReadU32BE(s); 45 | for (int i = 0; i < 9; i++) 46 | bbox[i] = new MODBBox(s); 47 | countVerts = Helper.ReadU32BE(s); 48 | vertices = new MODVector3[countVerts]; 49 | normals = new MODVector3[countVerts]; 50 | for (int i = 0; i < countVerts; i++) 51 | vertices[i] = new MODVector3(s); 52 | for (int i = 0; i < countVerts; i++) 53 | normals[i] = new MODVector3(s); 54 | countFaces = Helper.ReadU32BE(s); 55 | faces = new MODFace[countFaces]; 56 | for (int i = 0; i < countFaces; i++) 57 | faces[i] = new MODFace(s); 58 | } 59 | public string SaveToObj(int idx, ref int vcount) 60 | { 61 | StringBuilder sb = new StringBuilder(); 62 | sb.AppendLine("o Part_" + idx.ToString("D4")); 63 | foreach (MODVector3 v in vertices) 64 | sb.AppendLine(v.ToOBJ("v")); 65 | foreach (MODVector3 n in normals) 66 | sb.AppendLine(n.ToOBJ("vn")); 67 | sb.AppendLine("s off"); 68 | foreach (MODFace f in faces) 69 | sb.Append(f.ToOBJ(vcount)); 70 | vcount += (int)countVerts; 71 | return sb.ToString(); 72 | } 73 | } 74 | 75 | public class MODBBox 76 | { 77 | public ushort[] values = new ushort[4]; 78 | public MODBBox(Stream s) 79 | { 80 | for (int i = 0; i < 4; i++) 81 | values[i] = Helper.ReadU16BE(s); 82 | } 83 | } 84 | 85 | public class MODVector3 86 | { 87 | public float X, Y, Z, Padding; 88 | public MODVector3(Stream s) 89 | { 90 | X = ((short)Helper.ReadU16BE(s)) / 16f; 91 | Y = ((short)Helper.ReadU16BE(s)) / 16f; 92 | Z = ((short)Helper.ReadU16BE(s)) / 16f; 93 | Padding = (short)Helper.ReadU16BE(s); 94 | } 95 | 96 | public string ToOBJ(string type) 97 | { 98 | return type + " " + F(X) + " " + F(Y) + " " + F(Z); 99 | } 100 | 101 | private string F(float f) 102 | { 103 | return f.ToString().Replace(",", "."); 104 | } 105 | } 106 | 107 | public class MODFace 108 | { 109 | private byte[] raw; 110 | public ushort f1, f2, f3, f4; 111 | public byte flags; 112 | public MODFace(Stream s) 113 | { 114 | raw = new byte[0x54]; 115 | s.Read(raw, 0, 0x54); 116 | MemoryStream m = new MemoryStream(raw); 117 | m.Seek(0x48, 0); 118 | f1 = Helper.ReadU16BE(m); 119 | f2 = Helper.ReadU16BE(m); 120 | f3 = Helper.ReadU16BE(m); 121 | f4 = Helper.ReadU16BE(m); 122 | f1++; 123 | f2++; 124 | f3++; 125 | f4++; 126 | flags = raw[0x53]; 127 | } 128 | 129 | public string ToOBJ(int offset) 130 | { 131 | StringBuilder sb = new StringBuilder(); 132 | sb.AppendLine("f " + (f1 + offset) + "//" + (f1 + offset) + " " 133 | + (f2 + offset) + "//" + (f2 + offset) + " " 134 | + (f3 + offset) + "//" + (f3 + offset)); 135 | if ((flags & 0x8) != 0) 136 | sb.AppendLine("f " + (f2 + offset) + "//" + (f2 + offset) + " " 137 | + (f3 + offset) + "//" + (f3 + offset) + " " 138 | + (f4 + offset) + "//" + (f4 + offset)); 139 | return sb.ToString(); 140 | } 141 | } 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /CrocExplorerWV/PIXFile.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Drawing; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace CrocExplorerWV 10 | { 11 | public class PIXFile 12 | { 13 | public List headers = new List(); 14 | public List images = new List(); 15 | 16 | public PIXFile(byte[] data) 17 | { 18 | MemoryStream m = new MemoryStream(data); 19 | m.Seek(0x10, 0); 20 | try 21 | { 22 | while (m.Position < data.Length) 23 | { 24 | ReadChunk(m); 25 | } 26 | } 27 | catch { } 28 | } 29 | 30 | public static byte[] MakePixdata(PIXHeader header, Bitmap bmp) 31 | { 32 | MemoryStream m = new MemoryStream(); 33 | for (int y = 0; y < header.Height; y++) 34 | for (int x = 0; x < header.Width; x++) 35 | { 36 | switch (header.PixelFormat) 37 | { 38 | case 5: 39 | Color c = bmp.GetPixel(x, y); 40 | ushort value = (ushort)(c.R >> 3); 41 | value <<= 6; 42 | value |= (ushort)(c.G >> 2); 43 | value <<= 5; 44 | value |= (ushort)(c.B >> 3); 45 | m.WriteByte((byte)(value >> 8)); 46 | m.WriteByte((byte)value); 47 | break; 48 | } 49 | } 50 | return m.ToArray(); 51 | } 52 | 53 | public static Bitmap MakeBitmap(PIXHeader header, PIXData image) 54 | { 55 | if (header == null || image == null) 56 | return null; 57 | Bitmap result = new Bitmap(header.Width, header.Height); 58 | Graphics gr = Graphics.FromImage(result); 59 | gr.Clear(Color.White); 60 | MemoryStream m = new MemoryStream(image.ImageData); 61 | for (int y = 0; y < header.Height; y++) 62 | for (int x = 0; x < header.Width; x++) 63 | { 64 | switch (header.PixelFormat) 65 | { 66 | case 5: 67 | m.Seek((x + y * header.Width) * image.BytesPerPixel, 0); 68 | ushort value = Helper.ReadU16LE(m); 69 | byte b = (byte)(value & 0x1F); 70 | value >>= 5; 71 | byte g = (byte)(value & 0x3F); 72 | value >>= 6; 73 | byte r = (byte)(value & 0x1F); 74 | r <<= 3; 75 | g <<= 2; 76 | b <<= 3; 77 | result.SetPixel(x, y, Color.FromArgb(255, r, g, b)); 78 | break; 79 | } 80 | } 81 | return result; 82 | } 83 | 84 | private void ReadChunk(Stream s) 85 | { 86 | uint id = Helper.ReadU32LE(s); 87 | switch (id) 88 | { 89 | case 0x3D: 90 | headers.Add(new PIXHeader(s)); 91 | break; 92 | case 0x21: 93 | images.Add(new PIXData(s)); 94 | break; 95 | default: 96 | Log.WriteLine("Found unknown chunk id=0x" + id.ToString("X")); 97 | throw new Exception(); 98 | } 99 | } 100 | 101 | public class PIXHeader 102 | { 103 | public uint _fileOffset; 104 | public uint Length; 105 | public byte PixelFormat; 106 | public ushort PageWidth; 107 | public ushort Width; 108 | public ushort Height; 109 | public ushort OffsetX; 110 | public ushort OffsetY; 111 | public ushort Unknown; 112 | public string name; 113 | 114 | public PIXHeader(Stream s) 115 | { 116 | _fileOffset = (uint)s.Position; 117 | Length = Helper.ReadU32LE(s); 118 | PixelFormat = (byte)s.ReadByte(); 119 | PageWidth = Helper.ReadU16LE(s); 120 | Width = Helper.ReadU16LE(s); 121 | Height = Helper.ReadU16LE(s); 122 | OffsetX = Helper.ReadU16LE(s); 123 | OffsetY = Helper.ReadU16LE(s); 124 | Unknown = Helper.ReadU16LE(s); 125 | byte b; 126 | name = ""; 127 | while ((b = (byte)s.ReadByte()) != 0) 128 | name += (char)b; 129 | } 130 | } 131 | 132 | public class PIXData 133 | { 134 | public uint _fileOffset; 135 | public uint Length; 136 | public uint PixelCount; 137 | public uint BytesPerPixel; 138 | public byte[] ImageData; 139 | 140 | public PIXData(Stream s) 141 | { 142 | _fileOffset = (uint)s.Position; 143 | Length = Helper.ReadU32LE(s); 144 | PixelCount = Helper.ReadU32LE(s); 145 | BytesPerPixel = Helper.ReadU32LE(s); 146 | ImageData = new byte[Length]; 147 | s.Read(ImageData, 0, (int)Length); 148 | } 149 | } 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /CrocExplorerWV/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.Windows.Forms; 6 | 7 | namespace CrocExplorerWV 8 | { 9 | static class Program 10 | { 11 | /// 12 | /// Der Haupteinstiegspunkt für die Anwendung. 13 | /// 14 | [STAThread] 15 | static void Main() 16 | { 17 | Application.EnableVisualStyles(); 18 | Application.SetCompatibleTextRenderingDefault(false); 19 | Application.Run(new Form1()); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /CrocExplorerWV/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // Allgemeine Informationen über eine Assembly werden über die folgenden 6 | // Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, 7 | // die mit einer Assembly verknüpft sind. 8 | [assembly: AssemblyTitle("CrocExplorerWV")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("CrocExplorerWV")] 13 | [assembly: AssemblyCopyright("Copyright © 2019")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar 18 | // für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von 19 | // COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest. 20 | [assembly: ComVisible(false)] 21 | 22 | // Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird 23 | [assembly: Guid("f3085117-08bf-4396-9767-7f4d26228ade")] 24 | 25 | // Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: 26 | // 27 | // Hauptversion 28 | // Nebenversion 29 | // Buildnummer 30 | // Revision 31 | // 32 | // Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern 33 | // übernehmen, indem Sie "*" eingeben: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /CrocExplorerWV/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // Dieser Code wurde von einem Tool generiert. 4 | // Laufzeitversion:4.0.30319.42000 5 | // 6 | // Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn 7 | // der Code erneut generiert wird. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace CrocExplorerWV.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. 17 | /// 18 | // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert 19 | // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert. 20 | // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen 21 | // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.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 | /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. 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("CrocExplorerWV.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle 51 | /// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden. 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 | /// Sucht eine lokalisierte Zeichenfolge, die SamplerState Sampler : register(s0); 65 | ///Texture2D ShaderTexture : register(t0); 66 | ///struct VertexShaderOutput 67 | ///{ 68 | /// float4 Position : SV_Position; 69 | /// float4 Color : COLOR; 70 | /// float2 TextureUV : TEXCOORD0; 71 | ///}; 72 | ///float4 main(VertexShaderOutput input) : SV_Target 73 | ///{ 74 | /// return ShaderTexture.Sample(Sampler, input.TextureUV); 75 | ///} ähnelt. 76 | /// 77 | internal static string pixelShaderTextured { 78 | get { 79 | return ResourceManager.GetString("pixelShaderTextured", resourceCulture); 80 | } 81 | } 82 | 83 | /// 84 | /// Sucht eine lokalisierte Zeichenfolge, die struct VertexShaderInput 85 | ///{ 86 | /// float4 Position : SV_POSITION; 87 | /// float4 Color : COLOR; 88 | ///}; 89 | /// 90 | ///float4 main(VertexShaderInput input) : SV_TARGET 91 | ///{ 92 | /// return input.Color; 93 | ///} ähnelt. 94 | /// 95 | internal static string pixelShaderWired { 96 | get { 97 | return ResourceManager.GetString("pixelShaderWired", resourceCulture); 98 | } 99 | } 100 | 101 | /// 102 | /// Sucht eine lokalisierte Zeichenfolge, die cbuffer PerObject: register(b0) 103 | ///{ 104 | /// float4x4 WorldViewProj; 105 | ///}; 106 | /// 107 | ///struct VertexShaderInput 108 | ///{ 109 | /// float4 Position : SV_Position; 110 | /// float4 Color : COLOR; 111 | /// float2 TextureUV : TEXCOORD0; 112 | ///}; 113 | /// 114 | ///struct VertexShaderOutput 115 | ///{ 116 | /// float4 Position : SV_Position; 117 | /// float4 Color : COLOR; 118 | /// float2 TextureUV : TEXCOORD0; 119 | ///}; 120 | /// 121 | ///VertexShaderOutput main(VertexShaderInput input) 122 | ///{ 123 | /// VertexShaderOutput output = (VertexShaderOutput)0; 124 | /// output.Position = mul(input.Position, WorldViewProj); 125 | /// output.TextureUV = input. [Rest der Zeichenfolge wurde abgeschnitten]"; ähnelt. 126 | /// 127 | internal static string vertexShaderTextured { 128 | get { 129 | return ResourceManager.GetString("vertexShaderTextured", resourceCulture); 130 | } 131 | } 132 | 133 | /// 134 | /// Sucht eine lokalisierte Zeichenfolge, die cbuffer PerObject: register(b0) 135 | ///{ 136 | /// float4x4 WorldViewProj; 137 | ///}; 138 | /// 139 | ///struct VertexShaderInput 140 | ///{ 141 | /// float4 Position : SV_Position; 142 | /// float4 Color : COLOR; 143 | ///}; 144 | /// 145 | ///struct VertexShaderOutput 146 | ///{ 147 | /// float4 Position : SV_Position; 148 | /// float4 Color : COLOR; 149 | ///}; 150 | /// 151 | ///VertexShaderOutput main(VertexShaderInput input) 152 | ///{ 153 | /// VertexShaderOutput output = (VertexShaderOutput)0; 154 | /// output.Position = mul(input.Position, WorldViewProj); 155 | /// output.Color = input.Color; 156 | /// return output; 157 | ///} ähnelt. 158 | /// 159 | internal static string vertexShaderWired { 160 | get { 161 | return ResourceManager.GetString("vertexShaderWired", resourceCulture); 162 | } 163 | } 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /CrocExplorerWV/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 | 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 | SamplerState Sampler : register(s0); 122 | Texture2D ShaderTexture : register(t0); 123 | struct VertexShaderOutput 124 | { 125 | float4 Position : SV_Position; 126 | float4 Color : COLOR; 127 | float2 TextureUV : TEXCOORD0; 128 | }; 129 | float4 main(VertexShaderOutput input) : SV_Target 130 | { 131 | return ShaderTexture.Sample(Sampler, input.TextureUV); 132 | } 133 | 134 | 135 | struct VertexShaderInput 136 | { 137 | float4 Position : SV_POSITION; 138 | float4 Color : COLOR; 139 | }; 140 | 141 | float4 main(VertexShaderInput input) : SV_TARGET 142 | { 143 | return input.Color; 144 | } 145 | 146 | 147 | cbuffer PerObject: register(b0) 148 | { 149 | float4x4 WorldViewProj; 150 | }; 151 | 152 | struct VertexShaderInput 153 | { 154 | float4 Position : SV_Position; 155 | float4 Color : COLOR; 156 | float2 TextureUV : TEXCOORD0; 157 | }; 158 | 159 | struct VertexShaderOutput 160 | { 161 | float4 Position : SV_Position; 162 | float4 Color : COLOR; 163 | float2 TextureUV : TEXCOORD0; 164 | }; 165 | 166 | VertexShaderOutput main(VertexShaderInput input) 167 | { 168 | VertexShaderOutput output = (VertexShaderOutput)0; 169 | output.Position = mul(input.Position, WorldViewProj); 170 | output.TextureUV = input.TextureUV; 171 | return output; 172 | } 173 | 174 | 175 | cbuffer PerObject: register(b0) 176 | { 177 | float4x4 WorldViewProj; 178 | }; 179 | 180 | struct VertexShaderInput 181 | { 182 | float4 Position : SV_Position; 183 | float4 Color : COLOR; 184 | }; 185 | 186 | struct VertexShaderOutput 187 | { 188 | float4 Position : SV_Position; 189 | float4 Color : COLOR; 190 | }; 191 | 192 | VertexShaderOutput main(VertexShaderInput input) 193 | { 194 | VertexShaderOutput output = (VertexShaderOutput)0; 195 | output.Position = mul(input.Position, WorldViewProj); 196 | output.Color = input.Color; 197 | return output; 198 | } 199 | 200 | -------------------------------------------------------------------------------- /CrocExplorerWV/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // Dieser Code wurde von einem Tool generiert. 4 | // Laufzeitversion:4.0.30319.42000 5 | // 6 | // Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn 7 | // der Code erneut generiert wird. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace CrocExplorerWV.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.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 | -------------------------------------------------------------------------------- /CrocExplorerWV/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CrocExplorerWV/bin/x86/Release/Be.Windows.Forms.HexBox.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroKilo/CrocExplorerWV/8b313ae1f9a634ecc1ae9aa0d6bf8d4aff27efa5/CrocExplorerWV/bin/x86/Release/Be.Windows.Forms.HexBox.dll -------------------------------------------------------------------------------- /CrocExplorerWV/bin/x86/Release/CrocExplorerWV.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroKilo/CrocExplorerWV/8b313ae1f9a634ecc1ae9aa0d6bf8d4aff27efa5/CrocExplorerWV/bin/x86/Release/CrocExplorerWV.exe -------------------------------------------------------------------------------- /CrocExplorerWV/bin/x86/Release/CrocExplorerWV.exe.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /CrocExplorerWV/bin/x86/Release/SharpDX.D3DCompiler.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroKilo/CrocExplorerWV/8b313ae1f9a634ecc1ae9aa0d6bf8d4aff27efa5/CrocExplorerWV/bin/x86/Release/SharpDX.D3DCompiler.dll -------------------------------------------------------------------------------- /CrocExplorerWV/bin/x86/Release/SharpDX.DXGI.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroKilo/CrocExplorerWV/8b313ae1f9a634ecc1ae9aa0d6bf8d4aff27efa5/CrocExplorerWV/bin/x86/Release/SharpDX.DXGI.dll -------------------------------------------------------------------------------- /CrocExplorerWV/bin/x86/Release/SharpDX.Desktop.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroKilo/CrocExplorerWV/8b313ae1f9a634ecc1ae9aa0d6bf8d4aff27efa5/CrocExplorerWV/bin/x86/Release/SharpDX.Desktop.dll -------------------------------------------------------------------------------- /CrocExplorerWV/bin/x86/Release/SharpDX.Direct2D1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroKilo/CrocExplorerWV/8b313ae1f9a634ecc1ae9aa0d6bf8d4aff27efa5/CrocExplorerWV/bin/x86/Release/SharpDX.Direct2D1.dll -------------------------------------------------------------------------------- /CrocExplorerWV/bin/x86/Release/SharpDX.Direct3D11.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroKilo/CrocExplorerWV/8b313ae1f9a634ecc1ae9aa0d6bf8d4aff27efa5/CrocExplorerWV/bin/x86/Release/SharpDX.Direct3D11.dll -------------------------------------------------------------------------------- /CrocExplorerWV/bin/x86/Release/SharpDX.Mathematics.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroKilo/CrocExplorerWV/8b313ae1f9a634ecc1ae9aa0d6bf8d4aff27efa5/CrocExplorerWV/bin/x86/Release/SharpDX.Mathematics.dll -------------------------------------------------------------------------------- /CrocExplorerWV/bin/x86/Release/SharpDX.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroKilo/CrocExplorerWV/8b313ae1f9a634ecc1ae9aa0d6bf8d4aff27efa5/CrocExplorerWV/bin/x86/Release/SharpDX.dll -------------------------------------------------------------------------------- /CrocExplorerWV/bin/x86/Release/res/default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroKilo/CrocExplorerWV/8b313ae1f9a634ecc1ae9aa0d6bf8d4aff27efa5/CrocExplorerWV/bin/x86/Release/res/default.png -------------------------------------------------------------------------------- /CrocExplorerWV/dll/SharpDX.D3DCompiler.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroKilo/CrocExplorerWV/8b313ae1f9a634ecc1ae9aa0d6bf8d4aff27efa5/CrocExplorerWV/dll/SharpDX.D3DCompiler.dll -------------------------------------------------------------------------------- /CrocExplorerWV/dll/SharpDX.D3DCompiler.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroKilo/CrocExplorerWV/8b313ae1f9a634ecc1ae9aa0d6bf8d4aff27efa5/CrocExplorerWV/dll/SharpDX.D3DCompiler.pdb -------------------------------------------------------------------------------- /CrocExplorerWV/dll/SharpDX.DXGI.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroKilo/CrocExplorerWV/8b313ae1f9a634ecc1ae9aa0d6bf8d4aff27efa5/CrocExplorerWV/dll/SharpDX.DXGI.dll -------------------------------------------------------------------------------- /CrocExplorerWV/dll/SharpDX.DXGI.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroKilo/CrocExplorerWV/8b313ae1f9a634ecc1ae9aa0d6bf8d4aff27efa5/CrocExplorerWV/dll/SharpDX.DXGI.pdb -------------------------------------------------------------------------------- /CrocExplorerWV/dll/SharpDX.Desktop.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroKilo/CrocExplorerWV/8b313ae1f9a634ecc1ae9aa0d6bf8d4aff27efa5/CrocExplorerWV/dll/SharpDX.Desktop.dll -------------------------------------------------------------------------------- /CrocExplorerWV/dll/SharpDX.Desktop.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroKilo/CrocExplorerWV/8b313ae1f9a634ecc1ae9aa0d6bf8d4aff27efa5/CrocExplorerWV/dll/SharpDX.Desktop.pdb -------------------------------------------------------------------------------- /CrocExplorerWV/dll/SharpDX.Direct2D1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroKilo/CrocExplorerWV/8b313ae1f9a634ecc1ae9aa0d6bf8d4aff27efa5/CrocExplorerWV/dll/SharpDX.Direct2D1.dll -------------------------------------------------------------------------------- /CrocExplorerWV/dll/SharpDX.Direct2D1.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroKilo/CrocExplorerWV/8b313ae1f9a634ecc1ae9aa0d6bf8d4aff27efa5/CrocExplorerWV/dll/SharpDX.Direct2D1.pdb -------------------------------------------------------------------------------- /CrocExplorerWV/dll/SharpDX.Direct3D11.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroKilo/CrocExplorerWV/8b313ae1f9a634ecc1ae9aa0d6bf8d4aff27efa5/CrocExplorerWV/dll/SharpDX.Direct3D11.dll -------------------------------------------------------------------------------- /CrocExplorerWV/dll/SharpDX.Direct3D11.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroKilo/CrocExplorerWV/8b313ae1f9a634ecc1ae9aa0d6bf8d4aff27efa5/CrocExplorerWV/dll/SharpDX.Direct3D11.pdb -------------------------------------------------------------------------------- /CrocExplorerWV/dll/SharpDX.Mathematics.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroKilo/CrocExplorerWV/8b313ae1f9a634ecc1ae9aa0d6bf8d4aff27efa5/CrocExplorerWV/dll/SharpDX.Mathematics.dll -------------------------------------------------------------------------------- /CrocExplorerWV/dll/SharpDX.Mathematics.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroKilo/CrocExplorerWV/8b313ae1f9a634ecc1ae9aa0d6bf8d4aff27efa5/CrocExplorerWV/dll/SharpDX.Mathematics.pdb -------------------------------------------------------------------------------- /CrocExplorerWV/dll/SharpDX.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroKilo/CrocExplorerWV/8b313ae1f9a634ecc1ae9aa0d6bf8d4aff27efa5/CrocExplorerWV/dll/SharpDX.dll -------------------------------------------------------------------------------- /CrocExplorerWV/dll/SharpDX.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroKilo/CrocExplorerWV/8b313ae1f9a634ecc1ae9aa0d6bf8d4aff27efa5/CrocExplorerWV/dll/SharpDX.pdb -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Croc Explorer by Warranty Voider 2 | 3 | a tool to explore the game content of the game Croc: The Legend of Gobbos 4 | 5 | Features: 6 | 7 | - browse wad files 8 | - on the fly RLE de/compression 9 | - raw import/export for wad files 10 | - preview/import/export for pix files as png 11 | - preview/export of models 12 | - preview/export/import of sounds 13 | 14 | most information taken from: https://web.archive.org/web/20140708201323/http://www.epiczen.net/crocfileformats.html --------------------------------------------------------------------------------