189 lines
5.2 KiB
Python
189 lines
5.2 KiB
Python
#!/usr/bin/python
|
|
|
|
# yeah, I know my python code sucks. get over it
|
|
|
|
import sys
|
|
import re
|
|
|
|
def ReadMobjinfo(f):
|
|
mobjs = []
|
|
mobj = None
|
|
for line in f:
|
|
l, _, comment = line.strip().partition("//")
|
|
if mobj is not None:
|
|
if re.findall("[\t ]*},", l):
|
|
mobjs.append(mobj)
|
|
mobj = None
|
|
elif comment:
|
|
val = re.sub("[\t ,]", "", l)
|
|
# no casts allowed!
|
|
for match in re.finditer("\\(([A-Za-z0-9_]+)\\)", val):
|
|
start, end = match.span()
|
|
val = val[:start] + val[end:]
|
|
mobj.append(val)
|
|
else:
|
|
if "{" in l:
|
|
mobj = []
|
|
elif l.startswith("}") and l.endswith(";"):
|
|
return mobjs
|
|
sys.exit("error: unexpected EOF reading mobjinfo")
|
|
|
|
def ReadStruct(f, pattern):
|
|
states = []
|
|
for line in f:
|
|
l, _, comment = line.strip().partition("//")
|
|
if l.startswith("#"):
|
|
if l == "#ifndef ROTSPRITE": # bruh
|
|
f.readline()
|
|
elif l == "#else" or l == "#endif":
|
|
continue
|
|
else:
|
|
sys.exit("error: unknown directive "+l)
|
|
elif "{" in l:
|
|
state = re.search(pattern, l.strip("{} ,\t"))
|
|
if not state:
|
|
sys.exit("error: invalid line "+l)
|
|
states.append(list(state.groups()))
|
|
elif l.startswith("}") and l.endswith(";"):
|
|
return states
|
|
sys.exit("error: unexpected EOF")
|
|
|
|
def FindStruct(f, match, pattern):
|
|
for l in f:
|
|
if l.startswith(match):
|
|
if not l.endswith("{\n"): # not for skincolors
|
|
f.readline()
|
|
return ReadStruct(f, pattern) if pattern != "mobj" else ReadMobjinfo(f)
|
|
|
|
def ReadEnum(f, match):
|
|
out = []
|
|
comments = {} # why not?
|
|
for line in f:
|
|
l, _, comment = line.strip().partition("//")
|
|
if comment:
|
|
i = len(out)
|
|
if comments.get(i) is None:
|
|
comments[i] = []
|
|
comments[i].append(comment)
|
|
if e := re.findall(f"({match}[A-Za-z0-9_]+),?", l):
|
|
out.append(e[0])
|
|
elif l.startswith("}") and l.endswith(";"):
|
|
enumname = re.findall("} *([A-Za-z0-9_]+);", l)
|
|
return out, comments, enumname[0]
|
|
sys.exit("error: unexpected EOF reading enum")
|
|
|
|
def FindEnum(f, match, enum):
|
|
enumname = None
|
|
typedef = "typedef enum"
|
|
for l in f:
|
|
if l.startswith(typedef):
|
|
f.readline()
|
|
out, comments, tname = ReadEnum(f, match)
|
|
if tname == enum:
|
|
return out, comments
|
|
sys.exit("error: couldn't find "+enum)
|
|
|
|
def WriteSoc(states, fields, keyword, names, comments):
|
|
i = 0
|
|
for state in states:
|
|
comment = comments.get(i)
|
|
if comment:
|
|
for c in comment:
|
|
out.write(f"#{c}\n")
|
|
out.write(f"{keyword} {names[i]}\n")
|
|
for j in range(len(state)):
|
|
v = state[j].strip("{} \t\"")
|
|
if v != fields[j][1]:
|
|
if fields[j][0] != "Caption":
|
|
v = re.sub("[\t ]", "", v)
|
|
if fields[j][0] == "Accessible":
|
|
# lowercase doesn't work, might as well use numbers
|
|
v = "1" if v == "true" else "0"
|
|
out.write(f"{fields[j][0]} = {v}\n")
|
|
out.write("\n")
|
|
i += 1
|
|
|
|
if __name__ == "__main__":
|
|
if len(sys.argv) < 2:
|
|
print("Usage: info2soc.py <path to src> <outfile>")
|
|
sys.exit()
|
|
path = sys.argv[1]
|
|
if len(sys.argv) < 3:
|
|
outpath = "info.soc"
|
|
else:
|
|
outpath = sys.argv[2]
|
|
with open(path+"/info.h", "r") as f:
|
|
statenames, statecom = FindEnum(f, "S_", "statenum_t")
|
|
mobjnames, mobjcom = FindEnum(f, "MT_", "mobjtype_t")
|
|
with open(path+"/sounds.h", "r") as f:
|
|
sfxnames, sfxcom = FindEnum(f, "sfx_", "sfxenum_t")
|
|
with open(path+"/doomdef.h", "r") as f:
|
|
colornames, colorcom = FindEnum(f, "SKINCOLOR_", "skincolornum_t")
|
|
out = open(outpath, "w")
|
|
with open(path+"/info.c", "r") as f:
|
|
states = FindStruct(f, "state_t states[NUMSTATES]",
|
|
"([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+)")
|
|
fields = [ # field name, and default value (so it can be omitted)
|
|
("SpriteName", "SPR_NULL"),
|
|
("SpriteFrame", "0"),
|
|
("Duration", "0"),
|
|
("Action", "NULL"),
|
|
("Var1", "0"),
|
|
("Var2", "0"),
|
|
("Next", "S_NULL"),
|
|
]
|
|
WriteSoc(states, fields, "State", statenames, statecom)
|
|
|
|
mobjs = FindStruct(f, "mobjinfo_t mobjinfo[NUMMOBJTYPES]", "mobj")
|
|
fields = [
|
|
("MapThingNum", "-1"),
|
|
("SpawnState", "S_NULL"),
|
|
("SpawnHealth", "0"),
|
|
("SeeState", "S_NULL"),
|
|
("SeeSound", "sfx_None"),
|
|
("ReactionTime", "0"),
|
|
("AttackSound", "sfx_None"),
|
|
("PainState", "S_NULL"),
|
|
("PainChance", "0"),
|
|
("PainSound", "sfx_None"),
|
|
("MeleeState", "S_NULL"),
|
|
("MissileState", "S_NULL"),
|
|
("DeathState", "S_NULL"),
|
|
("XDeathState", "S_NULL"),
|
|
("DeathSound", "sfx_None"),
|
|
("Speed", "0"),
|
|
("Radius", "0"),
|
|
("Height", "0"),
|
|
("DispOffset", "0"),
|
|
("Mass", "0"),
|
|
("Damage", "0"),
|
|
("ActiveSound", "sfx_None"),
|
|
("Flags", "0"),
|
|
("RaiseState", "S_NULL"),
|
|
]
|
|
WriteSoc(mobjs, fields, "Mobj", mobjnames, mobjcom)
|
|
|
|
colors = FindStruct(f, "skincolor_t skincolors[MAXSKINCOLORS]",
|
|
"^([^,]+),(.+),([^,]+),([^,]+),([^,]+),([^,]+)")
|
|
fields = [
|
|
("Name", ""),
|
|
("Ramp", ""),
|
|
("InvColor", ""),
|
|
("InvShade", ""),
|
|
("ChatColor", ""),
|
|
("Accessible", "false"),
|
|
]
|
|
WriteSoc(colors, fields, "Color", colornames, colorcom)
|
|
with open(path+"/sounds.c", "r") as f:
|
|
sounds = FindStruct(f, "sfxinfo_t S_sfx[NUMSFX]",
|
|
"[^,]+,([^,]+),([^,]+),([^,]+),([^,]+),[^,]+,[^,]+,([^,]+),[^,]+,[^,]+,(.+)")
|
|
fields = [
|
|
("Singular", "false"),
|
|
("Priority", "0"),
|
|
("Flags", "0"),
|
|
("Volume", "-1"),
|
|
("SkinSound", "-1"),
|
|
("Caption", ""),
|
|
]
|
|
WriteSoc(sounds, fields, "Sound", sfxnames, sfxcom)
|
|
out.close()
|