Class: Sabrina::GBAString

Inherits:
Bytestream show all
Defined in:
lib/sabrina/gba_string.rb

Overview

A class for dealing with string data stored on a ROM.

It is required that :rom and either :table and :index (recommended) or :offset be set in order to enable writing back to a ROM file.

Constant Summary collapse

BLANK =

The byte to recognize as a blank character (space) for line breaking.

"\x00"
FILLER =

The byte used to right-pad short strings to the desired length.

"\x00"
NEWLINE =

The line break byte.

"\xFE"
TERMINATOR =

The byte recognized as the end of GBA-encoded string data.

"\xFF"
MISSING_HEX =

The fallback byte for GBA encoding.

"\x00"
MISSING_CHR =

The fallback character for GBA decoding.

'?'
TERMINATOR_CHR =

An input string ending with this character will be treated as already terminated.

'$'

Instance Attribute Summary

Attributes inherited from Bytestream

#filename, #index, #last_write, #rom, #table, #work_dir

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Bytestream

#lz77_mode, #offset, #offset=, parse_offset, #pointer, #string_mode

Methods included from Bytestream::ByteInput

#from_bytes, #from_hex, #from_rom, #from_rom_as_lz77, #from_table, #from_table_as_pointer

Methods included from Bytestream::RomOperations

#calculate_length, #clear_cache, #reload_from_rom, #write_to_rom

Methods included from Bytestream::ByteOutput

#to_b, #to_bytes, #to_hex, #to_hex_reverse, #to_i, #to_lz77

Constructor Details

#initialize(h = {}) ⇒ GBAString

Same as Bytestream#initialize, but with :is_gba_string set to true by default and support for the following extra options.

Parameters:

  • h (Hash) (defaults to: {})

Options Hash (h):

  • :break_range (Range)

    where in the string to try and insert a newline.

See Also:



85
86
87
88
89
90
# File 'lib/sabrina/gba_string.rb', line 85

def initialize(h = {})
  @is_gba_string = true
  @break_range = nil

  super
end

Class Method Details

.from_rom(rom, offset, h = {}) ⇒ GBAString

Creates a new Sabrina::GBAString object from a ROM offset, attempting to read it as a GBA-encoded, 0xFF-terminated string.

Parameters:

Returns:



39
40
41
42
43
# File 'lib/sabrina/gba_string.rb', line 39

def from_rom(rom, offset, h = {})
  h.merge!(rom: rom, offset: offset)

  new(h)
end

.from_string(s, break_range = nil, length = nil, h = {}) ⇒ GBAString

Creates a new Sabrina::GBAString object from a string, encoding it to GBA format and optionally normalizing to length and breaking within break_range.

Parameters:

  • s (String)
  • length (Integer) (defaults to: nil)
  • break_range (Range) (defaults to: nil)
  • h (Hash) (defaults to: {})

Returns:



64
65
66
67
68
69
70
71
72
73
74
# File 'lib/sabrina/gba_string.rb', line 64

def from_string(s, break_range = nil, length = nil, h = {})
  length ||= (s.end_with?('$') ? s.length : s.length + 1)

  h.merge!(
    representation: s,
    length: length,
    break_range: break_range
  )

  new(h)
end

.from_table(rom, table, index, index_length = 11, h = {}) ⇒ GBAString

Same as Bytestream::ByteInput#from_table, but allows index_length to default to 11 (the typical value for a monster name table) and requires no length due to implicit string mode.



51
52
53
# File 'lib/sabrina/gba_string.rb', line 51

def from_table(rom, table, index, index_length = 11, h = {})
  super(rom, table, index, index_length, nil, h)
end

Instance Method Details

#generate_bytesString

Encodes the internal string data to a GBA-encoded byte stream.

Returns:

  • (String)


113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/sabrina/gba_string.rb', line 113

def generate_bytes
  s = present.dup

  a = s.scan(/./).map do |x|
    hexcode = Config.charmap_in.fetch(x, MISSING_HEX)
    hexcode.hex.chr
  end

  if @length
    if a.length > @length
      a.slice!(@length..-1)
    else
      a << FILLER until a.length >= @length
    end
    a[-1] = TERMINATOR
  else
    a << TERMINATOR
  end

  if @break_range
    break_index = @break_range.first + (a[@break_range].rindex(BLANK) || 3)
    a[break_index] = NEWLINE
  end

  a.map { |x| x.force_encoding('ASCII-8BIT') }
    .join(''.force_encoding('ASCII-8BIT'))
end

#presentString

Attempts to decode the byte data as a GBA-encoded string.

Returns:

  • (String)


95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/sabrina/gba_string.rb', line 95

def present
  return @representation if @representation

  charmap = Config.charmap_out
  # charmap.merge!(Config.charmap_out_special) if special

  a = []
  to_bytes.each_char do |x|
    hexcode = format('%02X', x.each_byte.to_a[0])
    a.push(charmap.fetch(hexcode, MISSING_CHR))
  end

  @representation = a.join('')
end

#to_sString

Returns the string representation with the end of string mark trimmed.

Returns:

  • (String)


144
145
146
# File 'lib/sabrina/gba_string.rb', line 144

def to_s
  present.dup.chomp('$')
end