2018-05-16 01:12:16 +05:30
|
|
|
#!/usr/bin/python3
|
2018-05-16 03:34:53 +05:30
|
|
|
import ctypes
|
|
|
|
from __init__ import libc
|
2018-05-16 01:12:16 +05:30
|
|
|
|
|
|
|
#--------------------------------------+
|
|
|
|
# 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")
|
2018-05-16 03:34:53 +05:30
|
|
|
del libc
|
2018-05-16 01:12:16 +05:30
|
|
|
|
|
|
|
#--------------------------------------+
|
|
|
|
# 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]
|
|
|
|
|