.wad file format of id Tech 1: Go parsing library

Application

id Tech 1

File extension

wad

KS implementation details

License: CC0-1.0

References

This page hosts a formal specification of .wad file format of id Tech 1 using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.

Go source code to parse .wad file format of id Tech 1

doom_wad.go

// Code generated by kaitai-struct-compiler from a .ksy source file. DO NOT EDIT.

import (
	"github.com/kaitai-io/kaitai_struct_go_runtime/kaitai"
	"io"
	"bytes"
)

type DoomWad struct {
	Magic string
	NumIndexEntries int32
	IndexOffset int32
	_io *kaitai.Stream
	_root *DoomWad
	_parent kaitai.Struct
	_f_index bool
	index []*DoomWad_IndexEntry
}
func NewDoomWad() *DoomWad {
	return &DoomWad{
	}
}

func (this DoomWad) IO_() *kaitai.Stream {
	return this._io
}

func (this *DoomWad) Read(io *kaitai.Stream, parent kaitai.Struct, root *DoomWad) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp1, err := this._io.ReadBytes(int(4))
	if err != nil {
		return err
	}
	tmp1 = tmp1
	this.Magic = string(tmp1)
	tmp2, err := this._io.ReadS4le()
	if err != nil {
		return err
	}
	this.NumIndexEntries = int32(tmp2)
	tmp3, err := this._io.ReadS4le()
	if err != nil {
		return err
	}
	this.IndexOffset = int32(tmp3)
	return err
}
func (this *DoomWad) Index() (v []*DoomWad_IndexEntry, err error) {
	if (this._f_index) {
		return this.index, nil
	}
	this._f_index = true
	_pos, err := this._io.Pos()
	if err != nil {
		return nil, err
	}
	_, err = this._io.Seek(int64(this.IndexOffset), io.SeekStart)
	if err != nil {
		return nil, err
	}
	for i := 0; i < int(this.NumIndexEntries); i++ {
		_ = i
		tmp4 := NewDoomWad_IndexEntry()
		err = tmp4.Read(this._io, this, this._root)
		if err != nil {
			return nil, err
		}
		this.index = append(this.index, tmp4)
	}
	_, err = this._io.Seek(_pos, io.SeekStart)
	if err != nil {
		return nil, err
	}
	return this.index, nil
}

/**
 * Number of entries in the lump index
 */

/**
 * Offset to the start of the index
 */
type DoomWad_Blockmap struct {
	OriginX int16
	OriginY int16
	NumCols int16
	NumRows int16
	LinedefsInBlock []*DoomWad_Blockmap_Blocklist
	_io *kaitai.Stream
	_root *DoomWad
	_parent *DoomWad_IndexEntry
}
func NewDoomWad_Blockmap() *DoomWad_Blockmap {
	return &DoomWad_Blockmap{
	}
}

func (this DoomWad_Blockmap) IO_() *kaitai.Stream {
	return this._io
}

func (this *DoomWad_Blockmap) Read(io *kaitai.Stream, parent *DoomWad_IndexEntry, root *DoomWad) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp5, err := this._io.ReadS2le()
	if err != nil {
		return err
	}
	this.OriginX = int16(tmp5)
	tmp6, err := this._io.ReadS2le()
	if err != nil {
		return err
	}
	this.OriginY = int16(tmp6)
	tmp7, err := this._io.ReadS2le()
	if err != nil {
		return err
	}
	this.NumCols = int16(tmp7)
	tmp8, err := this._io.ReadS2le()
	if err != nil {
		return err
	}
	this.NumRows = int16(tmp8)
	for i := 0; i < int(this.NumCols * this.NumRows); i++ {
		_ = i
		tmp9 := NewDoomWad_Blockmap_Blocklist()
		err = tmp9.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.LinedefsInBlock = append(this.LinedefsInBlock, tmp9)
	}
	return err
}

/**
 * Grid origin, X coord
 */

/**
 * Grid origin, Y coord
 */

/**
 * Number of columns
 */

/**
 * Number of rows
 */

/**
 * Lists of linedefs for every block
 */
type DoomWad_Blockmap_Blocklist struct {
	Offset uint16
	_io *kaitai.Stream
	_root *DoomWad
	_parent *DoomWad_Blockmap
	_f_linedefs bool
	linedefs []int16
}
func NewDoomWad_Blockmap_Blocklist() *DoomWad_Blockmap_Blocklist {
	return &DoomWad_Blockmap_Blocklist{
	}
}

func (this DoomWad_Blockmap_Blocklist) IO_() *kaitai.Stream {
	return this._io
}

func (this *DoomWad_Blockmap_Blocklist) Read(io *kaitai.Stream, parent *DoomWad_Blockmap, root *DoomWad) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp10, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.Offset = uint16(tmp10)
	return err
}

/**
 * List of linedefs found in this block
 */
func (this *DoomWad_Blockmap_Blocklist) Linedefs() (v []int16, err error) {
	if (this._f_linedefs) {
		return this.linedefs, nil
	}
	this._f_linedefs = true
	_pos, err := this._io.Pos()
	if err != nil {
		return nil, err
	}
	_, err = this._io.Seek(int64(this.Offset * 2), io.SeekStart)
	if err != nil {
		return nil, err
	}
	for i := 1;; i++ {
		tmp11, err := this._io.ReadS2le()
		if err != nil {
			return nil, err
		}
		_it := tmp11
		this.linedefs = append(this.linedefs, _it)
		if _it == -1 {
			break
		}
	}
	_, err = this._io.Seek(_pos, io.SeekStart)
	if err != nil {
		return nil, err
	}
	return this.linedefs, nil
}

/**
 * Offset to the list of linedefs
 */
type DoomWad_IndexEntry struct {
	Offset int32
	Size int32
	Name string
	_io *kaitai.Stream
	_root *DoomWad
	_parent *DoomWad
	_raw_contents []byte
	_f_contents bool
	contents interface{}
}
func NewDoomWad_IndexEntry() *DoomWad_IndexEntry {
	return &DoomWad_IndexEntry{
	}
}

func (this DoomWad_IndexEntry) IO_() *kaitai.Stream {
	return this._io
}

func (this *DoomWad_IndexEntry) Read(io *kaitai.Stream, parent *DoomWad, root *DoomWad) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp12, err := this._io.ReadS4le()
	if err != nil {
		return err
	}
	this.Offset = int32(tmp12)
	tmp13, err := this._io.ReadS4le()
	if err != nil {
		return err
	}
	this.Size = int32(tmp13)
	tmp14, err := this._io.ReadBytes(int(8))
	if err != nil {
		return err
	}
	tmp14 = kaitai.BytesStripRight(tmp14, 0)
	this.Name = string(tmp14)
	return err
}
func (this *DoomWad_IndexEntry) Contents() (v interface{}, err error) {
	if (this._f_contents) {
		return this.contents, nil
	}
	this._f_contents = true
	thisIo := this._root._io
	_pos, err := thisIo.Pos()
	if err != nil {
		return nil, err
	}
	_, err = thisIo.Seek(int64(this.Offset), io.SeekStart)
	if err != nil {
		return nil, err
	}
	switch (this.Name) {
	case "BLOCKMAP":
		tmp15, err := thisIo.ReadBytes(int(this.Size))
		if err != nil {
			return nil, err
		}
		tmp15 = tmp15
		this._raw_contents = tmp15
		_io__raw_contents := kaitai.NewStream(bytes.NewReader(this._raw_contents))
		tmp16 := NewDoomWad_Blockmap()
		err = tmp16.Read(_io__raw_contents, this, this._root)
		if err != nil {
			return nil, err
		}
		this.contents = tmp16
	case "LINEDEFS":
		tmp17, err := thisIo.ReadBytes(int(this.Size))
		if err != nil {
			return nil, err
		}
		tmp17 = tmp17
		this._raw_contents = tmp17
		_io__raw_contents := kaitai.NewStream(bytes.NewReader(this._raw_contents))
		tmp18 := NewDoomWad_Linedefs()
		err = tmp18.Read(_io__raw_contents, this, this._root)
		if err != nil {
			return nil, err
		}
		this.contents = tmp18
	case "PNAMES":
		tmp19, err := thisIo.ReadBytes(int(this.Size))
		if err != nil {
			return nil, err
		}
		tmp19 = tmp19
		this._raw_contents = tmp19
		_io__raw_contents := kaitai.NewStream(bytes.NewReader(this._raw_contents))
		tmp20 := NewDoomWad_Pnames()
		err = tmp20.Read(_io__raw_contents, this, this._root)
		if err != nil {
			return nil, err
		}
		this.contents = tmp20
	case "SECTORS":
		tmp21, err := thisIo.ReadBytes(int(this.Size))
		if err != nil {
			return nil, err
		}
		tmp21 = tmp21
		this._raw_contents = tmp21
		_io__raw_contents := kaitai.NewStream(bytes.NewReader(this._raw_contents))
		tmp22 := NewDoomWad_Sectors()
		err = tmp22.Read(_io__raw_contents, this, this._root)
		if err != nil {
			return nil, err
		}
		this.contents = tmp22
	case "SIDEDEFS":
		tmp23, err := thisIo.ReadBytes(int(this.Size))
		if err != nil {
			return nil, err
		}
		tmp23 = tmp23
		this._raw_contents = tmp23
		_io__raw_contents := kaitai.NewStream(bytes.NewReader(this._raw_contents))
		tmp24 := NewDoomWad_Sidedefs()
		err = tmp24.Read(_io__raw_contents, this, this._root)
		if err != nil {
			return nil, err
		}
		this.contents = tmp24
	case "TEXTURE1":
		tmp25, err := thisIo.ReadBytes(int(this.Size))
		if err != nil {
			return nil, err
		}
		tmp25 = tmp25
		this._raw_contents = tmp25
		_io__raw_contents := kaitai.NewStream(bytes.NewReader(this._raw_contents))
		tmp26 := NewDoomWad_Texture12()
		err = tmp26.Read(_io__raw_contents, this, this._root)
		if err != nil {
			return nil, err
		}
		this.contents = tmp26
	case "TEXTURE2":
		tmp27, err := thisIo.ReadBytes(int(this.Size))
		if err != nil {
			return nil, err
		}
		tmp27 = tmp27
		this._raw_contents = tmp27
		_io__raw_contents := kaitai.NewStream(bytes.NewReader(this._raw_contents))
		tmp28 := NewDoomWad_Texture12()
		err = tmp28.Read(_io__raw_contents, this, this._root)
		if err != nil {
			return nil, err
		}
		this.contents = tmp28
	case "THINGS":
		tmp29, err := thisIo.ReadBytes(int(this.Size))
		if err != nil {
			return nil, err
		}
		tmp29 = tmp29
		this._raw_contents = tmp29
		_io__raw_contents := kaitai.NewStream(bytes.NewReader(this._raw_contents))
		tmp30 := NewDoomWad_Things()
		err = tmp30.Read(_io__raw_contents, this, this._root)
		if err != nil {
			return nil, err
		}
		this.contents = tmp30
	case "VERTEXES":
		tmp31, err := thisIo.ReadBytes(int(this.Size))
		if err != nil {
			return nil, err
		}
		tmp31 = tmp31
		this._raw_contents = tmp31
		_io__raw_contents := kaitai.NewStream(bytes.NewReader(this._raw_contents))
		tmp32 := NewDoomWad_Vertexes()
		err = tmp32.Read(_io__raw_contents, this, this._root)
		if err != nil {
			return nil, err
		}
		this.contents = tmp32
	default:
		tmp33, err := thisIo.ReadBytes(int(this.Size))
		if err != nil {
			return nil, err
		}
		tmp33 = tmp33
		this._raw_contents = tmp33
	}
	_, err = thisIo.Seek(_pos, io.SeekStart)
	if err != nil {
		return nil, err
	}
	return this.contents, nil
}
type DoomWad_Linedef struct {
	VertexStartIdx uint16
	VertexEndIdx uint16
	Flags uint16
	LineType uint16
	SectorTag uint16
	SidedefRightIdx uint16
	SidedefLeftIdx uint16
	_io *kaitai.Stream
	_root *DoomWad
	_parent *DoomWad_Linedefs
}
func NewDoomWad_Linedef() *DoomWad_Linedef {
	return &DoomWad_Linedef{
	}
}

func (this DoomWad_Linedef) IO_() *kaitai.Stream {
	return this._io
}

func (this *DoomWad_Linedef) Read(io *kaitai.Stream, parent *DoomWad_Linedefs, root *DoomWad) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp34, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.VertexStartIdx = uint16(tmp34)
	tmp35, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.VertexEndIdx = uint16(tmp35)
	tmp36, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.Flags = uint16(tmp36)
	tmp37, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.LineType = uint16(tmp37)
	tmp38, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.SectorTag = uint16(tmp38)
	tmp39, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.SidedefRightIdx = uint16(tmp39)
	tmp40, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.SidedefLeftIdx = uint16(tmp40)
	return err
}
type DoomWad_Linedefs struct {
	Entries []*DoomWad_Linedef
	_io *kaitai.Stream
	_root *DoomWad
	_parent *DoomWad_IndexEntry
}
func NewDoomWad_Linedefs() *DoomWad_Linedefs {
	return &DoomWad_Linedefs{
	}
}

func (this DoomWad_Linedefs) IO_() *kaitai.Stream {
	return this._io
}

func (this *DoomWad_Linedefs) Read(io *kaitai.Stream, parent *DoomWad_IndexEntry, root *DoomWad) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	for i := 0;; i++ {
		tmp41, err := this._io.EOF()
		if err != nil {
			return err
		}
		if tmp41 {
			break
		}
		tmp42 := NewDoomWad_Linedef()
		err = tmp42.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.Entries = append(this.Entries, tmp42)
	}
	return err
}

/**
 * @see <a href="https://doom.fandom.com/wiki/PNAMES">Source</a>
 */
type DoomWad_Pnames struct {
	NumPatches uint32
	Names []string
	_io *kaitai.Stream
	_root *DoomWad
	_parent *DoomWad_IndexEntry
}
func NewDoomWad_Pnames() *DoomWad_Pnames {
	return &DoomWad_Pnames{
	}
}

func (this DoomWad_Pnames) IO_() *kaitai.Stream {
	return this._io
}

func (this *DoomWad_Pnames) Read(io *kaitai.Stream, parent *DoomWad_IndexEntry, root *DoomWad) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp43, err := this._io.ReadU4le()
	if err != nil {
		return err
	}
	this.NumPatches = uint32(tmp43)
	for i := 0; i < int(this.NumPatches); i++ {
		_ = i
		tmp44, err := this._io.ReadBytes(int(8))
		if err != nil {
			return err
		}
		tmp44 = kaitai.BytesStripRight(tmp44, 0)
		this.Names = append(this.Names, string(tmp44))
	}
	return err
}

/**
 * Number of patches registered in this global game directory
 */

type DoomWad_Sector_SpecialSector int
const (
	DoomWad_Sector_SpecialSector__Normal DoomWad_Sector_SpecialSector = 0
	DoomWad_Sector_SpecialSector__DLightFlicker DoomWad_Sector_SpecialSector = 1
	DoomWad_Sector_SpecialSector__DLightStrobeFast DoomWad_Sector_SpecialSector = 2
	DoomWad_Sector_SpecialSector__DLightStrobeSlow DoomWad_Sector_SpecialSector = 3
	DoomWad_Sector_SpecialSector__DLightStrobeHurt DoomWad_Sector_SpecialSector = 4
	DoomWad_Sector_SpecialSector__DDamageHellslime DoomWad_Sector_SpecialSector = 5
	DoomWad_Sector_SpecialSector__DDamageNukage DoomWad_Sector_SpecialSector = 7
	DoomWad_Sector_SpecialSector__DLightGlow DoomWad_Sector_SpecialSector = 8
	DoomWad_Sector_SpecialSector__Secret DoomWad_Sector_SpecialSector = 9
	DoomWad_Sector_SpecialSector__DSectorDoorCloseIn30 DoomWad_Sector_SpecialSector = 10
	DoomWad_Sector_SpecialSector__DDamageEnd DoomWad_Sector_SpecialSector = 11
	DoomWad_Sector_SpecialSector__DLightStrobeSlowSync DoomWad_Sector_SpecialSector = 12
	DoomWad_Sector_SpecialSector__DLightStrobeFastSync DoomWad_Sector_SpecialSector = 13
	DoomWad_Sector_SpecialSector__DSectorDoorRaiseIn5Mins DoomWad_Sector_SpecialSector = 14
	DoomWad_Sector_SpecialSector__DFrictionLow DoomWad_Sector_SpecialSector = 15
	DoomWad_Sector_SpecialSector__DDamageSuperHellslime DoomWad_Sector_SpecialSector = 16
	DoomWad_Sector_SpecialSector__DLightFireFlicker DoomWad_Sector_SpecialSector = 17
	DoomWad_Sector_SpecialSector__DDamageLavaWimpy DoomWad_Sector_SpecialSector = 18
	DoomWad_Sector_SpecialSector__DDamageLavaHefty DoomWad_Sector_SpecialSector = 19
	DoomWad_Sector_SpecialSector__DScrollEastLavaDamage DoomWad_Sector_SpecialSector = 20
	DoomWad_Sector_SpecialSector__LightPhased DoomWad_Sector_SpecialSector = 21
	DoomWad_Sector_SpecialSector__LightSequenceStart DoomWad_Sector_SpecialSector = 22
	DoomWad_Sector_SpecialSector__LightSequenceSpecial1 DoomWad_Sector_SpecialSector = 23
	DoomWad_Sector_SpecialSector__LightSequenceSpecial2 DoomWad_Sector_SpecialSector = 24
)
var values_DoomWad_Sector_SpecialSector = map[DoomWad_Sector_SpecialSector]struct{}{0: {}, 1: {}, 2: {}, 3: {}, 4: {}, 5: {}, 7: {}, 8: {}, 9: {}, 10: {}, 11: {}, 12: {}, 13: {}, 14: {}, 15: {}, 16: {}, 17: {}, 18: {}, 19: {}, 20: {}, 21: {}, 22: {}, 23: {}, 24: {}}
func (v DoomWad_Sector_SpecialSector) isDefined() bool {
	_, ok := values_DoomWad_Sector_SpecialSector[v]
	return ok
}
type DoomWad_Sector struct {
	FloorZ int16
	CeilZ int16
	FloorFlat string
	CeilFlat string
	Light int16
	SpecialType DoomWad_Sector_SpecialSector
	Tag uint16
	_io *kaitai.Stream
	_root *DoomWad
	_parent *DoomWad_Sectors
}
func NewDoomWad_Sector() *DoomWad_Sector {
	return &DoomWad_Sector{
	}
}

func (this DoomWad_Sector) IO_() *kaitai.Stream {
	return this._io
}

func (this *DoomWad_Sector) Read(io *kaitai.Stream, parent *DoomWad_Sectors, root *DoomWad) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp45, err := this._io.ReadS2le()
	if err != nil {
		return err
	}
	this.FloorZ = int16(tmp45)
	tmp46, err := this._io.ReadS2le()
	if err != nil {
		return err
	}
	this.CeilZ = int16(tmp46)
	tmp47, err := this._io.ReadBytes(int(8))
	if err != nil {
		return err
	}
	tmp47 = tmp47
	this.FloorFlat = string(tmp47)
	tmp48, err := this._io.ReadBytes(int(8))
	if err != nil {
		return err
	}
	tmp48 = tmp48
	this.CeilFlat = string(tmp48)
	tmp49, err := this._io.ReadS2le()
	if err != nil {
		return err
	}
	this.Light = int16(tmp49)
	tmp50, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.SpecialType = DoomWad_Sector_SpecialSector(tmp50)
	tmp51, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.Tag = uint16(tmp51)
	return err
}

/**
 * Light level of the sector [0..255]. Original engine uses
 * COLORMAP to render lighting, so only 32 actual levels are
 * available (i.e. 0..7, 8..15, etc).
 */

/**
 * Tag number. When the linedef with the same tag number is
 * activated, some effect will be triggered in this sector.
 */
type DoomWad_Sectors struct {
	Entries []*DoomWad_Sector
	_io *kaitai.Stream
	_root *DoomWad
	_parent *DoomWad_IndexEntry
}
func NewDoomWad_Sectors() *DoomWad_Sectors {
	return &DoomWad_Sectors{
	}
}

func (this DoomWad_Sectors) IO_() *kaitai.Stream {
	return this._io
}

func (this *DoomWad_Sectors) Read(io *kaitai.Stream, parent *DoomWad_IndexEntry, root *DoomWad) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	for i := 0;; i++ {
		tmp52, err := this._io.EOF()
		if err != nil {
			return err
		}
		if tmp52 {
			break
		}
		tmp53 := NewDoomWad_Sector()
		err = tmp53.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.Entries = append(this.Entries, tmp53)
	}
	return err
}
type DoomWad_Sidedef struct {
	OffsetX int16
	OffsetY int16
	UpperTextureName string
	LowerTextureName string
	NormalTextureName string
	SectorId int16
	_io *kaitai.Stream
	_root *DoomWad
	_parent *DoomWad_Sidedefs
}
func NewDoomWad_Sidedef() *DoomWad_Sidedef {
	return &DoomWad_Sidedef{
	}
}

func (this DoomWad_Sidedef) IO_() *kaitai.Stream {
	return this._io
}

func (this *DoomWad_Sidedef) Read(io *kaitai.Stream, parent *DoomWad_Sidedefs, root *DoomWad) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp54, err := this._io.ReadS2le()
	if err != nil {
		return err
	}
	this.OffsetX = int16(tmp54)
	tmp55, err := this._io.ReadS2le()
	if err != nil {
		return err
	}
	this.OffsetY = int16(tmp55)
	tmp56, err := this._io.ReadBytes(int(8))
	if err != nil {
		return err
	}
	tmp56 = tmp56
	this.UpperTextureName = string(tmp56)
	tmp57, err := this._io.ReadBytes(int(8))
	if err != nil {
		return err
	}
	tmp57 = tmp57
	this.LowerTextureName = string(tmp57)
	tmp58, err := this._io.ReadBytes(int(8))
	if err != nil {
		return err
	}
	tmp58 = tmp58
	this.NormalTextureName = string(tmp58)
	tmp59, err := this._io.ReadS2le()
	if err != nil {
		return err
	}
	this.SectorId = int16(tmp59)
	return err
}
type DoomWad_Sidedefs struct {
	Entries []*DoomWad_Sidedef
	_io *kaitai.Stream
	_root *DoomWad
	_parent *DoomWad_IndexEntry
}
func NewDoomWad_Sidedefs() *DoomWad_Sidedefs {
	return &DoomWad_Sidedefs{
	}
}

func (this DoomWad_Sidedefs) IO_() *kaitai.Stream {
	return this._io
}

func (this *DoomWad_Sidedefs) Read(io *kaitai.Stream, parent *DoomWad_IndexEntry, root *DoomWad) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	for i := 0;; i++ {
		tmp60, err := this._io.EOF()
		if err != nil {
			return err
		}
		if tmp60 {
			break
		}
		tmp61 := NewDoomWad_Sidedef()
		err = tmp61.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.Entries = append(this.Entries, tmp61)
	}
	return err
}

/**
 * Used for TEXTURE1 and TEXTURE2 lumps, which designate how to
 * combine wall patches to make wall textures. This essentially
 * provides a very simple form of image compression, allowing
 * certain elements ("patches") to be reused / recombined on
 * different textures for more variety in the game.
 * @see <a href="https://doom.fandom.com/wiki/TEXTURE1_and_TEXTURE2">Source</a>
 */
type DoomWad_Texture12 struct {
	NumTextures int32
	Textures []*DoomWad_Texture12_TextureIndex
	_io *kaitai.Stream
	_root *DoomWad
	_parent *DoomWad_IndexEntry
}
func NewDoomWad_Texture12() *DoomWad_Texture12 {
	return &DoomWad_Texture12{
	}
}

func (this DoomWad_Texture12) IO_() *kaitai.Stream {
	return this._io
}

func (this *DoomWad_Texture12) Read(io *kaitai.Stream, parent *DoomWad_IndexEntry, root *DoomWad) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp62, err := this._io.ReadS4le()
	if err != nil {
		return err
	}
	this.NumTextures = int32(tmp62)
	for i := 0; i < int(this.NumTextures); i++ {
		_ = i
		tmp63 := NewDoomWad_Texture12_TextureIndex()
		err = tmp63.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.Textures = append(this.Textures, tmp63)
	}
	return err
}

/**
 * Number of wall textures
 */
type DoomWad_Texture12_Patch struct {
	OriginX int16
	OriginY int16
	PatchId uint16
	StepDir uint16
	Colormap uint16
	_io *kaitai.Stream
	_root *DoomWad
	_parent *DoomWad_Texture12_TextureBody
}
func NewDoomWad_Texture12_Patch() *DoomWad_Texture12_Patch {
	return &DoomWad_Texture12_Patch{
	}
}

func (this DoomWad_Texture12_Patch) IO_() *kaitai.Stream {
	return this._io
}

func (this *DoomWad_Texture12_Patch) Read(io *kaitai.Stream, parent *DoomWad_Texture12_TextureBody, root *DoomWad) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp64, err := this._io.ReadS2le()
	if err != nil {
		return err
	}
	this.OriginX = int16(tmp64)
	tmp65, err := this._io.ReadS2le()
	if err != nil {
		return err
	}
	this.OriginY = int16(tmp65)
	tmp66, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.PatchId = uint16(tmp66)
	tmp67, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.StepDir = uint16(tmp67)
	tmp68, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.Colormap = uint16(tmp68)
	return err
}

/**
 * X offset to draw a patch at (pixels from left boundary of a texture)
 */

/**
 * Y offset to draw a patch at (pixels from upper boundary of a texture)
 */

/**
 * Identifier of a patch (as listed in PNAMES lump) to draw
 */
type DoomWad_Texture12_TextureBody struct {
	Name string
	Masked uint32
	Width uint16
	Height uint16
	ColumnDirectory uint32
	NumPatches uint16
	Patches []*DoomWad_Texture12_Patch
	_io *kaitai.Stream
	_root *DoomWad
	_parent *DoomWad_Texture12_TextureIndex
}
func NewDoomWad_Texture12_TextureBody() *DoomWad_Texture12_TextureBody {
	return &DoomWad_Texture12_TextureBody{
	}
}

func (this DoomWad_Texture12_TextureBody) IO_() *kaitai.Stream {
	return this._io
}

func (this *DoomWad_Texture12_TextureBody) Read(io *kaitai.Stream, parent *DoomWad_Texture12_TextureIndex, root *DoomWad) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp69, err := this._io.ReadBytes(int(8))
	if err != nil {
		return err
	}
	tmp69 = kaitai.BytesStripRight(tmp69, 0)
	this.Name = string(tmp69)
	tmp70, err := this._io.ReadU4le()
	if err != nil {
		return err
	}
	this.Masked = uint32(tmp70)
	tmp71, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.Width = uint16(tmp71)
	tmp72, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.Height = uint16(tmp72)
	tmp73, err := this._io.ReadU4le()
	if err != nil {
		return err
	}
	this.ColumnDirectory = uint32(tmp73)
	tmp74, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.NumPatches = uint16(tmp74)
	for i := 0; i < int(this.NumPatches); i++ {
		_ = i
		tmp75 := NewDoomWad_Texture12_Patch()
		err = tmp75.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.Patches = append(this.Patches, tmp75)
	}
	return err
}

/**
 * Name of a texture, only `A-Z`, `0-9`, `[]_-` are valid
 */

/**
 * Obsolete, ignored by all DOOM versions
 */

/**
 * Number of patches that are used in a texture
 */
type DoomWad_Texture12_TextureIndex struct {
	Offset int32
	_io *kaitai.Stream
	_root *DoomWad
	_parent *DoomWad_Texture12
	_f_body bool
	body *DoomWad_Texture12_TextureBody
}
func NewDoomWad_Texture12_TextureIndex() *DoomWad_Texture12_TextureIndex {
	return &DoomWad_Texture12_TextureIndex{
	}
}

func (this DoomWad_Texture12_TextureIndex) IO_() *kaitai.Stream {
	return this._io
}

func (this *DoomWad_Texture12_TextureIndex) Read(io *kaitai.Stream, parent *DoomWad_Texture12, root *DoomWad) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp76, err := this._io.ReadS4le()
	if err != nil {
		return err
	}
	this.Offset = int32(tmp76)
	return err
}
func (this *DoomWad_Texture12_TextureIndex) Body() (v *DoomWad_Texture12_TextureBody, err error) {
	if (this._f_body) {
		return this.body, nil
	}
	this._f_body = true
	_pos, err := this._io.Pos()
	if err != nil {
		return nil, err
	}
	_, err = this._io.Seek(int64(this.Offset), io.SeekStart)
	if err != nil {
		return nil, err
	}
	tmp77 := NewDoomWad_Texture12_TextureBody()
	err = tmp77.Read(this._io, this, this._root)
	if err != nil {
		return nil, err
	}
	this.body = tmp77
	_, err = this._io.Seek(_pos, io.SeekStart)
	if err != nil {
		return nil, err
	}
	return this.body, nil
}
type DoomWad_Thing struct {
	X int16
	Y int16
	Angle uint16
	Type uint16
	Flags uint16
	_io *kaitai.Stream
	_root *DoomWad
	_parent *DoomWad_Things
}
func NewDoomWad_Thing() *DoomWad_Thing {
	return &DoomWad_Thing{
	}
}

func (this DoomWad_Thing) IO_() *kaitai.Stream {
	return this._io
}

func (this *DoomWad_Thing) Read(io *kaitai.Stream, parent *DoomWad_Things, root *DoomWad) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp78, err := this._io.ReadS2le()
	if err != nil {
		return err
	}
	this.X = int16(tmp78)
	tmp79, err := this._io.ReadS2le()
	if err != nil {
		return err
	}
	this.Y = int16(tmp79)
	tmp80, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.Angle = uint16(tmp80)
	tmp81, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.Type = uint16(tmp81)
	tmp82, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.Flags = uint16(tmp82)
	return err
}
type DoomWad_Things struct {
	Entries []*DoomWad_Thing
	_io *kaitai.Stream
	_root *DoomWad
	_parent *DoomWad_IndexEntry
}
func NewDoomWad_Things() *DoomWad_Things {
	return &DoomWad_Things{
	}
}

func (this DoomWad_Things) IO_() *kaitai.Stream {
	return this._io
}

func (this *DoomWad_Things) Read(io *kaitai.Stream, parent *DoomWad_IndexEntry, root *DoomWad) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	for i := 0;; i++ {
		tmp83, err := this._io.EOF()
		if err != nil {
			return err
		}
		if tmp83 {
			break
		}
		tmp84 := NewDoomWad_Thing()
		err = tmp84.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.Entries = append(this.Entries, tmp84)
	}
	return err
}
type DoomWad_Vertex struct {
	X int16
	Y int16
	_io *kaitai.Stream
	_root *DoomWad
	_parent *DoomWad_Vertexes
}
func NewDoomWad_Vertex() *DoomWad_Vertex {
	return &DoomWad_Vertex{
	}
}

func (this DoomWad_Vertex) IO_() *kaitai.Stream {
	return this._io
}

func (this *DoomWad_Vertex) Read(io *kaitai.Stream, parent *DoomWad_Vertexes, root *DoomWad) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp85, err := this._io.ReadS2le()
	if err != nil {
		return err
	}
	this.X = int16(tmp85)
	tmp86, err := this._io.ReadS2le()
	if err != nil {
		return err
	}
	this.Y = int16(tmp86)
	return err
}
type DoomWad_Vertexes struct {
	Entries []*DoomWad_Vertex
	_io *kaitai.Stream
	_root *DoomWad
	_parent *DoomWad_IndexEntry
}
func NewDoomWad_Vertexes() *DoomWad_Vertexes {
	return &DoomWad_Vertexes{
	}
}

func (this DoomWad_Vertexes) IO_() *kaitai.Stream {
	return this._io
}

func (this *DoomWad_Vertexes) Read(io *kaitai.Stream, parent *DoomWad_IndexEntry, root *DoomWad) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	for i := 0;; i++ {
		tmp87, err := this._io.EOF()
		if err != nil {
			return err
		}
		if tmp87 {
			break
		}
		tmp88 := NewDoomWad_Vertex()
		err = tmp88.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.Entries = append(this.Entries, tmp88)
	}
	return err
}