aboutsummaryrefslogtreecommitdiff
path: root/devtools/create_bladerunner
diff options
context:
space:
mode:
authorantoniou792018-12-28 19:07:12 +0200
committerEugene Sandulenko2019-01-06 17:12:02 +0100
commit24e3118b0889117208b66f7aa5dc68b79b8bb9d9 (patch)
treed6bb284983acf9330600ee5f5526f83a46302b79 /devtools/create_bladerunner
parentd724df4662dcb2777f635d7a8ec08788e726e869 (diff)
downloadscummvm-rg350-24e3118b0889117208b66f7aa5dc68b79b8bb9d9.tar.gz
scummvm-rg350-24e3118b0889117208b66f7aa5dc68b79b8bb9d9.tar.bz2
scummvm-rg350-24e3118b0889117208b66f7aa5dc68b79b8bb9d9.zip
DEVTOOLS: Bladerunner python libs in try except
Also added missing (renamed) script for MIX packer
Diffstat (limited to 'devtools/create_bladerunner')
-rw-r--r--devtools/create_bladerunner/subtitles/fontCreator/fonFileLib.py36
-rw-r--r--devtools/create_bladerunner/subtitles/fontCreator/fontCreator.py6
-rw-r--r--devtools/create_bladerunner/subtitles/fontCreator/grabberFromPNG17BR.py45
-rw-r--r--devtools/create_bladerunner/subtitles/mixResourceCreator/packBladeRunnerMIXFromPCTLKXLS04.py816
-rw-r--r--devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/audFileDecode.py22
-rw-r--r--devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/audFileLib.py43
-rw-r--r--devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/quoteSpreadsheetCreator.py6
-rw-r--r--devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/sortBladeRunnerWavs02.py37
-rw-r--r--devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/treFileLib.py25
9 files changed, 1009 insertions, 27 deletions
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"