Sorcerian (Genesis)/Notes

From Data Crystal
Jump to navigation Jump to search

Chip tiny.png The following article is a Notes Page for Sorcerian (Genesis).

Compression Algorithms

The game uses several compression algorithm for various data (gfx, some texts, maps), namely:

  • the infamous Nemesis compression algorithm
  • a LZ type algorithm, similar to the one used in Ys III
  • 2 similar RLE-type algorithms (described as RLE A and B), sometimes used one after the other (and sometimes not)

Description of RLE B

This routine require a step parameter to be specified.

At the beginning, start_decompressed_pos is 0.

  • first byte is fccccccc where f is a flag and ccccccc is a counter.

If this byte is 00, then the start_decompressed_pos is incremented (up to step - 1).

    • if f is clear, the next byte is read, and copied counter times every step bytes in the decompressed buffer
    • if f is set, the counter next bytes in source are copied every step bytes in the decompressed buffer

Pseudo Python code

# Buffer is a custom class, used for both source data and decompressed data
# 2 needed methods:
#    * read_b(), read_w(), read_l(): read a byte, a word or a long from the current position in the buffer 
#      (and updates current position)
#    * write_b(): write a byte to the current position in the buffer
#      (and updates current position, unless advance=False)

def rle_B_decode(src, step):
    dec = Buffer()
    
    for start in range(step):
        dec.set_pos(start)
        
        while True:
            counter = src.read_b()
            
            if counter == 0:
                break
            
            if bit(counter, 7) == 0:
                val = src.read_b()
                
                for _ in range(counter):
                    dec.write_b(val, advance=False)
                    dec.pos += step
                
            else:
                counter &= 0x7f
                
                for _ in range(counter):
                    dec.write_b(src.read_b(), advance=False)
                    dec.pos += step
        
    return dec