Skip to content

Instantly share code, notes, and snippets.

@yupferris yupferris/mt.rs
Last active Aug 20, 2018

Embed
What would you like to do?
Mario's Tennis graphics decompression routine in Rust-like pseudo-code. Manual decompilation is a bitch. :)
fn decompress(mut src: *const u8, dst: *mut u8) {
// Skip first 2 bytes (they're always zero)
src += 2;
let original_dst = dst;
// Load bytes_left
let mut bytes_left = ((*src as i32) << 8) + 1;
src += 1;
bytes_left += *src as i32;
src += 1;
loop {
// Load packet_flags
let mut packet_flags = *src;
src += 1;
// Iterate over control bits (lsb -> msb)
for _ in 0..8 {
// Load data_byte
let data_byte = *src;
src += 1;
// Load packet_flag from packet_flags lsb
let packet_flag = packet_flags & 0x1;
if packet_flag != 0 {
// Literal byte; output data_byte directly
*dst = data_byte;
dst += 1;
bytes_left -= 1;
} else {
// Backreference; data_byte and next byte encode distance+length
let run_distance = (*src << 4) | (data_byte >> 4);
src += 1;
let mut run_length = (data_byte & 0xf) + 3;
bytes_left -= run_length;
// run_length may have been greater than bytes_left; this is some weird logic to correct that :)
// (it totally works; don't think too much about it.. I could make this more clear but I want
// it to match the original as much as possible)
if bytes_left < 0 {
run_length += bytes_left;
}
let mut run_source = dst - run_distance;
if run_source < original_dst {
let num_zeroes = original_dst - run_source;
for _ in 0..num_zeroes {
// Output zero and inc dst pointer
*dst = 0;
dst += 1;
}
run_length -= num_zeroes;
run_source = original_dst;
}
if run_length > 0 {
for _ in 0..run_length {
// Output byte at [run_source] and inc run_source and dst pointer
*dst = *run_source;
run_source += 1;
dst += 1;
}
}
}
// Shift out packet flag from this iteration
packet_flags >>= 1;
if bytes_left < 0 {
break;
}
}
if bytes_left < 0 {
break;
}
}
}
@yupferris

This comment has been minimized.

Copy link
Owner Author

yupferris commented Feb 23, 2017

Ended up posting the whole main.rs contents here: https://gist.github.com/yupferris/308ae85241f40ccca680d50e79f08e34

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.