Error() public method

Logs an error
public Error ( String message ) : void
message String The message to explain the error
return void
        public static bool Read(RAFFileListEntry file, ref InibinFile data, Logger logger)
        {
            bool result = true;

            logger.Event("Reading inibin: " + file.FileName);

            try
            {
                // Get the data from the archive
                MemoryStream myInput = new MemoryStream( file.GetContent() );
                result = ReadCharacterInibin(myInput, ref data, logger);

                int end = file.FileName.LastIndexOf("/");
                String directory = file.FileName.Substring(0, end);
                String archive = file.RAFArchive.RAFFilePath;
                archive = archive.Replace("\\", "/");
                end = archive.LastIndexOf("/");
                archive = archive.Substring(0, end);

                data.directory = new DirectoryInfo(archive + "/" + directory);
                myInput.Close();
            }
            catch(Exception e)
            {
                logger.Error("Unable to open memory stream: " + file.FileName);
                logger.Error(e.Message);
                result = false;
            }

            return result;
        }
        public static bool Read(int skin, IFileEntry file,
            ref Dictionary<String, String> animations, Logger logger)
        {
            bool result = true;

            logger.Event("Parsing animation list: " + file.FileName );

            try
            {
                // Get the data from the archive
                MemoryStream myInput = new MemoryStream( file.GetContent() );
                StreamReader reader = new StreamReader(myInput);

                ParseAnimations(skin, reader, ref animations);

                reader.Close();
                myInput.Close();
            }
            catch
            {
                logger.Error("Failed to parse animation list: " + file.FileName);

                result = false;
                animations.Clear();
            }

            return result;
        }
Beispiel #3
0
        //Helper Functions.
        //(Because nested Try/Catch looks nasty in one function block.)
        private static bool ReadBinary(MemoryStream input, ref SKLFile data, Logger logger)
        {
            bool result = true;

            try
            {
                BinaryReader myFile = new BinaryReader(input, Encoding.ASCII);
                result = ReadData(myFile, ref data, logger);
                myFile.Close();
            }
            catch (Exception e)
            {
                logger.Error("Unable to open binary reader.");
                logger.Error(e.Message);
                result = false;
            }

            return result;
        }
Beispiel #4
0
        /// <summary>
        /// Read in binary .anm file from RAF.
        /// </summary>
        /// <param name="file">The file.</param>
        /// <param name="data">The contents of the file are stored in here.</param>
        /// <returns></returns>
        public static bool Read(RAFFileListEntry file, ref ANMFile data, Logger logger)
        {
            bool result = true;

            logger.Event("Reading anm: " + file.FileName);

            try
            {
                // Get the data from the archive
                MemoryStream myInput = new MemoryStream( file.GetContent() );
                result = ReadBinary(myInput, ref data, logger);
                myInput.Close();
            }
            catch(Exception e)
            {
                logger.Error("Unable to open memory stream: " + file.FileName);
                logger.Error(e.Message);
                result = false;
            }

            return result;
        }
        //
        // Helper creation function.
        //
        private bool Create(List<float> vertexPositions, List<float> vertexNormals,
            List<float> vertexTextureCoordinates, List<uint> indices, Logger logger)
        {
            bool result = true;

            logger.Event("Creating OpenGL static model.");

            numIndices = indices.Count;

            // Create Vertex Array Object
            if (result == true)
            {
                GL.GenVertexArrays(1, out vao);
            }

            ErrorCode error = GL.GetError();
            if (error != ErrorCode.NoError)
            {
                result = false;
            }

            // Bind VAO
            if (result == true)
            {
                GL.BindVertexArray(vao);
            }

            // Create the VBOs
            int[] buffers = new int[4];
            if (result == true)
            {
                GL.GenBuffers(4, buffers);
            }

            // Check for errors
            error = GL.GetError();
            if (error != ErrorCode.NoError)
            {
                result = false;
            }

            // Store data and bind vertex buffer.
            if (result == true)
            {
                vertexPositionBuffer = buffers[0];
                vertexNormalBuffer = buffers[1];
                vertexTextureCoordinateBuffer = buffers[2];
                indexBuffer = buffers[3];

                GL.BindBuffer(BufferTarget.ArrayBuffer, vertexPositionBuffer);
            }

            //
            //
            // Set vertex data.
            //
            //
            if (result == true)
            {
                GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vertexPositions.Count * sizeof(float)),
                    vertexPositions.ToArray(), BufferUsageHint.StaticDraw);
            }

            // Check for errors.
            error = GL.GetError();
            if (error != ErrorCode.NoError)
            {
                result = false;
            }

            // Put vertices into attribute slot 0.
            if (result == true)
            {
                GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float,
                    false, 0, 0);
            }

            error = GL.GetError();
            if (error != ErrorCode.NoError)
            {
                result = false;
            }

            // Enable the attribute index.
            if (result == true)
            {
                GL.EnableVertexAttribArray(0);
            }

            //
            //
            // Bind normal buffer.
            //
            //
            if (result == true)
            {
                GL.BindBuffer(BufferTarget.ArrayBuffer, vertexNormalBuffer);
            }

            // Set normal data.
            if (result == true)
            {
                GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vertexNormals.Count * sizeof(float)),
                    vertexNormals.ToArray(), BufferUsageHint.StaticDraw);
            }

            // Check for errors.
            error = GL.GetError();
            if (error != ErrorCode.NoError)
            {
                result = false;
            }

            // Put normals into attribute slot 1.
            if (result == true)
            {
                GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float,
                    false, 0, 0);
            }

            error = GL.GetError();
            if (error != ErrorCode.NoError)
            {
                result = false;
            }

            // Enable the attribute index.
            if (result == true)
            {
                GL.EnableVertexAttribArray(1);
            }

            //
            //
            // Bind texture cordinates buffer.
            //
            //
            if (result == true)
            {
                GL.BindBuffer(BufferTarget.ArrayBuffer, vertexTextureCoordinateBuffer);
            }

            // Set Texture Coordinate Data
            if (result == true)
            {
                GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vertexTextureCoordinates.Count * sizeof(float)),
                    vertexTextureCoordinates.ToArray(), BufferUsageHint.StaticDraw);
            }

            error = GL.GetError();
            if (error != ErrorCode.NoError)
            {
                result = false;
            }

            // Put texture coords into attribute slot 2.
            if (result == true)
            {
                GL.VertexAttribPointer(2, 2, VertexAttribPointerType.Float,
                    false, 0, 0);
            }

            error = GL.GetError();
            if (error != ErrorCode.NoError)
            {
                result = false;
            }

            // Enable the attribute index.
            if (result == true)
            {
                GL.EnableVertexAttribArray(2);
            }

            // Bind index buffer.
            if (result == true)
            {
                GL.BindBuffer(BufferTarget.ElementArrayBuffer, indexBuffer);
            }

            // Set index data.
            if (result == true)
            {
                GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(indices.Count * sizeof(uint)),
                    indices.ToArray(), BufferUsageHint.StaticDraw);
            }

            error = GL.GetError();
            if (error != ErrorCode.NoError)
            {
                result = false;
            }

            // Unbind VAO from pipeline.
            if (result == true)
            {
                GL.BindVertexArray(0);
            }
            else
            {
                logger.Error("Failed to create OpenGL static model.");
            }

            return result;
        }
Beispiel #6
0
        private static bool ReadData(BinaryReader file, ref ANMFile data, Logger logger)
        {
            bool result = true;

            try
            {
                // File Header Information.
                data.id = new String(file.ReadChars(ANMFile.ID_SIZE));
                data.version = file.ReadUInt32();

                // Version 0, 1, 2, 3 Code
                if (data.version == 0 ||
                    data.version == 1 ||
                    data.version == 2 ||
                    data.version == 3)
                {
                    //
                    // Header information specific to these versions.
                    //

                    data.magic = file.ReadUInt32();
                    data.numberOfBones = file.ReadUInt32();
                    data.numberOfFrames = file.ReadUInt32();
                    data.playbackFPS = file.ReadUInt32();

                    // Read in all the bones
                    for (UInt32 i = 0; i < data.numberOfBones; ++i)
                    {
                        ANMBone bone = new ANMBone();
                        bone.name = new String(file.ReadChars(ANMBone.BONE_NAME_LENGTH));
                        bone.name = RemoveAnimationNamePadding(bone.name);
                        bone.name = bone.name.ToLower();

                        // Unknown
                        file.ReadUInt32();

                        // For each bone, read in its value at each frame in the animation.
                        for (UInt32 j = 0; j < data.numberOfFrames; ++j)
                        {
                            ANMFrame frame = new ANMFrame();

                            // Read in the frame's quaternion.
                            frame.orientation[0] = file.ReadSingle(); // x
                            frame.orientation[1] = file.ReadSingle(); // y
                            frame.orientation[2] = file.ReadSingle(); // z
                            frame.orientation[3] = file.ReadSingle(); // w

                            // Read in the frame's position.
                            frame.position[0] = file.ReadSingle(); // x
                            frame.position[1] = file.ReadSingle(); // y
                            frame.position[2] = file.ReadSingle(); // z

                            bone.frames.Add(frame);
                        }

                        data.bones.Add(bone);
                    }
                }
                // Version 4 Code
                else if (data.version == 4)
                {
                    //
                    // Based on the reverse engineering work of Hossein Ahmadi.
                    //
                    // In this version, position vectors and orientation quaternions are
                    // stored separately in sorted, keyed blocks.  The assumption is Riot
                    // is removing duplicate vectors and quaternions by using an indexing scheme
                    // to look up values.
                    //
                    // So, after the header, there are three data sections: a vector section, a quaternion
                    // section, and a look up section.  The number of vectors and quaternions
                    // may not match the expected value based on the number of frames and bones.  However,
                    // the number of look ups should match this value and can be used to create the animation.

                    //
                    // Header information specific to version 4.
                    //

                    data.magic = file.ReadUInt32();

                    // Not sure what any of these mean.
                    float unknown = file.ReadSingle();
                    unknown = file.ReadSingle();
                    unknown = file.ReadSingle();

                    data.numberOfBones = file.ReadUInt32();
                    data.numberOfFrames = file.ReadUInt32();

                    // Time per frame is stored in this file type.  Need to invert it into FPS.
                    data.playbackFPS = (UInt32) Math.Round(1.0f / file.ReadSingle());

                    // These are offsets to specific data sections in the file.
                    UInt32 unknownOffset = file.ReadUInt32();
                    unknownOffset = file.ReadUInt32();
                    unknownOffset = file.ReadUInt32();

                    UInt32 positionOffset = file.ReadUInt32();
                    UInt32 orientationOffset = file.ReadUInt32();
                    UInt32 indexOffset = file.ReadUInt32();

                    // These last three values are confusing.
                    // They aren't a vector and they throw off the offset values
                    // by 12 bytes. Just ignore them and keep reading.
                    unknownOffset = file.ReadUInt32();
                    unknownOffset = file.ReadUInt32();
                    unknownOffset = file.ReadUInt32();

                    //
                    // Vector section.
                    //

                    List<float> positions = new List<float>();
                    UInt32 numberOfPositions = (orientationOffset - positionOffset) / sizeof(float);
                    for (UInt32 i = 0; i < numberOfPositions; ++i)
                    {
                        positions.Add(file.ReadSingle());
                    }

                    //
                    // Quaternion section.
                    //

                    List<float> orientations = new List<float>();
                    UInt32 numberOfOrientations = (indexOffset - orientationOffset) / sizeof(float);
                    for (UInt32 i = 0; i < numberOfOrientations; ++i)
                    {
                        orientations.Add(file.ReadSingle());
                    }

                    //
                    // Offset section.
                    //
                    // Note: Unlike versions 0-3, data in this version is
                    // Frame 1:
                    //      Bone 1:
                    //      Bone 2:
                    // ...
                    // Frame 2:
                    //      Bone 1:
                    // ...
                    //

                    Dictionary<UInt32, ANMBone> boneMap = new Dictionary<UInt32, ANMBone>();
                    for (Int32 i = 0; i < data.numberOfBones; ++i)
                    {
                        //
                        // The first frame is a special case since we are allocating bones
                        // as we read them in.
                        //

                        // Read in the offset data.
                        UInt32 boneID = file.ReadUInt32();
                        UInt16 positionID = file.ReadUInt16();
                        UInt16 unknownIndex = file.ReadUInt16(); // Unknown.
                        UInt16 orientationID = file.ReadUInt16();
                        unknownIndex = file.ReadUInt16(); // Unknown. Seems to always be zero.

                        // Allocate the bone.
                        ANMBone bone = new ANMBone();
                        bone.id = boneID;

                        // Allocate all the frames for the bone.
                        for (int j = 0; j < data.numberOfFrames; ++j)
                        {
                            bone.frames.Add(new ANMFrame());
                        }

                        // Retrieve the data for the first frame.
                        ANMFrame frame = bone.frames[0];
                        frame.position = LookUpVector(positionID, positions);
                        frame.orientation = LookUpQuaternion(orientationID, orientations);

                        // Store the bone in the dictionary by bone ID.
                        boneMap[boneID] = bone;
                    }

                    Int32 currentFrame = 1;
                    Int32 currentBone = 0;

                    UInt32 numberOfLookUps = (data.numberOfFrames - 1) * data.numberOfBones;
                    for (UInt32 i = 0; i < numberOfLookUps; ++i)
                    {
                        //
                        // Normal case for all frames after the first.
                        //

                        // Read in the offset data.

                        UInt32 boneID = file.ReadUInt32();
                        UInt16 positionID = file.ReadUInt16();
                        UInt16 unknownIndex = file.ReadUInt16(); // Unknown.
                        UInt16 orientationID = file.ReadUInt16();
                        unknownIndex = file.ReadUInt16(); // Unknown. Seems to always be zero.

                        // Retrieve the bone from the dictionary.
                        // Note: The bones appear to be in the same order in every frame.  So, a dictionary
                        // isn't exactly needed and you could probably get away with a list.  However, this way
                        // feels safer just in case something ends up being out of order.
                        ANMBone bone = boneMap[boneID];
                        ANMFrame frame = bone.frames[currentFrame];
                        frame.position = LookUpVector(positionID, positions);
                        frame.orientation = LookUpQuaternion(orientationID, orientations);

                        // This loop is slightly ambiguous.
                        //
                        // The problem is previous .anm versions contain data like:
                        // foreach bone
                        //      foreach frame
                        //
                        // However, this version contains data like:
                        // foreach frame
                        //      foreach bone
                        //
                        // So, reading one version is going to be a little goofy.
                        currentBone++;
                        if (currentBone >= data.numberOfBones)
                        {
                            currentBone = 0;
                            currentFrame++;
                        }
                    }

                    // Finally, we need to move all the data from the dictionary into the ANMFile.
                    foreach(var bone in boneMap)
                    {
                        data.bones.Add(bone.Value);
                    }

                    // Currently returning false for this version.  We can not render this version correctly yet.
                    // So, we need to tell the viewer not to try and load it.
                    result = false;
                }
                // Unknown version
                else
                {
                    logger.Error("Unknown anm version: " + data.version);
                    result = false;
                }
            }
            catch(Exception e)
            {
                logger.Error("Anm reading error.");
                logger.Error(e.Message);
                result = false;
            }

            logger.Event("File ID: " + data.id);
            logger.Event("Magic: " + data.magic);
            logger.Event("Version: " + data.version);
            logger.Event("Number of Bones: " + data.numberOfBones);
            logger.Event("Number of Frames: " + data.numberOfFrames);
            logger.Event("Playback FPS: " + data.playbackFPS);

            return result;
        }
Beispiel #7
0
        private static bool ReadData(BinaryReader file, ref SKNFile data, Logger logger)
        {
            bool result = true;

            try
            {
                // File Header Information.
                data.magic       = file.ReadInt32();
                data.version     = file.ReadInt16();
                data.numObjects  = file.ReadInt16();

                if (data.version == 1 || data.version == 2)
                {
                    // Contains material headers.
                    data.numMaterialHeaders = file.ReadInt32();
                    for (int i = 0; i < data.numMaterialHeaders; ++i)
                    {
                        // Read in the headers.
                        SKNMaterial header = new SKNMaterial();

                        header.name = new String(file.ReadChars(SKNMaterial.MATERIAL_NAME_SIZE));
                        header.startVertex = file.ReadInt32();
                        header.numVertices = file.ReadInt32();
                        header.startIndex = file.ReadInt32();
                        header.numIndices = file.ReadInt32();

                        data.materialHeaders.Add(header);
                    }

                    // Read in model data.
                    data.numIndices = file.ReadInt32();
                    data.numVertices = file.ReadInt32();

                    for (int i = 0; i < data.numIndices; ++i)
                    {
                        data.indices.Add(file.ReadInt16());
                    }

                    for (int i = 0; i < data.numVertices; ++i)
                    {
                        SKNVertex vertex = new SKNVertex();

                        vertex.position[0] = file.ReadSingle(); // x
                        vertex.position[1] = file.ReadSingle(); // y
                        vertex.position[2] = file.ReadSingle(); // z

                        for (int j = 0; j < SKNVertex.BONE_INDEX_SIZE; ++j)
                        {
                            int bone = (int)file.ReadByte();
                            vertex.boneIndex[j] = bone;
                        }

                        vertex.weights[0] = file.ReadSingle();
                        vertex.weights[1] = file.ReadSingle();
                        vertex.weights[2] = file.ReadSingle();
                        vertex.weights[3] = file.ReadSingle();

                        vertex.normal[0] = file.ReadSingle(); // x
                        vertex.normal[1] = file.ReadSingle(); // y
                        vertex.normal[2] = file.ReadSingle(); // z

                        vertex.texCoords[0] = file.ReadSingle(); // u
                        vertex.texCoords[1] = file.ReadSingle(); // v

                        data.vertices.Add(vertex);
                    }

                    // Data exclusive to version two.
                    if (data.version == 2)
                    {
                        data.endTab.Add(file.ReadInt32());
                        data.endTab.Add(file.ReadInt32());
                        data.endTab.Add(file.ReadInt32());
                    }
                }
                // Unknown Version
                else
                {
                    logger.Error("Unknown skn version: " + data.version);
                    result = false;
                }
            }
            catch(Exception e)
            {
                logger.Error("Skn reading error.");
                logger.Error(e.Message);
                result = false;
            }

            logger.Event("Magic: " + data.magic);
            logger.Event("Version: " + data.version);
            logger.Event("Number of Objects: " + data.numObjects);
            logger.Event("Number of Material Headers: " + data.numMaterialHeaders);
            logger.Event("Number of Vertices: " + data.numVertices);
            logger.Event("Number of Indices: " + data.numIndices);

            return result;
        }
Beispiel #8
0
        private static bool ReadData(BinaryReader file, ref SKLFile data, Logger logger)
        {
            bool result = true;

            try
            {
                // File Header Information.
                data.id = new String(file.ReadChars(SKLFile.ID_SIZE));
                data.version = file.ReadUInt32();

                if (data.version == 1 || data.version == 2)
                {
                    data.designerID = file.ReadUInt32();

                    // Read in the bones.
                    data.numBones = file.ReadUInt32();
                    for (int i = 0; i < data.numBones; ++i)
                    {
                        SKLBone bone = new SKLBone();

                        bone.name = new String(
                            file.ReadChars(SKLBone.BONE_NAME_SIZE));
                        bone.name = RemoveBoneNamePadding(bone.name);
                        bone.name = bone.name.ToLower();

                        bone.ID = i;
                        bone.parentID = file.ReadInt32();
                        bone.scale = file.ReadSingle();

                        // Read in transform matrix.
                        float[] orientation = new float[SKLBone.ORIENTATION_SIZE];
                        for (int j = 0; j < SKLBone.ORIENTATION_SIZE; ++j)
                        {
                            orientation[j] = file.ReadSingle();
                        }

                        bone.orientation = orientation;

                        // Position from matrix.
                        bone.position[0] = orientation[3];
                        bone.position[1] = orientation[7];
                        bone.position[2] = orientation[11];

                        data.bones.Add(bone);
                    }

                    // Version two contains bone IDs.
                    if (data.version == 2)
                    {
                        data.numBoneIDs = file.ReadUInt32();
                        for (uint i = 0; i < data.numBoneIDs; ++i)
                        {
                            data.boneIDs.Add(file.ReadUInt32());
                        }
                    }
                }
                // Newest version so far.
                else if (data.version == 0)
                {
                    // Header
                    Int16 zero = file.ReadInt16(); // ?

                    data.numBones = (uint)file.ReadInt16();

                    data.numBoneIDs = file.ReadUInt32();
                    Int16 offsetToVertexData = file.ReadInt16(); // Should be 64.

                    int unknown = file.ReadInt16(); // ?

                    int offset1 = file.ReadInt32();
                    int offsetToAnimationIndices = file.ReadInt32();
                    int offset2 = file.ReadInt32();
                    int offset3 = file.ReadInt32();
                    int offsetToStrings = file.ReadInt32();

                    // Not sure what this data represents.
                    // I think it's padding incase more header data is required later.
                    file.BaseStream.Position += 20;

                    file.BaseStream.Position = offsetToVertexData;
                    for (int i = 0; i < data.numBones; ++i)
                    {
                        SKLBone bone = new SKLBone();
                        // The old scale was always 0.1.
                        // For now, just go with it.
                        bone.scale = 0.1f;

                        zero = file.ReadInt16(); // ?
                        bone.ID = file.ReadInt16();
                        bone.parentID = file.ReadInt16();
                        unknown = file.ReadInt16(); // ?

                        int namehash = file.ReadInt32();

                        float twoPointOne = file.ReadSingle();

                        bone.position[0] = file.ReadSingle();
                        bone.position[1] = file.ReadSingle();
                        bone.position[2] = file.ReadSingle();

                        float one = file.ReadSingle(); // ? Maybe scales for X, Y, and Z
                        one = file.ReadSingle();
                        one = file.ReadSingle();

                        bone.orientation[0] = file.ReadSingle();
                        bone.orientation[1] = file.ReadSingle();
                        bone.orientation[2] = file.ReadSingle();
                        bone.orientation[3] = file.ReadSingle();

                        float ctx = file.ReadSingle(); // ctx
                        float cty = file.ReadSingle(); // cty
                        float ctz = file.ReadSingle(); // ctz

                        data.bones.Add(bone);

                        // The rest of the bone data is unknown. Maybe padding?
                        file.BaseStream.Position += 32;
                    }

                    file.BaseStream.Position = offset1;
                    for (int i = 0; i < data.numBones; ++i) // Inds for version 4 animation.
                    {
                        // 8 bytes
                        uint sklID = file.ReadUInt32();
                        uint anmID = file.ReadUInt32();

                        data.boneIDMap[anmID] = sklID;
                    }

                    file.BaseStream.Position = offsetToAnimationIndices;
                    for (int i = 0; i < data.numBoneIDs; ++i) // Inds for animation
                    {
                        // 2 bytes
                        UInt16 boneID = file.ReadUInt16();
                        data.boneIDs.Add(boneID);
                    }

                    file.BaseStream.Position = offsetToStrings;
                    for (int i = 0; i < data.numBones; ++i)
                    {
                        // bone names
                        string name = "";
                        while (name.Contains('\0') == false)
                        {
                            name += new string(file.ReadChars(4));
                        }
                        name = RemoveBoneNamePadding(name);
                        name = name.ToLower();

                        data.bones[i].name = name;
                    }
                }
                // Unknown Version
                else
                {
                    logger.Error("Unknown skl version: " + data.version);
                    result = false;
                }
            }
            catch (Exception e)
            {
                logger.Error("Skl reading error.");
                logger.Error(e.Message);
                result = false;
            }

            logger.Event("File ID: " + data.id);
            logger.Event("Version: " + data.version);
            logger.Event("Designer ID: " + data.designerID);
            logger.Event("Number of Bones: " + data.numBones);
            logger.Event("Number of Bone IDs: " + data.numBoneIDs);

            return result;
        }
Beispiel #9
0
        /// <summary>
        /// Read in binary .dds file from RAF.
        /// </summary>
        /// <param name="file">The file.</param>
        /// <param name="data">The contents of the file are stored in here.</param>
        /// <returns></returns>
        public static bool Read(RAFFileListEntry file, ref Bitmap bitmap, Logger logger)
        {
            bool result = true;

            logger.Event("Reading dds: " + file.FileName);

            try
            {
                // Create image.
                int[] images = new int[1];
                Il.ilGenImages(1, images);

                // Bind image.
                Il.ilBindImage(images[0]);

                // Load the image data into DevIL.
                byte[] data = file.GetContent();
                result = Il.ilLoadL(Il.IL_DDS, data, data.Length);
                if (result == true)
                {
                    int width = Il.ilGetInteger(Il.IL_IMAGE_WIDTH);
                    int height = Il.ilGetInteger(Il.IL_IMAGE_HEIGHT); ;

                    // Create the bitmap.
                    bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
                    Rectangle rect = new Rectangle(0, 0, width, height);

                    // Store the DevIL image data into the bitmap.
                    BitmapData bitmapData = bitmap.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);

                    Il.ilConvertImage(Il.IL_BGRA, Il.IL_UNSIGNED_BYTE);
                    Il.ilCopyPixels(0, 0, 0, width, height, 1, Il.IL_BGRA, Il.IL_UNSIGNED_BYTE, bitmapData.Scan0);

                    bitmap.UnlockBits(bitmapData);
                }

                // Free image.
                Il.ilDeleteImages(1, images);

                if (result == false)
                {
                    throw new System.Exception("Unable to load image data.");
                }
            }
            catch(Exception e)
            {
                logger.Error("Unable to open dds file: " + file.FileName);
                logger.Error(e.Message);
                result = false;
            }

            return result;
        }
        private bool StoreModel(ModelDefinition def, out LOLModel model, Logger logger)
        {
            model = new LOLModel();
            model.skinNumber = def.skin;
            model.animationList = def.anmListKey.ToLower();

            // Find the skn.
            if (skns.ContainsKey(def.skn))
            {
                model.skn = skns[def.skn];
            }
            else
            {
                logger.Error("Unable to find skn file: " + def.skn);
                return false;
            }

            // Find the skl.
            if (skls.ContainsKey(def.skl))
            {
                model.skl = skls[def.skl];
            }
            else
            {
                logger.Error("Unable to find skl file: " + def.skl);
                return false;
            }

            // Find the texture.
            if (textures.ContainsKey(def.tex))
            {
                model.texture = textures[def.tex];
            }
            else
            {
                logger.Error("Unable to find texture file: " + def.tex);
                return false;
            }

            return true;
        }
        private bool StoreAnimations(ref LOLModel model, Logger logger)
        {
            bool result = true;

            Dictionary<String, String> animationStrings =
                new Dictionary<String, String>();

            // Sanity
            if (animationLists.ContainsKey(model.animationList) == true)
            {
                result = ANMListReader.Read(model.skinNumber - 1, // indexing in animations.list assumes the original skin to be -1
                    animationLists[model.animationList], ref animationStrings, logger);
            }
            else
            {
                logger.Error("Unable to find animation list: " + model.animationList);
            }

            if (result == true)
            {
                // Store the animations in the model.
                foreach (var a in animationStrings)
                {
                    if (animations.ContainsKey(a.Value) == true)
                    {
                        if (model.animations.ContainsKey(a.Key) == false)
                        {
                            model.animations.Add(a.Key, animations[a.Value]);
                        }
                        else
                        {
                            logger.Error("Duplicate animation: " + a.Key);
                        }
                    }
                    else
                    {
                        logger.Error("Unable to find animation: " + a.Value);
                    }
                }
            }

            return result;
        }
        // Replacement for individual raf reading and individual filetype searching
        // Provide the directory of RADS\projects\lol_game_client\filearchives or the equivalent
        private bool ReadRAFs(DirectoryInfo dir, Logger logger)
        {
            try
            {
                RAFMasterFileList rafFiles = new RAFMasterFileList(dir.FullName);
                logger.Event("Opening the 'filearchives' directory: " + dir.FullName);
                foreach (RAFMasterFileList.RAFSearchResult result in rafFiles.SearchFileEntries(new string[] { ".dds", ".skn", ".skl", ".inibin", "animations.list", ".anm" }, RAFMasterFileList.RAFSearchType.All))
                {
                    RAFFileListEntry e = result.value;

                    // Split off the actual file name from the full path
                    String name = e.FileName.Substring(e.FileName.LastIndexOf('/') + 1).ToLower();

                    switch (result.searchPhrase)
                    {
                        case ".dds":
                            // Try to parse out unwanted textures.
                            if (!e.FileName.ToLower().Contains("loadscreen") &&
                                !e.FileName.ToLower().Contains("circle") &&
                                !e.FileName.ToLower().Contains("square") &&
                                e.FileName.ToLower().Contains("data") &&
                                e.FileName.ToLower().Contains("characters"))
                            {
                                // Check that the file isn't already in the dictionary
                                if (!textures.ContainsKey(name))
                                {
                                    textures.Add(name, e);
                                }
                                else
                                {
                                    logger.Warning("Duplicate texture " + name + ": " + e.FileName);
                                }
                            }
                            break;

                        case ".skn":
                            if (!skns.ContainsKey(name))
                            {
                                skns.Add(name, e);
                            }
                            else
                            {
                                logger.Warning("Duplicate skn " + name + ": " + e.FileName);
                            }
                            break;

                        case ".skl":
                            if (!skls.ContainsKey(name))
                            {
                                skls.Add(name, e);
                            }
                            else
                            {
                                logger.Warning("Duplicate skn " + name + ": " + e.FileName);
                            }
                            break;

                        case ".inibin":
                            // Try to only read champion inibins
                            if (e.FileName.ToLower().Contains("data") &&
                                e.FileName.ToLower().Contains("characters"))
                            {
                                inibins.Add(e);
                            }
                            else
                            {
                                logger.Warning("Excluding inibin " + name + ": " + e.FileName);
                            }
                            break;

                        case "animations.list":
                            // Riot changed their directory structure for some skins.
                            // Originally, champion Animation.list files were stored in a directory structure like
                            // "*/ChampionName/Animation.list".  Now, some are stored like
                            // "*/ChampionName/Skins/Skin01/Animation.list".

                            if (e.FileName.ToLower().Contains("skin") == false &&
                                e.FileName.ToLower().Contains("base") == false)
                            {
                                // Original Case.

                                // Remove the file name.
                                name = e.FileName.Remove(e.FileName.LastIndexOf('/'));

                                // Remove proceeding directories to get the parent directory
                                name = name.Substring(name.LastIndexOf('/') + 1).ToLower();
                            }
                            else
                            {
                                // Newer Case.
                                string path = e.FileName.ToString();
                                string[] splitPath = path.Split('/');

                                // Sanity
                                if (splitPath.Length > 3)
                                {
                                    name = splitPath[splitPath.Length - 4].ToLower();
                                }
                            }

                            // Store.
                            if (!animationLists.ContainsKey(name))
                            {
                                animationLists.Add(name, e);
                            }
                            else
                            {
                                logger.Warning("Duplicate animation list " + name + ": " + e.FileName);
                            }
                            break;

                        case ".anm":
                            // Remove the .anm extension.
                            name = name.Remove(name.Length - 4);

                            if (!animations.ContainsKey(name))
                            {
                                animations.Add(name, e);
                            }
                            else
                            {
                                logger.Warning("Duplicate anm " + name + ": " + e.FileName);
                            }
                            break;
                    }
                }

            }
            catch (Exception e)
            {
                // Something went wrong. Most likely the RAF read failed due to a bad directory.
                logger.Error("Failed to open RAFs");
                logger.Error(e.Message);
                return false;
            }

            return true;
        }
        private void GenerateModelDefinitions(Logger logger)
        {
            foreach (RAFFileListEntry f in inibins)
            {
                InibinFile iniFile = new InibinFile();
                bool readResult = InibinReader.Read(f, ref iniFile, logger);

                if (readResult == true)
                {
                    // Add the models from this .inibin file
                    List<ModelDefinition> modelDefs = iniFile.GetModelStrings();
                    for (int j = 0; j < modelDefs.Count; ++j)
                    {
                        // Name the model after the parent directory
                        // of the .inibin plus the name from the .inibin.
                        // Some things overlap without both.

                        string path = f.FileName;
                        string[] splitPath = path.Split('/');

                        string directoryName = splitPath[splitPath.Length - 2];
                        if (directoryName.Contains("Base") == true ||
                            directoryName.Contains("Skin") == true)
                        {
                            // The directory structure for this case will be something like
                            // "*/ChampionName/Skins/Base/".
                            // We just want the "ChampionName".
                            directoryName = splitPath[splitPath.Length - 4];
                        }

                        // Sometimes the name from the .inibin file is "".
                        // So, just name it after the directory
                        String name = modelDefs[j].name;
                        if (name == "")
                        {
                            name = directoryName + "/" + directoryName;
                        }
                        else
                        {
                            name = directoryName + "/" + name;
                        }

                        try
                        {
                            LOLModel model;
                            bool storeResult = StoreModel(modelDefs[j], out model, logger);

                            if (storeResult == true)
                            {
                                // Try to store animations for model as well
                                storeResult = StoreAnimations(ref model, logger);
                            }

                            if (storeResult == true)
                            {
                                if (models.ContainsKey(name) == false)
                                {
                                    logger.Event("Adding model definition: " + name);
                                    models.Add(name, model);
                                }
                                else
                                {
                                    logger.Warning("Duplicate model definition: " + name);
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            logger.Error("Unable to store model definition: " + name);
                            logger.Error(e.Message);
                        }
                    }
                }
            }
        }
        public bool Read(Logger logger)
        {
            bool result = true;

            // Clear old data.

            models.Clear();

            skls.Clear();
            skns.Clear();
            textures.Clear();

            inibins.Clear();
            animationLists.Clear();
            animations.Clear();

            DirectoryInfo rootDir = null;
            try
            {
                logger.Event("Reading models from: " + Root);
                rootDir = new DirectoryInfo(Root);
            }
            catch
            {
                logger.Error("Unable to get the directory information: " + Root);
                result = false;
            }

            //
            // Try to find the raf files and read them.
            //

            if (result == true)
            {
                try
                {
                    result = GetRAFFiles(rootDir, logger);

                    // If the finding or reading fails, bail.
                    if (!result)
                    {
                        logger.Error("Unable to find the 'filearchives' directory: " + Root);
                    }
                }
                catch (Exception e)
                {
                    logger.Error("Unable to open directory: " + Root);
                    logger.Error(e.Message);
                    result = false;
                }
            }

            // Sanity
            if (result == true)
            {
                GenerateModelDefinitions(logger);
            }

            return result;
        }