コード例 #1
0
        public long WriteTr3(BinaryWriterEx writer)
        {
            var meshOffset1 = writer.BaseStream.Position;

            writer.WriteBlock(Center);
            writer.Write(Radius);

            writer.Write(NumVertices);
            writer.WriteBlockArray(Vertices);

            writer.Write(NumNormals);
            if (NumNormals > 0)
            {
                writer.WriteBlockArray(Normals);
            }
            else if (NumNormals < 0)
            {
                writer.WriteBlockArray(Lights);
            }

            writer.Write(NumTexturedQuads);
            for (var k = 0; k < NumTexturedQuads; k++)
            {
                TexturedQuads[k].Write(writer);
            }
            // writer.WriteBlockArray(Meshes[i].TexturedRectangles);

            writer.Write(NumTexturedTriangles);
            for (var k = 0; k < NumTexturedTriangles; k++)
            {
                TexturedTriangles[k].Write(writer);
            }

            //  writer.WriteBlockArray(Meshes[i].TexturedTriangles);

            writer.Write(NumColoredRectangles);
            //writer.WriteBlockArray(Meshes[i].ColoredRectangles);

            writer.Write(NumColoredTriangles);
            //writer.WriteBlockArray(Meshes[i].ColoredTriangles);

            var meshOffset2 = writer.BaseStream.Position;
            var meshSize    = meshOffset2 - meshOffset1;

            if (meshSize % 4 != 0)
            {
                const ushort tempFiller = 0;
                writer.Write(tempFiller);
                meshSize += 2;
            }

            return(meshSize);
        }
コード例 #2
0
        public long WriteTr4AndTr5(BinaryWriterEx writer)
        {
            long meshOffset1 = writer.BaseStream.Position;

            writer.WriteBlock(Center);
            writer.Write(Radius);

            writer.Write(NumVertices);
            writer.WriteBlockArray(Vertices);

            writer.Write(NumNormals);
            if (NumNormals > 0)
            {
                writer.WriteBlockArray(Normals);
            }
            else if (NumNormals < 0)
            {
                writer.WriteBlockArray(Lights);
            }

            writer.Write(NumTexturedQuads);
            if (NumTexturedQuads != 0)
            {
                writer.WriteBlockArray(TexturedQuads);
            }

            writer.Write(NumTexturedTriangles);
            if (NumTexturedTriangles != 0)
            {
                writer.WriteBlockArray(TexturedTriangles);
            }

            var meshOffset2 = writer.BaseStream.Position;
            var meshSize    = meshOffset2 - meshOffset1;

            if (meshSize % 4 != 0)
            {
                const ushort tempFiller = 0;
                writer.Write(tempFiller);
                meshSize += 2;
            }

            return(meshSize);
        }
コード例 #3
0
        private void WriteLevelTr5Main()
        {
            // Now begin to compile the geometry block in a MemoryStream
            byte[] geometryDataBuffer;
            using (var geometryDataStream = new MemoryStream())
            {
                var writer = new BinaryWriterEx(geometryDataStream); // Don't dispose
                ReportProgress(80, "Writing geometry data to memory buffer");

                const int filler = 0;
                writer.Write(filler);

                var numRooms = (uint)_level.Rooms.Count(r => r != null);
                writer.Write(numRooms);

                foreach (var r in _level.Rooms.Where(r => r != null))
                {
                    _tempRooms[r].WriteTr5(writer);
                }

                // Write floordata
                var numFloorData = (uint)_floorData.Count;
                writer.Write(numFloorData);
                writer.WriteBlockArray(_floorData);

                // Write meshes
                var offset = writer.BaseStream.Position;

                const int numMeshData = 0;
                writer.Write(numMeshData);
                var totalMeshSize = 0;

                for (var i = 0; i < _meshes.Count; i++)
                {
                    var meshSize = _meshes[i].WriteTr4AndTr5(writer);
                    totalMeshSize += (int)meshSize;
                }

                var offset2 = writer.BaseStream.Position;
                // ReSharper disable once SuggestVarOrType_BuiltInTypes
                uint meshDataSize = (uint)((offset2 - offset - 4) / 2);

                // Save the size of the meshes
                writer.BaseStream.Seek(offset, SeekOrigin.Begin);
                writer.Write(meshDataSize);
                writer.BaseStream.Seek(offset2, SeekOrigin.Begin);

                // Write mesh pointers
                writer.Write((uint)_meshPointers.Count);
                writer.WriteBlockArray(_meshPointers);

                // Write animations' data
                writer.Write((uint)_animations.Count);
                foreach (var anim in _animations)
                {
                    anim.Write(writer, _level);
                }

                writer.Write((uint)_stateChanges.Count);
                writer.WriteBlockArray(_stateChanges);

                writer.Write((uint)_animDispatches.Count);
                writer.WriteBlockArray(_animDispatches);

                writer.Write((uint)_animCommands.Count);
                writer.WriteBlockArray(_animCommands);

                writer.Write((uint)_meshTrees.Count);
                writer.WriteBlockArray(_meshTrees);

                writer.Write((uint)_frames.Count);
                writer.WriteBlockArray(_frames);

                writer.Write((uint)_moveables.Count);
                for (var k = 0; k < _moveables.Count; k++)
                {
                    writer.WriteBlock(_moveables[k]);
                    writer.Write((ushort)0xfeff);
                }

                writer.Write((uint)_staticMeshes.Count);
                writer.WriteBlockArray(_staticMeshes);

                // SPR block
                writer.WriteBlockArray(new byte[] { 0x53, 0x50, 0x52, 0x00 });

                writer.Write((uint)_spriteTextures.Count);
                writer.WriteBlockArray(_spriteTextures);

                writer.Write((uint)_spriteSequences.Count);
                writer.WriteBlockArray(_spriteSequences);

                // Write camera, flyby and sound sources
                writer.Write((uint)_cameras.Count);
                writer.WriteBlockArray(_cameras);

                writer.Write((uint)_flyByCameras.Count);
                writer.WriteBlockArray(_flyByCameras);

                writer.Write((uint)_soundSources.Count);
                writer.WriteBlockArray(_soundSources);

                // Write pathfinding data
                writer.Write((uint)_boxes.Length);
                writer.WriteBlockArray(_boxes);

                writer.Write((uint)_overlaps.Length);
                writer.WriteBlockArray(_overlaps);

                for (var i = 0; i < _boxes.Length; i++)
                {
                    writer.Write(_zones[i].GroundZone1_Normal);
                }
                for (var i = 0; i < _boxes.Length; i++)
                {
                    writer.Write(_zones[i].GroundZone2_Normal);
                }
                for (var i = 0; i < _boxes.Length; i++)
                {
                    writer.Write(_zones[i].GroundZone3_Normal);
                }
                for (var i = 0; i < _boxes.Length; i++)
                {
                    writer.Write(_zones[i].GroundZone4_Normal);
                }
                for (var i = 0; i < _boxes.Length; i++)
                {
                    writer.Write(_zones[i].FlyZone_Normal);
                }
                for (var i = 0; i < _boxes.Length; i++)
                {
                    writer.Write(_zones[i].GroundZone1_Alternate);
                }
                for (var i = 0; i < _boxes.Length; i++)
                {
                    writer.Write(_zones[i].GroundZone2_Alternate);
                }
                for (var i = 0; i < _boxes.Length; i++)
                {
                    writer.Write(_zones[i].GroundZone3_Alternate);
                }
                for (var i = 0; i < _boxes.Length; i++)
                {
                    writer.Write(_zones[i].GroundZone4_Alternate);
                }
                for (var i = 0; i < _boxes.Length; i++)
                {
                    writer.Write(_zones[i].FlyZone_Alternate);
                }

                // Write animated textures
                _textureInfoManager.WriteAnimatedTextures(writer);

                // Write object textures
                writer.Write(checked ((byte)_textureInfoManager.UvRotateCount));
                writer.Write(new byte[] { 0x54, 0x45, 0x58, 0x00 });

                _textureInfoManager.WriteTextureInfos(writer, _level);

                // Write items and AI objects
                writer.Write((uint)_items.Count);
                writer.WriteBlockArray(_items);

                writer.Write((uint)_aiItems.Count);
                writer.WriteBlockArray(_aiItems);

                // Write sound meta data
                PrepareSoundsData();
                WriteSoundMetadata(writer);

                // Finish it
                writer.Write((ushort)0xcdcd);
                writer.Write((ushort)0xcdcd);
                writer.Write((ushort)0xcdcd);

                geometryDataBuffer = geometryDataStream.ToArray();
            }

            using (var fs = new FileStream(_dest, FileMode.Create, FileAccess.Write, FileShare.None))
            {
                using (var writer = new BinaryWriterEx(fs))
                {
                    ReportProgress(90, "Writing final level");
                    writer.WriteBlockArray(new byte[] { 0x54, 0x52, 0x34, 0x00 });

                    ReportProgress(91, "Writing textures");

                    // The room texture tile count currently also currently contains the wad textures
                    // But lets not bother with those fields too much since they only matter when bump maps are used and we don't use them.
                    writer.Write((ushort)_textureInfoManager.NumRoomPages);
                    writer.Write((ushort)_textureInfoManager.NumObjectsPages);
                    // Bump map pages must be multiplied by 2 or tile index will be wrong
                    writer.Write((ushort)(_textureInfoManager.NumBumpPages * 2));

                    // Compress data
                    ReportProgress(95, "Compressing data");

                    byte[] texture32 = null;
                    int    texture32UncompressedSize = -1;
                    byte[] texture16 = null;
                    int    texture16UncompressedSize = -1;
                    byte[] textureMisc = null;
                    int    textureMiscUncompressedSize = -1;
                    byte[] geometryData = geometryDataBuffer;
                    int    geometryDataUncompressedSize = geometryData.Length;

                    using (Task Texture32task = Task.Factory.StartNew(() =>
                    {
                        texture32 = ZLib.CompressData(_texture32Data);
                        texture32UncompressedSize = _texture32Data.Length;
                    }))
                        using (Task Texture16task = Task.Factory.StartNew(() =>
                        {
                            byte[] texture16Data = PackTextureMap32To16Bit(_texture32Data, _level.Settings);
                            texture16 = ZLib.CompressData(texture16Data);
                            texture16UncompressedSize = texture16Data.Length;
                        }))
                            using (Task textureMiscTask = Task.Factory.StartNew(() =>
                            {
                                Stream textureMiscData = PrepareFontAndSkyTexture();
                                textureMisc = ZLib.CompressData(textureMiscData);
                                textureMiscUncompressedSize = (int)textureMiscData.Length;
                            }))

                                Task.WaitAll(Texture32task, Texture16task, textureMiscTask);

                    // Write data
                    ReportProgress(97, "Writing compressed data to file.");

                    writer.Write(texture32UncompressedSize);
                    writer.Write(texture32.Length);
                    writer.Write(texture32);

                    writer.Write(texture16UncompressedSize);
                    writer.Write(texture16.Length);
                    writer.Write(texture16);

                    writer.Write(textureMiscUncompressedSize);
                    writer.Write(textureMisc.Length);
                    writer.Write(textureMisc);

                    writer.Write((ushort)_level.Settings.Tr5LaraType);
                    writer.Write((ushort)_level.Settings.Tr5WeatherType);

                    for (var i = 0; i < 28; i++)
                    {
                        writer.Write((byte)0);
                    }

                    // In TR5 geometry data is not compressed
                    writer.Write(geometryDataUncompressedSize);
                    writer.Write(geometryDataUncompressedSize);
                    writer.Write(geometryData);

                    ReportProgress(98, "Writing WAVE sounds");
                    WriteSoundData(writer);

                    // Write extra data
                    _volumeScripts = new List <VolumeScriptInstance>();

                    using (var ms = new MemoryStream())
                    {
                        var chunkIO = new ChunkWriter(new byte[] { 0x54, 0x52, 0x35, 0x4D }, new BinaryWriterFast(ms));

                        int currRoom = 0;
                        foreach (var r in _level.Rooms.Where(r => r != null))
                        {
                            // Add further extra data conditions here, otherwise compiler will skip this room altogether
                            if (r.Volumes.Count() > 0)
                            {
                                currRoom++;
                            }
                            else
                            {
                                currRoom++;
                                continue;
                            }

                            using (var extraRoomDataChunk = chunkIO.WriteChunk(Tr5MainExtraRoomData))
                            {
                                // First and only param after signature is internal room number
                                chunkIO.Raw.Write(currRoom);

                                using (var volumeListChunk = chunkIO.WriteChunk(Tr5MainChunkVolumeList))
                                {
                                    var trRoom = _tempRooms[r];

                                    foreach (var vol in r.Volumes)
                                    {
                                        using (var volumeChunk = chunkIO.WriteChunk(Tr5MainChunkVolume))
                                        {
                                            int scriptIndex = 0;
                                            if (_volumeScripts.Contains(vol.Scripts))
                                            {
                                                scriptIndex = _volumeScripts.IndexOf(vol.Scripts);
                                            }
                                            else
                                            {
                                                _volumeScripts.Add(vol.Scripts);
                                                scriptIndex = _volumeScripts.Count - 1;
                                            }

                                            // FIXME is it needed?
                                            int add = 0;
                                            if (vol is BoxVolumeInstance)
                                            {
                                                add = (int)((vol as BoxVolumeInstance).Size.Y / 2.0f);
                                            }

                                            var X = (int)Math.Round(trRoom.Info.X + vol.Position.X);
                                            var Y = (int)-Math.Round(r.WorldPos.Y + vol.Position.Y + add);
                                            var Z = (int)Math.Round(trRoom.Info.Z + vol.Position.Z);

                                            if (vol is BoxVolumeInstance)
                                            {
                                                chunkIO.Raw.Write(0);
                                            }
                                            else if (vol is SphereVolumeInstance)
                                            {
                                                chunkIO.Raw.Write(1);
                                            }
                                            else if (vol is PrismVolumeInstance)
                                            {
                                                chunkIO.Raw.Write(2);
                                            }

                                            chunkIO.Raw.Write(X);
                                            chunkIO.Raw.Write(Y);
                                            chunkIO.Raw.Write(Z);
                                            chunkIO.Raw.Write((short)vol.Activators);
                                            chunkIO.Raw.Write(scriptIndex);

                                            if (vol is BoxVolumeInstance)
                                            {
                                                var bv   = (BoxVolumeInstance)vol;
                                                var min  = vol.Position - (bv.Size / 2.0f);
                                                var max  = vol.Position + (bv.Size / 2.0f);
                                                var rotY = (ushort)Math.Max(0, Math.Min(ushort.MaxValue,
                                                                                        Math.Round(bv.RotationY * (65536.0 / 360.0))));
                                                var rotX = (ushort)Math.Max(0, Math.Min(ushort.MaxValue,
                                                                                        Math.Round(bv.RotationX * (65536.0 / 360.0))));

                                                chunkIO.Raw.Write(rotY);
                                                chunkIO.Raw.Write(rotX);
                                                chunkIO.Raw.Write((short)min.X);
                                                chunkIO.Raw.Write((short)min.Y);
                                                chunkIO.Raw.Write((short)min.Z);
                                                chunkIO.Raw.Write((short)max.X);
                                                chunkIO.Raw.Write((short)max.Y);
                                                chunkIO.Raw.Write((short)max.Z);
                                            }
                                            else if (vol is SphereVolumeInstance)
                                            {
                                                chunkIO.Raw.Write((vol as SphereVolumeInstance).Size);
                                            }
                                            else if (vol is PrismVolumeInstance)
                                            {
                                                var pv = (PrismVolumeInstance)vol;
                                                chunkIO.Raw.Write(pv.RotationY);
                                                chunkIO.Raw.Write(pv.Size);
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        /*
                         * using (var extraDataChunk = chunkIO.WriteChunk(Tr5MainExtraData))
                         * {
                         *  using (var volScriptListChunk = chunkIO.WriteChunk(Tr5MainChunkVolumeScriptList))
                         *  {
                         *      for (int i = 0; i < _volumeScripts.Count; i++)
                         *      {
                         *          var script = _volumeScripts[i];
                         *          using (var volScriptChunk = chunkIO.WriteChunk(Tr5MainChunkVolumeScript))
                         *          {
                         *              chunkIO.Raw.WriteStringUTF8(script.Name);
                         *
                         *              string onEnter = string.Empty;
                         *              string onInside = string.Empty;
                         *              string onLeave = string.Empty;
                         *
                         *              if (script.OnEnter.Trim().Length > 0)
                         *                  onEnter = "volscripts[" + i + "].OnEnter  = function(activator) \n" +
                         *                              _indent + script.OnEnter.Replace("\n", "\n" + _indent) + "\n" + "end;";
                         *
                         *              if (script.OnInside.Trim().Length > 0)
                         *                  onInside = "volscripts[" + i + "].OnInside = function(activator) \n" +
                         *                              _indent + script.OnInside.Replace("\n", "\n" + _indent) + "\n" + "end;";
                         *
                         *              if (script.OnLeave.Trim().Length > 0)
                         *                  onLeave  = "volscripts[" + i + "].OnLeave = function(activator) \n" +
                         *                              _indent + script.OnLeave.Replace("\n", "\n" + _indent) + "\n" + "end;";
                         *
                         *              string functionCode =
                         *                  onEnter  + (string.IsNullOrEmpty(onEnter)  ? string.Empty : "\n\n") +
                         *                  onInside + (string.IsNullOrEmpty(onInside) ? string.Empty : "\n\n") +
                         *                  onLeave  + (string.IsNullOrEmpty(onLeave)  ? string.Empty : "\n\n") ;
                         *
                         *              chunkIO.Raw.WriteStringUTF8(functionCode);
                         *          }
                         *      }
                         *  }
                         *
                         *  using (var chunkLuaIds = chunkIO.WriteChunk(Tr5MainChunkLuaIds))
                         *  {
                         *      for (int i = 0; i < _luaIdToItems.Count; i++)
                         *      {
                         *          chunkIO.WriteChunk(Tr5MainChunkLuaId, () =>
                         *          {
                         *              chunkIO.Raw.Write(_luaIdToItems.ElementAt(i).Key);
                         *              chunkIO.Raw.Write(_luaIdToItems.ElementAt(i).Value);
                         *          });
                         *      }
                         *  }
                         * }
                         */

                        chunkIO.Raw.Flush();

                        writer.Write((int)(ms.Length + 4));
                        writer.Write((int)(ms.Length + 4));
                        writer.Write(ms.ToArray(), 0, (int)ms.Length);
                        writer.Write((int)0);
                    }

                    ReportProgress(99, "Done");
                }
            }
        }
コード例 #4
0
        public TestLevel(string fileName, string outFileName = "")
        {
            this.fileName = fileName;

            FileStream     fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
            BinaryReaderEx reader     = new BinaryReaderEx(fileStream);

            byte[] buffer;

            reader.ReadBlock(out Version);
            reader.ReadBlock(out NumRoomTextureTiles);
            reader.ReadBlock(out NumObjectTextureTiles);
            reader.ReadBlock(out NumBumpTextureTiles);

            reader.ReadBlock(out Texture32UncompressedSize);
            reader.ReadBlock(out Texture32CompressedSize);

            Texture32 = new byte[Texture32CompressedSize];
            reader.ReadBlockArray(out Texture32, Texture32CompressedSize);
            Texture32 = ZLib.DecompressData(Texture32);

            ImageC img = ImageC.FromByteArray(Texture32, 256, (int)Texture32UncompressedSize / 262144 * 256);
            //img.Save("H:\\karnak.png");

            BinaryWriterEx wrttext = new BinaryWriterEx(new FileStream("textures.raw", FileMode.Create, FileAccess.Write, FileShare.None));

            wrttext.WriteBlockArray(Texture32);
            wrttext.Flush();
            wrttext.Close();

            reader.ReadBlock(out Texture16UncompressedSize);
            reader.ReadBlock(out Texture16CompressedSize);
            Texture16 = new byte[Texture16CompressedSize];
            reader.ReadBlockArray(out Texture16, Texture16CompressedSize);
            Texture16 = ZLib.DecompressData(Texture16);

            reader.ReadBlock(out MiscTextureUncompressedSize);
            reader.ReadBlock(out MiscTextureCompressedSize);
            MiscTexture = new byte[MiscTextureCompressedSize];
            reader.ReadBlockArray(out MiscTexture, MiscTextureCompressedSize);
            MiscTexture = ZLib.DecompressData(MiscTexture);

            reader.ReadBlock(out LevelUncompressedSize);
            reader.ReadBlock(out LevelCompressedSize);
            buffer = new byte[LevelCompressedSize];
            reader.ReadBlockArray(out buffer, LevelCompressedSize);
            buffer = ZLib.DecompressData(buffer);

            var stream = new MemoryStream();

            stream.Write(buffer, 0, (int)LevelUncompressedSize);
            stream.Seek(0, SeekOrigin.Begin);

            BinaryWriterEx wrt = new BinaryWriterEx(new FileStream("coastal.bin", FileMode.Create, FileAccess.Write, FileShare.None));

            wrt.Write(buffer, 0, (int)LevelUncompressedSize);
            wrt.Flush();
            wrt.Close();

            BinaryWriterEx wrs = new BinaryWriterEx(new FileStream("samples." + outFileName + ".bin", FileMode.Create, FileAccess.Write, FileShare.None));

            byte[] samples = reader.ReadBytes((int)(reader.BaseStream.Length - reader.BaseStream.Position));
            wrs.Write(samples);
            wrs.Flush();
            wrs.Close();

            reader.Close();

            reader = new BinaryReaderEx(stream);
            reader.ReadBlock(out Unused);
            reader.ReadBlock(out NumRooms);

            int max = 0;

            StreamWriter wp = new StreamWriter(new FileStream("portals" + outFileName + ".txt", FileMode.Create, FileAccess.Write, FileShare.None));

            Rooms = new tr_room[NumRooms];
            for (int i = 0; i < NumRooms; i++)
            {
                wp.WriteLine("=====================================================================");
                wp.WriteLine("ROOM #" + i);
                wp.WriteLine("=====================================================================");

                reader.ReadBlock(out Rooms[i].Info);
                reader.ReadBlock(out Rooms[i].NumDataWords);
                reader.ReadBlock(out Rooms[i].NumVertices);
                //  Rooms[i].Vertices = new tr_room_vertex[Rooms[i].NumVertices];
                reader.ReadBlockArray(out Rooms[i].Vertices, Rooms[i].NumVertices);
                if (Rooms[i].NumVertices > max)
                {
                    max = Rooms[i].NumVertices;
                }
                reader.ReadBlock(out Rooms[i].NumRectangles);
                Rooms[i].Rectangles = new tr_face4[Rooms[i].NumRectangles];
                for (int j = 0; j < Rooms[i].NumRectangles; j++)
                {
                    // Rooms[i].Rectangles[j].Vertices = new ushort[4];
                    reader.ReadBlockArray(out Rooms[i].Rectangles[j].Vertices, 4);
                    reader.ReadBlock(out Rooms[i].Rectangles[j].Texture);
                }

                reader.ReadBlock(out Rooms[i].NumTriangles);
                Rooms[i].Triangles = new tr_face3[Rooms[i].NumTriangles];
                for (int j = 0; j < Rooms[i].NumTriangles; j++)
                {
                    // Rooms[i].Triangles[j].Vertices = new ushort[3];
                    reader.ReadBlockArray(out Rooms[i].Triangles[j].Vertices, 3);
                    reader.ReadBlock(out Rooms[i].Triangles[j].Texture);
                }

                reader.ReadBlock(out Rooms[i].NumSprites);

                reader.ReadBlock(out Rooms[i].NumPortals);
                //Rooms[i].Portals = new tr_room_portal[Rooms[i].NumPortals];
                reader.ReadBlockArray(out Rooms[i].Portals, Rooms[i].NumPortals);

                for (int nn = 0; nn < Rooms[i].Portals.Length; nn++)
                {
                    tr_room_portal pt = Rooms[i].Portals[nn];
                    wp.WriteLine(nn + ": ");
                    wp.WriteLine("Room: " + pt.AdjoiningRoom);
                    for (int vv = 0; vv < 4; vv++)
                    {
                        wp.Write("V" + vv + " = " + pt.Vertices[vv].X + ", " + pt.Vertices[vv].Y + ", " + pt.Vertices[vv].Z);
                        wp.WriteLine("");
                    }
                    wp.WriteLine("");
                }

                reader.ReadBlock(out Rooms[i].NumZSectors);
                reader.ReadBlock(out Rooms[i].NumXSectors);
                //Rooms[i].Sectors = new tr_room_sector[Rooms[i].NumZSectors * Rooms[i].NumXSectors];
                reader.ReadBlockArray(out Rooms[i].Sectors, (uint)Rooms[i].NumZSectors * Rooms[i].NumXSectors);

                reader.ReadBlock(out Rooms[i].AmbientIntensity1);
                reader.ReadBlock(out Rooms[i].AmbientIntensity2);

                reader.ReadBlock(out Rooms[i].NumLights);
                reader.ReadBlockArray(out Rooms[i].Lights, Rooms[i].NumLights);

                reader.ReadBlock(out Rooms[i].NumStaticMeshes);
                reader.ReadBlockArray(out Rooms[i].StaticMeshes, Rooms[i].NumStaticMeshes);

                reader.ReadBlock(out Rooms[i].AlternateRoom);
                reader.ReadBlock(out Rooms[i].Flags);
                reader.ReadBlock(out Rooms[i].Param1);
                reader.ReadBlock(out Rooms[i].Unknown1);
                reader.ReadBlock(out Rooms[i].Unknown2);
            }

            wp.Flush();
            wp.Close();
            //return;

            reader.ReadBlock(out NumFloorData);
            reader.ReadBlockArray(out FloorData, NumFloorData);

            reader.ReadBlock(out NumMeshData);

            /*for (int i = 0; i < NumFloorData; i++)
             *  Console.WriteLine(FloorData[i].ToString("X2"));*/

            int   numBytes   = 0;
            int   totalBytes = 0;
            int   l          = 0;
            short temp       = 0;

            Meshes = new tr_mesh[2048];
            while (totalBytes < NumMeshData * 2)
            {
                long offset1 = reader.BaseStream.Position;

                reader.ReadBlock(out Meshes[l].Center);
                reader.ReadBlock(out Meshes[l].Radius);
                numBytes += 10;

                reader.ReadBlock(out Meshes[l].NumVertices);
                reader.ReadBlockArray(out Meshes[l].Vertices, Meshes[l].NumVertices);
                numBytes += 2 + 6 * Meshes[l].NumVertices;

                reader.ReadBlock(out Meshes[l].NumNormals);
                if (Meshes[l].NumNormals > 0)
                {
                    reader.ReadBlockArray(out Meshes[l].Normals, Meshes[l].NumNormals);
                    numBytes += 2 + 6 * Meshes[l].NumNormals;
                }
                else
                {
                    reader.ReadBlockArray(out Meshes[l].Lights, -Meshes[l].NumNormals);
                    numBytes += 2 - 2 * Meshes[l].NumNormals;
                }

                reader.ReadBlock(out Meshes[l].NumTexturedRectangles);
                reader.ReadBlockArray(out Meshes[l].TexturedRectangles, Meshes[l].NumTexturedRectangles);
                numBytes += 2 + 12 * Meshes[l].NumTexturedRectangles;

                reader.ReadBlock(out Meshes[l].NumTexturedTriangles);
                reader.ReadBlockArray(out Meshes[l].TexturedTriangles, Meshes[l].NumTexturedTriangles);
                numBytes += 2 + 10 * Meshes[l].NumTexturedTriangles;

                long offset2 = reader.BaseStream.Position;
                int  diff    = (int)(offset2 - offset1);
                if (diff % 4 != 0)
                {
                    reader.ReadBlock(out temp); diff += 2;
                }
                Meshes[l].MeshSize    = numBytes;
                Meshes[l].MeshPointer = totalBytes;

                if (l == 209)
                {
                    BinaryWriterEx tmpwriter = new BinaryWriterEx(new FileStream("cleopal.msh", FileMode.Create, FileAccess.Write, FileShare.None));
                    tmpwriter.WriteBlock(Meshes[l].Center);
                    tmpwriter.WriteBlock(Meshes[l].Radius);
                    tmpwriter.WriteBlock(Meshes[l].NumVertices);
                    tmpwriter.WriteBlockArray(Meshes[l].Vertices);
                    tmpwriter.WriteBlock(Meshes[l].NumNormals);
                    if (Meshes[l].NumNormals > 0)
                    {
                        tmpwriter.WriteBlockArray(Meshes[l].Normals);
                    }
                    else
                    {
                        tmpwriter.WriteBlockArray(Meshes[l].Lights);
                    }
                    tmpwriter.WriteBlock(Meshes[l].NumTexturedRectangles);
                    tmpwriter.WriteBlockArray(Meshes[l].TexturedRectangles);
                    tmpwriter.WriteBlock(Meshes[l].NumTexturedTriangles);
                    tmpwriter.WriteBlockArray(Meshes[l].TexturedTriangles);

                    tmpwriter.Flush();
                    tmpwriter.Close();
                }

                totalBytes += diff;// numBytes;
                numBytes    = 0;
                l++;
            }

            Array.Resize(ref Meshes, l);

            NumMeshes = (uint)Meshes.Length;

            reader.ReadBlock(out NumMeshPointers);
            reader.ReadBlockArray(out MeshPointers, NumMeshPointers);

            reader.ReadBlock(out NumAnimations);
            reader.ReadBlockArray(out Animations, NumAnimations);

            reader.ReadBlock(out NumStateChanges);
            reader.ReadBlockArray(out StateChanges, NumStateChanges);

            reader.ReadBlock(out NumAnimDispatches);
            reader.ReadBlockArray(out AnimDispatches, NumAnimDispatches);

            reader.ReadBlock(out NumAnimCommands);
            reader.ReadBlockArray(out AnimCommands, NumAnimCommands);

            reader.ReadBlock(out NumMeshTrees);
            reader.ReadBlockArray(out MeshTrees, NumMeshTrees);

            logger.Debug(reader.BaseStream.Position.ToString());
            reader.ReadBlock(out NumFrames);
            reader.ReadBlockArray(out Frames, NumFrames);

            reader.ReadBlock(out NumMoveables);
            reader.ReadBlockArray(out Moveables, NumMoveables);

            reader.ReadBlock(out NumStaticMeshes);
            reader.ReadBlockArray(out StaticMeshes, NumStaticMeshes);

            reader.ReadBlockArray(out SPR, 3);

            reader.ReadBlock(out NumSpriteTextures);
            reader.ReadBlockArray(out SpriteTextures, NumSpriteTextures);

            reader.ReadBlock(out NumSpriteSequences);
            reader.ReadBlockArray(out SpriteSequences, NumSpriteSequences);

            reader.ReadBlock(out NumCameras);
            reader.ReadBlockArray(out Cameras, NumCameras);

            reader.ReadBlock(out NumFlyByCameras);
            reader.ReadBlockArray(out FlyByCameras, NumFlyByCameras * 40);

            reader.ReadBlock(out NumSoundSources);
            reader.ReadBlockArray(out SoundSources, NumSoundSources);

            reader.ReadBlock(out NumBoxes);
            reader.ReadBlockArray(out Boxes, NumBoxes);

            reader.ReadBlock(out NumOverlaps);
            reader.ReadBlockArray(out Overlaps, NumOverlaps);

            // reader.ReadBlockArray(out Zones, NumBoxes * 10);
            Zones = new short[NumBoxes * 10];
            for (int n = 0; n < NumBoxes * 10; n++)
            {
                Zones[n] = reader.ReadInt16();
            }

            reader.ReadBlock(out NumAnimatedTextures);
            short[] animTextures;
            reader.ReadBlockArray(out animTextures, NumAnimatedTextures);

            string fn = Path.GetFileNameWithoutExtension(fileName);

            if (File.Exists("pathfinding." + fn + "." + outFileName + ".txt"))
            {
                File.Delete("pathfinding." + fn + "." + outFileName + ".txt");
            }
            StreamWriter writer = new StreamWriter(new FileStream("pathfinding." + fn + "." + outFileName + ".txt", FileMode.Create, FileAccess.Write, FileShare.None));

            writer.WriteLine("BOXES");

            for (int n = 0; n < Boxes.Length; n++)
            {
                writer.WriteLine("[" + n + "] " + "Xmin: " + Boxes[n].Xmin + ", " + "Xmax: " + Boxes[n].Xmax + ", " +
                                 "Zmin: " + Boxes[n].Zmin + ", " + "Zmax: " + Boxes[n].Zmax + ", " +
                                 "Floor: " + Boxes[n].TrueFloor + ", Overlap Index: " + Boxes[n].OverlapIndex);
            }

            writer.WriteLine(" ");
            writer.WriteLine("OVERLAPS");

            for (int n = 0; n < Overlaps.Length; n++)
            {
                writer.WriteLine("[" + n + "] " + (Overlaps[n] & 0x7fff));
                if ((Overlaps[n] & 0x8000) != 0)
                {
                    writer.WriteLine("--- END OF LIST ---");
                }
            }

            writer.WriteLine(" ");
            writer.WriteLine("ZONES");

            for (int n = 0; n < Boxes.Length; n++)
            {
                /*writer.WriteLine("[" + n + "] " + "Ground1: " + Zones[n * 10 + 0] + ", " + "Ground2: " + Zones[n * 10 + 1] + ", " +
                 *               "Ground3: " + Zones[n * 10 + 2] + ", " + "Ground4: " + Zones[n * 10 + 3] + ", " +
                 *               "Fly: " + Zones[n * 10 + 4] + ", A_Ground1: " + Zones[n * 10 + 5] + ", " + "A_Ground2: " + Zones[n * 10 + 6] + ", " +
                 *               "A_Ground3: " + Zones[n * 10 + 7] + ", " + "A_Ground4: " + Zones[n * 10 + 8] + ", " +
                 *               "A_Fly: " + Zones[n * 10 + 9]);*/
                writer.WriteLine("[" + n + "] " + "Ground1: " + Zones[n] + ", " + "Ground2: " + Zones[1 * NumBoxes + n] + ", " +
                                 "Ground3: " + Zones[2 * NumBoxes + n] + ", " + "Ground4: " + Zones[3 * NumBoxes + n] + ", " +
                                 "Fly: " + Zones[4 * NumBoxes + n] + ", A_Ground1: " + Zones[5 * NumBoxes + n] + ", " + "A_Ground2: " + Zones[6 * NumBoxes + n] + ", " +
                                 "A_Ground3: " + Zones[7 * NumBoxes + n] + ", " + "A_Ground4: " + Zones[8 * NumBoxes + n] + ", " +
                                 "A_Fly: " + Zones[9 * NumBoxes + n]);
            }

            writer.Flush();
            writer.Close();

            reader.ReadBlockArray(out TEX, 4);

            reader.ReadBlock(out NumObjectTextures);
            reader.ReadBlockArray(out ObjectTextures, NumObjectTextures);

            if (File.Exists("textures." + fn + "." + outFileName + ".txt"))
            {
                File.Delete("textures." + fn + "." + outFileName + ".txt");
            }
            writer = new StreamWriter(new FileStream("textures." + fn + "." + outFileName + ".txt", FileMode.Create, FileAccess.Write, FileShare.None));

            for (int ii = 0; ii < NumObjectTextures; ii++)
            {
                writer.WriteLine("TEXTURE #" + ii);
                writer.WriteLine("    TileAndFlags: " + (ObjectTextures[ii].Tile).ToString());
                writer.WriteLine("    NewFlags: " + (ObjectTextures[ii].Flags).ToString());
                writer.WriteLine("    Tile: " + (ObjectTextures[ii].Tile & 0xFF).ToString());
                for (int jj = 0; jj < 4; jj++)
                {
                    writer.WriteLine("    " + jj + " X: " +
                                     ((ushort)(ObjectTextures[ii].Vertices[jj].Xpixel << 8 + ObjectTextures[ii].Vertices[jj].Xcoordinate)).ToString() +
                                     " Y: " +
                                     ((ushort)(ObjectTextures[ii].Vertices[jj].Ypixel << 8 + ObjectTextures[ii].Vertices[jj].Ycoordinate)).ToString() +
                                     " (" + ObjectTextures[ii].Vertices[jj].Xpixel + ", " + ObjectTextures[ii].Vertices[jj].Ypixel + ")");
                }

                /* BinaryWriterEx tmpwriter2 = new BinaryWriterEx(new FileStream("test\\cleopal_" + ii + ".text", FileMode.Create, FileAccess.Write, FileShare.None));
                 * tmpwriter2.WriteBlock(ObjectTextures[ii]);
                 * tmpwriter2.Flush();
                 * tmpwriter2.Close();*/
            }

            writer.Flush();
            writer.Close();

            reader.ReadBlock(out NumItems);
            reader.ReadBlockArray(out Items, NumItems);

            reader.ReadBlock(out NumAiItems);
            reader.ReadBlockArray(out AiItems, NumAiItems);

            StreamWriter aiw = new StreamWriter(new FileStream("AI" + outFileName + ".txt", FileMode.Create, FileAccess.Write, FileShare.None));

            for (int n = 0; n < NumAiItems; n++)
            {
                aiw.WriteLine("[" + n + "]");
                aiw.WriteLine("    ObjectID: " + AiItems[n].ObjectID);
                aiw.WriteLine("    X: " + AiItems[n].X);
                aiw.WriteLine("    Y: " + AiItems[n].Y);
                aiw.WriteLine("    Z: " + AiItems[n].Z);
                aiw.WriteLine("    Room: " + AiItems[n].Room);
                aiw.WriteLine("    Angle: " + AiItems[n].Angle);
            }

            aiw.Flush();
            aiw.Close();

            BinaryWriterEx bwex = new BinaryWriterEx(new FileStream("sounds" + outFileName + ".sfx", FileMode.Create, FileAccess.Write, FileShare.None));

            var numDemo = reader.ReadInt16();

            byte[] soundmap        = reader.ReadBytes((numDemo != 0 ? numDemo * 2 : 740));
            int    numSoundDetails = reader.ReadInt32();

            byte[] details    = reader.ReadBytes(8 * numSoundDetails);
            int    numIndices = reader.ReadInt32();

            byte[] indices = reader.ReadBytes(4 * numIndices);

            bwex.Write(soundmap);
            bwex.Write(numSoundDetails);
            bwex.Write(details);
            bwex.Write(numIndices);
            bwex.Write(indices);

            bwex.Flush();
            bwex.Close();

            List <byte> bytes = new List <byte>();

            while (reader.BaseStream.Position < reader.BaseStream.Length)
            {
                bytes.Add(reader.ReadByte());
            }
        }
コード例 #5
0
        private void WriteLevelTr5()
        {
            AddNecessaryTr5Items();

            // Now begin to compile the geometry block in a MemoryStream
            byte[] geometryDataBuffer;
            using (var geometryDataStream = new MemoryStream())
            {
                var writer = new BinaryWriterEx(geometryDataStream); // Don't dispose
                ReportProgress(80, "Writing geometry data to memory buffer");

                const int filler = 0;
                writer.Write(filler);

                var numRooms = (uint)_level.Rooms.Count(r => r != null);
                writer.Write(numRooms);

                foreach (var r in _level.Rooms.Where(r => r != null))
                {
                    _tempRooms[r].WriteTr5(writer);
                }

                // Write floordata
                var numFloorData = (uint)_floorData.Count;
                writer.Write(numFloorData);
                writer.WriteBlockArray(_floorData);

                // Write meshes
                var offset = writer.BaseStream.Position;

                const int numMeshData = 0;
                writer.Write(numMeshData);
                var totalMeshSize = 0;

                for (var i = 0; i < _meshes.Count; i++)
                {
                    var meshSize = _meshes[i].WriteTr4AndTr5(writer);
                    totalMeshSize += (int)meshSize;
                }

                var offset2 = writer.BaseStream.Position;
                // ReSharper disable once SuggestVarOrType_BuiltInTypes
                uint meshDataSize = (uint)((offset2 - offset - 4) / 2);

                // Save the size of the meshes
                writer.BaseStream.Seek(offset, SeekOrigin.Begin);
                writer.Write(meshDataSize);
                writer.BaseStream.Seek(offset2, SeekOrigin.Begin);

                // Write mesh pointers
                writer.Write((uint)_meshPointers.Count);
                writer.WriteBlockArray(_meshPointers);

                // Write animations' data
                writer.Write((uint)_animations.Count);
                foreach (var anim in _animations)
                {
                    anim.Write(writer, _level);
                }

                writer.Write((uint)_stateChanges.Count);
                writer.WriteBlockArray(_stateChanges);

                writer.Write((uint)_animDispatches.Count);
                writer.WriteBlockArray(_animDispatches);

                writer.Write((uint)_animCommands.Count);
                writer.WriteBlockArray(_animCommands);

                writer.Write((uint)_meshTrees.Count);
                writer.WriteBlockArray(_meshTrees);

                writer.Write((uint)_frames.Count);
                writer.WriteBlockArray(_frames);

                writer.Write((uint)_moveables.Count);
                for (var k = 0; k < _moveables.Count; k++)
                {
                    writer.WriteBlock(_moveables[k]);
                    writer.Write((ushort)0xfeff);
                }

                writer.Write((uint)_staticMeshes.Count);
                writer.WriteBlockArray(_staticMeshes);

                // SPR block
                writer.WriteBlockArray(new byte[] { 0x53, 0x50, 0x52, 0x00 });

                writer.Write((uint)_spriteTextures.Count);
                writer.WriteBlockArray(_spriteTextures);

                writer.Write((uint)_spriteSequences.Count);
                writer.WriteBlockArray(_spriteSequences);

                // Write camera, flyby and sound sources
                writer.Write((uint)_cameras.Count);
                writer.WriteBlockArray(_cameras);

                writer.Write((uint)_flyByCameras.Count);
                writer.WriteBlockArray(_flyByCameras);

                writer.Write((uint)_soundSources.Count);
                writer.WriteBlockArray(_soundSources);

                // Write pathfinding data
                writer.Write((uint)_boxes.Length);
                writer.WriteBlockArray(_boxes);

                writer.Write((uint)_overlaps.Length);
                writer.WriteBlockArray(_overlaps);

                for (var i = 0; i < _boxes.Length; i++)
                {
                    writer.Write(_zones[i].GroundZone1_Normal);
                }
                for (var i = 0; i < _boxes.Length; i++)
                {
                    writer.Write(_zones[i].GroundZone2_Normal);
                }
                for (var i = 0; i < _boxes.Length; i++)
                {
                    writer.Write(_zones[i].GroundZone3_Normal);
                }
                for (var i = 0; i < _boxes.Length; i++)
                {
                    writer.Write(_zones[i].GroundZone4_Normal);
                }
                for (var i = 0; i < _boxes.Length; i++)
                {
                    writer.Write(_zones[i].FlyZone_Normal);
                }
                for (var i = 0; i < _boxes.Length; i++)
                {
                    writer.Write(_zones[i].GroundZone1_Alternate);
                }
                for (var i = 0; i < _boxes.Length; i++)
                {
                    writer.Write(_zones[i].GroundZone2_Alternate);
                }
                for (var i = 0; i < _boxes.Length; i++)
                {
                    writer.Write(_zones[i].GroundZone3_Alternate);
                }
                for (var i = 0; i < _boxes.Length; i++)
                {
                    writer.Write(_zones[i].GroundZone4_Alternate);
                }
                for (var i = 0; i < _boxes.Length; i++)
                {
                    writer.Write(_zones[i].FlyZone_Alternate);
                }

                // Write animated textures
                _textureInfoManager.WriteAnimatedTextures(writer);

                // Write object textures
                writer.Write(checked ((byte)_textureInfoManager.UvRotateCount));
                writer.Write(new byte[] { 0x54, 0x45, 0x58, 0x00 });

                _textureInfoManager.WriteTextureInfos(writer, _level);

                // Write items and AI objects
                writer.Write((uint)_items.Count);
                writer.WriteBlockArray(_items);

                writer.Write((uint)_aiItems.Count);
                writer.WriteBlockArray(_aiItems);

                // Write sound meta data
                PrepareSoundsData();
                WriteSoundMetadata(writer);

                // Finish it
                writer.Write((ushort)0xcdcd);
                writer.Write((ushort)0xcdcd);
                writer.Write((ushort)0xcdcd);

                geometryDataBuffer = geometryDataStream.ToArray();
            }

            using (var writer = new BinaryWriterEx(new FileStream(_dest, FileMode.Create, FileAccess.Write, FileShare.None)))
            {
                ReportProgress(90, "Writing final level");
                writer.WriteBlockArray(new byte[] { 0x54, 0x52, 0x34, 0x00 });

                ReportProgress(91, "Writing textures");

                // The room texture tile count currently also currently contains the wad textures
                // But lets not bother with those fields too much since they only matter when bump maps are used and we don't use them.
                writer.Write((ushort)_textureInfoManager.NumRoomPages);
                writer.Write((ushort)_textureInfoManager.NumObjectsPages);
                // Bump map pages must be multiplied by 2 or tile index will be wrong
                writer.Write((ushort)(_textureInfoManager.NumBumpPages * 2));

                // Compress data
                ReportProgress(95, "Compressing data");

                byte[] texture32 = null;
                int    texture32UncompressedSize = -1;
                byte[] texture16 = null;
                int    texture16UncompressedSize = -1;
                byte[] textureMisc = null;
                int    textureMiscUncompressedSize = -1;
                byte[] geometryData = geometryDataBuffer;
                int    geometryDataUncompressedSize = geometryData.Length;

                using (Task Texture32task = Task.Factory.StartNew(() =>
                {
                    texture32 = ZLib.CompressData(_texture32Data);
                    texture32UncompressedSize = _texture32Data.Length;
                }))
                    using (Task Texture16task = Task.Factory.StartNew(() =>
                    {
                        byte[] texture16Data = PackTextureMap32To16Bit(_texture32Data, _level.Settings);
                        texture16 = ZLib.CompressData(texture16Data);
                        texture16UncompressedSize = texture16Data.Length;
                    }))
                        using (Task textureMiscTask = Task.Factory.StartNew(() =>
                        {
                            Stream textureMiscData = PrepareFontAndSkyTexture();
                            textureMisc = ZLib.CompressData(textureMiscData);
                            textureMiscUncompressedSize = (int)textureMiscData.Length;
                        }))

                            Task.WaitAll(Texture32task, Texture16task, textureMiscTask);

                // Write data
                ReportProgress(97, "Writing compressed data to file.");

                writer.Write(texture32UncompressedSize);
                writer.Write(texture32.Length);
                writer.Write(texture32);

                writer.Write(texture16UncompressedSize);
                writer.Write(texture16.Length);
                writer.Write(texture16);

                writer.Write(textureMiscUncompressedSize);
                writer.Write(textureMisc.Length);
                writer.Write(textureMisc);

                writer.Write((ushort)_level.Settings.Tr5LaraType);
                writer.Write((ushort)_level.Settings.Tr5WeatherType);

                for (var i = 0; i < 28; i++)
                {
                    writer.Write((byte)0);
                }

                // In TR5 geometry data is not compressed
                writer.Write(geometryDataUncompressedSize);
                writer.Write(geometryDataUncompressedSize);
                writer.Write(geometryData);

                ReportProgress(98, "Writing WAVE sounds");
                WriteSoundData(writer);

                ReportProgress(99, "Done");
            }
        }
コード例 #6
0
        public void WriteTr4(BinaryWriterEx writer)
        {
            writer.WriteBlock(Info);

            var offset = writer.BaseStream.Position;

            writer.Write(0);

            writer.Write((ushort)Vertices.Count);
            for (var k = 0; k < Vertices.Count; k++)
            {
                writer.Write(Vertices[k].Position.X);
                writer.Write(Vertices[k].Position.Y);
                writer.Write(Vertices[k].Position.Z);
                writer.Write(Vertices[k].Lighting1);
                writer.Write(Vertices[k].Attributes);
                writer.Write(Vertices[k].Lighting2);
            }

            writer.Write((ushort)Quads.Count);
            for (var k = 0; k < Quads.Count; k++)
            {
                Quads[k].Write(writer);
            }

            writer.Write((ushort)Triangles.Count);
            for (var k = 0; k < Triangles.Count; k++)
            {
                Triangles[k].Write(writer);
            }

            // For sprites, not used
            writer.Write((ushort)0);

            // Now save current offset and calculate the size of the geometry
            var offset2 = writer.BaseStream.Position;
            // ReSharper disable once SuggestVarOrType_BuiltInTypes
            ushort roomGeometrySize = (ushort)((offset2 - offset - 4) / 2);

            // Save the size of the geometry
            writer.BaseStream.Seek(offset, SeekOrigin.Begin);
            writer.Write(roomGeometrySize);
            writer.BaseStream.Seek(offset2, SeekOrigin.Begin);

            // Write portals
            writer.WriteBlock((ushort)Portals.Count);
            if (Portals.Count != 0)
            {
                writer.WriteBlockArray(Portals);
            }

            // Write sectors
            writer.Write(NumZSectors);
            writer.Write(NumXSectors);
            writer.WriteBlockArray(Sectors);

            // Write room color
            writer.Write(AmbientIntensity);

            // Write lights
            writer.WriteBlock((ushort)Lights.Count);
            if (Lights.Count != 0)
            {
                writer.WriteBlockArray(Lights);
            }

            // Write static meshes
            writer.WriteBlock((ushort)StaticMeshes.Count);
            if (StaticMeshes.Count != 0)
            {
                writer.WriteBlockArray(StaticMeshes);
            }

            // Write final data
            writer.Write(AlternateRoom);
            writer.Write(Flags);
            writer.Write(WaterScheme);
            writer.Write(ReverbInfo);
            writer.Write(AlternateGroup);
        }
コード例 #7
0
        public void WriteTr3(BinaryWriterEx writer)
        {
            writer.WriteBlock(Info);

            var offset = writer.BaseStream.Position;

            writer.Write(0);

            writer.Write((ushort)Vertices.Count);
            for (var k = 0; k < Vertices.Count; k++)
            {
                writer.Write(Vertices[k].Position.X);
                writer.Write(Vertices[k].Position.Y);
                writer.Write(Vertices[k].Position.Z);
                writer.Write(Vertices[k].Lighting1);
                writer.Write(Vertices[k].Attributes);
                writer.Write(Vertices[k].Lighting2);
            }

            writer.Write((ushort)Quads.Count);
            for (var k = 0; k < Quads.Count; k++)
            {
                Quads[k].Write(writer);
            }

            writer.Write((ushort)Triangles.Count);
            for (var k = 0; k < Triangles.Count; k++)
            {
                Triangles[k].Write(writer);
            }

            // For sprites, not used
            writer.Write((ushort)0);

            // Now save current offset and calculate the size of the geometry
            var offset2 = writer.BaseStream.Position;
            // ReSharper disable once SuggestVarOrType_BuiltInTypes
            ushort roomGeometrySize = (ushort)((offset2 - offset - 4) / 2);

            // Save the size of the geometry
            writer.BaseStream.Seek(offset, SeekOrigin.Begin);
            writer.Write(roomGeometrySize);
            writer.BaseStream.Seek(offset2, SeekOrigin.Begin);

            // Write portals
            writer.WriteBlock((ushort)Portals.Count);
            if (Portals.Count != 0)
            {
                writer.WriteBlockArray(Portals);
            }

            // Write sectors
            writer.Write(NumZSectors);
            writer.Write(NumXSectors);
            writer.WriteBlockArray(Sectors);

            // Write room color
            writer.Write((ushort)(AmbientIntensity));

            // Light mode is broken in TR3
            writer.Write((ushort)0x00);

            // Write lights
            writer.WriteBlock((ushort)Lights.Count);
            if (Lights.Count != 0)
            {
                foreach (var light in Lights)
                {
                    writer.Write(light.X);
                    writer.Write(light.Y);
                    writer.Write(light.Z);
                    writer.Write(light.Color.Red);
                    writer.Write(light.Color.Green);
                    writer.Write(light.Color.Blue);
                    writer.Write(light.LightType);

                    if (light.LightType == 0) // FIXME: TR3 sun type - UNKNOWN NORMALS FORMAT!
                    {
                        writer.Write((ushort)(light.X + (light.DirectionX * 1024.0f)));
                        writer.Write((ushort)(light.Y + (light.DirectionY * 1024.0f)));
                        writer.Write((ushort)(light.Z + (light.DirectionZ * 1024.0f)));
                        writer.Write((ushort)0x0000); // Padding
                    }
                    else
                    {
                        writer.Write((uint)light.Intensity);
                        writer.Write((uint)light.Out);
                    }
                }
            }

            // Write static meshes
            writer.WriteBlock((ushort)StaticMeshes.Count);
            if (StaticMeshes.Count != 0)
            {
                writer.WriteBlockArray(StaticMeshes);
            }

            // Write final data
            writer.Write(AlternateRoom);
            writer.Write(Flags);
            writer.Write(WaterScheme);
            writer.Write(ReverbInfo);
            writer.Write((byte)0x00); // Alternate group was introduced in TR4
        }
コード例 #8
0
        private void WriteSoundMetadata(BinaryWriter writer)
        {
            if (_level.Settings.GameVersion > TRVersion.Game.TR3)
            {
                // In TRNG and TR5Main NumDemoData is used as sound map size
                writer.Write((ushort)(_level.Settings.GameVersion == TRVersion.Game.TRNG ||
                                      _level.Settings.GameVersion == TRVersion.Game.TR5Main ? _soundMapSize : 0));
            }

            using (var ms = new MemoryStream())
            {
                using (var bw = new BinaryWriterEx(ms))
                {
                    // Write soundmap to level file
                    for (int i = 0; i < _finalSoundMap.Length; i++)
                    {
                        bw.Write(_finalSoundMap[i]);
                    }

                    // Write sound details
                    int lastSampleIndex = 0;
                    bw.Write((uint)_finalSoundInfosList.Count);
                    for (int i = 0; i < _finalSoundInfosList.Count; i++)
                    {
                        var soundDetail = _finalSoundInfosList[i];

                        if (soundDetail.Samples.Count > 0x0F)
                        {
                            throw new Exception("Too many sound effects for sound info '" + soundDetail.Name + "'.");
                        }

                        ushort characteristics = (ushort)(3 & (int)soundDetail.LoopBehaviour);
                        characteristics |= (ushort)(soundDetail.Samples.Count << 2);
                        if (soundDetail.DisablePanning)
                        {
                            characteristics |= 0x1000;
                        }
                        if (soundDetail.RandomizePitch)
                        {
                            characteristics |= 0x2000;
                        }
                        if (soundDetail.RandomizeVolume)
                        {
                            characteristics |= 0x4000;
                        }

                        if (_level.Settings.GameVersion <= TRVersion.Game.TR2)
                        {
                            var newSoundDetail = new tr_sound_details();
                            newSoundDetail.Sample          = (ushort)lastSampleIndex;
                            newSoundDetail.Volume          = (ushort)Math.Round(soundDetail.Volume / 100.0f * 32767.0f);
                            newSoundDetail.Chance          = (byte)Math.Round((soundDetail.Chance == 100 ? 0 : soundDetail.Chance) / 100.0f * 32767.0f);
                            newSoundDetail.Characteristics = characteristics;
                            bw.WriteBlock(newSoundDetail);
                        }
                        else
                        {
                            var newSoundDetail = new tr3_sound_details();
                            newSoundDetail.Sample          = (ushort)lastSampleIndex;
                            newSoundDetail.Volume          = (byte)Math.Round(soundDetail.Volume / 100.0f * 255.0f);
                            newSoundDetail.Range           = (byte)soundDetail.RangeInSectors;
                            newSoundDetail.Chance          = (byte)Math.Round((soundDetail.Chance == 100 ? 0 : soundDetail.Chance) / 100.0f * 255.0f);
                            newSoundDetail.Pitch           = (byte)Math.Round(soundDetail.PitchFactor / 100.0f * 127.0f + (soundDetail.PitchFactor < 0 ? 256 : 0));
                            newSoundDetail.Characteristics = characteristics;
                            bw.WriteBlock(newSoundDetail);
                        }
                        lastSampleIndex += soundDetail.Samples.Count;
                    }

                    if (_level.Settings.GameVersion < TRVersion.Game.TR5Main && lastSampleIndex > 255)
                    {
                        _progressReporter.ReportWarn("Level contains " + lastSampleIndex +
                                                     " samples, while maximum is 256. Level will crash. Turn off some sounds to prevent that.");
                    }

                    // Write sample indices (not used but parsed in TR4-5)
                    bw.Write((uint)_finalSoundIndicesList.Count);
                    for (int i = 0; i < _finalSoundIndicesList.Count; i++)
                    {
                        bw.Write((uint)_finalSoundIndicesList[i]);
                    }
                }

                writer.Write(ms.ToArray());
            }
        }