mirror of
https://notabug.org/scuti/lib3ddevil1
synced 2024-11-22 05:42:59 +05:30
split python file into parts
This commit is contained in:
parent
e9c9b51f16
commit
d8e1c45156
121
bindings/main.py
Normal file
121
bindings/main.py
Normal file
@ -0,0 +1,121 @@
|
||||
from py3devil1pld import *
|
||||
from py3devil1tex import *
|
||||
from py3devil1geo import *
|
||||
|
||||
#--------------------------------------+
|
||||
# Regular Python
|
||||
#--------------------------------------+
|
||||
|
||||
if __name__ == "__main__":
|
||||
def pldtest(devil1pld, pldheader):
|
||||
with open("pl01.pld", "rb") as f:
|
||||
data = f.read()
|
||||
devil1pld.getheader(ctypes.byref(pldheader), data)
|
||||
devil1pld.printheader(ctypes.byref(pldheader))
|
||||
# for offset in pldheader.getoffsets():
|
||||
# print(hex(offset))
|
||||
|
||||
def textest(devil1tex, texheader):
|
||||
print("texture test")
|
||||
with open("pl01.pld_1.txp", "rb") as f:
|
||||
data = f.read()
|
||||
# texheader = ctypes.cast(data, ctypes.POINTER(TexturePack))
|
||||
th = ctypes.pointer(texheader)
|
||||
devil1tex.getheader(ctypes.byref(th), data)
|
||||
devil1tex.printheader(th)
|
||||
batchdesc = TextureBatchDescriptor()
|
||||
bd = ctypes.pointer(batchdesc)
|
||||
print("\nbatch descriptor:")
|
||||
devil1tex.getbatchdesc(ctypes.byref(bd), 1, data, len(data))
|
||||
devil1tex.printbatchdesc(bd)
|
||||
print(bd.contents.textureSize)
|
||||
|
||||
def geotest(devil1geo, geoheader):
|
||||
print("geo test")
|
||||
with open("pl00.pld_0", "rb") as f:
|
||||
data = f.read()
|
||||
# geoheader = ctypes.cast(data, ctypes.POINTER(Header))
|
||||
gh = ctypes.pointer(geoheader)
|
||||
devil1geo.getheader(ctypes.byref(gh), data)
|
||||
devil1geo.printheader(gh)
|
||||
meshheader = MeshHeader()
|
||||
mh = ctypes.pointer(meshheader)
|
||||
devil1geo.getmeshheader(ctypes.byref(mh), 1, data)
|
||||
devil1geo.printmeshheader(mh)
|
||||
|
||||
def main():
|
||||
sharedlib='./lib3ddevil1.so'
|
||||
libc = ctypes.cdll.LoadLibrary(sharedlib)
|
||||
if (not libc):
|
||||
print("Couldn't load %s" % sharedlib)
|
||||
return 1
|
||||
print("OK")
|
||||
|
||||
pldfn = Devil1PLD_FN.in_dll(libc, "DEVIL1PLD")
|
||||
pldh = PldHeader()
|
||||
pldtest(pldfn, pldh)
|
||||
|
||||
texfn = Devil1TEX_FN.in_dll(libc, "DEVIL1TEX")
|
||||
texh = TexturePack()
|
||||
textest(texfn, texh)
|
||||
|
||||
geofn = Devil1GEO_FN.in_dll(libc, "DEVIL1GEO")
|
||||
geoh = Header()
|
||||
geotest(geofn, geoh)
|
||||
|
||||
def mainx():
|
||||
with open("pl01.pld", "rb") as f:
|
||||
data = f.read()
|
||||
pld = PLDHeader(data)
|
||||
pld.show()
|
||||
pld2 = PLDHeader()
|
||||
pld2.show()
|
||||
|
||||
with open("pl01.pld_1.txp", "rb") as f:
|
||||
data = f.read()
|
||||
txp = TEXturePack(data)
|
||||
txp.show()
|
||||
print(txp.getbatchno())
|
||||
print(txp.getfirstbatchoffset())
|
||||
tbd = TEXtureBatchDescriptor(1, data)
|
||||
tbd.show()
|
||||
print(tbd.gettexturesize())
|
||||
#tx = TEXtures(0, tbd.gettexno(), data)
|
||||
tx = TEXtureBatch(0, data)
|
||||
ts = tx.gettextures()
|
||||
for i in range(0, 10):
|
||||
print(ts[0].data[i])
|
||||
|
||||
with open("pl00.pld_0", "rb") as f:
|
||||
data = f.read()
|
||||
gh = GEOHeader(data)
|
||||
gh.show()
|
||||
print("-------------")
|
||||
print(gh.getmeshno())
|
||||
print(gh.getunknownb())
|
||||
print(gh.getunknownc())
|
||||
print(gh.getunknownd())
|
||||
print(gh.getpadding())
|
||||
print(gh.getunknownoffset())
|
||||
mh = MEShHeader(3, data)
|
||||
mh.show()
|
||||
m = MEsh(0, data)
|
||||
m.show()
|
||||
# p = m.getpositions()
|
||||
# print("positions:")
|
||||
# for point in p:
|
||||
# print(point)
|
||||
# n = m.getnormals()
|
||||
# print("normals:")
|
||||
# for point in n:
|
||||
# print(point)
|
||||
# u = m.getuvs()
|
||||
# print("uvs:")
|
||||
# for point in u:
|
||||
# print(point)
|
||||
dbatch = m.getbatchdata()
|
||||
print(hex(dbatch.numVertex))
|
||||
print(hex(dbatch.padding))
|
||||
#---------------------------------------+
|
||||
# main()
|
||||
mainx()
|
@ -1,546 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
import ctypes, sys
|
||||
|
||||
#--------------------------------------+
|
||||
# Devil 1: PLD Base
|
||||
#--------------------------------------+
|
||||
|
||||
class PldHeader(ctypes.Structure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
("numOffset", ctypes.c_int),
|
||||
("offsets", ctypes.POINTER(ctypes.c_int))
|
||||
]
|
||||
|
||||
class Devil1PLD_FN(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("getheader" , ctypes.CFUNCTYPE(
|
||||
ctypes.c_bool,
|
||||
ctypes.POINTER(PldHeader),
|
||||
ctypes.c_char_p)),
|
||||
("sizeofsector", ctypes.CFUNCTYPE(
|
||||
ctypes.c_int,
|
||||
ctypes.POINTER(PldHeader),
|
||||
ctypes.c_int)),
|
||||
("printheader" , ctypes.CFUNCTYPE(None,
|
||||
ctypes.POINTER(PldHeader)))
|
||||
]
|
||||
|
||||
#--------------------------------------+
|
||||
# Devil 1: TEX Base
|
||||
#--------------------------------------+
|
||||
|
||||
class TexturePack(ctypes.Structure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
("id", ctypes.c_char * 4), # fixed length 4, reverse order
|
||||
("batchNumber", ctypes.c_int),
|
||||
("firstBatchOffset", ctypes.c_int),
|
||||
("unknownA", ctypes.c_int)
|
||||
]
|
||||
|
||||
class TextureBatchDescriptor(ctypes.Structure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
("batchIdx", ctypes.c_int),
|
||||
("hash", ctypes.c_int),
|
||||
("texNumber", ctypes.c_int),
|
||||
("unknownA", ctypes.c_int * 8),
|
||||
("textureSize", ctypes.c_int),
|
||||
("unknownB", ctypes.c_int * 30)
|
||||
]
|
||||
|
||||
class Texture(ctypes.Structure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
("data", ctypes.POINTER(ctypes.c_ubyte))
|
||||
]
|
||||
|
||||
class TextureBatch(ctypes.Structure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
("batch", ctypes.POINTER(Texture))
|
||||
]
|
||||
|
||||
class Devil1TEX_FN(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("printheader", ctypes.CFUNCTYPE(
|
||||
None,
|
||||
ctypes.POINTER(TexturePack))),
|
||||
("printbatchdesc", ctypes.CFUNCTYPE(
|
||||
None,
|
||||
ctypes.POINTER(TextureBatchDescriptor))),
|
||||
("getheader", ctypes.CFUNCTYPE(
|
||||
ctypes.c_bool,
|
||||
ctypes.POINTER(
|
||||
ctypes.POINTER(TexturePack)),
|
||||
ctypes.c_char_p)),
|
||||
("getbatchdesc", ctypes.CFUNCTYPE(
|
||||
ctypes.c_bool,
|
||||
ctypes.POINTER(
|
||||
ctypes.POINTER(TextureBatchDescriptor)),
|
||||
ctypes.c_uint,
|
||||
ctypes.c_char_p,
|
||||
ctypes.c_uint)),
|
||||
("getbatch", ctypes.CFUNCTYPE(
|
||||
ctypes.c_bool,
|
||||
ctypes.POINTER(
|
||||
ctypes.POINTER(TextureBatch)),
|
||||
ctypes.c_uint,
|
||||
ctypes.c_char_p,
|
||||
ctypes.c_uint)),
|
||||
("gettextures", ctypes.CFUNCTYPE(
|
||||
ctypes.c_bool,
|
||||
ctypes.POINTER(Texture),
|
||||
ctypes.c_uint,
|
||||
ctypes.c_char_p,
|
||||
ctypes.c_uint))
|
||||
]
|
||||
|
||||
#--------------------------------------+
|
||||
# Devil 1: GEO Base
|
||||
#--------------------------------------+
|
||||
|
||||
class Header(ctypes.Structure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
("numMesh", ctypes.c_ubyte),
|
||||
("unknownNumberB", ctypes.c_ubyte),
|
||||
("unknownNumberC", ctypes.c_ubyte),
|
||||
("unknownNumberD", ctypes.c_ubyte),
|
||||
("padding", ctypes.c_int),
|
||||
("unknownOffset", ctypes.c_ulonglong)
|
||||
]
|
||||
|
||||
class MeshHeader(ctypes.Structure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
("numBatch", ctypes.c_short),
|
||||
("numVertex", ctypes.c_short),
|
||||
("u", ctypes.c_uint),
|
||||
("offsetBatches", ctypes.c_ulonglong),
|
||||
("flags", ctypes.c_ulonglong)
|
||||
]
|
||||
|
||||
class Coordinate(ctypes.Structure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
("x", ctypes.c_float),
|
||||
("y", ctypes.c_float),
|
||||
("z", ctypes.c_float)
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return "(%s, %s, %s)" % (str(self.x), str(self.y), str(self.z))
|
||||
|
||||
class UVs(ctypes.Structure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
("u", ctypes.c_short),
|
||||
("v", ctypes.c_short)
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return "(%s, %s)" % (str(self.u), str(self.v))
|
||||
|
||||
class BoneIndexes(ctypes.Structure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
("indexes", ctypes.c_ubyte * 4),
|
||||
]
|
||||
|
||||
class BoneWeights(ctypes.Structure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
("weights", ctypes.c_short)
|
||||
]
|
||||
|
||||
|
||||
class BatchData(ctypes.Structure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
("numVertex", ctypes.c_short),
|
||||
("uB", ctypes.c_short),
|
||||
("padding", ctypes.c_uint),
|
||||
("offsetPositions", ctypes.c_ulonglong),
|
||||
("offsetNormals", ctypes.c_ulonglong),
|
||||
("offsetUVs", ctypes.c_ulonglong),
|
||||
("offsetBoneIndexes", ctypes.c_ulonglong),
|
||||
("offsetBoneWeights", ctypes.c_ulonglong),
|
||||
("offsets", ctypes.c_ulonglong)
|
||||
]
|
||||
|
||||
class VertexData(ctypes.Structure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
("positions", ctypes.POINTER(Coordinate)),
|
||||
("normals", ctypes.POINTER(Coordinate)),
|
||||
("u", ctypes.POINTER(UVs)),
|
||||
("bi", ctypes.POINTER(BoneIndexes)),
|
||||
("bw", ctypes.POINTER(BoneWeights))
|
||||
]
|
||||
|
||||
class Batch(ctypes.Structure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
("bd", ctypes.POINTER(BatchData)),
|
||||
("vd", VertexData)
|
||||
]
|
||||
|
||||
class Mesh(ctypes.Structure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
("b", ctypes.POINTER(Batch))
|
||||
]
|
||||
|
||||
class Devil1GEO_FN(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("printheader", ctypes.CFUNCTYPE(
|
||||
None,
|
||||
ctypes.POINTER(Header))),
|
||||
("printmeshheader", ctypes.CFUNCTYPE(
|
||||
None,
|
||||
ctypes.POINTER(MeshHeader))),
|
||||
("printbatch", ctypes.CFUNCTYPE(
|
||||
None,
|
||||
ctypes.POINTER(Batch))),
|
||||
("printcoordinate", ctypes.CFUNCTYPE(
|
||||
None,
|
||||
ctypes.POINTER(Coordinate))),
|
||||
("getheader", ctypes.CFUNCTYPE(
|
||||
None,
|
||||
ctypes.POINTER(ctypes.POINTER(Header)),
|
||||
ctypes.c_char_p)),
|
||||
("getmeshheader", ctypes.CFUNCTYPE(
|
||||
ctypes.c_bool,
|
||||
ctypes.POINTER(ctypes.POINTER(MeshHeader)),
|
||||
ctypes.c_uint,
|
||||
ctypes.c_char_p)),
|
||||
("getbatch", ctypes.CFUNCTYPE(
|
||||
ctypes.c_bool,
|
||||
ctypes.POINTER(Batch),
|
||||
ctypes.c_uint,
|
||||
ctypes.c_char_p)),
|
||||
("getmesh", ctypes.CFUNCTYPE(
|
||||
ctypes.c_bool,
|
||||
ctypes.POINTER(Mesh),
|
||||
ctypes.c_uint,
|
||||
ctypes.c_char_p,
|
||||
ctypes.c_uint))
|
||||
]
|
||||
|
||||
#--------------------------------------+
|
||||
# Python Objs
|
||||
#--------------------------------------+
|
||||
|
||||
sharedlib = './lib3ddevil1.so'
|
||||
libc = ctypes.cdll.LoadLibrary(sharedlib)
|
||||
if not libc:
|
||||
print("Couldn't load %s" % sharedlib)
|
||||
sys.exit()
|
||||
del sys
|
||||
print("\nlib3ddevil1 loaded.")
|
||||
devil1pld = Devil1PLD_FN.in_dll(libc, "DEVIL1PLD")
|
||||
devil1tex = Devil1TEX_FN.in_dll(libc, "DEVIL1TEX")
|
||||
devil1geo = Devil1GEO_FN.in_dll(libc, "DEVIL1GEO")
|
||||
|
||||
class PLDHeader:
|
||||
def __init__(self, filedata = None):
|
||||
# Store C Struct in order to call C functions
|
||||
self.cstruct = PldHeader()
|
||||
if filedata:
|
||||
devil1pld.getheader(ctypes.byref(self.cstruct), filedata)
|
||||
self.eof = len(filedata)
|
||||
|
||||
def show(self):
|
||||
devil1pld.printheader(ctypes.byref(self.cstruct))
|
||||
return
|
||||
|
||||
def getnumoffsets(self):
|
||||
return self.cstruct.numOffsets
|
||||
|
||||
# return pythonic list of offsets
|
||||
def getoffsets(self):
|
||||
return self.cstruct.offsets[:self.cstruct.numOffset]
|
||||
|
||||
def sizeofsector(self, i):
|
||||
ptr = ctypes.byref(self.cstruct)
|
||||
return devil1pld.sizeofsector(ptr, i, self.eof)
|
||||
|
||||
class TEXturePack:
|
||||
def __init__(self, filedata):
|
||||
self.cstruct = ctypes.pointer(TexturePack())
|
||||
devil1tex.getheader(ctypes.byref(self.cstruct), filedata)
|
||||
return
|
||||
|
||||
def show(self):
|
||||
devil1tex.printheader(self.cstruct)
|
||||
|
||||
def getbatchno(self):
|
||||
return self.cstruct.contents.batchNumber
|
||||
|
||||
def getfirstbatchoffset(self):
|
||||
return self.cstruct.contents.firstBatchOffset
|
||||
|
||||
class TEXtureBatchDescriptor:
|
||||
def __init__(self, i, filedata):
|
||||
self.cstruct = ctypes.pointer(TextureBatchDescriptor())
|
||||
ptrofptr = ctypes.byref(self.cstruct)
|
||||
if filedata:
|
||||
devil1tex.getbatchdesc(ptrofptr, i, filedata, len(filedata))
|
||||
return
|
||||
|
||||
def show(self):
|
||||
devil1tex.printbatchdesc(self.cstruct)
|
||||
|
||||
def getbatchidx(self):
|
||||
return self.cstruct.contents.batchIdx
|
||||
|
||||
def gethash(self):
|
||||
return self.cstruct.contents.hash
|
||||
|
||||
def gettexno(self):
|
||||
return self.cstruct.contents.texNumber
|
||||
|
||||
def gettexturesize(self):
|
||||
return self.cstruct.contents.textureSize
|
||||
|
||||
class TEXtureBatch:
|
||||
def __init__(self, i, filedata):
|
||||
self.cstruct = TextureBatch()
|
||||
if filedata:
|
||||
self.cstruct.batch = None
|
||||
tbd = TEXtureBatchDescriptor(i, filedata)
|
||||
self.amount = tbd.gettexno()
|
||||
memsize = self.amount * tbd.gettexturesize()
|
||||
self.cstruct.batch = ctypes.cast(
|
||||
ctypes.create_string_buffer(memsize),
|
||||
ctypes.POINTER(Texture))
|
||||
devil1tex.gettextures(self.cstruct.batch, i, filedata, len(filedata))
|
||||
return
|
||||
|
||||
def gettextures(self):
|
||||
return self.cstruct.batch[:self.amount]
|
||||
|
||||
class GEOHeader:
|
||||
def __init__(self, filedata):
|
||||
self.cstruct = ctypes.pointer(Header())
|
||||
ptrofptr = ctypes.byref(self.cstruct)
|
||||
if filedata:
|
||||
devil1geo.getheader(ptrofptr, filedata)
|
||||
return
|
||||
|
||||
def show(self):
|
||||
devil1geo.printheader(self.cstruct)
|
||||
|
||||
def getmeshno(self):
|
||||
return self.cstruct.contents.numMesh
|
||||
|
||||
def getunknownb(self):
|
||||
return self.cstruct.contents.unknownNumberB
|
||||
|
||||
def getunknownc(self):
|
||||
return self.cstruct.contents.unknownNumberC
|
||||
|
||||
def getunknownd(self):
|
||||
return self.cstruct.contents.unknownNumberD
|
||||
|
||||
def getpadding(self):
|
||||
return hex(self.cstruct.contents.padding)
|
||||
|
||||
def getunknownoffset(self):
|
||||
return hex(self.cstruct.contents.unknownOffset)
|
||||
|
||||
|
||||
class MEShHeader:
|
||||
def __init__(self, i, filedata):
|
||||
self.cstruct = ctypes.pointer(MeshHeader())
|
||||
ptrofptr = ctypes.byref(self.cstruct)
|
||||
if filedata:
|
||||
devil1geo.getmeshheader(ptrofptr, i, filedata)
|
||||
return
|
||||
pass
|
||||
|
||||
def show(self):
|
||||
devil1geo.printmeshheader(self.cstruct)
|
||||
|
||||
def getbatchno(self):
|
||||
return self.cstruct.contents.numBatch
|
||||
|
||||
def getnumvertex(self):
|
||||
return self.cstruct.contents.numVertex
|
||||
|
||||
def getunknown(self):
|
||||
return hex(self.cstruct.contents.u)
|
||||
|
||||
def getoffsetbatches(self):
|
||||
return self.cstruct.contents.offsetBatches
|
||||
|
||||
def getflags(self):
|
||||
return self.cstruct.contents.flags
|
||||
|
||||
class MEsh:
|
||||
def __init__(self, i, filedata):
|
||||
self.cstruct = Mesh()
|
||||
if filedata:
|
||||
mh = MEShHeader(i, filedata)
|
||||
# allocate memory for the size of batch * number of batches
|
||||
memsize = ctypes.sizeof(Batch) * mh.getbatchno()
|
||||
self.cstruct.b = ctypes.cast(
|
||||
ctypes.create_string_buffer(memsize),
|
||||
ctypes.POINTER(Batch))
|
||||
if not devil1geo.getmesh(
|
||||
ctypes.byref(self.cstruct),
|
||||
i,
|
||||
filedata,
|
||||
len(filedata)):
|
||||
print("failed to get mesh")
|
||||
del mh, memsize
|
||||
return
|
||||
|
||||
def show(self):
|
||||
if self.cstruct.b:
|
||||
devil1geo.printbatch(self.cstruct.b)
|
||||
else:
|
||||
print("nothing to show")
|
||||
|
||||
def getbatchdata(self):
|
||||
return self.cstruct.b.contents.bd.contents
|
||||
|
||||
def getpositions(self):
|
||||
length = self.cstruct.b.contents.bd.contents.numVertex
|
||||
return self.cstruct.b.contents.vd.positions[:length]
|
||||
|
||||
def getnormals(self):
|
||||
length = self.cstruct.b.contents.bd.contents.numVertex
|
||||
return self.cstruct.b.contents.vd.normals[:length]
|
||||
|
||||
def getuvs(self):
|
||||
length = self.cstruct.b.contents.bd.contents.numVertex
|
||||
return self.cstruct.b.contents.vd.u[:length]
|
||||
|
||||
def getboneindexes(self):
|
||||
length = self.cstruct.b.contents.bd.contents.numVertex
|
||||
return self.cstruct.b.contents.vd.bi[:length]
|
||||
|
||||
def getboneweights(self):
|
||||
length = self.cstruct.b.contents.bd.contents.numVertex
|
||||
return self.cstruct.b.contents.vd.bw[:length]
|
||||
|
||||
#--------------------------------------+
|
||||
# Regular Python
|
||||
#--------------------------------------+
|
||||
if __name__ == "__main__":
|
||||
def pldtest(devil1pld, pldheader):
|
||||
with open("pl01.pld", "rb") as f:
|
||||
data = f.read()
|
||||
devil1pld.getheader(ctypes.byref(pldheader), data)
|
||||
devil1pld.printheader(ctypes.byref(pldheader))
|
||||
# for offset in pldheader.getoffsets():
|
||||
# print(hex(offset))
|
||||
|
||||
def textest(devil1tex, texheader):
|
||||
print("texture test")
|
||||
with open("pl01.pld_1.txp", "rb") as f:
|
||||
data = f.read()
|
||||
# texheader = ctypes.cast(data, ctypes.POINTER(TexturePack))
|
||||
th = ctypes.pointer(texheader)
|
||||
devil1tex.getheader(ctypes.byref(th), data)
|
||||
devil1tex.printheader(th)
|
||||
batchdesc = TextureBatchDescriptor()
|
||||
bd = ctypes.pointer(batchdesc)
|
||||
print("\nbatch descriptor:")
|
||||
devil1tex.getbatchdesc(ctypes.byref(bd), 1, data, len(data))
|
||||
devil1tex.printbatchdesc(bd)
|
||||
print(bd.contents.textureSize)
|
||||
|
||||
def geotest(devil1geo, geoheader):
|
||||
print("geo test")
|
||||
with open("pl00.pld_0", "rb") as f:
|
||||
data = f.read()
|
||||
# geoheader = ctypes.cast(data, ctypes.POINTER(Header))
|
||||
gh = ctypes.pointer(geoheader)
|
||||
devil1geo.getheader(ctypes.byref(gh), data)
|
||||
devil1geo.printheader(gh)
|
||||
meshheader = MeshHeader()
|
||||
mh = ctypes.pointer(meshheader)
|
||||
devil1geo.getmeshheader(ctypes.byref(mh), 1, data)
|
||||
devil1geo.printmeshheader(mh)
|
||||
|
||||
def main():
|
||||
sharedlib='./lib3ddevil1.so'
|
||||
libc = ctypes.cdll.LoadLibrary(sharedlib)
|
||||
if (not libc):
|
||||
print("Couldn't load %s" % sharedlib)
|
||||
return 1
|
||||
print("OK")
|
||||
|
||||
pldfn = Devil1PLD_FN.in_dll(libc, "DEVIL1PLD")
|
||||
pldh = PldHeader()
|
||||
pldtest(pldfn, pldh)
|
||||
|
||||
texfn = Devil1TEX_FN.in_dll(libc, "DEVIL1TEX")
|
||||
texh = TexturePack()
|
||||
textest(texfn, texh)
|
||||
|
||||
geofn = Devil1GEO_FN.in_dll(libc, "DEVIL1GEO")
|
||||
geoh = Header()
|
||||
geotest(geofn, geoh)
|
||||
|
||||
def mainx():
|
||||
with open("pl01.pld", "rb") as f:
|
||||
data = f.read()
|
||||
pld = PLDHeader(data)
|
||||
pld.show()
|
||||
pld2 = PLDHeader()
|
||||
pld2.show()
|
||||
|
||||
with open("pl01.pld_1.txp", "rb") as f:
|
||||
data = f.read()
|
||||
txp = TEXturePack(data)
|
||||
txp.show()
|
||||
print(txp.getbatchno())
|
||||
print(txp.getfirstbatchoffset())
|
||||
tbd = TEXtureBatchDescriptor(1, data)
|
||||
tbd.show()
|
||||
print(tbd.gettexturesize())
|
||||
#tx = TEXtures(0, tbd.gettexno(), data)
|
||||
tx = TEXtureBatch(0, data)
|
||||
ts = tx.gettextures()
|
||||
for i in range(0, 10):
|
||||
print(ts[0].data[i])
|
||||
|
||||
with open("pl00.pld_0", "rb") as f:
|
||||
data = f.read()
|
||||
gh = GEOHeader(data)
|
||||
gh.show()
|
||||
print("-------------")
|
||||
print(gh.getmeshno())
|
||||
print(gh.getunknownb())
|
||||
print(gh.getunknownc())
|
||||
print(gh.getunknownd())
|
||||
print(gh.getpadding())
|
||||
print(gh.getunknownoffset())
|
||||
mh = MEShHeader(3, data)
|
||||
mh.show()
|
||||
m = MEsh(0, data)
|
||||
m.show()
|
||||
# p = m.getpositions()
|
||||
# print("positions:")
|
||||
# for point in p:
|
||||
# print(point)
|
||||
# n = m.getnormals()
|
||||
# print("normals:")
|
||||
# for point in n:
|
||||
# print(point)
|
||||
# u = m.getuvs()
|
||||
# print("uvs:")
|
||||
# for point in u:
|
||||
# print(point)
|
||||
dbatch = m.getbatchdata()
|
||||
print(hex(dbatch.numVertex))
|
||||
print(hex(dbatch.padding))
|
||||
#---------------------------------------+
|
||||
# main()
|
||||
mainx()
|
||||
|
254
bindings/py3devil1geo.py
Normal file
254
bindings/py3devil1geo.py
Normal file
@ -0,0 +1,254 @@
|
||||
#!/usr/bin/python3
|
||||
import ctypes, sys
|
||||
|
||||
sharedlib = './lib3ddevil1.so'
|
||||
libc = ctypes.cdll.LoadLibrary(sharedlib)
|
||||
if not libc:
|
||||
print("Couldn't load %s" % sharedlib)
|
||||
sys.exit()
|
||||
del sys
|
||||
|
||||
print("\nlib3ddevil1 loaded.")
|
||||
|
||||
#--------------------------------------+
|
||||
# Basic Struct
|
||||
#--------------------------------------+
|
||||
|
||||
class Header(ctypes.Structure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
("numMesh", ctypes.c_ubyte),
|
||||
("unknownNumberB", ctypes.c_ubyte),
|
||||
("unknownNumberC", ctypes.c_ubyte),
|
||||
("unknownNumberD", ctypes.c_ubyte),
|
||||
("padding", ctypes.c_int),
|
||||
("unknownOffset", ctypes.c_ulonglong)
|
||||
]
|
||||
|
||||
class MeshHeader(ctypes.Structure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
("numBatch", ctypes.c_short),
|
||||
("numVertex", ctypes.c_short),
|
||||
("u", ctypes.c_uint),
|
||||
("offsetBatches", ctypes.c_ulonglong),
|
||||
("flags", ctypes.c_ulonglong)
|
||||
]
|
||||
|
||||
class Coordinate(ctypes.Structure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
("x", ctypes.c_float),
|
||||
("y", ctypes.c_float),
|
||||
("z", ctypes.c_float)
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return "(%s, %s, %s)" % (str(self.x), str(self.y), str(self.z))
|
||||
|
||||
class UVs(ctypes.Structure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
("u", ctypes.c_short),
|
||||
("v", ctypes.c_short)
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return "(%s, %s)" % (str(self.u), str(self.v))
|
||||
|
||||
class BoneIndexes(ctypes.Structure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
("indexes", ctypes.c_ubyte * 4),
|
||||
]
|
||||
|
||||
class BoneWeights(ctypes.Structure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
("weights", ctypes.c_short)
|
||||
]
|
||||
|
||||
|
||||
class BatchData(ctypes.Structure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
("numVertex", ctypes.c_short),
|
||||
("uB", ctypes.c_short),
|
||||
("padding", ctypes.c_uint),
|
||||
("offsetPositions", ctypes.c_ulonglong),
|
||||
("offsetNormals", ctypes.c_ulonglong),
|
||||
("offsetUVs", ctypes.c_ulonglong),
|
||||
("offsetBoneIndexes", ctypes.c_ulonglong),
|
||||
("offsetBoneWeights", ctypes.c_ulonglong),
|
||||
("offsets", ctypes.c_ulonglong)
|
||||
]
|
||||
|
||||
class VertexData(ctypes.Structure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
("positions", ctypes.POINTER(Coordinate)),
|
||||
("normals", ctypes.POINTER(Coordinate)),
|
||||
("u", ctypes.POINTER(UVs)),
|
||||
("bi", ctypes.POINTER(BoneIndexes)),
|
||||
("bw", ctypes.POINTER(BoneWeights))
|
||||
]
|
||||
|
||||
class Batch(ctypes.Structure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
("bd", ctypes.POINTER(BatchData)),
|
||||
("vd", VertexData)
|
||||
]
|
||||
|
||||
class Mesh(ctypes.Structure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
("b", ctypes.POINTER(Batch))
|
||||
]
|
||||
|
||||
class Devil1GEO_FN(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("printheader", ctypes.CFUNCTYPE(
|
||||
None,
|
||||
ctypes.POINTER(Header))),
|
||||
("printmeshheader", ctypes.CFUNCTYPE(
|
||||
None,
|
||||
ctypes.POINTER(MeshHeader))),
|
||||
("printbatch", ctypes.CFUNCTYPE(
|
||||
None,
|
||||
ctypes.POINTER(Batch))),
|
||||
("printcoordinate", ctypes.CFUNCTYPE(
|
||||
None,
|
||||
ctypes.POINTER(Coordinate))),
|
||||
("getheader", ctypes.CFUNCTYPE(
|
||||
None,
|
||||
ctypes.POINTER(ctypes.POINTER(Header)),
|
||||
ctypes.c_char_p)),
|
||||
("getmeshheader", ctypes.CFUNCTYPE(
|
||||
ctypes.c_bool,
|
||||
ctypes.POINTER(ctypes.POINTER(MeshHeader)),
|
||||
ctypes.c_uint,
|
||||
ctypes.c_char_p)),
|
||||
("getbatch", ctypes.CFUNCTYPE(
|
||||
ctypes.c_bool,
|
||||
ctypes.POINTER(Batch),
|
||||
ctypes.c_uint,
|
||||
ctypes.c_char_p)),
|
||||
("getmesh", ctypes.CFUNCTYPE(
|
||||
ctypes.c_bool,
|
||||
ctypes.POINTER(Mesh),
|
||||
ctypes.c_uint,
|
||||
ctypes.c_char_p,
|
||||
ctypes.c_uint))
|
||||
]
|
||||
|
||||
devil1geo = Devil1GEO_FN.in_dll(libc, "DEVIL1GEO")
|
||||
|
||||
#--------------------------------------+
|
||||
# Pythonic Object
|
||||
#--------------------------------------+
|
||||
|
||||
class GEOHeader:
|
||||
def __init__(self, filedata):
|
||||
self.cstruct = ctypes.pointer(Header())
|
||||
ptrofptr = ctypes.byref(self.cstruct)
|
||||
if filedata:
|
||||
devil1geo.getheader(ptrofptr, filedata)
|
||||
return
|
||||
|
||||
def show(self):
|
||||
devil1geo.printheader(self.cstruct)
|
||||
|
||||
def getmeshno(self):
|
||||
return self.cstruct.contents.numMesh
|
||||
|
||||
def getunknownb(self):
|
||||
return self.cstruct.contents.unknownNumberB
|
||||
|
||||
def getunknownc(self):
|
||||
return self.cstruct.contents.unknownNumberC
|
||||
|
||||
def getunknownd(self):
|
||||
return self.cstruct.contents.unknownNumberD
|
||||
|
||||
def getpadding(self):
|
||||
return hex(self.cstruct.contents.padding)
|
||||
|
||||
def getunknownoffset(self):
|
||||
return hex(self.cstruct.contents.unknownOffset)
|
||||
|
||||
|
||||
class MEShHeader:
|
||||
def __init__(self, i, filedata):
|
||||
self.cstruct = ctypes.pointer(MeshHeader())
|
||||
ptrofptr = ctypes.byref(self.cstruct)
|
||||
if filedata:
|
||||
devil1geo.getmeshheader(ptrofptr, i, filedata)
|
||||
return
|
||||
pass
|
||||
|
||||
def show(self):
|
||||
devil1geo.printmeshheader(self.cstruct)
|
||||
|
||||
def getbatchno(self):
|
||||
return self.cstruct.contents.numBatch
|
||||
|
||||
def getnumvertex(self):
|
||||
return self.cstruct.contents.numVertex
|
||||
|
||||
def getunknown(self):
|
||||
return hex(self.cstruct.contents.u)
|
||||
|
||||
def getoffsetbatches(self):
|
||||
return self.cstruct.contents.offsetBatches
|
||||
|
||||
def getflags(self):
|
||||
return self.cstruct.contents.flags
|
||||
|
||||
class MEsh:
|
||||
def __init__(self, i, filedata):
|
||||
self.cstruct = Mesh()
|
||||
if filedata:
|
||||
mh = MEShHeader(i, filedata)
|
||||
# allocate memory for the size of batch * number of batches
|
||||
memsize = ctypes.sizeof(Batch) * mh.getbatchno()
|
||||
self.cstruct.b = ctypes.cast(
|
||||
ctypes.create_string_buffer(memsize),
|
||||
ctypes.POINTER(Batch))
|
||||
if not devil1geo.getmesh(
|
||||
ctypes.byref(self.cstruct),
|
||||
i,
|
||||
filedata,
|
||||
len(filedata)):
|
||||
print("failed to get mesh")
|
||||
del mh, memsize
|
||||
return
|
||||
|
||||
def show(self):
|
||||
if self.cstruct.b:
|
||||
devil1geo.printbatch(self.cstruct.b)
|
||||
else:
|
||||
print("nothing to show")
|
||||
|
||||
def getbatchdata(self):
|
||||
return self.cstruct.b.contents.bd.contents
|
||||
|
||||
def getpositions(self):
|
||||
length = self.cstruct.b.contents.bd.contents.numVertex
|
||||
return self.cstruct.b.contents.vd.positions[:length]
|
||||
|
||||
def getnormals(self):
|
||||
length = self.cstruct.b.contents.bd.contents.numVertex
|
||||
return self.cstruct.b.contents.vd.normals[:length]
|
||||
|
||||
def getuvs(self):
|
||||
length = self.cstruct.b.contents.bd.contents.numVertex
|
||||
return self.cstruct.b.contents.vd.u[:length]
|
||||
|
||||
def getboneindexes(self):
|
||||
length = self.cstruct.b.contents.bd.contents.numVertex
|
||||
return self.cstruct.b.contents.vd.bi[:length]
|
||||
|
||||
def getboneweights(self):
|
||||
length = self.cstruct.b.contents.bd.contents.numVertex
|
||||
return self.cstruct.b.contents.vd.bw[:length]
|
65
bindings/py3devil1pld.py
Normal file
65
bindings/py3devil1pld.py
Normal file
@ -0,0 +1,65 @@
|
||||
#!/usr/bin/python3
|
||||
import ctypes, sys
|
||||
|
||||
sharedlib = './lib3ddevil1.so'
|
||||
libc = ctypes.cdll.LoadLibrary(sharedlib)
|
||||
if not libc:
|
||||
print("Couldn't load %s" % sharedlib)
|
||||
sys.exit()
|
||||
del sys
|
||||
print("\nlib3ddevil1 loaded.")
|
||||
|
||||
#--------------------------------------+
|
||||
# Basic Struct
|
||||
#--------------------------------------+
|
||||
|
||||
class PldHeader(ctypes.Structure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
("numOffset", ctypes.c_int),
|
||||
("offsets", ctypes.POINTER(ctypes.c_int))
|
||||
]
|
||||
|
||||
class Devil1PLD_FN(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("getheader" , ctypes.CFUNCTYPE(
|
||||
ctypes.c_bool,
|
||||
ctypes.POINTER(PldHeader),
|
||||
ctypes.c_char_p)),
|
||||
("sizeofsector", ctypes.CFUNCTYPE(
|
||||
ctypes.c_int,
|
||||
ctypes.POINTER(PldHeader),
|
||||
ctypes.c_int)),
|
||||
("printheader" , ctypes.CFUNCTYPE(None,
|
||||
ctypes.POINTER(PldHeader)))
|
||||
]
|
||||
|
||||
devil1pld = Devil1PLD_FN.in_dll(libc, "DEVIL1PLD")
|
||||
|
||||
#--------------------------------------+
|
||||
# Pythonic Object
|
||||
#--------------------------------------+
|
||||
|
||||
class PLDHeader:
|
||||
def __init__(self, filedata = None):
|
||||
# Store C Struct in order to call C functions
|
||||
self.cstruct = PldHeader()
|
||||
if filedata:
|
||||
devil1pld.getheader(ctypes.byref(self.cstruct), filedata)
|
||||
self.eof = len(filedata)
|
||||
|
||||
def show(self):
|
||||
devil1pld.printheader(ctypes.byref(self.cstruct))
|
||||
return
|
||||
|
||||
def getnumoffsets(self):
|
||||
return self.cstruct.numOffsets
|
||||
|
||||
# return pythonic list of offsets
|
||||
def getoffsets(self):
|
||||
return self.cstruct.offsets[:self.cstruct.numOffset]
|
||||
|
||||
def sizeofsector(self, i):
|
||||
ptr = ctypes.byref(self.cstruct)
|
||||
return devil1pld.sizeofsector(ptr, i, self.eof)
|
||||
|
144
bindings/py3devil1tex.py
Normal file
144
bindings/py3devil1tex.py
Normal file
@ -0,0 +1,144 @@
|
||||
#!/usr/bin/python3
|
||||
import ctypes, sys
|
||||
|
||||
sharedlib = './lib3ddevil1.so'
|
||||
libc = ctypes.cdll.LoadLibrary(sharedlib)
|
||||
if not libc:
|
||||
print("Couldn't load %s" % sharedlib)
|
||||
sys.exit()
|
||||
del sys
|
||||
|
||||
print("\nlib3ddevil1 loaded.")
|
||||
|
||||
#--------------------------------------+
|
||||
# Basic Struct
|
||||
#--------------------------------------+
|
||||
|
||||
class TexturePack(ctypes.Structure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
("id", ctypes.c_char * 4), # fixed length 4, reverse order
|
||||
("batchNumber", ctypes.c_int),
|
||||
("firstBatchOffset", ctypes.c_int),
|
||||
("unknownA", ctypes.c_int)
|
||||
]
|
||||
|
||||
class TextureBatchDescriptor(ctypes.Structure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
("batchIdx", ctypes.c_int),
|
||||
("hash", ctypes.c_int),
|
||||
("texNumber", ctypes.c_int),
|
||||
("unknownA", ctypes.c_int * 8),
|
||||
("textureSize", ctypes.c_int),
|
||||
("unknownB", ctypes.c_int * 30)
|
||||
]
|
||||
|
||||
class Texture(ctypes.Structure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
("data", ctypes.POINTER(ctypes.c_ubyte))
|
||||
]
|
||||
|
||||
class TextureBatch(ctypes.Structure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
("batch", ctypes.POINTER(Texture))
|
||||
]
|
||||
|
||||
class Devil1TEX_FN(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("printheader", ctypes.CFUNCTYPE(
|
||||
None,
|
||||
ctypes.POINTER(TexturePack))),
|
||||
("printbatchdesc", ctypes.CFUNCTYPE(
|
||||
None,
|
||||
ctypes.POINTER(TextureBatchDescriptor))),
|
||||
("getheader", ctypes.CFUNCTYPE(
|
||||
ctypes.c_bool,
|
||||
ctypes.POINTER(
|
||||
ctypes.POINTER(TexturePack)),
|
||||
ctypes.c_char_p)),
|
||||
("getbatchdesc", ctypes.CFUNCTYPE(
|
||||
ctypes.c_bool,
|
||||
ctypes.POINTER(
|
||||
ctypes.POINTER(TextureBatchDescriptor)),
|
||||
ctypes.c_uint,
|
||||
ctypes.c_char_p,
|
||||
ctypes.c_uint)),
|
||||
("getbatch", ctypes.CFUNCTYPE(
|
||||
ctypes.c_bool,
|
||||
ctypes.POINTER(
|
||||
ctypes.POINTER(TextureBatch)),
|
||||
ctypes.c_uint,
|
||||
ctypes.c_char_p,
|
||||
ctypes.c_uint)),
|
||||
("gettextures", ctypes.CFUNCTYPE(
|
||||
ctypes.c_bool,
|
||||
ctypes.POINTER(Texture),
|
||||
ctypes.c_uint,
|
||||
ctypes.c_char_p,
|
||||
ctypes.c_uint))
|
||||
]
|
||||
|
||||
devil1tex = Devil1TEX_FN.in_dll(libc, "DEVIL1TEX")
|
||||
|
||||
#--------------------------------------+
|
||||
# Pythonic Object
|
||||
#--------------------------------------+
|
||||
|
||||
class TEXturePack:
|
||||
def __init__(self, filedata):
|
||||
self.cstruct = ctypes.pointer(TexturePack())
|
||||
devil1tex.getheader(ctypes.byref(self.cstruct), filedata)
|
||||
return
|
||||
|
||||
def show(self):
|
||||
devil1tex.printheader(self.cstruct)
|
||||
|
||||
def getbatchno(self):
|
||||
return self.cstruct.contents.batchNumber
|
||||
|
||||
def getfirstbatchoffset(self):
|
||||
return self.cstruct.contents.firstBatchOffset
|
||||
|
||||
class TEXtureBatchDescriptor:
|
||||
def __init__(self, i, filedata):
|
||||
self.cstruct = ctypes.pointer(TextureBatchDescriptor())
|
||||
ptrofptr = ctypes.byref(self.cstruct)
|
||||
if filedata:
|
||||
devil1tex.getbatchdesc(ptrofptr, i, filedata, len(filedata))
|
||||
return
|
||||
|
||||
def show(self):
|
||||
devil1tex.printbatchdesc(self.cstruct)
|
||||
|
||||
def getbatchidx(self):
|
||||
return self.cstruct.contents.batchIdx
|
||||
|
||||
def gethash(self):
|
||||
return self.cstruct.contents.hash
|
||||
|
||||
def gettexno(self):
|
||||
return self.cstruct.contents.texNumber
|
||||
|
||||
def gettexturesize(self):
|
||||
return self.cstruct.contents.textureSize
|
||||
|
||||
class TEXtureBatch:
|
||||
def __init__(self, i, filedata):
|
||||
self.cstruct = TextureBatch()
|
||||
if filedata:
|
||||
self.cstruct.batch = None
|
||||
tbd = TEXtureBatchDescriptor(i, filedata)
|
||||
self.amount = tbd.gettexno()
|
||||
memsize = self.amount * tbd.gettexturesize()
|
||||
self.cstruct.batch = ctypes.cast(
|
||||
ctypes.create_string_buffer(memsize),
|
||||
ctypes.POINTER(Texture))
|
||||
devil1tex.gettextures(self.cstruct.batch, i, filedata, len(filedata))
|
||||
return
|
||||
|
||||
def gettextures(self):
|
||||
return self.cstruct.batch[:self.amount]
|
||||
|
Loading…
Reference in New Issue
Block a user