From d0dcf67ac6b3463962b1d9530063cd8d30a7bc50 Mon Sep 17 00:00:00 2001 From: mcmartin Date: Sun, 24 Feb 2008 22:06:03 +0000 Subject: [PATCH] Resource information is now centralized in resources.csv. The old scripts that trolled content/ and src/ for information have been retired, and the new script reads the CSV file and generates the resource files directly. Future changes to the resource indices or content should be done by modifying resources.csv and regenerating the data. git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@2925 8092fc87-c524-0410-9efc-e669fe64eaf9 --- tools/resmap/README.txt | 43 ++++---- tools/resmap/gen_resfiles.py | 124 ++++++++++++++++++++++ tools/resmap/{ => old}/addtypes.py | 0 tools/resmap/{ => old}/deploy.py | 0 tools/resmap/{ => old}/explorer.py | 0 tools/resmap/{ => old}/mastermap.py | 0 tools/resmap/{ => old}/relst.py | 0 tools/resmap/{ => old}/resid_generated.py | 0 tools/resmap/{ => old}/scan_defines.py | 0 tools/resmap/{ => old}/stridgen.py | 0 10 files changed, 148 insertions(+), 19 deletions(-) create mode 100644 tools/resmap/gen_resfiles.py rename tools/resmap/{ => old}/addtypes.py (100%) rename tools/resmap/{ => old}/deploy.py (100%) rename tools/resmap/{ => old}/explorer.py (100%) rename tools/resmap/{ => old}/mastermap.py (100%) rename tools/resmap/{ => old}/relst.py (100%) rename tools/resmap/{ => old}/resid_generated.py (100%) rename tools/resmap/{ => old}/scan_defines.py (100%) rename tools/resmap/{ => old}/stridgen.py (100%) diff --git a/tools/resmap/README.txt b/tools/resmap/README.txt index 136f6171b..29b79ffd3 100644 --- a/tools/resmap/README.txt +++ b/tools/resmap/README.txt @@ -1,23 +1,28 @@ -The resmap tool is a set of utilities for generating subsidiary resource -index files based on the current system. +The resources.csv file contains a master list of all resources in the +game, as well as both integer and string names for each one. Running +gen_resfiles.py will cause it to regenerate uqm.rmp, all the .ls2 +files, and the i*.h source headers that produce the #defines. ----- +The .csv file itself is a comma-separated-values list with nine +fields: -Currently available runnable files: +1. The header file that will define the constant, with "src/" as its + base directory +2. The resource index that will define the integer resource, with + "content/" is its base directory +3. The name of the #defined constant +4. The integral resource package +5. The integral resource instance +6. The integral resource type +7. The string resource id +8. The string resource type +9. The resource file that contains the content to be loaded -mastermap.py: Walks the content tree, finds all the .lst files, and - produces a master resource map mapping IDs to each file. +The integral resource type is mainly for backwards compatibility, but +it is the index into the array defined by getres.c (so, MUSICRES is 6, +for instance). ----- - -Currently available library files: - -explorer.py: Provides routines for locating and parsing .lst files in - the content tree. - -stridgen.py: This does most of the grunt work. It provides the - makeid() function, which, given a filename, produces a - suitable Resource ID string. This is handled with a huge - array of regular expressions at present; as the design - of the resource tree evolves, this script may be kept in - sync with it. +If a resource is defined but has no associated content by default +(i.e., for bonus material), the last two fields will be "--". They +will not receive an entry in the .rmp file, but it will still be legal +to refer to the #defined constant or the integral resource ID. diff --git a/tools/resmap/gen_resfiles.py b/tools/resmap/gen_resfiles.py new file mode 100644 index 000000000..2552b53f2 --- /dev/null +++ b/tools/resmap/gen_resfiles.py @@ -0,0 +1,124 @@ +#!/usr/bin/python + +import sys +import os +import os.path + +basedir = os.path.join(os.path.pardir, os.path.pardir, "sc2") +contentdir = os.path.join (basedir, "content") +srcdir = os.path.join (basedir, "src") + +class ResEntry(object): + def __init__(self, line_num, hfile, ls2file, constant, pkg, inst, typ, res_id, res_type, res_file): + self.line_num = line_num + self.hfile = hfile + self.ls2file = ls2file + self.constant = constant + self.package = int(pkg) + self.instance = int(inst) + self.int_type = int(typ) + self.res_id = res_id + self.res_type = res_type + self.res_file = res_file + def res_number(self): + return res_encode (self.package, self.instance, self.int_type) + +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 (pkg, instance, t) + +def read_csv (fname="resources.csv"): + result = [] + linenum = 0 + for line in file(fname): + linenum += 1 + # We allow hash comments, but it's not wise to have them in the official + # list, since it may interfere with CSV importers. + if '#' in line: + line = line[:line.index('#')] + line = line.strip() + if len(line) > 0: + data = [x.strip() for x in line.split (',')] + if len(data) == 9: + try: + result.append(ResEntry(linenum, *data)) + except ValueError: + print>>sys.stderr, "Warning: Noninteger P/I/T in line %d" % linenum + else: + print>>sys.strderr, "Warning: Incorrect number of fields in line %d" % linenum + return result + +def get_headers(l): + result = {} + for res in l: + result[res.hfile]=True + names = result.keys() + names.sort() + return names + + +def get_resfiles(l): + result = {} + for res in l: + result[res.ls2file]=True + names = result.keys() + names.sort() + return names + +def ls2_text(index, vals): + result = [] + in_index = [x for x in vals if x.ls2file == index] + in_index.sort(lambda x,y: x.res_number() - y.res_number()) + for entry in in_index: + result.append("%3d %3d %3d %s" % (entry.package, entry.instance, entry.int_type, entry.res_id)) + return result + +def rmp_text(vals): + result = [] + in_index = [x for x in vals if x.res_file != "--"] + in_index.sort(lambda x,y: cmp(x.res_id, y.res_id)) + for entry in in_index: + if x.res_type != "--": + result.append("%s = %s:%s" % (entry.res_id, entry.res_type, entry.res_file)) + else: + print>>sys.stderr, "Warning: Resource ID %s (on line %d) has no associated type" % (entry.line_num, entry.res_id) + result.append("%s = UNKNOWNRES:%s" % (entry.res_id, entry.res_file)) + return result + +def h_text(header, vals): + result = ["/* This file was auto-generated by the gen_resfiles utility and", + " should not be edited directly. Modify the master resource list", + " instead and regenerate. */", + ""] + in_index = [x for x in vals if x.hfile == header] + in_index.sort(lambda x,y: x.res_number() - y.res_number()) + for entry in in_index: + result.append("#define %s %s" % (entry.constant, res_encode_str(entry.package, entry.instance, entry.int_type))) + return result + +def dump_values(data): + keys = data.keys() + keys.sort() + for f in keys: + print "Writing ",f + outfile = file(f,"wt") + for l in data[f]: + print>>outfile, l + outfile.close() + +def collate_data(data): + result = {} + headers = get_headers(data) + indices = get_resfiles(data) + for index in indices: + result[os.path.join(contentdir, *(index.split('/')))] = ls2_text(index, data) + for header in headers: + result[os.path.join(srcdir, *(header.split('/')))] = h_text(header, data) + result[os.path.join(contentdir, 'uqm.rmp')] = rmp_text(data) + return result + +if __name__=="__main__": + data = collate_data(read_csv()) + dump_values(data) diff --git a/tools/resmap/addtypes.py b/tools/resmap/old/addtypes.py similarity index 100% rename from tools/resmap/addtypes.py rename to tools/resmap/old/addtypes.py diff --git a/tools/resmap/deploy.py b/tools/resmap/old/deploy.py similarity index 100% rename from tools/resmap/deploy.py rename to tools/resmap/old/deploy.py diff --git a/tools/resmap/explorer.py b/tools/resmap/old/explorer.py similarity index 100% rename from tools/resmap/explorer.py rename to tools/resmap/old/explorer.py diff --git a/tools/resmap/mastermap.py b/tools/resmap/old/mastermap.py similarity index 100% rename from tools/resmap/mastermap.py rename to tools/resmap/old/mastermap.py diff --git a/tools/resmap/relst.py b/tools/resmap/old/relst.py similarity index 100% rename from tools/resmap/relst.py rename to tools/resmap/old/relst.py diff --git a/tools/resmap/resid_generated.py b/tools/resmap/old/resid_generated.py similarity index 100% rename from tools/resmap/resid_generated.py rename to tools/resmap/old/resid_generated.py diff --git a/tools/resmap/scan_defines.py b/tools/resmap/old/scan_defines.py similarity index 100% rename from tools/resmap/scan_defines.py rename to tools/resmap/old/scan_defines.py diff --git a/tools/resmap/stridgen.py b/tools/resmap/old/stridgen.py similarity index 100% rename from tools/resmap/stridgen.py rename to tools/resmap/old/stridgen.py