From 234cdf19e5ef1eb6d8baedcd9476fe4354f45368 Mon Sep 17 00:00:00 2001 From: antoniou79 Date: Tue, 1 Jan 2019 20:14:24 +0200 Subject: DEVTOOLS: Multilingual support for quoteSpreadsheetCreator Versions supported are English, German, French, Italian and Spanish More work would be required for Russian versions to be supported by the spreadsheet creator. I don't have access to the Russian version that ScummVM currently supports/in the detection table. Current implementation could be improved (to do away with all the if clauses for the glyph "exceptions") but this is not high priority. --- .../quotesSpreadsheetCreator/audFileDecode.py | 12 +- .../quotesSpreadsheetCreator/audFileLib.py | 30 +- .../sortBladeRunnerWavs02.py | 392 ++++++++++++++------- .../quotesSpreadsheetCreator/treFileLib.py | 26 +- 4 files changed, 308 insertions(+), 152 deletions(-) (limited to 'devtools/create_bladerunner/subtitles') diff --git a/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/audFileDecode.py b/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/audFileDecode.py index 1cb28f273e..52ef7231f0 100644 --- a/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/audFileDecode.py +++ b/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/audFileDecode.py @@ -59,15 +59,15 @@ def aud_decode_ima_chunk(audioBufferIn, index, sample, cs_chunk): audioBufferOut = [] #for i in range(0, len(audioBufferIn)): - # print '%d: %d'%(i, int(audioBufferIn[i])) + # print 'Debug:: %d= %d'%(i, int(audioBufferIn[i])) for sample_index in range (0, cs_chunk): try: code = audioBufferIn[sample_index >> 1] except: code = 0xa9 # dummy workaround because the c code is accessing an out of bounds index sometimes due to this shift here - #print "cs_chunk %d, sample_index %d, shifted %d, code: %d" % (cs_chunk, sample_index, sample_index >> 1, int(audioBufferIn[sample_index >> 1])) - #print "cs_chunk %s, sample_index %s, shifted %s, code: %s" % \ + #print "Debug:: cs_chunk %d, sample_index %d, shifted %d, code= %d" % (cs_chunk, sample_index, sample_index >> 1, int(audioBufferIn[sample_index >> 1])) + #print "Debug:: cs_chunk %s, sample_index %s, shifted %s, code= %s" % \ # (''.join('{:04X}'.format(cs_chunk)), ''.join('{:02X}'.format(sample_index)), ''.join('{:02X}'.format(sample_index >> 1)), ''.join('{:04X}'.format(int(code)))) code = code >> 4 if (sample_index & 1) else code & 0xf step = aud_ima_step_table[index] @@ -88,7 +88,7 @@ def aud_decode_ima_chunk(audioBufferIn, index, sample, cs_chunk): sample = 32767 audioBufferOut.append(ctypes.c_short( sample ).value ) #audioBufferOut.append(sample) # it's not different from above... ctypes.c_short( sample ).value - #print "audio_out[%s]: %s" % (''.join('{:02X}'.format(sample_index)), ''.join('{:02X}'.format(audioBufferOut[sample_index]))); + #print "Debug:: audio_out[%s]= %s" % (''.join('{:02X}'.format(sample_index)), ''.join('{:02X}'.format(audioBufferOut[sample_index]))); index += aud_ima_index_adjust_table[code & 7] if (index < 0): index = 0 @@ -220,11 +220,11 @@ class audFileDecode: if __name__ == '__main__': # main() - print "Running %s as main module" % (my_module_name) + print "Debug:: Running %s as main module" % (my_module_name) decodeInstance = audFileDecode() else: #debug - #print "Running %s imported from another module" % (my_module_name) + #print "Debug:: Running %s imported from another module" % (my_module_name) pass \ No newline at end of file diff --git a/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/audFileLib.py b/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/audFileLib.py index cc4c33afb8..e8c5632cc5 100644 --- a/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/audFileLib.py +++ b/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/audFileLib.py @@ -82,7 +82,7 @@ class audFile: # std::fstream& fs, AudFileNS::pos_type startAudFilepos, AudFileNS::pos_type endAudFilepos, const std::string& filename def extract_as_wav(self, audBytesBuff, filename): - print "Saving to wav: " + filename + print "Info:: Saving to wav: " + filename cvirtualBinaryD = self.decode(audBytesBuff) # TODO DEBUG REMOVED FOR NOW. TODO RESTORE THIS!!! @@ -138,10 +138,10 @@ class audFile: tmpTuple = struct.unpack_from('b', audBytesBuff, offsInAudFile) self.header().compression = tmpTuple[0] offsInAudFile += 1 - print "samplerate: %d\tsizeIn: %d\tsizeOut: %d\tflags: %d\tcompression: %d" % (self.get_samplerate(), self.header().size_in, self.header().size_out, self.header().flags, self.header().compression) + print "Debug:: Sample rate= %d\tsizeIn= %d\tsizeOut= %d\tflags= %d\tcompression= %d" % (self.get_samplerate(), self.header().size_in, self.header().size_out, self.header().flags, self.header().compression) if self.get_samplerate() < 8000 or self.get_samplerate() > 48000 or self.header().size_in > (maxLength - SIZE_OF_AUD_HEADER_IN_BYTES ): - print "AUD HEADER SIZE ERROR::2" + print "Error:: Bad AUD Header size::2" return False else: if self.header().compression == 1: @@ -205,7 +205,7 @@ class audFile: def get_chunk_data(self, inAudFileBytesBuffer, startOffs, sizeToRead): #fs.read((char*)byteChunkDataPtr, sizeToRead) outChunkDataLst = [] - #print "startOffs %d, sizeToRead %d" % (startOffs, sizeToRead) + #print "Debug:: startOffs %d, sizeToRead %d" % (startOffs, sizeToRead) for i in range(startOffs, startOffs + sizeToRead): #outChunkDataLst.append(ctypes.c_char(inAudFileBytesBuffer[i]).value) #outChunkDataLst.append(ctypes.c_byte(inAudFileBytesBuffer[i]).value) @@ -221,7 +221,7 @@ class audFile: def decode(self, audBytesBuff): # The * operator unpacks an argument list. It allows you to call a function with the list items as individual arguments. # binDataOut = struct.pack('i'*len(data), *data) - print "DECODING..." + print "Info:: DECODING..." # Cvirtual_binary d; binaryDataOutLst = [] binaryDataOutBuff = None @@ -238,9 +238,9 @@ class audFile: #out_chunk_header = AudChunkHeader() (errGetChunk, bufferDataPos, out_chunk_header) = self.get_chunk_header(chunk_i, audBytesBuff, len(audBytesBuff)) if errGetChunk != 0: -# print "Error OR End file case while getting uncompressed chunk header!" +# print "Warning:: Error OR End file case while getting uncompressed chunk header!" break - #print "Get uncompressed chunk header returned:: %d " % (out_chunk_header.id) + #print "Debug:: Get uncompressed chunk header returned:: %d " % (out_chunk_header.id) #Cvirtual_binary out_chunk_data; #AudFileNS::byte* byteChunkDataPtr = out_chunk_data.write_start(out_chunk_header.size_in); (errorGCD, byteChunkDataLst) = self.get_chunk_data(audBytesBuff, bufferDataPos, out_chunk_header.size_in) @@ -259,24 +259,24 @@ class audFile: chunk_i = 0 wIndex = 0 while (wIndex < cb_audio): - #print("chunkI: %d\t Windex: %d\t cb_audio: %d") % (chunk_i,wIndex,cb_audio) + #print("Debug:: chunkI= %d\t Windex= %d\t cb_audio= %d") % (chunk_i,wIndex,cb_audio) #AudChunkHeader out_chunk_header; #out_chunk_header = AudChunkHeader() #errGetChunk = self.get_chunk_header(chunk_i, fs, startAudFilepos, endAudFilepos, out_chunk_header); (errGetChunk, bufferDataPos, out_chunk_header) = self.get_chunk_header(chunk_i, audBytesBuff, len(audBytesBuff)) if errGetChunk != 0: - print "Error OR End file case while getting COMPRESSED chunk header!" + print "Warning:: Error OR End file case while getting COMPRESSED chunk header!" break - #print "Get COMPRESSED chunk header returned:: headerInSize: %d headerOutSize: %d id: %d" % (out_chunk_header.size_in, out_chunk_header.size_out, out_chunk_header.id) + #print "Debug:: Get COMPRESSED chunk header returned:: headerInSize: %d headerOutSize: %d id: %d" % (out_chunk_header.size_in, out_chunk_header.size_out, out_chunk_header.id) #Cvirtual_binary out_chunk_data; #AudFileNS::byte* byteChunkDataPtr = out_chunk_data.write_start(out_chunk_header.size_in); (errorGCD, byteChunkDataLst) = self.get_chunk_data(audBytesBuff, bufferDataPos, out_chunk_header.size_in) # export decoded chunk to w (output) buffer (of SHORTS) at the point where we're currently at (so append there) - #print "byteChunkDataLst len: %d, size_in was: %d" % (len(byteChunkDataLst), out_chunk_header.size_in) + #print "Debug:: byteChunkDataLst len= %d, size_in was= %d" % (len(byteChunkDataLst), out_chunk_header.size_in) decodedAudioChunkAsLst = decodeInstance.decode_chunk(byteChunkDataLst, out_chunk_header.size_out / self.get_cb_sample()); binaryDataOutLst.extend(decodedAudioChunkAsLst) wIndex += out_chunk_header.size_out - #print("new Windex: %d\t cb_audio: %d") % (wIndex,cb_audio) + #print("Debug:: New Windex= %d\t cb_audio= %d") % (wIndex,cb_audio) chunk_i += 1 binaryDataOutBuff = struct.pack('h'*len(binaryDataOutLst), *binaryDataOutLst) return binaryDataOutBuff @@ -302,7 +302,7 @@ class audFile: # if __name__ == '__main__': # main() - print "Running %s as main module" % (my_module_name) + print "Debug:: Running %s as main module" % (my_module_name) # assumes a file of name 000000.AUD in same directory inAUDFile = None errorFound = False @@ -310,7 +310,7 @@ if __name__ == '__main__': inAUDFile = open(os.path.join('.','00000000.AUD'), 'rb') except: errorFound = True - print "Unexpected error:", sys.exc_info()[0] + print "Error:: Unexpected event:", sys.exc_info()[0] raise if not errorFound: allOfAudFileInBuffer = inAUDFile.read() @@ -320,5 +320,5 @@ if __name__ == '__main__': inAUDFile.close() else: #debug - #print "Running %s imported from another module" % (my_module_name) + #print "Debug:: Running %s imported from another module" % (my_module_name) pass \ 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 6e61cc9278..167ce824dc 100644 --- a/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/sortBladeRunnerWavs02.py +++ b/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/sortBladeRunnerWavs02.py @@ -4,9 +4,6 @@ # Created by Praetorian (ShadowNate) for Classic Adventures in Greek # classic.adventures.in.greek@gmail.com # -# TODO update README -# TODO test recreation of TRE file (Especially in Credits which the original has a few special characters (font delegates)) -# # 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 # @@ -50,29 +47,34 @@ from treFileLib import * #reload(sys) #sys.setdefaultencoding('utf8') -company_email = "classic.adventures.in.greek@gmail.com" -app_version = "0.70" -app_name = "sortBladeRunnerWavs" -app_wrapper_name = "quotesSpreadsheetCreator.py" -app_name_spaced = "Blade Runner Transcript Excel Creator (bare bones)" -app_short_desc = "Create an Excel (.XLS) for transcribing Blade Runner. It can also extract TRE files and export WAV files for game's resources. " -traceModeEnabled = False +COMPANY_EMAIL = "classic.adventures.in.greek@gmail.com" +APP_VERSION = "0.80" +APP_NAME = "sortBladeRunnerWavs" +APP_WRAPPER_NAME = "quotesSpreadsheetCreator.py" +APP_NAME_spaced = "Blade Runner Transcript Excel Creator (bare bones)" +APP_SHORT_DESC = "Create an Excel (.XLS) for transcribing Blade Runner. It can also extract TRx (x is the language code of the game) files and export WAV files for game's resources. " +gTraceModeEnabled = False +gActiveLanguageDescriptionCodeTuple = '' -stringReplacementForRootFolderWithExtractedFiles = "" -numReplaceStartingCharacters = 0 +gStringReplacementForRootFolderWithExtractedFiles = "" +gNumReplaceStartingCharacters = 0 OUTPUT_XLS_FILENAME = 'out.xls' -OUTPUT_XLS_QUOTES_SHEET = 'INGQUO_E.TRE' +OUTPUT_XLS_QUOTES_SHEET = 'INGQUO_E.TR' + +SUPPORTED_TLK_INPUT_FILES = [('1.TLK', 'TLK01'), ('2.TLK', 'TLK02'), ('3.TLK', 'TLK03'), ('A.TLK', 'TLK0A'), ('SPCHSFX.TLK', 'TLKSPCHSFX')] +SUPPORTED_MIX_INPUT_FILES = ['STARTUP.MIX'] +# 15 TRx files +SUPPORTED_EXPORTED_TRx_FILES = ['CLUES.TR','ACTORS.TR','CRIMES.TR','CLUETYPE.TR','KIA.TR','SPINDEST.TR','VK.TR','OPTIONS.TR','DLGMENU.TR','ENDCRED.TR','HELP.TR','SCORERS.TR','KIACRED.TR','ERRORMSG.TR','AUTOSAVE.TR'] +SUPPORTED_PLACEHOLDER_VQA_FILES = ['WSTLGO_', 'BRLOGO_', 'INTRO_', 'MW_A_', 'MW_B01_', 'MW_B02_', 'MW_B03_', 'MW_B04_', 'MW_B05_', 'INTRGT_', 'MW_D_', 'MW_C01_', 'MW_C02_', 'MW_C03_', 'END04A_', 'END04B_', 'END04C_', 'END06_', 'END01A_', 'END01B_', 'END01C_', 'END01D_', 'END01E_', 'END01F_', 'END03_'] -supportedTLKInputFiles = [('1.TLK', 'TLK01'), ('2.TLK', 'TLK02'), ('3.TLK', 'TLK03'), ('A.TLK', 'TLK0A'), ('SPCHSFX.TLK', 'TLKSPCHSFX')] -supportedMIXInputFiles = ['STARTUP.MIX'] -# 15 TRE files -supportedExportedTREFiles = ['CLUES.TRE','ACTORS.TRE','CRIMES.TRE','CLUETYPE.TRE','KIA.TRE','SPINDEST.TRE','VK.TRE','OPTIONS.TRE','DLGMENU.TRE','ENDCRED.TRE','HELP.TRE','SCORERS.TRE','KIACRED.TRE','ERRORMSG.TRE','AUTOSAVE.TRE'] +SUPPORTED_LANGUAGES_DESCRIPTION_CODE_TLIST = [('EN_ANY', 'E', 'English'), ('DE_DEU', 'G', 'German'), ('FR_FRA', 'F', 'French'), ('IT_ITA', 'I', 'Italian'), ('RU_RUS', 'R', 'Russian'), ('ES_ESP', 'S', 'Spanish')] +DEFAULT_LANG_DESC_CODE = SUPPORTED_LANGUAGES_DESCRIPTION_CODE_TLIST[0] -wavfiles = [] -wavfilesNoDups = [] -actorPropertyEntries = [] #[0]:id, [1]:ShortHand Name [2]:Full Name -actorPropertyEntriesWasInit = False +gWavFiles = [] +gWavFilesNoDups = [] +gActorPropertyEntries = [] #[0]:id, [1]:ShortHand Name [2]:Full Name +gActorPropertyEntriesWasInit = False # strFileName should be the full file name (including extension) @@ -97,10 +99,10 @@ def calculateFoldHash(strFileName): #print (strParam +': ' +''.join('{:08X}'.format(hash))) return hash -# Fill the actorPropertyEntries table +# Fill the gActorPropertyEntries table def initActorPropertyEntries(thePathToActorNamesTxt): - global actorPropertyEntriesWasInit - global actorPropertyEntries + global gActorPropertyEntriesWasInit + global gActorPropertyEntries firstLine = True # print "opening actornames" if thePathToActorNamesTxt is None or not thePathToActorNamesTxt: @@ -116,40 +118,40 @@ def initActorPropertyEntries(thePathToActorNamesTxt): # print "skippingHeader" firstLine = False else: - actorPropertyEntries.append(line) - actorPropertyEntriesWasInit = True + gActorPropertyEntries.append(line) + gActorPropertyEntriesWasInit = True tsv.close() def getActorShortNameById(lookupActorId): - global actorPropertyEntriesWasInit - global actorPropertyEntries - if not actorPropertyEntriesWasInit: + global gActorPropertyEntriesWasInit + global gActorPropertyEntries + if not gActorPropertyEntriesWasInit: return '' else: - for actorEntryTmp in actorPropertyEntries: + for actorEntryTmp in gActorPropertyEntries: if int(actorEntryTmp[0]) == int(lookupActorId): return actorEntryTmp[1] return '' def getActorFullNameById(lookupActorId): - global actorPropertyEntriesWasInit - global actorPropertyEntries - if not actorPropertyEntriesWasInit: + global gActorPropertyEntriesWasInit + global gActorPropertyEntries + if not gActorPropertyEntriesWasInit: return '' else: - for actorEntryTmp in actorPropertyEntries: + for actorEntryTmp in gActorPropertyEntries: if int(actorEntryTmp[0]) == int(lookupActorId): return actorEntryTmp[2] return '' def getActorIdByShortName(lookupActorShortName): - global actorPropertyEntriesWasInit - global actorPropertyEntries - if not actorPropertyEntriesWasInit: + global gActorPropertyEntriesWasInit + global gActorPropertyEntries + if not gActorPropertyEntriesWasInit: return '' else: - for actorEntryTmp in actorPropertyEntries: + for actorEntryTmp in gActorPropertyEntries: if actorEntryTmp[1] == lookupActorShortName: return actorEntryTmp[0].zfill(2) return '' @@ -158,11 +160,11 @@ def getActorShortNameAndLocalQuoteIdByAUDHashID(audHashId): actorId = 0 actorShortName = '' actorLocalQuoteId = 0 - if not actorPropertyEntriesWasInit: + if not gActorPropertyEntriesWasInit: print "Error:: actor properties were not initialized!" return (actorId, actorShortName, actorLocalQuoteId) - for actorEntryTmp in actorPropertyEntries: + for actorEntryTmp in gActorPropertyEntries: if( (audHashId - (int(actorEntryTmp[0]) * 10000) ) >= 0) and ((audHashId - (int(actorEntryTmp[0]) * 10000)) < 10000): actorId = int(actorEntryTmp[0]) actorShortName = actorEntryTmp[1] @@ -182,7 +184,7 @@ def ensure_dir(directory): # Reading in the INPUT TLK files and checking all the AUD file properties # def inputTLKsExtract(inputTLKpath, outputWAVpath): - # try to open all TLK file entries from supportedTLKInputFiles + # try to open all TLK file entries from SUPPORTED_TLK_INPUT_FILES # then per TLK file # create an output folder in the OUTPUT PATH named TLK## for the 1, 2, 3 TLK and TLKSPCHSFX for the SPCHSFX.TLK # printout: @@ -197,25 +199,25 @@ def inputTLKsExtract(inputTLKpath, outputWAVpath): # breaking after first for loop yields only the top directory files, which is what we want for (dirpath, dirnames, filenames) in walk(inputTLKpath): for filename in filenames: - for tlkTuple in supportedTLKInputFiles: + for tlkTuple in SUPPORTED_TLK_INPUT_FILES: if filename.upper() == tlkTuple[0]: inputTLKFilesFound.append(tlkTuple) break for tmpTLKfileTuple in inputTLKFilesFound: - if traceModeEnabled: + if gTraceModeEnabled: print "Info:: Found TLK: %s" % ('"' + inputTLKpath + tmpTLKfileTuple[0] + '"') errorFound = False inTLKFile = None # # Create output folder if not exists at output path - if traceModeEnabled: + if gTraceModeEnabled: print "Ensuring output directory %s" % (os.path.join(outputWAVpath, tmpTLKfileTuple[1] )) ensure_dir(os.path.join(outputWAVpath, tmpTLKfileTuple[1] ) ) try: inTLKFile = open(os.path.join(inputTLKpath,tmpTLKfileTuple[0]), 'rb') except: errorFound = True - print "Error:: Unexpected error:", sys.exc_info()[0] + print "Error:: Unexpected event:", sys.exc_info()[0] raise if not errorFound: tmpBuff = inTLKFile.read(2) @@ -231,8 +233,8 @@ def inputTLKsExtract(inputTLKpath, outputWAVpath): # 2 + 4 = 6 bytes short MIX header # 12 bytes per TLK entry in entries table # quick size validation - if traceModeEnabled: - print "Entries: %d, data segment %d bytes" % (numOfEntriesToExtract, allTlkFileSize) + if gTraceModeEnabled: + print "Debug:: Entries= %d, Data segment size= %d bytes" % (numOfEntriesToExtract, allTlkFileSize) if allActualBytesInMixFile != 2 + 4 + 12 * numOfEntriesToExtract + allTlkFileSize: print "Error:: TLK file size mismatch with reported size in header for %s!" % (tmpTLKfileTuple[0]) else: @@ -253,8 +255,8 @@ def inputTLKsExtract(inputTLKpath, outputWAVpath): tmpBuff = inTLKFile.read(4) tmpRdTuple = struct.unpack('I', tmpBuff) sizeOfAUDEntry = tmpRdTuple[0] - if traceModeEnabled: - print "Entry: %s, offset %s, data segment %s bytes" % (''.join('{:08X}'.format(idOfAUDEntry)), ''.join('{:08X}'.format(offsetOfAUDEntry)),''.join('{:08X}'.format(sizeOfAUDEntry))) + if gTraceModeEnabled: + print "Debug:: Entry= %s, offset %s, Data segment size= %s bytes" % (''.join('{:08X}'.format(idOfAUDEntry)), ''.join('{:08X}'.format(offsetOfAUDEntry)),''.join('{:08X}'.format(sizeOfAUDEntry))) # # put file in AUD object # do we need AUD decode? @@ -285,7 +287,7 @@ def inputTLKsExtract(inputTLKpath, outputWAVpath): if not os.path.isfile(os.path.join(outputWAVpath, tmpTLKfileTuple[1], targetSimpleFileName) ): thisAudFile.extract_as_wav(audFileBuffer, os.path.join(outputWAVpath, tmpTLKfileTuple[1], targetSimpleFileName) ) else: - if traceModeEnabled: + if gTraceModeEnabled: print "Info:: Output file %s already exists. Skipping..." % (os.path.join(outputWAVpath, tmpTLKfileTuple[1], targetSimpleFileName)) else: print "Error:: while LOADING aud file!" @@ -299,18 +301,18 @@ def inputTLKsExtract(inputTLKpath, outputWAVpath): return def inputMIXExtractTREs(inputMIXpath, excelOutBook = None): - print "Info:: Checking in %s for MIX files to extract TRE's from" % (inputMIXpath) + print "Info:: Checking in %s for MIX files to extract Text Resources (TR%ss) from..." % (inputMIXpath, gActiveLanguageDescriptionCodeTuple[1]) inputMIXFilesFound = [] # breaking after first for loop yields only the top directory files, which is what we want for (dirpath, dirnames, filenames) in walk(inputMIXpath): for filename in filenames: - for mixFileName in supportedMIXInputFiles: + for mixFileName in SUPPORTED_MIX_INPUT_FILES: if filename.upper() == mixFileName: inputMIXFilesFound.append(mixFileName) break for tmpMIXfileName in inputMIXFilesFound: - if traceModeEnabled: - print "Found MIX: %s" % ('"' + tmpMIXfileName + '"') + if gTraceModeEnabled: + print "Info:: Found MIX file: %s" % ('"' + tmpMIXfileName + '"') errorFound = False inMIXFile = None # @@ -318,7 +320,7 @@ def inputMIXExtractTREs(inputMIXpath, excelOutBook = None): inMIXFile = open(os.path.join(inputMIXpath,tmpMIXfileName), 'rb') except: errorFound = True - print "Error:: Unexpected error:", sys.exc_info()[0] + print "Error:: Unexpected event:", sys.exc_info()[0] raise if not errorFound: totalTREs = 0 @@ -335,8 +337,8 @@ def inputMIXExtractTREs(inputMIXpath, excelOutBook = None): # 2 + 4 = 6 bytes short MIX header # 12 bytes per MIX entry in entries table # quick size validation - if traceModeEnabled: - print "Entries: %d, data segment %d bytes" % (numOfEntriesToExtract, allMixFileSize) + if gTraceModeEnabled: + print "Debug:: Entries= %d, Data segment size= %d bytes" % (numOfEntriesToExtract, allMixFileSize) if allActualBytesInMixFile != 2 + 4 + 12 * numOfEntriesToExtract + allMixFileSize: print "Error:: MIX file size mismatch with reported size in header for %s!" % (tmpMIXfileName) else: @@ -348,7 +350,7 @@ def inputMIXExtractTREs(inputMIXpath, excelOutBook = None): # for i in range(0, numOfEntriesToExtract): foundTREFile = False - currTreFileName = 'UNKNOWN.TRE' + currTreFileName = 'UNKNOWN.TR%s' % (gActiveLanguageDescriptionCodeTuple[1]) inMIXFile.seek(2 + 4 + 12*i) tmpBuff = inMIXFile.read(4) tmpRdTuple = struct.unpack('I', tmpBuff) @@ -360,15 +362,16 @@ def inputMIXExtractTREs(inputMIXpath, excelOutBook = None): tmpRdTuple = struct.unpack('I', tmpBuff) sizeOfMIXEntry = tmpRdTuple[0] - for suppTREFileName in supportedExportedTREFiles: + for suppTREFileName in SUPPORTED_EXPORTED_TRx_FILES: + suppTREFileName = suppTREFileName + gActiveLanguageDescriptionCodeTuple[1] if(idOfMIXEntry == calculateFoldHash(suppTREFileName)): foundTREFile = True currTreFileName = suppTREFileName break if (foundTREFile == True): - if traceModeEnabled: - print "Entry Name: %s, Entry ID: %s, offset %s, data segment %s bytes" % (currTreFileName, ''.join('{:08X}'.format(idOfMIXEntry)), ''.join('{:08X}'.format(offsetOfMIXEntry)),''.join('{:08X}'.format(sizeOfMIXEntry))) + if gTraceModeEnabled: + print "Debug:: Entry Name= %s, Entry ID= %s, offset= %s, Data segment size= %s bytes" % (currTreFileName, ''.join('{:08X}'.format(idOfMIXEntry)), ''.join('{:08X}'.format(offsetOfMIXEntry)),''.join('{:08X}'.format(sizeOfMIXEntry))) # # IF TRE FILE: # put file in TRE object @@ -376,15 +379,15 @@ def inputMIXExtractTREs(inputMIXpath, excelOutBook = None): # inMIXFile.seek(2 + 4 + 12*numOfEntriesToExtract + offsetOfMIXEntry) if(offsetOfMIXEntry + sizeOfMIXEntry > allMixFileSize): - print "Error:: TRE file size mismatch with reported size in entry header!" + print "Error:: TR%s file size mismatch with reported size in entry header!" % (gActiveLanguageDescriptionCodeTuple[1]) else: treFileBuffer = inMIXFile.read(sizeOfMIXEntry) if (len(treFileBuffer) == sizeOfMIXEntry): # load TRE file thisTreFile = treFile() if (thisTreFile.loadTreFile(treFileBuffer, allMixFileSize)): - if traceModeEnabled: - print "Info:: TRE file loaded" + if gTraceModeEnabled: + print "Info:: TR%s file loaded" % (gActiveLanguageDescriptionCodeTuple[1]) if excelOutBook != None: sh = excelOutBook.add_sheet(currTreFileName) n = 0 # keeps track of rows @@ -402,19 +405,133 @@ def inputMIXExtractTREs(inputMIXpath, excelOutBook = None): objStr = e1[1] #print type (objUTF8SafeStr) # the type is STR here # python strings are immutable (can't replace characters) but we have an issue with certain special characters in the ORIGINAL TRE (kiacred and endcred) - # (they are out of their order from their proper order in windwos-1252) + # (they are out of their order from their proper order in windows-1252) # so we need to create a new string. + # TODO: The following check could be streamlined if it could use semi-auto constructed glyph mappings per font per Text Resource file. + # TODO: ^^ This could help support Russian versions -- but one the other hand maybe it's a bit over-engineering (?) objUTF8SafeStr = "" for i in range(0, len(objStr)): - if (objStr[i] == '\x81'): - objUTF8SafeStr += 'ü' - elif (objStr[i] == '\x82'): - objUTF8SafeStr += 'é' + if ( currTreFileName[:-1] == 'ERRORMSG.TR'): + # ERRORMSG.TRx uses different font than the others and there are conflicts, so we can't put it in the same checks with the other TRxs + # + # ENG version has no ERRORMSG exceptions + # GER + if (objStr[i] == '\xe4'): # DEU - ERRORMSG.TRG + objUTF8SafeStr += 'ä' + elif (objStr[i] == '\xf6'): # DEU - ERRORMSG.TRG + objUTF8SafeStr += 'ö' + elif (objStr[i] == '\xfc'): # DEU - ERRORMSG.TRG + objUTF8SafeStr += 'ü' + # FRA + elif (objStr[i] == '\x82'): # FRA - ERRORMSG.TRF + objUTF8SafeStr += 'é' # this is identical to the KIA6PT mapping + elif (objStr[i] == '\x85'): # FRA - ERRORMSG.TRF (also used in ITA ERRORMSG.TRI - same glyph) + objUTF8SafeStr += 'à' # this is identical to the KIA6PT mapping + elif (objStr[i] == '\x8a'): # FRA - ERRORMSG.TRF (also used in ITA ERRORMSG.TRI - same glyph) + objUTF8SafeStr += 'è' # this is identical to the KIA6PT mapping + elif (objStr[i] == '\xe0'): # FRA - ERRORMSG.TRF + objUTF8SafeStr += 'à' + elif (objStr[i] == '\xe8'): # FRA - ERRORMSG.TRF + objUTF8SafeStr += 'è' + elif (objStr[i] == '\xe9'): # FRA - ERRORMSG.TRF (also used in ESP ERRORMSG.TRS - same glyph) + objUTF8SafeStr += 'é' + elif (objStr[i] == '\xea'): # FRA - ERRORMSG.TRF + objUTF8SafeStr += 'ê' + # ITA + #elif (objStr[i] == '\x85'): # ITA - ERRORMSG.TRI [commented out: already covered in FRA check above] + # objUTF8SafeStr += 'à' # this is identical to the KIA6PT mapping + #elif (objStr[i] == '\x8a'): # ITA - ERRORMSG.TRI [commented out: already covered in FRA check above] + # objUTF8SafeStr += 'è' # this is identical to the KIA6PT mapping + elif (objStr[i] == '\x97'): # ITA - ERRORMSG.TRI + objUTF8SafeStr += 'ù' # this is identical to the KIA6PT mapping + # ESP + elif (objStr[i] == '\xa2'): # ESP - ERRORMSG.TRS + objUTF8SafeStr += 'ó' # this is identical to the KIA6PT mapping + elif (objStr[i] == '\xe1'): # ESP - ERRORMSG.TRS + objUTF8SafeStr += 'á' + #elif (objStr[i] == '\xe9'): # ESP - ERRORMSG.TRS [commented out: already covered in FRA check above] + # objUTF8SafeStr += 'é' + elif (objStr[i] == '\xed'): # ESP - ERRORMSG.TRS + objUTF8SafeStr += 'í' + elif (objStr[i] == '\xf3'): # ESP - ERRORMSG.TRS + objUTF8SafeStr += 'ó' + else: + objUTF8SafeStr += objStr[i] else: - objUTF8SafeStr += objStr[i] + # all the other TRx use the KIA6PT.FON + # There could be variances of the KIA6PT.FON per Blade Runner version + # TODO: For now, we assume that there aren't significant variances that warrant a more elaborate approach + if (objStr[i] == '\x81'): # EN, DEU, FRA, ITA, ESP + objUTF8SafeStr += 'ü' + elif (objStr[i] == '\x82'): # EN, DEU, FRA, ITA, ESP + objUTF8SafeStr += 'é' + ## Extras (DEU): + elif (objStr[i] == '\x84'): # DEU + objUTF8SafeStr += 'ä' # + elif (objStr[i] == '\x8e'): # DEU + objUTF8SafeStr += 'Ä' # + elif (objStr[i] == '\x94'): # DEU + objUTF8SafeStr += 'ö' # + elif (objStr[i] == '\x9a'): # DEU + objUTF8SafeStr += 'Ü' # + elif (objStr[i] == '\xe1'): # DEU (ENDCRED.TRG) + objUTF8SafeStr += 'ß' # + ## Extras (FRA): + elif (objStr[i] == '\x85'): # FRA, ITA + objUTF8SafeStr += 'à' # re-used in ITA, same glyph + elif (objStr[i] == '\x87'): # FRA + objUTF8SafeStr += 'ç' + elif (objStr[i] == '\x88'): # FRA + objUTF8SafeStr += 'ê' + elif (objStr[i] == '\x8a'): # FRA, ITA + objUTF8SafeStr += 'è' # re-used in ITA, same glyph + elif (objStr[i] == '\x8b'): # FRA + objUTF8SafeStr += 'ï' + elif (objStr[i] == '\x8c'): # FRA + objUTF8SafeStr += 'î' + elif (objStr[i] == '\x93'): # FRA + objUTF8SafeStr += 'ô' + elif (objStr[i] == '\x96'): # FRA + objUTF8SafeStr += 'û' + elif (objStr[i] == '\x97'): # FRA, ITA + objUTF8SafeStr += 'ù' # re-used in ITA, same glyph + ## Extras (ITA): + #elif (objStr[i] == '\x85'): # ITA [commented out: already covered in FRA check above] + # objUTF8SafeStr += 'à' + #elif (objStr[i] == '\x8a'): # ITA [commented out: already covered in FRA check above] + # objUTF8SafeStr += 'è' + elif (objStr[i] == '\x8d'): # ITA + objUTF8SafeStr += 'ì' + #elif (objStr[i] == '\x97'): # ITA [commented out: already covered in FRA check above] + # objUTF8SafeStr += 'ù' + # Extras (ESP): + elif (objStr[i] == '\xa0'): # ESP + objUTF8SafeStr += 'á' + elif (objStr[i] == '\xa1'): # ESP + objUTF8SafeStr += 'í' + elif (objStr[i] == '\xa2'): # ESP + objUTF8SafeStr += 'ó' + elif (objStr[i] == '\xa3'): # ESP + objUTF8SafeStr += 'ú' + elif (objStr[i] == '\xa4'): # ESP + objUTF8SafeStr += 'ñ' + elif (objStr[i] == '\xa5'): # ESP + objUTF8SafeStr += 'Ñ' + elif (objStr[i] == '\xa8'): # ESP + objUTF8SafeStr += '¿' + elif (objStr[i] == '\xad'): # ESP + objUTF8SafeStr += '¡' + elif (objStr[i] == '\x90'): # ESP + objUTF8SafeStr += 'É' + else: + objUTF8SafeStr += objStr[i] #objUTF8Safe = objUTF8Safe.replace('\x81',u'u') #'ü' # this does not work #objUTF8Safe = objUTF8Safe.replace('\x82',u'e') #'é' # this does not work - objUTF8Unicode = unicode(objUTF8SafeStr, 'utf-8') + try: + objUTF8Unicode = unicode(objUTF8SafeStr, 'utf-8') + except Exception as e: + print 'Error:: Failed to create unicode string: ' + str(e) + objUTF8Unicode = unicode("???", 'utf-8') sh.write(m, 1, objUTF8Unicode) @@ -423,11 +540,11 @@ def inputMIXExtractTREs(inputMIXpath, excelOutBook = None): # pass totalTREs = totalTREs + 1 else: - print "Error:: while LOADING TRE file!" + print "Error:: while LOADING TR%s file!" % (gActiveLanguageDescriptionCodeTuple[1]) else: - print "Error:: while reading TRE file %s into mem buffer" % (''.join('{:08X}'.format(idOfMIXEntry))) + print "Error:: while reading TR%s file %s into mem buffer" % (gActiveLanguageDescriptionCodeTuple[1], ''.join('{:08X}'.format(idOfMIXEntry))) inMIXFile.close() - print "Info:: Total TREs: %d " % (totalTREs) + print "Info:: Total TR%ss handled: %d " % (gActiveLanguageDescriptionCodeTuple[1], totalTREs) return @@ -435,8 +552,8 @@ def inputMIXExtractTREs(inputMIXpath, excelOutBook = None): # Creating the OUTPUT XLS file with one sheet named as the @param sheet with entries based on the list1 (wav files, without duplicates) # def outputXLS(filename, sheet, list1, parseTREResourcesAlso = False, mixInputFolderPath = ''): - global stringReplacementForRootFolderWithExtractedFiles - global numReplaceStartingCharacters + global gStringReplacementForRootFolderWithExtractedFiles + global gNumReplaceStartingCharacters book = xlwt.Workbook() sh = book.add_sheet(sheet) # First Row @@ -503,8 +620,8 @@ def outputXLS(filename, sheet, list1, parseTREResourcesAlso = False, mixInputFol # real path of filename realPathOfFileNameToLink = twoTokensOfRelDirnameAndFilenameXLS[2] # checks if not empty - if stringReplacementForRootFolderWithExtractedFiles and numReplaceStartingCharacters > 0: - realPathOfFileNameToLink = realPathOfFileNameToLink.replace(realPathOfFileNameToLink[:numReplaceStartingCharacters], stringReplacementForRootFolderWithExtractedFiles) + if gStringReplacementForRootFolderWithExtractedFiles and gNumReplaceStartingCharacters > 0: + realPathOfFileNameToLink = realPathOfFileNameToLink.replace(realPathOfFileNameToLink[:gNumReplaceStartingCharacters], gStringReplacementForRootFolderWithExtractedFiles) #works in Linux + Libreoffice # also works in Windows + LibreOffice (run from msys) -- tried something like: @@ -532,9 +649,30 @@ def outputXLS(filename, sheet, list1, parseTREResourcesAlso = False, mixInputFol inputMIXExtractTREs(mixInputFolderPath, book) # TODO add sheets # TODO handle special string characters (to UTF-8) + try: + book.save(filename) + except: + print "Error:: Could not save the output Excel file (maybe it's open?)" - book.save(filename) - +# +# Aux function to validate input language description +# +def getLanguageDescCodeTuple(candidateLangDescriptionStr): + if (candidateLangDescriptionStr is None or not candidateLangDescriptionStr ): + resultTuple = DEFAULT_LANG_DESC_CODE + else: + tmpMatchTuplesList = [ (x,y,z) for (x,y,z) in SUPPORTED_LANGUAGES_DESCRIPTION_CODE_TLIST if x == candidateLangDescriptionStr] + if tmpMatchTuplesList is not None and len(tmpMatchTuplesList) > 0: + resultTuple = tmpMatchTuplesList[0] + else: + resultTuple = None + return resultTuple + +def printInfoMessageForLanguageSelectionSyntax(): + tmpCSVSupportedLangDescValues = ", ".join( zip(*SUPPORTED_LANGUAGES_DESCRIPTION_CODE_TLIST)[0] ) + print "Valid values for language selection are: %s" % (tmpCSVSupportedLangDescValues) + print "Default value is: %s (%s)" % (DEFAULT_LANG_DESC_CODE[0], DEFAULT_LANG_DESC_CODE[2]) + return # # # @@ -542,10 +680,19 @@ def outputXLS(filename, sheet, list1, parseTREResourcesAlso = False, mixInputFol # main def main(argsCL): # TODO parse arguments using argparse? https://docs.python.org/3/library/argparse.html#module-argparse - global traceModeEnabled - traceModeEnabled = False + global gTraceModeEnabled + global gStringReplacementForRootFolderWithExtractedFiles + global gNumReplaceStartingCharacters + global gActiveLanguageDescriptionCodeTuple + global gWavFiles + global gWavFilesNoDups + + gTraceModeEnabled = False + gActiveLanguageDescriptionCodeTuple = DEFAULT_LANG_DESC_CODE + pathToActorNamesTxt = "" + candidateLangDescriptionTxt = "" TMProotFolderWithExtractedFiles = "" TMProotFolderWithInputTLKFiles = "" @@ -554,32 +701,34 @@ def main(argsCL): extractTreFilesMode = False invalidSyntax = False - print "Running %s (%s)..." % (app_name_spaced, app_version) + 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 "%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 "%s takes has one mandatory argument, the folder of the extracted WAV files:" % (app_wrapper_name) - print "Valid syntax: %s -op folderpath_for_extracted_wav_Files [-ip folderpath_for_TLK_Files] [-ian path_to_actornames_txt] [-m stringPathToReplaceFolderpathInExcelLinks] [-xwav] [-xtre] [--trace]" % (app_wrapper_name) + print "%s takes has one mandatory argument, the folder of the extracted WAV files:" % (APP_WRAPPER_NAME) + print "Valid syntax: %s -op folderpath_for_extracted_wav_Files [-ip folderpath_for_TLK_Files] [-ian path_to_actornames_txt] [-m stringPathToReplaceFolderpathInExcelLinks] [-ld gameInputLanguageDescription] [-xwav] [-xtre] [--trace]" % (APP_WRAPPER_NAME) print "The -op switch has an argument that is the path for extracted WAV files folder. The -op switch is REQUIRED always." print "The -ip switch has an argument that is the path for the input (TLK or MIX) files folder (can be the same as the Blade Runner installation folder)." print "The -ian switch is followed by the path to actornames.txt, if it's not in the current working directory." print "The -m switch has an argument that is a replacement string for the path to the folder of extracted WAV files which will be used as a prefix for the links in the output XLS file." + print "The -ld switch has an argument that is the language description of the original game files that you use as input." + printInfoMessageForLanguageSelection() print "The -xwav switch enables the WAV audio extract mode from the TLK files. It requires an INPUT path to be set with the -ip switch." - print "The -xtre switch enables the TRE parsing mode from the original MIX files. It requires an INPUT path to be set with the -ip switch." + print "The -xtre switch enables the TR%s parsing mode from the original MIX files. It requires an INPUT path to be set with the -ip switch." % (gActiveLanguageDescriptionCodeTuple[1]) print "The --trace switch enables more debug messages being printed during execution." print "If the app finishes successfully a sortedWavs.xls file will be created in the same folder with the app." print "--------------------" print "Thank you for using this app." - print "Please provide any feedback to: %s " % (company_email) + 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) + 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 @@ -588,33 +737,41 @@ def main(argsCL): if( i < (len(argsCL) - 1) and argsCL[i][:1] == '-' and argsCL[i+1][:1] != '-'): if (argsCL[i] == '-op'): TMProotFolderWithExtractedFiles = argsCL[i+1] - numReplaceStartingCharacters = len(TMProotFolderWithExtractedFiles) + gNumReplaceStartingCharacters = len(TMProotFolderWithExtractedFiles) elif (argsCL[i] == '-ip'): TMProotFolderWithInputTLKFiles = argsCL[i+1] elif (argsCL[i] == '-m'): - stringReplacementForRootFolderWithExtractedFiles = argsCL[i+1] + gStringReplacementForRootFolderWithExtractedFiles = argsCL[i+1] elif (argsCL[i] == '-ian'): pathToActorNamesTxt = argsCL[i+1] + elif (argsCL[i] == '-ld'): + candidateLangDescriptionTxt = argsCL[i+1] elif (argsCL[i] == '-xwav'): - print "Extract WAVs from TLK files mode enabled." + print "Info:: Extract WAVs from TLK files mode enabled." extractWavFilesMode = True elif (argsCL[i] == '-xtre'): - print "Extract TRE mode enabled." + print "Info:: Extract Text Resources (TR%ss) mode enabled." % (gActiveLanguageDescriptionCodeTuple[1]) extractTreFilesMode = True elif argsCL[i] == '--trace': print "Info:: Trace mode enabled (more debug messages)." - traceModeEnabled = True + gTraceModeEnabled = True if not TMProotFolderWithExtractedFiles: # this argument is mandatory invalidSyntax = True - if (extractWavFilesMode == True or extractTreFilesMode == True) and (TMProotFolderWithInputTLKFiles == ''): + if (not invalidSyntax) and (extractWavFilesMode == True or extractTreFilesMode == True) and (TMProotFolderWithInputTLKFiles == ''): invalidSyntax = True - + + gActiveLanguageDescriptionCodeTuple = getLanguageDescCodeTuple(candidateLangDescriptionTxt) + if (not invalidSyntax) and gActiveLanguageDescriptionCodeTuple is None: + print "Error:: Invalid language code was specified" + printInfoMessageForLanguageSelectionSyntax() + invalidSyntax = True + if not invalidSyntax: - + print "Info:: Game Language Selected: %s (%s)" % (gActiveLanguageDescriptionCodeTuple[0], gActiveLanguageDescriptionCodeTuple[2]) # parse Actors files: initActorPropertyEntries(pathToActorNamesTxt) -# for actorEntryTmp in actorPropertyEntries: +# for actorEntryTmp in gActorPropertyEntries: # print "Found actor: %s %s %s" % (actorEntryTmp[0], actorEntryTmp[1], actorEntryTmp[2]) # # Checking for the optional case of parsing the input TLK files to extract to WAV @@ -627,7 +784,7 @@ def main(argsCL): # # Parsing the extracted WAV files # - print "Parsing the extracted WAV audio files. Please wait (it could take a while)..." + print "Info:: Parsing the extracted WAV audio files. Please wait (this could take a while)..." for (dirpath, dirnames, filenames) in walk(TMProotFolderWithExtractedFiles): for nameIdx, nameTmp in enumerate(filenames): relDirName = '' @@ -639,9 +796,9 @@ def main(argsCL): # print os.path.dirname(dirpath) # print os.path.abspath(os.path.join(os.path.join(dirpath, nameTmp), os.pardir)) filenames[nameIdx] = filenames[nameIdx] +'&' + relDirName + '&' + os.path.join(dirpath, nameTmp) - wavfiles.extend(filenames) + gWavFiles.extend(filenames) # break - for fileIdx, filenameTmp in enumerate(wavfiles): + for fileIdx, filenameTmp in enumerate(gWavFiles): twoTokensOfFilenameAndRelDirname = filenameTmp.split('&', 1) if len(twoTokensOfFilenameAndRelDirname) != 2: print "ERROR in filename and rel dirname split: %s" % (filenameTmp) @@ -682,7 +839,7 @@ def main(argsCL): # # # foundMatchForActorShortHand = False -# for actorEntryTmp in actorPropertyEntries: +# for actorEntryTmp in gActorPropertyEntries: # if actorEntryTmp[1] == threeTokensOfFilename[0]: # threeTokensOfFilename[0] = actorEntryTmp[0].zfill(2) # threeTokensOfFilename.append(actorEntryTmp[2]) @@ -691,21 +848,21 @@ def main(argsCL): # end of replace actor name shorthand twoTokensOfFilenameForExt[0] = '#'.join(threeTokensOfFilename) filenameTmp = twoTokensOfFilenameForExt[0] + '&' + twoTokensOfFilenameAndRelDirname[1] - wavfiles[fileIdx] = filenameTmp + gWavFiles[fileIdx] = filenameTmp else: print "ERROR in spliting tokens on _: %s" % (filenameTmp) sys.exit(0) #sort in-place # # - wavfiles.sort() + gWavFiles.sort() # # # # # # Code for renaming non conforming filenames - just to be consistent in file naming # # TO BE RUN ONCE FOR CONFORMANCE. No NEED TO Re-RUN # # If its run though, comment this section and re-run the tool to get proper links in Excel file # # -# for filenameSrcTmp in wavfiles: +# for filenameSrcTmp in gWavFiles: # # get real full path from last token when split at & # # create target full path from the parentdir of last token and the current state of first 3 tokens when splitting at '#' # # report mismatch @@ -727,7 +884,7 @@ def main(argsCL): # END OF: Code for renaming non conforming filenames - just to be consistent in file naming # # - for filenameSrcTmp in wavfiles: + for filenameSrcTmp in gWavFiles: duplicateFound = False # print "Converted %s" % (filenameSrcTmp) # Weed out duplicates by copying to another table (quick and dirty) @@ -736,7 +893,7 @@ def main(argsCL): threeTokensOfQuoteFilenameSrc = twoTokensOfRelDirnameAndFilenameSrc[0].split('#', 2) #concatenate actorID and quoteID for search key keyForDuplicateSearchSrc = threeTokensOfQuoteFilenameSrc[0] + threeTokensOfQuoteFilenameSrc[1] - for fileTargIdx, filenameTargTmp in enumerate(wavfilesNoDups): + for fileTargIdx, filenameTargTmp in enumerate(gWavFilesNoDups): twoTokensOfRelDirnameAndFilenameTarg = filenameTargTmp.split('&', 2) tmpRelDirNameTarg = twoTokensOfRelDirnameAndFilenameTarg[1] threeTokensOfQuoteFilenameTarg = twoTokensOfRelDirnameAndFilenameTarg[0].split('#', 2) @@ -745,21 +902,20 @@ def main(argsCL): if(keyForDuplicateSearchSrc == keyForDuplicateSearchTarg): #print "Found duplicate %s" % (filenameSrcTmp) duplicateFound = True - wavfilesNoDups[fileTargIdx] = twoTokensOfRelDirnameAndFilenameTarg[0] + '&' + tmpRelDirNameSrc + ',' + tmpRelDirNameTarg + '&' + twoTokensOfRelDirnameAndFilenameTarg[2] + gWavFilesNoDups[fileTargIdx] = twoTokensOfRelDirnameAndFilenameTarg[0] + '&' + tmpRelDirNameSrc + ',' + tmpRelDirNameTarg + '&' + twoTokensOfRelDirnameAndFilenameTarg[2] break if(duplicateFound == False): - wavfilesNoDups.append(filenameSrcTmp) -# for filenameSrcTmp in wavfilesNoDups: + gWavFilesNoDups.append(filenameSrcTmp) +# for filenameSrcTmp in gWavFilesNoDups: # print "Unique %s" % (filenameSrcTmp) - - print "Creating output excel %s file..." % (OUTPUT_XLS_FILENAME) - outputXLS(OUTPUT_XLS_FILENAME, OUTPUT_XLS_QUOTES_SHEET, wavfilesNoDups, extractTreFilesMode, TMProotFolderWithInputTLKFiles) + print "Info:: Creating output excel %s file..." % (OUTPUT_XLS_FILENAME) + outputXLS(OUTPUT_XLS_FILENAME, OUTPUT_XLS_QUOTES_SHEET + gActiveLanguageDescriptionCodeTuple[1], gWavFilesNoDups, extractTreFilesMode, TMProotFolderWithInputTLKFiles) else: invalidSyntax = True if invalidSyntax == True: - print "Invalid syntax\n Try: \n %s --help for more info \n %s --version for version info " % (app_wrapper_name, app_wrapper_name) - print "Valid syntax: %s -op folderpath_for_extracted_wav_Files [-ip folderpath_for_TLK_Files] [-ian path_to_actornames_txt] [-m stringPathToReplaceFolderpathInExcelLinks] [-xwav] [-xtre] [--trace]" % (app_wrapper_name) + print "Error:: Invalid syntax!\n Try: \n %s --help for more info \n %s --version for version info " % (APP_WRAPPER_NAME, APP_WRAPPER_NAME) + print "Valid syntax: %s -op folderpath_for_extracted_wav_Files [-ip folderpath_for_TLK_Files] [-ian path_to_actornames_txt] [-m stringPathToReplaceFolderpathInExcelLinks] [-ld gameInputLanguageDescription] [-xwav] [-xtre] [--trace]" % (APP_WRAPPER_NAME) tmpi = 0 for tmpArg in argsCL: if tmpi==0: #skip first argument @@ -781,5 +937,5 @@ if __name__ == '__main__': main(sys.argv[0:]) else: ## debug - #print 'Debug:: %s was imported from another module' % (app_wrapper_name) + #print 'Debug:: %s was imported from another module' % (APP_WRAPPER_NAME) pass diff --git a/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/treFileLib.py b/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/treFileLib.py index 6f54bb3563..9c5d56b5dc 100644 --- a/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/treFileLib.py +++ b/devtools/create_bladerunner/subtitles/quotesSpreadsheetCreator/treFileLib.py @@ -57,7 +57,7 @@ class treFile: # # string IDs table (each entry is unsigned integer 4 bytes) # - print "Total texts in TRE: %d" % (self.header().numOfTextResources) + print "Info:: Total texts in Text Resource file= %d" % (self.header().numOfTextResources) for idx in range(0, self.header().numOfTextResources): tmpTuple = struct.unpack_from('I', treBytesBuff, offsInTreFile) # unsigned integer 4 bytes self.stringEntriesLst.append( (tmpTuple[0], '') ) @@ -75,7 +75,7 @@ class treFile: #absStartOfOffsetTable = absStartOfIndexTable + (self.header().numOfTextResources * 4) #absStartOfStringTable = absStartOfOffsetTable + ((self.header().numOfTextResources+1) * 4) - #print "buffer type " , type(treBytesBuff) # it is str + #print "Debug:: buffer type " , type(treBytesBuff) # it is str for idx in range(0, self.header().numOfTextResources): currOffset = self.stringOffsets[idx] + absStartOfIndexTable @@ -85,16 +85,16 @@ class treFile: # This works ok. # allTextsFound = treBytesBuff[currOffset:].split('\x00') - # check "problematic" character cases: - if currOffset == 5982 or currOffset == 6050 or currOffset == 2827 or currOffset == 2880: - print "Offs: %d\tFound String: %s" % ( currOffset,''.join(allTextsFound[0]) ) - #print "Offs: %d\tFound String: %s" % ( currOffset,''.join(allTextsFound[0]) ) + ## check "problematic" character cases: + #if currOffset == 5982 or currOffset == 6050 or currOffset == 2827 or currOffset == 2880: + # print "Debug:: Offs= %d\tFound String= %s" % ( currOffset,''.join(allTextsFound[0]) ) + # #print "Debug:: Offs: %d\tFound String= %s" % ( currOffset,''.join(allTextsFound[0]) ) (theId, stringOfIdx) = self.stringEntriesLst[idx] self.stringEntriesLst[idx] = (theId, ''.join(allTextsFound[0])) - #print "ID: %d\tFound String: %s" % ( theId,''.join(allTextsFound[0]) ) + #print "Debug:: ID= %d\tFound String= %s" % ( theId,''.join(allTextsFound[0]) ) return True except: - print "Loading failure!" + print "Error:: Loading Text Resource Failed!" return False def header(self): @@ -104,7 +104,7 @@ class treFile: # if __name__ == '__main__': # main() - print "Running %s as main module" % (my_module_name) + print "Debug:: Running %s as main module" % (my_module_name) # assumes a file of name ACTORS.TRE in same directory inTREFile = None errorFound = False @@ -112,17 +112,17 @@ if __name__ == '__main__': inTREFile = open(os.path.join('.','ACTORS.TRE'), 'rb') except: errorFound = True - print "Unexpected error:", sys.exc_info()[0] + print "Error:: Unexpected event= ", sys.exc_info()[0] raise if not errorFound: allOfTreFileInBuffer = inTREFile.read() treFileInstance = treFile() if (treFileInstance.loadTreFile(allOfTreFileInBuffer, len(allOfTreFileInBuffer))): - print "TRE file loaded successfully!" + print "Info:: Text Resource file loaded successfully!" else: - print "Error while loading TRE file!" + print "Error:: Error while loading Text Resource file!" inTREFile.close() else: #debug - #print "Running %s imported from another module" % (my_module_name) + #print "Debug:: Running %s imported from another module" % (my_module_name) pass \ No newline at end of file -- cgit v1.2.3