Module: Sabrina::Bytestream::RomOperations

Included in:
Sabrina::Bytestream
Defined in:
lib/sabrina/bytestream/rom_operations.rb

Overview

Methods related to writing and retrieving various ROM data.

Instance Method Summary collapse

Instance Method Details

#calculate_lengthInteger

TODO:

Return key :original_length for Lz77.uncompress is currently unreliable. Wipe and overwrite in place for table data is disabled.

Returns the length of the Lz77 data stored on the ROM if :lz77 mode is on and a table of offset is provided. Otherwise, returns the length of the byte data.

Returns:

  • (Integer)


103
104
105
106
107
108
109
# File 'lib/sabrina/bytestream/rom_operations.rb', line 103

def calculate_length
  return @length_cache if @length_cache
  if @lz77 && offset
    return @length_cache = @rom.read_lz77(offset)[:original_length]
  end
  to_bytes.length
end

#clear_cache(h = { lz77: true }) ⇒ self

Wipes the internal cache so that the data may be reloaded from ROM if present.

Subclasses should call this whenever the internal representation of data is changed, and define ByteOutput#generate_bytes to regenerate the byte data from the internal representation.

Parameters:

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

    @option h [Boolean] :lz77 whether to clear the internal representation

    as well (defaults to +true+).
    

Returns:

  • (self)


88
89
90
91
92
93
# File 'lib/sabrina/bytestream/rom_operations.rb', line 88

def clear_cache(h = { lz77: true })
  @lz77_cache = nil if h.fetch(:lz77, true)
  @length_cache = nil if h.fetch(:lz77, true) && !@lz77
  @bytes_cache = nil
  self
end

#reload_from_romself

Wipes the internal cache AND the representation so that the data may be synced from ROM if present.

Returns:

  • (self)


70
71
72
73
74
75
# File 'lib/sabrina/bytestream/rom_operations.rb', line 70

def reload_from_rom
  @representation = nil
  clear_cache
  present
  self
end

#write_to_romArray

TODO:

Return key :original_length for Lz77.uncompress is currently unreliable. Wipe and overwrite in place for table data is disabled.

Writes the byte data to the ROM, trying to use first the table index and then the offset (and failing if neither is known).

If the table index is known, the data will be written to an available free space on the ROM and the table will be updated.

If the table data is unknown, the data will be written in place at the offset.

This method will call #reload_from_rom and update and return the Sabrina::Bytestream#last_write array.

Returns:



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/sabrina/bytestream/rom_operations.rb', line 22

def write_to_rom
  old_length = calculate_length
  b = (@lz77 ? to_lz77 : to_bytes)
  new_length = b.length
  old_offset = offset

  unless @rom && old_offset
    fail 'Rom and offset or table/index must be set before writing.'
  end
  fail 'Byte string is empty. Aborting.' if b.empty?
  fail "Byte string too long #{new_length}. Aborting." if new_length > 10_000

  @last_write = []

  new_offset =
    if !@pointer_mode || !(@table && @index)
      @last_write << 'Bytestream#repoint: Overwriting in place.' \
      " (#{old_offset})"
      old_offset
      # Wipe and overwrite disabled due to
      # Lz77.uncompress[:original_length] inaccuracy.
      #
      # elsif new_length <= old_length
      # @last_write << 'Repoint: New length less than or equal to old' \
      #   'length, overwriting in place.'
      # @last_write << @rom.wipe(old_offset, old_length, true)
      # old_offset
    else
      o = repoint
      @last_write << 'Bytestream#repoint: Wiping disabled in this' \
        "version. Leaving #{old_length} bytes at #{old_offset}" \
        " (#{ format('%06X', old_offset) }) in #{@rom} intact."
      @last_write << "Bytestream#repoint: Repointed to #{o}" \
        " (#{ format('%06X', o) })."
      # @last_write << @rom.wipe(old_offset, old_length)
      o
    end

  @last_write << @rom.write(new_offset, b)
  clear_cache(lz77: false)

  @last_write
end