-
Notifications
You must be signed in to change notification settings - Fork 5
/
txdef.py
executable file
·120 lines (102 loc) · 4.15 KB
/
txdef.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import collections
from omg import util, lump, wad
TextureDef = util.make_struct(
"TextureDef",
"""Class for texture definitions""",
[["name", '8s', "-"],
["dummy1", 'l', 0 ],
["width", 'h', 0 ],
["height", 'h', 0 ],
["dummy2", 'l', 0 ],
["npatches", 'h', 0 ]],
init_exec = "self.patches = []"
)
PatchDef = util.make_struct(
"PatchDef",
"""Class for patches""",
[["x", 'h', 0],
["y", 'h', 0],
["id", 'h', -1],
["dummy1", 'h', 1],
["dummy2", 'h', 0],
["name", 'x', "-"]]
)
# TODO: integrate with textures lump group instead?
class Textures(collections.OrderedDict):
"""An editor for Doom's TEXTURE1, TEXTURE2 and PNAMES lumps."""
def __init__(self, *args):
"""Create new, optionally loading content from given
TEXTURE1/2 and PNAMES lumps or a txdefs group. E.g.:
Textures(texture1, pnames)
Textures(txdefs)
"""
collections.OrderedDict.__init__(self)
if len(args):
self.from_lumps(*args)
def from_lumps(self, *args):
"""Load texture definitions from a TEXTURE1/2 lump and its
associated PNAMES lump, or a lump group containing the lumps."""
from wad import LumpGroup
if len(args) == 1:
g = args[0]
assert isinstance(g, LumpGroup)
if "TEXTURE1" in g: self.from_lumps(g["TEXTURE1"], g["PNAMES"])
if "TEXTURE2" in g: self.from_lumps(g["TEXTURE2"], g["PNAMES"])
elif len(args) == 2:
self._from_lumps(args[0], args[1])
def _from_lumps(self, texture1, pnames):
# util.Unpack PNAMES
numdefs = util.unpack16(pnames.data[0:2])
pnames = [util.zstrip(pnames.data[ptr:ptr+8]) \
for ptr in xrange(4, 8*numdefs+4, 8)]
# util.Unpack TEXTURE1
data = texture1.data
numtextures = util.unpack('<l', data[0:4])[0]
pointers = util.unpack('<'+('l'*numtextures), data[4:4+numtextures*4])
for ptr in pointers:
texture = TextureDef(bytes=data[ptr:ptr+22])
for pptr in range(ptr+22, ptr+22+10*texture.npatches, 10):
x, y, idn = util.unpack('<hhh', data[pptr:pptr+6])
texture.patches.append(PatchDef(x, y, name=pnames[idn]))
self[texture.name] = texture
def to_lumps(self):
"""Returns two lumps TEXTURE1, PNAMES"""
textures = self.items()
textures.sort()
pnames = []
# Count unique patch names, assign correct num to each patch
used_pnames = {}
for name, data in textures:
for p in data.patches:
if p.name not in used_pnames:
used_pnames[p.name] = len(used_pnames)
p.id = used_pnames[p.name]
pnmap = sorted([(i, name) for (name, i) in used_pnames.iteritems()])
pnames = util.pack32(len(pnmap)) + \
''.join(util.zpad(util.safe_name(name)) for i, name in pnmap)
texture1 = []
pointers = []
ptr = 4 + len(self)*4
for name, data in textures:
data.npatches = len(data.patches)
texture1.append(data.pack())
texture1.append(''.join(p.pack() for p in data.patches))
pointers.append(ptr)
ptr += 22 + data.npatches*10
a = util.pack32(len(textures))
#print "a", len(a)
b = ''.join([util.pack32(p) for p in pointers])
#print "b", len(b)
#print "texture1", type(texture1), len(texture1)
#print texture1
c = ''.join(texture1)
texture1 = ''.join([a, b, c])
g = wad.TxdefGroup('txdefs', lump.Lump, ['TEXTURE?', 'PNAMES'])
g['TEXTURE1'], g['PNAMES'] = lump.Lump(texture1), lump.Lump(pnames)
return g
def simple(self, name, plump):
"""Create a simple texture with a given name, from a given lump."""
self[name] = TextureDef()
self[name].patches.append(PatchDef())
self[name].patches[0].name = name
self[name].width, self[name].height = plump.dimensions