Skip to content

Development : Custom Texture FIle Format

KillzXGaming edited this page Aug 4, 2019 · 3 revisions

A template for a custom texture file

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Toolbox.Library;
using Toolbox.Library.Forms;
using Toolbox.Library.IO;

namespace FirstPlugin
{
    //An example of a texture container that holds multiple textures
    public class TexContainer : TreeNodeFile, IFileFormat
    {
        public FileType FileType { get; set; } = FileType.Image;

        public bool CanSave { get; set; };

        public string[] Description { get; set; } = new string[] { "TEX" };
        public string[] Extension { get; set; } = new string[] { "*.tex" };
        public string FileName { get; set; }
        public string FilePath { get; set; } 

        //Stores compression info from being opened (done automaitcally)
        public IFileInfo IFileInfo { get; set; }

        //Check how the file wil be opened
        public bool Identify(System.IO.Stream stream)
        {
            return Utils.HasExtension(FileName, ".tex");
        }

        //A Type list for custom types
        //With this you can add in classes with IFileMenuExtension to add menus for this format
        public Type[] Types
        {
            get
            {
                List<Type> types = new List<Type>();
                return types.ToArray();
            }
        }

        public void Load(System.IO.Stream stream)
        {
            //Set this if you want to save the file format
            CanSave = true;

            //You can add a FileReader with Toolbox.Library.IO namespace
            using (var reader = new FileReader(stream))
            {
                //Lets pretend to parse a file as an example
                uint textureCount = reader.ReadUInt32();
                for (int i = 0; i < textureCount; i++)
                {
                    Texture tex = new Texture();
                    tex.Width = reader.ReadUInt32();
                    tex.Height = reader.ReadUInt32();
                    tex.MipCount = reader.ReadUInt32();
                    tex.Text = reader.ReadZeroTerminatedString();

                    //Lets pretend this is a gamecube format
                    //Those tend to commonly use shared formats
                    var Format = reader.ReadEnum<Decode_Gamecube.TextureFormats>(false);

                    //Turn this format into a common format used by this tool
                     tex.Format = Decode_Gamecube.ToGenericFormat(Format);

                    //Lets set our method of decoding
                    tex.PlatformSwizzle = PlatformSwizzle.Platform_Gamecube;

                    //Make sure to load the image data
                    int ImageSize = reader.ReadInt32();
                    tex.ImageData = reader.ReadBytes(ImageSize);

                    //Everything is ready. Lets add to the file tree
                    Nodes.Add(tex);
                }
            }
        }

        public byte[] Save()
        {
            return null;
        }

        public void Unload()
        {

        }

        public class Texture : STGenericTexture
        {
            public byte[] ImageData;

            //A list of supported formats
            //This gets used in the re encode option
            public override TEX_FORMAT[] SupportedFormats
            {
                get
                {
                    return new TEX_FORMAT[]
                    {
                    TEX_FORMAT.C14X2,
                    TEX_FORMAT.C4,
                    TEX_FORMAT.C8,
                    TEX_FORMAT.CMPR,
                    TEX_FORMAT.I4,
                    TEX_FORMAT.L8,
                    TEX_FORMAT.IA4,
                    TEX_FORMAT.IA8,
                    TEX_FORMAT.R5G5B5_UNORM,
                    TEX_FORMAT.R5G5B5A3_UNORM,
                    TEX_FORMAT.R32G32B32A32_FLOAT,
                };
                }
            }

            public override bool CanEdit { get; set; } = false;

            //This gets used in the image editor if the image gets edited
            //This wll not be ran if "CanEdit" is set to false!
            public override void SetImageData(System.Drawing.Bitmap bitmap, int ArrayLevel)
            {

            }

            //Gets the raw image data in bytes
            //Gets decoded automatically
            public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
            {
                return ImageData;
            }


            //This is an event for when the tree is clicked on
            //Load our editor
            public override void OnClick(TreeView treeView)
            {
                //Here we check for an active editor and load a new one if not found
                //This is used when a tree/object editor is used
                ImageEditorBase editor = (ImageEditorBase)LibraryGUI.GetActiveContent(typeof(ImageEditorBase));
                if (editor == null)
                {
                    editor = new ImageEditorBase();
                    editor.Dock = DockStyle.Fill;
                    LibraryGUI.LoadEditor(editor);
                }

                //Load our image and any properties
                //If you don't make a class for properties you can use a generic class provided in STGenericTexture
                editor.LoadProperties(GenericProperties);
                editor.LoadImage(this);
            }
        }
    }
}