aboutsummaryrefslogtreecommitdiff
path: root/tools/themeparser.py
diff options
context:
space:
mode:
authorYotam Barnoy2010-10-31 11:08:43 +0000
committerYotam Barnoy2010-10-31 11:08:43 +0000
commit94c8d0a14df429a1b25bd9f5c5d75497fd0ddbd1 (patch)
tree3df2a4ae7967c56d464729669fc06ce4e93dff36 /tools/themeparser.py
parent8df4278ba8cfbf71228e1927f9db635a9a30a57f (diff)
parentdca3c8d8bfc6c4db38cf8e8291818dd472041d4e (diff)
downloadscummvm-rg350-94c8d0a14df429a1b25bd9f5c5d75497fd0ddbd1.tar.gz
scummvm-rg350-94c8d0a14df429a1b25bd9f5c5d75497fd0ddbd1.tar.bz2
scummvm-rg350-94c8d0a14df429a1b25bd9f5c5d75497fd0ddbd1.zip
Updated with latest from trunk
svn-id: r53976
Diffstat (limited to 'tools/themeparser.py')
-rw-r--r--tools/themeparser.py268
1 files changed, 134 insertions, 134 deletions
diff --git a/tools/themeparser.py b/tools/themeparser.py
index 7150fa02ed..993f7c79bc 100644
--- a/tools/themeparser.py
+++ b/tools/themeparser.py
@@ -51,70 +51,70 @@ def pbin(data):
class STXBinaryFile(object):
class InvalidRGBColor(Exception):
pass
-
+
class InvalidResolution(Exception):
pass
-
+
class InvalidFontIdentifier(Exception):
pass
-
+
class InvalidBitmapName(Exception):
pass
-
+
class InvalidDialogOverlay(Exception):
pass
-
+
class DrawStepData(object):
def __init__(self, isDefault, packFormat, function):
self.isDefault = isDefault
self.packFormat = packFormat
self.parse = function
-
+
BYTEORDER = '>' # big-endian format by default, platform independent
-
+
TRUTH_VALUES = {"" : 0, "true" : 1, "false" : 0, "True" : 1, "False" : 0}
-
+
BLOCK_HEADERS = {
"bitmaps" : 0x0100000A,
"fonts" : 0x0100000B,
"cursor" : 0x0100000C,
"drawdata" : 0x0100000D,
-
+
"globals" : 0x0200000A,
"dialog" : 0x0200000B,
}
-
+
DIALOG_shading = {"none" : 0x0, "dim" : 0x1, "luminance" : 0x2}
-
+
DS_triangleOrientations = {"top" : 0x1, "bottom" : 0x2, "left" : 0x3, "right" : 0x4}
DS_fillModes = {"none" : 0x0, "foreground" : 0x1, "background" : 0x2, "gradient" : 0x3}
DS_vectorAlign = {"left" : 0x1, "right" : 0x2, "bottom" : 0x3, "top" : 0x4, "center" : 0x5}
-
+
DS_functions = {
- "void" : 0x0, "circle" : 0x1, "square" : 0x2, "roundedsq" : 0x3, "bevelsq" : 0x4,
+ "void" : 0x0, "circle" : 0x1, "square" : 0x2, "roundedsq" : 0x3, "bevelsq" : 0x4,
"line" : 0x5, "triangle" : 0x6, "fill" : 0x7, "tab" : 0x8, "bitmap" : 0x9, "cross" : 0xA
}
-
+
DS_fonts = {
- "text_default" : 0x0, "text_hover" : 0x1, "text_disabled" : 0x2,
+ "text_default" : 0x0, "text_hover" : 0x1, "text_disabled" : 0x2,
"text_inverted" : 0x3, "text_button" : 0x4, "text_button_hover" : 0x5, "text_normal" : 0x6
}
-
+
DS_text_alignV = {"bottom" : 0x0, "center" : 0x1, "top" : 0x2}
DS_text_alignH = {"left" : 0x0, "center" : 0x1, "right" : 0x2}
-
+
DS_list = [
"func", "fill", "stroke", "gradient_factor",
"width", "height", "xpos", "ypos",
"radius", "bevel", "shadow", "orientation", "file",
"fg_color", "bg_color", "gradient_start", "gradient_end", "bevel_color"
]
-
+
def __init__(self, themeName, autoLoad = True, verbose = False):
self._themeName = themeName
self._stxFiles = []
self._verbose = verbose
-
+
self.DS_data = {
# attribute name isDefault pack parse function
"func" : self.DrawStepData(False, "B", lambda f: self.DS_functions[f]),
@@ -136,74 +136,74 @@ class STXBinaryFile(object):
"gradient_end" : self.DrawStepData(True, "4s", self.__parseColor),
"bevel_color" : self.DrawStepData(True, "4s", self.__parseColor)
}
-
+
if autoLoad:
if not os.path.isdir(themeName) or not os.path.isfile(os.path.join(themeName, "THEMERC")):
raise IOError
-
+
for filename in os.listdir(themeName):
filename = os.path.join(themeName, filename)
if os.path.isfile(filename) and filename.endswith('.stx'):
self._stxFiles.append(filename)
-
+
def debug(self, text):
if self._verbose: print (text)
-
+
def debugBinary(self, data):
if self._verbose:
print ("BINARY OUTPUT (%d bytes): %s" % (len(data), " ".join(["%0.2X" % ord(c) for c in data])))
-
+
def addSTXFile(self, filename):
if not os.path.isfile(filename):
raise IOError
else:
- self._stxFiles.append(filename)
-
+ self._stxFiles.append(filename)
+
def parse(self):
if not self._stxFiles:
self.debug("No files have been loaded for parsing on the theme.")
raise IOError
-
+
for f in self._stxFiles:
self.debug("Parsing %s." % f)
with open(f) as stxFile:
self.__parseFile(stxFile)
-
+
def __parseFile(self, xmlFile):
stxDom = DOM.parse(xmlFile)
-
+
for layout in stxDom.getElementsByTagName("layout_info"):
self.__parseLayout(layout)
for render in stxDom.getElementsByTagName("render_info"):
self.__parseRender(render)
-
+
stxDom.unlink()
-
+
def __getBitmap(self, bmp):
bmp = str(bmp)
-
+
if bmp == "":
return 0x0
if bmp not in self._bitmaps:
raise self.InvalidBitmapName
-
+
return self._bitmaps[bmp]
-
+
def __parseDrawStep(self, drawstepDom, localDefaults = {}):
-
+
dstable = {}
-
+
if drawstepDom.tagName == "defaults":
isGlobal = drawstepDom.parentNode.tagName == "render_info"
-
+
for ds in self.DS_list:
if self.DS_data[ds].isDefault and drawstepDom.hasAttribute(ds):
dstable[ds] = self.DS_data[ds].parse(drawstepDom.getAttribute(ds))
-
+
elif isGlobal:
dstable[ds] = None
-
+
else:
for ds in self.DS_data:
if drawstepDom.hasAttribute(ds):
@@ -212,13 +212,13 @@ class STXBinaryFile(object):
dstable[ds] = localDefaults[ds] if ds in localDefaults else self._globalDefaults[ds]
else:
dstable[ds] = None
-
+
return dstable
-
-
+
+
def __parseDrawStepToBin(self, stepDict):
"""
- /BBBBiiiiiBBB4s4s4s4s4sB/ ==
+ /BBBBiiiiiBBB4s4s4s4s4sB/ ==
function (byte)
fill (byte)
stroke (byte)
@@ -238,10 +238,10 @@ class STXBinaryFile(object):
gradient_end (4 byte)
bevel_color (4 byte)
"""
-
+
packLayout = ""
packData = []
-
+
for ds in self.DS_list:
layout = self.DS_data[ds].packFormat
data = stepDict[ds]
@@ -249,18 +249,18 @@ class STXBinaryFile(object):
if not data:
size = struct.calcsize(layout)
packLayout += "B" * size
-
+
for d in range(size):
packData.append(0)
else:
packLayout += layout
packData.append(data)
-
-
+
+
stepBin = struct.pack(self.BYTEORDER + packLayout, *tuple(packData))
return stepBin
-
-
+
+
def __parseResolutionToBin(self, resString):
"""
/B bHH bHH bHH/ == 1 byte + x * 9 bytes
@@ -269,34 +269,34 @@ class STXBinaryFile(object):
resolution X (half)
resolution Y (half)
"""
-
+
if resString == "":
return struct.pack(self.BYTEORDER + "BbHH", 1, 0, 0, 0)
-
+
resolutions = resString.split(", ")
packFormat = "B" + "bHH" * len(resolutions)
packData = [len(resolutions)]
-
+
for res in resolutions:
exclude = 0
if res[0] == '-':
exclude = 1
res = res[1:]
-
+
try:
x, y = res.split('x')
x = 0 if x == 'X' else int(x)
y = 0 if y == 'Y' else int(y)
except ValueError:
raise InvalidResolution
-
+
packData.append(exclude)
packData.append(x)
packData.append(y)
-
+
buff = struct.pack(self.BYTEORDER + packFormat, *tuple(packData))
return buff
-
+
def __parseRGBToBin(self, color):
"""
/xBBB/ == 32 bits
@@ -305,24 +305,24 @@ class STXBinaryFile(object):
green color (byte)
blue color (byte)
"""
-
+
try:
rgb = tuple(map(int, color.split(", ")))
except ValueError:
raise self.InvalidRGBColor
-
+
if len(rgb) != 3:
raise self.InvalidRGBColor
-
+
for c in rgb:
if c < 0 or c > 255:
raise self.InvalidRGBColor
-
+
rgb = struct.pack(self.BYTEORDER + "xBBB", *tuple(rgb))
-
+
# self.debugBinary(rgb)
return rgb
-
+
def __parseColor(self, color):
try:
color = self.__parseRGBToBin(color)
@@ -330,93 +330,93 @@ class STXBinaryFile(object):
if color not in self._colors:
raise self.InvalidRGBColor
color = self._colors[color]
-
+
return color
-
-
+
+
def __parsePalette(self, paletteDom):
- self._colors = {}
-
+ self._colors = {}
+
for color in paletteDom.getElementsByTagName("color"):
color_name = color.getAttribute('name')
color_rgb = self.__parseRGBToBin(color.getAttribute('rgb'))
-
+
self._colors[color_name] = color_rgb
# self.debug("COLOR: %s" % (color_name))
-
-
+
+
def __parseBitmaps(self, bitmapsDom):
self._bitmaps = {}
idCount = 0xA0
packLayout = ""
packData = []
-
+
for bitmap in bitmapsDom.getElementsByTagName("bitmap"):
bmpName = str(bitmap.getAttribute("filename"))
self._bitmaps[bmpName] = idCount
-
+
packLayout += "B%ds" % (len(bmpName) + 1)
packData.append(idCount)
packData.append(bmpName)
idCount += 1
-
-
+
+
bitmapBinary = struct.pack(
self.BYTEORDER + "IB" + packLayout,
self.BLOCK_HEADERS['bitmaps'],
len(bitmapsDom.getElementsByTagName("bitmap")),
*tuple(packData)
)
-
+
# self.debug("BITMAPS:\n%s\n\n" % pbin(bitmapBinary))
return bitmapBinary
-
+
def __parseFonts(self, fontsDom):
"""
/IB Bs4ss .../
section header (uint32)
number of font definitions (byte)
-
+
id for font definition (byte)
resolution for font (byte array)
color for font (4 bytes)
font filename (byte array, null terminated)
"""
-
+
packLayout = ""
packData = []
for font in fontsDom.getElementsByTagName("font"):
ident = font.getAttribute("id")
-
+
if ident not in self.DS_fonts:
raise self.InvalidFontIdentifier
-
+
color = self.__parseColor(font.getAttribute("color"))
filename = str(font.getAttribute("file"))
-
+
if filename == 'default':
filename = ''
-
+
resolution = self.__parseResolutionToBin(font.getAttribute("resolution"))
-
+
packLayout += "B%ds4s%ds" % (len(resolution), len(filename) + 1)
packData.append(self.DS_fonts[ident])
packData.append(resolution)
packData.append(color)
- packData.append(filename)
-
+ packData.append(filename)
+
fontsBinary = struct.pack(self.BYTEORDER + \
- "IB" + packLayout,
- self.BLOCK_HEADERS['fonts'],
+ "IB" + packLayout,
+ self.BLOCK_HEADERS['fonts'],
len(fontsDom.getElementsByTagName("font")),
*tuple(packData)
)
-
-
+
+
# self.debug("FONTS DATA:\n%s\n\n" % pbin(fontsBinary))
return fontsBinary
-
+
def __parseTextToBin(self, textDom):
"""
/BBBx/
@@ -425,19 +425,19 @@ class STXBinaryFile(object):
horizontal alignment (byte)
padding until word (byte)
"""
-
+
font = textDom.getAttribute("font")
if font not in self.DS_fonts:
raise self.InvalidFontIdentifier
-
+
textBin = struct.pack(self.BYTEORDER + "BBBx",
self.DS_fonts[font],
self.DS_text_alignV[textDom.getAttribute("vertical_align")],
self.DS_text_alignH[textDom.getAttribute("horizontal_align")]
)
-
+
return textBin
-
+
def __parseDrawData(self, ddDom):
"""
/IsIBBHss/
@@ -450,32 +450,32 @@ class STXBinaryFile(object):
** text segment (4 bytes)
drawstep segments (byte array)
"""
-
-
+
+
localDefaults = ddDom.getElementsByTagName("defaults")
localDefaults = localDefaults[0] if localDefaults else {}
-
+
stepList = []
-
+
for ds in ddDom.getElementsByTagName("drawstep"):
dstable = self.__parseDrawStep(ds, localDefaults)
dsbinary = self.__parseDrawStepToBin(dstable)
-
+
stepList.append(dsbinary)
stepByteArray = "".join(stepList)
-
+
resolution = self.__parseResolutionToBin(ddDom.getAttribute("resolution"))
-
+
text = ddDom.getElementsByTagName("text")
text = self.__parseTextToBin(text[0]) if text else ""
-
+
id_hash = str.__hash__(str(ddDom.getAttribute("id"))) & 0xFFFFFFFF
cached = self.TRUTH_VALUES[ddDom.getAttribute("cached")]
-
+
ddBinary = struct.pack(self.BYTEORDER + \
"I%dsIBBH4s%ds" % (len(resolution), len(stepByteArray)),
-
+
self.BLOCK_HEADERS['drawdata'], # Section Header (uint32)
resolution, # Resolution (byte array, word-aligned)
id_hash, # DrawData id hash (uint32)
@@ -485,10 +485,10 @@ class STXBinaryFile(object):
text, # ** text segment (byte array)
stepByteArray # drawstep segments (byte array)
)
-
+
# self.debug("DRAW DATA %s (%X): \n" % (ddDom.getAttribute("id"), id_hash) + pbin(ddBinary) + "\n\n")
return ddBinary
-
+
def __parseCursor(self, cursorDom):
"""
/IsBBhh/
@@ -499,11 +499,11 @@ class STXBinaryFile(object):
hotspot X (half)
hotspot Y (half)
"""
-
+
resolution = self.__parseResolutionToBin(cursorDom.getAttribute("resolution"))
scale = int(cursorDom.getAttribute("scale"))
hsX, hsY = cursorDom.getAttribute("hotspot").split(", ")
-
+
cursorBin = struct.pack(self.BYTEORDER + "I%dsBBhh" % len(resolution),
self.BLOCK_HEADERS['cursor'],
resolution,
@@ -512,19 +512,19 @@ class STXBinaryFile(object):
int(hsX),
int(hsY)
)
-
+
# self.debug("CURSOR:\n%s\n\n" % pbin(cursorBin))
return cursorBin
-
+
def __parseDialog(self, dialogDom):
-
+
dialog_id = str(dialogDom.getAttribute("name"))
resolution = self.__parseResolutionToBin(dialogDom.getAttribute("resolution"))
-
+
overlays = str(dialogDom.getAttribute("overlays"))
overlay_type = 0x0
overlay_parent = ""
-
+
if overlays == "screen":
overlay_type = 0x1
elif overlays == "screen_center":
@@ -532,19 +532,19 @@ class STXBinaryFile(object):
else:
overlay_type = 0x3
overlay_parent = str(overlays)
-
+
dialog_enabled = 0x1
if dialogDom.hasAttribute("enabled"):
dialog_enabled = self.TRUTH_VALUES[dialogDom.getAttribute("enabled")]
-
+
dialog_shading = 0x0
if dialogDom.hasAttribute("shading"):
dialog_shading = self.DIALOG_shading[dialogDom.getAttribute("shading")]
-
+
dialog_inset = 0
if dialogDom.hasAttribute("inset"):
dialog_inset = int(dialogDom.getAttribute("inset"))
-
+
dialogBin = struct.pack(self.BYTEORDER + \
"I%ds%dsBBBB%ds" % (len(resolution), len(dialog_id) + 1, len(overlay_parent) + 1),
self.BLOCK_HEADERS['dialog'],
@@ -556,51 +556,51 @@ class STXBinaryFile(object):
overlay_type,
overlay_parent,
)
-
+
return dialogBin
-
+
def __parseLayout(self, layoutDom):
self.debug("GLOBAL SECTION: LAYOUT INFO.")
-
+
dialogBIN = ""
-
+
for dialog in layoutDom.getElementsByTagName("dialog"):
dialogBIN += self.__parseDialog(dialog)
-
-
+
+
printBinaryDump(dialogBIN)
-
+
return dialogBIN
-
+
def __parseRender(self, renderDom):
self.debug("GLOBAL SECTION: RENDER INFO.")
-
+
bitmapBIN = ""
fontsBIN = ""
cursorBIN = ""
drawdataBIN = ""
-
+
# parse color palettes
paletteDom = renderDom.getElementsByTagName("palette")
if paletteDom:
self.__parsePalette(paletteDom[0])
-
+
# parse bitmaps
bitmapsDom = renderDom.getElementsByTagName("bitmaps")
if bitmapsDom:
bitmapBIN = self.__parseBitmaps(bitmapsDom[0])
-
+
# parse fonts
fontsDom = renderDom.getElementsByTagName("fonts")[0]
fontsBIN = self.__parseFonts(fontsDom)
-
+
# parse defaults
defaultsDom = renderDom.getElementsByTagName("defaults")
if defaultsDom:
self._globalDefaults = self.__parseDrawStep(defaultsDom[0])
else:
self._globalDefaults = {}
-
+
# parse cursors
for cur in renderDom.getElementsByTagName("cursor"):
cursorBIN += self.__parseCursor(cur)
@@ -612,10 +612,10 @@ class STXBinaryFile(object):
renderInfoBIN = bitmapBIN + fontsBIN + cursorBIN + drawdataBIN
printBinaryDump(renderInfoBIN)
-
+
return renderInfoBIN
if __name__ == '__main__':
bin = STXBinaryFile('../gui/themes/scummclassic', True, True)
bin.parse()
-
+