Class: Doom::Wad::Reader

Inherits:
Object
  • Object
show all
Defined in:
lib/doom/wad/reader.rb

Defined Under Namespace

Classes: DirectoryEntry

Constant Summary collapse

IWAD =
'IWAD'
PWAD =
'PWAD'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path) ⇒ Reader

Returns a new instance of Reader.



13
14
15
16
17
# File 'lib/doom/wad/reader.rb', line 13

def initialize(path)
  @file = File.open(path, 'rb')
  read_header
  read_directory
end

Instance Attribute Details

#directoryObject (readonly)

Returns the value of attribute directory.



11
12
13
# File 'lib/doom/wad/reader.rb', line 11

def directory
  @directory
end

#num_lumpsObject (readonly)

Returns the value of attribute num_lumps.



11
12
13
# File 'lib/doom/wad/reader.rb', line 11

def num_lumps
  @num_lumps
end

#typeObject (readonly)

Returns the value of attribute type.



11
12
13
# File 'lib/doom/wad/reader.rb', line 11

def type
  @type
end

Instance Method Details

#closeObject



99
100
101
102
# File 'lib/doom/wad/reader.rb', line 99

def close
  @file.close
  (@pwad_files || []).each(&:close)
end

#find_lump(name) ⇒ Object



19
20
21
# File 'lib/doom/wad/reader.rb', line 19

def find_lump(name)
  @directory.find { |entry| entry.name == name.upcase }
end

#iwad?Boolean

Returns:

  • (Boolean)


52
53
54
# File 'lib/doom/wad/reader.rb', line 52

def iwad?
  @type == IWAD
end

#lumps_between(start_marker, end_marker) ⇒ Object



40
41
42
43
44
45
46
# File 'lib/doom/wad/reader.rb', line 40

def lumps_between(start_marker, end_marker)
  start_idx = @directory.index { |e| e.name == start_marker }
  end_idx = @directory.index { |e| e.name == end_marker }
  return [] unless start_idx && end_idx

  @directory[start_idx + 1...end_idx]
end

#merge_pwad(pwad) ⇒ Object

Merge a PWAD on top of this IWAD. PWAD lumps override IWAD lumps with the same name. Map lumps (between map markers) are replaced as a group.

Raises:



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/doom/wad/reader.rb', line 59

def merge_pwad(pwad)
  raise Error, "Can only merge a PWAD" unless pwad.pwad?
  @lump_cache.clear

  pwad.directory.each do |pwad_entry|
    # Check if this lump already exists in the IWAD
    existing_idx = @directory.index { |e| e.name == pwad_entry.name }
    if existing_idx
      # Replace it -- but we need to read from the PWAD file
      @directory[existing_idx] = pwad_entry
    else
      # Append new lump
      @directory << pwad_entry
    end
  end

  # Keep the PWAD file open for reading its lumps
  @pwad_files ||= []
  @pwad_files << pwad
  @num_lumps = @directory.size
end

#pwad?Boolean

Returns:

  • (Boolean)


48
49
50
# File 'lib/doom/wad/reader.rb', line 48

def pwad?
  @type == PWAD
end

#read_lump(name) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
# File 'lib/doom/wad/reader.rb', line 23

def read_lump(name)
  return @lump_cache[name] if @lump_cache.key?(name)

  entry = find_lump(name)
  return nil unless entry

  @file.seek(entry.offset)
  data = @file.read(entry.size)
  @lump_cache[name] = data
  data
end

#read_lump_at(entry) ⇒ Object

Override read_lump_at to check if entry belongs to a PWAD file



82
83
84
85
# File 'lib/doom/wad/reader.rb', line 82

def read_lump_at(entry)
  @file.seek(entry.offset)
  @file.read(entry.size)
end

#read_lump_own(entry) ⇒ Object

Read a lump that belongs to this WAD’s own file



94
95
96
97
# File 'lib/doom/wad/reader.rb', line 94

def read_lump_own(entry)
  @file.seek(entry.offset)
  @file.read(entry.size)
end