DEVTOOLS: BLADERUNNER: Added version sheet and EFIGS support

Now multiple languages can be packed in a single MIX file
This commit is contained in:
Thanasis Antoniou 2019-05-29 12:02:45 +03:00
parent a041a29111
commit 04d7f72bf7
4 changed files with 305 additions and 128 deletions

View file

@ -19,7 +19,7 @@ make devtools/create_bladerunner/subtitles
7. Launch the Blade Runner game using ScummVM.
## quotesSpreadsheetCreator (quoteSpreadsheetCreator.py)
(requires python lib *xlwt* (tested with version 1.3.0), *wave* (included in the Python 2 Standard Library)
(requires python libs *xlwt* (tested with version 1.3.0), *wave* (included in the Python 2 Standard Library)
A tool to gather all the speech audio filenames in an Excel file which will include a column with links to the audio file location on the PC. By Ctrl+MouseClick on that column's entries you should be able to listen to the corresponding wav file.
The output Excel file *out.xls* should help with the transcription of all the spoken *in-game* quotes. It also provides extra quote information such as the corresponding actor ID and quote ID per quote.
@ -49,7 +49,7 @@ The tool __requires__ a valid path to the actornames.txt file; this file is incl
## mixResourceCreator (mixResourceCreator.py)
(requires python lib *xlrd* (tested with version 1.2.0))
(requires python libs *xlrd* (tested with version 1.2.0), *xlwt* (tested with version 1.3.0), *xlutils* (tested with version 2.0.0))
A tool to process the aforementioned Excel file with the dialogue transcriptions and output text resource files (TRx) that will be packed along with the external font (see fontCreator tool) into a SUBTITLES.MIX file. Multiple TRx files will be created intermediately in order to fully support subtitles in the game. One TRx file includes all in-game spoken quotes and the rest of them correspond to any VQA video sequence that contain voice acting.
Usage:
```
@ -62,7 +62,7 @@ Syntax Notes:
2. The "-ian" optional switch is followed by the path to the actornames.txt file -- if this is omitted then the file is assumed to reside in the current working directory.
3. The "-cft" optional switch is followed by the path to the text configuration file "configureFontsTranslation.txt" -- if this is omitted then the file is assumed to reside in the current working directory.
4. The "-ld" optional switch is followed by a language description for the language of the game you are exporting Text Resources from. This switch is meaningful when you also use the "-xtre" switch to export Text Resource files.
* Valid language values are: EN_ANY, DE_DEU, FR_FRA, IT_ITA, ES_ESP, RU_RUS
* Valid language values are: EN_ANY, DE_DEU, FR_FRA, IT_ITA, ES_ESP, RU_RUS, EFIGS
* Default language value is: EN_ANY (English)
5. The "--trace" optional switch enables extra debug messages to be printed.

View file

@ -15,8 +15,11 @@ shutilLibFound = False
ctypesLibFound = False
csvLibFound = False
xlrdLibFound = False
xlwtLibFound = False
xlutilsLibFound = False
reLibFound = False
structLibFound = False
datetimeLibFound = False
try:
import os
@ -46,6 +49,13 @@ except ImportError:
else:
ctypesLibFound = True
try:
from datetime import datetime
except ImportError:
print "[Error] datetime python library is required to be installed!"
else:
datetimeLibFound = True
try:
import csv
except ImportError:
@ -60,6 +70,20 @@ except ImportError:
else:
xlrdLibFound = True
try:
import xlwt
except ImportError:
print "[Error] xlwt python library is required to be installed!"
else:
xlwtLibFound = True
try:
from xlutils.copy import copy
except ImportError:
print "[Error] xlutils python library is required to be installed!"
else:
xlutilsLibFound = True
try:
import re
except ImportError:
@ -74,12 +98,17 @@ except ImportError:
else:
structLibFound = True
if (not osLibFound) \
or (not sysLibFound) \
or (not shutilLibFound) \
or (not ctypesLibFound) \
or (not datetimeLibFound) \
or (not csvLibFound) \
or (not xlrdLibFound) \
or (not xlwtLibFound) \
or (not xlutilsLibFound) \
or (not reLibFound) \
or (not structLibFound):
sys.stdout.write("[Error] Errors were found when trying to import required python libraries\n")
@ -90,9 +119,10 @@ from os import path
from xlrd import *
# for pack
from struct import *
from subtlsVersTextResource import *
COMPANY_EMAIL = "classic.adventures.in.greek@gmail.com"
APP_VERSION = "0.90"
APP_VERSION = "1.00"
APP_NAME = "packBladeRunnerMIXFromPCTLKXLS"
APP_WRAPPER_NAME = "mixResourceCreator.py"
APP_NAME_SPACED = "Blade Runner MIX Resource Creator"
@ -100,11 +130,14 @@ APP_SHORT_DESC = "Make a Text Resource file for spoken in-game quotes and pack T
WINDOWS_1252_ENCODING = 'windows-1252'
SUBTITLES_DEFAULT_VERSION_NUMBER = '3'
# TODO- maybe the '_E' part is not needed
SUBTITLES_FONT_NAME_CATEGORY = 'SUBTLS_E'
DEFAULT_SUBTITLES_FONT_NAME = SUBTITLES_FONT_NAME_CATEGORY + '.FON'
DEFAULT_SUBTITLES_MIX_OUTPUT_NAME = u'SUBTITLES.MIX'
SUPPORTED_DIALOGUE_VERSION_SHEET = 'SBTLVERS.TRE'
# all dialogue sheets get the SUBTLS_E.FON for translation to a Text Resource (TRx)
# In-game dialogue sheet
# TODO- maybe the '_E' part is not needed, since we use the suffix (x) of the extension (TRx) to signify the language
@ -119,6 +152,7 @@ SUPPORTED_VIDEO_DIALOGUE_SHEETS_LOCALIZED = ['INTRO_', 'MW_A_', 'MW_B01_', 'MW_B
# We use a single naming for TAHOMA here because both TAHOMA18 and TAHOMA24 are used for ENDCRED.TRx
# The TRx files that are identically named to the originals are supposed to override them (needs ScummVM compatible functionality for that)
# This is so that fan made translations are supported.
# V:1.00 - Added 'SBTLVERS.TR' here to provide info for the versioning and compilation date of the Subtitles.MIX file
SUPPORTED_TRANSLATION_SHEETS = [('OPTIONS.TR', 'KIA6PT'),
('DLGMENU.TR', 'KIA6PT'),
('SCORERS.TR', 'TAHOMA'),
@ -134,14 +168,15 @@ SUPPORTED_TRANSLATION_SHEETS = [('OPTIONS.TR', 'KIA6PT'),
('KIACRED.TR', 'KIA6PT'),
('CLUETYPE.TR', 'KIA6PT'),
('ENDCRED.TR', 'TAHOMA'),
('POGO.TR', 'KIA6PT')]
('POGO.TR', 'KIA6PT'),
(SUPPORTED_DIALOGUE_VERSION_SHEET[:-1], 'KIA6PT')]
# The FON files that are identically named to the originals are supposed to override them (needs ScummVM compatible functionality for that)
# We don't deal with 10PT.FON since it's not used.
# Also we don't deal with the SYSTEM (external OS font) that ERRORMSG.TRx uses!
# TODO we probably could skip importing ERRORMSG.TRx (to SUBTITLES.MIX) altogether, since translating that has no point! In that case SYSTEM.FON should be removed from here since it's currently of no use otherwise and support for it is not really required...
# TODO we probably could skip importing ERRORMSG.TRx (to SUBTITLES.MIX) altogether, since translating that has no point! In that case SYSTEM.FON should be removed from here since it's currently of no use otherwise and support for it is not really required.
SUPPORTED_OTHER_FILES_FOR_MIX = [DEFAULT_SUBTITLES_FONT_NAME, 'KIA6PT.FON', 'TAHOMA18.FON', 'TAHOMA24.FON', 'SYSTEM.FON']
SUPPORTED_LANGUAGES_DESCRIPTION_CODE_TLIST = [('EN_ANY', 'E', 'English'), ('DE_DEU', 'G', 'German'), ('FR_FRA', 'F', 'French'), ('IT_ITA', 'I', 'Italian'), ('ES_ESP', 'S', 'Spanish'), ('RU_RUS', 'R', 'Russian')]
SUPPORTED_LANGUAGES_DESCRIPTION_CODE_TLIST = [('EN_ANY', 'E', 'English'), ('DE_DEU', 'G', 'German'), ('FR_FRA', 'F', 'French'), ('IT_ITA', 'I', 'Italian'), ('ES_ESP', 'S', 'Spanish'), ('RU_RUS', 'R', 'Russian'), ('EFIGS', '#', 'EFIGS')]
DEFAULT_LANG_DESC_CODE = SUPPORTED_LANGUAGES_DESCRIPTION_CODE_TLIST[0]
DEFAULT_TARGET_ENCODING_PER_FONT = [(SUBTITLES_FONT_NAME_CATEGORY, WINDOWS_1252_ENCODING), ('KIA6PT', 'cp437'), ('TAHOMA', 'cp437'), ('SYSTEM', 'latin-1')]
@ -411,14 +446,37 @@ def getSortMixFilesKey(item):
signedKeyTmp = ctypes.c_long(keyTmp).value
return signedKeyTmp
def getSupportedInGameQuotesSheetsList():
supportedInGameQuotesSheetsList = []
for tmpActiveLanguageDescriptionCodeTuple in SUPPORTED_LANGUAGES_DESCRIPTION_CODE_TLIST:
if (gActiveLanguageDescriptionCodeTuple[1] != '#' and tmpActiveLanguageDescriptionCodeTuple[1] == gActiveLanguageDescriptionCodeTuple[1]) \
or (gActiveLanguageDescriptionCodeTuple[1] == '#' and tmpActiveLanguageDescriptionCodeTuple[1] != '#' and tmpActiveLanguageDescriptionCodeTuple[1] != 'R'):
supportedInGameQuotesSheetsList += [(x + '%s.TR%s' % (tmpActiveLanguageDescriptionCodeTuple[1], tmpActiveLanguageDescriptionCodeTuple[1])) for x in SUPPORTED_INGAME_DIALOGUE_SHEETS]
return supportedInGameQuotesSheetsList
def getSupportedSubtitleSheetsList():
mergedListOfSupportedSubtitleSheets = []
mergedListOfSupportedSubtitleSheets += getSupportedInGameQuotesSheetsList()
mergedListOfSupportedSubtitleSheets += [(x + 'E.VQA') for x in SUPPORTED_VIDEO_DIALOGUE_SHEETS_ENGLISH]
for tmpActiveLanguageDescriptionCodeTuple in SUPPORTED_LANGUAGES_DESCRIPTION_CODE_TLIST:
if (gActiveLanguageDescriptionCodeTuple[1] != '#' and tmpActiveLanguageDescriptionCodeTuple[1] == gActiveLanguageDescriptionCodeTuple[1]) \
or (gActiveLanguageDescriptionCodeTuple[1] == '#' and tmpActiveLanguageDescriptionCodeTuple[1] != '#' and tmpActiveLanguageDescriptionCodeTuple[1] != 'R'):
mergedListOfSupportedSubtitleSheets += [(x + '%s.VQA' % (tmpActiveLanguageDescriptionCodeTuple[1])) for x in SUPPORTED_VIDEO_DIALOGUE_SHEETS_LOCALIZED]
return mergedListOfSupportedSubtitleSheets
def getSupportedTranslatedTrxFilenamesList():
listOfSupportedTranslatedTrxFilenames = []
for tmpActiveLanguageDescriptionCodeTuple in SUPPORTED_LANGUAGES_DESCRIPTION_CODE_TLIST:
if (gActiveLanguageDescriptionCodeTuple[1] != '#' and tmpActiveLanguageDescriptionCodeTuple[1] == gActiveLanguageDescriptionCodeTuple[1]) \
or (gActiveLanguageDescriptionCodeTuple[1] == '#' and tmpActiveLanguageDescriptionCodeTuple[1] != '#' and tmpActiveLanguageDescriptionCodeTuple[1] != 'R'):
for translatedTRxFileName in [ (x[0] + '%s' % (tmpActiveLanguageDescriptionCodeTuple[1])) for x in SUPPORTED_TRANSLATION_SHEETS] :
if translatedTRxFileName[:-1] != SUPPORTED_DIALOGUE_VERSION_SHEET[:-1] or tmpActiveLanguageDescriptionCodeTuple[1] == 'E':
listOfSupportedTranslatedTrxFilenames.append(translatedTRxFileName)
return listOfSupportedTranslatedTrxFilenames
#
def outputMIX():
# output file should be DEFAULT_SUBTITLES_MIX_OUTPUT_NAME
# checking with known hashes to verify calculateFoldHash
#calculateFoldHash('AR01-MIN.SET')
#calculateFoldHash('AR02-MIN.SET')
#calculateFoldHash('CLOVDIES.AUD')
#calculateFoldHash('INTRO.VQA')
print "[Info] Writing to output MIX file: %s..." % (DEFAULT_SUBTITLES_MIX_OUTPUT_NAME)
errorFound = False
@ -438,7 +496,7 @@ def outputMIX():
# 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.
# *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))
@ -461,23 +519,29 @@ def outputMIX():
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.
mergedListOfSupportedSubtitleSheets = [(x + '%s.TR%s' % (gActiveLanguageDescriptionCodeTuple[1], gActiveLanguageDescriptionCodeTuple[1])) for x in SUPPORTED_INGAME_DIALOGUE_SHEETS]
mergedListOfSupportedSubtitleSheets = mergedListOfSupportedSubtitleSheets + [(x + 'E.VQA') for x in SUPPORTED_VIDEO_DIALOGUE_SHEETS_ENGLISH]
mergedListOfSupportedSubtitleSheets = mergedListOfSupportedSubtitleSheets + [(x + '%s.VQA' % (gActiveLanguageDescriptionCodeTuple[1])) for x in SUPPORTED_VIDEO_DIALOGUE_SHEETS_LOCALIZED]
#mergedListOfSupportedSubtitleSheets = SUPPORTED_INGAME_DIALOGUE_SHEETS + SUPPORTED_VIDEO_DIALOGUE_SHEETS
mergedListOfSupportedSubtitleSheets = getSupportedSubtitleSheetsList()
if gTraceModeEnabled:
print "[Trace] mergedListOfSupportedSubtitleSheets="
print mergedListOfSupportedSubtitleSheets
for sheetDialogueName in mergedListOfSupportedSubtitleSheets:
sheetDialogueNameTRx = sheetDialogueName[:-4] + ('.TR%s' %(gActiveLanguageDescriptionCodeTuple[1]))
sheetDialogueNameTRx = sheetDialogueName
if sheetDialogueNameTRx[-4:-1] != '.TR':
tmpActiveLanguageTRxCode = sheetDialogueNameTRx[-5]
sheetDialogueNameTRx = sheetDialogueName[:-4] + ('.TR%s' %(tmpActiveLanguageTRxCode))
if os.path.isfile('./' + sheetDialogueNameTRx):
entryID = calculateFoldHash(sheetDialogueNameTRx)
mixEntryfileSizeBytes = os.path.getsize('./' + sheetDialogueNameTRx)
mixFileEntries.append((entryID, sheetDialogueNameTRx, mixEntryfileSizeBytes))
totalFilesDataSize += mixEntryfileSizeBytes
for translatedTREFileName in [ (x[0] + '%s' % (gActiveLanguageDescriptionCodeTuple[1])) for x in SUPPORTED_TRANSLATION_SHEETS] :
if os.path.isfile('./' + translatedTREFileName):
entryID = calculateFoldHash(translatedTREFileName)
mixEntryfileSizeBytes = os.path.getsize('./' + translatedTREFileName)
mixFileEntries.append((entryID, translatedTREFileName, mixEntryfileSizeBytes))
supportedTranslatedTrxFilenamesList = getSupportedTranslatedTrxFilenamesList()
for translatedTRxFileName in supportedTranslatedTrxFilenamesList:
if os.path.isfile('./' + translatedTRxFileName):
entryID = calculateFoldHash(translatedTRxFileName)
mixEntryfileSizeBytes = os.path.getsize('./' + translatedTRxFileName)
mixFileEntries.append((entryID, translatedTRxFileName, mixEntryfileSizeBytes))
totalFilesDataSize += mixEntryfileSizeBytes
for otherFileName in SUPPORTED_OTHER_FILES_FOR_MIX:
@ -550,6 +614,8 @@ def outputMIX():
# TODO all strings are NULL terminated in the TRE file!
def translateQuoteToAsciiProper(cellObj, pSheetName):
if cellObj.ctype == xlrd.XL_CELL_NUMBER:
return '%.2f' % cellObj.value
newQuoteReplaceSpecials = cellObj.value.encode("utf-8")
#if gTraceModeEnabled:
# print ('[Debug] Encoded to unicode: %s' % (newQuoteReplaceSpecials))
@ -557,10 +623,8 @@ def translateQuoteToAsciiProper(cellObj, pSheetName):
pertinentListOfOutOfOrderGlyphs = []
mergedListOfSupportedSubtitleSheets = [(x + '%s.TR%s' % (gActiveLanguageDescriptionCodeTuple[1], gActiveLanguageDescriptionCodeTuple[1])) for x in SUPPORTED_INGAME_DIALOGUE_SHEETS]
mergedListOfSupportedSubtitleSheets = mergedListOfSupportedSubtitleSheets + [(x + 'E.VQA') for x in SUPPORTED_VIDEO_DIALOGUE_SHEETS_ENGLISH]
mergedListOfSupportedSubtitleSheets = mergedListOfSupportedSubtitleSheets + [(x + '%s.VQA' % (gActiveLanguageDescriptionCodeTuple[1])) for x in SUPPORTED_VIDEO_DIALOGUE_SHEETS_LOCALIZED]
#mergedListOfSupportedSubtitleSheets = SUPPORTED_INGAME_DIALOGUE_SHEETS + SUPPORTED_VIDEO_DIALOGUE_SHEETS
mergedListOfSupportedSubtitleSheets = getSupportedSubtitleSheetsList()
supportedTranslatedTrxFilenamesList = getSupportedTranslatedTrxFilenamesList()
localTargetEncoding = ''
#if gTraceModeEnabled:
@ -579,12 +643,11 @@ def translateQuoteToAsciiProper(cellObj, pSheetName):
if tmpFontName == DEFAULT_SUBTITLES_FONT_NAME[:-4]:
pertinentListOfOutOfOrderGlyphs = tmpOOOList
break
elif pSheetName in [(x[0] + '%s' % (gActiveLanguageDescriptionCodeTuple[1])) for x in SUPPORTED_TRANSLATION_SHEETS]:
elif pSheetName in supportedTranslatedTrxFilenamesList:
pertinentFontType = ''
#[treAndFontTypeTuple for treAndFontTypeTuple in SUPPORTED_TRANSLATION_SHEETS if treAndFontTypeTuple[0] == pSheetName]
for (tmpSheetName, tmpFontType) in SUPPORTED_TRANSLATION_SHEETS:
tmpSheetName = tmpSheetName + '%s' % (gActiveLanguageDescriptionCodeTuple[1])
if tmpSheetName == pSheetName:
if tmpSheetName == pSheetName[:-1]:
pertinentFontType = tmpFontType
break
@ -630,7 +693,7 @@ def translateQuoteToAsciiProper(cellObj, pSheetName):
try:
newQuoteReplaceSpecialsRetStr = newQuoteReplaceSpecials.encode(localTargetEncoding)
except Exception as e:
print "[Error] Could not encode text::" + str(e)
print "[Error] Could not encode text in " + localTargetEncoding + "::" + str(e)
newQuoteReplaceSpecialsRetStr = "??????????"
#try:
# newQuoteReplaceSpecialsRetStr = newQuoteReplaceSpecials.encode(localTargetEncoding)
@ -698,11 +761,62 @@ def inputXLS(pathtoInputExcelFilename):
#xl_sheet = xl_workbook.sheet_by_index(0)
#
#
mergedListOfSupportedSubtitleSheets = [(x + '%s.TR%s' % (gActiveLanguageDescriptionCodeTuple[1], gActiveLanguageDescriptionCodeTuple[1])) for x in SUPPORTED_INGAME_DIALOGUE_SHEETS]
mergedListOfSupportedSubtitleSheets = mergedListOfSupportedSubtitleSheets + [(x + 'E.VQA') for x in SUPPORTED_VIDEO_DIALOGUE_SHEETS_ENGLISH]
mergedListOfSupportedSubtitleSheets = mergedListOfSupportedSubtitleSheets + [(x + '%s.VQA' % (gActiveLanguageDescriptionCodeTuple[1])) for x in SUPPORTED_VIDEO_DIALOGUE_SHEETS_LOCALIZED]
#mergedListOfSupportedSubtitleSheets = SUPPORTED_INGAME_DIALOGUE_SHEETS + SUPPORTED_VIDEO_DIALOGUE_SHEETS
mergedListOfSupportedSubtitleSheetsAndTranslatedTREs = mergedListOfSupportedSubtitleSheets + [ (x[0] + '%s' % (gActiveLanguageDescriptionCodeTuple[1])) for x in SUPPORTED_TRANSLATION_SHEETS ]
supportedInGameQuotesSheetsList = getSupportedInGameQuotesSheetsList()
mergedListOfSupportedSubtitleSheets = getSupportedSubtitleSheetsList()
supportedTranslatedTrxFilenamesList = getSupportedTranslatedTrxFilenamesList()
mergedListOfSupportedSubtitleSheetsAndTranslatedTREs = mergedListOfSupportedSubtitleSheets + supportedTranslatedTrxFilenamesList
# Check for a version info sheet and create one if it does not exist
xl_sheet = None
try:
xl_sheet = xl_workbook.sheet_by_name(SUPPORTED_DIALOGUE_VERSION_SHEET)
except Exception as e:
if gTraceModeEnabled:
print '[Debug] Could not open requested sheet: ' + SUPPORTED_DIALOGUE_VERSION_SHEET + ' in Excel::' + str(e)
if xl_sheet is None:
# we didn't find a sheet for version info, so we should auto-create a Sheet for it
if gTraceModeEnabled:
print '[Debug] Sheet: %s was not found. Creating a temporary sheet for version info...' % (SUPPORTED_DIALOGUE_VERSION_SHEET)
sbtlVersTRInstance = sbtlVersTextResource(gTraceModeEnabled)
bookCopy = copy(xl_workbook)
xl_sheet = bookCopy.add_sheet(SUPPORTED_DIALOGUE_VERSION_SHEET)
n = 0
col1_name = 'Subtitles Version Info'
xl_sheet.write(n, 0, col1_name)
# Second Row
n = 1
col1_name = 'ID'
col2_name = 'Value'
col3_name = 'Notes'
xl_sheet.write(n, 0, col1_name)
xl_sheet.write(n, 1, col2_name)
xl_sheet.write(n, 2, col3_name)
n += 1
objUTF8Unicode = None
for m, e1 in enumerate(sbtlVersTRInstance.getSbtlVersEntriesList(), n):
xl_sheet.write(m, 0, e1[0])
for i1 in range(1,3):
objStr = e1[i1]
try:
# We assume utf-8 charset (since we get the text from a python script)
objUTF8Unicode = unicode(objStr, 'utf-8')
except Exception as e:
print '[Error] Failed to create unicode string: ' + str(e)
objUTF8Unicode = unicode("???", 'utf-8')
xl_sheet.write(m, i1, objUTF8Unicode)
try:
bookCopy.save(pathtoInputExcelFilename)
except Exception as e:
print "[Error] Giving up: Could not save to output Excel file:: " + str(e)
sys.exit(1) # Terminate if we couldn't write to output Excel file
if gTraceModeEnabled:
print '[Debug] Sheet: %s was created successfully.' % (SUPPORTED_DIALOGUE_VERSION_SHEET)
inputXLS(pathtoInputExcelFilename)
return
# end of check for a version info sheet
for sheetDialogueName in mergedListOfSupportedSubtitleSheetsAndTranslatedTREs:
xl_sheet = None
@ -710,11 +824,13 @@ def inputXLS(pathtoInputExcelFilename):
xl_sheet = xl_workbook.sheet_by_name(sheetDialogueName)
except Exception as e:
if gTraceModeEnabled:
print '[Debug] Could not open requested sheet in Excel::' + str(e)
print '[Debug] Could not open requested sheet: ' + sheetDialogueName + ' in Excel::' + str(e)
if xl_sheet is None:
if (not gTraceModeEnabled) and (sheetDialogueName not in supportedTranslatedTrxFilenamesList):
print '[Warning] %s sheet was not found in input Excel file.' % (sheetDialogueName)
else: #if(xl_sheet is not None):
if xl_sheet is not None:
if gTraceModeEnabled:
print ('[Debug] Sheet name: %s' % xl_sheet.name)
gNumOfSpokenQuotes = xl_sheet.nrows - 2 # all rows minus the first TWO rows with headers
@ -738,7 +854,8 @@ def inputXLS(pathtoInputExcelFilename):
tmpStartFrame = 0 # for VQA sheets
tmpEndFrame = 0 # for VQA sheets
mode = 0 # init to unknown
if xl_sheet.name == mergedListOfSupportedSubtitleSheets[0]:
if xl_sheet.name in supportedInGameQuotesSheetsList:
if gTraceModeEnabled:
print '[Debug] IN GAME QUOTES'
mode = 1 #in-game quote
@ -746,7 +863,7 @@ def inputXLS(pathtoInputExcelFilename):
if gTraceModeEnabled:
print '[Debug] VQA SCENE DIALOGUE'
mode = 2 #VQA
elif xl_sheet.name in [ (x[0] + '%s' % (gActiveLanguageDescriptionCodeTuple[1])) for x in SUPPORTED_TRANSLATION_SHEETS ]:
elif xl_sheet.name in supportedTranslatedTrxFilenamesList:
if gTraceModeEnabled:
print '[Debug] TRANSLATED TEXT RESOURCE'
mode = 3 # Translated TRE
@ -755,16 +872,16 @@ def inputXLS(pathtoInputExcelFilename):
del gTableOfStringEntries[:]
del gTableOfStringOffsets[:]
for row_idx in range(2, xl_sheet.nrows):
#if gTraceModeEnabled:
# print "[Debug] Line %d" % (row_idx)
if gTraceModeEnabled:
print "[Debug] 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:
#if gTraceModeEnabled:
# print ('[Debug] Column: [%s] cell_obj: [%s]' % (col_idx, cell_obj))
if gTraceModeEnabled:
print ('[Debug] Column: [%s] cell_obj: [%s]' % (col_idx, cell_obj))
if(col_idx == 0):
#switchFlagShowQuote = False
twoTokensfirstColSplitAtDotXLS = cell_obj.value.split('.', 1)
@ -832,7 +949,8 @@ def inputXLS(pathtoInputExcelFilename):
# For translated TRE sheets the id is already in first column, the text is in the next one
#
elif mode == 3:
#print ('[Debug] Column: [%s] cell_obj: [%s]' % (col_idx, cell_obj))
if gTraceModeEnabled:
print ('[Debug] Column: [%s] cell_obj: [%s]' % (col_idx, cell_obj))
if(col_idx == 0):
tmpQuoteID = parseIntCellValue(cell_obj.value, row_idx, col_idx, xl_sheet.name, xl_sheet.nrows, xl_sheet.ncols)
gTableOfStringIds.append(tmpQuoteID)
@ -843,6 +961,13 @@ def inputXLS(pathtoInputExcelFilename):
# #newQuoteReplaceSpecials = cell_obj.value.decode("utf-8") # unicode(cell_obj.value, 'windows-1252')
# #print ('[Debug] decoded to unicode: %s ' % (newQuoteReplaceSpecials)) # error with char xf1
newQuoteReplaceSpecialsAscii = translateQuoteToAsciiProper(cell_obj, xl_sheet.name)
if xl_sheet.name == SUPPORTED_DIALOGUE_VERSION_SHEET:
if tmpQuoteID == 2:
#generate date timestamp
now = datetime.now()
newQuoteReplaceSpecialsAscii = now.strftime("%H:%M:%S %d/%m/%Y")
elif tmpQuoteID == 3:
newQuoteReplaceSpecialsAscii = gActiveLanguageDescriptionCodeTuple[2]
#if switchFlagShowQuote == True:
# print ('[Debug] 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
@ -866,29 +991,37 @@ def inputXLS(pathtoInputExcelFilename):
# WRITE TO TRE FILE
#
errorFound = False
outTREFile = None
outTREFileName = sheetDialogueName[:-4]
outTRxFile = None
outTRxFileName = sheetDialogueName
# this check is basically for sheets that end in .VQA, which should now end in .TRx
# ie. INTRO_E.VQA in EFIGS mode will create INTRO_E.TRE
# in FIGS mode we can't create all TRx for each one of the .VQA sheets, because
# that would be redundant rather than practical and also
# pairs (MW_B01_E.TRI, MW_C01_E.TRE), (MW_B02_E.TRI, MW_C02_E.TRE), (MW_B03_E.TRI, MW_C03_E.TRE) have the same hash, which is a problem for their indexing in the MIX file
if outTRxFileName[-4:-1] != '.TR':
tmpActiveLanguageTRxCode = outTRxFileName[-5]
outTRxFileName = sheetDialogueName[:-4] + ('.TR%s' %(tmpActiveLanguageTRxCode))
try:
outTREFile = open("./" + outTREFileName + (".TR%s" %(gActiveLanguageDescriptionCodeTuple[1])), 'wb')
outTRxFile = open("./" + outTRxFileName, 'wb')
except Exception as e:
errorFound = True
print ('[Error] Unable to write to output TR%s file:: ' %(gActiveLanguageDescriptionCodeTuple[1])) + str(e)
print ('[Error] Unable to write to output file %s:: ' %(outTRxFileName)) + str(e)
if not errorFound:
numOfSpokenQuotesToWrite = pack('I', gNumOfSpokenQuotes) # unsigned integer 4 bytes
outTREFile.write(numOfSpokenQuotesToWrite)
outTRxFile.write(numOfSpokenQuotesToWrite)
# write string IDs table
for idxe in range(0, len(gTableOfStringIds)):
idOfStringToWrite = pack('I', gTableOfStringIds[idxe]) # unsigned integer 4 bytes
outTREFile.write(idOfStringToWrite)
outTRxFile.write(idOfStringToWrite)
# write string offsets table
for idxe in range(0, len(gTableOfStringOffsets)):
offsetOfStringToWrite = pack('I', gTableOfStringOffsets[idxe]) # unsigned integer 4 bytes
outTREFile.write(offsetOfStringToWrite)
outTRxFile.write(offsetOfStringToWrite)
#write strings with null terminator
for idxe in range(0, len(gTableOfStringEntries)):
outTREFile.write(gTableOfStringEntries[idxe])
outTREFile.write('\0')
outTREFile.close()
outTRxFile.write(gTableOfStringEntries[idxe])
outTRxFile.write('\0')
outTRxFile.close()
return
#

View file

@ -0,0 +1,44 @@
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
#
my_module_version = "1.00"
my_module_name = "subtlsVersTextResource"
# Template for SBTLVERS.TRE sheet's values ((row 2 and below)
SBTLVERS_TEXT_RESOURCE_TUPLE_LIST = [
(0, "ScummVM Team", "Credits"),
(1, "2", "Version (an incremental number)"),
(2, "##:##:## ##/##/####", "Placeholder Date of compilation (HH:mm:ss dd/mm/yyyy)"),
(3, "EFIGS", "Placeholder Language mode")
]
#
#
#
class sbtlVersTextResource:
m_traceModeEnabled = True
# traceModeEnabled is bool to enable more printed debug messages
def __init__(self, traceModeEnabled = True):
self.m_traceModeEnabled = traceModeEnabled
return
def printSbtlVersTemplate(self):
for (idTre, textTre) in SBTLVERS_TEXT_RESOURCE_TUPLE_LIST:
print "%s\t%s" % (idTre, textTre)
return
def getSbtlVersEntriesList(self):
return SBTLVERS_TEXT_RESOURCE_TUPLE_LIST
if __name__ == '__main__':
# main()
print "[Debug] Running %s as main module" % (my_module_name)
traceModeEnabled = False
sbtlVersTRInstance = sbtlVersTextResource(traceModeEnabled)
sbtlVersTRInstance.printSbtlVersTemplate()
else:
#debug
#print "[Debug] Running %s imported from another module" % (my_module_name)
pass

View file

@ -7,8 +7,8 @@ FONT_OUTPUT := SUBTLS_E.FON
BLADERUNNER_SUBTITLES_SCRIPTS_ROOT_FOLDER := $(srcdir)/devtools/create_bladerunner/subtitles
BLADERUNNER_SUBTITLES_SAMPLE_INPUT_FOLDER := $(srcdir)/devtools/create_bladerunner/subtitles/sampleInput
INTERMEDIATE_RESOURCE_FILES_UI := "OPTIONS.TRE" "DLGMENU.TRE" "SCORERS.TRE" "VK.TRE" "CLUES.TRE" "CRIMES.TRE" "ACTORS.TRE" "HELP.TRE" "AUTOSAVE.TRE" "ERRORMSG.TRE" "SPINDEST.TRE" "KIA.TRE" "KIACRED.TRE" "CLUETYPE.TRE" "ENDCRED.TRE" "POGO.TRE"
INTERMEDIATE_RESOURCE_FILES_SUBS := "INGQUO_E.TRE" "WSTLGO_E.TRE" "BRLOGO_E.TRE" "INTRO_E.TRE" "MW_A_E.TRE" "MW_B01_E.TRE" "MW_B02_E.TRE" "MW_B03_E.TRE" "MW_B04_E.TRE" "MW_B05_E.TRE" "INTRGT_E.TRE" "MW_D_E.TRE" "MW_C01_E.TRE" "MW_C02_E.TRE" "MW_C03_E.TRE" "END04A_E.TRE" "END04B_E.TRE" "END04C_E.TRE" "END06_E.TRE" "END01A_E.TRE" "END01B_E.TRE" "END01C_E.TRE" "END01D_E.TRE" "END01E_E.TRE" "END01F_E.TRE" "END03_E.TRE"
INTERMEDIATE_RESOURCE_FILES_UI := OPTIONS.TR* DLGMENU.TR* SCORERS.TR* VK.TR* CLUES.TR* CRIMES.TR* ACTORS.TR* HELP.TR* AUTOSAVE.TR* ERRORMSG.TR* SPINDEST.TR* KIA.TR* KIACRED.TR* CLUETYPE.TR* ENDCRED.TR* POGO.TR* SBTLVERS.TR*
INTERMEDIATE_RESOURCE_FILES_SUBS := INGQUO_*.TR* WSTLGO_E.TR* BRLOGO_E.TR* INTRO_*.TR* MW_A_*.TR* MW_B01_*.TR* MW_B02_*.TR* MW_B03_*.TR* MW_B04_*.TR* MW_B05_*.TR* INTRGT_*.TR* MW_D_*.TR* MW_C01_*.TR* MW_C02_*.TR* MW_C03_*.TR* END04A_*.TR* END04B_*.TR* END04C_*.TR* END06_*.TR* END01A_*.TR* END01B_*.TR* END01C_*.TR* END01D_*.TR* END01E_*.TR* END01F_*.TR* END03_*.TR*
INPUT_TRANSCRIPT_FILENAME := englishTranscript.xls
INPUT_TRANSCRIPT_FILEPATH := $(BLADERUNNER_SUBTITLES_SAMPLE_INPUT_FOLDER)/$(INPUT_TRANSCRIPT_FILENAME)
@ -42,7 +42,7 @@ $(FONT_OUTPUT): $(BLADERUNNER_SUBTITLES_SAMPLE_INPUT_FOLDER)/$(INPUT_FONT_GLYPHS
# Creation of final output mix file SUBTILES.MIX
# The MIX file will pack the fonts file $(FONT_OUTPUT) as well as resources created from the transcript (EXCEL) file $(INPUT_TRANSCRIPT_FILENAME)
# The $(INPUT_TRANSCRIPT_AUX_CONF_FILENAME) file is used to configure the creation of the mix file
# This command sequence will erase any intermediate resource files (.TRE) at the end.
# This command sequence will erase any intermediate resource files (.TR*) at the end.
# The $(FONT_OUTPUT) file will not be erased.
$(TOOL_OUTPUT): $(FONT_OUTPUT) $(INPUT_TRANSCRIPT_FILEPATH) $(BLADERUNNER_SUBTITLES_SAMPLE_INPUT_FOLDER)/$(INPUT_TRANSCRIPT_AUX_CONF_FILENAME) $(BLADERUNNER_SUBTITLES_SCRIPTS_ROOT_FOLDER)/common/actornames.txt
$(info ---------)
@ -55,5 +55,5 @@ $(TOOL_OUTPUT): $(FONT_OUTPUT) $(INPUT_TRANSCRIPT_FILEPATH) $(BLADERUNNER_SUBTIT
$(info If successful, a $(TOOL_OUTPUT) file will be created in your working directory)
$(info Please, copy this $(TOOL_OUTPUT) into your Blade Runner game directory!)
$(info ---------)
$(BLADERUNNER_SUBTITLES_SCRIPTS_ROOT_FOLDER)/mixResourceCreator/mixResourceCreator.py -x $(INPUT_TRANSCRIPT_FILEPATH) -ian $(BLADERUNNER_SUBTITLES_SCRIPTS_ROOT_FOLDER)/common/actornames.txt -cft $(BLADERUNNER_SUBTITLES_SAMPLE_INPUT_FOLDER)/$(INPUT_TRANSCRIPT_AUX_CONF_FILENAME)
$(BLADERUNNER_SUBTITLES_SCRIPTS_ROOT_FOLDER)/mixResourceCreator/mixResourceCreator.py -x $(INPUT_TRANSCRIPT_FILEPATH) -ian $(BLADERUNNER_SUBTITLES_SCRIPTS_ROOT_FOLDER)/common/actornames.txt -cft $(BLADERUNNER_SUBTITLES_SAMPLE_INPUT_FOLDER)/$(INPUT_TRANSCRIPT_AUX_CONF_FILENAME) -ld EFIGS
-$(RM) $(INTERMEDIATE_RESOURCE_FILES_UI) $(INTERMEDIATE_RESOURCE_FILES_SUBS)