From 5bb3e70344cfafa8c09561b6d7d157026ce18b4f Mon Sep 17 00:00:00 2001 From: Ian C Date: Fri, 21 Jan 2005 00:52:26 +0000 Subject: Initial checkin --- WAD.cs | 365 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 365 insertions(+) create mode 100644 WAD.cs (limited to 'WAD.cs') diff --git a/WAD.cs b/WAD.cs new file mode 100644 index 0000000..42a687d --- /dev/null +++ b/WAD.cs @@ -0,0 +1,365 @@ +// Noddybox.DOOM - DOOM WAD Wrapper +// Copyright (C) 2004 Ian Cowburn +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +using System; +using System.IO; +using System.Collections; +using System.Text; + +namespace Noddybox.DOOM +{ + /// + /// Defines a WAD File + /// + public class WAD : IEnumerable, IEnumerator + { + // ==================================== + // PUBLIC + // ==================================== + + /// + /// Describes the type of WAD + /// + public enum EWadType + { + /// + /// An Interal WAD (eg. DOOM 2) + /// + IWAD, + + /// + /// A Patch WAD (eg. a user-defined level) + /// + PWAD + }; + + /// + /// Construct a new, empty WAD file + /// + public WAD() + { + m_type=EWadType.PWAD; + m_entry=new ArrayList(); + m_ascii=new ASCIIEncoding(); + } + + /// + /// Load a WAD file from disk + /// + /// The WAD file + /// + /// I/O errors + /// + public WAD(string path) + { + m_path=path; + m_entry=new ArrayList(); + m_ascii=new ASCIIEncoding(); + Load(); + } + + /// + /// Get/set the path of the WAD file on disk + /// + public string Path + { + get {return m_path;} + set {m_path=value;} + } + + /// + /// Get the type of WAD file + /// + public EWadType WadType + { + get {return m_type;} + } + + /// + /// Adds a new lump to the WAD + /// + /// The lump + public void AddEntry(WADEntry e) + { + m_entry.Add(e); + } + + /// + /// Removes a lump from the WAD + /// + /// The lump + public void RemoveEntry(WADEntry e) + { + m_entry.Remove(e); + } + + /// + /// Find a lump + /// + /// The name to find + /// The first lump that matches the name, or null for no match + public WADEntry FindEntry(string name) + { + foreach (WADEntry e in m_entry) + { + if (e.Name==name) + { + return e; + } + } + + return null; + } + + /// + /// Load a WAD file + /// + /// + /// I/O errors + /// + public void Load() + { + if (m_path==null) + { + throw new DoomException("Tried to load a WAD without a path"); + } + + FileStream fs=File.OpenRead(m_path); + + string id=ReadString(fs,4); + + if (id=="IWAD") + { + m_type=EWadType.IWAD; + } + else if (id=="PWAD") + { + m_type=EWadType.PWAD; + } + else + { + fs.Close(); + throw new DoomException("Not a WAD File - " + m_path); + } + + m_entry.Clear(); + + int num=ReadLong(fs); + + if (num>0) + { + fs.Position=ReadLong(fs); + + for(int f=0;f + /// Saves the WAD file + /// + /// + /// Tried to save an IWAD file + /// + /// + /// I/O errors + /// + public void Save() + { + if (m_path==null) + { + throw new DoomException("Tried to save a WAD without a path"); + } + + if (m_type==EWadType.IWAD) + { + throw new DoomException("Tried to save an IWAD"); + } + + FileStream fs=File.Create(m_path); + + int len=0; + + foreach (WADEntry e in this) + { + len+=e.Length; + } + + WriteString(fs,"PWAD",4); + WriteLong(fs,m_entry.Count); + + int offset=12; + + WriteLong(fs,len+offset); + + foreach (WADEntry e in m_entry) + { + fs.Write(e.Data,0,e.Length); + } + + foreach (WADEntry e in m_entry) + { + WriteLong(fs,offset); + WriteLong(fs,e.Length); + WriteString(fs,e.Name,8); + offset+=e.Length; + } + + fs.Close(); + } + + /// + /// Returns the number of lumps in the WAD + /// + public int Count + { + get {return m_entry.Count;} + } + + /// + /// Index into the lumps + /// + public WADEntry this[int index] + { + get {return (WADEntry)m_entry[index];} + } + + /// + /// Gets an enumerator + /// + /// The enumerator + public IEnumerator GetEnumerator() + { + Reset(); + return this; + } + + /// + /// Get the current object from the enumerator + /// + public object Current + { + get + { + if (m_iter_index==-1) + { + throw new InvalidOperationException(); + } + + return m_entry[m_iter_index]; + } + } + + /// + /// Reset the enumerator to the start of the collection. + /// + public void Reset() + { + m_iter_index=-1; + } + + /// + /// Move the enumerator to the next item. + /// + /// True if there are more objects to enumerate over + public bool MoveNext() + { + m_iter_index++; + + if (m_iter_index>=m_entry.Count) + { + m_iter_index=-1; + } + + return m_iter_index!=-1; + } + + // ==================================== + // PRIVATE + // ==================================== + private string m_path; + private EWadType m_type; + private ArrayList m_entry; + private ASCIIEncoding m_ascii; + + private int m_iter_index; + + private int ReadLong(FileStream fs) + { + int l=0; + + for(int f=0;f<4;f++) + { + int b=fs.ReadByte(); + l|=b<<(f*8); + } + + return l; + } + + private string ReadString(FileStream fs, int len) + { + byte[] data=new byte[len]; + + fs.Read(data,0,len); + + return m_ascii.GetString(data,0,len); + } + + private void WriteLong(FileStream fs, int l) + { + for(int f=0;f<4;f++) + { + fs.WriteByte((byte)(l&0xff)); + l=l>>8; + } + } + + private void WriteString(FileStream fs, string s, int len) + { + byte[] data=m_ascii.GetBytes(s); + + for(int f=0;f