hbc/pywii/Alameda/Alameda.py
2016-11-23 14:35:12 +09:00

1737 lines
46 KiB
Python

have_pyglet = False
try:
from pyglet import clock, window
from pyglet.gl import *
from pyglet.image import *
have_pyglet = True
except:
pass
import sys, os
sys.path.append(os.path.realpath(os.path.dirname(sys.argv[0]))+"/../Common")
from Struct import Struct
import struct
import pywii as wii
def LZ77Decompress(data):
inp = 0
dlen = len(data)
data += '\0' * 16
ret = []
while inp < dlen:
bitmask = ord(data[inp])
inp += 1
for i in xrange(8):
if bitmask & 0x80:
rep = ord(data[inp])
repLength = (rep >> 4) + 3
inp += 1
repOff = ord(data[inp]) | ((rep & 0x0F) << 8)
inp += 1
assert repOff <= len(ret)
while repLength > 0:
ret.append(ret[-repOff - 1])
repLength -= 1
else:
ret.append(data[inp])
inp += 1
bitmask <<= 1
return ''.join(ret)
class U8(object):
class U8Header(Struct):
__endian__ = Struct.BE
def __format__(self):
self.Tag = Struct.string(4)
self.RootNode = Struct.uint32
self.HeaderSize = Struct.uint32
self.DataOffset = Struct.uint32
self.Zeroes = Struct.uint8[0x10]
class U8Node(Struct):
__endian__ = Struct.BE
def __format__(self):
self.Type = Struct.uint16
self.NameOffset = Struct.uint16
self.DataOffset = Struct.uint32
self.Size = Struct.uint32
def __init__(self, data=None):
self.Files = {}
if data != None:
self.Unpack(data)
def Unpack(self, data):
pos = 0
u8 = self.U8Header()
u8.unpack(data[pos:pos+len(u8)])
pos += len(u8)
assert u8.Tag == 'U\xAA8-'
pos += u8.RootNode - 0x20
root = self.U8Node()
root.unpack(data[pos:pos+len(root)])
pos += len(root)
children = []
for i in xrange(root.Size - 1):
child = self.U8Node()
child.unpack(data[pos:pos+len(child)])
pos += len(child)
children.append(child)
stringTable = data[pos:pos + u8.DataOffset - len(u8) - root.Size * len(root)]
pos += len(stringTable)
currentOffset = u8.DataOffset
path = ['.']
pathDepth = [root.Size - 1]
for offset,child in enumerate(children):
name = stringTable[child.NameOffset:].split('\0', 1)[0]
if child.Type == 0x0100:
path.append(name)
pathDepth.append(child.Size-offset-1)
elif child.Type == 0:
name = '/'.join(path + [name])
if currentOffset < child.DataOffset:
diff = child.DataOffset - currentOffset
assert diff <= 32
pos += diff
currentOffset += diff
currentOffset += child.Size
self.Files[name.lower()] = data[pos:pos+child.Size]
pos += child.Size
pathDepth[-1] -= 1
if pathDepth[-1] == 0:
path = path[:-1]
pathDepth = pathDepth[:-1]
class IMD5Header(Struct):
__endian__ = Struct.BE
def __format__(self):
self.Tag = Struct.string(4)
self.Size = Struct.uint32
self.Zeroes = Struct.uint8[8]
self.MD5 = Struct.uint8[0x10]
def IMD5(data):
imd5 = IMD5Header()
imd5.unpack(data[:len(imd5)])
assert imd5.Tag == 'IMD5'
pos = len(imd5)
if data[pos:pos+4] == 'LZ77':
return LZ77Decompress(data[pos+8:])
else:
return data[pos:]
class TPL(object):
class TPLHeader(Struct):
__endian__ = Struct.BE
def __format__(self):
self.Magic = Struct.string(4)
self.Count = Struct.uint32
self.Size = Struct.uint32
class TexOffsets(Struct):
__endian__ = Struct.BE
def __format__(self):
self.HeaderOff = Struct.uint32
self.PaletteOff = Struct.uint32
class TexHeader(Struct):
__endian__ = Struct.BE
def __format__(self):
self.Size = Struct.uint16[2]
self.Format = Struct.uint32
self.DataOff = Struct.uint32
self.Wrap = Struct.uint32[2]
self.Filter = Struct.uint32[2]
self.LODBias = Struct.float
self.EdgeLOD = Struct.uint8
self.LOD = Struct.uint8[2]
self.Unpacked = Struct.uint8
class PalHeader(Struct):
__endian__ = Struct.BE
def __format__(self):
self.Count = Struct.uint16
self.Unpacked = Struct.uint8
self.Pad = Struct.uint8
self.Format = Struct.uint32
self.DataOff = Struct.uint32
def __init__(self, data=None):
self.Textures = []
if data != None:
self.Unpack(data)
def Unpack(self, data):
header = self.TPLHeader()
header.unpack(data[:len(header)])
pos = len(header)
assert header.Magic == '\x00\x20\xAF\x30'
assert header.Size == 0xc
for i in xrange(header.Count):
offs = self.TexOffsets()
offs.unpack(data[pos:pos+len(offs)])
pos += len(offs)
self.Textures.append(self.ParseTexture(data, offs))
def ParseTexture(self, data, offs):
texHeader = self.TexHeader()
texHeader.unpack(data[offs.HeaderOff:offs.HeaderOff+len(texHeader)])
format = texHeader.Format
self.format = format
rgba = None
if format == 0:
rgba = self.I4(data[texHeader.DataOff:], texHeader.Size)
elif format == 1:
rgba = self.I8(data[texHeader.DataOff:], texHeader.Size)
elif format == 2:
rgba = self.IA4(data[texHeader.DataOff:], texHeader.Size)
elif format == 3:
rgba = self.IA8(data[texHeader.DataOff:], texHeader.Size)
elif format == 4:
rgba = self.RGB565(data[texHeader.DataOff:], texHeader.Size)
elif format == 5:
rgba = self.RGB5A3(data[texHeader.DataOff:], texHeader.Size)
elif format == 6:
rgba = self.RGBA8(data[texHeader.DataOff:], texHeader.Size)
elif format == 14:
rgba = self.S3TC(data[texHeader.DataOff:], texHeader.Size)
else:
print 'Unknown texture format', format
if rgba == None:
rgba = '\0\0\0\0' * texHeader.Size[0] * texHeader.Size[1]
image = ImageData(texHeader.Size[1], texHeader.Size[0], 'RGBA', rgba)
print format
return image
def I4(self, data, (y, x)):
out = [0 for i in xrange(x * y)]
outp = 0
inp = 0
for i in xrange(0, y, 8):
for j in xrange(0, x, 8):
ofs = 0
for k in xrange(8):
off = min(x - j, 8)
for sub in xrange(0, off, 2):
texel = ord(data[inp])
high, low = texel >> 4, texel & 0xF
if (outp + ofs + sub) < (x*y):
out[outp + ofs + sub] = (high << 4) | (high << 20) | (high << 12) | 0xFF<<24
if sub + 1 < off:
if (outp + ofs + sub + 1) < (x*y):
out[outp + ofs + sub + 1] = (low << 4) | (low << 20) | (low << 12) | 0xFF<<24
inp += 1
ofs += x
inp += (8 - off) / 2
outp += off
outp += x * 7
return ''.join(Struct.uint32(p) for p in out)
def I8(self, data, (y, x)):
out = [0 for i in xrange(x * y*2)]
outp = 0
inp = 0
for i in xrange(0, y, 4):
for j in xrange(0, x, 4):
ofs = 0
for k in xrange(4):
off = min(x - j, 4)
for sub in xrange(off):
texel = ord(data[inp])
out[outp + ofs + sub] = (texel << 24) | (texel << 16) | (texel << 8) | 0xFF
inp += 1
ofs += x
inp += 4 - off * 2
outp += off
outp += x * 3
return ''.join(Struct.uint32(p) for p in out)
def IA4(self, data, (y, x)):
out = [0 for i in xrange(x * y)]
outp = 0
inp = 0
for i in xrange(0, y, 4):
for j in xrange(0, x, 8):
ofs = 0
for k in xrange(4):
off = min(x - j, 8)
for sub in xrange(off):
texel = ord(data[inp])
alpha, inte = texel >> 4, texel & 0xF
if (outp + ofs + sub) < (x*y):
out[outp + ofs + sub] = (inte << 4) | (inte << 12) | (inte << 20) | (alpha << 28)
inp += 1
ofs += x
inp += 8 - off
outp += off
outp += x * 3
return ''.join(Struct.uint32(p) for p in out)
def IA8(self, data, (y, x)):
out = [0 for i in xrange(x * y)]
outp = 0
inp = 0
for i in xrange(0, y, 4):
for j in xrange(0, x, 4):
ofs = 0
for k in xrange(4):
off = min(x - j, 4)
for sub in xrange(off):
if (outp + ofs + sub) < (x*y):
texel = Struct.uint16(data[inp:inp + 2], endian='>')
p = (texel & 0xFF)
p |= (texel & 0xFF) << 8
p |= (texel & 0xFF) << 16
p |= (texel >> 8) << 24
out[outp + ofs + sub] = p
inp += 2
ofs += x
inp += (4 - off) * 2
outp += off
outp += x * 3
return ''.join(Struct.uint32(p) for p in out)
def RGB565(self, data, (y, x)):
out = [0 for i in xrange(x * y)]
outp = 0
inp = 0
for i in xrange(0, y, 4):
for j in xrange(0, x, 4):
ofs = 0
for k in xrange(4):
off = min(x - j, 4)
for sub in xrange(off):
if (outp + ofs + sub) < (x*y):
texel = Struct.uint16(data[inp:inp + 2], endian='>')
p = ((texel >> 11) & 0x1F) << 3
p |= ((texel >> 5) & 0x3F) << 10
p |= ( texel & 0x1F) << 19
p |= 0xFF<<24
out[outp + ofs + sub] = p
inp += 2
ofs += x
inp += (4 - off) * 2
outp += off
outp += x * 3
return ''.join(Struct.uint32(p) for p in out)
def RGB5A3(self, data, (y, x)):
out = [0 for i in xrange(x * y)]
outp = 0
inp = 0
for i in xrange(0, y, 4):
for j in xrange(0, x, 4):
ofs = 0
for k in xrange(4):
off = min(x - j, 4)
for sub in xrange(off):
texel = Struct.uint16(data[inp:inp + 2], endian='>')
if texel & 0x8000:
p = ((texel >> 10) & 0x1F) << 3
p |= ((texel >> 5) & 0x1F) << 11
p |= ( texel & 0x1F) << 19
p |= 0xFF<<24
else:
p = ((texel >> 12) & 0x07) << 29
p |= ((texel >> 8) & 0x0F) << 4
p |= ((texel >> 4) & 0x0F) << 12
p |= (texel & 0x0F) << 20
if (outp + ofs + sub) < (x*y):
out[outp + ofs + sub] = p
inp += 2
ofs += x
inp += (4 - off) * 2
outp += off
outp += x * 3
return ''.join(Struct.uint32(p) for p in out)
def RGBA8(self, data, (y, x)):
out = [0 for i in xrange(x * y)]
outp = 0
inp = 0
for i in xrange(0, y, 4):
for j in xrange(0, x, 4):
ofs = 0
for k in xrange(4):
off = min(x - j, 4)
for sub in xrange(off):
texel = Struct.uint16(data[inp:inp + 2], endian='>')<<16
texel |= Struct.uint16(data[inp+32:inp + 34], endian='>')
if (outp + ofs + sub) < (x*y):
out[outp + ofs + sub] = texel&0xff000000 | ((texel>>16)&0xff) | (texel&0xff00) | ((texel<<16)&0xff0000)
inp += 2
ofs += x
inp += (4 - off) * 2
outp += off
inp += 32
outp += x * 3
return ''.join(Struct.uint32(p) for p in out)
def unpack_rgb565(self,texel):
b = (texel&0x1f)<<3
g = ((texel>>5)&0x3f)<<2
r = ((texel>>11)&0x1f)<<3
b |= b>>5
g |= g>>6
r |= r>>5
return (0xff<<24) | (b<<16) | (g<<8) | r
def icolor(self,a,b,fa,fb,fc):
c = 0
for i in xrange(0,32,8):
xa = (a>>i)&0xff
xb = (b>>i)&0xff
xc = min(255,max(0,int((xa*fa + xb*fb)/fc)))
c |= xc<<i
return c
def S3TC(self, data, (y, x)):
out = [0 for i in xrange(x * y)]
TILE_WIDTH = 8
TILE_HEIGHT = 8
inp = 0
outp = 0
for i in xrange(0, y, TILE_HEIGHT):
for j in xrange(0, x, TILE_WIDTH):
maxw = min(x - j,TILE_WIDTH)
for k in xrange(2):
for l in xrange(2):
rgb = [0,0,0,0]
texel1 = Struct.uint16(data[inp:inp + 2], endian='>')
texel2 = Struct.uint16(data[inp + 2:inp + 4], endian='>')
rgb[0] = self.unpack_rgb565(texel1)
rgb[1] = self.unpack_rgb565(texel2)
if texel1 > texel2:
rgb[2] = self.icolor (rgb[0], rgb[1], 2, 1, 3) | 0xff000000
rgb[3] = self.icolor (rgb[1], rgb[0], 2, 1, 3) | 0xff000000
else:
rgb[2] = self.icolor (rgb[0], rgb[1], 0.5, 0.5, 1) | 0xff000000
rgb[3] = 0
# color selection (00, 01, 10, 11)
cm = map(ord,data[inp+4:inp+8])
ofs = l*4
for n in range(4):
if (ofs + outp)<(x*y):
# one row (4 texels)
if maxw > (0 + l*4):
out[ofs + 0 + outp] = rgb[(cm[n] & 0xc0) >> 6];
if maxw > (1 + l*4):
out[ofs + 1 + outp] = rgb[(cm[n] & 0x30) >> 4];
if maxw > (2 + l*4):
out[ofs + 2 + outp] = rgb[(cm[n] & 0x0c) >> 2];
if maxw > (3 + l*4):
out[ofs + 3 + outp] = rgb[(cm[n] & 0x03) >> 0];
ofs += x
inp += 8
outp += x * 4
outp += maxw - x * 8
outp += x * (TILE_HEIGHT - 1)
return ''.join(Struct.uint32(p) for p in out)
class Object(object):
def __init__(self, name):
self.Frame = 0
self.Name = name
self.Alpha = 255
self.Animations = 0
def __str__(self):
return self.Name
class Pane(Object):
def __init__(self, name, flags=0x104, alpha=255, coords=[0,0,0,0,0,0,1,1,0,0]):
Object.__init__(self, name)
self.Flags = flags
self.Alpha = alpha
self.Coords = list(coords)
self.Children = []
self.Enabled = True
def getX(self): return self.Coords[0]
def setX(self,v): self.Coords[0] = v
def getY(self): return self.Coords[1]
def setY(self,v): self.Coords[1] = v
def getMagX(self): return self.Coords[6]
def setMagX(self,v): self.Coords[6] = v
def getMagY(self): return self.Coords[7]
def setMagY(self,v): self.Coords[7] = v
def getW(self): return self.Coords[8]
def setW(self,v): self.Coords[8] = v
def getH(self): return self.Coords[9]
def setH(self,v): self.Coords[9] = v
def getRot(self): return self.Coords[5]
def setRot(self,v): self.Coords[5] = v
X = property(getX,setX)
Y = property(getY,setY)
MagX = property(getMagX,setMagX)
MagY = property(getMagY,setMagY)
Width = property(getW,setW)
Height = property(getH,setH)
Rot = property(getRot,setRot)
def Add(self, child):
self.Children.append(child)
def AnimDone(self):
if not Object.AnimDone(self):
return False
for child in self.Children:
if not child.AnimDone():
return False
return True
class Picture(Pane):
def __init__(self, name, flags=0x504, alpha=255, coords=[0,0,0,0,0,0,1,1,0,0], unk=[0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff], mat=0, flags2=0x100, matcoord=[(0,0),(1,0),(0,1),(1,1)]):
Pane.__init__(self, name, flags, alpha, coords)
self.Unk = unk
self.Material = mat
self.Flags2 = flags2
self.MaterialCoords = list(matcoord)
class ItemList(object):
HDRLEN=4
LSIZE=4
OFFSET=0
IS_ATOM=True
def __init__(self, data=None):
self.Items = []
if data is not None:
self.unpack(data)
def add(self,n):
self.Items.append(n)
def unpack(self, data):
pos = 0
if self.IS_ATOM:
pos = 8
count = self.__unpkcnt__(data[pos:])
pos = self.__getlistoff__(data[pos:])
for i in xrange(count):
off = Struct.uint32(data[pos:pos+4], endian='>') + self.OFFSET
if i == (count-1):
next = len(data)
else:
next = Struct.uint32(data[pos+self.LSIZE:pos+self.LSIZE+4], endian='>') + self.OFFSET
pos += self.LSIZE
self.unpack_item(i, data[off:next])
# sanity check
#dp = self.pack()
#assert dp == data
def pack(self,extra=None):
extradata = ""
if extra is not None:
extradata = extra.pack()
data = ""
offsets = []
for n,i in enumerate(self.Items):
offsets.append(len(data))
data += self.pack_item(n,i)
listlen = len(self.Items) * self.LSIZE
head = self.__mkheader__()
outdata = ""
if self.IS_ATOM:
outdata += self.FOURCC + Struct.uint32((len(extradata) + listlen + len(data) + 8 + len(head) + 3) &(~3), endian='>')
outdata += head
dataoff = len(outdata) + listlen - self.OFFSET
assert dataoff >= 0
for n in offsets:
outdata += Struct.uint32(n + dataoff, endian='>')
if self.LSIZE > 4:
outdata += (self.LSIZE-4)*"\x00"
outdata += data
outdata += extradata
if len(outdata)%4 != 0:
outdata += (4-len(outdata)%4)*"\x00"
return outdata
def __mkheader__(self):
return Struct.uint16(len(self.Items), endian='>') + "\x00\x00"
def __unpkcnt__(self, data):
return Struct.uint16(data[0:2], endian='>')
def __getlistoff__(self, data):
off=self.HDRLEN
if self.IS_ATOM:
off += 8
return off
def __getitem__(self, n):
return self.Items[n]
def __len__(self):
return len(self.Items)
class StdAtom(Struct):
__endian__ = Struct.BE
def __format__(self):
self.FourCC = Struct.string(4)
self.Size = Struct.uint32
def pack(self):
self.FourCC = self.FOURCC
self.Size = len(self)
return Struct.pack(self)
class Brlyt(object):
class BrlytHeader(Struct):
__endian__ = Struct.BE
def __format__(self):
self.Magic = Struct.string(4)
self.Unk = Struct.uint32
self.Size = Struct.uint32
self.UnkCount = Struct.uint16
self.AtomCount = Struct.uint16
class BrlytLYT1(StdAtom):
FOURCC = "lyt1"
def __format__(self):
StdAtom.__format__(self)
self.Flag = Struct.uint8
self.pad = Struct.uint8[3]
self.Width = Struct.float
self.Height = Struct.float
class BrlytTexture(object):
def __init__(self, name, texture=None):
self.Name = name
self.Texture = texture
self.GLTexture = None
def create_texture(self):
self.GLTexture = self.Texture.create_texture(Texture)
class BrlytTXL1(ItemList):
LSIZE = 8
OFFSET = 12
FOURCC = "txl1"
def __init__(self, archive=None, data=None):
self.Archive = archive
ItemList.__init__(self, data)
def unpack_item(self, i, data):
fn = data.split('\0', 1)[0]
print fn
tex = TPL(self.Archive.Files['./arc/timg/' + fn.lower()]).Textures[0]
self.Items.append(Brlyt.BrlytTexture(fn, tex))
def pack_item(self, i, item):
return item.Name + "\0"
class BrlytMAT1(ItemList):
LSIZE = 4
OFFSET = 0
FOURCC = "mat1"
def __init__(self, data=None):
ItemList.__init__(self, data)
def unpack_item(self, num, data):
mtl = Brlyt.BrlytMaterial()
mtl.unpack(data)
self.Items.append(mtl)
def pack_item(self, i, item):
return item.pack()
class BrlytMaterialFlags(object):
def __init__(self,value=None):
if value is not None:
self.unpack(value)
def unpack(self,value):
self.value = value
self.NumTextures = value & 15
self.NumCoords = (value>>4) & 15
self.m_2 = (value>>8) & 15
self.m_4 = bool((value>>12) & 1)
self.m_6 = (value>>13) & 3
self.m_5 = (value>>15) & 7
self.m_3 = (value>>18) & 31
self.m_9 = bool((value>>23) & 1)
self.m_10 = bool((value>>24) & 1)
self.m_7 = bool((value>>25) & 1)
self.m_8 = bool((value>>27) & 1)
def show(self):
print "Flags: %08x"%self.value
print "ReserveGXMem("
print " r4 =",self.NumTextures
print " r5 =",self.NumCoords
print " r6 =",self.m_2
print " r7 =",self.m_3
print " r8 =",self.m_4
print " r9 =",self.m_5
print " r10 =",self.m_6
print " 0x8(%sp) =",self.m_7
print " 0xC(%sp) =",self.m_8
print " 0x10(%sp) =",self.m_9
print " 0x14(%sp) =",self.m_10
print ")"
def pack(self):
val = 0
val |= self.NumTextures
val |= self.NumCoords << 4
val |= self.m_2 << 8
val |= self.m_4 << 12
val |= self.m_6 << 13
val |= self.m_5 << 15
val |= self.m_3 << 18
val |= self.m_9 << 23
val |= self.m_10 << 24
val |= self.m_7 << 25
val |= self.m_8 << 27
return val
class BrlytMatHeader(Struct):
__endian__ = Struct.BE
def __format__(self):
self.Name = Struct.string(0x14)
self.Color1 = Struct.uint16[4]
self.Color2 = Struct.uint16[4]
self.Color3 = Struct.uint16[4]
self.Blah = Struct.uint32[4]
self.Flags = Struct.uint32
# 0-3 num 0-8
# 4-7 num 0-10
# 8-11 num 0-8
# 12 bool
# 13-14 num 0-3
# 15-17 num 0-4
# 18-22 num 0-16
# 23 bool
# 24 bool
# 25 bool a
# 27 bool
# if 25, xtra word
# if 27, xtra word
# if 12, xtra word
# 13-14 * 0x14
# 15-17 * 4
# 18-22 * 16
# if 23, xtra word
# if 24, xtra word
class BrlytMaterial(object):
def __init__(self, name=None):
if name is not None:
self.Name = name
self.Color1 = [0,0,0,0]
self.Color2 = [255,255,255,255]
self.Color3 = [255,255,255,255]
self.Blah = [0xffffffff,0xffffffff,0xffffffff,0xffffffff]
self.Textures = []
self.TextureCoords = []
self.SthB = []
self.SthI = None
self.SthJ = None
self.SthC = None
self.SthD = []
self.SthE = []
self.SthF = []
self.SthG = 0x77000000
self.SthH = None
def unpack(self, data):
wii.chexdump(data)
hdr = Brlyt.BrlytMatHeader()
hdr.unpack(data)
self.FlagData = Brlyt.BrlytMaterialFlags(hdr.Flags)
self.FlagData.show()
self.Name = hdr.Name.split("\0",1)[0]
self.Color1 = hdr.Color1
self.Color2 = hdr.Color2
self.Color3 = hdr.Color3
self.Blah = hdr.Blah
ptr = 0x40
self.Textures = []
self.TextureCoords = []
self.SthB = []
self.SthI = None
self.SthJ = None
self.SthC = None
self.SthD = []
self.SthE = []
self.SthF = []
self.SthG = None
self.SthH = None
for i in range(self.FlagData.NumTextures):
texid = Struct.uint16(data[ptr:ptr+2], endian='>')
texcs = Struct.uint8(data[ptr+2], endian='>')
texct = Struct.uint8(data[ptr+3], endian='>')
print " * Texture: %04x %d %d"%(texid,texcs,texct)
self.Textures.append((texid,texcs,texct))
ptr += 4
for i in range(self.FlagData.NumCoords):
dat = []
for j in range(5):
dat.append(Struct.float(data[ptr+j*4:ptr+j*4+4], endian='>'))
print " * Coords: [",', '.join(["%f"%x for x in dat]),"]"
ptr += 0x14
self.TextureCoords.append(dat)
for i in range(self.FlagData.m_2):
dat = Struct.uint32(data[ptr:ptr+4], endian='>')
self.SthB.append(dat)
print " * SthB: %08x"%dat
ptr += 0x04
if self.FlagData.m_7:
self.SthI = Struct.uint32(data[ptr:ptr+4], endian='>')
print " SthI: %08x"%self.SthI
ptr += 0x04
if self.FlagData.m_8:
self.SthJ = Struct.uint32(data[ptr:ptr+4], endian='>')
print " SthJ: %08x"%self.SthJ
ptr += 0x04
if self.FlagData.m_4:
self.SthC = Struct.uint32(data[ptr:ptr+4], endian='>')
print " SthC: %08x"%self.SthC
ptr += 0x04
for i in range(self.FlagData.m_6):
dat = []
for j in range(5):
dat.append(Struct.float(data[ptr+j*4:ptr+j*4+4], endian='>'))
self.SthD.append(dat)
print " * SthD: [",', '.join(["%f"%x for x in dat]),"]"
ptr += 0x14
for i in range(self.FlagData.m_5):
dat = Struct.uint32(data[ptr:ptr+4], endian='>')
self.SthE.append(dat)
print " * SthE: %08x"%dat
ptr += 0x04
for i in range(self.FlagData.m_3):
dat = []
for j in range(4):
dat.append(Struct.uint32(data[ptr+j*4:ptr+j*4+4], endian='>'))
self.SthF.append(dat)
print " * SthF: [",', '.join(["%08x"%x for x in dat]),"]"
ptr += 0x10
if self.FlagData.m_9:
dat = Struct.uint32(data[ptr:ptr+4], endian='>')
self.SthG = dat
print " SthG: %08x"%dat
ptr += 0x04
if self.FlagData.m_10:
dat = Struct.uint32(data[ptr:ptr+4], endian='>')
self.SthH = dat
print " SthH: %08x"%dat
ptr += 0x04
#assert ptr == len(data)
def pack(self):
self.FlagData = Brlyt.BrlytMaterialFlags()
self.FlagData.NumTextures = len(self.Textures)
self.FlagData.NumCoords = len(self.TextureCoords)
self.FlagData.m_2 = len(self.SthB)
self.FlagData.m_7 = self.SthI is not None
self.FlagData.m_8 = self.SthJ is not None
self.FlagData.m_4 = self.SthC is not None
self.FlagData.m_6 = len(self.SthD)
self.FlagData.m_5 = len(self.SthE)
self.FlagData.m_3 = len(self.SthF)
self.FlagData.m_9 = self.SthG is not None
self.FlagData.m_10 = self.SthH is not None
self.Flags = self.FlagData.pack()
hdr = Brlyt.BrlytMatHeader()
hdr.Name = self.Name + "\x00"*(0x14-len(self.Name))
hdr.Color1 = self.Color1
hdr.Color2 = self.Color2
hdr.Color3 = self.Color3
hdr.Blah = self.Blah
hdr.Flags = self.Flags
data = hdr.pack()
for i in self.Textures:
data += Struct.uint16(i[0], endian='>')
data += Struct.uint8(i[1], endian='>')
data += Struct.uint8(i[2], endian='>')
for i in self.TextureCoords:
for j in i:
data += Struct.float(j, endian='>')
for i in self.SthB:
data += Struct.uint32(i, endian='>')
if self.SthI is not None:
data += Struct.uint32(self.SthI, endian='>')
if self.SthJ is not None:
data += Struct.uint32(self.SthJ, endian='>')
if self.SthC is not None:
data += Struct.uint32(self.SthC, endian='>')
for i in self.SthD:
for j in i:
data += Struct.float(j, endian='>')
for i in self.SthE:
data += Struct.uint32(i, endian='>')
for i in self.SthF:
for j in i:
data += Struct.uint32(j, endian='>')
if self.SthG is not None:
data += Struct.uint32(self.SthG, endian='>')
if self.SthH is not None:
data += Struct.uint32(self.SthH, endian='>')
return data
class BrlytPAN1(StdAtom):
FOURCC = "pan1"
def __format__(self):
StdAtom.__format__(self)
self.Flags = Struct.uint16
self.Alpha = Struct.uint16
self.Name = Struct.string(0x18)
self.Coords = Struct.float[10]
class BrlytPIC1(BrlytPAN1):
FOURCC = "pic1"
def __format__(self):
Brlyt.BrlytPAN1.__format__(self)
self.unk = Struct.uint8[16]
self.Material = Struct.uint16
self.Flags2 = Struct.uint16
self.MaterialCoords = Struct.float[8]
def __init__(self, archive, data, renderer):
self.Archive = archive
self.Textures = Brlyt.BrlytTXL1()
self.Materials = Brlyt.BrlytMAT1()
self.LastPic = None
self.RootPane = None
self.RootPaneName = None
self.Objects = {}
self.PanePath = []
self.PaneId = 0
self.Language = "ENG"
self.Renderer = renderer
if data != None:
self.Unpack(data)
def Unpack(self, data):
pos = 0
header = self.BrlytHeader()
header.unpack(data[:len(header)])
print "BRLYT header:"
wii.chexdump(data[:len(header)])
print " unk1: %08x"%header.Unk
print " unkc: %08x"%header.UnkCount
pos += len(header)
print " %d atoms"%header.AtomCount
assert header.Magic == 'RLYT'
for i in xrange(header.AtomCount):
atom = StdAtom()
atom.unpack(data[pos:pos+len(atom)])
atomdata = data[pos:pos+atom.Size]
if atom.FourCC == 'txl1':
self.TXL1(atomdata)
elif atom.FourCC == 'lyt1':
self.LYT1(atomdata)
elif atom.FourCC == 'mat1':
self.MAT1(atomdata)
elif atom.FourCC == 'pan1':
self.PAN1(atomdata)
elif atom.FourCC == 'pas1':
self.PAS1(atomdata)
elif atom.FourCC == 'pae1':
self.PAE1(atomdata)
elif atom.FourCC == 'pic1':
self.PIC1(atomdata)
elif atom.FourCC == "grp1":
self.GRP1(atomdata)
else:
print "Unknown FOURCC:",atom.FourCC
wii.chexdump(atomdata)
pos += atom.Size
def _PackObject(self, object):
atoms = 0
if isinstance(object,Pane):
atoms += 1
if isinstance(object,Picture):
atom = Brlyt.BrlytPIC1()
else:
atom = Brlyt.BrlytPAN1()
atom.Name = object.Name + "\x00"*(0x18-len(object.Name))
atom.Alpha = int(object.Alpha * 256)
atom.Flags = object.Flags
atom.Coords = object.Coords
if isinstance(object,Picture):
atom.Flags2 = object.Flags2
atom.Material = object.Material
atom.unk = object.Unk
atom.MaterialCoords = sum(map(list,object.MaterialCoords),[])
data = atom.pack()
if len(object.Children) > 0:
atoms += 2
data += "pas1\x00\x00\x00\x08"
for child in object.Children:
ac, dc = self._PackObject(child)
data += dc
atoms += ac
data += "pae1\x00\x00\x00\x08"
return atoms, data
else:
raise ValueError("Unknown object: "+repr(object))
def Pack(self, extra=None):
header = self.BrlytHeader()
header.Unk = 0xfeff0008
header.UnkCount = 0x10
header.Magic = "RLYT"
header.AtomCount = 0
data = ""
data += self.mkLYT1()
header.AtomCount+=1
data += self.mkTXL1()
header.AtomCount+=1
data += self.mkMAT1(extra)
header.AtomCount+=1
atoms, ndata = self._PackObject(self.RootPane)
data += ndata
header.AtomCount += atoms
#uuugly. TODO: fix this crap.
data += "grp1\x00\x00\x00\x1cRootGroup\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
header.AtomCount += 1
header.Size = len(data) + len(header)
data = header.pack() + data
return data
def mkLYT1(self):
lyt1 = self.BrlytLYT1()
lyt1.Width = self.Width
lyt1.Height = self.Height
lyt1.Flag = 1
for n in range(3):
lyt1.pad[n] = 0
return lyt1.pack()
def mkTXL1(self):
return self.Textures.pack()
def mkMAT1(self, extra=None):
return self.Materials.pack(extra)
def LYT1(self, data):
lyt1 = self.BrlytLYT1()
lyt1.unpack(data)
self.Width = lyt1.Width
self.Height = lyt1.Height
print "LYT1: %f x %f, flag %d"%(self.Width, self.Height, lyt1.Flag)
self.Renderer.Create(int(self.Width), int(self.Height))
def TXL1(self, data):
self.Textures = self.BrlytTXL1(self.Archive, data)
for i in self.Textures:
i.create_texture()
def ApplyMask(self, image, mask):
print "Making mask:",image,mask
print image.width,image.height,mask.width,mask.height
if image.height != mask.height or image.width != mask.width:
raise ValueError("Mask dimensions must be equal to mask dimensions")
newdata = [0 for x in xrange(image.height * image.width * 4)]
for pix in xrange(image.height * image.width):
newdata[pix*4 + 0] = image.data[pix*4 + 0]
newdata[pix*4 + 1] = image.data[pix*4 + 1]
newdata[pix*4 + 2] = image.data[pix*4 + 2]
newdata[pix*4 + 3] = mask.data[pix*4 + 0]
return ImageData(image.width, image.height, 'RGBA', ''.join(newdata))
def MAT1(self, data):
self.Materials = self.BrlytMAT1(data)
def _addpane(self, p):
self.CurPane = p
self.Objects[p.Name] = p
if self.RootPane is None:
self.RootPane = p
else:
self.PanePath[-1].Add(p)
def PAN1(self, data):
wii.chexdump(data)
pane = Brlyt.BrlytPAN1()
pane.unpack(data)
p = Pane(pane.Name.split('\0',1)[0], pane.Flags, pane.Alpha/256.0, pane.Coords)
print 'Pane %s (flags %04x, alpha %f): ' % (p.Name, pane.Flags, pane.Alpha),pane.Coords
self._addpane(p)
def PAS1(self, data):
wii.chexdump(data)
if self.CurPane is None:
raise ValueError("No current pane!")
self.PanePath.append(self.CurPane)
print "Pane start:",'.'.join(map(str,self.PanePath))
self.CurPane = None
def PAE1(self, data):
print "Pane end:",'.'.join(map(str,self.PanePath))
self.PanePath = self.PanePath[:-1]
def PIC1(self, data):
wii.chexdump(data)
pic = Brlyt.BrlytPIC1()
pic.unpack(data)
mc = []
for i in range(4):
mc.append(pic.MaterialCoords[i*2:i*2+2])
print mc
p = Picture(pic.Name.split("\0",1)[0], pic.Flags, pic.Alpha/256.0, pic.Coords, pic.unk, pic.Material, pic.Flags2, mc)
print repr(p.Name)
mat = self.Materials[pic.Material]
if mat is not None:
self._addpane(p)
else:
print 'Picture %s with null material!'
def GRP1(self, data):
wii.chexdump(data)
if len(data) < 0x1c:
pass
lang = data[0x8:0x18].split('\0', 1)[0]
nitems = Struct.uint16(data[0x18:0x1a], endian='>')
p = 0x1c
items = []
for i in xrange(nitems):
items.append(data[p:].split('\0', 1)[0])
p += 0x10
for i in items:
try:
if lang != self.Language:
self.Objects[i].Enabled = False
else:
self.Objects[i].Enabled = True
except:
pass
class Brlan(object):
A_COORD = "RLPA"
A_PARM = "RLVC"
C_X = 0
C_Y = 1
C_ANGLE = 5
C_MAGX = 6
C_MAGY = 7
C_WIDTH = 8
C_HEIGHT = 9
P_ALPHA = 0x10
class BrlanHeader(Struct):
__endian__ = Struct.BE
def __format__(self):
self.Magic = Struct.string(4)
self.Unk = Struct.uint32
self.Size = Struct.uint32
self.UnkCount = Struct.uint16
self.AtomCount = Struct.uint16
def __init__(self, data=None):
self.Anim = None
if data != None:
self.Unpack(data)
else:
self.Anim = Brlan.BrlanPAI1()
def Unpack(self, data):
header = self.BrlanHeader()
header.unpack(data[:len(header)])
pos = len(header)
assert header.Magic == 'RLAN'
for i in xrange(header.AtomCount):
atom = StdAtom()
atom.unpack(data[pos:pos+len(atom)])
atomdata = data[pos:pos+atom.Size]
pos += atom.Size
if atom.FourCC == 'pai1':
self.PAI1(atomdata)
else:
print "Unknown animation atom: %s"%atom.FourCC
class BrlanPAI1(ItemList):
LSIZE=4
OFFSET=0
FOURCC="pai1"
HDRLEN=12
def unpack(self, data):
self.FrameCount = Struct.uint16(data[8:10], endian='>')
print self.FrameCount
ItemList.unpack(self, data)
def __mkheader__(self):
hdr = Struct.uint16(self.FrameCount, endian='>')
hdr += Struct.uint16(0x100, endian='>')
hdr += Struct.uint32(len(self.Items), endian='>')
hdr += Struct.uint32(0x14, endian='>')
return hdr
def __unpkcnt__(self, data):
return Struct.uint32(data[4:8], endian='>')
def __getlistoff__(self, data):
return Struct.uint32(data[8:12], endian='>')
def unpack_item (self, num, data):
self.Items.append(Brlan.BrlanAnimSet(data))
def pack(self, offset, count):
self.FrameCount = count
self.Offset = offset
return ItemList.pack(self)
def pack_item (self, num, item):
return item.pack(self.Offset)
def __getitem__(self, n):
if isinstance(n,str):
for i in self.Items:
if i.Name == n:
return i
raise KeyError("Key %s not found"%n)
else:
return ItemList.__getitem__(self, n)
def __contains__(self, n):
if isinstance(n,str):
for i in self.Items:
if i.Name == n:
return True
return False
else:
return n in self.Items
class BrlanAnimSet(ItemList):
LSIZE=4
OFFSET=0
HDRLEN=0x18
IS_ATOM=False
def __init__(self, data=None):
if data is not None and len(data)<0x14:
self.Name = data
ItemList.__init__(self, None)
else:
ItemList.__init__(self, data)
def unpack(self, data):
self.Name = data[:0x14].split("\0",1)[0]
print self.Name
ItemList.unpack(self, data)
def __mkheader__(self):
hdr = self.Name + "\x00" * (0x14-len(self.Name))
hdr += Struct.uint8(len(self.Items), endian='>')
hdr += "\x00\x00\x00"
return hdr
def __unpkcnt__(self, data):
return Struct.uint8(data[0x14:0x15], endian='>')
def unpack_item (self, num, data):
self.Items.append(Brlan.BrlanAnimClass(data))
def pack_item (self, num, item):
return item.pack(self.Offset)
def pack(self, offset):
self.Offset = offset
return ItemList.pack(self)
def __getitem__(self, n):
if isinstance(n,str):
for i in self.Items:
if i.Type == n:
return i
raise KeyError("Key %s not found"%n)
else:
return ItemList.__getitem__(self, n)
class BrlanAnimClass(ItemList):
LSIZE=4
OFFSET=0
HDRLEN=8
IS_ATOM=False
class BrlanAnimClassIterator(object):
def __init__(self, cl):
self.cl = cl
self.item = 0
def __iter__(self):
return self
def next(self):
if self.item == len(self.cl.Items):
raise StopIteration()
else:
self.item += 1
return self.cl.Items[self.item-1]
def __init__(self, data=None):
if data is not None and len(data) == 4:
self.Type = data
ItemList.__init__(self, None)
else:
ItemList.__init__(self, data)
def unpack(self, data):
self.Type = data[0:4]
print " ",self.Type
ItemList.unpack(self, data)
def __mkheader__(self):
hdr = self.Type
hdr += Struct.uint8(len(self.Items), endian='>')
hdr += "\x00\x00\x00"
return hdr
def __unpkcnt__(self, data):
return Struct.uint8(data[4:5], endian='>')
def unpack_item (self, num, data):
self.Items.append(Brlan.BrlanAnim(data))
def pack(self, offset):
self.Offset = offset
return ItemList.pack(self)
def pack_item (self, num, item):
return item.pack(self.Offset)
def __getitem__(self, n):
for i in self.Items:
if i.Type == n:
return i
raise KeyError("Key %d not found"%n)
def __iter__(self):
return self.BrlanAnimClassIterator(self)
class BrlanAnim(object):
def __init__(self, data=None):
self.Triplets = []
self.Unk = 0x200
self.Type = 0
if data is not None and isinstance(data,int):
self.Type = data
else:
self.unpack(data)
def unpack(self, data):
self.Type = Struct.uint16(data[0:2], endian='>')
self.Unk = Struct.uint16(data[2:4], endian='>')
count = Struct.uint16(data[4:6], endian='>')
pos = Struct.uint32(data[8:12], endian='>')
print " ",self.Type
if self.Unk == 0x200:
print " Triplets:"
for i in range(count):
F = Struct.float(data[pos+0:pos+4], endian='>')
P = Struct.float(data[pos+4:pos+8], endian='>')
D = Struct.float(data[pos+8:pos+12], endian='>')
print " %11f %11f %11f"%(F,P,D)
self.Triplets.append((F,P,D))
pos += 12
else:
print " Unknown format: %04x"%self.Unk
def pack(self, offset):
self.Triplets.sort(key=lambda x: x[0])
t = self.Triplets
self.Triplets = []
lt = (None, None, None)
for i in t:
if i == lt:
pass
elif i[0] == lt[0]:
raise ValueError("Duplicate triplet frame numbers with different data")
else:
self.Triplets.append(i)
out = Struct.uint16(self.Type, endian='>')
out += Struct.uint16(self.Unk, endian='>')
out += Struct.uint16(len(self.Triplets), endian='>')
out += "\x00\x00"
out += Struct.uint32(0xc, endian='>')
for F,P,D in self.Triplets:
out += Struct.float(F-offset, endian='>')
out += Struct.float(P, endian='>')
out += Struct.float(D, endian='>')
return out
def add(self, F, P=None, D=None):
if isinstance(F,tuple):
self.Triplets.append(F)
else:
self.Triplets.append((F,P,D))
def rep(self, start, end, times):
replist = []
for i in self.Triplets:
if i[0] >= start and i[0] <= end:
replist.append(i)
if len(replist) == 0:
return
off = end-start
for i in range(times-1):
for a,b,c in replist:
self.Triplets.append((a+off,b,c))
off += end-start
a,b,c = replist[0]
if a == start:
self.Triplets.append((a+off,b,c))
def repsimple(self, start, end, times, sp, sd, ep, ed):
step = float(end-start) / times
self.Triplets.append((start, sp, sd))
self.Triplets.append((start+step/2.0, ep, ed))
self.rep(start, start+step, times)
def calc(self, frame):
for tn in range(len(self.Triplets)):
if self.Triplets[tn][0] > frame:
if tn == 0:
return self.Triplets[0][1]
else:
start, value1, coef1 = self.Triplets[tn-1]
end, value2, coef2 = self.Triplets[tn]
t = (frame - start) / (end - start)
nf = end - start
return \
coef1 * 1 * nf * (t + t**3 - 2*t**2) + \
coef2 * 1 * nf * (t**3 - t**2) + \
value1 * (1 + (2*t**3 - 3*t**2)) + \
value2 * (-2*t**3 + 3*t**2)
else:
return self.Triplets[-1][1]
def __getitem__(self, n):
return self.Triplets[n]
def PAI1(self, data):
assert self.Anim is None
self.Anim = self.BrlanPAI1(data)
return
def Pack(self, a=None, b=None):
if a is None and b is None:
frames = self.FrameCount
offset = 0
elif a is not None and b is None:
frames = a
offset = 0
elif a is not None and b is not None:
frames = b-a
offset = a
else:
raise ValueError("WTF are you doing")
header = self.BrlanHeader()
header.Unk = 0xfeff0008
header.UnkCount = 0x10
header.Magic = "RLAN"
header.AtomCount = 1
data = self.Anim.pack(offset, frames)
header.Size = len(data) + len(header)
data = header.pack() + data
return data
if have_pyglet:
class BannerWindow(window.Window):
def on_resize(self, width, height):
glViewport(0, 0, width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(-width/2, width/2, -height/2, height/2, -1, 1)
glMatrixMode(GL_MODELVIEW)
class Renderer(object):
def __init__(self):
self.Brlyt = None
self.Brlan = None
def Create(self, width, height):
self.Width = width
self.Height = height
print "Render: %f x %f"%(self.Width,self.Height)
self.Window = BannerWindow(self.Width, self.Height)
self.Window.set_exclusive_mouse(False)
glClearColor(0.0, 0.0, 0.0, 0.0)
glClearDepth(1.0)
glDepthFunc(GL_LEQUAL)
glEnable(GL_DEPTH_TEST)
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)
glEnable(GL_BLEND)
glEnable(GL_TEXTURE_2D)
clock.set_fps_limit(60)
def Render(self, item, wireframe=False):
if not item.Enabled:
return
if isinstance(item, Picture):
mat = self.Brlyt.Materials[item.Material]
texture = self.Brlyt.Textures[mat.Textures[0][0]].GLTexture
mtc = mat.TextureCoords[0]
x, y, a, b, c, rot, xsc, ysc, xs, ys = item.Coords[:10]
xs *= xsc
ys *= ysc
#print item.Name,x,y,xs,ys
xc, yc = x-(xs/2),y-(ys/2)
glPushMatrix()
glMatrixMode( GL_MODELVIEW )
glTranslatef( x, y, 0)
glRotatef(rot,0,0,1)
glScalef(xs,ys,0)
if not wireframe:
col = [x/255.0 for x in list(mat.Color2)]
col[3] = col[3] * item.Alpha / 255.0
tw = texture.tex_coords[6]
th = texture.tex_coords[7]
mc = item.MaterialCoords
glMatrixMode( GL_TEXTURE )
glPushMatrix()
glTranslatef(0.5,0.5,0)
glTranslatef(mtc[0],mtc[1],0)
glScalef(mtc[3],mtc[4],0)
glTranslatef(-0.5,-0.5,0)
array = (GLfloat * 32)(
mc[0][0] * tw, mc[0][1] * th, 0, 1.,
-0.5, 0.5, 0, 1.,
mc[1][0] * tw, mc[1][1] * th, 0, 1.,
0.5, 0.5, 0, 1.,
mc[3][0] * tw, mc[3][1] * th, 0, 1.,
0.5, -0.5, 0, 1.,
mc[2][0] * tw, mc[2][1] * th, 0, 1.,
-0.5, -0.5, 0, 1.)
glColor4f(*col)
glPushAttrib(GL_ENABLE_BIT)
glEnable(texture.target)
glBindTexture(texture.target, texture.id)
if mat.Textures[0][1] == 0x0:
glTexParameteri(texture.target, GL_TEXTURE_WRAP_S, GL_CLAMP)
elif mat.Textures[0][1] == 0x1:
glTexParameteri(texture.target, GL_TEXTURE_WRAP_S, GL_REPEAT)
elif mat.Textures[0][1] == 0x2:
glTexParameteri(texture.target, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT)
else:
glTexParameteri(texture.target, GL_TEXTURE_WRAP_S, GL_CLAMP)
if mat.Textures[0][2] == 0x0:
glTexParameteri(texture.target, GL_TEXTURE_WRAP_T, GL_CLAMP)
elif mat.Textures[0][2] == 0x1:
glTexParameteri(texture.target, GL_TEXTURE_WRAP_T, GL_REPEAT)
elif mat.Textures[0][2] == 0x2:
glTexParameteri(texture.target, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT)
else:
glTexParameteri(texture.target, GL_TEXTURE_WRAP_T, GL_CLAMP)
glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT)
glInterleavedArrays(GL_T4F_V4F, 0, array)
glDrawArrays(GL_QUADS, 0, 4)
glPopClientAttrib()
glPopAttrib()
glBindTexture(texture.target, 0)
glPopMatrix()
glMatrixMode( GL_MODELVIEW )
else:
glColor3f(1,0,0)
glBegin(GL_LINE_STRIP)
glVertex2f(-0.5,-0.5)
glVertex2f(0.5,-0.5)
glVertex2f(0.5,0.5)
glVertex2f(-0.5,0.5)
glVertex2f(-0.5,-0.5)
glColor3f(1,1,1)
glEnd()
pass
glPopMatrix()
if isinstance(item, Pane):
if item.Coords is not None:
x, y, a, b, c, rot, xsc, ysc, xs, ys = item.Coords[:10]
else:
x = y = 0
xs = ys = 0
xsc = 1
ysc = 1
glPushMatrix()
glTranslatef(x, y, 0)
glRotatef(rot,0,0,1)
glScalef(xsc,ysc,0)
#glScalef(xs,ys,1)
for child in item.Children:
self.Render(child,wireframe)
glPopMatrix()
def Animate(self, frame):
for set in self.Brlan.Anim:
for clss in set:
for anim in clss:
#print set.Name, clss.Type, anim.Type, anim.calc(frame), frame
if clss.Type == Brlan.A_COORD:
self.Brlyt.Objects[set.Name].Coords[anim.Type] = anim.calc(frame)
elif clss.Type == Brlan.A_PARM:
if anim.Type == Brlan.P_ALPHA:
self.Brlyt.Objects[set.Name].Alpha = anim.calc(frame)
def MainLoop(self, loop):
frame = 0
print "Starting mainloop: loop =",loop
print "Length in frames:",self.Brlan.Anim.FrameCount
while not self.Window.has_exit:
self.Window.dispatch_events()
self.Window.clear()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
glColor4f(1.0, 1.0, 1.0, 1.0)
self.Render(self.Brlyt.RootPane,False)
#self.Render(self.Brlyt.RootPane,True)
#clock.tick()
self.Window.flip()
if self.Brlan is not None:
self.Animate(frame)
if frame >= self.Brlan.Anim.FrameCount:
if not loop:
print "Animation done!"
return True
else:
print "Looping..."
frame = -1
frame += 1
class Alameda(object):
class IMETHeader(Struct):
__endian__ = Struct.BE
def __format__(self):
self.Zeroes = Struct.uint8[0x40]
self.IMET = Struct.string(4)
self.Fixed = Struct.uint8[8]
self.Sizes = Struct.uint32[3]
self.Flag1 = Struct.uint32
self.Names = Struct.string(0x2A<<1, encoding='utf-16-be', stripNulls=True)[7]
self.Zeroes = Struct.uint8[0x348]
self.MD5 = Struct.uint8[0x10]
def __init__(self, fn, type='icon'):
renderer = Renderer()
fp = file(fn, 'rb')
imet = self.IMETHeader()
try:
imet.unpack(fp.read(len(imet)))
except:
imet = None
if imet is None or imet.IMET != 'IMET':
imet = self.IMETHeader()
fp.seek(0x40)
imet.unpack(fp.read(len(imet)))
assert imet.IMET == 'IMET'
print 'English title: %s' % imet.Names[1]
root = U8(fp.read())
if type == 'icon':
banner = U8(IMD5(root.Files['./meta/icon.bin']))
renderer.Brlyt = Brlyt(banner, banner.Files['./arc/blyt/icon.brlyt'], renderer)
fd = None
try:
fd = banner.Files['./arc/anim/icon.brlan']
except:
pass
if fd is not None:
renderer.Brlan = Brlan(fd)
loop = True
else:
banner = U8(IMD5(root.Files['./meta/banner.bin']))
renderer.Brlyt = Brlyt(banner, banner.Files['./arc/blyt/banner.brlyt'], renderer)
loop = not banner.Files.has_key('./arc/anim/banner_start.brlan')
if not loop:
renderer.Brlan = Brlan(banner.Files['./arc/anim/banner_start.brlan'])
else:
renderer.Brlan = Brlan(banner.Files['./arc/anim/banner.brlan'])
if renderer.MainLoop(loop) and type == 'banner' and not loop:
renderer.Brlan = Brlan(banner.Files['./arc/anim/banner_loop.brlan'])
renderer.MainLoop(True)
if __name__=='__main__':
Alameda(*sys.argv[1:])