diff --git a/tools/resmap/explorer.py b/tools/resmap/explorer.py index 1ea7ce8bf..6e8b91f2e 100644 --- a/tools/resmap/explorer.py +++ b/tools/resmap/explorer.py @@ -2,6 +2,7 @@ import sys import os import os.path +import re def collect_extension(d, ext): result = [] @@ -10,6 +11,14 @@ def collect_extension(d, ext): result.append(os.path.join(dirpath, l)) return result +def collect_res_headers(d, pattern="i.*\\.h$"): + result = [] + regex = re.compile(pattern) + for (dirpath, dirnames, filenames) in os.walk(d): + for l in [f for f in filenames if regex.match(f) != None]: + result.append(os.path.join(dirpath, l)) + return result + def read_list(f): result = [] for line in file(f): @@ -18,6 +27,16 @@ def read_list(f): result.append(((int(parsed[0]), int(parsed[1]), int(parsed[2])), parsed[3])) return result + +def read_header(f): + result = [] + for line in file(f): + line = line.strip() + if line.startswith("#define"): + parsed = [x.strip() for x in line.split()] + if len(parsed) == 3 and parsed[2].startswith('0') and parsed[2].endswith('L'): + result.append((parsed[1], parsed[2])) + return result if __name__ == "__main__": print "This is a library and isn't intended to be run directly." diff --git a/tools/resmap/scan_defines.py b/tools/resmap/scan_defines.py new file mode 100755 index 000000000..27853e25e --- /dev/null +++ b/tools/resmap/scan_defines.py @@ -0,0 +1,120 @@ +#!/usr/bin/python + +import sys +import os +import os.path +import re +import explorer + +if len(sys.argv) < 2: + basedir = os.path.join(os.path.pardir, os.path.pardir, "sc2") +else: + basedir = sys.argv[2] + +contentdir = os.path.join (basedir, "content") +srcdir = os.path.join (basedir, "src") + +verbose = True + +def get_type(x): + return x & 0xFF + +def get_instance(x): + return (x >> 8) & 0x1FFF + +def get_package(x): + return (x >> 21) & 0x7FF + +def res_decode(r): + return (get_package(r), get_instance(r), get_type(r)) + +def res_encode(pkg, instance, t): + return ((pkg & 0x7ff) << 21) | ((instance & 0x1FFF) << 8) | (t & 0xFF) + +def res_encode_str (pkg, instance, t): + return "0x%08xL" % res_encode (p, i, t) + +def res_decode_str (resnum): + return res_decode (int(long(resnum, 16))) + +def parse_packages(): + result = {} + pkgnames = explorer.collect_extension(contentdir, '.ls2') + packages = [(x, explorer.read_list(x)) for x in pkgnames] + for (name, pkg) in packages: + name = name[len(contentdir)+1:] + this_index = {} + for ((p, i, t), target) in pkg: + this_index[res_encode(p, i, t)] = target + result[name] = this_index + return result + +def parse_resmap(): + result = {} + for line in file(os.path.join(contentdir, 'uqm.rmp')): + xs = [x.strip() for x in line.split('=', 1)] + if len (xs) == 2: + if ':' in xs[1]: + xs[1] = xs[1][xs[1].index(':')+1:] + result[xs[0]] = xs[1] + return result + +def get_index_from_header (h): + match = re.search (r"sc2code/comm/([^/]*)/.*\.h", h) + if match != None: + return "comm/%s.ls2" % match.group(1) + match = re.search (r"sc2code/ships/([^/]*)/.*\.h", h) + if match != None: + return "%s.ls2" % match.group(1) + return "starcon.ls2" + +def parse_headers(pkgdata, fnamemap): + result = [] + headernames = explorer.collect_res_headers(srcdir) + headerdata = [(x, explorer.read_header(x)) for x in headernames] + for (name, defines) in headerdata: + index = get_index_from_header (name) + if index in pkgdata: + resmap = pkgdata[index] + for (sym, val) in defines: + try: + trueval = res_encode (*res_decode_str (val)) + if trueval in resmap: + res_id = resmap[trueval] + if res_id in fnamemap: + fname = fnamemap[res_id] + else: + fname = '--' + result.append((sym, val, res_id, fname)) + else: + print>>sys.stderr, "Warning: Unknown RESOURCE %s for %s in %s (index %s)" % (val, sym, name, index) + except ValueError: + # This was something that wasn't a resource index + pass + else: + print>>sys.stderr, "Warning: Unknown RES_INDEX '%s'" % index + return result + +def go(): + ls2s = parse_packages() + rmp = parse_resmap() + vals = parse_headers (ls2s, rmp) + print """ +
+This table lists all of the various #defines used in the UQM code, the 32-bit RESOURCE index, the values it ultimately maps to.
+ +| Constant | Resource Number | Resource Name | Default filename |
|---|---|---|---|
| %s | %s | %s | %s |