Last active
May 6, 2016 23:19
-
-
Save svanellewee/5c0b0059f5e593e47f7753ffced7b724 to your computer and use it in GitHub Desktop.
Wad reader
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 sys | |
import logging | |
import struct | |
logging.basicConfig(level=logging.DEBUG) | |
logger =logging.getLogger(__name__) | |
def get_int(data): | |
return struct.unpack("<I", data)[0] | |
DIR_HEADER_SIZE=12 | |
def get_header(data_stream): | |
retval = {} | |
header = data_stream.read(DIR_HEADER_SIZE) | |
retval.update(dict(wad_type = header[:4])) | |
retval.update(dict(num_entries = get_int(header[4:8]))) | |
retval.update(dict(directory_absolute_location = get_int(header[8:DIR_HEADER_SIZE]))) | |
retval.update(dict(data_size = retval['directory_absolute_location'] - DIR_HEADER_SIZE)) | |
return retval | |
def get_data(data_stream, directory_location): | |
return { "data": data_stream.read(directory_location)} | |
def get_directory_entries(data_stream): | |
while True: | |
retval = {} | |
item = data_stream.read(16) | |
if len(item) != 16: | |
raise StopIteration | |
retval.update(dict(start = get_int(item[:4]))) | |
retval.update(dict(size = get_int(item[4:8]))) | |
retval.update(dict(name = item[8:16])) | |
yield retval | |
def build_directory(file_name): | |
with open(file_name, 'r') as wad_file: | |
header = get_header(wad_file) | |
wad_file.seek(header['directory_absolute_location']) | |
return [ i for i in get_directory_entries(wad_file)] | |
directory = build_directory(sys.argv[1]) | |
print len(directory) | |
def extract_data(file_name, directory, lumps_of_interest=None): | |
retval = {} | |
with open(file_name, 'r') as wad_file: | |
for lump in directory: | |
if lumps_of_interest and lump['start'] not in lumps_of_interest: | |
continue | |
wad_file.seek(lump['start']) | |
data = wad_file.read(lump['size']) | |
#print lump, len(data) | |
retval[lump['name'].strip('\0')] = data | |
return retval | |
E1M1_lumps = [ 67500, 68880, 75532, 94972, 96840, 105624, 106572, 113180, 115392, 116296 ] | |
data = extract_data(sys.argv[1], directory, E1M1_lumps) | |
for key, value in data.items(): | |
print key, len(value) | |
import io | |
def get_vertexes(byte_stream): | |
while True: | |
byte_elem = byte_stream.read(4) | |
if len(byte_elem) != 4: | |
raise StopIteration | |
yield struct.unpack("<hh", byte_elem) | |
def get_linedefs(byte_stream): | |
while True: | |
byte_elem = byte_stream.read(14) | |
if len(byte_elem) != 14: | |
raise StopIteration | |
retval = [] | |
#yield [ ord(i) for i in byte_elem] # 16 bytes | |
with io.BytesIO(byte_elem) as b: | |
retval.append(struct.unpack("<hh", b.read(4))) | |
# ignore the rest | |
yield retval | |
# a = struct.unpack("<hh", byte_elem[:4]) | |
# a = struct.unpack("<hh", byte_elem[:4]) | |
# a = struct.unpack("<hh", byte_elem[:4]) | |
# a = struct.unpack("<hh", byte_elem[:4]) | |
def get_dims(vertex_data): | |
lower_left = None | |
with io.BytesIO(vertex_data) as bio: | |
low = min(v[0] for v in get_vertexes(bio)) | |
bio.seek(0) | |
left = min(v[1] for v in get_vertexes(bio)) | |
bio.seek(0) | |
high = max(v[0] for v in get_vertexes(bio)) | |
bio.seek(0) | |
right = max(v[1] for v in get_vertexes(bio)) | |
lower_left = (low, left) | |
upper_right = (high, right) | |
return lower_left,upper_right | |
lower_left, upper_right = get_dims(data['VERTEXES']) | |
import svgwrite | |
dwg = svgwrite.Drawing('test.svg', size = (abs(upper_right[0]), abs(upper_right[1]))) | |
verts = [] | |
with io.BytesIO(data['VERTEXES']) as bio: | |
for v in get_vertexes(bio): | |
x, y = (v[0] - lower_left[0])/10.0, (v[1] - lower_left[1])/10.0 | |
verts.append((x,y)) | |
dwg.add(svgwrite.shapes.Rect((x,y),size=(0.5,0.5), stroke='#333', stroke_width=3)) | |
print len(verts),'LENG!' | |
count = 0 | |
with io.BytesIO(data['LINEDEFS']) as bio: | |
for v in get_linedefs(bio): | |
count += 1 | |
a,b = v[0] | |
print v, verts[a], verts[b] | |
dwg.add(dwg.line(verts[a],verts[b],stroke='#333', stroke_width=1)) | |
print count | |
dwg.save() | |
# some node fun. | |
with io.BytesIO(data['NODES']) as nodedata: | |
idx = 0 | |
while True: | |
dat = nodedata.read(8) | |
if not dat: | |
break | |
print idx,struct.unpack("<hhhh", dat) | |
idx +=1 | |
nodedata.read(16) | |
nodedata.read(4) |
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 sys | |
import logging | |
import struct | |
logging.basicConfig(level=logging.DEBUG) | |
logger =logging.getLogger(__name__) | |
# def getbytes(data): | |
# return struct.unpack('<I', data)[0] | |
DIR_HEADER_SIZE=12 | |
def get_directory(file_stream): | |
''' | |
0x00-0x03 string "PWAD" or "IWAD", defines whether the WAD is a PWAD or an IWAD | |
0x04-0x07 An integer specifying the number of entries in the directory | |
0x08-0x0b An integer holding a pointer to the location of the directory | |
''' | |
retval = {} | |
directory_raw = file_stream.read(DIR_HEADER_SIZE) | |
retval.update({"wad_type": directory_raw[:4]}) | |
retval.update({"num_entries": getbytes(directory_raw[4:8])[0]}) | |
retval.update({"location": getbytes(directory_raw[8:12])[0]}) | |
data_size = retval['location'] - DIR_HEADER_SIZE | |
retval.update({'data': file_stream.read(data_size)}) | |
return retval | |
def get_lump(file_stream): | |
lump = file_stream.read(16) | |
if len(lump) != 16: | |
return None | |
retval = {} | |
retval.update({"start": getbytes(lump[0:4])[0] - DIR_HEADER_SIZE}) | |
retval.update({"size": getbytes(lump[4:8])[0]}) | |
name = lump[8:16] | |
retval.update({"name": name}) | |
return retval | |
def getbytes(data): | |
return struct.unpack("<I", data) | |
with open(sys.argv[1],'rb') as wadfile: | |
directory_data = get_directory(wadfile) | |
print directory_data['wad_type'], directory_data['location'], directory_data['num_entries'], len(directory_data['data']) | |
while True: | |
lump = get_lump(wadfile) | |
if not lump: | |
break | |
data = directory_data['data'][lump['start']:lump['start']+lump['size']] | |
print lump, len(data) | |
if lump['name'] == 'VERTEXES': | |
print struct.unpack("<hh", data[0:4]) | |
print struct.unpack("<hh", data[4:8]) | |
# print struct.unpack("<hh", data[0:4]) | |
# print struct.unpack("<hh", data[0:4]) | |
# lump_start = getbytes(data[0:4]) | |
# lump_size = getbytes(data[4:8]) | |
# lump_name = data[8:16] | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Rendered file:
