示例#1
0
        //mxd. This rebuilds the WAD file, removing all "dead" entries
        // Tech info: WAD.Remove() doesn't remove lump data, so MapManager.TemporaryMapFile slowly gets bigger
        // with every map save/test, which leads to lumpsoffset overflowing when TemporaryMapFile size reaches
        // int.MaxValue bytes in size (that's ~2Gb).
        internal void Compress()
        {
            // No can't do...
            if (isreadonly)
            {
                return;
            }

            // Gather existing data
            int totaldatalength          = 0;
            List <LumpCopyData> copydata = new List <LumpCopyData>(lumps.Count);

            for (int i = 0; i < lumps.Count; i++)
            {
                // Copy lump...
                LumpCopyData lcd = new LumpCopyData();
                Lump         l   = lumps[i];

                lcd.FixedName = l.FixedName;
                lcd.Index     = i;
                lcd.Data      = l.Stream.ReadAllBytes();

                // Store data
                copydata.Add(lcd);

                // Track total length
                totaldatalength += l.Length;

                // Dispose lump
                l.Dispose();
            }

            // Compression required?
            if (totaldatalength >= lumpsoffset + 12)
            {
                return;
            }

            // Set new file length
            file.SetLength(totaldatalength + lumps.Count * 16);

            // Reset lumpsoffset
            lumpsoffset = 12;

            // Reset lumps collection
            lumps    = new List <Lump>(copydata.Count);
            numlumps = copydata.Count;

            // Recreate all lumps
            foreach (LumpCopyData lcd in copydata)
            {
                Lump l = new Lump(file, this, lcd.FixedName, lumpsoffset, lcd.Data.Length);
                l.Stream.Write(lcd.Data, 0, lcd.Data.Length);
                l.Stream.Seek(0, SeekOrigin.Begin);
                lumps.Insert(lcd.Index, l);

                lumpsoffset += lcd.Data.Length;
            }

            // Write new headers
            WriteHeaders();
        }
示例#2
0
        // This reads the THINGS from WAD file
        private void ReadThings(MapSet map, int firstindex)
        {
            MemoryStream mem;
            BinaryReader reader;
            int          num, i, tag, z, action, x, y, type, flags, angle;

            int[] args = new int[Thing.NUM_ARGS];
            Dictionary <string, bool> stringflags;
            Thing t;

            // Get the lump from wad file
            Lump lump = wad.FindLump("THINGS", firstindex);

            if (lump == null)
            {
                throw new Exception("Could not find required lump THINGS!");
            }

            // Prepare to read the items
            mem    = new MemoryStream(lump.Stream.ReadAllBytes());
            num    = (int)lump.Stream.Length / 20;
            reader = new BinaryReader(mem);

            // Read items from the lump
            map.SetCapacity(0, 0, 0, 0, map.Things.Count + num);
            for (i = 0; i < num; i++)
            {
                // Read properties from stream
                tag     = reader.ReadUInt16();
                x       = reader.ReadInt16();
                y       = reader.ReadInt16();
                z       = reader.ReadInt16();
                angle   = reader.ReadInt16();
                type    = reader.ReadUInt16();
                flags   = reader.ReadUInt16();
                action  = reader.ReadByte();
                args[0] = reader.ReadByte();
                args[1] = reader.ReadByte();
                args[2] = reader.ReadByte();
                args[3] = reader.ReadByte();
                args[4] = reader.ReadByte();

                // Make string flags
                stringflags = new Dictionary <string, bool>();
                foreach (KeyValuePair <string, string> f in manager.Config.ThingFlags)
                {
                    int fnum;
                    if (int.TryParse(f.Key, out fnum))
                    {
                        stringflags[f.Key] = ((flags & fnum) == fnum);
                    }
                }

                // Create new item
                t = map.CreateThing();
                t.Update(type, x, y, z, angle, stringflags, tag, action, args);
            }

            // Done
            mem.Dispose();
        }
示例#3
0
        // This reads the LINEDEFS and SIDEDEFS from WAD file
        private void ReadLinedefs(MapSet map, int firstindex,
                                  Dictionary <int, Vertex> vertexlink, Dictionary <int, Sector> sectorlink)
        {
            MemoryStream linedefsmem, sidedefsmem;
            BinaryReader readline, readside;
            Lump         linedefslump, sidedefslump;
            int          num, numsides, i, offsetx, offsety, v1, v2;
            int          s1, s2, flags, action, sc;

            int[] args = new int[Linedef.NUM_ARGS];
            Dictionary <string, bool> stringflags;
            string  thigh, tmid, tlow;
            Linedef l;
            Sidedef s;

            // Get the linedefs lump from wad file
            linedefslump = wad.FindLump("LINEDEFS", firstindex);
            if (linedefslump == null)
            {
                throw new Exception("Could not find required lump LINEDEFS!");
            }

            // Get the sidedefs lump from wad file
            sidedefslump = wad.FindLump("SIDEDEFS", firstindex);
            if (sidedefslump == null)
            {
                throw new Exception("Could not find required lump SIDEDEFS!");
            }

            // Prepare to read the items
            linedefsmem = new MemoryStream(linedefslump.Stream.ReadAllBytes());
            sidedefsmem = new MemoryStream(sidedefslump.Stream.ReadAllBytes());
            num         = (int)linedefslump.Stream.Length / 16;
            numsides    = (int)sidedefslump.Stream.Length / 30;
            readline    = new BinaryReader(linedefsmem);
            readside    = new BinaryReader(sidedefsmem);

            // Read items from the lump
            map.SetCapacity(0, map.Linedefs.Count + num, map.Sidedefs.Count + numsides, 0, 0);
            for (i = 0; i < num; i++)
            {
                // Read properties from stream
                v1      = readline.ReadUInt16();
                v2      = readline.ReadUInt16();
                flags   = readline.ReadUInt16();
                action  = readline.ReadByte();
                args[0] = readline.ReadByte();
                args[1] = readline.ReadByte();
                args[2] = readline.ReadByte();
                args[3] = readline.ReadByte();
                args[4] = readline.ReadByte();
                s1      = readline.ReadUInt16();
                s2      = readline.ReadUInt16();

                // Make string flags
                stringflags = new Dictionary <string, bool>();
                foreach (string f in manager.Config.SortedLinedefFlags)
                {
                    int fnum;
                    if (int.TryParse(f, out fnum))
                    {
                        stringflags[f] = ((flags & fnum) == fnum);
                    }
                }

                // Create new linedef
                if (vertexlink.ContainsKey(v1) && vertexlink.ContainsKey(v2))
                {
                    // Check if not zero-length
                    if (Vector2D.ManhattanDistance(vertexlink[v1].Position, vertexlink[v2].Position) > 0.0001f)
                    {
                        l = map.CreateLinedef(vertexlink[v1], vertexlink[v2]);
                        l.Update(stringflags, (flags & manager.Config.LinedefActivationsFilter), 0, action, args);
                        l.UpdateCache();

                        // Line has a front side?
                        if (s1 != ushort.MaxValue)
                        {
                            // Read front sidedef
                            sidedefsmem.Seek(s1 * 30, SeekOrigin.Begin);
                            if ((s1 * 30L) <= (sidedefsmem.Length - 30L))
                            {
                                offsetx = readside.ReadInt16();
                                offsety = readside.ReadInt16();
                                thigh   = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING);
                                tlow    = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING);
                                tmid    = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING);
                                sc      = readside.ReadUInt16();

                                // Create front sidedef
                                if (sectorlink.ContainsKey(sc))
                                {
                                    s = map.CreateSidedef(l, true, sectorlink[sc]);
                                    s.Update(offsetx, offsety, thigh, tmid, tlow);
                                }
                                else
                                {
                                    General.ErrorLogger.Add(ErrorType.Warning, "Sidedef " + s1 + " references invalid sector " + sc + ". Sidedef has been removed.");
                                }
                            }
                            else
                            {
                                General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references invalid sidedef " + s1 + ". Sidedef has been removed.");
                            }
                        }

                        // Line has a back side?
                        if (s2 != ushort.MaxValue)
                        {
                            // Read back sidedef
                            sidedefsmem.Seek(s2 * 30, SeekOrigin.Begin);
                            if ((s2 * 30L) <= (sidedefsmem.Length - 30L))
                            {
                                offsetx = readside.ReadInt16();
                                offsety = readside.ReadInt16();
                                thigh   = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING);
                                tlow    = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING);
                                tmid    = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING);
                                sc      = readside.ReadUInt16();

                                // Create back sidedef
                                if (sectorlink.ContainsKey(sc))
                                {
                                    s = map.CreateSidedef(l, false, sectorlink[sc]);
                                    s.Update(offsetx, offsety, thigh, tmid, tlow);
                                }
                                else
                                {
                                    General.ErrorLogger.Add(ErrorType.Warning, "Sidedef " + s2 + " references invalid sector " + sc + ". Sidedef has been removed.");
                                }
                            }
                            else
                            {
                                General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references invalid sidedef " + s2 + ". Sidedef has been removed.");
                            }
                        }
                    }
                    else
                    {
                        General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " is zero-length. Linedef has been removed.");
                    }
                }
                else
                {
                    General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references one or more invalid vertices. Linedef has been removed.");
                }
            }

            // Done
            linedefsmem.Dispose();
            sidedefsmem.Dispose();
        }
示例#4
0
        // This reads the LINEDEFS and SIDEDEFS from WAD file
        private void ReadLinedefs(MapSet map, int firstindex,
                                  Dictionary <int, Vertex> vertexlink, Dictionary <int, Sector> sectorlink)
        {
            MemoryStream linedefsmem, sidedefsmem;
            BinaryReader readline, readside;
            Lump         linedefslump, sidedefslump;
            int          num, numsides, i, offsetx, offsety, v1, v2;
            int          s1, s2, flags, action, tag, sc;
            Dictionary <string, bool> stringflags;
            string  thigh, tmid, tlow;
            Linedef l;
            Sidedef s;

            // Get the linedefs lump from wad file
            linedefslump = wad.FindLump("LINEDEFS", firstindex);
            if (linedefslump == null)
            {
                throw new Exception("Could not find required lump LINEDEFS!");
            }

            // Get the sidedefs lump from wad file
            sidedefslump = wad.FindLump("SIDEDEFS", firstindex);
            if (sidedefslump == null)
            {
                throw new Exception("Could not find required lump SIDEDEFS!");
            }

            // Prepare to read the items
            linedefsmem = new MemoryStream(linedefslump.Stream.ReadAllBytes());
            sidedefsmem = new MemoryStream(sidedefslump.Stream.ReadAllBytes());
            num         = (int)linedefslump.Stream.Length / 14;
            numsides    = (int)sidedefslump.Stream.Length / 30;
            readline    = new BinaryReader(linedefsmem);
            readside    = new BinaryReader(sidedefsmem);

            // Read items from the lump

            // ano - heuristic to detect sidedef compression
            if (num > numsides)
            {
                // ano - set sidedefs to some larger amount than
                // numsides before resizing back down
                // because in the case of sidedef compression the
                // array will have to be resized a lot
                map.SetCapacity(0, map.Linedefs.Count + num, map.Sidedefs.Count + (num * 2), 0, 0);
            }
            else
            {
                // ano - + 32 as extra leniency for some amount of sidedef
                // compression that goes undetected by the prev check
                // note this wont be resized back down but 32 is a neglible amount
                map.SetCapacity(0, map.Linedefs.Count + num, map.Sidedefs.Count + num + 32, 0, 0);
            }
            for (i = 0; i < num; i++)
            {
                // Read properties from stream
                v1     = readline.ReadUInt16();
                v2     = readline.ReadUInt16();
                flags  = readline.ReadUInt16();
                action = readline.ReadUInt16();
                tag    = readline.ReadUInt16();
                s1     = readline.ReadUInt16();
                s2     = readline.ReadUInt16();

                // Make string flags
                stringflags = new Dictionary <string, bool>();
                foreach (string f in manager.Config.SortedLinedefFlags)
                {
                    int fnum;
                    if (int.TryParse(f, out fnum))
                    {
                        stringflags[f] = ((flags & fnum) == fnum);
                    }
                }

                // Create new linedef
                if (vertexlink.ContainsKey(v1) && vertexlink.ContainsKey(v2))
                {
                    // Check if not zero-length
                    if (Vector2D.ManhattanDistance(vertexlink[v1].Position, vertexlink[v2].Position) > 0.0001f)
                    {
                        l = map.CreateLinedef(vertexlink[v1], vertexlink[v2]);
                        l.Update(stringflags, 0, tag, action, new int[Linedef.NUM_ARGS]);
                        l.UpdateCache();

                        // Line has a front side?
                        if (s1 != ushort.MaxValue)
                        {
                            // Read front sidedef
                            if ((s1 * 30L) <= (sidedefsmem.Length - 30L))
                            {
                                sidedefsmem.Seek(s1 * 30, SeekOrigin.Begin);
                                offsetx = readside.ReadInt16();
                                offsety = readside.ReadInt16();
                                thigh   = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING);
                                tlow    = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING);
                                tmid    = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING);
                                sc      = readside.ReadUInt16();

                                // Create front sidedef
                                if (sectorlink.ContainsKey(sc))
                                {
                                    s = map.CreateSidedef(l, true, sectorlink[sc]);
                                    s.Update(offsetx, offsety, thigh, tmid, tlow);
                                }
                                else
                                {
                                    General.ErrorLogger.Add(ErrorType.Warning, "Sidedef " + s1 + " references invalid sector " + sc + ". Sidedef has been removed.");
                                }
                            }
                            else
                            {
                                General.ErrorLogger.Add(ErrorType.Warning, "Linedef references invalid sidedef " + s1 + ". Sidedef has been removed.");
                            }
                        }

                        // Line has a back side?
                        if (s2 != ushort.MaxValue)
                        {
                            // Read back sidedef
                            if ((s2 * 30L) <= (sidedefsmem.Length - 30L))
                            {
                                sidedefsmem.Seek(s2 * 30, SeekOrigin.Begin);
                                offsetx = readside.ReadInt16();
                                offsety = readside.ReadInt16();
                                thigh   = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING);
                                tlow    = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING);
                                tmid    = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING);
                                sc      = readside.ReadUInt16();

                                // Create back sidedef
                                if (sectorlink.ContainsKey(sc))
                                {
                                    s = map.CreateSidedef(l, false, sectorlink[sc]);
                                    s.Update(offsetx, offsety, thigh, tmid, tlow);
                                }
                                else
                                {
                                    General.ErrorLogger.Add(ErrorType.Warning, "Sidedef " + s2 + " references invalid sector " + sc + ". Sidedef has been removed.");
                                }
                            }
                            else
                            {
                                General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references invalid sidedef " + s2 + ". Sidedef has been removed.");
                            }
                        }
                    }
                    else
                    {
                        General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " is zero-length. Linedef has been removed.");
                    }
                }
                else
                {
                    General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references one or more invalid vertices. Linedef has been removed.");
                }
            }
            if (num > numsides)
            {
                // ano - resize the arrays back down
                map.SetCapacity(0, map.Linedefs.Count, map.Sidedefs.Count, 0, 0);
            }

            // Done
            linedefsmem.Dispose();
            sidedefsmem.Dispose();
        }