#!/usr/bin/python # Script that compiles a set of resources into a single C++ source file. The C++ file # offers an initResources() function, which registers the resources with the resource # manager (class ResourceMgr) # # Copyright (C) 1997-2015 by Dimitri van Heesch. # # Permission to use, copy, modify, and distribute this software and its # documentation under the terms of the GNU General Public License is hereby # granted. No representations are made about the suitability of this software # for any purpose. It is provided "as is" without express or implied warranty. # See the GNU General Public License for more details. # # Documents produced by Doxygen are derivative works derived from the # input used in their production; they are not affected by this license. # from __future__ import print_function from os import listdir, stat, walk from os.path import isfile, join, splitext import sys class File(object): def __init__(self,directory,subdir,fileName,mode): self.directory = directory self.subdir = subdir self.fileName = fileName filePath = join(directory,subdir,fileName) self.fileSize = stat(filePath).st_size self.bareName = fileName.replace('.','_') self.inputFile = open(filePath,mode) def formatByte(self,byte): if isinstance(byte,int): return "%02x" % byte else: return format(ord(byte),'02x') def writeBytes(self,data,outputFile): bytes_per_line=16 print("static const unsigned char %s_data[] = " % self.bareName,file=outputFile) print("{",file=outputFile) lines = [data[x:x+bytes_per_line] for x in range(0,len(data),bytes_per_line)] linesAsString = ',\n '.join([', '.join(['0x'+self.formatByte(byte) for byte in line]) for line in lines]) print(' %s' % linesAsString,file=outputFile) print("};",file=outputFile) print("const int %s_len = %d;\n" % (self.bareName,len(data)),file=outputFile) def convertToBytes(self,outputFile): lines = [x for x in self.inputFile.readlines() if not x.startswith('#')] w,h = (int(x) for x in lines[0].split()) data = "".join(map(chr,[int(w>>8),int(w&0xFF),int(h>>8),int(h&0xFF)]+ [int(x) for line in lines[1:] for x in line.split()])) self.writeBytes(data,outputFile) @staticmethod def factory(directory,subdir,fname): ext = splitext(fname)[1] if ext=='.lum': return LumFile(directory,subdir,fname) if ext=='.luma': return LumaFile(directory,subdir,fname) if ext=='.css': return CSSFile(directory,subdir,fname) if ext=='.svg': return SVGFile(directory,subdir,fname) return VerbatimFile(directory,subdir,fname) class VerbatimFile(File): def __init__(self,directory,subdir,fileName): File.__init__(self,directory,subdir,fileName,"rb") def writeContents(self,outputFile): self.writeBytes(self.inputFile.read(),outputFile) def writeDirEntry(self,outputFile): print(" { \"%s\", \"%s\", %s_data, %s_len, Resource::Verbatim }," % (self.subdir,self.fileName,self.bareName,self.bareName), file=outputFile) class CSSFile(File): def __init__(self,directory,subdir,fileName): File.__init__(self,directory,subdir,fileName,"r") def writeContents(self,outputFile): self.writeBytes(self.inputFile.read(),outputFile) def writeDirEntry(self,outputFile): print(" { \"%s\", \"%s\", %s_data, %s_len, Resource::CSS }," % (self.subdir,self.fileName,self.bareName,self.bareName), file=outputFile) class SVGFile(File): def __init__(self,directory,subdir,fileName): File.__init__(self,directory,subdir,fileName,"r") def writeContents(self,outputFile): self.writeBytes(self.inputFile.read(),outputFile) def writeDirEntry(self,outputFile): print(" { \"%s\", \"%s\", %s_data, %s_len, Resource::SVG }," % (self.subdir,self.fileName,self.bareName,self.bareName), file=outputFile) class LumFile(File): def __init__(self,directory,subdir,fileName): File.__init__(self,directory,subdir,fileName,"r") def writeContents(self,outputFile): self.convertToBytes(outputFile) def writeDirEntry(self,outputFile): print(" { \"%s\", \"%s\", %s_data, %s_len, Resource::Luminance }," % (self.subdir,self.fileName,self.bareName,self.bareName), file=outputFile) class LumaFile(File): def __init__(self,directory,subdir,fileName): File.__init__(self,directory,subdir,fileName,"r") def writeContents(self,outputFile): self.convertToBytes(outputFile) def writeDirEntry(self,outputFile): print(" { \"%s\", \"%s\", %s_data, %s_len, Resource::LumAlpha }," % (self.subdir,self.fileName,self.bareName,self.bareName), file=outputFile) def main(): if len(sys.argv)<3: sys.exit('Usage: %s directory output_file.cpp' % sys.argv[0]) directory = sys.argv[1] files = [] for dirName, subdirList, fileList in walk(directory): for fname in fileList: subdir = dirName[len(directory)+1:] if dirName.startswith(directory) else dirName if subdir: files.append(File.factory(directory,subdir,fname)) files.sort(key=lambda f: f.subdir + "/" + f.fileName) outputFile = open(sys.argv[2],"w") print("#include \"resourcemgr.h\"\n",file=outputFile) for f in files: f.writeContents(outputFile) print("void initResources() { ResourceMgr::instance().registerResources({",file=outputFile) for f in files: f.writeDirEntry(outputFile) print("});}",file=outputFile) if __name__ == '__main__': main()