// 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.
//
// $Id$
//
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