Skip to content

Instantly share code, notes, and snippets.

@Xymph
Last active February 26, 2022 16:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Xymph/d7e2e045c1669d5541a1c3aa623f6198 to your computer and use it in GitHub Desktop.
Save Xymph/d7e2e045c1669d5541a1c3aa623f6198 to your computer and use it in GitHub Desktop.
Omgifol (https://doomwiki.org/wiki/Omgifol) script to collect stats of a Doom texture pack .WAD file, for DoomWiki.org - see https://doomwiki.org/wiki/User_talk:Redneckerz#Texture.2Fpalette_automation.3F for discussion and example results
#!/usr/bin/python
# texture pack statistics, by Frans P. de Vries (Xymph)
# discussion: https://doomwiki.org/wiki/User_talk:Redneckerz#Texture.2Fpalette_automation.3F
import sys, getopt, pprint
from omg import *
from omg.txdef import *
pp = pprint.PrettyPrinter(indent=2)
class SwitchDef(WADStruct):
"""Class for switches lump"""
_fields_ = [
("offname", ctypes.c_char * 9),
("onname", ctypes.c_char * 9),
("type", ctypes.c_int16)
]
class AnimatedDef(WADStruct):
"""Class for animated lump"""
_fields_ = [
("type", ctypes.c_ubyte),
("lastname", ctypes.c_char * 9),
("firstname", ctypes.c_char * 9),
("speed", ctypes.c_int32)
]
def _unpack_lump(class_, data):
s = ctypes.sizeof(class_)
return [class_(bytes=data[i:i+s]) for i in range(0,len(data),s)]
if len(sys.argv) < 2:
print("\n Omgifol script: collect stats of texture pack\n")
print(" Usage:")
print(" texpackstats.py [-t] [-k] [-s] [-a] texpack.wad\n")
print(" With flags -t/k/s/a, dump lists of textures, skies, switches and/or animated")
else:
# process optional flags
dump = { 't': False, 'k': False, 's': False, 'a': False }
try:
opts, args = getopt.getopt(sys.argv[1:], 'tksa')
for o, a in opts:
if o == '-t':
dump['t'] = True
if o == '-k':
dump['k'] = True
if o == '-s':
dump['s'] = True
if o == '-a':
dump['a'] = True
except getopt.GetoptError as err:
print(str(err))
sys.exit(2)
print("Loading %s..." % args[0])
inwad = WAD()
inwad.from_file(args[0])
# compile textures data
textures = omg.txdef.Textures(inwad.txdefs)
# collect new textures made from patches in this pack
packtex = []
for texname,texture in textures.items():
for patch in texture.patches:
# prevent one OTEX patch getting skipped
patch.name = patch.name.replace('+', '_')
if patch.name in inwad.patches and texname not in packtex:
packtex.append(texname)
print("Textures:",len(packtex))
if dump['t']:
packtex.sort()
pp.pprint(packtex)
print("Patches: ",len(inwad.patches))
print("Flats: ",len(inwad.flats))
# collect patches named *SKY*
skies = []
for patch in inwad.patches:
if "SKY" in patch:
skies.append(patch)
if len(skies) > 0:
print("Skies: ",len(skies))
if dump['k']:
pp.pprint(skies)
# check for and collect new switches
if "SWITCHES" in inwad.data:
switches = _unpack_lump(SwitchDef, inwad.data['SWITCHES'].data)
packswt = []
for switch in switches:
if switch.type > 0 and switch.offname in packtex and switch.offname not in packswt:
packswt.append([switch.offname, switch.onname])
print("Switches:",len(packswt))
if dump['s']:
print(" Off: On:")
pp.pprint(packswt)
# check for and collect new animated textures/flats
if "ANIMATED" in inwad.data:
# trim off terminator(s)
animdata = inwad.data['ANIMATED'].data
animdata = animdata[0:animdata.find(255)]
animated = _unpack_lump(AnimatedDef, animdata)
packanitex = []
packaniflt = []
for anim in animated:
if anim.type == 1 and anim.firstname in packtex and anim.firstname not in packanitex:
packanitex.append([anim.firstname, anim.lastname, anim.speed])
if anim.type == 0 and anim.firstname in inwad.flats and anim.firstname not in packaniflt:
packaniflt.append([anim.firstname, anim.lastname, anim.speed])
print("Animated:",len(packanitex)+len(packaniflt))
print("AniTexts:",len(packanitex))
if dump['a']:
print(" First: Last:")
pp.pprint(packanitex)
print("AniFlats:",len(packaniflt))
if dump['a']:
print(" First: Last:")
pp.pprint(packaniflt)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment