Skip to content

Instantly share code, notes, and snippets.

@shinyquagsire23
Last active September 6, 2023 22:09
Show Gist options
  • Save shinyquagsire23/20a86e65206ece28683a9b4c5597e172 to your computer and use it in GitHub Desktop.
Save shinyquagsire23/20a86e65206ece28683a9b4c5597e172 to your computer and use it in GitHub Desktop.
LEGO LOCO RFH/RFD unpacker
import struct
import os
contents = open("resource.RFH", "rb").read()
blob_f = open("resource.RFD", "rb")
def huff_decompress(data):
bits = 0
node = struct.unpack("<H", data[4:6])[0]
decomp = ""
for bytepos in range(0x808, len(data)):
bits = struct.unpack("<B", data[bytepos:bytepos+1])[0]
for bit in range(0, 8):
bit = bits & 1
bits = bits >> 1
nodepos = ((node * 4) + (bit * 2) + 8)
node = struct.unpack("<H", data[nodepos:nodepos+2])[0]
isterminal = (node & 0x100) == 0
if isterminal:
decomp += chr(node)
node = struct.unpack("<H", data[4:6])[0]
return decomp
pos = 0
while True:
str_len = struct.unpack("<L", contents[pos:pos+4])[0]
pos += 4
filename = "extract/"
for i in range(0, str_len-1):
filename += contents[pos]
pos += 1
pos += 1
file_size = struct.unpack("<L", contents[pos:pos+4])[0]
pos += 4
flags = struct.unpack("<L", contents[pos:pos+4])[0]
pos += 4
filename = filename.replace("\\", "/")
print filename + " size 0x%08x" % file_size + " compressed 0x%08x" % flags
if not os.path.exists(os.path.dirname(filename)):
try:
os.makedirs(os.path.dirname(filename))
except:
idk = 0
data = blob_f.read(file_size)
if flags & 1:
data = huff_decompress(data)
open(filename, "wb").write(data)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment