Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import sys
- import string
- from util import *
- class strg(object):
- name = ""
- size = None
- offset = None
- def __init__(self, id):
- self.id = id
- class audio(object):
- name = ""
- fileID = None
- strgID = None
- bankID = None
- def __init__(self, id):
- self.id = id
- class soundSet(object):
- offset = None
- fileID = None
- strgID = None
- def __init__(self, id):
- self.id = id
- class sarFile(object):
- fileName = ""
- path = ""
- offset = None
- ext = ".b"
- internal = False
- fileOffset = None
- fileInfoLength = None
- size = None
- bank = None
- def __init__(self, id):
- self.id = id
- class bwav(object):
- def __init__(self, id):
- self.id = id
- class warc(object):
- offset = None
- fileID = None
- sectionCount = None
- wavCount = None
- infoLength = None
- wavs = []
- name = ""
- folder = ""
- def __init__(self, id):
- self.id = id
- class bank(object):
- offset = None
- fileID = None
- wavs = []
- seqs = []
- name = ""
- folder = ""
- def __init__(self, id):
- self.id = id
- readu16 = readu16be
- readu32 = readu32be
- sar = open(sys.argv[1], 'rb')
- sar.seek(1)
- assert sar.read(3) == "SAR"
- byteOrder = readu16be(sar)
- print hex(byteOrder)
- if byteOrder == 0xfeff:
- readu16 = readu16be
- readu32 = readu32be
- endian = ">"
- # print "big endian"
- elif byteOrder == 0xfffe:
- readu16 = readu16le
- readu32 = readu32le
- endian = "<"
- # print "little endian"
- else:
- print "not found"
- #print endian
- sar.seek(0x10)
- sectionCount = readu16(sar)
- sar.seek(2, 1)
- #print sectionCount
- #print sys.argv[1] + " opened"
- for s in range(0, sectionCount):
- ID = readu16(sar)
- # print hex(ID)
- sar.seek(2, 1)
- if ID == 0x2000:
- strgOffset = readu32(sar)
- strgSize = readu32(sar)
- elif ID == 0x2001:
- infoOffset = readu32(sar)
- infoSize = readu32(sar)
- elif ID == 0x2002:
- fileOffset = readu32(sar)
- fileSize = readu32(sar)
- # Reading STRG section
- sar.seek(strgOffset)
- assert sar.read(4) == "STRG"
- assert readu32(sar) == strgSize
- for s in range(0, 2):
- ID = readu16(sar)
- # print hex(ID)
- sar.seek(2, 1)
- if ID == 0x2400:
- strgTableOffset = readu32(sar) + strgOffset + 8
- elif ID == 0x2401:
- strgOtherOffset = readu32(sar) + strgOffset + 8
- sar.seek(strgTableOffset)
- strgCount = readu32(sar)
- names = []
- for i in range(strgCount):
- names.append(strg(i))
- ID = readu16(sar)
- sar.seek(2, 1)
- if ID == 0x1f01:
- names[i].offset = readu32(sar) + strgTableOffset
- names[i].size = readu32(sar)
- tempPos = sar.tell()
- sar.seek(names[i].offset)
- names[i].name = sar.read(names[i].size-1)
- # print names[i].name
- sar.seek(tempPos)
- else: # string may be null
- pass
- # Reading INFO section
- sar.seek(infoOffset)
- assert sar.read(4) == "INFO"
- assert readu32(sar) == infoSize
- for i in range(8):
- ID = readu16(sar)
- # print hex(ID)
- sar.seek(2, 1)
- if ID == 0x2100:
- audioTableOffset = readu32(sar) + infoOffset + 8
- elif ID == 0x2101:
- bankTableOffset = readu32(sar) + infoOffset + 8
- elif ID == 0x2102:
- playerTableOffset = readu32(sar) + infoOffset + 8
- elif ID == 0x2103:
- warcTableOffset = readu32(sar) + infoOffset + 8
- elif ID == 0x2104:
- setTableOffset = readu32(sar) + infoOffset + 8
- elif ID == 0x2105:
- groupTableOffset = readu32(sar) + infoOffset + 8
- elif ID == 0x2106:
- fileTableOffset = readu32(sar) + infoOffset + 8
- elif ID == 0x220B:
- fileTableEnd = readu32(sar) + infoOffset + 8
- else:
- print "Unknown table pointer"
- sar.close()
- sys.exit()
- # process file table
- sar.seek(fileTableOffset)
- fileCount = readu32(sar)
- files = []
- for i in range(fileCount):
- sar.seek(fileTableOffset + 4 + i * 8)
- files.append(sarFile(i))
- ID = readu16(sar)
- # print hex(ID)
- sar.seek(2, 1)
- if ID == 0x220a:
- # print "exists"
- files[i].offset = readu32(sar)
- else:
- print "File doesn't exist"
- sar.seek(4, 1)
- sar.seek(fileTableOffset + files[i].offset)
- ID = readu16(sar)
- # print hex(ID)
- sar.seek(10, 1)
- if ID == 0x220c:
- files[i].internal = True
- ID = readu16(sar)
- sar.seek(2, 1)
- if ID != 0xffff:
- offset = readu32(sar)
- if offset != 0xffffffff:
- files[i].fileOffset = offset + fileOffset + 8
- files[i].size = readu32(sar)
- sar.seek(files[i].fileOffset)
- files[i].ext += string.lower(sar.read(4))
- # print files[i].ext
- elif ID == 0x220d:
- files[i].path = getString(sar)
- # print files[i].path
- # process wave archive table
- warcs = []
- sar.seek(warcTableOffset)
- warcCount = readu32(sar)
- for i in range(warcCount):
- warcs.append(warc(i))
- sar.seek(warcTableOffset + 4 + i * 8)
- ID = readu16(sar)
- # print hex(ID)
- sar.seek(2, 1)
- if ID == 0x2207:
- warcs[i].offset = readu32(sar)
- sar.seek(warcTableOffset + warcs[i].offset)
- # print hex(sar.tell())
- warcs[i].fileID = readu32(sar)
- #looping through warcs again to see which ones have a name
- for i in range(warcCount):
- fileID = warcs[i].fileID
- if i < warcCount - 1:
- warcs[i].infoLength = warcs[i+1].offset - warcs[i].offset
- else:
- warcs[i].infoLength = groupTableOffset - warcTableOffset - warcs[i].offset
- if warcs[i].infoLength > 0xc:
- sar.seek(warcTableOffset + warcs[i].offset + 0xc)
- strgID = readu32(sar)
- warcs[i].name = names[strgID].name
- else:
- warcs[i].name = "WARC_%s" % hex(i)
- files[fileID].fileName = warcs[i].name + files[fileID].ext
- print files[fileID].fileName
- # now to process wave archive
- if files[fileID].internal and files[fileID].fileOffset != None:
- sar.seek(files[fileID].fileOffset+1)
- # print hex(sar.tell())
- # print sar.read(4)
- assert sar.read(3) == "WAR"
- sar.seek(files[fileID].fileOffset)
- """
- war = open(files[fileID].fileName, "wb")
- war.write(sar.read(files[fileID].size))
- war.close()
- """
- # to be finished
- # process bank table
- banks = []
- sar.seek(bankTableOffset)
- bankCount = readu32(sar)
- print bankCount
- for i in range(bankCount):
- banks.append(bank(i))
- sar.seek(bankTableOffset + 4 + i * 8)
- ID = readu16(sar)
- # print hex(ID)
- sar.seek(2, 1)
- if ID == 0x2206:
- banks[i].offset = readu32(sar)
- sar.seek(bankTableOffset + banks[i].offset)
- fileID = banks[i].fileID = readu32(sar)
- sar.seek(0xc,1)
- strgID = banks[i].strgID = readu32(sar)
- banks[i].name = names[strgID].name
- # now to process bank
- if files[fileID].internal and files[fileID].fileOffset != None:
- sar.seek(files[fileID].fileOffset+1)
- # print hex(sar.tell())
- # print sar.read(4)
- assert sar.read(3) == "BNK"
- # to be finished
- # process audio table
- sounds = []
- sar.seek(audioTableOffset)
- audioCount = readu32(sar)
- print audioCount
- for i in range(audioCount):
- sounds.append(audio(i))
- sar.seek(audioTableOffset + 4 + i * 8)
- ID = readu16(sar)
- # print hex(ID)
- sar.seek(2, 1)
- if ID == 0x2200:
- sounds[i].offset = readu32(sar)
- sar.seek(audioTableOffset + sounds[i].offset)
- fileID = sounds[i].fileID = readu32(sar)
- sar.seek(8,1)
- typeID = readu16(sar)
- sar.seek(10,1)
- strgID = sounds[i].strgID = readu32(sar)
- sounds[i].name = names[strgID].name
- files[fileID].fileName = sounds[i].name + files[fileID].ext
- if files[fileID].internal:
- pass
- # print files[fileID].fileName
- if typeID == 0x2201: # External stream
- pass
- elif typeID == 0x2202: # Wave sound
- pass
- # print files[fileID].fileName
- sar.seek(files[fileID].fileOffset+1)
- assert sar.read(3) == "WSD"
- sar.seek(files[fileID].fileOffset)
- """
- wsd = open(files[fileID].fileName, "wb")
- wsd.write(sar.read(files[fileID].size))
- wsd.close()
- """
- elif typeID == 0x2203: # Sequence
- sar.seek(0x40,1)
- if fileID == 207:
- print hex(sar.tell())
- bankID = sounds[i].bankID = readByte(sar)
- # print hex(bankID)
- # banks[sounds[i].bankID].seqs.append(1)
- sar.seek(files[fileID].fileOffset+1)
- assert sar.read(3) == "SEQ"
- print hex(bankCount)
- #for i in range(bankCount):
- # print banks[i].name
- # print "\t" + str(len(banks[i].seqs))
- # for j in range(len(banks[i].seqs)):
- # print "\t" + files[banks[i].seqs[j]].fileName
- sar.close()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement