Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

View File

@@ -0,0 +1,227 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
ctypesLibFound = False
structLibFound = False
try:
import ctypes
except ImportError:
print ("[Error] ctypes python library is required to be installed!")
else:
ctypesLibFound = True
if (not ctypesLibFound):
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.70"
MY_MODULE_NAME = "audFileDecode"
aud_ima_index_adjust_table = [-1, -1, -1, -1, 2, 4, 6, 8]
# aud_ima_step_table has 89 entries
aud_ima_step_table = [
7, 8, 9, 10, 11, 12, 13, 14, 16,
17, 19, 21, 23, 25, 28, 31, 34, 37,
41, 45, 50, 55, 60, 66, 73, 80, 88,
97, 107, 118, 130, 143, 157, 173, 190, 209,
230, 253, 279, 307, 337, 371, 408, 449, 494,
544, 598, 658, 724, 796, 876, 963, 1060, 1166,
1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749,
3024, 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484,
7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, 15289,
16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 ]
aud_ws_step_table2 = [-2, -1, 0, 1]
aud_ws_step_table4 = [
-9, -8, -6, -5, -4, -3, -2, -1,
0, 1, 2, 3, 4, 5, 6, 8
]
# (const xccTHA::byte* audio_in, short* audio_out, int& index, int& sample, int cs_chunk)
# index and sample are passed by reference and changed here...
# audio_out is definitely affected!
def aud_decode_ima_chunk(audioBufferIn, index, sample, cs_chunk):
code = -1
delta = -1
step = -1
audioBufferOut = []
#for i in range(0, len(audioBufferIn)):
#if self.m_traceModeEnabled:
# 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 ("[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]
delta = step >> 3
if (code & 1):
delta += step >> 2
if (code & 2):
delta += step >> 1
if (code & 4):
delta += step
if (code & 8):
sample -= delta
if (sample < -32768):
sample = -32768
else:
sample += delta
if (sample > 32767):
sample = 32767
audioBufferOut.append(ctypes.c_short( sample ).value )
#audioBufferOut.append(sample) # it's not different from above... ctypes.c_short( sample ).value
#if self.m_traceModeEnabled:
# 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
elif (index > 88):
index = 88
## output buffer of shorts
#binDataOut = struct.pack('h'*len(audioBufferOut), *audioBufferOut)
#return (binDataOut, index, sample)
return (audioBufferOut, index, sample)
#
#
#
def aud_decode_clip8(v):
if (v < 0):
return 0
return 0xff if (v > 0xff) else v
#
#
#
# (const xccTHA::byte* r, char* w, int cb_s, int cb_d)
def aud_decode_ws_chunk(inputChunkBuffer, cb_s, cb_d):
outputChunkBuffer = []
inpChBuffIter = 0
outChBuffIter = 0
if (cb_s == cb_d):
# outputChunkBuffer = inputChunkBuffer[:cb_s] # memcpy(w, r, cb_s) # FIX
for mcp in range(0, cb_s):
outputChunkBuffer.append(ctypes.c_char(inputChunkBuffer[inpChBuffIter + mcp]).value)
#binDataOut = struct.pack('b'*len(outputChunkBuffer), *outputChunkBuffer)
#return binDataOut
return outputChunkBuffer
# const xccTHA::byte* s_end = inputChunkBuffer + cb_s; # FIX
s_end = inpChBuffIter + cb_s
sample = ctypes.c_int(0x80).value #int sample
while (inpChBuffIter < s_end):
inpChBuffIter += 1
count = ctypes.c_char(inputChunkBuffer[inpChBuffIter] & 0x3f).value # char count
switchKey = inputChunkBuffer[inpChBuffIter - 1] >> 6 # inputChunkBuffer[-1] # b[-1] is *(b - 1)
if switchKey == 0:
count += 1
for iter0 in range (count, 0, -1):
inpChBuffIter += 1
code = ctypes.c_int(inputChunkBuffer[inpChBuffIter]).value # int code
# assignment in C was right to left so:
# *(outputChunkBuffer++) = sample = clip8(sample + aud_ws_step_table2[code & 3])
# is:
# *(outputChunkBuffer++) = (sample = clip8(sample + aud_ws_step_table2[code & 3]))
# which is equivalent to these two commands:
# sample = clip8(sample + aud_ws_step_table2[code & 3])
# *(outputChunkBuffer++) = sample
# SO:
sample = aud_decode_clip8(sample + aud_ws_step_table2[code & 3])
outputChunkBuffer.append(ctypes.c_char(sample).value)
outChBuffIter += 1
sample = aud_decode_clip8(sample + aud_ws_step_table2[code >> 2 & 3])
outputChunkBuffer.append(ctypes.c_char(sample).value)
outChBuffIter += 1
sample = aud_decode_clip8(sample + aud_ws_step_table2[code >> 4 & 3])
outputChunkBuffer.append(ctypes.c_char(sample).value)
outChBuffIter += 1
sample = aud_decode_clip8(sample + aud_ws_step_table2[code >> 6])
outputChunkBuffer.append(ctypes.c_char(sample).value)
outChBuffIter += 1
elif switchKey == 1:
count += 1
for iter0 in range (count, 0, -1):
inpChBuffIter += 1
code = inputChunkBuffer[inpChBuffIter] # int code
sample += aud_ws_step_table4[code & 0xf]
sample = aud_decode_clip8(sample)
outputChunkBuffer.append(ctypes.c_char(sample).value)
outChBuffIter += 1
sample += aud_ws_step_table4[code >> 4]
sample = aud_decode_clip8(sample)
outputChunkBuffer.append(ctypes.c_char(sample).value)
outChBuffIter += 1
elif switchKey == 2:
if (count & 0x20):
#sample += static_cast<char>(count << 3) >> 3
#*(outputChunkBuffer++) = sample
sample += ((count & 0xFF) << 3 ) >> 3
outputChunkBuffer.append(ctypes.c_char(sample).value)
outChBuffIter += 1
else:
count += 1
# memcpy(outputChunkBuffer, inputChunkBuffer, count) # FIX
for mcp in range(0, count):
outputChunkBuffer.append(ctypes.c_char(inputChunkBuffer[inpChBuffIter + mcp]).value)
inpChBuffIter += count
outChBuffIter += count
sample = inputChunkBuffer[inpChBuffIter - 1]
else:
count += 1
# memset(outputChunkBuffer, sample, ++count)
for mst in range(0, count):
outputChunkBuffer.append(ctypes.c_char(sample).value)
outChBuffIter += count;
# output buffer of chars
#binDataOut = struct.pack('b'*len(outputChunkBuffer), *outputChunkBuffer)
#return binDataOut
return outputChunkBuffer
#
#
#
class audFileDecode(object):
m_index = -1
m_sample = -1
m_traceModeEnabled = False
# traceModeEnabled is bool to enable more printed debug messages
def __init__(self, traceModeEnabled = True, index = 0, sample = 0):
self.m_traceModeEnabled = traceModeEnabled
self.m_index = index;
self.m_sample = sample;
return
def index(self):
return self.m_index
# (const xccTHA::byte* audio_in, short* audio_out, int cs_chunk)
def decode_chunk(self, audio_in, cs_chunk):
(audio_Out, outIndex, outSample) = aud_decode_ima_chunk(audio_in, self.m_index, self.m_sample, cs_chunk)
self.m_index = outIndex
self.m_sample = outSample
return audio_Out
if __name__ == '__main__':
# main()
decodeInstance = audFileDecode()
if decodeInstance.m_traceModeEnabled:
print ("[Debug] Running %s (%s) as main module" % (MY_MODULE_NAME, MY_MODULE_VERSION))
else:
#debug
#print ("[Debug] Running %s (%s) imported from another module" % (MY_MODULE_NAME, MY_MODULE_VERSION))
pass

View File

@@ -0,0 +1,413 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
osLibFound = False
sysLibFound = False
shutilLibFound = False
waveLibFound = False
ctypesLibFound = False
structLibFound = False
try:
import os
except ImportError:
print ("[Error] os python library is required to be installed!")
else:
osLibFound = True
try:
import sys
except ImportError:
print ("[Error] sys python library is required to be installed!")
else:
sysLibFound = True
try:
import wave
except ImportError:
print ("[Error] Wave python library is required to be installed!")
else:
waveLibFound = True
try:
import struct
except ImportError:
print ("[Error] struct python library is required to be installed!")
else:
structLibFound = True
if (not osLibFound) \
or (not sysLibFound) \
or (not waveLibFound) \
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 *
MY_MODULE_VERSION = "0.90"
MY_MODULE_NAME = "audFileLib"
#constants
aud_chunk_id = 0x0000deaf
SIZE_OF_AUD_HEADER_IN_BYTES = 12
SIZE_OF_AUD_CHUNK_HEADER_IN_BYTES = 8
class AudHeader(object):
m_samplerate = 0 # Frequency // int16_t // TODO should be unsigned (?)
m_size_in = 0 # Size of file (without header) // int32_t // TODO should be unsigned (?)
m_size_out = 0 # Size of output data // int32_t // TODO should be unsigned (?)
m_flags = 0 # bit 0=stereo, bit 1=16bit // int8_t
m_compression = 0 # 1=WW compressed, 99=IMA ADPCM (0x63) // int8_t
m_populated = False
def __init__(self):
return
# The rest of the AUD files is divided in chunks.
# These are usually 512 bytes long, except for the last one.
class AudChunkHeader(object):
m_ch_size_in = 0 # Size of compressed data // int16_t // TODO should be unsigned (?)
m_ch_size_out = 0 # Size of output data // int16_t // TODO should be unsigned (?)
m_ch_id = 0x0000FFFF # Always 0x0000DEAF // int32_t
def __init__(self):
return
#
#
#
class audFile(object):
m_header = AudHeader()
m_traceModeEnabled = False
m_simpleAudioFileName = 'GENERIC.AUD'
# traceModeEnabled is bool to enable more printed debug messages
def __init__(self, traceModeEnabled = True):
self.m_simpleAudioFileName = 'GENERIC.AUD'
self.m_traceModeEnabled = traceModeEnabled
return
# std::fstream& fs, AudFileNS::pos_type startAudFilepos, AudFileNS::pos_type endAudFilepos, const std::string& filename
def export_as_wav(self, audBytesBuff, filename):
if (not self.header().m_populated):
print ("[Error] file was not loaded properly (header info missing): " + filename)
return 1
print ("[Info] Exporting to wav: " + filename)
cvirtualBinaryD = None
if self.header().m_compression > 0:
cvirtualBinaryD = self.decode(self.header().m_compression, audBytesBuff)
elif self.header().m_flags == 2: # compression 0, 16bit stereo
cbinaryDataOutLst = []
offsInAudFile = SIZE_OF_AUD_HEADER_IN_BYTES
for i in range(0, (len(audBytesBuff) - SIZE_OF_AUD_HEADER_IN_BYTES) // 2):
if (self.m_traceModeEnabled):
print ("[Trace] Reading bytes %d, %d" % (2*i, 2*i + 1))
tmpTupleL = struct.unpack_from('B', audBytesBuff, offsInAudFile)
offsInAudFile += 1
tmpTupleH = struct.unpack_from('B', audBytesBuff, offsInAudFile)
offsInAudFile += 1
cbinaryDataOutLst.append(tmpTupleL[0])
cbinaryDataOutLst.append(tmpTupleH[0])
cvirtualBinaryD = struct.pack('B'*len(cbinaryDataOutLst), *cbinaryDataOutLst)
if (not cvirtualBinaryD and (len(audBytesBuff) - SIZE_OF_AUD_HEADER_IN_BYTES) > 0):
print ("[Error] audio file could not be exported properly (0 data read): %s" % (filename))
return 1
elif (len(audBytesBuff) - SIZE_OF_AUD_HEADER_IN_BYTES) == 0:
print ("[Warning] Creating empty wav file: %s" % (filename))
cb_sample = self.get_cb_sample()
cs_remaining = self.get_c_samples()
waveWritFile = wave.open(filename, 'wb')
waveWritFile.setnchannels(self.get_c_channels())
waveWritFile.setsampwidth(cb_sample)
waveWritFile.setframerate(self.get_samplerate())
waveWritFile.setnframes(cs_remaining)
#waveWritFile.setcomptype(None, '')
waveWritFile.writeframesraw(cvirtualBinaryD)
waveWritFile.close()
# t_wav_header header;
# memset(&header, 0, sizeof(t_wav_header));
# header.file_header.id = wav_file_id; // # "RIFF"
# header.file_header.size = sizeof(header) - sizeof(header.file_header) + (cs_remaining << 1);
# header.form_type = wav_form_id; // # "WAVE"
# header.format_chunk.header.id = wav_format_id; // #"fmt "
# header.format_chunk.header.size = sizeof(header.format_chunk) - sizeof(header.format_chunk.header);
# header.format_chunk.formattag = 1;
# header.format_chunk.c_channels = 1;
# header.format_chunk.samplerate = get_samplerate();
# header.format_chunk.byterate = cb_sample * get_samplerate();
# header.format_chunk.blockalign = cb_sample;
# header.format_chunk.cbits_sample = cb_sample << 3;
# header.data_chunk_header.id = wav_data_id; # "data"
# header.data_chunk_header.size = cb_sample * cs_remaining;
# error = f.write(&header, sizeof(t_wav_header));
# return error ? error : f.write(d);
return 0 # TODO fix
def loadAudFile(self, audBytesBuff, maxLength, audFileName):
self.m_simpleAudioFileName = audFileName
offsInAudFile = 0
tmpTuple = struct.unpack_from('H', audBytesBuff, offsInAudFile)
self.header().m_samplerate = tmpTuple[0]
offsInAudFile += 2
tmpTuple = struct.unpack_from('I', audBytesBuff, offsInAudFile)
self.header().m_size_in = tmpTuple[0]
offsInAudFile += 4
tmpTuple = struct.unpack_from('I', audBytesBuff, offsInAudFile)
self.header().m_size_out = tmpTuple[0]
offsInAudFile += 4
tmpTuple = struct.unpack_from('B', audBytesBuff, offsInAudFile)
self.header().m_flags = tmpTuple[0]
offsInAudFile += 1
tmpTuple = struct.unpack_from('B', audBytesBuff, offsInAudFile)
self.header().m_compression = tmpTuple[0]
offsInAudFile += 1
if self.m_traceModeEnabled:
print ("[Debug] Sample rate: %d\tsizeIn: %d\tsizeOut: %d\tflags: %d\tcompression: %d" % (self.get_samplerate(), self.header().m_size_in, self.header().m_size_out, self.header().m_flags, self.header().m_compression))
if self.get_samplerate() < 8000 or self.get_samplerate() > 48000 or self.header().m_size_in > (maxLength - SIZE_OF_AUD_HEADER_IN_BYTES ):
print ("[Warning] Bad AUD Header info in file %s, size_in: %d, maxLen: %d" % (self.m_simpleAudioFileName, self.header().m_size_in, (maxLength - SIZE_OF_AUD_HEADER_IN_BYTES)))
if self.header().m_size_in == 0:
# handle special case where only the header of the AUD file is present and the size_in is 0.
# fill the header with "valid" info for an empty wav file
self.header().m_size_out = 0
self.header().m_samplerate = 22050
self.header().m_compression = 0
self.header().m_flags = 2
self.header().m_populated = True
return True
else:
return False
else:
if self.header().m_compression == 1:
if (self.header().m_flags != 0):
return False
elif self.header().m_compression == 0x63:
if (self.header().m_flags != 2):
return False
elif self.header().m_compression == 0: # no compression. At least some AUD files in SFX.MIX have this
if (self.header().m_flags != 2):
return False
self.header().m_populated = True
return True
# int AudFile::get_chunk_header(int i, std::fstream& fs, AudFileNS::pos_type startAudFilepos, AudFileNS::pos_type endAudFilepos, AudChunkHeader& outAudChunkHeader)
def get_chunk_header(self, chunkIdx, inAudFileBytesBuffer, inAudFileSize):
#fs.seekg(int(startAudFilepos) + int(SIZE_OF_AUD_HEADER_IN_BYTES), fs.beg);
#AudFileNS::pos_type rAudPos;
#rAudPos = fs.tellg();
outAudChunkHeader = AudChunkHeader()
rAudPos = SIZE_OF_AUD_HEADER_IN_BYTES
if (self.m_traceModeEnabled):
print ("[Trace] Getting chunk header at %d" % (rAudPos))
#AudChunkHeader tmpInremediateChunkheader;
tmpInremediateChunkheader = AudChunkHeader()
#while (i--) # value of i is decreased after checked by while loop
while(chunkIdx > 0):
chunkIdx -= 1
if (rAudPos + SIZE_OF_AUD_CHUNK_HEADER_IN_BYTES > inAudFileSize):
return (-1, rAudPos, None)
tmpAudFileOffset = rAudPos
tmpTuple = struct.unpack_from('H', inAudFileBytesBuffer, tmpAudFileOffset)
tmpInremediateChunkheader.m_ch_size_in = tmpTuple[0]
tmpAudFileOffset += 2
tmpTuple = struct.unpack_from('H', inAudFileBytesBuffer, tmpAudFileOffset)
tmpInremediateChunkheader.m_ch_size_out = tmpTuple[0]
tmpAudFileOffset += 2
tmpTuple = struct.unpack_from('I', inAudFileBytesBuffer, tmpAudFileOffset)
tmpInremediateChunkheader.m_ch_id = tmpTuple[0]
tmpAudFileOffset += 4
#fs.read((char*)&tmpInremediateChunkheader, SIZE_OF_AUD_CHUNK_HEADER_IN_BYTES);
rAudPos += SIZE_OF_AUD_CHUNK_HEADER_IN_BYTES + tmpInremediateChunkheader.m_ch_size_in
#fs.seekg(int(rAudPos), fs.beg);
if (rAudPos + SIZE_OF_AUD_CHUNK_HEADER_IN_BYTES > inAudFileSize ):
return (-1, rAudPos, None)
# write to FINAL output chunk header
tmpAudFileOffset = rAudPos
tmpTuple = struct.unpack_from('H', inAudFileBytesBuffer, tmpAudFileOffset)
outAudChunkHeader.m_ch_size_in = tmpTuple[0]
tmpAudFileOffset += 2
tmpTuple = struct.unpack_from('H', inAudFileBytesBuffer, tmpAudFileOffset)
outAudChunkHeader.m_ch_size_out = tmpTuple[0]
tmpAudFileOffset += 2
tmpTuple = struct.unpack_from('I', inAudFileBytesBuffer, tmpAudFileOffset)
outAudChunkHeader.m_ch_id = tmpTuple[0]
tmpAudFileOffset += 4
#fs.read((char*)&outAudChunkHeader, SIZE_OF_AUD_CHUNK_HEADER_IN_BYTES);
if (rAudPos + SIZE_OF_AUD_CHUNK_HEADER_IN_BYTES + outAudChunkHeader.m_ch_size_in > inAudFileSize):
return (-1, rAudPos, None)
rAudPos += SIZE_OF_AUD_CHUNK_HEADER_IN_BYTES
return (0, rAudPos, outAudChunkHeader) # //reinterpret_cast<const AudChunkHeader*>(r);
# int AudFile::get_chunk_data(int i, std::fstream& fs, int sizeToRead, AudFileNS::byte* byteChunkDataPtr)
def get_chunk_data(self, inAudFileBytesBuffer, startOffs, sizeToRead):
#fs.read((char*)byteChunkDataPtr, sizeToRead)
outChunkDataLst = []
if (self.m_traceModeEnabled):
print ("[Trace] Getting chunk data")
print ("[Trace] 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)
tmpTuple = struct.unpack_from('B', inAudFileBytesBuffer, i)
outChunkDataLst.append(tmpTuple[0])
#byteChunkDataOut = struct.pack('b'*len(outChunkDataLst), *outChunkDataLst)
#return (0, byteChunkDataOut)
return (0, outChunkDataLst)
# std::fstream& fs, AudFileNS::pos_type startAudFilepos, AudFileNS::pos_type endAudFilepos
# returned Cvirtual_binary
def decode(self, speccompression, 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)
if self.m_traceModeEnabled:
print ("[Debug] Decoding AUD file format...")
# Cvirtual_binary d;
binaryDataOutLst = []
binaryDataOutBuff = None
cb_audio = self.get_cb_sample() * self.get_c_samples() # int cb_audio - basically this should be the size_out
if speccompression == 1:
# write_start allocates space for virtualBinary
# AudFileNS::byte* w = d.write_start(cb_audio);
errGetChunk = 0 # int errGetChunk
#for (int chunk_i = 0; w != d.data_end(); chunk_i++)
chunk_i = 0
wIndex = 0
while (wIndex < cb_audio):
#AudChunkHeader out_chunk_header;
#out_chunk_header = AudChunkHeader()
(errGetChunk, bufferDataPos, out_chunk_header) = self.get_chunk_header(chunk_i, audBytesBuff, len(audBytesBuff))
if errGetChunk != 0:
if self.m_traceModeEnabled:
print ("[Trace] Error OR End file case while getting uncompressed chunk header!")
break
if self.m_traceModeEnabled:
print ("[Trace] Get uncompressed chunk header returned: %d " % (out_chunk_header.m_ch_id))
#Cvirtual_binary out_chunk_data;
#AudFileNS::byte* byteChunkDataPtr = out_chunk_data.write_start(out_chunk_header.m_ch_size_in);
(errorGCD, byteChunkDataLst) = self.get_chunk_data(audBytesBuff, bufferDataPos, out_chunk_header.m_ch_size_in)
# export decoded chunk to w (output) buffer (of CHARS) at the point where we're currently at (so append there)
decodedAudioChunkAsLst = aud_decode_ws_chunk(byteChunkDataLst, out_chunk_header.m_ch_size_in, out_chunk_header.m_ch_size_out)
binaryDataOutLst.extend(decodedAudioChunkAsLst)
wIndex += out_chunk_header.m_ch_size_out
chunk_i += 1
binaryDataOutBuff = struct.pack('b'*len(binaryDataOutLst), *binaryDataOutLst)
elif speccompression == 0x63:
decodeInstance = audFileDecode(self.m_traceModeEnabled);
#decodeInstance.init();
#AudFileNS::byte* w = d.write_start(cb_audio);
errGetChunk = 0 # int errGetChunk
# for (int chunk_i = 0; w != d.data_end(); chunk_i++)
chunk_i = 0
wIndex = 0
while (wIndex < cb_audio):
if self.m_traceModeEnabled:
print ("[Trace] 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 ("[Warning] Error OR End file case while getting COMPRESSED chunk header!")
break
if self.m_traceModeEnabled:
print ("[Trace] Get COMPRESSED chunk header returned:: headerInSize: %d headerOutSize: %d id: %d" % (out_chunk_header.m_ch_size_in, out_chunk_header.m_ch_size_out, out_chunk_header.m_ch_id))
#Cvirtual_binary out_chunk_data;
#AudFileNS::byte* byteChunkDataPtr = out_chunk_data.write_start(out_chunk_header.m_ch_size_in);
(errorGCD, byteChunkDataLst) = self.get_chunk_data(audBytesBuff, bufferDataPos, out_chunk_header.m_ch_size_in)
# export decoded chunk to w (output) buffer (of SHORTS) at the point where we're currently at (so append there)
if self.m_traceModeEnabled:
print ("[Trace] byteChunkDataLst len: %d, m_ch_size_in was: %d" % (len(byteChunkDataLst), out_chunk_header.m_ch_size_in))
# Use "//" for floor int division in decode_chunk(), since in python 3 just using "/" would result in float and that leads to error
decodedAudioChunkAsLst = decodeInstance.decode_chunk(byteChunkDataLst, (out_chunk_header.m_ch_size_out // self.get_cb_sample()));
binaryDataOutLst.extend(decodedAudioChunkAsLst)
wIndex += out_chunk_header.m_ch_size_out
if self.m_traceModeEnabled:
print ("[Trace] New Windex: %d\t cb_audio: %d" % (wIndex,cb_audio))
chunk_i += 1
binaryDataOutBuff = struct.pack('h'*len(binaryDataOutLst), *binaryDataOutLst)
if self.m_traceModeEnabled:
if binaryDataOutBuff is not None:
if self.m_traceModeEnabled:
print ("[Trace] Decoding Done.")
else: #if binaryDataOutBuff is None:
print ("[Error] Decoding yielded errors (data out buffer is null).")
return binaryDataOutBuff
def header(self):
return self.m_header
def get_c_samples(self):
# Use "//" for floor int division in return value, since in python 3 just using "/" would result in float and that leads to error
return (self.m_header.m_size_out // self.get_cb_sample())
def get_samplerate(self):
return self.m_header.m_samplerate;
# flag bit 0 is stereo(set) mono(clear)
def get_c_channels(self):
return 2 if (self.m_header.m_flags & 0x01) else 1;
# flag bit 1 is 16bit(set) 8bit (clear)
def get_cb_sample(self):
return 2 if (self.m_header.m_flags & 0x02) else 1
#
#
#
if __name__ == '__main__':
# main()
errorFound = False
# By default assumes a file of name 000000.AUD in same directory
# otherwise tries to use the first command line argument as input file
inAUDFile = None
inAUDFileName = '00000000.AUD'
if len(sys.argv[1:]) > 0 \
and os.path.isfile(os.path.join(u'.', sys.argv[1])) \
and len(sys.argv[1]) >= 5 \
and sys.argv[1][-3:].upper() == 'AUD':
inAUDFileName = sys.argv[1]
print ("[Info] Attempting to use %s as input AUD file..." % (inAUDFileName))
elif os.path.isfile(os.path.join(u'.', inAUDFileName)):
print ("[Info] Using default %s as input AUD file..." % (inAUDFileName))
else:
print ("[Error] No valid input file argument was specified and default input file %s is missing." % (inAUDFileName))
errorFound = True
if not errorFound:
try:
print ("[Info] Opening %s" % (inAUDFileName))
inAUDFile = open(os.path.join(u'.', inAUDFileName), 'rb')
except:
errorFound = True
print ("[Error] Unexpected event:", sys.exc_info()[0])
raise
if not errorFound:
allOfAudFileInBuffer = inAUDFile.read()
audFileInstance = audFile(True)
if audFileInstance.m_traceModeEnabled:
print ("[Debug] Running %s (%s) as main module" % (MY_MODULE_NAME, MY_MODULE_VERSION))
if audFileInstance.loadAudFile(allOfAudFileInBuffer, len(allOfAudFileInBuffer), inAUDFileName):
print ("[Info] Audio file (AUD) loaded successfully!")
audFileInstance.export_as_wav(allOfAudFileInBuffer, './tmp.wav')
else:
print ("[Error] Error while loading Audio file (AUD)!")
inAUDFile.close()
else:
#debug
#print ("[Debug] Running %s (%s) imported from another module" % (MY_MODULE_NAME, MY_MODULE_VERSION))
pass

View File

@@ -0,0 +1,104 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
MY_MODULE_VERSION = "1.10"
MY_MODULE_NAME = "devCommentaryText"
# All game versions should have the English text pre-filled in the POGO sheet
DEV_AUDIO_COMMENTARY_TUPLE_LIST = [
("MA04VO1A.AUD", "*McCoy's apartment*"),
("CT01VO1A.AUD", "*Chinatown*"),
("HC01VO1A.AUD", "*Hawker's Circle*")
]
EXTRA_SPEECH_AUDIO_TUPLE_LIST = [
('COLONY.AUD', "*Blimp Guy talk*"),
('67_0470R.AUD', "*Crowd talk*"),
('67_0480R.AUD', "*Crowd talk*"),
('67_0500R.AUD', "*Crowd talk*"),
('67_0540R.AUD', "*Crowd talk*"),
('67_0560R.AUD', "*Crowd talk*"),
('67_0870R.AUD', "*Crowd talk*"),
('67_0880R.AUD', "*Crowd talk*"),
('67_0900R.AUD', "*Crowd talk*"),
('67_0940R.AUD', "*Crowd talk*"),
('67_0960R.AUD', "*Crowd talk*"),
('67_1070R.AUD', "*Crowd talk*"),
('67_1080R.AUD', "*Crowd talk*"),
('67_1100R.AUD', "*Crowd talk*"),
('67_1140R.AUD', "*Crowd talk*"),
('67_1160R.AUD', "*Crowd talk*")
]
# we use the spoken quote id that triggers the comment as an ID for the DEV commentary quote
# Ids 00-9990 and above correspond to clicks or other transitions (no corresponding spoken in-game quote)
DEV_ISEZ_QUOTES_TUPLE_LIST = [
("IS-00-9990.AUD", "Blade Runner\nFrom the dark recesses of David Leary's imagination comes a game unlike any\nother. Blade Runner immerses you in the underbelly of future Los Angeles. Right\nfrom the start, the story pulls you in with graphic descriptions of a\ngrandmother doing the shimmy in her underwear, child molestation, brutal\ncold-blooded slaying of innocent animals, vomiting on desks, staring at a\nwoman's ass, the list goes on. And when the game starts, the real fun begins -\nshoot down-on-their-luck homeless people and toss them into a dumpster. Watch\nwith sadistic glee as a dog gets blown into chunky, bloody, bits by an\nexplosive, and even murder a shy little girl who loves you. If you think David\nLeary is sick, and you like sick, this is THE game for you.\n\nJW: Don't forget the wasting of helpless mutated cripples in the underground.\nIt's such a beautiful thing!\n\nDL: Go ahead. Just keep beating that snarling pit bull...ignore the foam\naround his jaws. There's room on the top shelf of my fridge for at least one\nmore head... - Psychotic Dave\n"),
("IS-99-1860.AUD", "MG: Is David Leary a self-respecting human or is he powered by rechargeable\nBatteries?"), # voice-over
("IS-99-1890.AUD", "JM: That McCoy--he's one funny guy! Jet-black fire truck, hehehehe..."), # voice-over
("IS-23-0130.AUD", "JM: Did it have a huge, ugly piece of chrome on it?"), # Officer Leary
("IS-23-0090.AUD", "JM: This officer has a talent for vivid metaphors."), # Officer Leary
("IS-00-4540.AUD", "DL: What is that supposed to mean? I didn't write this line..."),
("IS-00-4515.AUD", "MG: Hey, leave that officer alone. Can't you see he's busy?\nJM: (...mmm, donuts...)"), # clicking on Leary after we get his statement
("IS-23-0060.AUD", "MG: It's all fun and games until someone loses a tiger cub."), # Officer Leary
("IS-00-9991.AUD", "JM: Chrome...is that what that is?"), # pick up chrome
("IS-00-4510.AUD", "JM: It's hard to imagine that thing on either a car or a horse.\nMG: McCoy! What a witty chap...\nJM: He keeps me chuckling non-stop!"),
("IS-00-9992.AUD", "MG: Leaving already? The fun is just beginning!"), # leaving Runciter's zoo with Spinner
("IS-00-4500.AUD", "MG: We don't want any of that abstract art oozing out onto the street.")
]
#
#
#
class devCommentaryText(object):
m_traceModeEnabled = True
# traceModeEnabled is bool to enable more printed debug messages
def __init__(self, traceModeEnabled = True):
self.m_traceModeEnabled = traceModeEnabled
return
def printTexts(self):
if self.m_traceModeEnabled:
print ("[Trace] Printing all dev commentary text")
print ("\nAUDIO COMMENTARY")
print ("------------------")
for (idTre, textTre) in DEV_AUDIO_COMMENTARY_TUPLE_LIST:
print ("%s\t%s" % (idTre, textTre))
print ("\nEXTRA SPEECH AUDIO")
print ("------------------")
for (idTre, textTre) in EXTRA_SPEECH_AUDIO_TUPLE_LIST:
print ("%s\t%s" % (idTre, textTre))
print ("\nI_SEZ QUOTES")
print ("------------------")
for (idTre, textTre) in DEV_ISEZ_QUOTES_TUPLE_LIST:
print ("%s\t%s" % (idTre, textTre))
return
def getAudioCommentaryTextEntriesList(self):
if self.m_traceModeEnabled:
print ("[Trace] getAudioCommentaryTextEntriesList")
return DEV_AUDIO_COMMENTARY_TUPLE_LIST
def getISEZTextEntriesList(self):
if self.m_traceModeEnabled:
print ("[Trace] getISEZTextEntriesList")
return DEV_ISEZ_QUOTES_TUPLE_LIST
def getExtraSpeechAudioEntriesList(self):
if self.m_traceModeEnabled:
print ("[Trace] getExtraSpeechAudioEntriesList")
return EXTRA_SPEECH_AUDIO_TUPLE_LIST
#
#
#
if __name__ == '__main__':
# main()
print ("[Debug] Running %s (%s) as main module" % (MY_MODULE_NAME, MY_MODULE_VERSION))
traceModeEnabled = False
devCommentaryTextInstance = devCommentaryText(traceModeEnabled)
devCommentaryTextInstance.printTexts()
else:
#debug
#print ("[Debug] Running %s (%s) imported from another module" % (MY_MODULE_NAME, MY_MODULE_VERSION))
pass

View File

@@ -0,0 +1,203 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
MY_MODULE_VERSION = "1.10"
MY_MODULE_NAME = "pogoTextResource"
# All game versions should have the English text pre-filled in the POGO sheet
POGO_TEXT_RESOURCE_TUPLE_LIST = [
(0, "Air Conditioning"),
(1, "Amy Shoopman"),
(2, "Andy B. and the Milk Carton Kids"),
(3, "Area 51"),
(4, "Aspirin"),
(5, "Babylon 5"),
(6, "Bandit"),
(7, "Bauer Inline Skates"),
(8, "Bill Randolph"),
(9, "Bill (Mr. Motorola) and Sarah"),
(10, "Boo Berry and Frankenberry"),
(11, "Brett W. Sperry"),
(12, "Brianhead Ski Resort"),
(13, "Bubba"),
(14, "Bubbles"),
(15, "Building 2 Parking"),
(16, "The Buke"),
(17, "Chan \"The Emporer\" Lee"),
(18, "Cheezy Poofs"),
(19, "Chuck \"Walter\" Karras"),
(20, "Cinco De Mayo"),
(21, "Club Med"),
(22, "Code Complete"),
(23, "Coffee Pub, Las Vegas"),
(24, "Coke"),
(25, "Coin Magic"),
(26, "Count Chocula"),
(27, "Dad"),
(28, "David Arkenstone"),
(29, "Digital Camera"),
(30, "Direct X Team"),
(31, "Denis and Joanne Dyack"),
(32, "Blue Bayou, Disneyland"),
(33, "Dongle-Boy"),
(34, "Doves and Sparrows"),
(35, "Dovey"),
(36, "Draracles"),
(37, "Dry Air"),
(38, "Ed Del Castillo"),
(39, "Eric \"Kick Ass\" Cartman"),
(40, "FHM"),
(41, "Fog City Diner"),
(42, "Fog Studios"),
(43, "Gatorade"),
(44, "Gandhi Cuisine of India"),
(45, "Giant Lava Lamp"),
(46, "Eric and Nancy Gooch"),
(47, "Grayford Family"),
(48, "Comet Hale-Bopp"),
(49, "Joseph B. Hewitt IV"),
(50, "Hercules"),
(51, "Hillbilly Jeopardy"),
(52, "Home Cookin'"),
(53, "Hooey Stick"),
(54, "The Hypnotist"),
(55, "Insects on the Move"),
(56, "Intel"),
(57, "James Hong"),
(58, "Jasmine"),
(59, "The Mysterious Cockatiel"),
(60, "Joe's Frog"),
(61, "Jed"),
(62, "Jeeps"),
(63, "Jeeter"),
(64, "Jeff Brown"),
(65, "JoeB"),
(66, "Joe-Bob McClintock"),
(67, "Joseph Turkel"),
(68, "Jose Cuervo"),
(69, "Juggling Balls"),
(70, "Keith Parkinson"),
(71, "Khan"),
(72, "King of the Hill"),
(73, "Kurt O. and the Toothbrush Squad"),
(74, "Leonard and Shirley Legg"),
(75, "Leroy"),
(76, "Brion James"),
(77, "Louis and his \"friend\""),
(78, "M.C. Crammer and Janie"),
(79, "Men's Room Magna-Doodle"),
(80, "Mark and Deepti Rowland"),
(81, "Metro Pizza, Las Vegas"),
(82, "Matt Vella"),
(83, "Maui"),
(84, "1 Million Candlepower Spotlight"),
(85, "Mom"),
(86, "Movie-makers"),
(87, "Mr. Nonsense"),
(88, "Needles"),
(89, "Nerf Weaponry"),
(90, "Nimbus"),
(91, "Norm Vordahl"),
(92, "KNPR"),
(93, "Olive Garden"),
(94, "Onkyo"),
(95, "Orangey"),
(96, "Osbur, the Human Resource Manager"),
(97, "Our Cheery Friend Leary"),
(98, "Ousted Gnome King"),
(99, "Pepsi"),
(100, "Peta Wilson"),
(101, "Pogo the Mockingbird"),
(102, "Poker Nights"),
(103, "Pirates"),
(104, "Playmate Lingerie Calendar"),
(105, "Pop-Ice"),
(106, "Powerhouse Gym"),
(107, "Rade McDowell"),
(108, "Red Rock Canyon"),
(109, "Refrigeration"),
(110, "Rhoda"),
(111, "Richard and Kimberly Weier"),
(112, "Ridley Scott"),
(113, "Ruud the Dude"),
(114, "Our old pal Rick Parks"),
(115, "Ruby's Diner"),
(116, "Savatage"),
(117, "Scully and Mulder"),
(118, "Sean Young"),
(119, "Seinfeld"),
(120, "The Shadow"),
(121, "Shakes"),
(122, "Shorts"),
(123, "Silly Putty"),
(124, "The Simpsons"),
(125, "Thomas Christensen"),
(126, "We love you Steve Wetherill!!!"),
(127, "Skank"),
(128, "Slice"),
(129, "SSG"),
(130, "Steve and Anne Tall"),
(131, "South Park"),
(132, "Snap 'n Pops"),
(133, "Sneaker"),
(134, "Star Wars Trilogy"),
(135, "Nonstop Summer Pool Parties"),
(136, "Sunsets"),
(137, "T-Bone and Angie"),
(138, "T-shirts"),
(139, "Julio Schembari, Tango Pools"),
(140, "The Thermostat Key"),
(141, "The Wizard"),
(142, "Tomb Raider"),
(143, "Tom Elmer II"),
(144, "Tujia Linden"),
(145, "Turbo"),
(146, "Tweeter"),
(147, "Twonky"),
(148, "Ty and Judy Coon"),
(149, "The Courtyard"),
(150, "U.F.C."),
(151, "Uli Boehnke"),
(152, "Virgil"),
(153, "Virtual Boy"),
(154, "Westwood Offroad Excursion Team"),
(155, "William Sanderson"),
(156, "Xena"),
(157, "Zion National Park"),
(158, "We 3 coders give special thanks to:")
]
class pogoTextResource(object):
m_traceModeEnabled = True
# traceModeEnabled is bool to enable more printed debug messages
def __init__(self, traceModeEnabled = True):
self.m_traceModeEnabled = traceModeEnabled
return
def printPogo(self):
if self.m_traceModeEnabled:
print ("[Trace] printing Pogo...")
for (idTre, textTre) in POGO_TEXT_RESOURCE_TUPLE_LIST:
print ("%s\t%s" % (idTre, textTre))
return
def getPogoEntriesList(self):
if self.m_traceModeEnabled:
print ("[Trace] getPogoEntriesList()")
return POGO_TEXT_RESOURCE_TUPLE_LIST
#
#
#
if __name__ == '__main__':
# main()
print ("[Debug] Running %s (%s) as main module" % (MY_MODULE_NAME, MY_MODULE_VERSION))
traceModeEnabled = False
pogoTRInstance = pogoTextResource(traceModeEnabled)
pogoTRInstance.printPogo()
else:
#debug
#print ("[Debug] Running %s (%s) imported from another module" % (MY_MODULE_NAME, MY_MODULE_VERSION))
pass

View File

@@ -0,0 +1,17 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
sysLibFound = False
try:
import sys
except ImportError:
print ("[Error] sys python library is required to be installed!")
else:
sysLibFound = True
if (not sysLibFound):
sys.stdout.write("[Error] Errors were found when trying to import required python libraries\n")
sys.exit(1)
import sortBladeRunnerWavs02
if __name__ == "__main__":
sortBladeRunnerWavs02.main(sys.argv[0:])

View File

@@ -0,0 +1,75 @@
Id Short ActorDesc #skip first row
0 MCCOY McCoy
1 STEEL Steele
2 GORDO Gordo
3 DEKTO Dektora
4 GUZZA Guzza
5 CLOVI Clovis
6 LLUCY Lucy
7 IIIZO Izo
8 SADIK Sadik
9 CRAZY Crazylegs
10 LUTHE Luther
11 GRIGO Grigorian
12 TRANS Transient
13 LANCE Lance
14 BBBOB Bullet Bob
15 RUNCI Runciter
16 INSEC Insect Dealer
17 TGUAR Tyrell Guard
18 EARLQ Early Q
19 ZUBEN Zuben
20 HASAN Hasan
21 MARCU Marcus
22 MMMIA Mia
23 OLEAR Officer Leary
24 OGRAY Officer Grayford
25 HANOI Hanoi
26 BAKER Baker
27 DCLER Desk Clerk
28 HOWIE Howie Lee
29 FISHD Fish Dealer
30 KLEIN Klein
31 MURRA Murray
32 HBARK Hawker's Barkeep
33 HOLLO Holloway
34 SWALL Sergeant Walls
35 MORAJ Moraji
36 TBARD The Bard
37 PHOTG Photographer
38 DISPA Dispatcher
39 ANSWM Answering Machine
40 RAJIF Rajif
41 GKOLV Governor Kolvig
42 ERLQB Early Q Bartender
43 HPARR Hawker's Parrot
44 TAFPA Taffy Patron
45 LOCGU Lockup Guard
46 TEENA Teenager
47 HPATA Hysteria Patron A
48 HPATB Hysteria Patron B
49 HPATC Hysteria Patron C
50 SHOES Shoeshine Man
51 TYREL Tyrell
52 CCHEW Chew
53 GGAFF Gaff
54 BRYAN Bryant
55 TAFFY Taffy
56 SEBAS Sebastian
57 RACHA Rachael
58 GDOLL General Doll
59 ISABE Isabella
60 BLIMP Blimp Guy
61 NEWSC Newscaster
62 LLEON Leon
63 MALAN Male Announcer
64 FREEA Free Slot A
65 FREEB Free Slot B
66 MAGGI Maggie
67 ACTGA Actor Genwalker A
68 ACTGB Actor Genwalker B
69 ACTGC Actor Genwalker C
70 MUTAA Mutant A
71 MUTAB Mutant B
72 MUTAC Mutant C
99 MAINF Mainframe

View File

@@ -0,0 +1,9 @@
python2.7 quoteSpreadsheetCreator.py -op /d/BladeRunnerLPBackup/ENG_data/WAV -ip "/d/Westwood/BladeRunnerENG" -ian ../common/actornames.txt -ld EN_ANY -xtre -xwav -xpogo -xdevs --trace
python2.7 quoteSpreadsheetCreator.py -op /D/BladeRunnerLPBackup/DEU_data/WAV -ip "/d/Westwood/BladeRunnerDEU" -ian ../common/actornames.txt -ld DE_DEU -xtre -xwav -xpogo -xdevs
python2.7 quoteSpreadsheetCreator.py -op /D/BladeRunnerLPBackup/FRA_data/WAV -ip "/d/Westwood/BladeRunnerFRA" -ian ../common/actornames.txt -ld FR_FRA -xtre -xwav -xpogo -xdevs
python2.7 quoteSpreadsheetCreator.py -op /D/BladeRunnerLPBackup/ITA_data/WAV -ip "/d/Westwood/BladeRunnerIT" -ian ../common/actornames.txt -ld IT_ITA -xtre -xwav -xpogo -xdevs
python2.7 quoteSpreadsheetCreator.py -op /D/BladeRunnerLPBackup/ESP_data/WAV -ip "/d/Westwood/BladeRunnerESP" -ian ../common/actornames.txt -ld ES_ESP -xtre -xwav -xpogo -xdevs

View File

@@ -0,0 +1,181 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
osLibFound = False
sysLibFound = False
shutilLibFound = False
structLibFound = False
try:
import os
except ImportError:
print ("[Error] os python library is required to be installed!")
else:
osLibFound = True
try:
import sys
except ImportError:
print ("[Error] sys python library is required to be installed!")
else:
sysLibFound = True
try:
import struct
except ImportError:
print ("[Error] struct python library is required to be installed!")
else:
structLibFound = True
if (not osLibFound) \
or (not sysLibFound) \
or (not structLibFound):
sys.stdout.write("[Error] Errors were found when trying to import required python libraries\n")
sys.exit(1)
pathToParent = os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir)
pathToCommon = os.path.join(pathToParent, "common")
sys.path.append(pathToCommon)
from struct import *
from pythonCompat import *
MY_MODULE_VERSION = "0.70"
MY_MODULE_NAME = "treFileLib"
class TreHeader(object):
numOfTextResources = -1
def __init__(self):
return
class treFile(object):
m_header = TreHeader()
simpleTextResourceFileName = 'GENERIC.TRE'
stringEntriesLst = [] # list of two-value tuples. First value is ID, second value is String content
stringOffsets = []
m_traceModeEnabled = False
# traceModeEnabled is bool to enable more printed debug messages
def __init__(self, traceModeEnabled = True):
del self.stringEntriesLst[:]
del self.stringOffsets[:]
self.simpleTextResourceFileName = 'GENERIC.TRE'
self.m_traceModeEnabled = traceModeEnabled
return
def loadTreFile(self, treBytesBuff, maxLength, treFileName):
self.simpleTextResourceFileName = treFileName
offsInTreFile = 0
#
# parse TRE file fields for header
#
try:
tmpTuple = struct.unpack_from('I', treBytesBuff, offsInTreFile) # unsigned integer 4 bytes
self.header().numOfTextResources = tmpTuple[0]
offsInTreFile += 4
#
# string IDs table (each entry is unsigned integer 4 bytes)
#
if self.m_traceModeEnabled:
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], '') )
offsInTreFile += 4
# string offsets table (each entry is unsigned integer 4 bytes)
for idx in range(0, self.header().numOfTextResources):
tmpTuple = struct.unpack_from('I', treBytesBuff, offsInTreFile) # unsigned integer 4 bytes
self.stringOffsets.append( tmpTuple[0] )
offsInTreFile += 4
#
# strings (all entries are null terminated)
# TODO +++
absStartOfIndexTable = 4
#absStartOfOffsetTable = absStartOfIndexTable + (self.header().numOfTextResources * 4)
#absStartOfStringTable = absStartOfOffsetTable + ((self.header().numOfTextResources+1) * 4)
#print ("[Debug] buffer type: ", type(treBytesBuff)) # it is str
for idx in range(0, self.header().numOfTextResources):
currOffset = self.stringOffsets[idx] + absStartOfIndexTable
# the buffer (treBytesBuff) where we read the TRE file into, is "str" type but contains multiple null terminated strings
# the solution here (to not get out of index errors when reading the null terminator points) is
# to split the substring starting at the indicated offset each time, at the null character, and get the first string token.
# This works ok.
#
print (treBytesBuff[currOffset:])
if sys.version_info[0] <= 2:
allTextsFound = treBytesBuff[currOffset:].split('\x00')
else:
allTextsFound = treBytesBuff[currOffset:].split(b'\0')
print (allTextsFound[0])
### check "problematic" character cases:
##if self.m_traceModeEnabled:
## if currOffset == 5982 or currOffset == 6050 or currOffset == 2827 or currOffset == 2880:
## print ("[Debug] Offs: %d\tFound String: %s" % (currOffset, ''.join(allTextsFound[0]) ))
(theId, stringOfIdx) = self.stringEntriesLst[idx]
if sys.version_info[0] <= 2:
self.stringEntriesLst[idx] = (theId, ''.join(allTextsFound[0]))
else:
self.stringEntriesLst[idx] = (theId, allTextsFound[0])
if self.m_traceModeEnabled:
if sys.version_info[0] <= 2:
print ("[Trace] ID: %d\tFound String: %s" % (theId, ''.join(allTextsFound[0]) ))
else:
print ("[Trace] ID: %d\tFound String: %s" % (theId, allTextsFound[0] ))
return True
except Exception as e:
print ("[Error] Loading Text Resource %s failed!" % (self.simpleTextResourceFileName) + " " + str(e))
return False
def header(self):
return self.m_header
#
#
#
if __name__ == '__main__':
# main()
errorFound = False
# By default assumes a file of name ACTORS.TRE in same directory
# otherwise tries to use the first command line argument as input file
inTREFile = None
inTREFileName = 'ACTORS.TRE'
if len(sys.argv[1:]) > 0 \
and os.path.isfile(os.path.join(u'.', sys.argv[1])) \
and len(sys.argv[1]) >= 5 \
and sys.argv[1][-3:].upper() == 'TRE':
inTREFileName = sys.argv[1]
print ("[Info] Attempting to use %s as input TRE file..." % (inTREFileName))
elif os.path.isfile(os.path.join(u'.', inTREFileName)):
print ("[Info] Using default %s as input TRE file..." % (inTREFileName))
else:
print ("[Error] No valid input file argument was specified and default input file %s is missing." % (inTREFileName))
errorFound = True
if not errorFound:
try:
print ("[Info] Opening %s" % (inTREFileName))
inTREFile = open(os.path.join(u'.', inTREFileName), 'rb')
except:
errorFound = True
print ("[Error] Unexpected event: ", sys.exc_info()[0])
raise
if not errorFound:
allOfTreFileInBuffer = inTREFile.read()
treFileInstance = treFile(True)
if treFileInstance.m_traceModeEnabled:
print ("[Debug] Running %s (%s) as main module" % (MY_MODULE_NAME, MY_MODULE_VERSION))
if treFileInstance.loadTreFile(allOfTreFileInBuffer, len(allOfTreFileInBuffer), inTREFileName):
print ("[Info] Text Resource file loaded successfully!")
else:
print ("[Error] Error while loading Text Resource file!")
inTREFile.close()
else:
#debug
#print ("[Debug] Running %s (%s) imported from another module" % (MY_MODULE_NAME, MY_MODULE_VERSION))
pass