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
This commit is contained in:
mcmartin
2008-02-24 22:06:03 +00:00
parent 9d914998b9
commit d0dcf67ac6
10 changed files with 148 additions and 19 deletions
+24 -19
View File
@@ -1,23 +1,28 @@
The resmap tool is a set of utilities for generating subsidiary resource The resources.csv file contains a master list of all resources in the
index files based on the current system. 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 The integral resource type is mainly for backwards compatibility, but
produces a master resource map mapping IDs to each file. it is the index into the array defined by getres.c (so, MUSICRES is 6,
for instance).
---- If a resource is defined but has no associated content by default
(i.e., for bonus material), the last two fields will be "--". They
Currently available library files: 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.
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.
+124
View File
@@ -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)