123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- import ctypes
- import os, sys
- sys.path.append(
- os.path.abspath(
- os.path.join(
- os.path.dirname(__file__), "../../")))
- from lib3ddevil1.bindings import libc
- del os, sys
- #--------------------------------------+
- # 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")
- del libc
- #--------------------------------------+
- # Pythonic Object
- #--------------------------------------+
- class pyTexturePack:
- def __init__(self, filedata):
- self.cstruct = ctypes.pointer(TexturePack())
- if not devil1tex.getheader(ctypes.byref(self.cstruct), filedata):
- raise RuntimeError("failed to get texture pack header")
- return
- def show(self):
- devil1tex.printheader(self.cstruct)
- def getbatchnumber(self):
- return self.cstruct.contents.batchNumber
- def getfirstbatchoffset(self):
- return self.cstruct.contents.firstBatchOffset
- class pyTextureBatchDescriptor:
- def __init__(self, i, filedata):
- self.cstruct = ctypes.pointer(TextureBatchDescriptor())
- ptrofptr = ctypes.byref(self.cstruct)
- if filedata:
- if not devil1tex.getbatchdesc(
- ptrofptr,
- i,
- filedata,
- len(filedata)):
- raise RuntimeError("failed to get texturebatchdescriptor #" + str(i))
- 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 gettexnumber(self):
- return self.cstruct.contents.texNumber
- def gettexturesize(self):
- return self.cstruct.contents.textureSize
- class pyTextureBatch:
- def __init__(self, i, filedata):
- self.cstruct = TextureBatch()
- if filedata:
- self.cstruct.batch = None
- tbd = pyTextureBatchDescriptor(i, filedata)
- self.amount = tbd.gettexnumber()
- self.size = tbd.gettexturesize()
- memsize = self.amount * self.size
- self.cstruct.batch = ctypes.cast(
- ctypes.create_string_buffer(memsize),
- ctypes.POINTER(Texture))
- if not devil1tex.gettextures(
- self.cstruct.batch,
- i,
- filedata,
- len(filedata)):
- raise RuntimeError("failed to get textures of batch #" + str(i))
- return
- def gettextures(self):
- ptrs = self.cstruct.batch[:self.amount]
- textures = []
- for ptr in ptrs:
- texture = ctypes.cast(ptr.data,
- ctypes.POINTER(
- ctypes.c_ubyte * self.size))[0]
- textures.append(texture)
- return textures
|