Example #1
0
        private static DWordTexture ConvertTexture(WordTexture t)
        {
            var ret = new DWordTexture(new uint[256][]);
            for (var y = 0; y < 256; y++)
            {
                ret.Pixels[y] = new uint[256];

                for (var x = 0; x < 256; x++)
                {
                    var color = t.Pixels[y][x];
                    uint val = 0;
                    if ((color & 0x8000) != 0)
                    {
                        val = (uint)(
                            ((color & 0x00007c00) >> 7) 
                            | (((color & 0x000003e0) >> 2) << 8) 
                            | ((color & 0x0000001f) << 3 << 16) 
                            | 0xff000000);
                    }
                    ret.Pixels[y][x] = val;
                }
            }
            return ret;
        }
Example #2
0
        public void GenTexAndPalettesIfEmpty()
        {
            if (EngineVersion == Engine.TR2) return; // TR2 already has 8-bit, 16-bit and 32-bit tex and palette

            if ((Texture16 ?? new WordTexture[0]).Length == 0)
            {
                // Generate 16-bit textures
                Texture16 = new WordTexture[Textures.Length];
                for (var i = 0; i < Texture16.Length; i++)
                {
                    Texture16[i] = new WordTexture(new ushort[256][]);
                    for (var y = 0; y < 256; y++)
                    {
                        Texture16[i].Pixels[y] = new ushort[256];

                        for (var x = 0; x < 256; x++)
                        {
                            Texture16[i].Pixels[y][x] = new ByteColor(Textures[i].Pixels[y][x]).ToUInt16();
                        }
                    }
                }
            }

            

            if (WriteGameVersion < TRGame.TR4 && (Equals(Palette, default(Palette)) || (Texture8 ?? new ByteTexture[0]).Length == 0))
            {
                unsafe
                {
                    Texture8 = new ByteTexture[Textures.Length];

                    var bigBmp = new Bitmap(Textures.Length * 256, 256, PixelFormat.Format32bppArgb);
                    for (var bi = 0; bi < Textures.Length; bi++)
                    {
                        var bt = Textures[bi];
                        var bmp = new Bitmap(256, 256, PixelFormat.Format32bppArgb);
                        var bmpData = bmp.LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.WriteOnly,
                            PixelFormat.Format32bppArgb);
                        var scan0 = (uint*)bmpData.Scan0;
                        for (var y = 0; y < 256; y++)
                        {
                            var scanline = bt.Pixels[y];
                            fixed (uint* ptr = scanline)
                            {
                                for (var i = 0; i < 256; i++)
                                    scan0[y * 256 + i] = (ptr[i] & 0xff00ff00) |
                                                         ((ptr[i] & 0x00ff0000) >> 16) |
                                                         ((ptr[i] & 0x000000ff) << 16);
                            }
                        }
                        bmp.UnlockBits(bmpData);
                        using (var gr = Graphics.FromImage(bigBmp))
                            gr.DrawImage(bmp, new Rectangle(bi * 256, 0, 256, 256), 0, 0, 256, 256, GraphicsUnit.Pixel);
                    }
                    var bmp8 = bigBmp.Clone(new Rectangle(0, 0, bigBmp.Width, 256), PixelFormat.Format8bppIndexed);
                    Palette = new Palette() { Colour = bmp8.Palette.Entries.Select(x => (ByteColor)x).ToArray().Resize(256) };

                    for (var i = 0; i < Textures.Length; i++)
                    {
                        Texture8[i] = new ByteTexture(new byte[256][]);

                        for (var y = 0; y < 256; y++)
                        {
                            Texture8[i].Pixels[y] = new byte[256];

                            for (var x = 0; x < 256; x++)
                            {
                                Texture8[i].Pixels[y][x] = (byte)Array.IndexOf(bmp8.Palette.Entries, bmp8.GetPixel(i * 256 + x, y));
                            }
                        }
                    }




                    //Gen8bitPaletteFrom32bitTex(Textures);

                    // Generate 8-bit textures

                    /*for (var i = 0; i < Textures.Length; i++)
                    {
                        var tex = Textures[i];
                        Texture8[i] = new ByteTexture(new byte[256][]);
                        for (var y = 0; y < 256; y++)
                        {
                            Texture8[i].Pixels[y] = new byte[256];

                            for (var x = 0; x < 256; x++)
                            {
                                Texture8[i].Pixels[y][x] =
                                    (byte) Helper.closestColor1(Palette.Colour, new ByteColor(tex.Pixels[y][x]));
                            }
                        }
                    }*/
                }
            }
            if (WriteEngineVersion < Engine.TR4 && Equals(Palette16, default(Palette)))
            {
                Palette16 = new Palette {Colour = Palette.Colour.Select(x => new ByteColor(x.R, x.G, x.B, 0xFF)).ToArray()};
            }
        }
Example #3
0
        private void Load_TR4()
        {
            var version = reader.ReadUInt32();

            if (!version.IsAnyOf((uint)0x00345254, (uint)0x63345254, 0xFFFFFFF0))
                throw new ArgumentException("Load_TR4: Wrong level version");

            Texture16 = new WordTexture[0];

            var numRoomTextiles = reader.ReadUInt16();
            var numObjTextiles = reader.ReadUInt16();
            var numBumpTextiles = reader.ReadUInt16();
            var numMiscTextiles = 2;
            var numTextiles = numRoomTextiles + numObjTextiles + numBumpTextiles + numMiscTextiles;

            var uncompSize = reader.ReadUInt32();
            if (uncompSize == 0)
                throw new ArgumentException("Load_TR4: Textiles32 uncompSize == 0", nameof(uncompSize));

            var compSize = reader.ReadUInt32();
            if (compSize > 0)
            {
                var compBuffer = reader.ReadBytes((int) compSize);

                var newsrc_ = Helper.Decompress(compBuffer);
                Textures = newsrc_.ReadArray(numTextiles - numMiscTextiles, () => DWordTexture.Read(newsrc_));
            }

            uncompSize = reader.ReadUInt32();
            if (uncompSize == 0)
                throw new ArgumentException("Load_TR4: Textiles16 uncompSize == 0", nameof(uncompSize));

            compSize = reader.ReadUInt32();
            if (compSize > 0)
            {
                if (Textures.Length == 0)
                {
                    var compBuffer = reader.ReadBytes((int) compSize);

                    var newsrc_ = Helper.Decompress(compBuffer);
                    Texture16 = newsrc_.ReadArray(numTextiles - numMiscTextiles, () => WordTexture.Read(newsrc_));
                }
                else
                {
                    reader.BaseStream.Position += compSize;
                }
            }

            uncompSize = reader.ReadUInt32();
            if (uncompSize == 0)
                throw new ArgumentException("Load_TR4: Textiles32d uncompSize == 0", nameof(uncompSize));

            compSize = reader.ReadUInt32();
            if (compSize > 0)
            {
                if (Textures.Length == 0)
                {
                    // 262144 = 256*256*4
                    if (uncompSize / 262144 > 2)
                        Cerr.Write("Load_TR4: NumMiscTextiles > 2");

                    Array.Resize(ref Textures, numTextiles);

                    var compBuffer = reader.ReadBytes((int) compSize);

                    var newsrc_ = Helper.Decompress(compBuffer);
                    Textures = Textures.AddArray(newsrc_.ReadArray(numMiscTextiles, () => DWordTexture.Read(newsrc_)));
                }
                else
                {
                    reader.BaseStream.Position += compSize;
                }
            }

            uncompSize = reader.ReadUInt32();
            if (uncompSize == 0)
                throw new ArgumentException("Load_TR4: Packed geometry uncompSize == 0", nameof(uncompSize));

            compSize = reader.ReadUInt32();
            if (compSize == 0)
                throw new ArgumentException("Load_TR4: Packed geometry", nameof(compSize));

            var compBuffer_ = reader.ReadBytes((int) compSize);

            var newsrc = Helper.Decompress(compBuffer_);

            var unused = newsrc.ReadUInt32();
            if (unused != 0)
                Cerr.Write("Load_TR4: unused: Expected 0, Found " + unused.ToString("X8"));

            var numRooms = newsrc.ReadUInt16();
            Rooms = newsrc.ReadArray(numRooms, () => Room.Read(newsrc, Engine.TR4));

            var numFloorData = newsrc.ReadUInt32();
            FloorData = newsrc.ReadUInt16Array(numFloorData);

            var tmpr = reader;
            reader = newsrc;
            ReadMeshData();
            reader = tmpr;

            var numAnimations = newsrc.ReadUInt32();
            Animations = newsrc.ReadArray(numAnimations, () => Animation.Read(newsrc, Engine.TR4));

            var numStateChanges = newsrc.ReadUInt32();
            StateChanges = newsrc.ReadArray(numStateChanges, () => StateChange.Read(newsrc));

            var numAnimDispatches = newsrc.ReadUInt32();
            AnimDispatches = newsrc.ReadArray(numAnimDispatches, () => AnimDispatch.Read(newsrc));

            var numAnimCommands = newsrc.ReadUInt32();
            AnimCommands = newsrc.ReadInt16Array(numAnimCommands);

            var numMeshTreeData = newsrc.ReadUInt32();
            MeshTreeData = newsrc.ReadUInt32Array(numMeshTreeData);

            tmpr = reader;
            reader = newsrc;
            ReadFrameMoveableData();
            reader = tmpr;

            var numStaticMeshes = newsrc.ReadUInt32();
            StaticMeshes = newsrc.ReadArray(numStaticMeshes, () => StaticMesh.Read(newsrc));

            var spr1 = (char)newsrc.ReadSByte();
            var spr2 = (char)newsrc.ReadSByte();
            var spr3 = (char)newsrc.ReadSByte();
            var spr = "" + spr1 + spr2 + spr3;
            if(spr != "SPR")
                throw new ArgumentException("Load_TR4: Expected 'SPR', Found '" + spr + "'", nameof(spr));

            var numSpriteTextures = newsrc.ReadUInt32();
            SpriteTextures = newsrc.ReadArray(numSpriteTextures, () => SpriteTexture.Read(newsrc, Engine.TR4));

            var numSpriteSequences = newsrc.ReadUInt32();
            SpriteSequences = newsrc.ReadArray(numSpriteSequences, () => SpriteSequence.Read(newsrc));

            var numCameras = newsrc.ReadUInt32();
            Cameras = newsrc.ReadArray(numCameras, () => Camera.Read(newsrc));

            var numFlybyCameras = newsrc.ReadUInt32();
            FlybyCameras = newsrc.ReadArray(numFlybyCameras, () => FlybyCamera.Read(newsrc));

            var numSoundSources = newsrc.ReadUInt32();
            SoundSources = newsrc.ReadArray(numSoundSources, () => SoundSource.Read(newsrc));

            var numBoxes = newsrc.ReadUInt32();
            Boxes = newsrc.ReadArray(numBoxes, () => Box.Read(newsrc, Engine.TR2));

            var numOverlaps = newsrc.ReadUInt32();
            Overlaps = newsrc.ReadUInt16Array(numOverlaps);

            Zones = newsrc.ReadArray(numBoxes, () => Zone.Read(newsrc, Engine.TR2));

            var numAnimatedTextures = newsrc.ReadUInt32();
            AnimatedTextures = newsrc.ReadUInt16Array(numAnimatedTextures);

            AnimatedTexturesUVCount = newsrc.ReadByte();

            var tex1 = (char)newsrc.ReadSByte();
            var tex2 = (char)newsrc.ReadSByte();
            var tex3 = (char)newsrc.ReadSByte();
            var tex = "" + tex1 + tex2 + tex3;
            if (tex != "TEX")
                throw new ArgumentException("Load_TR4: Expected 'TEX', Found '" + tex + "'", nameof(tex));

            var numObjectTextures = newsrc.ReadUInt32();
            ObjectTextures = newsrc.ReadArray(numObjectTextures, () => ObjectTexture.Read(newsrc, Engine.TR4));

            var numItems = newsrc.ReadUInt32();
            Items = newsrc.ReadArray(numItems, () => Item.Read(newsrc, Engine.TR4));

            var numAiObjects = newsrc.ReadUInt32();
            AIObjects = newsrc.ReadArray(numAiObjects, () => AIObject.Read(newsrc));

            var numDemoData = newsrc.ReadUInt16();
            DemoData = newsrc.ReadBytes(numDemoData);

            SoundMap = newsrc.ReadInt16Array(Constants.TR_AUDIO_MAP_SIZE_TR4);

            var numSoundDetails = newsrc.ReadUInt32();
            SoundDetails = newsrc.ReadArray(numSoundDetails, () => Loader.SoundDetails.Read(newsrc, Engine.TR3));

            var numSampleIndices = newsrc.ReadUInt32();
            SampleIndices = newsrc.ReadUInt32Array(numSampleIndices);

            var numSamples = reader.ReadUInt32();
            if(numSamples > 0)
            {
                SamplesCount = (int) numSamples;
                SamplesData = reader.ReadBytes((int)(reader.BaseStream.Length - reader.BaseStream.Position));
            }

            if (Textures.Length == 0)
            {
                Textures = new DWordTexture[Texture16.Length];
                for (uint i = 0; i < Texture16.Length; i++)
                {
                    Textures[i] = ConvertTexture(Texture16[i]);
                }
            }
        }
Example #4
0
 /// <summary>
 /// Reads a <see cref="WordTexture"/>
 /// </summary>
 /// <param name="br">The <see cref="BinaryReader"/> used to read the <see cref="WordTexture"/></param>
 /// <returns>A <see cref="WordTexture"/></returns>
 public static WordTexture Read(BinaryReader br)
 {
     var ret = new WordTexture
     {
         Pixels = new ushort[256][]
     };
     for (var i = 0; i < 256; i++)
     {
         ret.Pixels[i] = br.ReadUInt16Array(256);
     }
     return ret;
 }
Example #5
0
        private void Load_TR5()
        {
            var version = reader.ReadUInt32();

            if (version != 0x00345254)
                throw new ArgumentException("Load_TR5: Wrong level version");

            var numRoomTextiles = reader.ReadUInt16();
            var numObjTextiles = reader.ReadUInt16();
            var numBumpTextiles = reader.ReadUInt16();
            var numMiscTextiles = 3;
            var numTextiles = numRoomTextiles + numObjTextiles + numBumpTextiles + numMiscTextiles;

            var uncompSize = reader.ReadUInt32();
            if (uncompSize == 0)
                throw new ArgumentException("Load_TR5: Textiles32 uncompSize == 0", nameof(uncompSize));

            var compSize = reader.ReadUInt32();
            if (compSize > 0)
            {
                var compBuffer = reader.ReadBytes((int)compSize);

                var newsrc = Helper.Decompress(compBuffer);
                Textures = newsrc.ReadArray(numTextiles - numMiscTextiles, () => DWordTexture.Read(newsrc));
            }

            uncompSize = reader.ReadUInt32();
            if (uncompSize == 0)
                throw new ArgumentException("Load_TR5: Textiles16 uncompSize == 0", nameof(uncompSize));

            compSize = reader.ReadUInt32();
            Texture16 = new WordTexture[0];
            if (compSize > 0)
            {
                if (Textures.Length == 0)
                {
                    var compBuffer = reader.ReadBytes((int)compSize);

                    var newsrc = Helper.Decompress(compBuffer);
                    Texture16 = newsrc.ReadArray(numTextiles - numMiscTextiles, () => WordTexture.Read(newsrc));
                }
                else
                {
                    reader.BaseStream.Position += compSize;
                }
            }

            uncompSize = reader.ReadUInt32();
            if (uncompSize == 0)
                throw new ArgumentException("Load_TR5: Textiles32d uncompSize == 0", nameof(uncompSize));

            compSize = reader.ReadUInt32();
            if (compSize > 0)
            {
                // 262144 = Width * Height * Depth
                //        =  256  *  256   *  4
                if (uncompSize / 262144 > 3)
                    Cerr.Write("Load_TR5: NumMiscTextiles > 3");

                var compBuffer = reader.ReadBytes((int) compSize);

                var newsrc = Helper.Decompress(compBuffer);
                var t = newsrc.ReadArray(numMiscTextiles, () => DWordTexture.Read(newsrc));

                Textures = Textures.AddArray(t);
            }

            LaraType = (LaraType) reader.ReadUInt16();
            WeatherType = (WeatherType) reader.ReadUInt16();

            var flags = reader.ReadUInt32Array(7); // 28 bytes zero padding
            for (var i = 0; i < flags.Length; i++)
            {
                if (flags[i] != 0)
                    Cerr.Write("Load_TR5: flags[" + (i + 1) + "]: Expected 0, Found 0x" + flags[i].ToString("X8"));
            }

            var levelUncompSize = reader.ReadUInt32();
            var levelCompSize = reader.ReadUInt32();

            var unused = reader.ReadUInt32();
            if(unused != 0)
                Cerr.Write("Load_TR5: unused: Expected 0, Found " + unused.ToString("X8"));

            var numRooms = reader.ReadUInt32();
            Rooms = reader.ReadArray(numRooms, () => Room.Read(reader, Engine.TR5));

            var numFloorData = reader.ReadUInt32();
            FloorData = reader.ReadUInt16Array(numFloorData);

            ReadMeshData();

            var numAnimations = reader.ReadUInt32();
            Animations = reader.ReadArray(numAnimations, () => Animation.Read(reader, Engine.TR4));

            var numStateChanges = reader.ReadUInt32();
            StateChanges = reader.ReadArray(numStateChanges, () => StateChange.Read(reader));

            var numAnimDispatches = reader.ReadUInt32();
            AnimDispatches = reader.ReadArray(numAnimDispatches, () => AnimDispatch.Read(reader));

            var numAnimCommands = reader.ReadUInt32();
            AnimCommands = reader.ReadInt16Array(numAnimCommands);

            var numMeshTreeData = reader.ReadUInt32();
            MeshTreeData = reader.ReadUInt32Array(numMeshTreeData);

            ReadFrameMoveableData();

            var numStaticMeshes = reader.ReadUInt32();
            StaticMeshes = reader.ReadArray(numStaticMeshes, () => StaticMesh.Read(reader));

            var spr1 = (char) reader.ReadSByte();
            var spr2 = (char) reader.ReadSByte();
            var spr3 = (char) reader.ReadSByte();
            var spr4 = (char) reader.ReadSByte();
            var spr = "" + spr1 + spr2 + spr3 + spr4;
            if (spr != "SPR\0")
                throw new ArgumentException("Load_TR5: Expected 'SPR', Found '" + spr + "'", nameof(spr));

            var numSpriteTextures = reader.ReadUInt32();
            SpriteTextures = reader.ReadArray(numSpriteTextures, () => SpriteTexture.Read(reader, Engine.TR4));

            var numSpriteSequences = reader.ReadUInt32();
            SpriteSequences = reader.ReadArray(numSpriteSequences, () => SpriteSequence.Read(reader));

            var numCameras = reader.ReadUInt32();
            Cameras = reader.ReadArray(numCameras, () => Camera.Read(reader));

            var numFlybyCameras = reader.ReadUInt32();
            FlybyCameras = reader.ReadArray(numFlybyCameras, () => FlybyCamera.Read(reader));

            var numSoundSources = reader.ReadUInt32();
            SoundSources = reader.ReadArray(numSoundSources, () => SoundSource.Read(reader));

            var numBoxes = reader.ReadUInt32();
            Boxes = reader.ReadArray(numBoxes, () => Box.Read(reader, Engine.TR2));

            var numOverlaps = reader.ReadUInt32();
            Overlaps = reader.ReadUInt16Array(numOverlaps);

            Zones = reader.ReadArray(numBoxes, () => Zone.Read(reader, Engine.TR2));

            var numAnimatedTextures = reader.ReadUInt32();
            AnimatedTextures = reader.ReadUInt16Array(numAnimatedTextures);

            AnimatedTexturesUVCount = reader.ReadByte();

            var tex1 = (char)reader.ReadSByte();
            var tex2 = (char)reader.ReadSByte();
            var tex3 = (char)reader.ReadSByte();
            var tex4 = (char) reader.ReadSByte();
            var tex = "" + tex1 + tex2 + tex3 + tex4;
            if (tex != "TEX\0")
                throw new ArgumentException("Load_TR5: Expected 'TEX', Found '" + tex + "'", nameof(tex));

            var numObjectTextures = reader.ReadUInt32();
            ObjectTextures = reader.ReadArray(numObjectTextures, () => ObjectTexture.Read(reader, Engine.TR5));

            var numItems = reader.ReadUInt32();
            Items = reader.ReadArray(numItems, () => Item.Read(reader, Engine.TR4));

            var numAiObjects = reader.ReadUInt32();
            AIObjects = reader.ReadArray(numAiObjects, () => AIObject.Read(reader));

            var numDemoData = reader.ReadUInt16();
            DemoData = reader.ReadBytes(numDemoData);

            SoundMap = reader.ReadInt16Array(Constants.TR_AUDIO_MAP_SIZE_TR5);

            var numSoundDetails = reader.ReadUInt32();
            SoundDetails = reader.ReadArray(numSoundDetails, () => Loader.SoundDetails.Read(reader, Engine.TR3));

            var numSampleIndices = reader.ReadUInt32();
            SampleIndices = reader.ReadUInt32Array(numSampleIndices);

            reader.BaseStream.Position += 6;

            var numSamples = reader.ReadUInt32();
            if (numSamples > 0)
            {
                SamplesCount = (int)numSamples;
                SamplesData = reader.ReadBytes((int)(reader.BaseStream.Length - reader.BaseStream.Position));
            }

            if (Textures.Length == 0)
            {
                Textures = new DWordTexture[Texture16.Length];
                for (uint i = 0; i < Texture16.Length; i++)
                {
                    Textures[i] = ConvertTexture(Texture16[i]);
                }
            }
        }