Class: NEXXT::Parser::Session
- Inherits:
-
Object
- Object
- NEXXT::Parser::Session
- Defined in:
- lib/nexxt/parser/session.rb
Instance Attribute Summary collapse
-
#chr_copy ⇒ Object
readonly
Returns the value of attribute chr_copy.
-
#chr_main ⇒ Object
readonly
Returns the value of attribute chr_main.
-
#flat_table ⇒ Object
readonly
Returns the value of attribute flat_table.
-
#metasprites ⇒ Object
readonly
Returns the value of attribute metasprites.
-
#metasprites_offset ⇒ Object
readonly
Returns the value of attribute metasprites_offset.
-
#table ⇒ Object
readonly
Returns the value of attribute table.
-
#text ⇒ Object
readonly
Returns the value of attribute text.
Class Method Summary collapse
- .decode_hex(string) ⇒ Object
- .decompose_key(key) ⇒ Object
- .make_metasprites(names:, bytes:, offset:) ⇒ Object
- .metasprite_names(table) ⇒ Object
- .parse_table(flat_table) ⇒ Object
- .read(file) ⇒ Object
Instance Method Summary collapse
-
#initialize(text) ⇒ Session
constructor
A new instance of Session.
Constructor Details
#initialize(text) ⇒ Session
Returns a new instance of Session.
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/nexxt/parser/session.rb', line 11 def initialize(text) @text = text lines = text.lines(chomp: true).compact @flat_table = lines.grep(/=/).to_h { |line| line.split('=', 2) } @table = Session.parse_table(@flat_table) @chr_main = Session.decode_hex(@table.dig('CHR', 'Main')) @chr_copy = Session.decode_hex(@table.dig('CHR', 'Copy')) @chr_undo = Session.decode_hex(@table.dig('CHR', 'Undo')) @metasprites_offset = @table.dig('Var', 'Sprite', 'Grid').then do |grid| { x: grid['X'].to_i, y: grid['Y'].to_i } end @metasprites = Session.( names: Session.(@table.dig('Meta', 'Sprite')), bytes: Session.decode_hex(@table.dig('Meta', 'Sprites')), offset: @metasprites_offset ) end |
Instance Attribute Details
#chr_copy ⇒ Object (readonly)
Returns the value of attribute chr_copy.
8 9 10 |
# File 'lib/nexxt/parser/session.rb', line 8 def chr_copy @chr_copy end |
#chr_main ⇒ Object (readonly)
Returns the value of attribute chr_main.
8 9 10 |
# File 'lib/nexxt/parser/session.rb', line 8 def chr_main @chr_main end |
#flat_table ⇒ Object (readonly)
Returns the value of attribute flat_table.
8 9 10 |
# File 'lib/nexxt/parser/session.rb', line 8 def flat_table @flat_table end |
#metasprites ⇒ Object (readonly)
Returns the value of attribute metasprites.
8 9 10 |
# File 'lib/nexxt/parser/session.rb', line 8 def @metasprites end |
#metasprites_offset ⇒ Object (readonly)
Returns the value of attribute metasprites_offset.
8 9 10 |
# File 'lib/nexxt/parser/session.rb', line 8 def @metasprites_offset end |
#table ⇒ Object (readonly)
Returns the value of attribute table.
8 9 10 |
# File 'lib/nexxt/parser/session.rb', line 8 def table @table end |
#text ⇒ Object (readonly)
Returns the value of attribute text.
8 9 10 |
# File 'lib/nexxt/parser/session.rb', line 8 def text @text end |
Class Method Details
.decode_hex(string) ⇒ Object
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/nexxt/parser/session.rb', line 57 def self.decode_hex(string) return if string.nil? || string.empty? string = string['_root'] if string.is_a?(Hash) values = [] until string.empty? match = string.match(/\A(?:\[(?<rle>[0-9a-f]+)\]|(?<literal>[0-9a-f]{2}))(?<rest>.*)/) raise "Invalid string #{string}" unless match if (rle = match['rle']) values += [values[-1] || 0] * (rle.to_i(16) - 1) elsif (literal = match['literal']) values << literal.to_i(16) end string = match['rest'] end values end |
.decompose_key(key) ⇒ Object
53 54 55 |
# File 'lib/nexxt/parser/session.rb', line 53 def self.decompose_key(key) key.split(/(?<=[^A-Z0-9])(?=[A-Z0-9])|(?<=CHR)/).map { |part| part.delete('_') } end |
.make_metasprites(names:, bytes:, offset:) ⇒ Object
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/nexxt/parser/session.rb', line 83 def self.(names:, bytes:, offset:) return [] if bytes.nil? || bytes.empty? sprites = bytes.each_slice(256) .to_a .map do || .each_slice(4) .reject { |row| row[0] == 255 && row[2] == 255 && row[3] == 255 } .map do |y, tile, attribute, x| raise "Invalid bytes #{bytes}" if y.nil? || tile.nil? || attribute.nil? || x.nil? Sprite.new(y: y - offset[:y], tile: tile, attribute: attribute, x: x - offset[:x]) end end names.map do |name, index| Metasprite.new(name: name, sprites: sprites[index]) end end |
.metasprite_names(table) ⇒ Object
76 77 78 79 80 81 |
# File 'lib/nexxt/parser/session.rb', line 76 def self.(table) return {} if table.nil? table.select { |key, value| value.is_a?(String) && key =~ /\d/ } .to_h { |key, value| [value, key.to_i] } end |
.parse_table(flat_table) ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/nexxt/parser/session.rb', line 36 def self.parse_table(flat_table) table = {} flat_table.each do |key, value| path = decompose_key(key) path.reduce(table) do |a, e| a[e] = { '_root' => a[e] } unless a[e].nil? || a[e].is_a?(Hash) a[e] ||= {} end if path.size > 1 table.dig(*path[..-2])[path[-1]] = value else table[path.first] = value end end table end |
.read(file) ⇒ Object
32 33 34 |
# File 'lib/nexxt/parser/session.rb', line 32 def self.read(file) new(File.read(file)) end |