Tlk wraps a File object that points to a .tlk file.
Constants
| HEADER_SIZE | = | 20 |
| DATA_ELEMENT_SIZE | = | 4 + 16 + 4 + 4 + 4 + 4 + 4 |
Attributes
| cache | [R] | |
| language | [R] | The language_id of this Tlk. |
Public class methods
Cereate
# File lib/nwn/tlk.rb, line 32 32: def initialize io 33: @io = io 34: 35: # Read the header 36: @file_type, @file_version, language_id, 37: string_count, string_entries_offset = 38: @io.e_read(HEADER_SIZE, "header").unpack("A4 A4 I I I") 39: 40: raise IOError, "The given IO does not describe a valid tlk table" unless 41: @file_type == "TLK" && @file_version == "V3.0" 42: 43: @size = string_count 44: @language = language_id 45: @entries_offset = string_entries_offset 46: 47: @cache = {} 48: end
Public instance methods
Returns a TLK entry as a hash with the following keys:
:text string: The text :sound string: A sound resref, or "" if no sound is specified. :sound_length float: Length of the given resref (or 0.0 if no sound is given).
id is the numeric offset within the Tlk, starting at 0. The maximum is Tlk#size - 1.
# File lib/nwn/tlk.rb, line 57 57: def [](id) 58: return { :text => "", :sound => "", :sound_length => 0.0, :volume_variance => 0, :pitch_variance => 0} if id == 0xffffffff 59: 60: return @cache[id] if @cache[id] 61: 62: raise ArgumentError, "No such string ID: #{id.inspect}" if id > self.highest_id || id < 0 63: seek_to = HEADER_SIZE + (id) * DATA_ELEMENT_SIZE 64: @io.seek(seek_to) 65: data = @io.e_read(DATA_ELEMENT_SIZE, "tlk entry = #{id}") 66: 67: flags, sound_resref, v_variance, p_variance, offset, 68: size, sound_length = data.unpack("I A16 I I I I f") 69: flags = flags.to_i 70: 71: @io.seek(@entries_offset + offset) 72: text = @io.e_read(size, "tlk entry = #{id}, offset = #{@entries_offset + offset}") 73: 74: text = flags & 0x1 > 0 ? text : "" 75: sound = flags & 0x2 > 0 ? sound_resref : "" 76: sound_length = flags & 0x4 > 0 ? sound_length.to_f : 0.0 77: 78: @cache[id] = { 79: :text => text, :sound => sound, :sound_length => sound_length, 80: :volume_variance => v_variance, :pitch_variance => p_variance 81: } 82: end
Add a new entry to this Tlk and return the strref given to it. To override existing entries, use tlk[][:text] = “..“
# File lib/nwn/tlk.rb, line 86 86: def add text, sound = "", sound_length = 0.0, v_variance = 0, p_variance = 0 87: next_id = self.highest_id + 1 88: $stderr.puts "put in cache: #{next_id}" 89: @cache[next_id] = {:text => text, :sound => sound, :sound_length => 0.0, :volume_variance => v_variance, :pitch_variance => p_variance} 90: next_id 91: end
Return the highest ID in this Tlk table.
# File lib/nwn/tlk.rb, line 94 94: def highest_id 95: highest_cached = @cache.keys.sort[-1] || 0 96: @size - 1 > highest_cached ? @size - 1 : highest_cached 97: end
Write this Tlk to io. Take care not to write it to the same IO object you are reading from.
# File lib/nwn/tlk.rb, line 101 101: def write_to io 102: text_block = [] 103: offsets = [] 104: offset = 0 105: for i in 0..self.highest_id do 106: entry = self[i] 107: offsets[i] = offset 108: text_block << entry[:text] 109: offset += entry[:text].size 110: end 111: text_block = text_block.join("") 112: 113: header = [ 114: @file_type, @file_version, 115: @language, 116: self.highest_id + 1, HEADER_SIZE + (self.highest_id + 1) * DATA_ELEMENT_SIZE 117: ].pack("A4 A4 I I I") 118: 119: entries = [] 120: for i in 0..self.highest_id do 121: entry = self[i] 122: text, sound, sound_length = entry[:text], entry[:sound], entry[:sound_length] 123: flags = 0 124: flags |= 0x01 if text.size > 0 125: flags |= 0x02 if sound.size > 0 126: flags |= 0x04 if sound_length > 0.0 127: entries << [ 128: flags, sound, entry[:volume_variance], entry[:pitch_variance], offsets[i], text.size, sound_length 129: ].pack("I a16 I I I I f") 130: end 131: entries = entries.join("") 132: 133: io.write(header) 134: io.write(entries) 135: io.write(text_block) 136: end