From 7bb38c39ad9fbc0cfdf4efa691bf96ee962678a9 Mon Sep 17 00:00:00 2001
From: Alex <41452060+gmh4589@users.noreply.github.com>
Date: Mon, 7 Oct 2024 15:17:54 +0300
Subject: [PATCH] Mips select option, cubemap saving, ATI support

 - Added ATI1 and ATI2 codecs support
 - Added option to change mips count
 - Added option to saving cubemap textures
 - Fix width and height input
 - Rebuild GUI
---
 Form1.Designer.cs | 73 +++++++++++++++++++++++++++++++++++++----------
 Form1.cs          | 33 ++++++++++++++++++---
 README.md         | 22 +++++++-------
 codecList.cs      | 20 +++++++++++++
 4 files changed, 118 insertions(+), 30 deletions(-)

diff --git a/Form1.Designer.cs b/Form1.Designer.cs
index e6f7c07..25861f8 100644
--- a/Form1.Designer.cs
+++ b/Form1.Designer.cs
@@ -41,10 +41,14 @@ private void InitializeComponent()
             this.cInput = new System.Windows.Forms.ComboBox();
             this.label4 = new System.Windows.Forms.Label();
             this.offsetInput = new System.Windows.Forms.NumericUpDown();
+            this.checkBox1 = new System.Windows.Forms.CheckBox();
+            this.label5 = new System.Windows.Forms.Label();
+            this.mipsCount = new System.Windows.Forms.NumericUpDown();
             this.tableLayoutPanel1.SuspendLayout();
             ((System.ComponentModel.ISupportInitialize)(this.wInput)).BeginInit();
             ((System.ComponentModel.ISupportInitialize)(this.hInput)).BeginInit();
             ((System.ComponentModel.ISupportInitialize)(this.offsetInput)).BeginInit();
+            ((System.ComponentModel.ISupportInitialize)(this.mipsCount)).BeginInit();
             this.SuspendLayout();
             // 
             // tableLayoutPanel1
@@ -56,7 +60,7 @@ private void InitializeComponent()
             this.tableLayoutPanel1.Controls.Add(this.okBTN, 1, 0);
             this.tableLayoutPanel1.Controls.Add(this.folderBTN, 0, 1);
             this.tableLayoutPanel1.Controls.Add(this.cancelBTN, 1, 1);
-            this.tableLayoutPanel1.Location = new System.Drawing.Point(10, 215);
+            this.tableLayoutPanel1.Location = new System.Drawing.Point(10, 167);
             this.tableLayoutPanel1.Name = "tableLayoutPanel1";
             this.tableLayoutPanel1.RowCount = 2;
             this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 53F));
@@ -105,9 +109,9 @@ private void InitializeComponent()
             this.label1.AutoSize = true;
             this.label1.Location = new System.Drawing.Point(10, 10);
             this.label1.Name = "label1";
-            this.label1.Size = new System.Drawing.Size(35, 13);
+            this.label1.Size = new System.Drawing.Size(38, 13);
             this.label1.TabIndex = 1;
-            this.label1.Text = "Width";
+            this.label1.Text = "Height";
             // 
             // wInput
             // 
@@ -123,7 +127,7 @@ private void InitializeComponent()
             0,
             0});
             this.wInput.Name = "wInput";
-            this.wInput.Size = new System.Drawing.Size(200, 20);
+            this.wInput.Size = new System.Drawing.Size(97, 20);
             this.wInput.TabIndex = 2;
             this.wInput.Value = new decimal(new int[] {
             1024,
@@ -134,15 +138,15 @@ private void InitializeComponent()
             // label2
             // 
             this.label2.AutoSize = true;
-            this.label2.Location = new System.Drawing.Point(10, 60);
+            this.label2.Location = new System.Drawing.Point(123, 10);
             this.label2.Name = "label2";
-            this.label2.Size = new System.Drawing.Size(38, 13);
+            this.label2.Size = new System.Drawing.Size(35, 13);
             this.label2.TabIndex = 3;
-            this.label2.Text = "Hieght";
+            this.label2.Text = "Width";
             // 
             // hInput
             // 
-            this.hInput.Location = new System.Drawing.Point(10, 80);
+            this.hInput.Location = new System.Drawing.Point(115, 30);
             this.hInput.Maximum = new decimal(new int[] {
             100000,
             0,
@@ -154,7 +158,7 @@ private void InitializeComponent()
             0,
             0});
             this.hInput.Name = "hInput";
-            this.hInput.Size = new System.Drawing.Size(200, 20);
+            this.hInput.Size = new System.Drawing.Size(97, 20);
             this.hInput.TabIndex = 4;
             this.hInput.Value = new decimal(new int[] {
             1024,
@@ -165,7 +169,7 @@ private void InitializeComponent()
             // label3
             // 
             this.label3.AutoSize = true;
-            this.label3.Location = new System.Drawing.Point(10, 110);
+            this.label3.Location = new System.Drawing.Point(12, 53);
             this.label3.Name = "label3";
             this.label3.Size = new System.Drawing.Size(38, 13);
             this.label3.TabIndex = 5;
@@ -175,7 +179,7 @@ private void InitializeComponent()
             // 
             this.cInput.FlatStyle = System.Windows.Forms.FlatStyle.System;
             this.cInput.FormattingEnabled = true;
-            this.cInput.Location = new System.Drawing.Point(10, 130);
+            this.cInput.Location = new System.Drawing.Point(10, 69);
             this.cInput.Name = "cInput";
             this.cInput.Size = new System.Drawing.Size(200, 21);
             this.cInput.TabIndex = 6;
@@ -183,7 +187,7 @@ private void InitializeComponent()
             // label4
             // 
             this.label4.AutoSize = true;
-            this.label4.Location = new System.Drawing.Point(10, 160);
+            this.label4.Location = new System.Drawing.Point(12, 93);
             this.label4.Name = "label4";
             this.label4.Size = new System.Drawing.Size(35, 13);
             this.label4.TabIndex = 7;
@@ -191,21 +195,56 @@ private void InitializeComponent()
             // 
             // offsetInput
             // 
-            this.offsetInput.Location = new System.Drawing.Point(10, 180);
+            this.offsetInput.Location = new System.Drawing.Point(10, 109);
             this.offsetInput.Maximum = new decimal(new int[] {
             1410065408,
             2,
             0,
             0});
             this.offsetInput.Name = "offsetInput";
-            this.offsetInput.Size = new System.Drawing.Size(200, 20);
+            this.offsetInput.Size = new System.Drawing.Size(97, 20);
             this.offsetInput.TabIndex = 8;
             // 
+            // checkBox1
+            // 
+            this.checkBox1.AutoSize = true;
+            this.checkBox1.Location = new System.Drawing.Point(13, 144);
+            this.checkBox1.Name = "checkBox1";
+            this.checkBox1.Size = new System.Drawing.Size(81, 17);
+            this.checkBox1.TabIndex = 9;
+            this.checkBox1.Text = "Is cubemap";
+            this.checkBox1.UseVisualStyleBackColor = true;
+            this.checkBox1.CheckedChanged += new System.EventHandler(this.checkBox1_CheckedChanged);
+            // 
+            // label5
+            // 
+            this.label5.AutoSize = true;
+            this.label5.Location = new System.Drawing.Point(123, 93);
+            this.label5.Name = "label5";
+            this.label5.Size = new System.Drawing.Size(59, 13);
+            this.label5.TabIndex = 10;
+            this.label5.Text = "Mips count";
+            // 
+            // mipsCount
+            // 
+            this.mipsCount.Location = new System.Drawing.Point(115, 110);
+            this.mipsCount.Maximum = new decimal(new int[] {
+            16,
+            0,
+            0,
+            0});
+            this.mipsCount.Name = "mipsCount";
+            this.mipsCount.Size = new System.Drawing.Size(97, 20);
+            this.mipsCount.TabIndex = 11;
+            // 
             // Form1
             // 
             this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
-            this.ClientSize = new System.Drawing.Size(224, 301);
+            this.ClientSize = new System.Drawing.Size(224, 250);
+            this.Controls.Add(this.mipsCount);
+            this.Controls.Add(this.label5);
+            this.Controls.Add(this.checkBox1);
             this.Controls.Add(this.offsetInput);
             this.Controls.Add(this.label4);
             this.Controls.Add(this.cInput);
@@ -221,6 +260,7 @@ private void InitializeComponent()
             ((System.ComponentModel.ISupportInitialize)(this.wInput)).EndInit();
             ((System.ComponentModel.ISupportInitialize)(this.hInput)).EndInit();
             ((System.ComponentModel.ISupportInitialize)(this.offsetInput)).EndInit();
+            ((System.ComponentModel.ISupportInitialize)(this.mipsCount)).EndInit();
             this.ResumeLayout(false);
             this.PerformLayout();
 
@@ -241,6 +281,9 @@ private void InitializeComponent()
         private System.Windows.Forms.ComboBox cInput;
         private System.Windows.Forms.Label label4;
         private System.Windows.Forms.NumericUpDown offsetInput;
+        private System.Windows.Forms.CheckBox checkBox1;
+        private System.Windows.Forms.Label label5;
+        private System.Windows.Forms.NumericUpDown mipsCount;
     }
 }
 
diff --git a/Form1.cs b/Form1.cs
index 3fddb4f..a5cc1fc 100644
--- a/Form1.cs
+++ b/Form1.cs
@@ -9,6 +9,7 @@ public partial class Form1 : Form
     {
         private string fileName = string.Empty;
         private CodecList codecList;
+        bool isCubemap = false;
 
         public Form1()
         {
@@ -70,16 +71,32 @@ private void dds_file_save(string codec_name, string file_name="temp")
                 byte[] codec_data = codecList.GetCodecData(codec_name);
                 byte[] name_codec = codecList.GetCodecName(codec_name);
                 int codec_data_len = codec_data.Length;
+                int linear_size = 0; 
+                int mips_count = (int)mipsCount.Value; 
+                
+                if (x > y) {
+                    linear_size = x;   
+                } else {
+                    linear_size = y; 
+                }
 
-                using (FileStream ddsFile = new FileStream("out\\" + file_name + ".dds", FileMode.Create, FileAccess.Write))
+                if (isCubemap)
+                {
+                    codec_data[25] = 0xFE;
+                } else {
+                    codec_data[25] = 0x00;
+                }
+
+                    using (FileStream ddsFile = new FileStream("out\\" + file_name + ".dds", FileMode.Create, FileAccess.Write))
                 {
                     ddsFile.Write(new byte[] { 0x44, 0x44, 0x53, 0x20, 0x7C, 0x00, 0x00, 0x00 }, 0, 8); // DDS Header
                     ddsFile.Write(new byte[] { keys[0], pixel_format[0], depth[0], 0x00 }, 0, 4);
                     ddsFile.Write(BitConverter.GetBytes(x), 0, 4); // Height
                     ddsFile.Write(BitConverter.GetBytes(y), 0, 4); // Width
-                    ddsFile.Write(BitConverter.GetBytes(y), 0, 4); // Linear size
-                    ddsFile.Write(new byte[] { 0x01 }, 0, 1);
-                    ddsFile.Write(new byte[51], 0, 51);
+                    ddsFile.Write(BitConverter.GetBytes(linear_size), 0, 4); // Linear size
+                    ddsFile.Write(new byte[] { 0x01, 0x00, 0x00, 0x00 }, 0, 4);
+                    ddsFile.Write(BitConverter.GetBytes(mips_count), 0, 1);
+                    ddsFile.Write(new byte[47], 0, 47);
                     ddsFile.Write(new byte[] { 0x20, 0x00, 0x00, 0x00 }, 0, 4);
                     ddsFile.Write(rgb, 0, 4);
                     ddsFile.Write(name_codec, 0, 4);
@@ -127,6 +144,14 @@ private void cancelBTN_Click(object sender, EventArgs e)
                 Console.WriteLine(codec);
                 this.dds_file_save(codec, codec);
             }
+
+            MessageBox.Show("All formats are saved!", "INFO", MessageBoxButtons.OK, MessageBoxIcon.Warning);
         }
+
+        private void checkBox1_CheckedChanged(object sender, EventArgs e)
+        {
+            isCubemap = !isCubemap;
+        }
+
     }
 }
diff --git a/README.md b/README.md
index 5070c2e..86c9f8e 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,11 @@
-# dds_header_generator
-Tools for generating headers to DDS textures files from any games
-
-USAGE:
-Run EXE file (download from release)
-Press open file and select a file
-Select a parametrs to cut texture from your file (offset, height, width and codec)
-Press SAVE button
-Near to EXE file create file temp.dds
-Open temp.dds with any texture veiwer (for example XnView)
-If result not good, save file another time with other parametrs
+# dds_header_generator
+Tools for generating headers to DDS textures files from any games
+
+USAGE:
+Run EXE file (download from release)
+Press open file and select a file
+Select a parametrs to cut texture from your file (offset, height, width and codec)
+Press SAVE button
+Near to EXE file create file temp.dds
+Open temp.dds with any texture veiwer (for example XnView)
+If result not good, save file another time with other parametrs
diff --git a/codecList.cs b/codecList.cs
index 05c71a9..4d73b89 100644
--- a/codecList.cs
+++ b/codecList.cs
@@ -29,6 +29,26 @@ public CodecList()
                     {"pixel_format", new byte[] {0x10}},
                     {"rgb", new byte[] {0x04, 0x00, 0x00, 0x00}}
             }
+        },
+            {"ATI1", new Dictionary<string, byte[]>
+                {
+                    {"codec", new byte[] {0x41, 0x54, 0x49, 0x31}},
+                    {"codec_data", new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+                    {"depth", new byte[] {0x0a}},
+                    {"keys", new byte[] {0x07}},
+                    {"pixel_format", new byte[] {0x10}},
+                    {"rgb", new byte[] {0x04, 0x00, 0x00, 0x00}}
+            }
+        },
+            {"ATI2", new Dictionary<string, byte[]>
+                {
+                    {"codec", new byte[] {0x41, 0x54, 0x49, 0x32}},
+                    {"codec_data", new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+                    {"depth", new byte[] {0x0a}},
+                    {"keys", new byte[] {0x07}},
+                    {"pixel_format", new byte[] {0x10}},
+                    {"rgb", new byte[] {0x04, 0x00, 0x00, 0x00}}
+            }
         },
             {"B4G4R4A4_UNORM", new Dictionary<string, byte[]>
                 {