Пример #1
0
        private static MainFieldChara ReadMainChara(byte[] oneb)
        {
            MainFieldChara localMfc = new MainFieldChara();

            using (MemoryStream ms = new MemoryStream(oneb))
                using (BinaryReader br = new BinaryReader(ms))
                {
                    List <uint> timOffsets = new List <uint>();
                    uint        timOffset;
                    while ((timOffset = br.ReadUInt32()) != 0xffffffff)
                    {
                        timOffsets.Add(timOffset & 0x00FFFFFF);
                    }
                    uint modelPointer = br.ReadUInt32();

                    //read textures
                    List <Texture2D> tex2Dreader = new List <Texture2D>();
                    for (int i = 0; i < timOffsets.Count; i++)
                    {
                        TIM2 tim = new TIM2(br, timOffsets[i]);
                        tex2Dreader.Add(tim.GetTexture());
                    }
                    localMfc.textures = tex2Dreader.ToArray();

                    //read models
                    ms.Seek(modelPointer, SeekOrigin.Begin);

                    Debug_MCH mch = new Debug_MCH(ms, br, Debug_MCH.mchMode.FieldMain);
                    localMfc.mch = mch;
                }
            return(localMfc);
        }
Пример #2
0
 public texl(byte[] texlBuffer)
 {
     textures = new Texture2D[20][];
     using (MemoryStream ms = new MemoryStream(texlBuffer))
         using (BinaryReader br = new BinaryReader(ms))
             for (int i = 0; i < TEX_COUNT; i++)
             {
                 int  timOffset = i * TEX_SIZE;
                 TIM2 tim       = new TIM2(texlBuffer, (uint)timOffset);
                 textures[i] = new Texture2D[tim.GetClutCount];
                 for (ushort k = 0; k < textures[i].Length; k++)
                 {
                     textures[i][k] = tim.GetTexture(k, true);
                 }
             }
 }
Пример #3
0
 public TIM2[] TryReadTIM(BinaryReader br)
 {
     try
     {
         var tim = new TIM2(br, noExec: true);
         if (tim.NotTIM)
         {
             return(TIM = null);
         }
         isTIM = true;
         return(TIM = new TIM2[] { tim });
     }
     catch (InvalidDataException)
     {
         return(TIM = null);
     }
 }
Пример #4
0
 public texl(byte[] texlBuffer)
 {
     textures = new TextureHandler[20][];
     using (MemoryStream ms = new MemoryStream(texlBuffer))
         using (BinaryReader br = new BinaryReader(ms))
             for (int i = 0; i < TEX_COUNT; i++)
             {
                 int  timOffset = i * TEX_SIZE;
                 TIM2 tim       = new TIM2(texlBuffer, (uint)timOffset);
                 textures[i] = new TextureHandler[tim.GetClutCount];
                 for (ushort k = 0; k < textures[i].Length; k++)
                 {
                     textures[i][k] = TextureHandler.Create($"texl_tim{(i + 1).ToString("D2")}.tim", tim, k, null);
                 }
                 //todo detect if mods aren't using palettes.
             }
 }
Пример #5
0
        /// <summary>
        /// Reads chara.one buffer -&gt; chara one is a file packed with MCH files and TIM textures
        /// without pointers. File needs to be scanned
        /// </summary>
        /// <param name="buffer">Full chara.one file</param>
        public CharaOne(byte[] buffer)
        {
            this.buffer = buffer;
            List <Debug_MCH>      mchs         = new List <Debug_MCH>();
            List <TextureHandler> texturesList = new List <TextureHandler>();
            int i = 0;

            MemoryStream ms = null;

            using (BinaryReader br = new BinaryReader(ms = new MemoryStream(this.buffer)))
            {
                uint eof = br.ReadUInt32();
                TIM2 tim;
                while (ms.CanRead)
                {
                    if (ms.Position >= ms.Length)
                    {
                        break;
                    }
                    else if (BitConverter.ToUInt16(this.buffer, (int)ms.Position) == 0)
                    {
                        ms.Seek(2, SeekOrigin.Current);
                    }
                    else if (br.ReadUInt64() == 0x0000000800000010)
                    {
                        ms.Seek(-8, SeekOrigin.Current);
                        tim = new TIM2(this.buffer, (uint)ms.Position);
                        ms.Seek(tim.GetHeight * tim.GetWidth / 2 + 64, SeekOrigin.Current); //i.e. 64*20=1280/2=640 + 64= 704 + eof
                        texturesList.Add(TextureHandler.Create($"chara_tim{(i++).ToString("D2")}", tim, 0, null));
                    }
                    else //is geometry structure
                    {
                        ms.Seek(-8, SeekOrigin.Current);
                        Debug_MCH mch = new Debug_MCH(ms, br);
                        if (mch.bValid())
                        {
                            mchs.Add(mch);
                        }
                    }
                }
                ms = null;
            }
            mchInstances = mchs.ToArray();
            textures     = texturesList.ToArray();
        }
Пример #6
0
 private void Section38()
 {
     using (MemoryStream ms = new MemoryStream(buffer))
         using (BinaryReader br = new BinaryReader(ms))
         {
             ms.Seek(sectionPointers[38 - 1], SeekOrigin.Begin);
             var innerSec = GetInnerPointers(br);
             sec38_textures = new List <Texture2D[]>();
             for (int i = 0; i < innerSec.Length; i++)
             {
                 TIM2 tim = new TIM2(buffer, (uint)(sectionPointers[38 - 1] + innerSec[i]));
                 sec38_textures.Add(new Texture2D[tim.GetClutCount]);
                 for (ushort k = 0; k < sec38_textures[i].Length; k++)
                 {
                     sec38_textures[i][k] = tim.GetTexture(k, true);
                 }
             }
         }
 }
Пример #7
0
        private Textures(byte[] buffer, long byteOffset, string fileName)
        {
            //#if DEBUG
            //            //Dump for debug
            //            _br.BaseStream.Seek(start, SeekOrigin.Begin);
            //            using (BinaryWriter fs = new BinaryWriter(File.Create(Path.Combine(Path.GetTempPath(), $"{start}.dump"), (int)(_br.BaseStream.Length - _br.BaseStream.Position), FileOptions.None)))
            //                fs.Write(_br.ReadBytes((int)(_br.BaseStream.Length - _br.BaseStream.Position)));
            //#endif
            IReadOnlyList <uint> pTim;

            using (var br = new BinaryReader(new MemoryStream(buffer)))
            {
                br.BaseStream.Seek(byteOffset, SeekOrigin.Begin);
                //Begin create Textures struct
                //populate the tim Count;
                var cTim = br.ReadInt32();
                //create arrays per Count and Read pointers into array
                pTim = Enumerable.Range(0, cTim).Select(_ => (uint)(byteOffset + br.ReadUInt32())).ToList()
                       .AsReadOnly();
                //Read EOF
                Eof = br.ReadUInt32();
            }

            //Read TIM -> TextureHandler into array
            TextureHandler getTexture(uint offset, int i)
            {
                if (buffer[offset] == 0x10)
                {
                    var tm       = new TIM2(buffer, offset); //broken
                    var filename = $"{fileName}_{i}";
                    var path     = Path.Combine(Path.GetTempPath(), "battle.dat");
                    Directory.CreateDirectory(path);
                    //tm.SavePNG(Path.Combine(path,filename));
                    return(TextureHandler.Create(filename, tm)); // tm.GetTexture(0);
                }
                Memory.Log.WriteLine($"{nameof(Textures)}::{nameof(getTexture)}.{offset} :: Not a tim file!");
                return(null);
            }

            _textures = pTim.Select(getTexture).ToList().AsReadOnly();
        }
Пример #8
0
 /// <summary>
 /// Section 39: Textures of roads, train tracks and bridge
 /// </summary>
 private void Section39()
 {
     using (MemoryStream ms = new MemoryStream(buffer))
         using (BinaryReader br = new BinaryReader(ms))
         {
             ms.Seek(sectionPointers[39 - 1], SeekOrigin.Begin);
             var innerSec = GetInnerPointers(br);
             sec39_texture = new Texture2D(Memory.graphics.GraphicsDevice, VRAM_TEXBLOCKWIDTH, VRAM_TEXBLOCKHEIGHT, false, SurfaceFormat.Color);
             for (int i = 0; i < innerSec.Length; i++)
             {
                 TIM2      tim         = new TIM2(buffer, (uint)(sectionPointers[39 - 1] + innerSec[i]));
                 Texture2D atlasChunk  = tim.GetTexture(0, true);
                 byte[]    chunkBuffer = new byte[atlasChunk.Width * atlasChunk.Height * 4];
                 atlasChunk.GetData(chunkBuffer, 0, chunkBuffer.Length);
                 int newX = tim.GetOrigX - SEC39_VRAM_STARTX;
                 int newY = tim.GetOrigY - SEC39_VRAM_STARTY;
                 newX = (newX / VRAM_BLOCKSTEP) * VRAM_BLOCKSIZE;
                 sec39_texture.SetData(0, new Microsoft.Xna.Framework.Rectangle(newX, newY, atlasChunk.Width, atlasChunk.Height), chunkBuffer, 0, chunkBuffer.Length);
             }
         }
 }
Пример #9
0
        /// <summary>
        /// Method designed for Stage texture loading.
        /// </summary>
        /// <param name="texturePointer">Absolute pointer to TIM texture header in stageBuffer</param>
        private void ReadTexture(uint texturePointer, BinaryReader br)
        {
            TIM2 textureInterface = new TIM2(br, texturePointer);

            if (Memory.EnableDumpingData || EnableDumpingData)
            {
                IEnumerable <Model> temp = (from mg in modelGroups
                                            from m in mg
                                            select m).Where(x => x.vertices != null && x.triangles != null && x.quads != null);
                //IOrderedEnumerable<byte> cluts = temp.SelectMany(x => x.quads.Select(y => y.clut)).Union(temp.SelectMany(x => x.triangles.Select(y => y.clut))).Distinct().OrderBy(x => x);
                //IOrderedEnumerable<byte> unks = temp.SelectMany(x => x.quads.Select(y => y.UNK)).Union(temp.SelectMany(x => x.triangles.Select(y => y.UNK))).Distinct().OrderBy(x => x);
                //IOrderedEnumerable<byte> hides = temp.SelectMany(x => x.quads.Select(y => y.bHide)).Union(temp.SelectMany(x => x.triangles.Select(y => y.bHide))).Distinct().OrderBy(x => x);
                //IOrderedEnumerable<byte> gpu = temp.SelectMany(x => x.quads.Select(y => y.GPU)).Union(temp.SelectMany(x => x.triangles.Select(y => y.GPU))).Distinct().OrderBy(x => x);
                //IOrderedEnumerable<Color> color = temp.SelectMany(x => x.quads.Select(y => y.Color)).Union(temp.SelectMany(x => x.triangles.Select(y => y.Color))).Distinct().OrderBy(x => x.R).ThenBy(x => x.G).ThenBy(x => x.B);
                var tuv = (from m in temp
                           where m.triangles != null && m.triangles.Length > 0
                           from t in m.triangles
                           where t != null
                           select new { t.clut, t.TexturePage, t.MinUV, t.MaxUV, t.Rectangle }).Distinct().OrderBy(x => x.TexturePage).ThenBy(x => x.clut).ToList();
                var quv = (from m in temp
                           where m.quads != null && m.quads.Length > 0
                           from q in m.quads
                           where q != null
                           select new { q.clut, q.TexturePage, q.MinUV, q.MaxUV, q.Rectangle }).Distinct().OrderBy(x => x.TexturePage).ThenBy(x => x.clut) /*.Where(x => x.Rectangle.Height > 0 && x.Rectangle.Width > 0)*/.ToList();
                var all = tuv.Union(quv);
                foreach (var tpGroup in all.GroupBy(x => x.TexturePage))
                {
                    byte texturepage = tpGroup.Key;
                    foreach (var clutGroup in tpGroup.GroupBy(x => x.clut))
                    {
                        byte   clut     = clutGroup.Key;
                        string filename = Path.GetFileNameWithoutExtension(Memory.Encounters.Filename);
                        string p        = Path.Combine(Path.GetTempPath(), "Battle Stages", filename, "Reference");
                        Directory.CreateDirectory(p);
                        filename = $"{filename}_{clut}_{texturepage}.png";
                        using (Texture2D tex = textureInterface.GetTexture(clut))
                            using (RenderTarget2D tmp = new RenderTarget2D(Memory.graphics.GraphicsDevice, 256, 256))
                            {
                                Memory.graphics.GraphicsDevice.SetRenderTarget(tmp);
                                Memory.SpriteBatchStartAlpha();
                                Memory.graphics.GraphicsDevice.Clear(Color.TransparentBlack);
                                foreach (Rectangle r in clutGroup.Select(x => x.Rectangle))
                                {
                                    Rectangle src = r;
                                    Rectangle dst = r;
                                    src.Offset(texturepage * 128, 0);
                                    Memory.spriteBatch.Draw(tex, dst, src, Color.White);
                                }
                                Memory.SpriteBatchEnd();
                                Memory.graphics.GraphicsDevice.SetRenderTarget(null);
                                using (FileStream fs = new FileStream(Path.Combine(p, filename), FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
                                    tmp.SaveAsPng(fs, 256, 256);
                            }
                    }
                }
            }
            Width  = textureInterface.GetWidth;
            Height = textureInterface.GetHeight;
            string path = Path.Combine(Path.GetTempPath(), "Battle Stages", Path.GetFileNameWithoutExtension(Memory.Encounters.Filename));

            Directory.CreateDirectory(path);

            if (Memory.EnableDumpingData || EnableDumpingData)
            {
                string fullpath = Path.Combine(path, $"{Path.GetFileNameWithoutExtension(Memory.Encounters.Filename)}_Clut.png");
                if (!File.Exists(fullpath))
                {
                    textureInterface.SaveCLUT(fullpath);
                }
            }

            textures = new TextureHandler[textureInterface.GetClutCount];
            for (ushort i = 0; i < textureInterface.GetClutCount; i++)
            {
                textures[i] = TextureHandler.Create(Memory.Encounters.Filename, textureInterface, i);
                if (Memory.EnableDumpingData || EnableDumpingData)
                {
                    textures[i].Save(path, false);
                }
            }
        }
Пример #10
0
        private void ReadBuffer(byte[] oneBuffer)
        {
            List <CharaModelHeaders> cmh = new List <CharaModelHeaders>();
            int lastMsPosition           = 0;

            using (MemoryStream ms = new MemoryStream(oneBuffer))
                using (BinaryReader br = new BinaryReader(ms))
                {
                    uint nModels = br.ReadUInt32();
                    for (int i = 0; i < nModels; i++)
                    {
                        CharaModelHeaders localCmh = new CharaModelHeaders
                        {
                            offset    = br.ReadUInt32() + 4,
                            size      = br.ReadUInt32(),
                            size2     = br.ReadUInt32(),
                            flagDWORD = br.ReadUInt32()
                        };
                        bool bIgnorePadding = false;
                        bool bMainChara     = false;
                        if (localCmh.flagDWORD >> 24 == 0xD0) //main character file
                        {
                            localCmh.timOffset       = new uint[0];
                            localCmh.modelDataOffset = 0xFFFFFFFF;
                            ms.Seek(4, SeekOrigin.Current);
                            bMainChara = true;
                        }
                        else if (localCmh.flagDWORD >> 24 == 0xa0) //unknown- object without texture/ placeholder?
                        {
                            localCmh.timOffset       = new uint[0];
                            localCmh.modelDataOffset = 0xFFFFFFFF;
                            ms.Seek(8, SeekOrigin.Current);
                            bIgnorePadding = true;
                        }
                        else
                        {
                            List <uint> timOffsets    = new List <uint>();
                            uint        flagTimOffset = localCmh.flagDWORD & 0x00FFFFFF;

                            timOffsets.Add(localCmh.flagDWORD << 8);
                            uint localTimOffset;
                            while ((localTimOffset = br.ReadUInt32()) != 0xFFFFFFFF)
                            {
                                timOffsets.Add(localTimOffset & 0x00FFFFFF);
                            }
                            localCmh.timOffset       = timOffsets.ToArray();
                            localCmh.modelDataOffset = br.ReadUInt32();
                        }
                        localCmh.modelName = br.ReadChars(8);
                        localCmh.padding   = br.ReadUInt32();
                        if (localCmh.padding != 0xEEEEEEEE && !bIgnorePadding) //null models for placeholders are 2 not eeeeeeee
                        {
                            throw new Exception("Chara one- padding was not 0xEEEEEEEE- check code for ReadBuffer in FieldCharaOne");
                        }

                        if (localCmh.modelDataOffset != 0xFFFFFFFF)
                        {
                            lastMsPosition = (int)ms.Position;
                            ms.Seek(localCmh.offset + localCmh.modelDataOffset, SeekOrigin.Begin);
                            localCmh.mch = new Debug_MCH(ms, br, Debug_MCH.mchMode.FieldNPC, 3f);
                            //ms.Seek(localCmh.offset + 4, SeekOrigin.Begin);
                            List <Texture2D> texList = new List <Texture2D>();
                            for (int n = 0; n < localCmh.timOffset.Length; n++)
                            {
                                if (localCmh.timOffset[n] > 0x10000000)
                                {
                                    localCmh.timOffset[n] = localCmh.timOffset[n] & 0x00FFFFFF;
                                }
                                TIM2 localTim = new TIM2(br, localCmh.offset + localCmh.timOffset[n]);
                                texList.Add(localTim.GetTexture());
                            }
                            localCmh.textures = texList.ToArray();
                            ms.Seek(lastMsPosition, SeekOrigin.Begin);
                        }
                        else if (bMainChara)
                        {
                            lastMsPosition = (int)ms.Position;
                            //this is main chara, so please grab data from main_chr.fs
                            int getRefId = int.Parse(new string(localCmh.modelName).Substring(1, 3));
                            var chara    = FieldMainCharaOne.MainFieldCharacters.Where(x => x.id == getRefId).First();
                            localCmh.modelDataOffset = 1;
                            localCmh.mch             = chara.mch;
                            localCmh.textures        = chara.textures;
                            ms.Seek(localCmh.offset, SeekOrigin.Begin);
                            localCmh.mch.MergeAnimations(ms, br);
                            ms.Seek(lastMsPosition, SeekOrigin.Begin);
                        }

                        cmh.Add(localCmh);
                    }
                }
            fieldModels = cmh.ToArray();
        }
Пример #11
0
        private void ReadBuffer(byte[] oneBuffer)
        {
            var cmh = new List <CharaModelHeaders>();

            using (var ms = new MemoryStream(oneBuffer))
                using (var br = new BinaryReader(ms))
                {
                    var nModels = br.ReadUInt32();
                    for (var i = 0; i < nModels; i++)
                    {
                        var localCmh = new CharaModelHeaders
                        {
                            Offset    = br.ReadUInt32() + 4,
                            Size      = br.ReadUInt32(),
                            Size2     = br.ReadUInt32(),
                            FlagDword = br.ReadUInt32()
                        };
                        var bIgnorePadding = false;
                        var bMainChara     = false;
                        if (localCmh.FlagDword >> 24 == 0xD0) //main character file
                        {
                            localCmh.TIMOffset       = new uint[0];
                            localCmh.ModelDataOffset = 0xFFFFFFFF;
                            ms.Seek(4, SeekOrigin.Current);
                            bMainChara = true;
                        }
                        else if (localCmh.FlagDword >> 24 == 0xa0) //unknown- object without texture/ placeholder?
                        {
                            localCmh.TIMOffset       = new uint[0];
                            localCmh.ModelDataOffset = 0xFFFFFFFF;
                            ms.Seek(8, SeekOrigin.Current);
                            bIgnorePadding = true;
                        }
                        else
                        {
                            var timOffsets = new List <uint>();
                            // ReSharper disable once UnusedVariable
                            var flagTimOffset = localCmh.FlagDword & 0x00FFFFFF;

                            timOffsets.Add(localCmh.FlagDword << 8);
                            uint localTimOffset;
                            while ((localTimOffset = br.ReadUInt32()) != 0xFFFFFFFF)
                            {
                                timOffsets.Add(localTimOffset & 0x00FFFFFF);
                            }
                            localCmh.TIMOffset       = timOffsets.ToArray();
                            localCmh.ModelDataOffset = br.ReadUInt32();
                        }
                        localCmh.ModelName = br.ReadChars(8);
                        localCmh.Padding   = br.ReadUInt32();
                        if (localCmh.Padding != 0xEEEEEEEE && !bIgnorePadding) //null models for placeholders are 2 not eeeeeeee
                        {
                            throw new Exception("Chara one- padding was not 0xEEEEEEEE- check code for ReadBuffer in FieldCharaOne");
                        }

                        int lastMsPosition;
                        if (localCmh.ModelDataOffset != 0xFFFFFFFF)
                        {
                            lastMsPosition = (int)ms.Position;
                            ms.Seek(localCmh.Offset + localCmh.ModelDataOffset, SeekOrigin.Begin);
                            localCmh.MCH = new Debug_MCH(ms, br, Debug_MCH.mchMode.FieldNPC, 3f);
                            //ms.Seek(localCmh.offset + 4, SeekOrigin.Begin);
                            var texList = new List <Texture2D>();
                            for (var n = 0; n < localCmh.TIMOffset.Length; n++)
                            {
                                if (localCmh.TIMOffset[n] > 0x10000000)
                                {
                                    localCmh.TIMOffset[n] = localCmh.TIMOffset[n] & 0x00FFFFFF;
                                }
                                var localTim = new TIM2(br, localCmh.Offset + localCmh.TIMOffset[n]);
                                texList.Add(localTim.GetTexture());
                            }
                            localCmh.Textures = texList.ToArray();
                            ms.Seek(lastMsPosition, SeekOrigin.Begin);
                        }
                        else if (bMainChara)
                        {
                            lastMsPosition = (int)ms.Position;
                            //this is main chara, so please grab data from main_chr.fs
                            var getRefId = int.Parse(new string(localCmh.ModelName).Substring(1, 3));
                            var chara    = FieldMainCharaOne.MainFieldCharacters.First(x => x.ID == getRefId);
                            localCmh.ModelDataOffset = 1;
                            localCmh.MCH             = chara.MCH;
                            localCmh.Textures        = chara.Textures;
                            ms.Seek(localCmh.Offset, SeekOrigin.Begin);
                            localCmh.MCH.MergeAnimations(ms, br);
                            ms.Seek(lastMsPosition, SeekOrigin.Begin);
                        }

                        cmh.Add(localCmh);
                    }
                }
            FieldModels = cmh.ToArray();
        }