def __init__(self): """ Creates a completely new NSMBU area """ super().__init__() # Default area number self.areanum = 1 # Default tileset names for NSMBU self.tileset0 = 'Pa0_jyotyu' self.tileset1 = '' self.tileset2 = '' self.tileset3 = '' self.blocks = [b''] * 15 self.blocks[4] = (to_bytes(0, 8) + to_bytes(0x426C61636B, 5) + to_bytes(0, 15)) # Settings self.eventBits32 = 0 self.eventBits64 = 0 self.wrapFlag = False self.unkFlag1 = False self.timelimit = 400 self.unkFlag2 = True self.unkFlag3 = True self.unkFlag4 = True self.startEntrance = 0 self.startEntranceCoinBoost = 0 self.timelimit2 = 300 self.timelimit3 = 0 # Lists of things self.entrances = [] self.sprites = [] self.bounding = [] self.bgs = [] self.zones = [] self.locations = [] self.pathdata = [] self.nPathdata = [] self.paths = [] self.nPaths = [] self.comments = [] self.layers = [[], [], []] # Metadata self.LoadMiyamotoInfo(None) # BG data self.bgCount = 1 self.bgs = {} self.bgblockid = [] bg = struct.unpack('>HxBxxxx16sxBxx', self.blocks[4]) self.bgblockid.append(bg[0]) self.bgs[bg[0]] = bg
def SaveSprites(self): """ Saves the sprites back to block 8 """ offset = 0 sprstruct = struct.Struct('>HHH10sBB3sxxx') buffer = bytearray((len(self.sprites) * 24) + 4) f_int = int for sprite in self.sprites: try: sprstruct.pack_into( buffer, offset, f_int(sprite.type), f_int(sprite.objx), f_int(sprite.objy), sprite.spritedata[:10], SLib.MapPositionToZoneID(self.zones, sprite.objx, sprite.objy, True), 0, sprite.spritedata[10:] + to_bytes(0, 1)) except struct.error: # Hopefully this will solve the mysterious bug, and will # soon no longer be necessary. raise ValueError('SaveSprites struct.error. Current sprite data dump:\n' + \ str(offset) + '\n' + \ str(sprite.type) + '\n' + \ str(sprite.objx) + '\n' + \ str(sprite.objy) + '\n' + \ str(sprite.spritedata[:6]) + '\n' + \ str(sprite.zoneID) + '\n' + \ str(bytes([sprite.spritedata[7], ])) + '\n', ) offset += 24 buffer[offset] = 0xFF buffer[offset + 1] = 0xFF buffer[offset + 2] = 0xFF buffer[offset + 3] = 0xFF self.blocks[7] = bytes(buffer)
def test_to_bytes(): dataset = { "some": b"some", 1: 1, } for x, y in dataset.items(): got = to_bytes(x) assert got == y, f"x {x} change to {got}, while {y} expected"
def LoadSprites(self): """ Loads block 8, the sprites """ spritedata = self.blocks[7] sprcount = len(spritedata) // 24 sprstruct = struct.Struct('>HHHHIIxx2sxxxx') offset = 0 sprites = [] unpack = sprstruct.unpack_from append = sprites.append obj = SpriteItem for i in range(sprcount): data = unpack(spritedata, offset) append(obj(data[0], data[1], data[2], to_bytes(data[3], 2) + to_bytes(data[4], 4) + to_bytes(data[5], 4) + data[6])) offset += 24 self.sprites = sprites
def STMtoSTM(f, magic, dest, dest_bom): outputBuffer = bytearray(len(f)) pos = 0 if f[4:6] == b'\xFF\xFE': bom = '<' elif f[4:6] == b'\xFE\xFF': bom = '>' else: print("\nInvalid BOM!") print("\nExiting in 5 seconds...") time.sleep(5) sys.exit(1) if not dest_bom: if dest in ["FSTM", "FSTP"]: dest_bom = '>' else: dest_bom = '<' header = Header(bom) header.data(f, pos) curr = magic dest_ver = {"FSTM": 0x40000, "CSTM": 0x2020000, "FSTP": 0x20100} if magic == dest: dest_ver[dest] = header.version outputBuffer[pos:pos + header.size] = bytes( Header(dest_bom).pack(to_bytes(dest, 4), header.size_, dest_ver[dest], header.fileSize, header.numBlocks, header.reserved)) outputBuffer[4:6] = (b'\xFE\xFF' if dest_bom == '>' else b'\xFF\xFE') pos += header.size dest_type = {"FSTM": 0x4002, "CSTM": 0x4002, "FSTP": 0x4004} sized_refs = {} for i in range(1, header.numBlocks + 1): sized_refs[i] = Ref(bom) sized_refs[i].data(f, pos + 12 * (i - 1)) if sized_refs[i].type_ in [0x4002, 0x4004]: outputBuffer[pos + 12 * (i - 1):pos + 12 * (i - 1) + sized_refs[i].size] = bytes( Ref(dest_bom).pack(dest_type[dest], sized_refs[i].offset)) else: outputBuffer[pos + 12 * (i - 1):pos + 12 * (i - 1) + sized_refs[i].size] = bytes( Ref(dest_bom).pack(sized_refs[i].type_, sized_refs[i].offset)) sized_refs[i].block_size = struct.unpack( bom + "I", f[pos + 12 * (i - 1) + 8:pos + 12 * i])[0] outputBuffer[pos + 12 * (i - 1) + 8:pos + 12 * i] = to_bytes( sized_refs[i].block_size, 4, dest_bom) if sized_refs[1].type_ != 0x4000 or sized_refs[1].offset in [0, -1]: print("\nSomething went wrong!\nError code: 1") print("\nExiting in 5 seconds...") time.sleep(5) sys.exit(1) pos = sized_refs[1].offset info = BLKHeader(bom) info.data(f, pos) outputBuffer[pos:pos + info.size] = bytes( BLKHeader(dest_bom).pack(info.magic, info.size_)) pos += info.size stmInfo_ref = Ref(bom) stmInfo_ref.data(f, pos) outputBuffer[pos:pos + stmInfo_ref.size] = bytes( Ref(dest_bom).pack(stmInfo_ref.type_, stmInfo_ref.offset)) if stmInfo_ref.type_ != 0x4100 or stmInfo_ref.offset in [0, -1]: print("\nSomething went wrong!\nError code: 2") print("\nExiting in 5 seconds...") time.sleep(5) sys.exit(1) stmInfo_ref.pos = pos pos += stmInfo_ref.size trkInfoTable_ref = Ref(bom) trkInfoTable_ref.data(f, pos) outputBuffer[pos:pos + trkInfoTable_ref.size] = bytes( Ref(dest_bom).pack(trkInfoTable_ref.type_, trkInfoTable_ref.offset)) if trkInfoTable_ref.type_ not in [0x0101, 0]: print("\nSomething went wrong!\nError code: 3") print("\nExiting in 5 seconds...") time.sleep(5) sys.exit(1) pos += trkInfoTable_ref.size channelInfoTable_ref = Ref(bom) channelInfoTable_ref.data(f, pos) outputBuffer[pos:pos + channelInfoTable_ref.size] = bytes( Ref(dest_bom).pack(channelInfoTable_ref.type_, channelInfoTable_ref.offset)) if channelInfoTable_ref.type_ != 0x0101: print("\nSomething went wrong!\nError code: 4") print("\nExiting in 5 seconds...") time.sleep(5) sys.exit(1) pos = stmInfo_ref.offset + stmInfo_ref.pos stmInfo = STMInfo(bom) stmInfo.data(f, pos) outputBuffer[pos:pos + stmInfo.size] = bytes( STMInfo(dest_bom).pack( stmInfo.codec, stmInfo.loop_flag, stmInfo.count, stmInfo.sample, stmInfo.loop_start, stmInfo.loop_end, stmInfo.sampleBlk_count, stmInfo.sampleBlk_size, stmInfo.sampleBlk_sampleCount, stmInfo.lSampleBlk_size, stmInfo.lSampleBlk_sampleCount, stmInfo.lSampleBlk_padSize, stmInfo.seek_size, stmInfo.SISC)) pos += stmInfo.size sampleData_ref = Ref(bom) sampleData_ref.data(f, pos) outputBuffer[pos:pos + sampleData_ref.size] = bytes( Ref(dest_bom).pack(sampleData_ref.type_, sampleData_ref.offset)) pos += 8 trkInfoTable = {} trkInfo = {} if trkInfoTable_ref.offset not in [0, -1]: pos = trkInfoTable_ref.offset + stmInfo_ref.pos count = struct.unpack(bom + "I", f[pos:pos + 4])[0] outputBuffer[pos:pos + 4] = to_bytes(count, 4, dest_bom) pos += 4 for i in range(1, count + 1): pos = trkInfoTable_ref.offset + stmInfo_ref.pos + 4 trkInfoTable[i] = Ref(bom) trkInfoTable[i].data(f, pos + 8 * (i - 1)) outputBuffer[pos + 8 * (i - 1):pos + 8 * (i - 1) + trkInfoTable[i].size] = bytes( Ref(dest_bom).pack(trkInfoTable[i].type_, trkInfoTable[i].offset)) if trkInfoTable[i].offset not in [0, -1]: pos = trkInfoTable[i].offset + pos - 4 trkInfo[i] = TRKInfo(bom) trkInfo[i].data(f, pos) outputBuffer[pos:pos + trkInfo[i].size] = bytes( TRKInfo(dest_bom).pack(trkInfo[i].volume, trkInfo[i].pan, trkInfo[i].unk)) pos += trkInfo[i].size channelIndexByteTable_ref = Ref(bom) channelIndexByteTable_ref.data(f, pos) outputBuffer[pos:pos + channelIndexByteTable_ref.size] = bytes( Ref(dest_bom).pack(channelIndexByteTable_ref.type_, channelIndexByteTable_ref.offset)) if channelIndexByteTable_ref.offset not in [0, -1]: pos = channelIndexByteTable_ref.offset + pos - trkInfo[ i].size count = struct.unpack(bom + "I", f[pos:pos + 4])[0] outputBuffer[pos:pos + 4] = to_bytes(count, 4, dest_bom) pos += 4 elem = f[pos:pos + count] outputBuffer[pos:pos + count] = elem channelInfoTable = {} ADPCMInfo_ref = {} param = {} pos = channelInfoTable_ref.offset + stmInfo_ref.pos count = struct.unpack(bom + "I", f[pos:pos + 4])[0] outputBuffer[pos:pos + 4] = to_bytes(count, 4, dest_bom) pos += 4 for i in range(1, count + 1): pos = channelInfoTable_ref.offset + stmInfo_ref.pos + 4 channelInfoTable[i] = Ref(bom) channelInfoTable[i].data(f, pos + 8 * (i - 1)) outputBuffer[pos + 8 * (i - 1):pos + 8 * (i - 1) + channelInfoTable[i].size] = bytes( Ref(dest_bom).pack(channelInfoTable[i].type_, channelInfoTable[i].offset)) if channelInfoTable[i].offset not in [0, -1]: pos = channelInfoTable[i].offset + pos - 4 ADPCMInfo_ref[i] = Ref(bom) ADPCMInfo_ref[i].data(f, pos) outputBuffer[pos:pos + ADPCMInfo_ref[i].size] = bytes( Ref(dest_bom).pack(ADPCMInfo_ref[i].type_, ADPCMInfo_ref[i].offset)) if ADPCMInfo_ref[i].offset not in [0, -1]: pos = ADPCMInfo_ref[i].offset + pos if ADPCMInfo_ref[i].type_ == 0x0300: for i in range(1, 17): param[i] = struct.unpack( bom + "H", f[pos + 2 * (i - 1):pos + 2 * (i - 1) + 2])[0] outputBuffer[pos + 2 * (i - 1):pos + 2 * (i - 1) + 2] = to_bytes(param[i], 2, dest_bom) pos += 32 context = DSPContext(bom) context.data(f, pos) outputBuffer[pos:pos + context.size] = bytes( DSPContext(dest_bom).pack(context.predictor_scale, context.preSample, context.preSample2)) pos += context.size loopContext = DSPContext(bom) loopContext.data(f, pos) outputBuffer[pos:pos + loopContext.size] = bytes( DSPContext(dest_bom).pack(loopContext.predictor_scale, loopContext.preSample, loopContext.preSample2)) pos += loopContext.size pos += 2 elif ADPCMInfo_ref[i].type_ == 0x0301: context = IMAContext(bom) context.data(f, pos) outputBuffer[pos:pos + context.size] = bytes( IMAContext(dest_bom).pack(context.data_, context.tableIndex)) pos += context.size loopContext = IMAContext(bom) loopContext.data(f, pos) outputBuffer[pos:pos + loopContext.size] = bytes( IMAContext(dest_bom).pack(loopContext.data_, loopContext.tableIndex)) pos += loopContext.size dest_dataHead = {"FSTM": b'DATA', "CSTM": b'DATA', "FSTP": b'PDAT'} for i in range(1, header.numBlocks + 1): if sized_refs[i].offset not in [0, -1]: if sized_refs[i].type_ == 0x4001: pos = sized_refs[i].offset seek = BLKHeader(bom) seek.data(f, pos) outputBuffer[pos:pos + seek.size] = bytes( BLKHeader(dest_bom).pack(seek.magic, seek.size_)) pos += seek.size seek.data_ = f[pos:pos + seek.size_ - 8] if curr[:-1] == dest[:-1]: outputBuffer[pos:pos + seek.size_ - 8] = seek.data_ else: for i in range(0, len(seek.data_), 2): outputBuffer[pos + i:pos + i + 2] = bytes([ seek.data_[i + 1], seek.data_[i], ]) elif sized_refs[i].type_ in [0x4002, 0x4004]: pos = sized_refs[i].offset data = BLKHeader(bom) data.data(f, pos) outputBuffer[pos:pos + data.size] = bytes( BLKHeader(dest_bom).pack(dest_dataHead[dest], data.size_)) pos += data.size data.data_ = f[pos:pos + data.size_ - 8] if bom != dest_bom and stmInfo.codec == 1: for i in range(0, len(data.data_), 2): outputBuffer[pos + i:pos + i + 2] = bytes([ data.data_[i + 1], data.data_[i], ]) else: outputBuffer[pos:pos + data.size_ - 8] = data.data_ return outputBuffer
def STMtoWAV(f, magic, dest, dest_bom): outputBuffer = bytearray(len(f)) if f[4:6] == b'\xFF\xFE': bom = '<' elif f[4:6] == b'\xFE\xFF': bom = '>' else: print("\nInvalid BOM!") print("\nExiting in 5 seconds...") time.sleep(5) sys.exit(1) if not dest_bom: if dest == "FWAV": dest_bom = '>' else: dest_bom = '<' header = Header(bom) header.data(f, 0) pos = header.size sized_refs = {} for i in range(1, header.numBlocks + 1): sized_refs[i] = Ref(bom) sized_refs[i].data(f, pos + 12 * (i - 1)) if sized_refs[1].type_ != 0x4000 or sized_refs[1].offset in [0, -1]: print("\nSomething went wrong!\nError code: 1") print("\nExiting in 5 seconds...") time.sleep(5) sys.exit(1) pos = sized_refs[1].offset info = BLKHeader(bom) info.data(f, pos) pos += 8 stmInfo_ref = Ref(bom) stmInfo_ref.data(f, pos) if stmInfo_ref.type_ != 0x4100 or stmInfo_ref.offset in [0, -1]: print("\nSomething went wrong!\nError code: 2") print("\nExiting in 5 seconds...") time.sleep(5) sys.exit(1) stmInfo_ref.pos = pos pos += stmInfo_ref.size * 2 channelInfoTable_ref = Ref(bom) channelInfoTable_ref.data(f, pos) if channelInfoTable_ref.type_ != 0x0101: print("\nSomething went wrong!\nError code: 4") print("\nExiting in 5 seconds...") time.sleep(5) sys.exit(1) pos = stmInfo_ref.offset + stmInfo_ref.pos stmInfo = STMInfo(bom) stmInfo.data(f, pos) sampleBlk_size = (stmInfo.sampleBlk_count - 1) * stmInfo.sampleBlk_size + stmInfo.lSampleBlk_size wavInfo = WAVInfo(bom) wavInfo.codec = stmInfo.codec wavInfo.loop_flag = stmInfo.loop_flag wavInfo.sample = stmInfo.sample wavInfo.loop_start = stmInfo.loop_start wavInfo.loop_end = stmInfo.loop_end wavInfo.reserved = 0 otherPos = 0x48 + wavInfo.size outputBuffer[0x48:otherPos] = bytes( WAVInfo(dest_bom).pack(wavInfo.codec, wavInfo.loop_flag, wavInfo.sample, wavInfo.loop_start, wavInfo.loop_end, wavInfo.reserved)) channelInfoTable = {} sampleData_ref = {} ADPCMInfo_ref = {} param = {} pos = channelInfoTable_ref.offset + stmInfo_ref.pos countPos = pos otherCountPos = otherPos count = struct.unpack(bom + "I", f[pos:pos + 4])[0] outputBuffer[otherPos:otherPos + 4] = to_bytes(count, 4, dest_bom) otherFstChInfPos = otherCountPos + 4 + count * 8 otherADPCMInfPos = otherFstChInfPos + count * 0x14 for i in range(1, count + 1): pos = countPos + 4 otherPos = otherCountPos + 4 channelInfoTable[i] = Ref(bom) channelInfoTable[i].data(f, pos + 8 * (i - 1)) if channelInfoTable[i].offset in [0, -1]: outputBuffer[otherPos + 8 * (i - 1):otherPos + 8 * (i - 1) + channelInfoTable[i].size] = bytes( Ref(dest_bom).pack(0x7100, channelInfoTable[i].offset)) else: outputBuffer[otherPos + 8 * (i - 1):otherPos + 8 * (i - 1) + channelInfoTable[i].size] = bytes( Ref(dest_bom).pack( 0x7100, otherFstChInfPos + 0x14 * (i - 1) - otherCountPos)) pos = channelInfoTable[i].offset + countPos otherPos = otherFstChInfPos + 0x14 * (i - 1) sampleData_ref[i] = Ref(bom) currsampleBlkSize = sampleBlk_size * (i - 1) outputBuffer[otherPos:otherPos + sampleData_ref[i].size] = bytes( Ref(dest_bom).pack(0x1F00, 0x18 + align(currsampleBlkSize, 0x20))) ADPCMInfo_ref[i] = Ref(bom) ADPCMInfo_ref[i].data(f, pos) if ADPCMInfo_ref[i].offset in [0, -1]: outputBuffer[otherPos + 8:otherPos + 8 + ADPCMInfo_ref[i].size] = bytes( Ref(dest_bom).pack(ADPCMInfo_ref[i].type_, ADPCMInfo_ref[i].offset)) else: pos = ADPCMInfo_ref[i].offset + pos if ADPCMInfo_ref[i].type_ == 0x0300: outputBuffer[otherPos + 8:otherPos + 8 + ADPCMInfo_ref[i].size] = bytes( Ref(dest_bom).pack( ADPCMInfo_ref[i].type_, otherADPCMInfPos + 0x2E * (i - 1) - otherPos)) otherPos = otherADPCMInfPos + 0x2E * (i - 1) for i in range(16): i += 1 param[i] = struct.unpack( bom + "H", f[pos + 2 * (i - 1):pos + 2 * (i - 1) + 2])[0] outputBuffer[otherPos + 2 * (i - 1):otherPos + 2 * (i - 1) + 2] = to_bytes( param[i], 2, dest_bom) pos += 32 otherPos += 32 context = DSPContext(bom) context.data(f, pos) outputBuffer[otherPos:otherPos + context.size] = bytes( DSPContext(dest_bom).pack(context.predictor_scale, context.preSample, context.preSample2)) pos += context.size otherPos += context.size loopContext = DSPContext(bom) loopContext.data(f, pos) outputBuffer[otherPos:otherPos + loopContext.size] = bytes( DSPContext(dest_bom).pack(loopContext.predictor_scale, loopContext.preSample, loopContext.preSample2)) pos += loopContext.size otherPos += loopContext.size pos += 2 otherPos += 2 elif ADPCMInfo_ref[i].type_ == 0x0301: outputBuffer[otherPos + 8:otherPos + 8 + ADPCMInfo_ref[i].size] = bytes( Ref(dest_bom).pack( ADPCMInfo_ref[i].type_, otherADPCMInfPos + 8 * (i - 1) - otherPos)) otherPos = otherADPCMInfPos + 8 * (i - 1) context = IMAContext(bom) context.data(f, pos) outputBuffer[otherPos:otherPos + context.size] = bytes( IMAContext(dest_bom).pack(context.data_, context.tableIndex)) pos += context.size otherPos += context.size loopContext = IMAContext(bom) loopContext.data(f, pos) outputBuffer[otherPos:otherPos + loopContext.size] = bytes( IMAContext(dest_bom).pack(loopContext.data_, loopContext.tableIndex)) pos += loopContext.size otherPos += loopContext.size else: otherPos += 0x14 dataBlkOffset = align(otherPos, 0x20) infoBlkSize = dataBlkOffset - 0x40 otherDataBlkOffset = 0 dataSize = 0 for i in range(1, header.numBlocks + 1): if sized_refs[i].offset not in [0, -1]: if sized_refs[i].type_ in [0x4002, 0x4004]: otherDataBlkOffset = sized_refs[i].offset dataBlkHead = BLKHeader(bom) dataBlkHead.data(f, otherDataBlkOffset) dataSize = dataBlkHead.size_ pos = header.size numBlocks = 0 for i in sized_refs: if sized_refs[i].type_ not in [0x4000, 0x4002]: continue elif sized_refs[i].type_ == 0x4000: numBlocks += 1 outputBuffer[pos:pos + 8] = bytes(Ref(dest_bom).pack(0x7000, 0x40)) outputBuffer[pos + 8:pos + 12] = struct.pack( dest_bom + "I", infoBlkSize) outputBuffer[0x40:0x48] = bytes( BLKHeader(dest_bom).pack(b'INFO', infoBlkSize)) else: if 0 not in [otherDataBlkOffset, dataSize ] and otherDataBlkOffset != -1: data = f[otherDataBlkOffset + 0x20:otherDataBlkOffset + dataSize] pos = 0 blocks = [] for i in range((stmInfo.sampleBlk_count - 1) * count): blocks.append(data[pos:pos + stmInfo.sampleBlk_size]) pos += stmInfo.sampleBlk_size for i in range(count): blocks.append(data[pos:pos + stmInfo.lSampleBlk_size]) pos += stmInfo.lSampleBlk_padSize sampleData = [[ blocks[i * count + j] for i in range(stmInfo.sampleBlk_count) ] for j in range(count)] samples = [] for channel in sampleData: channelSampleData = b''.join(channel) padding = b'\0' * (align(len(channelSampleData), 0x20) - len(channelSampleData)) samples.append(b''.join([channelSampleData, padding])) data = b''.join(samples) if bom != dest_bom and stmInfo.codec == 1: data_ = bytearray(data) for i in range(0, len(data), 2): data_[i:i + 2] = bytes([ data[i + 1], data[i], ]) data = bytes(data_) del data_ pos = header.size numBlocks += 1 outputBuffer[pos + 12:pos + 20] = bytes( Ref(dest_bom).pack(0x7001, dataBlkOffset)) outputBuffer[dataBlkOffset + 0x20:] = data outputBuffer[dataBlkOffset:dataBlkOffset + 8] = bytes( BLKHeader(dest_bom).pack(b'DATA', len(outputBuffer) - dataBlkOffset)) outputBuffer[pos + 20:pos + 24] = struct.pack( dest_bom + "I", len(outputBuffer) - dataBlkOffset) dest_ver = {"FWAV": 0x10100, "CWAV": 0x2010000} outputBuffer[:header.size] = bytes( Header(dest_bom).pack(to_bytes(dest, 4), 0x40, dest_ver[dest], len(outputBuffer), numBlocks, header.reserved)) outputBuffer[4:6] = (b'\xFE\xFF' if dest_bom == '>' else b'\xFF\xFE') return outputBuffer
def WAVtoWAV(f, magic, dest, dest_bom): outputBuffer = bytearray(len(f)) pos = 0 if f[4:6] == b'\xFF\xFE': bom = '<' elif f[4:6] == b'\xFE\xFF': bom = '>' else: print("\nInvalid BOM!") print("\nExiting in 5 seconds...") time.sleep(5) sys.exit(1) if dest_bom == '': if dest == "FWAV": dest_bom = '>' else: dest_bom = '<' header = Header(bom) header.data(f, pos) dest_ver = {"FWAV": 0x10100, "CWAV": 0x2010000} if magic == dest: dest_ver[dest] = header.version outputBuffer[pos:pos + header.size] = bytes( Header(dest_bom).pack(to_bytes(dest, 4), header.size_, dest_ver[dest], header.fileSize, header.numBlocks, header.reserved)) outputBuffer[4:6] = (b'\xFE\xFF' if dest_bom == '>' else b'\xFF\xFE') pos += header.size sized_refs = {} for i in range(1, header.numBlocks + 1): sized_refs[i] = Ref(bom) sized_refs[i].data(f, pos + 12 * (i - 1)) outputBuffer[pos + 12 * (i - 1):pos + 12 * (i - 1) + sized_refs[i].size] = bytes( Ref(dest_bom).pack(sized_refs[i].type_, sized_refs[i].offset)) sized_refs[i].block_size = struct.unpack( bom + "I", f[pos + 12 * (i - 1) + 8:pos + 12 * i])[0] outputBuffer[pos + 12 * (i - 1) + 8:pos + 12 * i] = to_bytes( sized_refs[i].block_size, 4, dest_bom) if sized_refs[1].type_ != 0x7000 or sized_refs[1].offset in [0, -1]: print("\nSomething went wrong!\nError code: 5") print("\nExiting in 5 seconds...") time.sleep(5) sys.exit(1) pos = sized_refs[1].offset info = BLKHeader(bom) info.data(f, pos) info.pos = pos outputBuffer[pos:pos + info.size] = bytes( BLKHeader(dest_bom).pack(info.magic, info.size_)) pos += info.size wavInfo = WAVInfo(bom) wavInfo.data(f, pos) outputBuffer[pos:pos + wavInfo.size] = bytes( WAVInfo(dest_bom).pack(wavInfo.codec, wavInfo.loop_flag, wavInfo.sample, wavInfo.loop_start, wavInfo.loop_end, wavInfo.reserved)) pos += wavInfo.size channelInfoTable = {} sampleData_ref = {} ADPCMInfo_ref = {} param = {} count = struct.unpack(bom + "I", f[pos:pos + 4])[0] outputBuffer[pos:pos + 4] = to_bytes(count, 4, dest_bom) countPos = pos for i in range(1, count + 1): pos = countPos + 4 channelInfoTable[i] = Ref(bom) channelInfoTable[i].data(f, pos + 8 * (i - 1)) outputBuffer[pos + 8 * (i - 1):pos + 8 * (i - 1) + channelInfoTable[i].size] = bytes( Ref(dest_bom).pack(channelInfoTable[i].type_, channelInfoTable[i].offset)) if channelInfoTable[i].offset not in [0, -1]: pos = channelInfoTable[i].offset + countPos sampleData_ref[i] = Ref(bom) sampleData_ref[i].data(f, pos) outputBuffer[pos:pos + sampleData_ref[i].size] = bytes( Ref(dest_bom).pack(sampleData_ref[i].type_, sampleData_ref[i].offset)) pos += 8 ADPCMInfo_ref[i] = Ref(bom) ADPCMInfo_ref[i].data(f, pos) outputBuffer[pos:pos + ADPCMInfo_ref[i].size] = bytes( Ref(dest_bom).pack(ADPCMInfo_ref[i].type_, ADPCMInfo_ref[i].offset)) if ADPCMInfo_ref[i].offset not in [0, -1]: pos = ADPCMInfo_ref[i].offset + pos - 8 if ADPCMInfo_ref[i].type_ == 0x0300: for i in range(16): i += 1 param[i] = struct.unpack( bom + "H", f[pos + 2 * (i - 1):pos + 2 * (i - 1) + 2])[0] outputBuffer[pos + 2 * (i - 1):pos + 2 * (i - 1) + 2] = to_bytes(param[i], 2, dest_bom) pos += 32 context = DSPContext(bom) context.data(f, pos) outputBuffer[pos:pos + context.size] = bytes( DSPContext(dest_bom).pack(context.predictor_scale, context.preSample, context.preSample2)) pos += context.size loopContext = DSPContext(bom) loopContext.data(f, pos) outputBuffer[pos:pos + loopContext.size] = bytes( DSPContext(dest_bom).pack(loopContext.predictor_scale, loopContext.preSample, loopContext.preSample2)) pos += loopContext.size pos += 2 elif ADPCMInfo_ref[i].type_ == 0x0301: context = IMAContext(bom) context.data(f, pos) outputBuffer[pos:pos + context.size] = bytes( IMAContext(dest_bom).pack(context.data_, context.tableIndex)) pos += context.size loopContext = IMAContext(bom) loopContext.data(f, pos) outputBuffer[pos:pos + loopContext.size] = bytes( IMAContext(dest_bom).pack(loopContext.data_, loopContext.tableIndex)) pos += loopContext.size for i in range(1, header.numBlocks + 1): if sized_refs[i].offset not in [0, -1]: if sized_refs[i].type_ == 0x7001: pos = sized_refs[i].offset data = BLKHeader(bom) data.data(f, pos) outputBuffer[pos:pos + data.size] = bytes( BLKHeader(dest_bom).pack(data.magic, data.size_)) pos += data.size data.data_ = f[pos:pos + data.size_ - 8] if bom != dest_bom and wavInfo.codec == 1: for i in range(0, len(data.data_), 2): outputBuffer[pos + i:pos + i + 2] = bytes([ data.data_[i + 1], data.data_[i], ]) else: outputBuffer[pos:pos + data.size_ - 8] = data.data_ return outputBuffer