Created
February 27, 2019 15:28
-
-
Save Andoryuuta/82721ec457ce2c2f93042776f104f29d to your computer and use it in GitHub Desktop.
VampiresDawn bin.dat & m.dat parsing.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import struct | |
import math | |
import random | |
from hexdump import hexdump | |
def load_m_dat(): | |
with open('m.dat', 'rb') as f: | |
# Read until EOF | |
while f.read(1): | |
f.seek(-1,1) | |
m_id = f.read(1)[0] | |
size = struct.unpack('>H', f.read(2))[0] | |
data = f.read(size) | |
x_dim = data[1] << 3 | |
y_dim = data[2] << 3 | |
print('m_id: {}, size: {:X}, dim:{}x{}'.format(m_id, size, x_dim, y_dim)) | |
# Parse map data into an array | |
md = [[0 for x in range(x_dim)] for x in range(y_dim)] | |
cur = 4 | |
for y in range(y_dim): | |
for x in range(x_dim): | |
# Get the tile id for this x/y | |
md[y][x] = data[cur] & 0x7F | |
# If MSB is set then the tile id takes up 2 bytes. | |
if data[cur] & 0x80 != 0: | |
cur += 1 | |
md[y][x] = (data[cur] | data[cur] << 8) & 0xFFFF | |
cur += 1 | |
# Display in a way that you can see the structure, | |
# Associates random characters to tile IDs for IDs that cant be directly coverted to ASCII and printed. | |
printable_chars = [chr(i) for i in range(0x20, 0x7F)] | |
chosen_tile_to_char_map = {} | |
for xrow in md: | |
rs = '' | |
for tile_id in xrow: | |
used = chr(tile_id) | |
if tile_id < 0x20 or tile_id >= 0x7F: | |
try: | |
used = chosen_tile_to_char_map[tile_id] | |
except: | |
used = random.choice(printable_chars) | |
chosen_tile_to_char_map[tile_id] = used | |
rs += ' ' + used | |
print(rs) | |
def load_bin_dat(): | |
with open('bin.dat', 'rb') as f: | |
# Get the file count | |
count = struct.unpack('>I', f.read(4))[0] | |
offsets = [] | |
# Get the offsets | |
for i in range(count): | |
offset = struct.unpack('>I', f.read(4))[0] | |
print("i:{}, offset:{:X}".format(i, offset)) | |
offsets.append(offset) | |
# Extract the files | |
start = ((count*4)+4) | |
for i in range(len(offsets)-1): | |
f.seek(start+offsets[i]) | |
# Read until the start of the next offset | |
data = f.read(offsets[i+1]) | |
# Make filename, add .png ext if it starts with the png magic. | |
filename = str(i) | |
if data[0:4] == b'\x89PNG': | |
filename += '.png' | |
output_path = os.path.join('output', filename) | |
with open(output_path, 'wb') as outf: | |
outf.write(data) | |
print('wrote file: {}, size: {:X}'.format(output_path, len(data))) | |
load_bin_dat() | |
load_m_dat() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment