From 24e3118b0889117208b66f7aa5dc68b79b8bb9d9 Mon Sep 17 00:00:00 2001 From: antoniou79 Date: Fri, 28 Dec 2018 19:07:12 +0200 Subject: DEVTOOLS: Bladerunner python libs in try except Also added missing (renamed) script for MIX packer --- .../subtitles/fontCreator/fonFileLib.py | 36 +- .../subtitles/fontCreator/fontCreator.py | 6 +- .../subtitles/fontCreator/grabberFromPNG17BR.py | 45 +- .../packBladeRunnerMIXFromPCTLKXLS04.py | 816 +++++++++++++++++++++ .../quotesSpreadsheetCreator/audFileDecode.py | 22 +- .../quotesSpreadsheetCreator/audFileLib.py | 43 +- .../quoteSpreadsheetCreator.py | 6 +- .../sortBladeRunnerWavs02.py | 37 +- .../quotesSpreadsheetCreator/treFileLib.py | 25 +- 9 files changed, 1009 insertions(+), 27 deletions(-) create mode 100644 devtools/create_bladerunner/subtitles/mixResourceCreator/packBladeRunnerMIXFromPCTLKXLS04.py (limited to 'devtools/create_bladerunner/subtitles') diff --git a/devtools/create_bladerunner/subtitles/fontCreator/fonFileLib.py b/devtools/create_bladerunner/subtitles/fontCreator/fonFileLib.py index 9c27062bc2..7b41e8cbdb 100644 --- a/devtools/create_bladerunner/subtitles/fontCreator/fonFileLib.py +++ b/devtools/create_bladerunner/subtitles/fontCreator/fonFileLib.py @@ -1,10 +1,38 @@ #!/usr/bin/env python2.7 # -*- coding: UTF-8 -*- # -import os, sys, shutil -import struct +import os, sys + +shutilLibFound = False +structLibFound = False +imagePilLibFound = False + +try: + import shutil +except ImportError: + print "Error:: Shutil python library is required to be installed!" +else: + shutilLibFound = True + +try: + import struct +except ImportError: + print "Error:: struct python library is required to be installed!" +else: + structLibFound = True + +try: + import Image +except ImportError: + print "Error:: Image python library (PIL) is required to be installed!" +else: + imagePilLibFound = True + +if (not shutilLibFound) or (not structLibFound) or (not imagePilLibFound): + sys.stdout.write("Error:: Errors were found when trying to import required python libraries\n") + sys.exit(1) + from struct import * -import Image my_module_version = "0.50" my_module_name = "fonFileLib" @@ -205,7 +233,7 @@ if __name__ == '__main__': # assumes a file of name TAHOMA24.FON in same directory inFONFile = None #inFONFileName = 'TAHOMA24.FON' # USED IN CREDIT END-TITLES and SCORERS BOARD AT POLICE STATION - #inFONFileName = 'TAHOMA18.FON' # USED IN CREDIT END-TITLES + #inFONFileName = 'TAHOMA18.FON' # USED IN CREDIT END-TITLES #inFONFileName = '10PT.FON' # BLADE RUNNER UNUSED FONT? #inFONFileName = 'KIA6PT.FON' # BLADE RUNNER MAIN FONT inFONFileName = 'SUBTLS_E.FON' # Subtitles font custom diff --git a/devtools/create_bladerunner/subtitles/fontCreator/fontCreator.py b/devtools/create_bladerunner/subtitles/fontCreator/fontCreator.py index 582282ed88..f90d60466a 100644 --- a/devtools/create_bladerunner/subtitles/fontCreator/fontCreator.py +++ b/devtools/create_bladerunner/subtitles/fontCreator/fontCreator.py @@ -2,9 +2,9 @@ # -*- coding: UTF-8 -*- import sys if not (sys.version_info[0] == 2 and sys.version_info[1] == 7): - sys.stdout.write("Error:: Blade Runner Font Creator script requires Python 2.7\n") - sys.exit(1) + sys.stdout.write("Error:: Blade Runner Font Creator script requires Python 2.7\n") + sys.exit(1) import grabberFromPNG17BR if __name__ == "__main__": - grabberFromPNG17BR.main(sys.argv[0:]) \ No newline at end of file + grabberFromPNG17BR.main(sys.argv[0:]) \ No newline at end of file diff --git a/devtools/create_bladerunner/subtitles/fontCreator/grabberFromPNG17BR.py b/devtools/create_bladerunner/subtitles/fontCreator/grabberFromPNG17BR.py index 629f0e25c5..4687c01c7e 100644 --- a/devtools/create_bladerunner/subtitles/fontCreator/grabberFromPNG17BR.py +++ b/devtools/create_bladerunner/subtitles/fontCreator/grabberFromPNG17BR.py @@ -67,12 +67,47 @@ # DONE: make space pixels (var spaceWidthInPixels) into an external param? # DONE: INFO NOTE IT IS NOT POSSIBLE TO have partial transparency -import os, sys, shutil -from os import walk, errno -import Image +import os, sys + +shutilLibFound = False +structLibFound = False +imagePilLibFound = False +reLibFound = False + +try: + import shutil +except ImportError: + print "Error:: Shutil python library is required to be installed!" +else: + shutilLibFound = True + +try: + import struct +except ImportError: + print "Error:: struct python library is required to be installed!" +else: + structLibFound = True + +try: + import Image +except ImportError: + print "Error:: Image python library (PIL) is required to be installed!" +else: + imagePilLibFound = True + +try: + import re +except ImportError: + print "Error:: re (Regular expression operations) python library is required to be installed!" +else: + reLibFound = True + +if (not shutilLibFound) or (not structLibFound) or (not imagePilLibFound) or (not reLibFound): + sys.stdout.write("Error:: Errors were found when trying to import required python libraries\n") + sys.exit(1) + +from os import walk, errno, path from struct import * -import re -import os.path from fonFileLib import * company_email = "classic.adventures.in.greek@gmail.com" diff --git a/devtools/create_bladerunner/subtitles/mixResourceCreator/packBladeRunnerMIXFromPCTLKXLS04.py b/devtools/create_bladerunner/subtitles/mixResourceCreator/packBladeRunnerMIXFromPCTLKXLS04.py new file mode 100644 index 0000000000..bf62889bb1 --- /dev/null +++ b/devtools/create_bladerunner/subtitles/mixResourceCreator/packBladeRunnerMIXFromPCTLKXLS04.py @@ -0,0 +1,816 @@ +#!/usr/bin/env python2.7 +# -*- coding: UTF-8 -*- +# +# Created by Praetorian (ShadowNate) for Classic Adventures in Greek +# classic.adventures.in.greek@gmail.com +# Works with Excel version outSpeech-15-06-2018-1856-TranslatingComms-080.xls and above +# +# DONE - Support at least one translation too (ie Greek) +# Print a warning if packing a TRE without the corresponding font(s) -- only a warning though +# +import os, sys + +shutilLibFound = False +ctypesLibFound = False +csvLibFound = False +xlrdLibFound = False +reLibFound = False + +try: + import shutil +except ImportError: + print "Error:: Shutil python library is required to be installed!" +else: + shutilLibFound = True + +try: + import ctypes +except ImportError: + print "Error:: ctypes python library is required to be installed!" +else: + ctypesLibFound = True + +try: + import csv +except ImportError: + print "Error:: csv python library is required to be installed!" +else: + csvLibFound = True + +try: + import xlrd +except ImportError: + print "Error:: xlrd python library is required to be installed!" +else: + xlrdLibFound = True + +try: + import re +except ImportError: + print "Error:: re (Regular expression operations) python library is required to be installed!" +else: + reLibFound = True + +if (not shutilLibFound) or (not ctypesLibFound) or (not csvLibFound) or (not xlrdLibFound) or (not reLibFound): + sys.stdout.write("Error:: Errors were found when trying to import required python libraries\n") + sys.exit(1) + + +from os import path +from xlrd import * +# for pack +from struct import * + +company_email = "classic.adventures.in.greek@gmail.com" +app_version = "0.70" +app_name = "packBladeRunnerMIXFromPCTLKXLS" +app_name_spaced = "Blade Runner MIX Resource Creator" +app_short_desc = "Get a TRE file from spoken in-game quotes" +numOfSpokenQuotes = 0 + +defaultSubtitlesFontName = 'SUBTLS_E.FON' +defaultSubtitlesMixOutputName = u'SUBTITLES.MIX' + +origEncoding = 'windows-1252' +defaultTargetEncoding = 'windows-1252' +defaultTargetEncodingUnicode = unicode(defaultTargetEncoding, 'utf-8') +targetEncoding = '' +targetEncodingUnicode = '' + +traceModeEnabled = False + +# DONE ADD ALL SHEETS NEEDED FROM THE XLS +# all dialogue sheets get the SUBTLS_E.FON for translation to TRE +# - TODO maybe merge this with TAHOMA18.FON eventually +supportedDialogueSheets = ['INGQUO_E.TRE', 'WSTLGO_E.VQA', 'BRLOGO_E.VQA', 'INTRO_E.VQA', 'MW_A_E.VQA', 'MW_B01_E.VQA', 'MW_B02_E.VQA', 'MW_B03_E.VQA', 'MW_B04_E.VQA', 'MW_B05_E.VQA', 'INTRGT_E.VQA', 'MW_D_E.VQA', 'MW_C01_E.VQA', 'MW_C02_E.VQA', 'MW_C03_E.VQA', 'END04A_E.VQA', 'END04B_E.VQA', 'END04C_E.VQA', 'END06_E.VQA', 'END01A_E.VQA', 'END01B_E.VQA', 'END01C_E.VQA', 'END01D_E.VQA', 'END01E_E.VQA', 'END01F_E.VQA', 'END03_E.VQA'] +# +# Each TRE sheet gets a specific font to handle their translation to TRE +# TAHOMA means both TAHOMA (their translation should be identical (although in the original they have minor differences but they don't affect anything) +# We use a single naming for TAHOMA here because both TAHOMA18 and TAHOMA24 are used for ENDCRED.TRE +# The TRE files that are identically named to the originals are supposed to override them (needs ScummVM compatible functionality for that) + +supportedTranslationSheets = [('OPTIONS.TRE', 'KIA6PT'), ('DLGMENU.TRE', 'KIA6PT'), ('SCORERS.TRE', 'TAHOMA'), ('VK.TRE', 'KIA6PT'), ('CLUES.TRE', 'KIA6PT'), ('CRIMES.TRE', 'KIA6PT'), ('ACTORS.TRE', 'KIA6PT'), ('HELP.TRE', 'KIA6PT'), ('AUTOSAVE.TRE', 'KIA6PT'), ('ERRORMSG.TRE', 'KIA6PT'), ('SPINDEST.TRE', 'KIA6PT'), ('KIA.TRE', 'KIA6PT'), ('KIACRED.TRE', 'KIA6PT'), ('CLUETYPE.TRE', 'KIA6PT'), ('ENDCRED.TRE', 'TAHOMA'), ('POGO.TRE', 'KIA6PT')] +# The FON files that are identically named to the originals are supposed to override them (needs ScummVM compatible functionality for that) +supportedOtherFilesForMix = [defaultSubtitlesFontName, 'KIA6PT.FON', 'TAHOMA18.FON', 'TAHOMA24.FON'] # , '10PT.FON'] # we don't deal with 10PT.FON since it's not used -- TODO verify this. + + +tableOfStringIds = [] +tableOfStringOffsets = [] +tableOfStringEntries = [] + +# this list is used in order to replace the actual indices of characters with delegate font indices (ASCII indexes of the target code-page) which have been used during the font creation (or exist in in the internal TAHOMA font) +# contains tuples of two values. First value is actual Utf char, the second is a replacement ASCII char +listOfFontNamesToOutOfOrderGlyphs = [] +arrangedListOfFontNamesToOutOfOrderGlyphs = [] + +actorPropertyEntries = [] +actorPropertyEntriesWasInit = False + +def initOverrideEncoding(pathToConfigureFontsTranslationTxt): + global targetEncoding + + if pathToConfigureFontsTranslationTxt is None or not pathToConfigureFontsTranslationTxt: + configureFontsTranslationTextFile = u'configureFontsTranslation.txt' + relPath = u'.' + pathToConfigureFontsTranslationTxt = os.path.join(relPath, configureFontsTranslationTextFile) + print "Warning:: Font Translation Configuration file not found in arguments. Attempting to open local file %s if it exists" % (configureFontsTranslationTextFile) + + configureTranslationFailed = True + try: + if os.access(pathToConfigureFontsTranslationTxt, os.F_OK): + conFontsTranslationFile = open(pathToConfigureFontsTranslationTxt, 'r') + linesLst = conFontsTranslationFile.readlines() + conFontsTranslationFile.close() + if linesLst is None or len(linesLst) == 0: + configureTranslationFailed = True + else: + if traceModeEnabled: + print "Info:: Font Translation Configuration Info: " + involvedTokensLst =[] + for readEncodLine in linesLst: + tmplineTokens = re.findall("[^\t\n]+",readEncodLine ) + for x in tmplineTokens: + involvedTokensLst.append(x) + + for tokenNameKeyPair in involvedTokensLst: + nameKeyTupl = tokenNameKeyPair.split('=', 1) + try: + if len(nameKeyTupl) == 2 and nameKeyTupl[0] == 'targetEncoding' and nameKeyTupl[1] is not None and nameKeyTupl[1] != '-' and nameKeyTupl[1] != '': + targetEncodingUnicode = unicode(nameKeyTupl[1], 'utf-8') + targetEncoding = unicode.encode("%s" % targetEncodingUnicode, origEncoding) + elif len(nameKeyTupl) == 2 and nameKeyTupl[0] == 'fontNameAndOutOfOrderGlyphs' and nameKeyTupl[1] is not None and nameKeyTupl[1] != '': + # split at hash tag first + tmpListOfOutOfOrderGlyphs = [] + del(tmpListOfOutOfOrderGlyphs[:]) + fontNameAndOOOGlyphsTuple = nameKeyTupl[1].split('#', 1) + if (len (fontNameAndOOOGlyphsTuple) == 2 and fontNameAndOOOGlyphsTuple[0] != '' and fontNameAndOOOGlyphsTuple[1] is not None and fontNameAndOOOGlyphsTuple[1] != ''): + tmpFontName = fontNameAndOOOGlyphsTuple[0] + # split at comma, then split at ':' and store tuples of character + explicitOutOfOrderGlyphsTokenUnicode = unicode(fontNameAndOOOGlyphsTuple[1], 'utf-8') # unicode(fontNameAndOOOGlyphsTuple[1], 'utf-8') + #explicitOutOfOrderGlyphsTokenStr = unicode.encode("%s" % explicitOutOfOrderGlyphsTokenUnicode, targetEncoding) + #explicitOutOfOrderGlyphsTokenStr = explicitOutOfOrderGlyphsTokenUnicode.decode(targetEncoding) # unicode.encode("%s" % explicitOutOfOrderGlyphsTokenUnicode, 'utf-8') + tokensOfOutOfOrderGlyphsStrList = explicitOutOfOrderGlyphsTokenUnicode.split(',') + for tokenX in tokensOfOutOfOrderGlyphsStrList: + tokensOfTupleList = tokenX.split(':') + tmpListOfOutOfOrderGlyphs.append( (unichr(ord(tokensOfTupleList[0])), unichr(ord(tokensOfTupleList[1]))) ) + + if tmpFontName not in [x[0] for x in listOfFontNamesToOutOfOrderGlyphs]: + listOfFontNamesToOutOfOrderGlyphs.append( ( tmpFontName, tmpListOfOutOfOrderGlyphs) ) + + else: + configureTranslationFailed = True + break + except: + configureTranslationFailed = True + raise + + if not (targetEncoding is None or not targetEncoding): + configureTranslationFailed = False + + except: + print "Error:: while trying to access file for encoding info: %s" % (pathToConfigureFontsTranslationTxt) + raise + configureTranslationFailed = True + + if configureTranslationFailed == True: +# targetEncoding = defaultTargetEncoding + print "Error: Could not find proper override encoding info in: %s" % (pathToConfigureFontsTranslationTxt) + sys.exit() # terminate if override Failed (Blade Runner) + # + # TODO ASDF fix this!!! + # + if(len(listOfFontNamesToOutOfOrderGlyphs) == 0): + tmpFontType = defaultSubtitlesFontName[:-4] # remove the .FON extensionFromTheName + print "Info:: Empty list for out of order glyphs. Assuming default out of order glyphs and only for the %s font" % (tmpFontType) + tmplistOfOutOfOrderGlyphs = [] + tmplistOfOutOfOrderGlyphs.append((u'\xed', u'\u0386')) # spanish i (si) + tmplistOfOutOfOrderGlyphs.append((u'\xf1', u'\xa5')) # spanish n (senor) + tmplistOfOutOfOrderGlyphs.append((u'\xe2', u'\xa6')) # a for (liver) pate + tmplistOfOutOfOrderGlyphs.append((u'\xe9', u'\xa7')) # e for (liver) pate + listOfFontNamesToOutOfOrderGlyphs.append( (tmpFontType, tmplistOfOutOfOrderGlyphs)) + if traceModeEnabled: + print "Info:: Explicit Out Of Order Glyphs List: " , listOfFontNamesToOutOfOrderGlyphs + # arrange list properly: + # check if the list contains same item as key and value (in different pairs) + # if such case then the pair with the key should preceed the pair with the value matched, + # to avoid replacing instances of a special character (key) with a delegate (value) that will be later replaced again due to the second pair + # + for (itFontName, itOOOGlyphList) in listOfFontNamesToOutOfOrderGlyphs: + while (True): + foundMatchingPairs = False + for glyphDelegItA in itOOOGlyphList: + for glyphDelegItB in itOOOGlyphList: + if (glyphDelegItA[1] == glyphDelegItB[0] and itOOOGlyphList.index(glyphDelegItA) < itOOOGlyphList.index(glyphDelegItB)): + # swap + itamA, itamB = itOOOGlyphList.index(glyphDelegItA), itOOOGlyphList.index(glyphDelegItB) + itOOOGlyphList[itamB], itOOOGlyphList[itamA] = itOOOGlyphList[itamA], itOOOGlyphList[itamB] + foundMatchingPairs = True + break + if (foundMatchingPairs == True): + break + if(foundMatchingPairs == False): + break # the whole while loop + arrangedListOfFontNamesToOutOfOrderGlyphs.append( ( itFontName, itOOOGlyphList)) + if traceModeEnabled: + print "Info:: Arranged Glyphs Delegates List: " , arrangedListOfFontNamesToOutOfOrderGlyphs + return + +# +# Fill the actorPropertyEntries table +def initActorPropertyEntries(thePathToActorNamesTxt): + global actorPropertyEntriesWasInit + global actorPropertyEntries + firstLine = True +# print "opening actornames" + if thePathToActorNamesTxt is None or not thePathToActorNamesTxt: + + actorNamesTextFile = u'actornames.txt' + relPath = u'.' + thePathToActorNamesTxt = os.path.join(relPath, actorNamesTextFile) + print "Warning:: Actor names text file %s not found in arguments. Attempting to open local file if it exists" % (thePathToActorNamesTxt) + with open(thePathToActorNamesTxt) as tsv: + for line in csv.reader(tsv, dialect="excel-tab"): + #skip first line header + if firstLine == True: +# print "skippingHeader" + firstLine = False + else: + actorPropertyEntries.append(line) + actorPropertyEntriesWasInit = True + tsv.close() + +def getActorShortNameById(lookupActorId): + global actorPropertyEntriesWasInit + global actorPropertyEntries + if not actorPropertyEntriesWasInit: + return '' + else: + for actorEntryTmp in actorPropertyEntries: + if int(actorEntryTmp[0]) == int(lookupActorId): + return actorEntryTmp[1] + return '' + + +def getActorFullNameById(lookupActorId): + global actorPropertyEntriesWasInit + global actorPropertyEntries + if not actorPropertyEntriesWasInit: + return '' + else: + for actorEntryTmp in actorPropertyEntries: + if int(actorEntryTmp[0]) == int(lookupActorId): + return actorEntryTmp[2] + return '' + +def getActorIdByShortName(lookupActorShortName): + global actorPropertyEntriesWasInit + global actorPropertyEntries + if not actorPropertyEntriesWasInit: + return '' + else: + for actorEntryTmp in actorPropertyEntries: + if actorEntryTmp[1] == lookupActorShortName: + return actorEntryTmp[0].zfill(2) + return '' + +# +# +# FOR MIX FILE +# + +# strFileName should be the full file name (including extension) +def calculateFoldHash(strFileName): + i = 0 + hash = 0 + strParam = strFileName.upper() + lenFileName = len(strParam); + while i < lenFileName and i < 12: + groupSum = 0 + # work in groups of 4 bytes + for j in range(0, 4): + # LSB first, so the four letters in the string are re-arranged (first letter goes to lower place) + groupSum >>= 8; + if (i < lenFileName): + groupSum |= (ord(strParam[i]) << 24) + i += 1 + else: # if i >= lenFileName but still haven't completed the four byte loop add 0s + groupSum |= 0 + hash = ((hash << 1) | ((hash >> 31) & 1)) + groupSum + hash &= 0xFFFFFFFF # mask here! + if traceModeEnabled: + print (strParam +': ' +''.join('{:08X}'.format(hash))) + return hash + +# +# aux - sort by first object in list of tuples +def getSortMixFilesKey(item): + keyTmp = item[0] & 0xFFFFFFFF + + signedKeyTmp = ctypes.c_long(keyTmp).value + return signedKeyTmp +# +def outputMIX(): + # output file should be defaultSubtitlesMixOutputName + # checking with known hashes to verify calculateFoldHash + #calculateFoldHash('AR01-MIN.SET') + #calculateFoldHash('AR02-MIN.SET') + #calculateFoldHash('CLOVDIES.AUD') + #calculateFoldHash('INTRO.VQA') + + errorFound = False + outMIXFile = None + try: + relPath = u'.' + outputMixPath = os.path.join(relPath, defaultSubtitlesMixOutputName) + outMIXFile = open(outputMixPath, 'wb') + except: + errorFound = True + if not errorFound: + # Write header + # 2 bytes: number of entries (NumFiles) + # TODO 4 bytes: size of data segment + # 12 * NumFiles bytes: Entry descriptors table + # 4 bytes: ID (hash) + # 4 bytes: Byte offset in Data Segment + # 4 bytes: Byte length of entry data + # TODO *Data Segment* - contains the file data. Offset from Entry Descriptors does not include header segment byte length. + # Note that the offsets are relative to the start of the body so to find the + # actual offset in the MIX you have to add the size of the header which is + # (6 + (12 * NumFiles)) + + # + # ID column should in ascending order in MIX FILES (the engine uses binary sort to search for files) + # so order the files based on ID hash + # Create a list of 3-item tuples, first item is id, second item is filename + # Then sort the list + # Then write to entry table + # + # Also filenames should be 8 characters at most and 4 more for extension to conform with specs + # ^^ this is done manually by making sure the filenames in the sheets of the excel as compliant + # Based on observations from STARTUP.MIX: + # 1) the hash ids can overflow and so lower numbers seem to appear down in the index table entries list + # -- So we sort hash but we first tranlste the unsigned key to signed with ctypes + # 2) the offsets are not necessarily sorted, meaning that the first entry in the index table won't necessarily have the 0x00000000 offset + i = 0 + mixFileEntries = [] + totalFilesDataSize = 0 + currOffsetForDataSegment = 0 # we start after header and table of index entries, from 0, (but this means that when reading the offset we need to add 6 + numOfFiles * 12). This does not concern us though. + for sheetDialogueName in supportedDialogueSheets: + sheetDialogueNameTRE = sheetDialogueName[:-4] + '.TRE' + if os.path.isfile('./' + sheetDialogueNameTRE): + entryID = calculateFoldHash(sheetDialogueNameTRE) + mixEntryfileSizeBytes = os.path.getsize('./' + sheetDialogueNameTRE) + mixFileEntries.append((entryID, sheetDialogueNameTRE, mixEntryfileSizeBytes)) + totalFilesDataSize += mixEntryfileSizeBytes + + for translatedTREFileName in [ x[0] for x in supportedTranslationSheets] : + if os.path.isfile('./' + translatedTREFileName): + entryID = calculateFoldHash(translatedTREFileName) + mixEntryfileSizeBytes = os.path.getsize('./' + translatedTREFileName) + mixFileEntries.append((entryID, translatedTREFileName, mixEntryfileSizeBytes)) + totalFilesDataSize += mixEntryfileSizeBytes + + for otherFileName in supportedOtherFilesForMix: + if os.path.isfile('./' + otherFileName): + entryID = calculateFoldHash(otherFileName) + mixEntryfileSizeBytes = os.path.getsize('./' + otherFileName) + mixFileEntries.append((entryID, otherFileName, mixEntryfileSizeBytes)) + totalFilesDataSize += mixEntryfileSizeBytes + mixFileEntries.sort(key=getSortMixFilesKey) + # + # We write num of files here. After we verified they exist + # + numOfFiles = len(mixFileEntries) + numOfFilesToWrite = pack('h',numOfFiles) # short 2 bytes + outMIXFile.write(numOfFilesToWrite) + + # This is just the data segment (after the entries index table). Adds up all the file sizes here + totalFilesDataSizeToWrite = pack('I',totalFilesDataSize) # unsigned integer 4 bytes + outMIXFile.write(totalFilesDataSizeToWrite) + + if traceModeEnabled: + print ("Debug:: Sorted Entries based on EntryId") + for mixFileEntry in mixFileEntries: + if traceModeEnabled: + print (''.join('{:08X}'.format(mixFileEntry[0])) + ': ' + mixFileEntry[1] + ' : ' + ''.join('{:08X}'.format(mixFileEntry[2]))) + entryID = mixFileEntry[0] & 0xFFFFFFFF + entryIDToWrite = pack('I',entryID) # unsigned integer 4 bytes + outMIXFile.write(entryIDToWrite) + entryOffset = currOffsetForDataSegment # offsets have base after header and table of index entries + entryOffsetToWrite = pack('I',entryOffset) # unsigned integer 4 bytes + outMIXFile.write(entryOffsetToWrite) + entryByteLength = mixFileEntry[2] # File size + entryByteLengthToWrite = pack('I',entryByteLength) # unsigned integer 4 bytes + outMIXFile.write(entryByteLengthToWrite) + currOffsetForDataSegment += entryByteLength + # Add data segments here + errorReadingFound = False + for mixFileEntry in mixFileEntries: + try: + inEntryMIXFile = open("./"+ mixFileEntry[1], 'rb') + except: + errorReadingFound = True + if not errorReadingFound: + outMIXFile.write(inEntryMIXFile.read()) + inEntryMIXFile.close() + else: + print ("Error while reading in ENTRY file") + break + + outMIXFile.close() + print "Info:: Total Resource files packed in %s: %d" % (defaultSubtitlesMixOutputName, numOfFiles) + return +# +# END FOR MIX FILE +# +# + +#def inputXLS(filename) + #TODO extra pass once the quotes have been updated for weird unicode characters + #TODO some ' quotes appear as \u2019 and others appear normally as '. what's that about? + #DONE manually I've replaced all weird \u2019 single quotes with ''' + #the spanish n is \xf1 -> we put it at ascii value: \xA5 -- font index 0xA6 ? + #the spanish i is \xed -> we put it at ascii value: \xA2 -- font index 0xA3 ? + #pâté + # a actual ascii value is 0xE2 in codepage 1252 -- put it in ascii value 0xA6 (165) -- font index 0xA7 + # e actual ascii value is 0xE9 in codepage 1252 -- put it in ascii value 0xA7 (166) -- font index 0xA8 + #TODO what are other characters are special? + #TODO transition to ASCII chars to store in TRE file? + #DONE manually I've replaced all one-char '...' with three dots + # TODO actors TRE has 0x49 entries, (73 names), but table of ids has 73 entries BUT the offset table (first offset is calced + 0x04, so from end of the first 4 count bytes) has 74 entries. The last entry indexes the end of file (!) + # TODO all strings are NULL terminated in the TRE file! + +def translateQuoteToAsciiProper(cellObj, pSheetName): + newQuoteReplaceSpecials = cellObj.value.encode("utf-8") + #print ('Encoded to unicode: %s ' % (newQuoteReplaceSpecials)) + newQuoteReplaceSpecials = newQuoteReplaceSpecials.decode("utf-8") + + pertinentListOfOutOfOrderGlyphs = [] + #print pSheetName + #print supportedDialogueSheets + #print defaultSubtitlesFontName[:-4] + #print [x[0] for x in listOfFontNamesToOutOfOrderGlyphs] + if pSheetName in supportedDialogueSheets and defaultSubtitlesFontName[:-4] in [x[0] for x in listOfFontNamesToOutOfOrderGlyphs]: + for (tmpFontName, tmpOOOList) in listOfFontNamesToOutOfOrderGlyphs: + if tmpFontName == defaultSubtitlesFontName[:-4]: + pertinentListOfOutOfOrderGlyphs = tmpOOOList + break + elif pSheetName in [x[0] for x in supportedTranslationSheets]: + pertinentFontType = '' + #[treAndFontTypeTuple for treAndFontTypeTuple in supportedTranslationSheets if treAndFontTypeTuple[0] == pSheetName] + for (tmpSheetName, tmpFontType) in supportedTranslationSheets: + if tmpSheetName == pSheetName: + pertinentFontType = tmpFontType + break + for (tmpFontName, tmpOOOList) in listOfFontNamesToOutOfOrderGlyphs: + if tmpFontName == pertinentFontType: + pertinentListOfOutOfOrderGlyphs = tmpOOOList + break + + #newQuoteReplaceSpecials = newQuoteReplaceSpecials.replace(u"\u0386", u"\u00A3") + for repTuple in pertinentListOfOutOfOrderGlyphs: + newQuoteReplaceSpecials = newQuoteReplaceSpecials.replace(repTuple[0], repTuple[1]) + # WORKAROUND, we re-replace the spanish i delegate again here! +# newQuoteReplaceSpecials = newQuoteReplaceSpecials.replace(u'\xa2', u'\u0386') # this is needed for spanish i because in utf-8 it's actually the u'\u0386' that's assigned to A tonomeno which is the delegate. +# newQuoteReplaceSpecials = newQuoteReplaceSpecials.replace(u"\u0386", u"\u00A3") +# #newQuoteReplaceSpecials = newQuoteReplaceSpecials.replace(u"\u0386", u"\u00A3") # greek alpha tonomeno -- TODO which character is this in the excel (utf value) ??? +# newQuoteReplaceSpecials = newQuoteReplaceSpecials.replace(u"\u00ed", u"\u00A2") # spanish i +# newQuoteReplaceSpecials = newQuoteReplaceSpecials.replace(u"\u00f1", u"\u00A5") # spanish n +# #newQuoteReplaceSpecials = newQuoteReplaceSpecials.replace(u"\u00A4", u"\u00A5") # spanish n +# newQuoteReplaceSpecials = newQuoteReplaceSpecials.replace(u"\u00e2", u"\u00A6") # a from pate -- todo this is not confirmed in-game font (but it is in our external font as of yet) +# newQuoteReplaceSpecials = newQuoteReplaceSpecials.replace(u"\u00e9", u"\u00A7") # e from pate -- todo this is not confirmed in-game font (but it is in our external font as of yet) + # other replacements. + newQuoteReplaceSpecials = newQuoteReplaceSpecials.replace(u"\u2019", u"\u0027") # right single quote + newQuoteReplaceSpecials = newQuoteReplaceSpecials.replace(u"\u2018", u"\u0027") # left single quote + newQuoteReplaceSpecials = newQuoteReplaceSpecials.replace(u"\u2026", u"\u002e\u002e\u002e") # three dots together (changes length) + newQuoteReplaceSpecials = newQuoteReplaceSpecials.replace(u"\u201D", u"\u0022") # right double quote + newQuoteReplaceSpecials = newQuoteReplaceSpecials.replace(u"\u201C", u"\u0022") # left double quote + # TODO? replace new line ??? with another char (maybe |)? + + #newQuoteReplaceSpecialsUnicode = unicode(newQuoteReplaceSpecials, 'utf-8') + #newQuoteReplaceSpecialsStr = unicode.encode("%s" % newQuoteReplaceSpecials, targetEncoding) + + #print type(newQuoteReplaceSpecials) # type is unicode + #print type(newQuoteReplaceSpecials.encode('utf-8')) # type is str +# print targetEncoding +# print newQuoteReplaceSpecials +# newQuoteReplaceSpecialsDec = newQuoteReplaceSpecials.decode(targetEncoding) + newQuoteReplaceSpecialsRetStr = '' + newQuoteReplaceSpecialsRetStr = newQuoteReplaceSpecials.encode(targetEncoding) +# try: +# newQuoteReplaceSpecialsRetStr = newQuoteReplaceSpecials.encode(targetEncoding) +# except: +# print "===============================================================================" +# print "===============================================================================" +# print "ERROR:" +# print newQuoteReplaceSpecials +# print newQuoteReplaceSpecials.encode(targetEncoding, errors='xmlcharrefreplace') +# print "===============================================================================" +# print "===============================================================================" +# newQuoteReplaceSpecialsRetStr = newQuoteReplaceSpecials.encode(targetEncoding, errors='xmlcharrefreplace') + return newQuoteReplaceSpecialsRetStr +# return newQuoteReplaceSpecialsEnStr + + +def inputXLS(filename): + global numOfSpokenQuotes + global tableOfStringIds + global tableOfStringOffsets + global tableOfStringEntries + # Open the workbook + xl_workbook = xlrd.open_workbook(filename, encoding_override="utf-8") + + + # List sheet names, and pull a sheet by name + # + # sheet_names = xl_workbook.sheet_names() + #print('Sheet Names', sheet_names) + # + #xl_sheet = xl_workbook.sheet_by_name(sheet_names[0]) + + # Or grab the first sheet by index + # (sheets are zero-indexed) + # First sheet is the in-game quotes + # + # xl_sheet = xl_workbook.sheet_by_index(0) + # + # + mergedListOfSubtitleSheetsAndTranslatedTREs = supportedDialogueSheets + [ x[0] for x in supportedTranslationSheets ] + + for sheetDialogueName in mergedListOfSubtitleSheetsAndTranslatedTREs: + xl_sheet = xl_workbook.sheet_by_name(sheetDialogueName) + if(xl_sheet is not None): + if traceModeEnabled: + print ('Sheet name: %s' % xl_sheet.name) + numOfSpokenQuotes = xl_sheet.nrows - 2 # all rows minus the first TWO rows with headers + if traceModeEnabled: + print ('Debug:: num of spoken quotes: %d' % numOfSpokenQuotes) + # stats for debug + extremeQuotesList = [] + longestLength = 0 + predefinedLengthThreshold = 145 + quoteNumAboveThreshold = 0 + # end of stats for debug + + + absStartOfIndexTable = 4 + absStartOfOffsetTable = absStartOfIndexTable + (numOfSpokenQuotes * 4) # = 4 + 0x1577 * 4 = 4 + 0x55DC = 0x55E0 + absStartOfStringTable = absStartOfOffsetTable + ((numOfSpokenQuotes+1) * 4) # = 0x55E0 + (0x1578 * 4) = 0xABC0 + curStrStartOffset = absStartOfStringTable - 4 + newQuoteReplaceSpecialsAscii = '' + tmpQuoteID = 0 + #switchFlagShowQuote = False # for debugging + tmpStartFrame = 0 # for VQA sheets + tmpEndFrame = 0 # for VQA sheets + mode = 0 # init to unknown + if xl_sheet.name == supportedDialogueSheets[0]: + if traceModeEnabled: + print 'IN GAME QUOTES' + mode = 1 #in-game quote + elif xl_sheet.name in supportedDialogueSheets: + if traceModeEnabled: + print 'VQA SCENE DIALOGUE' + mode = 2 #VQA + elif xl_sheet.name in [ x[0] for x in supportedTranslationSheets ]: + if traceModeEnabled: + print 'TRANSLATED TRE' + mode = 3 # Translated TRE + # + del tableOfStringIds[:] + del tableOfStringEntries[:] + del tableOfStringOffsets[:] + for row_idx in range(2, xl_sheet.nrows): + #print "Line %d" % (row_idx) + for col_idx in range(0, xl_sheet.ncols): + cell_obj = xl_sheet.cell(row_idx, col_idx) + # + # FOR IN-GAME QUOTES -- Iterate through columns starting from col 0. We need cols: 0, 2 + # + if mode == 1: + #print ('Column: [%s] cell_obj: [%s]' % (col_idx, cell_obj)) + if(col_idx == 0): + #switchFlagShowQuote = False + twoTokensfirstColSplitAtDotXLS = cell_obj.value.split('.', 1) + if len(twoTokensfirstColSplitAtDotXLS) == 2: + twoTokensfirstColSplitAtDashXLS = twoTokensfirstColSplitAtDotXLS[0].split('-', 1) + if len(twoTokensfirstColSplitAtDashXLS) == 2: + tmpQuoteID = int( twoTokensfirstColSplitAtDashXLS[0]) * 10000 + int(twoTokensfirstColSplitAtDashXLS[1]) + #print ('row_idx %d. tag %s = quoteId [%d]' % (row_idx, twoTokensfirstColSplitAtDotXLS[0], tmpQuoteID)) + tableOfStringIds.append(tmpQuoteID) + #if(tmpQuoteID == 160110 or tmpQuoteID == 160010): + # switchFlagShowQuote = True + + elif(col_idx == 1) : + #if switchFlagShowQuote == True: + # print ('length: %d: %s' % (len(cell_obj.value), cell_obj.value)) + # print ('object: %s' % (cell_obj)) + # #newQuoteReplaceSpecials = cell_obj.value.decode("utf-8") # unicode(cell_obj.value, 'windows-1252') + # #print ('decoded to unicode: %s ' % (newQuoteReplaceSpecials)) # error with char xf1 + newQuoteReplaceSpecialsAscii = translateQuoteToAsciiProper(cell_obj, xl_sheet.name) + #if switchFlagShowQuote == True: + # print ('length: %d: %s' % (len(newQuoteReplaceSpecialsAscii), newQuoteReplaceSpecialsAscii)) + #print ':'.join(x.encode('hex') for x in newQuoteReplaceSpecialsAscii) # seems to work. new chars are non-printable but exist in string + + tableOfStringEntries.append(newQuoteReplaceSpecialsAscii) + tableOfStringOffsets.append(curStrStartOffset) + curStrStartOffset += (len(newQuoteReplaceSpecialsAscii) + 1) + if ( longestLength < len(newQuoteReplaceSpecialsAscii)): + longestLength = len(newQuoteReplaceSpecialsAscii) + if ( predefinedLengthThreshold < len(newQuoteReplaceSpecialsAscii)): + extremeQuotesList.append((tmpQuoteID, newQuoteReplaceSpecialsAscii)) + quoteNumAboveThreshold += 1 + #print ('row_idx %d. tag %s = quoteId [%d], length: %d: %s' % (row_idx, twoTokensfirstColSplitAtDotXLS[0], tmpQuoteID, len(newQuoteReplaceSpecialsAscii), newQuoteReplaceSpecialsAscii)) + # + # FOR VQAs -- Iterate through columns starting from col 2. We need cols: 2, 9, 10 + # + elif mode == 2: + if(col_idx == 2): # subtitle text + newQuoteReplaceSpecialsAscii = translateQuoteToAsciiProper(cell_obj, xl_sheet.name) + #print ('length: %d: %s' % (len(newQuoteReplaceSpecialsAscii), newQuoteReplaceSpecialsAscii)) + #print ':'.join(x.encode('hex') for x in newQuoteReplaceSpecialsAscii) # seems to work. new chars are non-printable but exist in string + # don't append to tableOfStringEntries yet + elif(col_idx == 9): # startFrame + #print "cell: %s" % (cell_obj.value) + tmpStartFrame = int(cell_obj.value) + elif(col_idx == 10): # endFrame + tmpEndFrame = int(cell_obj.value) + tmpQuoteID = tmpStartFrame | (tmpEndFrame << 16) # top 16 bits are end frame (up to 65536 frames which is enough) and low 16 bits are startFrame + + tableOfStringIds.append(tmpQuoteID) + tableOfStringEntries.append(newQuoteReplaceSpecialsAscii) + tableOfStringOffsets.append(curStrStartOffset) + curStrStartOffset += (len(newQuoteReplaceSpecialsAscii) + 1) + if ( longestLength < len(newQuoteReplaceSpecialsAscii)): + longestLength = len(newQuoteReplaceSpecialsAscii) + if ( predefinedLengthThreshold < len(newQuoteReplaceSpecialsAscii)): + extremeQuotesList.append((tmpQuoteID, newQuoteReplaceSpecialsAscii)) + quoteNumAboveThreshold += 1 + # + # For translated TRE sheets the id is already in first column, the text is in the next one + # + elif mode == 3: + #print ('Column: [%s] cell_obj: [%s]' % (col_idx, cell_obj)) + if(col_idx == 0): + tmpQuoteID = int(cell_obj.value) + tableOfStringIds.append(tmpQuoteID) + elif(col_idx == 1) : + #if switchFlagShowQuote == True: + # print ('length: %d: %s' % (len(cell_obj.value), cell_obj.value)) + # print ('object: %s' % (cell_obj)) + # #newQuoteReplaceSpecials = cell_obj.value.decode("utf-8") # unicode(cell_obj.value, 'windows-1252') + # #print ('decoded to unicode: %s ' % (newQuoteReplaceSpecials)) # error with char xf1 + newQuoteReplaceSpecialsAscii = translateQuoteToAsciiProper(cell_obj, xl_sheet.name) + #if switchFlagShowQuote == True: + # print ('length: %d: %s' % (len(newQuoteReplaceSpecialsAscii), newQuoteReplaceSpecialsAscii)) + #print ':'.join(x.encode('hex') for x in newQuoteReplaceSpecialsAscii) # seems to work. new chars are non-printable but exist in string + + tableOfStringEntries.append(newQuoteReplaceSpecialsAscii) + tableOfStringOffsets.append(curStrStartOffset) + curStrStartOffset += (len(newQuoteReplaceSpecialsAscii) + 1) + if ( longestLength < len(newQuoteReplaceSpecialsAscii)): + longestLength = len(newQuoteReplaceSpecialsAscii) + if ( predefinedLengthThreshold < len(newQuoteReplaceSpecialsAscii)): + extremeQuotesList.append((tmpQuoteID, newQuoteReplaceSpecialsAscii)) + quoteNumAboveThreshold += 1 + #print ('row_idx %d. tag %s = quoteId [%d], length: %d: %s' % (row_idx, twoTokensfirstColSplitAtDotXLS[0], tmpQuoteID, len(newQuoteReplaceSpecialsAscii), newQuoteReplaceSpecialsAscii)) + + tableOfStringOffsets.append(curStrStartOffset) # the final extra offset entry + if traceModeEnabled: + print 'Debug:: Longest Length = %d, quotes above threshold (%d): %d' % (longestLength, predefinedLengthThreshold, quoteNumAboveThreshold) + for extremQuotTuple in extremeQuotesList: + print "Id: %d, Q: %s" % (extremQuotTuple[0], extremQuotTuple[1]) + # + # WRITE TO TRE FILE + # + errorFound = False + outTREFile = None + outTREFileName = sheetDialogueName[:-4] + try: + outTREFile = open("./" + outTREFileName + ".TRE", 'wb') + except: + errorFound = True + if not errorFound: + numOfSpokenQuotesToWrite = pack('I',numOfSpokenQuotes) # unsigned integer 4 bytes + outTREFile.write(numOfSpokenQuotesToWrite) + # write string IDs table + for idxe in range(0,len(tableOfStringIds)): + idOfStringToWrite = pack('I',tableOfStringIds[idxe]) # unsigned integer 4 bytes + outTREFile.write(idOfStringToWrite) + # write string offsets table + for idxe in range(0,len(tableOfStringOffsets)): + offsetOfStringToWrite = pack('I',tableOfStringOffsets[idxe]) # unsigned integer 4 bytes + outTREFile.write(offsetOfStringToWrite) + #write strings with null terminator + for idxe in range(0,len(tableOfStringEntries)): + outTREFile.write(tableOfStringEntries[idxe]) + outTREFile.write('\0') + outTREFile.close() + return +# +# +# +# ######################## +# main +# 00_0000 -- DealsInInsects dupl TLK01, TLK0A +# 00_0510 -- ThinkingOfChangingJobs-Leon dupl TLK02, TLK03 +# 00-8520 -- WhatDoYouKnow dupl TLK01, TLK0A +def main(argsCL): + # TODO parse arguments using argparse? https://docs.python.org/3/library/argparse.html#module-argparse + global traceModeEnabled + traceModeEnabled = False + pathToQuoteExcelFile = "" + pathToActorNamesTxt = "" + pathToConfigureFontsTranslationTxt = "" + + invalidSyntax = False + print "Running %s (%s)..." % (app_name_spaced, app_version) +# print "Len of sysargv = %s" % (len(argsCL)) + if len(argsCL) == 2: + if(argsCL[1] == '--help'or argsCL[1] == '-h'): + print "%s %s supports Blade Runner (English version, CD edition)." % (app_name_spaced, app_version) + print app_short_desc + print "Created by Praetorian of the classic adventures in Greek team." + print "Always keep backups!" + print "--------------------" + print "Preparatory steps:" + print "1. Copy the BladeRunnerPCTLK.xls file (latest version, downloaded from Google Sheets) in some folder on your PC." + print "--------------------" + print "%s takes 1 mandatory argument:" % (app_name_spaced) + print "Valid syntax: " + print "%s -x path_to_BladeRunnerPCTLK_xls [-ian path_to_actornames_txt] [-cft path_to_configureFontsTranslation_txt] [--trace]" % (app_name) + print "-x is followed by the path to the excel file with the subtitle quotes." + print "-ian is followed by the path to actornames.txt, if it's not in the current working directory." + print "-cft is followed by the path to configureFontsTranslation.txt, if it's not in the current working directory." + print "The --trace switch enables more debug messages being printed during execution." + print "If the app finishes successfully a " + supportedDialogueSheets[0] + " and a few other .TRE files for the VQAs " + print "in the Excel file as well as a %s file containing all of them will be created in the same folder with the app." % (defaultSubtitlesMixOutputName) + print "--------------------" + print "Thank you for using this app." + print "Please provide any feedback to: %s " % (company_email) + sys.exit() + elif(argsCL[1] == '--version' or argsCL[1] == '-v'): + print "%s %s supports Blade Runner (English version, CD edition)." % (app_name_spaced, app_version) + print "Please provide any feedback to: %s " % (company_email) + sys.exit() + else: + invalidSyntax = True + elif len(argsCL) > 2: + for i in range(1, len(argsCL)): + if( i < (len(argsCL) - 1) and argsCL[i][:1] == '-' and argsCL[i+1][:1] != '-'): + if (argsCL[i] == '-x'): + pathToQuoteExcelFile = argsCL[i+1] + elif (argsCL[i] == '-ian'): + pathToActorNamesTxt = argsCL[i+1] + elif (argsCL[i] == '-cft'): + pathToConfigureFontsTranslationTxt = argsCL[i+1] + elif sys.argv[i] == '--trace': + print "Info:: Trace mode enabled (more debug messages)." + traceModeEnabled = True + + if not pathToQuoteExcelFile: + invalidSyntax = True + + if not invalidSyntax: + # parse any overrideEncoding file if exists: + initOverrideEncoding(pathToConfigureFontsTranslationTxt) + + + # parse the EXCEL File + # parse Actors files: + initActorPropertyEntries(pathToActorNamesTxt) +# for actorEntryTmp in actorPropertyEntries: +# print "Found actor: %s %s %s" % (actorEntryTmp[0], actorEntryTmp[1], actorEntryTmp[2]) + inputXLS(pathToQuoteExcelFile) + outputMIX() + + else: + invalidSyntax = True + + if invalidSyntax == True: + print "Invalid syntax\n Try: \n %s --help for more info \n %s --version for version info " % (app_name, app_name) + print "Valid syntax: " + print "%s -x path_to_BladeRunnerPCTLK_xls [-ian path_to_actornames_txt] [-cft path_to_configureFontsTranslation_txt] [--trace]" % (app_name) + print "-x is followed by the path to the excel file with the subtitle quotes." + print "-ian is followed by the path to actornames.txt, if it's not in the current working directory." + print "-cft is followed by the path to configureFontsTranslation.txt, if it's not in the current working directory." + print "The --trace switch enabled more debug messages being printed during execution." + print "If the app finishes successfully a " + supportedDialogueSheets[0] + " and a few other .TRE files for the VQAs " + print "in the Excel file as well as a %s file containing all of them will be created in the same folder with the app." % (defaultSubtitlesMixOutputName) + tmpi = 0 + for tmpArg in argsCL: + if tmpi==0: #skip first argument + tmpi+=1 + continue + print "\nArgument: %s" % (tmpArg) + tmpi+=1 + +# Total unique quotes seems to be 5495! +# TODO rename files in folders to conform to the underscore '_' and '-' format (a few don't -- let's have them all conforming!) +# ######################### +# +if __name__ == "__main__": + main(sys.argv[0:]) +else: + ## debug + #print 'Debug:: %s was imported from another module' % (app_name) + pass diff --git a/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/audFileDecode.py b/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/audFileDecode.py index 2c87108479..9fc3b25a2b 100644 --- a/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/audFileDecode.py +++ b/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/audFileDecode.py @@ -1,7 +1,27 @@ #!/usr/bin/env python2.7 # -*- coding: UTF-8 -*- # -import ctypes +ctypesLibFound = False +structLibFound = False + +try: + import ctypes +except ImportError: + print "Error:: ctypes python library is required to be installed!" +else: + ctypesLibFound = True + +try: + import struct +except ImportError: + print "Error:: struct python library is required to be installed!" +else: + structLibFound = True + +if (not ctypesLibFound) or (not structLibFound): + sys.stdout.write("Error:: Errors were found when trying to import required python libraries\n") + sys.exit(1) + from struct import * my_module_version = "0.50" diff --git a/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/audFileLib.py b/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/audFileLib.py index 682a31e16c..a771435a02 100644 --- a/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/audFileLib.py +++ b/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/audFileLib.py @@ -1,12 +1,47 @@ #!/usr/bin/env python2.7 # -*- coding: UTF-8 -*- # -import os, sys, shutil -import wave -import struct +import os, sys + +shutilLibFound = False +waveLibFound = False +ctypesLibFound = False +structLibFound = False + +try: + import shutil +except ImportError: + print "Error:: Shutil python library is required to be installed!" +else: + shutilLibFound = True + +try: + import wave +except ImportError: + print "Error:: Wave python library is required to be installed!" +else: + waveLibFound = True + +try: + import ctypes +except ImportError: + print "Error:: ctypes python library is required to be installed!" +else: + ctypesLibFound = True + +try: + import struct +except ImportError: + print "Error:: struct python library is required to be installed!" +else: + structLibFound = True + +if (not shutilLibFound) or (not waveLibFound) or (not ctypesLibFound) or (not structLibFound): + sys.stdout.write("Error:: Errors were found when trying to import required python libraries\n") + sys.exit(1) + from struct import * from audFileDecode import * -import ctypes my_module_version = "0.50" my_module_name = "audFileLib" diff --git a/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/quoteSpreadsheetCreator.py b/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/quoteSpreadsheetCreator.py index c1bdc84413..04c50e52cc 100644 --- a/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/quoteSpreadsheetCreator.py +++ b/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/quoteSpreadsheetCreator.py @@ -2,9 +2,9 @@ # -*- coding: UTF-8 -*- import sys if not (sys.version_info[0] == 2 and sys.version_info[1] == 7): - sys.stdout.write("Error:: Blade Runner Quotes Spreadsheet Creator script requires Python 2.7\n") - sys.exit(1) + sys.stdout.write("Error:: Blade Runner Quotes Spreadsheet Creator script requires Python 2.7\n") + sys.exit(1) import sortBladeRunnerWavs02 if __name__ == "__main__": - sortBladeRunnerWavs02.main(sys.argv[0:]) \ No newline at end of file + sortBladeRunnerWavs02.main(sys.argv[0:]) \ No newline at end of file diff --git a/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/sortBladeRunnerWavs02.py b/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/sortBladeRunnerWavs02.py index b3f368ed40..0e0cf47ee0 100644 --- a/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/sortBladeRunnerWavs02.py +++ b/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/sortBladeRunnerWavs02.py @@ -10,11 +10,38 @@ # DONE Add code and switch option: to get the blade runner installation directory as input, then find the TLK files and extract them with proper naming # DONE fix proper names for sheets as per latest code changes # -import os, sys, shutil -from os import walk, errno -import xlwt -import csv -import os.path +import os, sys + +shutilLibFound = False +xlwtLibFound = False +csvLibFound = False + +try: + import shutil +except ImportError: + print "Error:: Shutil python library is required to be installed!" +else: + shutilLibFound = True + +try: + import xlwt +except ImportError: + print "Error:: xlwt python library is required to be installed!" +else: + xlwtLibFound = True + +try: + import csv +except ImportError: + print "Error:: csv python library is required to be installed!" +else: + csvLibFound = True + +if (not shutilLibFound) or (not structLibFound) or (not csvLibFound): + sys.stdout.write("Error:: Errors were found when trying to import required python libraries\n") + sys.exit(1) + +from os import walk, errno, path from xlwt import * from audFileLib import * from treFileLib import * diff --git a/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/treFileLib.py b/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/treFileLib.py index 29eac6a8e5..11f666132c 100644 --- a/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/treFileLib.py +++ b/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/treFileLib.py @@ -1,8 +1,29 @@ #!/usr/bin/env python2.7 # -*- coding: UTF-8 -*- # -import os, sys, shutil -import struct +import os, sys + +shutilLibFound = False +structLibFound = False + +try: + import shutil +except ImportError: + print "Error:: Shutil python library is required to be installed!" +else: + shutilLibFound = True + +try: + import struct +except ImportError: + print "Error:: struct python library is required to be installed!" +else: + structLibFound = True + +if (not shutilLibFound) or (not structLibFound): + sys.stdout.write("Error:: Errors were found when trying to import required python libraries\n") + sys.exit(1) + from struct import * my_module_version = "0.50" -- cgit v1.2.3