Index: source/collada/tests/tests.py =================================================================== --- source/collada/tests/tests.py +++ source/collada/tests/tests.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python3 + from ctypes import * import sys import os @@ -19,12 +21,12 @@ library = cdll.LoadLibrary('%s/system/%s' % (binaries, dll_filename)) def log(severity, message): - print '[%s] %s' % (('INFO', 'WARNING', 'ERROR')[severity], message) + print('[%s] %s' % (('INFO', 'WARNING', 'ERROR')[severity], message)) clog = CFUNCTYPE(None, c_int, c_char_p)(log) # (the CFUNCTYPE must not be GC'd, so try to keep a reference) library.set_logger(clog) -skeleton_definitions = open('%s/data/tools/collada/skeletons.xml' % binaries).read() +skeleton_definitions = open('%s/data/tests/collada/skeletons.xml' % binaries).read() library.set_skeleton_definitions(skeleton_definitions, len(skeleton_definitions)) def _convert_dae(func, filename, expected_status=0): @@ -107,7 +109,7 @@ for test_file in ['xsitest3c','xsitest3e','jav2d','jav2d2']: #for test_file in ['xsitest3']: #for test_file in []: - print "* Converting PMD %s" % (test_file) + print("* Converting PMD %s" % (test_file)) input_filename = '%s/%s.dae' % (test_data, test_file) output_filename = '%s/art/meshes/%s.pmd' % (test_mod, test_file) @@ -125,7 +127,7 @@ #for test_file in ['jav2','jav2b', 'jav2d']: for test_file in ['xsitest3c','xsitest3e','jav2d','jav2d2']: #for test_file in []: - print "* Converting PSA %s" % (test_file) + print("* Converting PSA %s" % (test_file)) input_filename = '%s/%s.dae' % (test_data, test_file) output_filename = '%s/art/animation/%s.psa' % (test_mod, test_file) Index: source/tools/fontbuilder2/FontLoader.py =================================================================== --- source/tools/fontbuilder2/FontLoader.py +++ source/tools/fontbuilder2/FontLoader.py @@ -47,7 +47,7 @@ cairo_ctx = cairo.Context (_surface) cairo_t = PycairoContext.from_address(id(cairo_ctx)).ctx - if FT_Err_Ok != _freetype_so.FT_New_Face (_ft_lib, filename, faceindex, ctypes.byref(ft_face)): + if FT_Err_Ok != _freetype_so.FT_New_Face (_ft_lib, filename.encode('ascii'), faceindex, ctypes.byref(ft_face)): raise Exception("Error creating FreeType font face for " + filename) # create cairo font face for freetype face Index: source/tools/fontbuilder2/Packer.py =================================================================== --- source/tools/fontbuilder2/Packer.py +++ source/tools/fontbuilder2/Packer.py @@ -176,7 +176,7 @@ # rectangle at its current placement. We cannot put the rectangle # any lower than this without overlapping the other rectangles. highest = self.heightSlices[leftSliceIndex].y - for index in xrange(leftSliceIndex + 1, rightSliceIndex): + for index in range(leftSliceIndex + 1, rightSliceIndex): if self.heightSlices[index].y > highest: highest = self.heightSlices[index].y Index: source/tools/fontbuilder2/dumpfontchars.py =================================================================== --- source/tools/fontbuilder2/dumpfontchars.py +++ source/tools/fontbuilder2/dumpfontchars.py @@ -8,11 +8,12 @@ (face, indexes) = FontLoader.create_cairo_font_face_for_file("../../../binaries/data/tools/fontbuilder/fonts/%s" % ttf, 0, FontLoader.FT_LOAD_DEFAULT) - mappings = [ (c, indexes(unichr(c))) for c in range(1, 65535) ] - print ttf, - print ' '.join(str(c) for (c, g) in mappings if g != 0) + mappings = [ (c, indexes(chr(c))) for c in range(1, 65535) ] + print(ttf, end=' ') + print(' '.join(str(c) for (c, g) in mappings if g != 0)) dump_font("DejaVuSansMono.ttf") -dump_font("DejaVuSans.ttf") +dump_font("FreeSans.ttf") +dump_font("LinBiolinum_Rah.ttf") dump_font("texgyrepagella-regular.otf") dump_font("texgyrepagella-bold.otf") Index: source/tools/fontbuilder2/fontbuilder.py =================================================================== --- source/tools/fontbuilder2/fontbuilder.py +++ source/tools/fontbuilder2/fontbuilder.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python3 + import cairo import codecs import math @@ -124,11 +126,11 @@ #for c in chars: for c in range(0x20, 0xFFFE): for i in range(len(indexList)): - idx = indexList[i](unichr(c)) + idx = indexList[i](chr(c)) if c == 0xFFFD and idx == 0: # use "?" if the missing-glyph glyph is missing idx = indexList[i]("?") if idx: - glyphs.append(Glyph(ctx, renderstyle, unichr(c), idx, faceList[i], size + dsizes[ttfNames[i]])) + glyphs.append(Glyph(ctx, renderstyle, chr(c), idx, faceList[i], size + dsizes[ttfNames[i]])) break # Sort by decreasing height (tie-break on decreasing width) @@ -139,7 +141,7 @@ for h in [32, 64, 128, 256, 512, 1024, 2048, 4096]: sizes.append((h, h)) sizes.append((h*2, h)) - sizes.sort(key = lambda (w, h): (w*h, max(w, h))) # prefer smaller and squarer + sizes.sort(key = lambda w_h: (w_h[0]*w_h[1], max(w_h[0], w_h[1]))) # prefer smaller and squarer for w, h in sizes: try: @@ -154,7 +156,7 @@ ctx, surface = setup_context(w, h, renderstyle) for g in glyphs: - g.render(ctx) + g.render(ctx) surface.write_to_png("%s.png" % outname) # Output the .fnt file with all the glyph positions etc @@ -184,7 +186,7 @@ fnt.close() return - print "Failed to fit glyphs in texture" + print("Failed to fit glyphs in texture") filled = { "fill": [(1, 1, 1, 1)] } stroked1 = { "colour": True, "stroke": [((0, 0, 0, 1), 2.0), ((0, 0, 0, 1), 2.0)], "fill": [(1, 1, 1, 1)] } @@ -230,5 +232,5 @@ ) for (name, (fontnames, loadopts), size, style) in fonts: - print "%s..." % name + print("%s..." % name) generate_font("../../../binaries/data/mods/mod/fonts/%s" % name, fontnames, loadopts, size, style, dsizes) Index: source/tools/selectiontexgen/selectiontexgen.py =================================================================== --- source/tools/selectiontexgen/selectiontexgen.py +++ source/tools/selectiontexgen/selectiontexgen.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python3 + """ Generates basic square and circle selection overlay textures by parsing all the entity XML files and reading their Footprint components. @@ -118,7 +120,7 @@ if not isdir(finalOutputDir): os.makedirs(finalOutputDir) - print "Generating " + os.path.normcase(finalOutputDir + "/" + outputBasename + ".png") + print("Generating " + os.path.normcase(finalOutputDir + "/" + outputBasename + ".png")) texture.write_to_png(finalOutputDir + "/" + outputBasename + ".png") textureMask.write_to_png(finalOutputDir + "/" + outputBasename + "_mask.png") @@ -149,7 +151,7 @@ # check if this entity has a footprint definition rootChildNodes = [n for n in rootNode.childNodes if n.localName is not None] # remove whitespace text nodes - footprintNodes = filter(lambda x: x.localName == "Footprint", rootChildNodes) + footprintNodes = [x for x in rootChildNodes if x.localName == "Footprint"] if not len(footprintNodes) == 1: continue @@ -158,10 +160,17 @@ continue # parse the footprint declaration - # Footprints can either have either one of these children: + # Footprints can have either one of these children: # # # There's also a node, but we don't care about it here. + # + # When a template inherits from another, we can have: + # - a footprint without either of the children (only the + # one), we can skip it since the correct texture will + # be generated for the parent. + # - a footprint with both children, one disabled (in order to + # override the parent), one regular. squareNodes = footprintNode.getElementsByTagName("Square") circleNodes = footprintNode.getElementsByTagName("Circle") @@ -169,8 +178,20 @@ numSquareNodes = len(squareNodes) numCircleNodes = len(circleNodes) - if not (numSquareNodes + numCircleNodes == 1): - print "Invalid Footprint definition: insufficient or too many Square and/or Circle definitions in %s" % xmlFile + if (numSquareNodes + numCircleNodes == 0): + continue + if (numSquareNodes == 1 and numCircleNodes == 1): + if squareNodes[0].hasAttribute("disable"): + if circleNodes[0].hasAttribute("disable"): + print("Invalid Footprint definition: all Square and Circle definitions disabled in %s" % xmlFile) + else: + numSquareNodes = 0 + elif circleNodes[0].hasAttribute("disable"): + numCircleNodes = 0 + else: + print("Invalid Footprint definition: conflicting Square and Circle definitions in %s" % xmlFile) + elif (numSquareNodes + numCircleNodes > 1): + print("Invalid Footprint definition: too many Square and/or Circle definitions in %s" % xmlFile) texShape = None texW = None # in world-space units @@ -190,11 +211,11 @@ # endfor xmlFiles - print "Found: %d footprints (%d square, %d circle)" % ( + print("Found: %d footprints (%d square, %d circle)" % ( len(textureTypesRaw), len([x for x in textureTypesRaw if x[0] == "square"]), len([x for x in textureTypesRaw if x[0] == "circle"]) - ) + )) textureTypes = set() @@ -208,11 +229,11 @@ textureTypes.add((type, w, h)) if snapSizes: - print "Reduced: %d footprints (%d square, %d circle)" % ( + print("Reduced: %d footprints (%d square, %d circle)" % ( len(textureTypes), len([x for x in textureTypes if x[0] == "square"]), len([x for x in textureTypes if x[0] == "circle"]) - ) + )) # create list from texture types set (so we can sort and have prettier output) textureTypes = sorted(list(textureTypes), key=operator.itemgetter(0,1,2)) # sort by the first tuple element, then by the second, then the third @@ -260,29 +281,29 @@ if normcase(scriptDir).replace('\\', '/').endswith("source/tools/selectiontexgen"): templateDir = "../../../binaries/data/mods/public/simulation/templates" else: - print "No template dir specified; use the --template-dir command line argument." + print("No template dir specified; use the --template-dir command line argument.") sys.exit() # check if the template dir exists templateDir = abspath(templateDir) if not isdir(templateDir): - print "No such template directory: %s" % templateDir + print("No such template directory: %s" % templateDir) sys.exit() # check if the output dir exists, create it if needed outputDir = abspath(options.output_dir) - print outputDir + print(outputDir) if not isdir(outputDir): - print "Creating output directory: %s" % outputDir + print("Creating output directory: %s" % outputDir) os.makedirs(outputDir) - print "Template directory:\t%s" % templateDir - print "Output directory: \t%s" % outputDir - print "------------------------------------------------" + print("Template directory:\t%s" % templateDir) + print("Output directory: \t%s" % outputDir) + print("------------------------------------------------") generateSelectionTextures( templateDir, outputDir, max(0.0, options.outer_stroke_scale), min(1.0, max(0.0, options.inner_stroke_scale)), - ) \ No newline at end of file + ) Index: source/tools/templatesanalyzer/Readme.txt =================================================================== --- source/tools/templatesanalyzer/Readme.txt +++ source/tools/templatesanalyzer/Readme.txt @@ -26,4 +26,4 @@ All contents of this folder are under the MIT License. -Enjoy! \ No newline at end of file +Enjoy! Index: source/tools/templatesanalyzer/unitTables.py =================================================================== --- source/tools/templatesanalyzer/unitTables.py +++ source/tools/templatesanalyzer/unitTables.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python3 + # Copyright (C) 2015 Wildfire Games. # # Permission is hereby granted, free of charge, to any person obtaining a copy Index: source/tools/xmlvalidator/validator.py =================================================================== --- source/tools/xmlvalidator/validator.py +++ source/tools/xmlvalidator/validator.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import argparse import os import re