예제 #1
0
        public MCNK(char[] magic, byte[] size, byte[] content) : base(magic, size)
        {
            using (BinaryReader reader = new BinaryReader(new MemoryStream(content)))
            {
                #region read MCNKhead
                mcHeader.Flags       = reader.ReadUInt32();
                mcHeader.IndexX      = reader.ReadUInt32();
                mcHeader.IndexY      = reader.ReadUInt32();
                mcHeader.NLayers     = reader.ReadUInt32();
                mcHeader.NDoodadRefs = reader.ReadUInt32();

                offset offset = new offset();
                offset.address   = reader.ReadUInt32();
                mcHeader.OfsMCVT = offset;

                offset           = new offset();
                offset.address   = reader.ReadUInt32();
                mcHeader.OfsMCNR = offset;
                offset           = new offset();
                offset.address   = reader.ReadUInt32();
                mcHeader.OfsMCLY = offset;
                offset           = new offset();
                offset.address   = reader.ReadUInt32();
                mcHeader.OfsMCRF = offset;
                offset           = new offset();
                offset.address   = reader.ReadUInt32();
                mcHeader.OfsMCAL = offset;

                mcHeader.SizeAlpha = reader.ReadUInt32();

                offset           = new offset();
                offset.address   = reader.ReadUInt32();
                mcHeader.OfsMCSH = offset;

                mcHeader.SizeShadow  = reader.ReadUInt32();
                mcHeader.Areaid      = reader.ReadUInt32();
                mcHeader.NMapObjRefs = reader.ReadUInt32();
                mcHeader.Holes       = reader.ReadUInt32();

                mcHeader.GroundEffectsMap = new byte[16];
                for (int x = 0; x < 16; x++)
                {
                    mcHeader.GroundEffectsMap[x] = reader.ReadByte();
                }

                mcHeader.PredTex        = reader.ReadUInt32();
                mcHeader.NoEffectDoodad = reader.ReadUInt32();

                offset           = new offset();
                offset.address   = reader.ReadUInt32();
                mcHeader.OfsMCSE = offset;

                mcHeader.NSndEmitters = reader.ReadUInt32();

                offset           = new offset();
                offset.address   = reader.ReadUInt32();
                mcHeader.OfsMCLQ = offset;

                mcHeader.SizeLiquid = reader.ReadUInt32();

                mcHeader.Pos    = new float[3];
                mcHeader.Pos[0] = reader.ReadSingle();
                mcHeader.Pos[1] = reader.ReadSingle();
                mcHeader.Pos[2] = reader.ReadSingle();

                offset           = new offset();
                offset.address   = reader.ReadUInt32();
                mcHeader.OfsMCCV = offset;

                mcHeader.Props    = reader.ReadUInt32();
                mcHeader.EffectId = reader.ReadUInt32();
                #endregion

                while (reader.BaseStream.Position < reader.BaseStream.Length)
                {
                    byte[] ChunkMagic   = reader.ReadBytes(4);
                    byte[] ChunkSize    = reader.ReadBytes(4);
                    byte[] ChunkContent = reader.ReadBytes(BitConverter.ToInt32(ChunkSize, 0));

                    string ChunkMagicString = ADT.MagicBytesToString(ChunkMagic);

                    switch (ChunkMagicString)
                    {
                    case "MCVT":
                        mcvt = new MCVT(ADT.MagicBytesToChars(ChunkMagic), ChunkSize, ChunkContent);
                        break;

                    case "MCCV":
                        mccv = new MCCV(ADT.MagicBytesToChars(ChunkMagic), ChunkSize, ChunkContent);
                        break;

                    case "MCNR":
                        mcnr = new MCNR(ADT.MagicBytesToChars(ChunkMagic), ChunkSize, ChunkContent, reader.ReadBytes(13));
                        break;

                    case "MCLY":
                        mcly = new MCLY(ADT.MagicBytesToChars(ChunkMagic), ChunkSize, ChunkContent);
                        break;

                    case "MCRF":
                        mcrf = new MCRF(ADT.MagicBytesToChars(ChunkMagic), ChunkSize, ChunkContent);
                        break;

                    case "MCAL":
                        mcal = new MCAL(ADT.MagicBytesToChars(ChunkMagic), ChunkSize, ChunkContent);
                        break;

                    case "MCSE":
                        mcse = new MCSE(ADT.MagicBytesToChars(ChunkMagic), ChunkSize, ChunkContent);
                        break;

                    case "MCSH":
                        mcsh = new MCSH(ADT.MagicBytesToChars(ChunkMagic), ChunkSize, ChunkContent);
                        break;

                    case "MCLQ":
                        mclq = new MCLQ(ADT.MagicBytesToChars(ChunkMagic), ChunkSize, ChunkContent);
                        break;
                    }

                    //Logger.log(ChunkMagicString, Logger.Direction.LEVEL2, ChunkContent.Length.ToString() + " byte");
                }
            }

            //Logger.log("---", Logger.Direction.LEVEL2);
        }
예제 #2
0
        //-----------------------------------------------------------------------------------------------------------------

        public void GenerateAlphaMaps(ADT adtfile, int GenerationMode)
        {
            if (GenerationMode == 0 || GenerationMode == 1) //MODE 0 & 1 (256 RGB ALPHAS, ONE PER CHUNK)
            {
                //----------------------------------------------------------------------------------------------------------
                ////////////////////////////////////////////////////////////////////////////////////////////////////////////
                ///ALPHA MAPS TEST
                ////////////////////////////////////////////////////////////////////////////////////////////////////////////
                //----------------------------------------------------------------------------------------------------------
                var valuesR = new MCAL().layer;
                var valuesG = new MCAL().layer;
                var valuesB = new MCAL().layer;
                for (uint c = 0; c < adtfile.chunks.Count(); c++)
                {
                    if (adtfile.texChunks[c].alphaLayer != null)
                    {
                        var bmp = new Bitmap(64, 64);
                        //Assign the channels...
                        switch (adtfile.texChunks[c].layers.Count())
                        {
                        case 2:
                            valuesR = adtfile.texChunks[c].alphaLayer[1].layer;
                            break;

                        case 3:
                            valuesR = adtfile.texChunks[c].alphaLayer[1].layer;
                            valuesG = adtfile.texChunks[c].alphaLayer[2].layer;
                            break;

                        case 4:
                            valuesR = adtfile.texChunks[c].alphaLayer[1].layer;
                            valuesG = adtfile.texChunks[c].alphaLayer[2].layer;
                            valuesB = adtfile.texChunks[c].alphaLayer[3].layer;
                            break;

                        default:
                            //Don't do anything
                            break;
                        }
                        if (GenerationMode == 0)
                        {
                            // 64x64 ALPHAS:
                            for (int x = 0; x < 64; x++)
                            {
                                for (int y = 0; y < 64; y++)
                                {
                                    Color color;
                                    switch (adtfile.texChunks[c].layers.Count())
                                    {
                                    case 2:
                                        color = Color.FromArgb(255, valuesR[x * 64 + y], 0, 0);
                                        break;

                                    case 3:
                                        color = Color.FromArgb(255, valuesR[x * 64 + y], valuesG[x * 64 + y], 0);
                                        break;

                                    case 4:
                                        color = Color.FromArgb(255, valuesR[x * 64 + y], valuesG[x * 64 + y], valuesB[x * 64 + y]);
                                        break;

                                    default:
                                        color = Color.FromArgb(255, 0, 0, 0);
                                        break;
                                    }
                                    bmp.SetPixel(x, y, color);
                                }
                            }
                        }
                        if (GenerationMode == 1)
                        {
                            // 63x63 ALPHAS: (Last column/row = previous one)
                            for (int x = 0; x < 63; x++)
                            {
                                for (int y = 0; y < 63; y++)
                                {
                                    Color color;
                                    switch (adtfile.texChunks[c].layers.Count())
                                    {
                                    case 2:
                                        color = Color.FromArgb(255, valuesR[x * 64 + y], 0, 0);
                                        break;

                                    case 3:
                                        color = Color.FromArgb(255, valuesR[x * 64 + y], valuesG[x * 64 + y], 0);
                                        break;

                                    case 4:
                                        color = Color.FromArgb(255, valuesR[x * 64 + y], valuesG[x * 64 + y], valuesB[x * 64 + y]);
                                        break;

                                    default:
                                        color = Color.FromArgb(255, 0, 0, 0);
                                        break;
                                    }
                                    bmp.SetPixel(x, y, color);
                                    if (y == 62)
                                    {
                                        bmp.SetPixel(x, y + 1, color);
                                    }
                                    if (x == 62)
                                    {
                                        bmp.SetPixel(x + 1, y, color);
                                    }
                                    if (x == 62 && y == 62)
                                    {
                                        bmp.SetPixel(x + 1, y + 1, color);
                                    }
                                }
                            }
                        }
                        //----------------------------------------------------------------------------------------------------------
                        //Fix bmp orientation:
                        //----------------------------------------------------------------------------------------------------------
                        bmp.RotateFlip(RotateFlipType.Rotate270FlipY);
                        //----------------------------------------------------------------------------------------------------------

                        //----------------------------------------------------------------------------------------------------------
                        //Store the generated map in the array
                        //----------------------------------------------------------------------------------------------------------
                        AlphaLayers.Add(bmp);
                        //----------------------------------------------------------------------------------------------------------
                    }
                    else //Create and add an empty BMP if Null
                    {
                        var bmp = new Bitmap(64, 64);
                        AlphaLayers.Add(bmp);
                    }
                }
                //----------------------------------------------------------------------------------------------------------
                ////////////////////////////////////////////////////////////////////////////////////////////////////////////
                ///ALPHA MAPS TEST END
                ////////////////////////////////////////////////////////////////////////////////////////////////////////////
                //----------------------------------------------------------------------------------------------------------
            }
            if (GenerationMode == 2 || GenerationMode == 3) //MODE 2 & 3 (A BLACK&WHITE ALPHA FOR EACH LAYER (ROUGHLY ~768 ALPHAS))
            {
                //----------------------------------------------------------------------------------------------------------
                ////////////////////////////////////////////////////////////////////////////////////////////////////////////
                ///ALPHA MAPS TEST
                ////////////////////////////////////////////////////////////////////////////////////////////////////////////
                //----------------------------------------------------------------------------------------------------------
                for (uint c = 0; c < adtfile.chunks.Count(); c++)
                {
                    var chunk = adtfile.chunks[c];
                    for (int li = 0; li < adtfile.texChunks[c].layers.Count(); li++)
                    {
                        if (adtfile.texChunks[c].alphaLayer != null)
                        {
                            var values = adtfile.texChunks[c].alphaLayer[li].layer;
                            var bmp    = new System.Drawing.Bitmap(64, 64);
                            {
                                if (GenerationMode == 2)
                                {
                                    // 64x64 ALPHAS:
                                    for (int x = 0; x < 64; x++)
                                    {
                                        for (int y = 0; y < 64; y++)
                                        {
                                            Color color;
                                            if (Managers.ConfigurationManager.ADTAlphaUseA)
                                            {
                                                color = System.Drawing.Color.FromArgb(values[x * 64 + y], values[x * 64 + y], values[x * 64 + y], values[x * 64 + y]);
                                            }
                                            else
                                            {
                                                color = System.Drawing.Color.FromArgb(255, values[x * 64 + y], values[x * 64 + y], values[x * 64 + y]);
                                            }
                                            bmp.SetPixel(x, y, color);
                                        }
                                    }
                                }
                                if (GenerationMode == 3)
                                {
                                    // 63x63 ALPHAS: (Last column/row = previous one)
                                    for (int x = 0; x < 63; x++)
                                    {
                                        for (int y = 0; y < 63; y++)
                                        {
                                            Color color;
                                            if (Managers.ConfigurationManager.ADTAlphaUseA)
                                            {
                                                color = System.Drawing.Color.FromArgb(values[x * 64 + y], values[x * 64 + y], values[x * 64 + y], values[x * 64 + y]);
                                            }
                                            else
                                            {
                                                color = System.Drawing.Color.FromArgb(255, values[x * 64 + y], values[x * 64 + y], values[x * 64 + y]);
                                            }
                                            bmp.SetPixel(x, y, color);
                                            if (y == 62)
                                            {
                                                bmp.SetPixel(x, y + 1, color);
                                            }
                                            if (x == 62)
                                            {
                                                bmp.SetPixel(x + 1, y, color);
                                            }
                                            if (x == 62 && y == 62)
                                            {
                                                bmp.SetPixel(x + 1, y + 1, color);
                                            }
                                        }
                                    }
                                }
                            }
                            //----------------------------------------------------------------------------------------------------------
                            //Store the layer textures
                            //----------------------------------------------------------------------------------------------------------
                            var AlphaLayerName = adtfile.textures.filenames[adtfile.texChunks[c].layers[li].textureId].ToLower();
                            AlphaLayersNames.Add(c + ";" + li + ";" + Path.GetFileNameWithoutExtension(AlphaLayerName));
                            //----------------------------------------------------------------------------------------------------------

                            //----------------------------------------------------------------------------------------------------------
                            //Fix bmp orientation:
                            //----------------------------------------------------------------------------------------------------------
                            bmp.RotateFlip(RotateFlipType.Rotate270FlipY);
                            //----------------------------------------------------------------------------------------------------------

                            //----------------------------------------------------------------------------------------------------------
                            //Store the generated map in the array
                            //----------------------------------------------------------------------------------------------------------
                            AlphaLayers.Add(bmp);
                            //----------------------------------------------------------------------------------------------------------
                        }
                    }
                }
                //----------------------------------------------------------------------------------------------------------
                ////////////////////////////////////////////////////////////////////////////////////////////////////////////
                ///ALPHA MAPS TEST END
                ////////////////////////////////////////////////////////////////////////////////////////////////////////////
                //----------------------------------------------------------------------------------------------------------
            }

            #region Splatmaps (1024x1024)
            if (GenerationMode == 4)
            {
                //Adapted from Selzier's code [https://github.com/Selzier/wow.export.unity/blob/master/src/js/3D/exporters/ADTExporter.js]

                //----------------------------------------------------------------------------------------------------------
                //Generate the splatmap json
                //----------------------------------------------------------------------------------------------------------
                #region Splatmap JSON
                string materialJSON = "{\"chunkData\":{"; // New JSON file to save material data
                for (uint c = 0; c < adtfile.chunks.Count(); c++)
                {
                    materialJSON += "\"" + c + "\":[";
                    for (int li = 0; li < adtfile.texChunks[c].layers.Count(); li++)
                    {
                        string AlphaLayerName = adtfile.textures.filenames[adtfile.texChunks[c].layers[li].textureId].ToLower();
                        if (Managers.ConfigurationManager.ADTPreserveTextureStruct)
                        {
                            AlphaLayerName = AlphaLayerName.Replace("\\", "\\\\").Replace(".blp", "");  //Remove extension and modify the path to use "\\" instead of "\"
                        }
                        else
                        {
                            AlphaLayerName = Path.GetFileNameWithoutExtension(AlphaLayerName); // Get only the filename
                        }

                        //Layer scale
                        float LayerScale = 4;
                        if (adtfile.texParams != null && adtfile.texParams.Count() >= adtfile.texChunks[c].layers[li].textureId)
                        {
                            LayerScale = (float)Math.Pow(2, (adtfile.texParams[adtfile.texChunks[c].layers[li].textureId].flags & 0xF0) >> 4);
                        }

                        materialJSON += "{\"id\":\"" + AlphaLayerName + "\",\"scale\":\"" + LayerScale + "\"},";
                    }
                    materialJSON  = materialJSON.Substring(0, materialJSON.Length - 1); // Remove tailing comma
                    materialJSON += "],";                                               // Close the subchunk array
                }
                materialJSON = materialJSON.Substring(0, materialJSON.Length - 1);      // Remove tailing comma
                string fullJSON = materialJSON + "},\"splatmapData\":{";                // Create JSON data to include splatmap data
                materialJSON += "}}";                                                   // Close the JSON data

                JObject matJSON = JObject.Parse(materialJSON);

                if (adtfile.textures.filenames.Length == 0)
                {
                    fullJSON += "\"id0\":\"null\",";
                }
                else
                {
                    for (int q = 0; q < adtfile.textures.filenames.Length; q++)
                    {
                        string textureFile = adtfile.textures.filenames[q].ToLower();

                        if (Managers.ConfigurationManager.ADTPreserveTextureStruct)
                        {
                            textureFile = textureFile.Replace("\\", "\\\\").Replace(".blp", ""); //Remove extension and modify the path to use "\\" instead of "\"
                        }
                        else
                        {
                            textureFile = Path.GetFileNameWithoutExtension(textureFile);
                        }

                        fullJSON += "\"id" + q + "\":\"" + textureFile + "\",";
                    }
                }

                fullJSON  = fullJSON.Substring(0, fullJSON.Length - 1); // remove tailing comma
                fullJSON += "}}";                                       // Close the JSON data

                SplatmapJSON = fullJSON;

                #endregion
                //----------------------------------------------------------------------------------------------------------

                //----------------------------------------------------------------------------------------------------------
                //Generate the actual splatmaps
                //----------------------------------------------------------------------------------------------------------
                #region Splatmap Bitmap

                string[] materialIDs = adtfile.textures.filenames;
                for (int i = 0; i < materialIDs.Length; i++)
                {
                    if (Managers.ConfigurationManager.ADTPreserveTextureStruct)
                    {
                        materialIDs[i] = materialIDs[i].ToLower().Replace(".blp", ""); //Remove extension for the files
                    }
                    else
                    {
                        materialIDs[i] = Path.GetFileNameWithoutExtension(materialIDs[i].ToLower());
                    }
                }
                int imageCount = IntCeil(materialIDs.Length, 4);

                //----------------------------------------------------------------------------------------------------------
                //Structure for this abomination:
                //----------------------------------------------------------------------------------------------------------
                //>A int array for every map we need that contains:
                //>A int array for each channel (4 in total A R G B) that contains:
                //>A 2D array for each pixel (1024x1024)
                int[][][,] pixelData = new int[imageCount][][, ];
                for (int p = 0; p < pixelData.Length; p++)
                {
                    pixelData[p] = new int[4][, ];
                    for (int i = 0; i < 4; i++)
                    {
                        pixelData[p][i] = new int[1024, 1024];
                    }
                }
                //----------------------------------------------------------------------------------------------------------

                // Now before we draw each sub-chunk to PNG, we need to check it's texture list in json.
                // Based on what order the textures are for that sub-chunk, we may need to draw RGBA in a different order than 0,1,2,3

                //Chunk offset
                int xOff = 0;
                int yOff = 0;

                //Loop for all the 256 texChunks
                for (int chunkIndex = 0; chunkIndex < 256; chunkIndex++)
                {
                    TexMCNK texChunk      = adtfile.texChunks[chunkIndex];
                    MCAL[]  alphaLayers   = texChunk.alphaLayer;
                    MCLY[]  textureLayers = texChunk.layers;

                    // If there is no texture data just skip it
                    if (textureLayers.Length > 0)
                    {
                        // X,Y Loop through the texChunk (data is stored as 64x64)
                        for (int x = 0; x < 64; x++)
                        {
                            for (int y = 0; y < 64; y++)
                            {
                                int alphaIndex = x * 64 + y;

                                int numberTextureLayers = matJSON["chunkData"][chunkIndex.ToString()].Count();

                                for (int k = 0; k < numberTextureLayers; k++)
                                {
                                    // k = 1, random materialID. This could be any RGBA, RGBA color!
                                    int    currentIndex = 0;
                                    string currentID    = (string)matJSON["chunkData"][chunkIndex.ToString()][k]["id"]; //Probably not a good idea to use a string though (check back on >7xx support)

                                    for (int l = 0; l < materialIDs.Length; l++)
                                    {
                                        if (materialIDs[l] == currentID)
                                        {
                                            currentIndex = l;
                                        }
                                    }
                                    int texIndex = currentIndex;

                                    // Calculate image index, 1 PNG image for each 4 textures. index 0 includes base texture on channel 0
                                    int imageIndex = IntFloor(texIndex, 4);

                                    // 0-3 RGBA. If imageIndex=0 this should not be 0 because that is basetexture
                                    int channelIndex = texIndex % 4;

                                    // 'vec3 blendTex' from the adt.fragment shader
                                    var blendTexs = new int[3];
                                    if (alphaLayers != null) //Those layers can be null
                                    {
                                        switch (alphaLayers.Length)
                                        {
                                        case 2:
                                            blendTexs[0] = alphaLayers[1].layer[alphaIndex];
                                            break;

                                        case 3:
                                            blendTexs[0] = alphaLayers[1].layer[alphaIndex];
                                            blendTexs[1] = alphaLayers[2].layer[alphaIndex];
                                            break;

                                        case 4:
                                            blendTexs[0] = alphaLayers[1].layer[alphaIndex];
                                            blendTexs[1] = alphaLayers[2].layer[alphaIndex];
                                            blendTexs[2] = alphaLayers[3].layer[alphaIndex];
                                            break;

                                        default:
                                            break;
                                        }
                                    }

                                    // 'vec4 layer_weights' from the adt.fragment shader
                                    var sumBlendTex = 0;
                                    for (int b = 0; b < blendTexs.Length; b++)
                                    {
                                        sumBlendTex += blendTexs[b];
                                    }
                                    sumBlendTex = Clamp(sumBlendTex, 0, 255);
                                    int[] layerWeights = new int[4];
                                    layerWeights[0] = 255 - sumBlendTex;
                                    layerWeights[1] = blendTexs[0];
                                    layerWeights[2] = blendTexs[1];
                                    layerWeights[3] = blendTexs[2];

                                    // Write the actual pixel data
                                    if (k == 0)
                                    {
                                        pixelData[imageIndex][channelIndex][x + xOff, y + yOff] = layerWeights[0];
                                    }
                                    else
                                    {
                                        pixelData[imageIndex][channelIndex][x + xOff, y + yOff] = layerWeights[k];
                                    }
                                }
                            }
                        }
                    }
                    //----------------------------------------------------------------------------------------------------------
                    //Change the offset
                    //----------------------------------------------------------------------------------------------------------
                    if (yOff + 64 > 960)
                    {
                        yOff = 0;
                        if (xOff + 64 <= 960)
                        {
                            xOff += 64;
                        }
                    }
                    else
                    {
                        yOff += 64;
                    }
                    //----------------------------------------------------------------------------------------------------------
                }

                //----------------------------------------------------------------------------------------------------------
                //Generate the bitmaps
                //----------------------------------------------------------------------------------------------------------
                for (int t = 0; t < imageCount; t++)
                {
                    Bitmap bmp = new Bitmap(1024, 1024);

                    for (int x = 0; x < 1024; x++)
                    {
                        for (int y = 0; y < 1024; y++)
                        {
                            Color currentColor = Color.FromArgb(
                                ZeroClamp(pixelData[t][3][x, y]), //A
                                ZeroClamp(pixelData[t][0][x, y]), //R
                                ZeroClamp(pixelData[t][1][x, y]), //G
                                ZeroClamp(pixelData[t][2][x, y])  //B
                                );

                            bmp.SetPixel(x, y, currentColor);
                        }
                    }

                    //----------------------------------------------------------------------------------------------------------
                    //Fix bmp orientation:
                    //----------------------------------------------------------------------------------------------------------
                    bmp.RotateFlip(RotateFlipType.Rotate270FlipY);
                    //----------------------------------------------------------------------------------------------------------

                    //----------------------------------------------------------------------------------------------------------
                    //Store the generated map in the list
                    //----------------------------------------------------------------------------------------------------------
                    AlphaLayers.Add(bmp);
                    //----------------------------------------------------------------------------------------------------------
                }
                //----------------------------------------------------------------------------------------------------------

                #endregion
                //----------------------------------------------------------------------------------------------------------
            }
            #endregion
        }
예제 #3
0
파일: MCNK.cs 프로젝트: Kaev/CoreADT
        public override byte[] GetChunkBytes()
        {
            using (var stream = new MemoryStream())
            {
                using (var writer = new BinaryWriter(stream))
                {
                    writer.Write((uint)Flags);
                    writer.WriteVector2UInt(Index);
                    writer.Write(Layers);
                    writer.Write(NumberDoodadRefs);
                    var positionOffsetMCVT = BaseStream.Position;
                    writer.Write(0);
                    var positionOffsetMCNR = BaseStream.Position;
                    writer.Write(0);
                    var positionOffsetMCLY = BaseStream.Position;
                    writer.Write(0);
                    var positionOffsetMCRF = BaseStream.Position;
                    writer.Write(0);
                    var positionOffsetMCAL = BaseStream.Position;
                    writer.Write(0);
                    writer.Write(SizeShadow);
                    var positionOffsetMCSH = BaseStream.Position;
                    writer.Write(0);
                    writer.Write(SizeShadow);
                    writer.Write(AreaId);
                    writer.Write(NumberMapObjectRefs);
                    writer.Write(Holes);
                    writer.Write(HolesPadding);
                    for (int i = 0; i < 16; i++)
                    {
                        writer.Write(ReallyLowQualityTextureingMap[i]);
                    }
                    writer.Write(PredTex);
                    writer.Write(NumberEffectDoodads);
                    var positionOffsetMCSE = BaseStream.Position;
                    writer.Write(0);
                    writer.Write(NumberSoundEmitters);
                    var positionOffsetMCLQ = BaseStream.Position;
                    writer.Write(0);
                    writer.Write(SizeLiquid);
                    writer.WriteVector3Float(Position);
                    var positionOffsetMCCV = BaseStream.Position;
                    writer.Write(0);
                    writer.Write(Unused1);
                    writer.Write(Unused2);

                    // Subchunks

                    var positionMCVT = BaseStream.Position;
                    BaseStream.Position = positionOffsetMCVT;
                    writer.Write(positionMCVT);
                    BaseStream.Position = positionMCVT;
                    writer.Write(MCVT.GetChunkHeaderBytes());
                    writer.Write(MCVT.GetChunkBytes());

                    var positionMCNR = BaseStream.Position;
                    BaseStream.Position = positionOffsetMCNR;
                    writer.Write(positionMCNR);
                    BaseStream.Position = positionMCNR;
                    writer.Write(MCNR.GetChunkHeaderBytes());
                    writer.Write(MCNR.GetChunkBytes());

                    var positionMCLY = BaseStream.Position;
                    BaseStream.Position = positionOffsetMCLY;
                    writer.Write(positionMCLY);
                    BaseStream.Position = positionMCLY;
                    writer.Write(MCLY.GetChunkHeaderBytes());
                    writer.Write(MCLY.GetChunkBytes());

                    var positionMCRF = BaseStream.Position;
                    BaseStream.Position = positionOffsetMCRF;
                    writer.Write(positionMCRF);
                    BaseStream.Position = positionMCRF;
                    writer.Write(MCRF.GetChunkHeaderBytes());
                    writer.Write(MCRF.GetChunkBytes());

                    // if WDT
                    var positionMCAL = BaseStream.Position;
                    BaseStream.Position = positionOffsetMCAL;
                    writer.Write(positionMCAL);
                    BaseStream.Position = positionMCAL;
                    writer.Write(MCAL.GetChunkHeaderBytes());
                    writer.Write(MCAL.GetChunkBytes());

                    if (SizeShadow > 8 && Flags.HasFlag(MCNKFlags.HasMCSH))
                    {
                        var positionMCSH = BaseStream.Position;
                        BaseStream.Position = positionOffsetMCSH;
                        writer.Write(positionMCSH);
                        BaseStream.Position = positionMCSH;
                        writer.Write(MCSH.GetChunkHeaderBytes());
                        writer.Write(MCSH.GetChunkBytes());
                    }

                    if (NumberSoundEmitters > 0)
                    {
                        var positionMCSE = BaseStream.Position;
                        BaseStream.Position = positionOffsetMCSE;
                        writer.Write(positionMCSE);
                        BaseStream.Position = positionMCSE;
                        writer.Write(MCSE.GetChunkHeaderBytes());
                        writer.Write(MCSE.GetChunkBytes());
                    }

                    if (SizeLiquid > 0)
                    {
                        var positionMCLQ = BaseStream.Position;
                        BaseStream.Position = positionOffsetMCLQ;
                        writer.Write(positionMCLQ);
                        BaseStream.Position = positionMCLQ;
                        writer.Write(MCLQ.GetChunkHeaderBytes());
                        writer.Write(MCLQ.GetChunkBytes());
                    }

                    var positionMCCV = BaseStream.Position;
                    BaseStream.Position = positionOffsetMCCV;
                    writer.Write(positionMCCV);
                    BaseStream.Position = positionMCCV;
                    writer.Write(MCCV.GetChunkHeaderBytes());
                    writer.Write(MCCV.GetChunkBytes());
                }
                return(stream.ToArray());
            }
        }
예제 #4
0
        private MCAL[] ReadMCALSubChunk(uint size, BinaryReader bin, TexMCNK mapchunk)
        {
            var mcal = new MCAL[mapchunk.layers.Length];

            mcal[0].layer = new byte[64 * 64];
            for (int i = 0; i < 64 * 64; i++)
            {
                mcal[0].layer[i] = 255;
            }

            uint read_offset = 0;

            for (int layer = 1; layer < mapchunk.layers.Length; ++layer)
            {
                // we assume that we have read as many bytes as this next layer's mcal offset. we then read depending on encoding
                if (mapchunk.layers[layer].offsetInMCAL != read_offset)
                {
                    throw new Exception("mismatch: layer before required more / less bytes than expected");
                }
                if (mapchunk.layers[layer].flags.HasFlag(mclyFlags.Flag_0x200)) // Compressed
                {
                    //Console.WriteLine("Compressed");
                    // first layer is always fully opaque -> you can let that out
                    // array of 3 x array of 64*64 chars: unpacked alpha values
                    mcal[layer].layer = new byte[64 * 64];

                    // sorry, I have no god damn idea about c#
                    // *x = value at x. x = pointer to data. ++x = advance pointer a byte
                    uint in_offset  = 0;
                    uint out_offset = 0;
                    while (out_offset < 4096)
                    {
                        byte info  = bin.ReadByte(); ++in_offset;
                        uint mode  = (uint)(info & 0x80) >> 7; // 0 = copy, 1 = fill
                        uint count = (uint)(info & 0x7f);      // do mode operation count times

                        if (mode != 0)
                        {
                            byte val = bin.ReadByte(); ++in_offset;
                            while (count-- > 0 && out_offset < 4096)
                            {
                                mcal[layer].layer[out_offset] = val;
                                ++out_offset;
                            }
                        }
                        else // mode == 1
                        {
                            while (count-- > 0 && out_offset < 4096)
                            {
                                var val = bin.ReadByte(); ++in_offset;
                                mcal[layer].layer[out_offset] = val;
                                ++out_offset;
                            }
                        }
                    }
                    read_offset += in_offset;
                    if (out_offset != 4096)
                    {
                        throw new Exception("we somehow overshoot. this should not be the case, except for broken adts");
                    }
                }
                else if (wdt.mphd.flags.HasFlag(Structs.WDT.mphdFlags.Flag_0x4) || wdt.mphd.flags.HasFlag(Structs.WDT.mphdFlags.Flag_0x80)) // Uncompressed (4096)
                {
                    //Console.WriteLine("Uncompressed (4096)");
                    mcal[layer].layer = bin.ReadBytes(4096);
                    read_offset      += 4096;
                }
                else // Uncompressed (2048)
                {
                    //Console.WriteLine("Uncompressed (2048)");
                    mcal[layer].layer = new byte[64 * 64];
                    var mcal_data = bin.ReadBytes(2048);
                    read_offset += 2048;
                    for (int i = 0; i < 2048; ++i)
                    {
                        // maybe nibbles swapped
                        mcal[layer].layer[2 * i + 0] = (byte)(((mcal_data[i] & 0x0F) >> 0) * 17);
                        mcal[layer].layer[2 * i + 1] = (byte)(((mcal_data[i] & 0xF0) >> 4) * 17);
                    }
                }
            }

            if (read_offset != size)
            {
                throw new Exception("Haven't finished reading chunk but should be");
            }

            return(mcal);
        }
예제 #5
0
파일: MCNK.cs 프로젝트: Kaev/CoreADT
        public MCNK(byte[] chunkBytes, WDT.WDT wdt) : base(chunkBytes)
        {
            Flags               = (MCNKFlags)ReadUInt32();
            Index               = this.ReadVector2UInt();
            Layers              = ReadUInt32();
            NumberDoodadRefs    = ReadUInt32();
            OffsetMCVT          = ReadUInt32();
            OffsetMCNR          = ReadUInt32();
            OffsetMCLY          = ReadUInt32();
            OffsetMCRF          = ReadUInt32();
            OffsetMCAL          = ReadUInt32();
            SizeAlpha           = ReadUInt32();
            OffsetMCSH          = ReadUInt32();
            SizeShadow          = ReadUInt32();
            AreaId              = ReadUInt32();
            NumberMapObjectRefs = ReadUInt32();
            Holes               = ReadUInt16();
            HolesPadding        = ReadUInt16();
            // Maybe change this to two longs like in https://bitbucket.org/mugadr_m/kotlin-wow/src/378f3fdec7fff325f52560fc2cce64c946cf57ab/editor/src/main/kotlin/ch/cromon/wow/io/files/map/wotlk/MapChunk.kt?at=master&fileviewer=file-view-default#MapChunk.kt-37
            for (int i = 0; i < 16; i++)
            {
                ReallyLowQualityTextureingMap[i] = ReadByte();
            }
            PredTex             = ReadUInt32();
            NumberEffectDoodads = ReadUInt32();
            OffsetMCSE          = ReadUInt32();
            NumberSoundEmitters = ReadUInt32();
            OffsetMCLQ          = ReadUInt32();
            SizeLiquid          = ReadUInt32();
            Position            = this.ReadVector3Float();
            OffsetMCCV          = ReadUInt32();
            Unused1             = ReadUInt32();
            Unused2             = ReadUInt32();

            if (OffsetMCVT > 0)
            {
                BaseStream.Position = OffsetMCVT;
                MCVT = new MCVT(ReadBytes((int)MCVT.ChunkSize));
            }

            if (OffsetMCNR > 0)
            {
                BaseStream.Position = OffsetMCNR;
                MCNR = new MCNR(ReadBytes((int)MCNR.ChunkSize));
            }

            if (OffsetMCLY > 0)
            {
                BaseStream.Position = OffsetMCLY;
                MCLY = new MCLY(ReadBytes((int)MCLY.ChunkSize));
            }

            if (OffsetMCRF > 0)
            {
                BaseStream.Position = OffsetMCRF;
                MCRF = new MCRF(ReadBytes((int)MCRF.ChunkSize), this);
            }

            // TODO: && No WDT file?
            if (OffsetMCAL > 0 && wdt != null)
            {
                BaseStream.Position = OffsetMCAL;
                MCAL = new MCAL(ReadBytes((int)MCAL.ChunkSize), this, wdt);
            }

            if (OffsetMCSH > 0 && SizeShadow > 8 && Flags.HasFlag(MCNKFlags.HasMCSH))
            {
                BaseStream.Position = OffsetMCSH;
                MCSH = new MCSH(ReadBytes((int)MCSH.ChunkSize));
            }

            if (OffsetMCSE > 0 && NumberSoundEmitters > 0)
            {
                BaseStream.Position = OffsetMCSE;
                MCSE = new MCSE(ReadBytes((int)MCSE.ChunkSize), this);
            }

            if (OffsetMCLQ > 0 && SizeLiquid > 0)
            {
                BaseStream.Position = OffsetMCLQ;
                MCLQ = new MCLQ(ReadBytes((int)MCLQ.ChunkSize), this);
            }

            if (OffsetMCCV > 0)
            {
                BaseStream.Position = OffsetMCCV;
                MCCV = new MCCV(ReadBytes((int)MCCV.ChunkSize));
            }
            Close();
        }