Class: Doom::Wad::Reader
- Inherits:
-
Object
- Object
- Doom::Wad::Reader
- Defined in:
- lib/doom/wad/reader.rb
Defined Under Namespace
Classes: DirectoryEntry
Constant Summary collapse
- IWAD =
'IWAD'- PWAD =
'PWAD'
Instance Attribute Summary collapse
-
#directory ⇒ Object
readonly
Returns the value of attribute directory.
-
#num_lumps ⇒ Object
readonly
Returns the value of attribute num_lumps.
-
#type ⇒ Object
readonly
Returns the value of attribute type.
Instance Method Summary collapse
- #close ⇒ Object
- #find_lump(name) ⇒ Object
-
#initialize(path) ⇒ Reader
constructor
A new instance of Reader.
- #iwad? ⇒ Boolean
- #lumps_between(start_marker, end_marker) ⇒ Object
-
#merge_pwad(pwad) ⇒ Object
Merge a PWAD on top of this IWAD.
- #pwad? ⇒ Boolean
- #read_lump(name) ⇒ Object
-
#read_lump_at(entry) ⇒ Object
Read a lump by directory entry, checking if it belongs to a PWAD file.
-
#read_lump_own(entry) ⇒ Object
Read a lump that belongs to this WAD's own file.
Constructor Details
#initialize(path) ⇒ 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
#directory ⇒ Object (readonly)
Returns the value of attribute directory.
11 12 13 |
# File 'lib/doom/wad/reader.rb', line 11 def directory @directory end |
#num_lumps ⇒ Object (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 |
#type ⇒ Object (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
#close ⇒ Object
96 97 98 99 |
# File 'lib/doom/wad/reader.rb', line 96 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
50 51 52 |
# File 'lib/doom/wad/reader.rb', line 50 def iwad? @type == IWAD end |
#lumps_between(start_marker, end_marker) ⇒ Object
38 39 40 41 42 43 44 |
# File 'lib/doom/wad/reader.rb', line 38 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.
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/doom/wad/reader.rb', line 57 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
46 47 48 |
# File 'lib/doom/wad/reader.rb', line 46 def pwad? @type == PWAD end |
#read_lump(name) ⇒ Object
23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# 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 # Route through read_lump_at, which reads from the file that actually # owns the entry. After merge_pwad a lump the PWAD overrode (PLAYPAL, # COLORMAP, TEXTUREx, PNAMES, a patch) lives in the PWAD file, so seeking # this reader's own IWAD handle at the entry's offset would read garbage. data = read_lump_at(entry) @lump_cache[name] = data data end |
#read_lump_at(entry) ⇒ Object
Read a lump by directory entry, checking if it belongs to a PWAD file
81 82 83 84 85 86 87 88 |
# File 'lib/doom/wad/reader.rb', line 81 def read_lump_at(entry) # Try PWAD files first (they may own this entry) (@pwad_files || []).each do |pwad| return pwad.read_lump_own(entry) if pwad.directory.include?(entry) end @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
91 92 93 94 |
# File 'lib/doom/wad/reader.rb', line 91 def read_lump_own(entry) @file.seek(entry.offset) @file.read(entry.size) end |