Skip to content

Instantly share code, notes, and snippets.

@Andoryuuta
Created February 27, 2019 15:28
Show Gist options
  • Save Andoryuuta/82721ec457ce2c2f93042776f104f29d to your computer and use it in GitHub Desktop.
Save Andoryuuta/82721ec457ce2c2f93042776f104f29d to your computer and use it in GitHub Desktop.
VampiresDawn bin.dat & m.dat parsing.
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