Example #1
0
        // Get all the wall textures from the wall texture resource
        public static List <WallTextureData> GetTextures(FileStream wadStream, WADInfo wadInfo, byte[] data)
        {
            var textures = new List <WallTextureData>();
            var numTexs  = BitConverter.ToInt32(data, 0);

            for (var i = 0; i < numTexs; i++)
            {
                var pointer = BitConverter.ToInt32(data, 4 + (i * 4));

                var name       = Encoding.UTF8.GetString(data, pointer, 8).ToUpper();
                var w          = BitConverter.ToInt16(data, pointer + 12);
                var h          = BitConverter.ToInt16(data, pointer + 14);
                var numPatches = BitConverter.ToInt16(data, pointer + 20);
                var patches    = new WallPatch[numPatches];
                for (var p = 0; p < numPatches; p++)
                {
                    var x     = BitConverter.ToInt16(data, pointer + 22 + (p * 10));
                    var y     = BitConverter.ToInt16(data, pointer + 22 + (p * 10) + 2);
                    var pnum  = BitConverter.ToInt16(data, pointer + 22 + (p * 10) + 4);
                    var pname = wadInfo.PatchNames[pnum];
                    var patch = new WallPatch(x, y, pnum, pname);
                    patches[p] = patch;
                }

                textures.Add(new WallTextureData(name, w, h, patches));
            }

            return(textures);
        }
Example #2
0
 void LoadWad()
 {
     using (var wadStream = new FileStream(fileName, FileMode.Open))
     {
         loadedWad     = WADReader.GetInfo(wadStream);
         availableMaps = WADReader.GetMapList(wadStream, loadedWad);
     }
 }
Example #3
0
        // Returns actual map data when given a map entry (from GetMapList)
        public static MapData GetMapData(FileStream wadStream, WADInfo wadInfo, WADMapEntry mapEntry)
        {
            var mapData = new MapData(wadInfo, mapEntry.Name,
                                      GetResource(wadStream, mapEntry.Things),
                                      GetResource(wadStream, mapEntry.LineDefs),
                                      GetResource(wadStream, mapEntry.SideDefs),
                                      GetResource(wadStream, mapEntry.Sectors),
                                      GetResource(wadStream, mapEntry.SubSectors),
                                      GetResource(wadStream, mapEntry.Segs),
                                      GetResource(wadStream, mapEntry.Vertexes));

            return(mapData);
        }
Example #4
0
        // Gets a list of maps in the WAD
        // At this level, we only care about metadata - so we get the name of the map and pointers to resources containing the map data
        public static List <WADMapEntry> GetMapList(FileStream wadStream, WADInfo wadInfo)
        {
            var maps = new List <WADMapEntry>();

            // Map names are either in the format "ExMy" or "MAPxx"
            // They also have a zero resource length as they're just markers in the WAD directory
            foreach (var entry in wadInfo.Entries.Where(e => (e.Name.StartsWith("MAP") || (e.Name[0] == 'E' && e.Name[2] == 'M')) && e.ResourceLength == 0))
            {
                var map = new WADMapEntry()
                {
                    Name = entry.Name
                };

                // The resource entries directly after the map marker are the actual map data
                // Let's find the ones we're interested in and hold pointers to them so we can get to them easily later
                var startIndex = wadInfo.Entries.IndexOf(entry);
                var index      = startIndex + 1;
                while (index < startIndex + 10 || index >= wadInfo.Entries.Count - 1)
                {
                    switch (wadInfo.Entries[index].Name)
                    {
                    case "THINGS": map.Things = wadInfo.Entries[index]; break;

                    case "LINEDEFS": map.LineDefs = wadInfo.Entries[index]; break;

                    case "SIDEDEFS": map.SideDefs = wadInfo.Entries[index]; break;

                    case "VERTEXES": map.Vertexes = wadInfo.Entries[index]; break;

                    case "SECTORS": map.Sectors = wadInfo.Entries[index]; break;

                    case "SSECTORS": map.SubSectors = wadInfo.Entries[index]; break;

                    case "SEGS": map.Segs = wadInfo.Entries[index]; break;
                    }

                    index++;
                }

                maps.Add(map);
            }

            return(maps);
        }
Example #5
0
        // Get a dictionary of wall patches based on the patch names listed in the wall texture data
        public static Dictionary <string, SpriteData> GetWallPatches(FileStream wadStream, WADInfo wadInfo, WallTextureData textureData)
        {
            var sprites = new Dictionary <string, SpriteData>();

            foreach (var patch in textureData.Patches)
            {
                if (!sprites.ContainsKey(patch.PatchName))
                {
                    sprites.Add(patch.PatchName, GetPictureSprite(wadStream, wadInfo.EntryDictionary[patch.PatchName]));
                }
            }

            return(sprites);
        }
Example #6
0
        // Deals with reading data from the WAD file
        // See https://github.com/nukeop/TheUnofficialDoomSpecs

        public static WADInfo GetInfo(FileStream wadStream)
        {
            // Root WAD data
            var wi = new WADInfo()
            {
                Type            = ReadString(wadStream, 0, 4),
                NumEntries      = ReadInt(wadStream, 4, 4),
                DirectoryOffset = ReadInt(wadStream, 8, 4)
            };

            // Get a list of the contents of the WAD
            for (var i = 0; i < wi.NumEntries; i++)
            {
                var entryOffset = wi.DirectoryOffset + (i * 16);
                var entry       = new WADEntry()
                {
                    ResourceOffset = ReadInt(wadStream, entryOffset, 4),
                    ResourceLength = ReadInt(wadStream, entryOffset + 4, 4),
                    Name           = ReadString(wadStream, entryOffset + 8, 8)
                };
                wi.Entries.Add(entry);
                if (!wi.EntryDictionary.ContainsKey(entry.Name.Replace("\0", "")))
                {
                    wi.EntryDictionary.Add(entry.Name.Replace("\0", ""), entry);
                    //Debug.Log(entry.Name);
                }
            }

            // Wall patches
            // Get patchnames lookup
            var patchesEntry = wi.EntryDictionary["PNAMES"];
            var patchesData  = GetResource(wadStream, patchesEntry);
            var numPatches   = BitConverter.ToInt32(patchesData, 0);

            wi.PatchNames = new string[numPatches];
            var pos = 4;

            for (var i = 0; i < numPatches; i++)
            {
                wi.PatchNames[i] = Encoding.UTF8.GetString(patchesData, pos, 8).ToUpper().Replace("\0", "");
                pos += 8;
            }

            // Wall textures: textures listed in the TEXTURE1 resource are for shareware (Episode 1) maps, all others are in TEXTURE2.
            var texEntry = wi.EntryDictionary["TEXTURE1"];
            var texList  = GetTextures(wadStream, wi, GetResource(wadStream, texEntry));

            foreach (var t in texList)
            {
                wi.WallTextures.Add(t.Name, t);
            }
            if (wi.EntryDictionary.ContainsKey("TEXTURE2"))
            {
                texEntry = wi.EntryDictionary["TEXTURE2"];
                texList  = GetTextures(wadStream, wi, GetResource(wadStream, texEntry));
                foreach (var t in texList)
                {
                    wi.WallTextures.Add(t.Name, t);
                }
            }

            return(wi);
        }
Example #7
0
        public MapData(WADInfo wadInfo, string name, byte[] thingsData, byte[] lineDefData, byte[] sideDefData, byte[] sectorData, byte[] subSectorData, byte[] segData, byte[] vertexData)
        {
            Name = name;

            Things     = new MapThing[thingsData.Length / 10];
            LineDefs   = new MapLineDef[lineDefData.Length / 14];
            SideDefs   = new MapSideDef[sideDefData.Length / 30];
            Sectors    = new MapSector[sectorData.Length / 26];
            Vertexes   = new MapVertex[vertexData.Length / 4];
            SubSectors = new MapSubSector[subSectorData.Length / 4];
            Segs       = new MapSeg[segData.Length / 12];

            var pos = 0;

            for (var i = 0; i < Things.Length; i++)
            {
                Things[i] = new MapThing(BitConverter.ToInt16(thingsData, pos),
                                         BitConverter.ToInt16(thingsData, pos + 2),
                                         BitConverter.ToInt16(thingsData, pos + 4),
                                         BitConverter.ToInt16(thingsData, pos + 6),
                                         BitConverter.ToInt16(thingsData, pos + 8));
                pos += 10;
            }

            pos = 0;
            for (var i = 0; i < LineDefs.Length; i++)
            {
                LineDefs[i] = new MapLineDef(BitConverter.ToInt16(lineDefData, pos),
                                             BitConverter.ToInt16(lineDefData, pos + 2),
                                             BitConverter.ToInt16(lineDefData, pos + 4),
                                             BitConverter.ToInt16(lineDefData, pos + 6),
                                             BitConverter.ToInt16(lineDefData, pos + 8),
                                             BitConverter.ToInt16(lineDefData, pos + 10),
                                             BitConverter.ToInt16(lineDefData, pos + 12));
                pos += 14;
            }

            pos = 0;
            for (var i = 0; i < SideDefs.Length; i++)
            {
                SideDefs[i] = new MapSideDef(BitConverter.ToInt16(sideDefData, pos),
                                             BitConverter.ToInt16(sideDefData, pos + 2),
                                             Encoding.UTF8.GetString(sideDefData, pos + 4, 8).ToUpper(),
                                             Encoding.UTF8.GetString(sideDefData, pos + 12, 8).ToUpper(),
                                             Encoding.UTF8.GetString(sideDefData, pos + 20, 8).ToUpper(),
                                             BitConverter.ToInt16(sideDefData, pos + 28));

                if (SideDefs[i].FullTexture != "-" && wadInfo.WallTextures.ContainsKey(SideDefs[i].FullTexture) && !WallsUsed.Contains(wadInfo.WallTextures[SideDefs[i].FullTexture]))
                {
                    WallsUsed.Add(wadInfo.WallTextures[SideDefs[i].FullTexture]);
                }
                if (SideDefs[i].UpperTexture != "-" && wadInfo.WallTextures.ContainsKey(SideDefs[i].UpperTexture) && !WallsUsed.Contains(wadInfo.WallTextures[SideDefs[i].UpperTexture]))
                {
                    WallsUsed.Add(wadInfo.WallTextures[SideDefs[i].UpperTexture]);
                }
                if (SideDefs[i].LowerTexture != "-" && wadInfo.WallTextures.ContainsKey(SideDefs[i].LowerTexture) && !WallsUsed.Contains(wadInfo.WallTextures[SideDefs[i].LowerTexture]))
                {
                    WallsUsed.Add(wadInfo.WallTextures[SideDefs[i].LowerTexture]);
                }

                pos += 30;
            }

            pos = 0;
            for (var i = 0; i < Sectors.Length; i++)
            {
                Sectors[i] = new MapSector(BitConverter.ToInt16(sectorData, pos),
                                           BitConverter.ToInt16(sectorData, pos + 2),
                                           Encoding.UTF8.GetString(sectorData, pos + 4, 8).ToUpper(),
                                           Encoding.UTF8.GetString(sectorData, pos + 12, 8).ToUpper(),
                                           BitConverter.ToInt16(sectorData, pos + 20),
                                           BitConverter.ToInt16(sectorData, pos + 22),
                                           BitConverter.ToInt16(sectorData, pos + 24));

                var cname = Sectors[i].CeilingTexture.Replace("\0", "");
                if (Sectors[i].CeilingTexture != "-" && wadInfo.EntryDictionary.ContainsKey(cname) && !FlatsUsed.Contains(wadInfo.EntryDictionary[cname]))
                {
                    FlatsUsed.Add(wadInfo.EntryDictionary[cname]);
                }
                var fname = Sectors[i].FloorTexture.Replace("\0", "");
                if (Sectors[i].FloorTexture != "-" && wadInfo.EntryDictionary.ContainsKey(fname) && !FlatsUsed.Contains(wadInfo.EntryDictionary[fname]))
                {
                    FlatsUsed.Add(wadInfo.EntryDictionary[fname]);
                }

                pos += 26;
            }

            pos = 0;
            for (var i = 0; i < SubSectors.Length; i++)
            {
                SubSectors[i] = new MapSubSector(BitConverter.ToInt16(subSectorData, pos),
                                                 BitConverter.ToInt16(subSectorData, pos + 2));

                pos += 4;
            }

            pos = 0;
            for (var i = 0; i < Segs.Length; i++)
            {
                Segs[i] = new MapSeg(BitConverter.ToInt16(segData, pos),
                                     BitConverter.ToInt16(segData, pos + 2),
                                     BitConverter.ToInt16(segData, pos + 4),
                                     BitConverter.ToInt16(segData, pos + 6),
                                     BitConverter.ToInt16(segData, pos + 8),
                                     BitConverter.ToInt16(segData, pos + 10));

                pos += 12;
            }

            pos = 0;
            for (var i = 0; i < Vertexes.Length; i++)
            {
                Vertexes[i] = new MapVertex(BitConverter.ToInt16(vertexData, pos),
                                            BitConverter.ToInt16(vertexData, pos + 2));
                pos += 4;
            }
        }