Repository for mbEditorPro 2.0
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

116 lines
3.6 KiB

# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
# Magicbane Emulator Project © 2013 - 2022
# www.magicbane.com
import struct
import zlib
def read_dword(cache_file):
data = cache_file.read(4)
return struct.unpack('<I', data)[0]
def read_qword(cache_file):
dwords = struct.unpack('<II', cache_file.read(8))
buffer = struct.pack('<II', dwords[1], dwords[0])
return struct.unpack('<Q', buffer)[0]
def read_resource_data(cache_file, start, length):
current_position = cache_file.tell()
cache_file.seek(start)
data = cache_file.read(length)
cache_file.seek(current_position)
return data
def load_cache_file(filename):
cache_file = open(filename, 'rb')
num_resources = read_dword(cache_file)
read_dword(cache_file)
read_dword(cache_file)
read_dword(cache_file)
resources = []
for _ in range(num_resources):
resource_id = read_qword(cache_file)
resource_offset = read_dword(cache_file)
resource_decompressed_len = read_dword(cache_file)
resource_compressed_len = read_dword(cache_file)
resource_data = read_resource_data(
cache_file,
resource_offset,
resource_compressed_len
)
if resource_decompressed_len > resource_compressed_len:
resource_data = zlib.decompress(resource_data)
resources.append([
resource_id,
resource_data
])
return resources
def write_dword(cache_file, value):
data = struct.pack('<I', value)
cache_file.write(data)
def write_qword(cache_file, value):
qword = struct.pack('<Q', value)
dwords = [
struct.unpack('<I', qword[:4])[0],
struct.unpack('<I', qword[4:])[0],
]
data = struct.pack('<II', dwords[1], dwords[0])
cache_file.write(data)
def write_bytes(cache_file, value):
cache_file.write(value)
def save_cache_file(filename, resources, compress=True):
cache_file = open(filename, 'wb')
num_resources = len(resources)
last_offset = 0
last_offset += 0x10 # header
last_offset += num_resources * 0x14 # resource_headers
data_start = last_offset
for resource in resources:
resource.append(last_offset)
resource.append(len(resource[1]))
if compress:
resource[1] = zlib.compress(resource[1])
resource.append(len(resource[1]))
last_offset += resource[4]
data_end = last_offset
write_dword(cache_file, num_resources)
write_dword(cache_file, data_start)
write_dword(cache_file, data_end)
write_dword(cache_file, 0xffffffff)
for resource in resources:
write_qword(cache_file, resource[0])
write_dword(cache_file, resource[2])
write_dword(cache_file, resource[3])
write_dword(cache_file, resource[4])
for resource in resources:
write_bytes(cache_file, resource[1])